geoserver源码学习与扩展——kml/kmz转shapefile文件

geoserver通过工作空间Workspace-数据源DataStore-图层Layer管理地理数据,默认只支持shapefile格式的文件发布,不支持kml/kmz、csv的文件格式,所以存在将这些数据转换为shapefile的需求。

kml/kmz的文件解析基于JavaAPIforKml包完成,该包支持kml和kmz的文件解析;

import de.micromata.opengis.kml.v_2_2_0.Kml;

/*解析kml文件*/
Kml kml = Kml.unmarshal(kmlFile);
processKml(kml,typeName);

/*解析kmz文件*/
Kml[] kmls = Kml.unmarshalFromKmz(kmzFile);
for(Kml kml : kmls){
    processKml(kml,typeName);
}

将Kml转换为shapefile文件也是通过如下2步完成:

1、将Kml转换为FeatureCollection;

2、利用ShapefileDumper类将FeatureCollection转存到硬盘(详见http://www.cnblogs.com/HandyLi/p/8616115.html,不再赘述);

 1     /*
 2      * Kml to FeatureCollection
 3     */
 4     private void processKml(Kml kml, String typeName){
 5         try{
 6             Feature kmlFeature = kml.getFeature();
 7             if(kmlFeature instanceof Document){
 8                 Document doc = (Document)kmlFeature;
 9 
10                 List<Feature> folderList = doc.getFeature();
11                 for(Feature folder: folderList){
12                     if(folder instanceof Folder){
13                         //one Folder to one SimpleFeatureCollection
14                         //get Field info
15                         List<String> typeSpec = new ArrayList<String>();
16                         typeSpec.add("the_geom:Point:srid="+ SRID);// <- the geometry attribute: Point type
17                         typeSpec.add("name:String");
18                         List<SimpleField> simpleFields = doc.getSchema().get(0).getSimpleField();
19                         for(SimpleField simField : simpleFields){
20                             String fieldType = simField.getType();
21                             String fieldName = simField.getName();
22                             typeSpec.add(fieldName + ":" + fieldType);
23                         }
24                         if(CreateCluster)//add Field:cluster                        
25                             typeSpec.add("cluster:String");
26                         String typeSpecs = String.join(",", typeSpec);
27                         final SimpleFeatureType TYPE = DataUtilities.createType(typeName,
28                                         typeSpecs // all attributes
29                                 );
30 
31                         SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
32                         /*
33                          * We create a FeatureCollection into which we will put each Feature created from a record
34                          * in the input csv data file
35                          */
36                         ListFeatureCollection collection = new ListFeatureCollection(TYPE);
37 
38                         List<Feature> placeList = ((Folder) folder).getFeature();
39                         for(Feature place: placeList){
40                             if(place instanceof Placemark){
41                                 Geometry kmlGeo = ((Placemark)place).getGeometry();
42                                 com.vividsolutions.jts.geom.Geometry jtsGeom = toJTSGeometry(kmlGeo);
43                                 featureBuilder.add(jtsGeom);
44                                 //Placemark name value
45                                 featureBuilder.add(((Placemark)place).getName());
46 
47                                 ExtendedData exData = ((Placemark)place).getExtendedData();
48                                 List<SimpleData> simDatas = exData.getSchemaData().get(0).getSimpleData();
49                                 for(SimpleData sData : simDatas){
50                                     featureBuilder.add(sData.getValue());
51                                 }                                
52                                 if(CreateCluster)
53                                     featureBuilder.add("");    //add cluster field value
54                                 SimpleFeature feature = featureBuilder.buildFeature(null);
55                                 collection.add(feature);
56                             }
57                         }
58                         // write to shapefile
59                         writeShapeFile(collection);
60                     }
61                 }
62             }
63         }
64         catch(Exception ex){
65             throw new IllegalArgumentException("KML parse error: " + ex.getMessage());
66         }        
67     }
注意:toJTSGeometry函数用于将Kml封装的Geometry类转换为JTS库里的Geometry类。
 1 /*
 2      * de.micromata.opengis.kml.v_2_2_0.Geometry transform to com.vividsolutions.jts.geom.Geometry
 3     */
 4     private com.vividsolutions.jts.geom.Geometry toJTSGeometry(Geometry kmlGeo){
 5         if(kmlGeo == null)
 6             return null;
 7 
 8         GeometryFactory geoFactory = JTSFactoryFinder.getGeometryFactory(null);
 9         if(kmlGeo instanceof MultiGeometry){
10             List<com.vividsolutions.jts.geom.Geometry> geoList = new ArrayList<com.vividsolutions.jts.geom.Geometry>();
11             List<Geometry> kmlGeoList = ((MultiGeometry)kmlGeo).getGeometry();
12             for(Geometry kmlSubGeo : kmlGeoList){
13                 geoList.add(toJTSGeometry(kmlSubGeo));
14             }            
15             GeometryCollection gc = geoFactory.createGeometryCollection(geoList.toArray(new com.vividsolutions.jts.geom.Geometry[0]));
16             return gc;
17         }
18         else if(kmlGeo instanceof de.micromata.opengis.kml.v_2_2_0.Point){
19             double dLong = ((de.micromata.opengis.kml.v_2_2_0.Point)kmlGeo).getCoordinates().get(0).getLongitude();
20             double dLat = ((de.micromata.opengis.kml.v_2_2_0.Point)kmlGeo).getCoordinates().get(0).getLatitude();
21             return geoFactory.createPoint(new Coordinate(dLong, dLat));
22         }
23         else if(kmlGeo instanceof LineString){
24             List<Coordinate> geoCoords = new ArrayList<Coordinate>();
25 
26             List<de.micromata.opengis.kml.v_2_2_0.Coordinate> coordList = ((LineString)kmlGeo).getCoordinates();
27             for(de.micromata.opengis.kml.v_2_2_0.Coordinate kmlCoord : coordList){
28                 double dLong = kmlCoord.getLongitude();
29                 double dLat = kmlCoord.getLatitude();
30                 geoCoords.add(new Coordinate(dLong, dLat));
31             }            
32             return geoFactory.createLineString(geoCoords.toArray(new Coordinate[0]));
33         }
34         else if(kmlGeo instanceof LinearRing){
35             List<Coordinate> geoCoords = new ArrayList<Coordinate>();
36             List<de.micromata.opengis.kml.v_2_2_0.Coordinate> coordList = ((LinearRing)kmlGeo).getCoordinates();
37             for(de.micromata.opengis.kml.v_2_2_0.Coordinate kmlCoord : coordList){
38                 double dLong = kmlCoord.getLongitude();
39                 double dLat = kmlCoord.getLatitude();
40                 geoCoords.add(new Coordinate(dLong, dLat));
41             }
42             return geoFactory.createLinearRing(geoCoords.toArray(new Coordinate[0]));
43         }
44         else if(kmlGeo instanceof Polygon){
45             List<com.vividsolutions.jts.geom.LinearRing> holes = new ArrayList<com.vividsolutions.jts.geom.LinearRing>();
46             com.vividsolutions.jts.geom.LinearRing shell = convertLinearRing(geoFactory, ((Polygon)kmlGeo).getOuterBoundaryIs().getLinearRing());
47             List<Boundary> innerBoundaryList = ((Polygon)kmlGeo).getInnerBoundaryIs();
48             for(Boundary inner : innerBoundaryList){
49                 holes.add(convertLinearRing(geoFactory,inner.getLinearRing()));
50             }
51             return geoFactory.createPolygon(shell, holes.toArray(new com.vividsolutions.jts.geom.LinearRing[0]));
52         }
53         else{
54             throw new IllegalArgumentException("Unrecognized geometry type: " + kmlGeo);
55         }
56     }
57     private com.vividsolutions.jts.geom.LinearRing convertLinearRing(GeometryFactory geoFactory, LinearRing geometry){
58         List<Coordinate> geoCoords = new ArrayList<Coordinate>();
59         List<de.micromata.opengis.kml.v_2_2_0.Coordinate> coordList = (geometry).getCoordinates();
60         for(de.micromata.opengis.kml.v_2_2_0.Coordinate kmlCoord : coordList){
61             double dLong = kmlCoord.getLongitude();
62             double dLat = kmlCoord.getLatitude();
63             geoCoords.add(new Coordinate(dLong, dLat));
64         }
65         return geoFactory.createLinearRing(geoCoords.toArray(new Coordinate[0]));
66 
67     }

 

 

 

posted @ 2018-03-21 15:13  GISer-Li  阅读(2058)  评论(0编辑  收藏  举报