前沿 在java中使用 geotool 工具,首先就是要先把这个依赖下载下来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 <dependency > <groupId > org.geotools</groupId > <artifactId > gt-main</artifactId > <version > ${geotools-version}</version > </dependency > <dependency > <groupId > org.geotools</groupId > <artifactId > gt-geojson</artifactId > <version > ${geotools-version}</version > </dependency > <dependency > <groupId > org.geotools</groupId > <artifactId > gt-geojson-core</artifactId > <version > ${geotools-version}</version > </dependency > <dependency > <groupId > org.geotools.xsd</groupId > <artifactId > gt-xsd-kml</artifactId > <version > ${geotools-version}</version > </dependency > <dependency > <groupId > org.geotools</groupId > <artifactId > gt-shapefile</artifactId > <version > ${geotools-version}</version > </dependency > <repositories > <repository > <id > osgeo</id > <name > Open Source Geospatial Foundation Repository</name > <url > https://repo.osgeo.org/repository/release/</url > </repository > <repository > <id > osgeo-snapshot</id > <name > OSGeo Snapshot Repository</name > <url > https://repo.osgeo.org/repository/snapshot/</url > </repository > </repositories >
参考文章: 【1】.填坑:Maven工程引用GeoTools依赖 将GeoTools对应的编译版本下载下来,并利用《填坑:IDEA导入Maven工程无法下载依赖项》方法,将依赖的jar包注册到本地仓库中。如果你配置了阿里的镜像,可以在自己的maven配置文件修改一下,直接从GeoTools的远程库中下载。 【2】.GeoTools依赖使用Maven下载失败解决办法记录 方法一:直接去官网下载,然后手动拷贝到本地仓库对应位置,然后点击idea中右侧的重新加载maven项目。方法二(推荐):在pom.xml中加入osgeo的仓库地址(注意setting中阿里云镜像的参数应为central ):方法三:在Maven的settings.xml中阿里镜像同级位置添加osgeo仓库地址,(osgeo-snapshot、GeoSolutions也可参考下面的方法,此方法貌似不对,但是能解决一部分人jar下载失败的问题)
1.kml转geojson 为了将 kml 转成 geojson ,我用了这两个库,结果就是很多的问题,首先就是引入的问题。
参考文章: 【1】.java使用geotools解析矢量数据kml、geojson、shp文件 【2】.springboot kml转geojson依赖(包含类型转换) 【3】.KML转Geojson
2.shape转geojson 参考文章: 【1】.java 使用GeoTools工具 geojson 与shp 相互转换 这个代码就可以直接运行,其实大同小异的 【2】.利用geotools实现Shapefile和GeoJSON相互转换 【3】.使用GeoTools进行GeoJSON和Shp的互相转换
3.通过坐标点生成LineString 参考文章: 【1】.通过坐标点生成geojson格式的Polygon文件(Java)
4.生成缓冲区 根据 geojson 格式的线数据,生成缓冲区,经过长时间的尝试,最后我还是搞定了代码,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 private String createBuff (String xcgj) { StringWriter writer=new StringWriter (); try { GeoJSONReader reader=new GeoJSONReader (xcgj); SimpleFeatureCollection featureCollection = reader.getFeatures(); SimpleFeatureType featureType = DataUtilities.createType("MultiPolygon" , "the_geom:MultiPolygon:srid=4326," + "name:String" ); SimpleFeatureIterator features = featureCollection.features(); List<SimpleFeature> targetFeatures=new ArrayList <>(); while (features.hasNext()) { SimpleFeature feature = features.next(); Geometry defaultGeometry = (Geometry) feature.getDefaultGeometry(); Geometry buff=defaultGeometry.buffer(buff_distance); SimpleFeatureBuilder featureBuilder=new SimpleFeatureBuilder (featureType); SimpleFeature buffFeature=featureBuilder.buildFeature(feature.getID()); buffFeature.setAttributes(feature.getAttributes()); buffFeature.setDefaultGeometry(buff); targetFeatures.add(buffFeature); } features.close(); SimpleFeatureCollection targetCollection=new ListFeatureCollection (featureType,targetFeatures); FeatureJSON featureJSON=new FeatureJSON (); featureJSON.writeFeatureCollection(targetCollection,writer); }catch (Exception e){ log.error("createBuff" ,e); } return writer.toString(); }
这里有一个问题,如果线有交叉的时候,生成的buffer就会出现空洞的情况,但是在arcgis中却没有产生空洞。
最后我还是用了一个 凸壳分析 (ConvexHull),将这个破洞补上了。
1 2 3 4 Geometry buff=defaultGeometry.buffer(buff_distance); buff=buff.convexHull();
参考文章: 【1】.GeoTools解析GeoJson为要素集(FeatureCollection)含嵌套数组属性 这里有所有的要素类型,遍历要素属性,获取指定属性信息功能。 【2】.gis地理数据处理:geotools将多个线段生成buffer并融合成多边形 这里使用 geometry.buffer(distance) 创建了buffer。 【3】.读写shp等空间数据,进行geometry、SimpleFeature等转换的工具类 这里有 simplefeature 转为 geometry 的方法 【4】.【geotool】wkt、geojson、geometry互相转换 【5】.GeoTools 构建线的缓冲区 BufferOp bufOp = new BufferOp(gfLineString) 【6】.Geotools创建Feature的两种方式 1.SimpleFeatureBuilder方式创建;2.getFeatureWriter方式创建; 【7】.【geotools随笔】FeatureType的创建与修改 这里我参考了 DataUtilities.createType 的创建。 【8】.GeoTools:Shapefile创建 这里其实也有 SimpleFeatureType 接口的说明。ShapefileDataStoreFactory类、ShapefileDataStore类、创建Shapefile文件实示例 【9】.计算JTS缓冲区面积(Java) 【10】.JTS (Java Topology Suite) 开发教程 联合分析 (Union)、凸壳分析 (ConvexHull)、差异分析 (Difference)、对称差异分析 (SymDifference)、构建不规则三角网 (TIN)、几何体致密化 (Densify) 【11】.JTS的buffer支持CAP的样式 【12】.JTS Geometry Operations(二) Buffer,返回的结果是一个Polygon或者 MultiPolygon,注意:bufOp.setEndCapStyle 缓冲样式的设置,总共有三种CAP_ROUND,CAP_BUTT,CAP_SQUARE 对应如下三种情况
5.计算面积 计算面积的方法很简单,就是使用 getArea() 方法获取面积
1 2 3 Geometry defaultGeometry = (Geometry) feature.getDefaultGeometry();defaultGeometry.setSRID(4326 ); result=defaultGeometry.getArea();
计算投影坐标系,就是将 4326 的坐标系转为了 3857 坐标系,然后计算了面积。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 Geometry defaultGeometry = (Geometry) feature.getDefaultGeometry();defaultGeometry.setSRID(4326 ); final String strWKTMercator = "PROJCS[\"World_Mercator\"," + "GEOGCS[\"GCS_WGS_1984\"," + "DATUM[\"WGS_1984\"," + "SPHEROID[\"WGS_1984\",6378137,298.257223563]]," + "PRIMEM[\"Greenwich\",0]," + "UNIT[\"Degree\",0.017453292519943295]]," + "PROJECTION[\"Mercator_1SP\"]," + "PARAMETER[\"False_Easting\",0]," + "PARAMETER[\"False_Northing\",0]," + "PARAMETER[\"Central_Meridian\",0]," + "PARAMETER[\"latitude_of_origin\",0]," + "UNIT[\"Meter\",1]]" ; CoordinateReferenceSystem mercatroCRS = CRS.parseWKT(strWKTMercator);MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, mercatroCRS);defaultGeometry= JTS.transform(defaultGeometry, transform); double area=defaultGeometry.getArea();CoordinateReferenceSystem source = null ;source = CRS.decode("CRS:84" ); CoordinateReferenceSystem target = null ;target = CRS.decode("EPSG:3857" ); MathTransform transform = null ;transform = CRS.findMathTransform(source, target, true ); Geometry transformGeom= null ; transformGeom = JTS.transform(defaultGeometry, transform); double area = transformGeom.getArea();CoordinateReferenceSystem srcCRS = CRS.decode("EPSG:4326" );CoordinateReferenceSystem crsTarget = CRS.decode("EPSG:3857" );MathTransform transform = CRS.findMathTransform(crsTarget,srcCRS,true );Geometry res = JTS.transform(defaultGeometry, transform);double area=defaultGeometry.getArea();
参考文章: 【1】.java geotools 计算面积 这里直接用 polygon.getArea() 计算的面积。 【2】.利用geoTools计算shp面积 【3】.GIS面积计算 【4】.根据wkt或geometry计算面积(平方米) 这里进行了投影转换,将84坐标转为了3857坐标。 【5】.经纬度坐标和投影坐标的转换 【6】.geotools之坐标转换 【7】.利用geoTools计算shp面积 这里也做了一个坐标变换,使用了shp文件坐标系,转为了 3857 坐标系。 【8】.Class Geometry
6.合并多边形 这里我是将多个 geomtry 合并到一个 list 中,然后进行合并的。这些 geomtry 可能相邻,也可能不相邻。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 try { Geometry[] geos= xcfwGeomList.toArray(new Geometry [xcfwGeomList.size()]); GeometryFactory geometryFactory = new GeometryFactory (); GeometryCollection geometryCollection = geometryFactory.createGeometryCollection(geos); Geometry resultGeom=geometryCollection.union(); SimpleFeatureType featureType = DataUtilities.createType("MultiPolygon" , "the_geom:MultiPolygon:srid=4326," + "name:String" ); SimpleFeatureBuilder featureBuilder=new SimpleFeatureBuilder (featureType); SimpleFeature buffFeature=featureBuilder.buildFeature("10000" ); buffFeature.setDefaultGeometry(resultGeom); StringWriter writer = new StringWriter (); writer.append("{\"type\": \"FeatureCollection\",\"features\":[" ); FeatureJSON geojson = new FeatureJSON (); geojson.writeFeature(buffFeature, writer); writer.append("]}" ); result.put("buffer" ,writer.toString()); }catch (Exception e){ log.error("getReport" ,e); }
参考文章: 【1】.使用Geotools合并多个Geometry成一个图形 1.在geometry数量少的情况下可以直接循环调用geometry的union方法。2.在geometry数量比较多的时候用上面的方法会比较耗时,可以改用GeometryCollection进行合并。 【2】.java List和数组相互转换方法 这是arraylist转换的方法 【3】.GeoTools测试几何合并union 这里有相邻和不相邻的图形合并。 【4】.Geotools中Geometry对象与GeoJson的相互转换 【5】.Java将WKT格式的Geomotry转换成GeoJSON 【6】.JTS-Geometry使用说明 创建多边形:GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
7.抽稀 自带了抽稀算法,不一定好用。
1 2 3 4 5 Geometry polyline=new GeometryFactory ().createLineString(polygonCoordinateList.toArray(new Coordinate [0 ])); double distance=5 *200 /Math.PI/6371000 ;polyline=DouglasPeuckerSimplifier.simplify(polyline,distance);
参考文章: 【1】.使用Java对轨迹进行抽稀,并生成mvt(Map Vector Tile)瓦片 这里有两种方法,一种就是使用jts算法,一种是自己实现了的道格拉斯算法。 【2】.JTS-Java图形拓扑学习笔记 没啥用 【3】.简化面 arcgis 简化面操作
8.geojson转为shp 采用参考文章1中的代码,基本上都可以实现,我遇到的问题:class org.geotools.data.directory.DirectoryDataStore cannot be cast to class org.geotools.data.shapefile.ShapefileDataStore (org.geotools.data.directory.DirectoryDataStore and org.geotools.data.shapefile.ShapefileDataStore are in unnamed module of loader ‘app’).
【解决方案】 这个问题的解决方案,就是不要传入一个路径,而是应该传入一个以 .shp 文件结尾的文件。
参考文章: 【1】.使用GeoTools进行GeoJSON和Shp的互相转换 【2】.SpatialDataTransformUtil.java 这里的代码可以用,没有关系,基本上都能用。 【3】.JAVA 超详细 将文件夹目录打包为 ZIP 压缩包并下载