From 8d9a2d656e4ae007590c622e5f7c228adacdca49 Mon Sep 17 00:00:00 2001
From: rain <167982779@qq.com>
Date: Fri, 14 Jun 2024 10:11:36 +0800
Subject: [PATCH] 统一风格

---
 src/main/java/com/dji/sample/patches/utils/GeoToolsUtil.java |  297 ++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 234 insertions(+), 63 deletions(-)

diff --git a/src/main/java/com/dji/sample/patches/utils/GeoToolsUtil.java b/src/main/java/com/dji/sample/patches/utils/GeoToolsUtil.java
index d8899bd..5ea11e8 100644
--- a/src/main/java/com/dji/sample/patches/utils/GeoToolsUtil.java
+++ b/src/main/java/com/dji/sample/patches/utils/GeoToolsUtil.java
@@ -2,13 +2,15 @@
 
 import com.dji.sample.patches.model.entity.LotInfo;
 import org.geotools.geometry.jts.JTSFactoryFinder;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.jts.geom.Envelope;
-import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.*;
 import org.locationtech.jts.io.ParseException;
 import org.locationtech.jts.io.WKTReader;
+import org.locationtech.jts.operation.buffer.BufferOp;
+import org.locationtech.jts.simplify.TopologyPreservingSimplifier;
 
 import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 /**
  * @PROJECT_NAME: drone
@@ -48,77 +50,94 @@
         return extremePoints;
     }
 
-    /**
-     * 航线点排序
-     *
-     * @return
-     */
-    public static Coordinate [] getRoutePointOrder(List<LotInfo> list) {
-        List<Coordinate> centros = new ArrayList<>();
-        List<List<Coordinate>> extremePoints = new ArrayList<>();
-        Map<Coordinate,List<Coordinate>> points = new HashMap<>();
-        list.forEach(patche -> {
-            String wkt = patche.getDkfw();
-            // 解析WKT字符串为多边形
-            WKTReader wktReader = new WKTReader(JTSFactoryFinder.getGeometryFactory());
-            Geometry polygon = null;
-            try {
-                polygon = wktReader.read(wkt);
-            } catch (ParseException e) {
-                throw new RuntimeException(e);
-            }
+    public static Coordinate[] sortCoordinatesByNearestDistance(Coordinate[] coordinates) {
 
-            // 开始封装中心点坐标
-            Coordinate coordinateCentro = getCentro(polygon);
-            centros.add(coordinateCentro);
+        // 将数组转换为List以便操作
+        List<Coordinate> coordinateList = new ArrayList<>(Arrays.asList(coordinates));
 
-            // 开始封装图斑4个航线
-            List<Coordinate> coordinatePointList = getExtremePoints(polygon);
-            extremePoints.add(coordinatePointList);
-            points.put(coordinateCentro,coordinatePointList);
+        // 排序后的坐标列表
+        List<Coordinate> sortedCoordinates = new ArrayList<>();
 
-        });
+        // 如果列表不为空,开始排序
+        if (!coordinateList.isEmpty()) {
+            // 将第一个点添加到排序列表中
+            sortedCoordinates.add(coordinateList.remove(0));
 
-        // 开始排序
-        // 机场经纬度
-        double airportLat = 28.624514734; // 机场纬度
-        double airportLon = 115.856725497; // 机场经度
-        Coordinate [] coordinates = new Coordinate[centros.size() + 1];
-        List<Coordinate> coordinateList = new ArrayList<>();
-        coordinates[0] = new Coordinate(airportLon, airportLat); //第一个为机场经纬度
-        coordinateList.add(new Coordinate(airportLon, airportLat)); //第一个为机场经纬度)
-        for (int i = 1; i < centros.size() + 1; i++) {
-            coordinates[i] = centros.get(i-1);
-            coordinateList.add(centros.get(i-1));
-        }
+            // 循环处理剩余的点
+            while (!coordinateList.isEmpty()) {
+                double minDistance = Double.MAX_VALUE;
+                Coordinate nearest = null;
 
-        // 对中心坐标数组进行排序
-        Coordinate[] retCoordinate = new Coordinate[coordinateList.size()];
-        Coordinate[] sortedCoordinates = DistanceCalculator.sortByDistance(coordinateList, airportLat, airportLon, 0,retCoordinate);
-
-        // 开始拼接图斑点位--按中心坐标数组排序顺序
-        // 长度-3第一个起点只有一个点位
-        Coordinate[] retc = new Coordinate[sortedCoordinates.length * 4 - 3];
-        // 赋值起点
-        retc[0] = sortedCoordinates[0];
-        int i = 0;
-        for (Coordinate num : sortedCoordinates) {
-            List<Coordinate> coordinatePoints = points.get(num);
-            if (null != coordinatePoints) {
-                for (int j = 0; j < coordinatePoints.size(); j++) {
-                    // 开始拼接
-                    retc[i * coordinatePoints.size() + j - 3] = coordinatePoints.get(j);
+                // 查找距离排序列表中最后一个点最近的点
+                for (Coordinate c : coordinateList) {
+                    double distance = DistanceCalculator.distance(sortedCoordinates.get(sortedCoordinates.size() - 1), c);
+                    if (distance < minDistance) {
+                        minDistance = distance;
+                        nearest = c;
+                    }
                 }
-            }
 
-            i++;
+                // 将找到的最近的点添加到排序列表中,并从原始列表中移除它
+                sortedCoordinates.add(nearest);
+                coordinateList.remove(nearest);
+            }
         }
 
-        return retc;
-
+        return sortedCoordinates.toArray(new Coordinate[0]);
 
     }
 
+    /**
+     * 获取拐点坐标(替换上面获取四个航点坐标方法)
+     *
+     * @return
+     */
+    public static List<Coordinate> getSimplifyPolygons(Geometry originalPolygon) {
+
+        List coordinatesList = new ArrayList();
+
+        // 应用抽稀算法,这里使用TopologyPreservingSimplifier作为示例
+        double distanceTolerance = 100.0; // 抽稀的容忍度,根据需要调整
+        Geometry simplifiedGeometry = TopologyPreservingSimplifier.simplify(originalPolygon, distanceTolerance);
+
+        // 转换回Polygon类型(如果需要)
+        Polygon simplifiedPolygon = (Polygon) simplifiedGeometry;
+
+        // 获取简化后的多边形的坐标序列
+        Coordinate[] coordinates = simplifiedPolygon.getCoordinates();
+
+        // 使用自定义Comparator对数组进行排序
+//        Arrays.sort(coordinates, Comparator.comparing(Coordinate::getX).thenComparing(Coordinate::getY));
+
+        // 假设第一个点是起始点
+//        Coordinate startPoint = coordinates[0];
+//
+//        // 使用自定义Comparator对数组进行排序,根据与startPoint的距离升序排序
+//        Arrays.sort(coordinates, Comparator.comparingDouble(c -> DistanceCalculator.distance(startPoint, c)));
+
+        Coordinate[] newCoord = sortCoordinatesByNearestDistance(coordinates);
+
+        // 遍历坐标数组,打印每个坐标点
+        for (Coordinate coord : newCoord) {
+            coordinatesList.add(coord);
+        }
+
+        // 使用Set去除重复项
+        Set<Coordinate> set = new HashSet<>(coordinatesList);
+
+        // 将Set转回List
+        List<Coordinate> uniqueCoordinates = new ArrayList<>(set);
+
+        return uniqueCoordinates;
+    }
+
+    public static int getSimplifyPolygonsNum(Geometry polygon) {
+        // 使用 TopologyPreservingSimplifier 进行抽稀
+        double distanceTolerance = 1.0; // 设置抽稀的容忍度,根据实际需要调整
+        Geometry simplifiedPolygon = TopologyPreservingSimplifier.simplify(polygon, distanceTolerance);
+
+        return simplifiedPolygon.getNumPoints();
+    }
 
     public static void main(String[] args) {
         //测试
@@ -134,7 +153,159 @@
         list.add(LotInfo.builder().dkfw("POLYGON((115.842039042965 28.6314426646115, 115.840992080122 28.631252307731, 115.842324578286 28.6305860586493, 115.843181184248 28.6305860586493, 115.84403779021 28.6304908802091, 115.84394261177 28.6317281999322, 115.842039042965 28.6314426646115))").build());
         list.add(LotInfo.builder().dkfw("POLYGON((115.807011889796 28.623935465138, 115.805869748513 28.6224126100944, 115.810247956764 28.6220318963334, 115.809581707682 28.623935465138, 115.807011889796 28.623935465138))").build());
 
-        getRoutePointOrder(list);
+
+//        list.forEach(patche -> {
+//            String wkt = patche.getDkfw();
+//            // 解析WKT字符串为多边形
+//            WKTReader wktReader = new WKTReader(JTSFactoryFinder.getGeometryFactory());
+//            Geometry polygon = null;
+//            try {
+//                polygon = wktReader.read(wkt);
+//            } catch (ParseException e) {
+//                throw new RuntimeException(e);
+//            }
+//
+//            // 开始封装中心点坐标
+//            Coordinate coordinateCentro = getCentro(polygon);
+//
+//            // 开始封装图斑4个航线
+////            List<Coordinate> coordinatePointList = getExtremePoints(polygon);
+//            List<Coordinate> coordinatePointList = getSimplifyPolygons(polygon);
+//
+//
+//        });
+
+
+        List<PointPO> pointPOS = getRoutePointOrder(list, 28.624514734, 115.856725497);
+
+        for (PointPO c :
+                pointPOS) {
+            System.out.println(c);
+        }
+
+
+    }
+
+    /**
+     * 航线点排序
+     *
+     * @return
+     */
+    public static List<PointPO> getRoutePointOrder(List<LotInfo> list, double airportLat, double airportLon) {
+        List<Coordinate> centros = new ArrayList<>();
+        List<List<Coordinate>> extremePoints = new ArrayList<>();
+        AtomicInteger numSize = new AtomicInteger();
+
+        for (LotInfo patche : list) {
+            String wkt = patche.getDkfw();
+            // 解析WKT字符串为多边形
+            WKTReader wktReader = new WKTReader(JTSFactoryFinder.getGeometryFactory());
+            Geometry polygon = null;
+            try {
+                polygon = wktReader.read(wkt);
+            } catch (ParseException e) {
+                throw new RuntimeException(e);
+            }
+
+            // 开始封装中心点坐标
+            Coordinate coordinateCentro = getCentro(polygon);
+
+            double distance = DistanceCalculator.calculateDistance(airportLat, airportLon, coordinateCentro.y,coordinateCentro.x);
+            // 机场范围,操作机场范围将不生成
+            if (distance * 1000 > 7000) {
+                continue;
+            }
+
+            centros.add(coordinateCentro);
+
+            // 开始封装图斑4个航线
+//            List<Coordinate> coordinatePointList = getExtremePoints(polygon);
+            List<Coordinate> coordinatePointList = getSimplifyPolygons(polygon);
+            extremePoints.add(coordinatePointList);
+//            points.put(coordinateCentro, coordinatePointList);
+
+            // 保存稀释拐点之后总数量
+            numSize.set(numSize.get() + coordinatePointList.size());
+        }
+
+
+        // 开始排序
+        Coordinate[] coordinates = new Coordinate[centros.size() + 1];
+        List<Coordinate> coordinateList = new ArrayList<>();
+        coordinates[0] = new Coordinate(airportLon, airportLat); //第一个为机场经纬度
+        coordinateList.add(new Coordinate(airportLon, airportLat)); //第一个为机场经纬度)
+        for (int i = 1; i < centros.size() + 1; i++) {
+            coordinates[i] = centros.get(i - 1);
+            coordinateList.add(centros.get(i - 1));
+        }
+
+        // 方案一:一个图斑按4个航点规划
+//        // 对中心坐标数组进行排序
+//        Coordinate[] retCoordinate = new Coordinate[coordinateList.size()];
+//        Coordinate[] sortedCoordinates = DistanceCalculator.sortByDistance(coordinateList, airportLat, airportLon, 0, retCoordinate);
+//
+//        // 开始拼接图斑点位--按中心坐标数组排序顺序
+//        // 长度-3第一个起点只有一个点位
+//        Coordinate[] retc = new Coordinate[sortedCoordinates.length * 4 - 3];
+//        // 赋值起点
+//        retc[0] = sortedCoordinates[0];
+//        int i = 0;
+//        for (Coordinate num : sortedCoordinates) {
+//            List<Coordinate> coordinatePoints = points.get(num);
+//            if (null != coordinatePoints) {
+//                for (int j = 0; j < coordinatePoints.size(); j++) {
+//                    // 开始拼接
+//                    retc[i * coordinatePoints.size() + j - 3] = coordinatePoints.get(j);
+//                }
+//            }
+//
+//            i++;
+//        }
+//
+//        return retc;
+
+
+        // 方案二:抽稀,获取拐点
+        Coordinate[] retCoordinate = new Coordinate[coordinateList.size()];
+        List<Coordinate> oldCoordinateList = new ArrayList<>(coordinateList);
+
+        // 获取中心点
+        Coordinate[] sortedCoordinates = DistanceCalculator.sortByDistance(coordinateList, airportLat, airportLon, 0, retCoordinate);
+
+        // 开始拼接图斑点位--按中心坐标数组排序顺序
+        Coordinate[] retc = new Coordinate[numSize.get() + 1];
+        List<PointPO> retcList = new ArrayList<>();
+
+        // 赋值起点
+        retc[0] = sortedCoordinates[0];
+        retcList.add(PointPO.builder().index(0).coordinate(sortedCoordinates[0]).build());
+        List<Integer> indexs = new ArrayList<>();
+
+        // 拿排序前的索引index 根据排序前和排序后的结果匹对------》后期优化
+        for (int i = 1; i < sortedCoordinates.length; i++) {
+            Coordinate c1 = sortedCoordinates[i];
+            for (int j = 1; j < oldCoordinateList.size(); j++) {
+                Coordinate c2 = oldCoordinateList.get(j);
+                if (c1.getX() == c2.getX() && c1.getY() == c2.getY()) {
+                    indexs.add(j - 1);
+                }
+            }
+        }
+
+
+        // 根据排序前的索引按顺序赋值
+        int i = 0;
+        for (Integer index : indexs) {
+            for (Coordinate coordinate : extremePoints.get(index)) {
+                i = i + 1;
+                retc[i] = coordinate;
+                retcList.add(PointPO.builder().index(index).coordinate(coordinate).build());
+            }
+        }
+
+
+        return retcList;
+
     }
 
 }

--
Gitblit v1.9.3