zoukankan      html  css  js  c++  java
  • 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     }
    
    
    
     
  • 相关阅读:
    我们的路该如何走?-序言
    [转贴]给想立志入行网络或已经初入行的朋友的建议(三)
    [转贴]给想立志入行网络或已经初入行的朋友的建议(二)
    为应用程序池defaultAppPool提供服务的进程在于world wide web publishing服务通信时遇到致命错误 进程id为1356. 数据字段包含错误号
    this.get_element .style为空或不是对象
    将linq查询转换为DataTable对象——学习笔记
    ASP.NET 未被授权访问所请求的资源。请考虑授予 ASP.NET 请求标识访问此资源的权限。
    常用改变选中行颜色
    DataTable写入Excel中 用Excel标准格式
    导出Excel出错:检索 COM 类工厂中 CLSID 为 {0002450000000000C000000000000046} 的组件失败
  • 原文地址:https://www.cnblogs.com/HandyLi/p/8616109.html
Copyright © 2011-2022 走看看