diff --git a/pom.xml b/pom.xml index b9a7e15..cdf70de 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,7 @@ 2.0.4 4.4.3 0.4.0 + 28.2 @@ -255,8 +256,97 @@ 1.13.1 + + org.geotools + gt-xml + ${geotools.version} + + + + org.geotools + gt-shapefile + ${geotools.version} + + + + org.geotools + gt-main + ${geotools.version} + + + jts-core + org.locationtech.jts + + + + + + org.geotools.xsd + gt-xsd-sld + ${geotools.version} + + + + org.geotools + gt-swing + ${geotools.version} + + + jts-core + org.locationtech.jts + + + guava + com.google.guava + + + + + + org.geotools + gt-geojson + ${geotools.version} + + + + org.geotools + gt-epsg-hsql + ${geotools.version} + + + + org.geotools.jdbc + gt-jdbc-postgis + ${geotools.version} + + + + + osgeo + OSGeo Release Repository + https://repo.osgeo.org/repository/release/ + + false + + + true + + + + osgeo-snapshot + OSGeo Snapshot Repository + https://repo.osgeo.org/repository/snapshot/ + + true + + + false + + + + diff --git a/src/main/java/com/xkrs/utilsnew/BufferAnalysisUtils.java b/src/main/java/com/xkrs/utilsnew/BufferAnalysisUtils.java new file mode 100644 index 0000000..01e4472 --- /dev/null +++ b/src/main/java/com/xkrs/utilsnew/BufferAnalysisUtils.java @@ -0,0 +1,123 @@ +package com.xkrs.utilsnew; + +import org.apache.hc.core5.util.TextUtils; +import org.geotools.data.simple.SimpleFeatureCollection; +import org.geotools.data.simple.SimpleFeatureIterator; +import org.geotools.filter.text.cql2.CQL; +import org.geotools.filter.text.cql2.CQLException; +import org.locationtech.jts.geom.*; +import org.locationtech.jts.operation.buffer.BufferParameters; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.filter.Filter; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class BufferAnalysisUtils { + + + private BufferAnalysisUtils() { + } + + public static void main(String[] args) throws CQLException { + String shapeFilePath = "/Users/liuchengqian/Desktop/data/shandong_land_type_2022.shp"; + SimpleFeatureCollection simpleFeatureCollection = ShpFileUtils.readShpFileFeatureCollection(shapeFilePath); + double longitude = 116.218;//经度 + double latitude = 36.0852;//纬度 + double distance = getBufferDistance(1500L);// buffer 宽度 1.5公里 + GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(PrecisionModel.FLOATING), 4326); + Coordinate[] coordinates = new Coordinate[]{new Coordinate(longitude, latitude)}; + Point point = new Point(geometryFactory.getCoordinateSequenceFactory().create(coordinates), geometryFactory); + Geometry pointBuffer = point.buffer(distance, 40, BufferParameters.CAP_ROUND); + String pointBufferWkt = pointBuffer.toText(); + double pointBufferArea = pointBuffer.getArea();//总面积 + // 相交过滤 + Filter intersectsFilter = CQL.toFilter(String.format("INTERSECTS(the_geom, %s)", pointBufferWkt)); + SimpleFeatureCollection filterSimpleFeatureCollection = simpleFeatureCollection.subCollection(intersectsFilter); + //地物类型对应的字段 + String landTypeProperty = "tblxmc"; + String defaultLandType = "其它"; + List targetLandTypeList = new ArrayList<>(); + targetLandTypeList.add("林地"); + targetLandTypeList.add("农作物"); + targetLandTypeList.add("水域"); + targetLandTypeList.add("建筑物"); + targetLandTypeList.add("水产养殖设施农用地"); +// targetLandTypeList.add("其他土地"); + Map targetLandTypeAreaMap = new HashMap<>(); + for (String targetLandType : targetLandTypeList) { + targetLandTypeAreaMap.put(targetLandType, 0D); + } + SimpleFeatureIterator featureIterator = filterSimpleFeatureCollection.features(); + while (featureIterator.hasNext()) { + try { + SimpleFeature simpleFeature = featureIterator.next(); + if (simpleFeature == null) { + System.out.println("simpleFeature == null"); + continue; + } + Geometry geometry = (Geometry) simpleFeature.getDefaultGeometry(); + if (geometry == null) { + System.out.println("geometry == null"); + continue; + } + String landType = simpleFeature.getProperty(landTypeProperty).getValue().toString().trim(); + if (TextUtils.isEmpty(landType) || (!targetLandTypeAreaMap.containsKey(landType))) { + System.out.println("!targetLandTypeMap.containsKey(landType), landType = " + landType); + continue; + } + // 检查多边形是否存在自相交或重叠的情况,如果有则修复 + Geometry geometryBuffer = geometry.buffer(0D); + if (!pointBuffer.intersects(geometryBuffer)) { + System.out.println("!pointBuffer.intersects(geometryBuffer)"); + continue; + } + Geometry intersectGeometry = pointBuffer.intersection(geometryBuffer); + if (intersectGeometry == null) { + System.out.println("intersectGeometry == null"); + continue; + } + double intersectArea = intersectGeometry.getArea(); + if (intersectArea < 0D) { + System.out.println("intersectArea < 0"); + continue; + } + targetLandTypeAreaMap.put(landType, targetLandTypeAreaMap.get(landType) + intersectArea); + } catch (Exception e) { + e.printStackTrace(); + } + } + double targetLandAreaSum = 0D; + StringBuilder builder = new StringBuilder(); + for (String targetLandType : targetLandTypeList) { + double currentArea = targetLandTypeAreaMap.get(targetLandType); + targetLandAreaSum += currentArea; + builder.append(targetLandType); + builder.append("="); + builder.append(formatDoublePer(currentArea / pointBufferArea)); + builder.append(", "); + } + builder.append(defaultLandType); + builder.append("="); + builder.append(formatDoublePer((pointBufferArea - targetLandAreaSum) / pointBufferArea)); + String result = builder.toString(); + System.out.println(result); + } + + + public static final int RADIUS = 6377830; + + private static double getBufferDistance(long meter) { + return meter * 180.D / Math.PI / RADIUS; + } + + private static final DecimalFormat decimalFormat = new DecimalFormat("0.00"); + + private static String formatDoublePer(double value) { + return decimalFormat.format(Math.abs(value) * 100D) + "%"; + } + +} diff --git a/src/main/java/com/xkrs/utilsnew/ShpFileUtils.java b/src/main/java/com/xkrs/utilsnew/ShpFileUtils.java new file mode 100644 index 0000000..717b574 --- /dev/null +++ b/src/main/java/com/xkrs/utilsnew/ShpFileUtils.java @@ -0,0 +1,50 @@ +package com.xkrs.utilsnew; + +import org.geotools.data.FeatureSource; +import org.geotools.data.Query; +import org.geotools.data.shapefile.ShapefileDataStore; +import org.geotools.data.simple.SimpleFeatureCollection; +import org.geotools.geometry.jts.ReferencedEnvelope; +import org.opengis.feature.type.AttributeDescriptor; +import org.opengis.feature.type.GeometryType; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.List; + +public class ShpFileUtils { + + private ShpFileUtils() { + } + + public static SimpleFeatureCollection readShpFileFeatureCollection(String shpPath) { + File shpFile = new File(shpPath); + SimpleFeatureCollection simpleFeatureCollection = null; + try { + ShapefileDataStore shapefileDataStore = new ShapefileDataStore(shpFile.toURI().toURL()); + // 设置编码,防止属性的中文字符出现乱码 + shapefileDataStore.setCharset(StandardCharsets.UTF_8); + // 这个typeNamae不传递,默认是文件名称 + FeatureSource featuresource = shapefileDataStore.getFeatureSource(shapefileDataStore.getTypeNames()[0]); + // 读取bbox + ReferencedEnvelope bbox = featuresource.getBounds(); + // 读取投影 + CoordinateReferenceSystem crs = featuresource.getSchema().getCoordinateReferenceSystem(); + // 特征总数 + int count = featuresource.getCount(Query.ALL); + // 获取当前数据的geometry类型(点、线、面) + GeometryType geometryType = featuresource.getSchema().getGeometryDescriptor().getType(); + // 读取要素 + simpleFeatureCollection = (SimpleFeatureCollection) featuresource.getFeatures(); + // 获取当前矢量数据有哪些属性字段值 + List attributes = simpleFeatureCollection.getSchema().getAttributeDescriptors(); + + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("读取完成!"); + return simpleFeatureCollection; + } +}