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;
+ }
+}