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,不再赘述);
/*
* 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文件的更多相关文章
- geoserver源码学习与扩展——跨域访问配置
在 geoserver源码学习与扩展——restAPI访问 博客中提到了geoserver的跨域参数设置,本文详细讲一下geoserver的跨域访问配置. geoserver的跨域访问依赖java-p ...
- geoserver源码学习与扩展——restAPI访问
产生这篇文章的想法是在前端通过js调用restAPI时,总是不成功,发送ajax请求时还总是出现类似跨域的问题,后来查找才发现,默认情况下restAPI的访问都需要管理员权限,而通过ajax请求传输用 ...
- geoserver源码学习与扩展——自动发布shapefile图层
geoserver通过工作空间Workspace-数据源DataStore-图层Layer管理地理数据,这些信息都通过Catalog进行组织和管理,要完成自动发布只需要在Catalog中增加相应的信息 ...
- geoserver源码学习与扩展——增加服务接口
参看:http://www.cnblogs.com/sillyemperor/archive/2011/01/11/1929420.html 上文写的很详细了.
- geoserver源码学习与扩展——CSV转shapefile文件
基于geotools实现csv转换为shapefile文件. 1.读取CSV文件,将其装入FeatureCollection: 2.利用ShapefileDumper类将FeatureCollecti ...
- MVC系列——MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)
前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配.再到控制器的激活,再到Action的执行这些个过程.今天还是趁热打铁,将我们的View也来完善下,也让整个系列相对完整,博主不希望烂尾. ...
- MVC系列——MVC源码学习:打造自己的MVC框架(三:自定义路由规则)
前言:上篇介绍了下自己的MVC框架前两个版本,经过两天的整理,版本三基本已经完成,今天还是发出来供大家参考和学习.虽然微软的Routing功能已经非常强大,完全没有必要再“重复造轮子”了,但博主还是觉 ...
- MVC系列——MVC源码学习:打造自己的MVC框架(一:核心原理)
前言:最近一段时间在学习MVC源码,说实话,研读源码真是一个痛苦的过程,好多晦涩的语法搞得人晕晕乎乎.这两天算是理解了一小部分,这里先记录下来,也给需要的园友一个参考,奈何博主技术有限,如有理解不妥之 ...
- ddms(基于 Express 的表单管理系统)源码学习
ddms是基于express的一个表单管理系统,今天抽时间看了下它的代码,其实算不上源码学习,只是对它其中一些小的开发技巧做一些记录,希望以后在项目开发中能够实践下. 数据层封装 模块只对外暴露mod ...
随机推荐
- 【BZOJ1283/3550】序列/[ONTAK2010]Vacation 最大费用流
[BZOJ1283]序列 Description 给出一个长度为 的正整数序列Ci,求一个子序列,使得原序列中任意长度为 的子串中被选出的元素不超过K(K,M<=100) 个,并且选出的元素之和 ...
- grunt的简单应用
grunt是干什么的呢,一句话:自动化.对于需要反复重复的任务,例如压缩(minification).编译.单元测试.linting等,自动化工具可以减轻你的劳动,简化你的工作.当你在 Gruntfi ...
- Idea之Tomcat
安装配置 启动 三种方式,run,debug,coverage 面板说明 上面一排 Debugger:debug模式的时候显示方法,调用关系,参数值等, Server:打印日志 ...
- delphi---EHlib第三方插件----TDBGridEH,TDBNumberEditEh,TDBComboBoxEh
一.TDBGridEH 1.多选 行 options->dgMultiSelect 2.列字体改变颜色,OnDrawColumnCell写下方法. if Column.FieldName='价格 ...
- LCS/LIS/LCIS 模板总结
/************************* LCS/LIS/LCIs模板总结: *************************/ /*************************** ...
- ORACLE_SID的查找
SID是System IDentifier的缩写,而ORACLE_SID就是Oracle System Identifier的缩写,在Oracle系统中,ORACLE_SID以环境变量的形式出现,在特 ...
- 程序运行时 0xC0000005: 读取位置 0x00000000 时发生访问冲突 ,可能是 com 组件引入各种问题
在使用com组件事,可能引入很多不是问题的问题,比如CString 定义出运行时出错等等,这些问题解决的办法就是初始化组件 然后释放组件, 在使用组件时,如果仅仅用在按钮事件或者别的mfc 对话框类里 ...
- pandas(五)处理缺失数据和层次化索引
pandas用浮点值Nan表示浮点和非浮点数组中的缺失数据.它只是一个便于被检测的标记而已. >>> string_data = Series(['aardvark','artich ...
- 解释一下python中的赋值运算符
我们将所有的算术运算符和赋值运算符号放在一起展示 a=7 a+=1 print(a) a-=1 print(a) a*=2 print(a) a/=2 print(a) a**=2 print(a) ...
- Shiro理解与总结
Feature Apache Shiro is a comprehensive application security framework with many features. The follo ...