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,不再赘述);

     /*
* Kml to FeatureCollection
*/
private void processKml(Kml kml, String typeName){
try{
Feature kmlFeature = kml.getFeature();
if(kmlFeature instanceof Document){
Document doc = (Document)kmlFeature; List<Feature> folderList = doc.getFeature();
for(Feature folder: folderList){
if(folder instanceof Folder){
//one Folder to one SimpleFeatureCollection
//get Field info
List<String> typeSpec = new ArrayList<String>();
typeSpec.add("the_geom:Point:srid="+ SRID);// <- the geometry attribute: Point type
typeSpec.add("name:String");
List<SimpleField> simpleFields = doc.getSchema().get(0).getSimpleField();
for(SimpleField simField : simpleFields){
String fieldType = simField.getType();
String fieldName = simField.getName();
typeSpec.add(fieldName + ":" + fieldType);
}
if(CreateCluster)//add Field:cluster
typeSpec.add("cluster:String");
String typeSpecs = String.join(",", typeSpec);
final SimpleFeatureType TYPE = DataUtilities.createType(typeName,
typeSpecs // all attributes
); SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
/*
* We create a FeatureCollection into which we will put each Feature created from a record
* in the input csv data file
*/
ListFeatureCollection collection = new ListFeatureCollection(TYPE); List<Feature> placeList = ((Folder) folder).getFeature();
for(Feature place: placeList){
if(place instanceof Placemark){
Geometry kmlGeo = ((Placemark)place).getGeometry();
com.vividsolutions.jts.geom.Geometry jtsGeom = toJTSGeometry(kmlGeo);
featureBuilder.add(jtsGeom);
//Placemark name value
featureBuilder.add(((Placemark)place).getName()); ExtendedData exData = ((Placemark)place).getExtendedData();
List<SimpleData> simDatas = exData.getSchemaData().get(0).getSimpleData();
for(SimpleData sData : simDatas){
featureBuilder.add(sData.getValue());
}
if(CreateCluster)
featureBuilder.add(""); //add cluster field value
SimpleFeature feature = featureBuilder.buildFeature(null);
collection.add(feature);
}
}
// write to shapefile
writeShapeFile(collection);
}
}
}
}
catch(Exception ex){
throw new IllegalArgumentException("KML parse error: " + ex.getMessage());
}
}
注意:toJTSGeometry函数用于将Kml封装的Geometry类转换为JTS库里的Geometry类。
 /*
* de.micromata.opengis.kml.v_2_2_0.Geometry transform to com.vividsolutions.jts.geom.Geometry
*/
private com.vividsolutions.jts.geom.Geometry toJTSGeometry(Geometry kmlGeo){
if(kmlGeo == null)
return null; GeometryFactory geoFactory = JTSFactoryFinder.getGeometryFactory(null);
if(kmlGeo instanceof MultiGeometry){
List<com.vividsolutions.jts.geom.Geometry> geoList = new ArrayList<com.vividsolutions.jts.geom.Geometry>();
List<Geometry> kmlGeoList = ((MultiGeometry)kmlGeo).getGeometry();
for(Geometry kmlSubGeo : kmlGeoList){
geoList.add(toJTSGeometry(kmlSubGeo));
}
GeometryCollection gc = geoFactory.createGeometryCollection(geoList.toArray(new com.vividsolutions.jts.geom.Geometry[0]));
return gc;
}
else if(kmlGeo instanceof de.micromata.opengis.kml.v_2_2_0.Point){
double dLong = ((de.micromata.opengis.kml.v_2_2_0.Point)kmlGeo).getCoordinates().get(0).getLongitude();
double dLat = ((de.micromata.opengis.kml.v_2_2_0.Point)kmlGeo).getCoordinates().get(0).getLatitude();
return geoFactory.createPoint(new Coordinate(dLong, dLat));
}
else if(kmlGeo instanceof LineString){
List<Coordinate> geoCoords = new ArrayList<Coordinate>(); List<de.micromata.opengis.kml.v_2_2_0.Coordinate> coordList = ((LineString)kmlGeo).getCoordinates();
for(de.micromata.opengis.kml.v_2_2_0.Coordinate kmlCoord : coordList){
double dLong = kmlCoord.getLongitude();
double dLat = kmlCoord.getLatitude();
geoCoords.add(new Coordinate(dLong, dLat));
}
return geoFactory.createLineString(geoCoords.toArray(new Coordinate[0]));
}
else if(kmlGeo instanceof LinearRing){
List<Coordinate> geoCoords = new ArrayList<Coordinate>();
List<de.micromata.opengis.kml.v_2_2_0.Coordinate> coordList = ((LinearRing)kmlGeo).getCoordinates();
for(de.micromata.opengis.kml.v_2_2_0.Coordinate kmlCoord : coordList){
double dLong = kmlCoord.getLongitude();
double dLat = kmlCoord.getLatitude();
geoCoords.add(new Coordinate(dLong, dLat));
}
return geoFactory.createLinearRing(geoCoords.toArray(new Coordinate[0]));
}
else if(kmlGeo instanceof Polygon){
List<com.vividsolutions.jts.geom.LinearRing> holes = new ArrayList<com.vividsolutions.jts.geom.LinearRing>();
com.vividsolutions.jts.geom.LinearRing shell = convertLinearRing(geoFactory, ((Polygon)kmlGeo).getOuterBoundaryIs().getLinearRing());
List<Boundary> innerBoundaryList = ((Polygon)kmlGeo).getInnerBoundaryIs();
for(Boundary inner : innerBoundaryList){
holes.add(convertLinearRing(geoFactory,inner.getLinearRing()));
}
return geoFactory.createPolygon(shell, holes.toArray(new com.vividsolutions.jts.geom.LinearRing[0]));
}
else{
throw new IllegalArgumentException("Unrecognized geometry type: " + kmlGeo);
}
}
private com.vividsolutions.jts.geom.LinearRing convertLinearRing(GeometryFactory geoFactory, LinearRing geometry){
List<Coordinate> geoCoords = new ArrayList<Coordinate>();
List<de.micromata.opengis.kml.v_2_2_0.Coordinate> coordList = (geometry).getCoordinates();
for(de.micromata.opengis.kml.v_2_2_0.Coordinate kmlCoord : coordList){
double dLong = kmlCoord.getLongitude();
double dLat = kmlCoord.getLatitude();
geoCoords.add(new Coordinate(dLong, dLat));
}
return geoFactory.createLinearRing(geoCoords.toArray(new Coordinate[0])); }

 

geoserver源码学习与扩展——kml/kmz转shapefile文件的更多相关文章

  1. geoserver源码学习与扩展——跨域访问配置

    在 geoserver源码学习与扩展——restAPI访问 博客中提到了geoserver的跨域参数设置,本文详细讲一下geoserver的跨域访问配置. geoserver的跨域访问依赖java-p ...

  2. geoserver源码学习与扩展——restAPI访问

    产生这篇文章的想法是在前端通过js调用restAPI时,总是不成功,发送ajax请求时还总是出现类似跨域的问题,后来查找才发现,默认情况下restAPI的访问都需要管理员权限,而通过ajax请求传输用 ...

  3. geoserver源码学习与扩展——自动发布shapefile图层

    geoserver通过工作空间Workspace-数据源DataStore-图层Layer管理地理数据,这些信息都通过Catalog进行组织和管理,要完成自动发布只需要在Catalog中增加相应的信息 ...

  4. geoserver源码学习与扩展——增加服务接口

    参看:http://www.cnblogs.com/sillyemperor/archive/2011/01/11/1929420.html 上文写的很详细了.

  5. geoserver源码学习与扩展——CSV转shapefile文件

    基于geotools实现csv转换为shapefile文件. 1.读取CSV文件,将其装入FeatureCollection: 2.利用ShapefileDumper类将FeatureCollecti ...

  6. MVC系列——MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)

    前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配.再到控制器的激活,再到Action的执行这些个过程.今天还是趁热打铁,将我们的View也来完善下,也让整个系列相对完整,博主不希望烂尾. ...

  7. MVC系列——MVC源码学习:打造自己的MVC框架(三:自定义路由规则)

    前言:上篇介绍了下自己的MVC框架前两个版本,经过两天的整理,版本三基本已经完成,今天还是发出来供大家参考和学习.虽然微软的Routing功能已经非常强大,完全没有必要再“重复造轮子”了,但博主还是觉 ...

  8. MVC系列——MVC源码学习:打造自己的MVC框架(一:核心原理)

    前言:最近一段时间在学习MVC源码,说实话,研读源码真是一个痛苦的过程,好多晦涩的语法搞得人晕晕乎乎.这两天算是理解了一小部分,这里先记录下来,也给需要的园友一个参考,奈何博主技术有限,如有理解不妥之 ...

  9. ddms(基于 Express 的表单管理系统)源码学习

    ddms是基于express的一个表单管理系统,今天抽时间看了下它的代码,其实算不上源码学习,只是对它其中一些小的开发技巧做一些记录,希望以后在项目开发中能够实践下. 数据层封装 模块只对外暴露mod ...

随机推荐

  1. Linux中Oracle的sqlplus下退格和Del键无效的问题解决

    利用rlwrap工具解决方法 1.安装rlwrap和readline库 CentOS下可以用EPEL的yum源直接安装,步骤如下: (1)RHEL/CentOS/SL Linux 6.x 下安装 EP ...

  2. Contos更换python版本

    1.查看版本 #python -VPython 2.6.6 2.安装前准备,安装相关库#yum install gcc gcc-c++ autoconf automake#yum install op ...

  3. django博客项目4:博客首页视图(1)

    Web 应用的交互过程其实就是 HTTP 请求与响应的过程.无论是在 PC 端还是移动端,我们通常使用浏览器来上网,上网流程大致来说是这样的: 我们打开浏览器,在地址栏输入想访问的网址,比如 http ...

  4. rest_framework之访问频率控制

    一  自定义频率控制类 class MyThrottle(): visitor_dic = {} def __init__(self): self.history = None def allow_r ...

  5. Keras网络层之常用层Core

    常用层 常用层对应于core模块,core内部定义了一系列常用的网络层,包括全连接.激活层等 Dense层 keras.layers.core.Dense(units, activation=None ...

  6. springboot接口 接收参数为实体对象跟MultipartFile对象报错。

    要把文件和普通数据类型分开接口传输,不可以兼容多个类型参数, 建议是传文件一个接口,返回url路径,再和普通数据一起提交,就是两次 企业上的做法都是这样,先用文件服务器保存文件,返回文件路径 http ...

  7. Hurst指数以及MF-DFA

    转:https://uqer.io/home/ https://uqer.io/community/share/564c3bc2f9f06c4446b48393 写在前面 9月的时候说想把arch包加 ...

  8. sizeof 是编译时运算符

    typedef char RT1;typedef struct{ char a[2]; } RT2;template<typename T> RT1 test(typename T::X ...

  9. Read Large Files in Python

    I have a large file ( ~4G) to process in Python. I wonder whether it is OK to "read" such ...

  10. (转)HttpWebRequest以UTF-8编码写入内容时发生“Bytes to be written to the stream exceed the Content-Length bytes size specified.”错误

    from:http://www.cnblogs.com/Gildor/archive/2010/12/13/1904060.html HttpWebRequest以UTF-8编码写入内容时发生“Byt ...