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 ...
随机推荐
- iOS企业开发In House ipa发布流程
这两天需要发布一个ipa放到网上供其他人安装,需要用到企业级开发者账号.在网上查了一下资料,感觉没有一个比较完善的流程,于是决定把整个流程写下来,供大家参考. 首先详细说明一下我们的目标,我们需要发布 ...
- 18.android studio 安装ing
1.首先得FQ,在谷歌中搜索android studio 2.安装时出现的问题. a. 解决方法,重启电脑,进入Bios,找到并将值设置为 :Intel Virtual Technology=Enab ...
- Tunneling protocol
w https://en.wikipedia.org/wiki/Tunneling_protocol
- Career Planning:Developers Best Practices Tutorial
This small tutorial is based on my past 16+ years of experience in software development industry. I ...
- 接口测试工具 — jmeter(数据库操作)
1.导入jdbc jar包 2.配置MySQL连接 3.执行sql语句
- IO 包中的其他类
打印流 PrintWriter 和 PrintWriter 直接操作输入流和文件 序列流 SequenceInputStream 对多个输入流进行合并 操作对象 ObjectInputStream 和 ...
- Android图片加载框架Picasso最全使用教程2
前言 前面我们已经介绍了Picasso的基本用法及如何将一张图片加载到ImageView中,下面我们就利用Picasso在ListView中加载图片;Let’s Go! 一个ListView的简单应用 ...
- Python Static Method
How to define a static method in Python?Demo: #!/usr/bin/python2.7 #coding:utf-8 # FileName: test.py ...
- BCB直接访问硬件端口和物理内存 - WinIO的应用
BCB直接访问硬件端口和物理内存 - WinIO的应用 (读硬盘参数和主板BIOS信息, 支持 Win9x/NT/2k/XP/2003) 关于直接访问端口, 有很多网站很多文章都讨论过, 但总找不到非 ...
- ibatis $与#的区别
在sql配置中比如in(#rewr#) 与in ($rewr$) 在Ibatis中我们使用SqlMap进行Sql查询时需要引用参数,在参数引用中遇到的符号#和$之间的区分为,#可以进行与编译,进行类型 ...