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 ...
随机推荐
- orchestrator-Raft集群部署
本文简要说明下orchestrator的Raft集群部署,其实部署很简单主要是好好研究下配置文件的配置,这里我的样例配置文件暂时只适用于我们这块业务 如果您自己使用请根据情况自行修改. 主要通过配置文 ...
- sql---如何把sql查询出来的结果当做另一个sql的条件查询,1、语句2、with as
'; -- table2 的 name 作为 table1的条件 select * from table1 where name in (select name from table2) --如果有多 ...
- 解决EF6中表名变成复数的情况
在用EF6 时,在进行数据调用的时候,总提示数据表名对象错误.. 解决此问题需要在继承DbContext的实体类中 加入: using System; using System.ComponentMo ...
- 看用Tornado如何自定义实现表单验证
我们知道,平时在登陆某个网站或软件时,网站对于你输入的内容是有要求的,并且会对你输入的错误内容有提示,对于Django这种大而全的web框架,是提供了form表单验证功能,但是对于Tornado而言, ...
- Thinkphp的list_to_tree 实现无限级分类列出全部节点
list_to_tree 使用起来十分方便,具体可查看手冊.由于我在用的时候须要同一时候列出全部节点,所以写了一个递归函数,拿出来供大家參考. public function index(){ Loa ...
- mysql 建立表之间关系 练习 1
练习:账号信息表,用户组,主机表,主机组 #用户表 mysql> create table user( id int not null unique auto_increment, userna ...
- rails timeout 异常
发现经常有”超时“的错误信息,如/usr/lib/ruby/1.8/timeout.rb:54:in `rbuf_fill': execution expired (Timeout::Error),恩 ...
- git分支更新代码命令
第一步: 查看状态 git status 第二步: 全部添加 git add --all 第三步: 再次查看状态 git status 第四步: 提交 git commit -m '备 ...
- Oracle 在64位机器上使用plSQL连接Oracle的问题(SQL*Net not properly installed)
问题: 在64位机器上了64位的oracle客户端. 然后装上PL/SQL Developer,但是连接oracle老报这个错: Initialization error SQL*Net n ...
- CNN学习笔记:池化层
CNN学习笔记:池化层 池化 池化(Pooling)是卷积神经网络中另一个重要的概念,它实际上是一种形式的降采样.有多种不同形式的非线性池化函数,而其中“最大池化(Max pooling)”是最为常见 ...