From 595e2bc9f191b4f58aab035cd4731e84ac03db91 Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Fri, 12 Dec 2025 15:09:38 +0800
Subject: [PATCH] 优化禁飞区距离算法

---
 ard-work/src/main/java/com/ard/work/component/websocket/handler/NoFlyDistanceManager.java |   41 ++++++++++++++++++++++++++++++++++-------
 ard-system/src/main/java/com/ard/data/noflyzone/utils/NoFlyZoneUtils.java                 |    5 ++++-
 2 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/ard-system/src/main/java/com/ard/data/noflyzone/utils/NoFlyZoneUtils.java b/ard-system/src/main/java/com/ard/data/noflyzone/utils/NoFlyZoneUtils.java
index e37cba3..b78f29b 100644
--- a/ard-system/src/main/java/com/ard/data/noflyzone/utils/NoFlyZoneUtils.java
+++ b/ard-system/src/main/java/com/ard/data/noflyzone/utils/NoFlyZoneUtils.java
@@ -244,5 +244,8 @@
         return vertexes;
     }
 
-
+    public static double degDistanceToMeter(double deg, double lat) {
+        // 1° ≈ 111320 米,但是经度和纬度不一样,这里用纬度做修正
+        return deg * 111320.0 * Math.cos(Math.toRadians(lat));
+    }
 }
diff --git a/ard-work/src/main/java/com/ard/work/component/websocket/handler/NoFlyDistanceManager.java b/ard-work/src/main/java/com/ard/work/component/websocket/handler/NoFlyDistanceManager.java
index 52a3a6e..70aced6 100644
--- a/ard-work/src/main/java/com/ard/work/component/websocket/handler/NoFlyDistanceManager.java
+++ b/ard-work/src/main/java/com/ard/work/component/websocket/handler/NoFlyDistanceManager.java
@@ -41,19 +41,26 @@
             ArdNoFlyBox box = zone.getArdNoFlyBox();
             if (box == null) continue;
 
-            // 包围盒快速排除
-            if (current.x < box.getMinx() || current.x > box.getMaxx() ||
-                    current.y < box.getMiny() || current.y > box.getMaxy()) {
+            // ⭐ 外扩 50 米
+            ArdNoFlyBox expanded = expandBoxByMeter(box, 50);
+
+            // ⭐ 包围盒快速排除必须使用 expanded,而不是 box
+            if (current.x < expanded.getMinx() || current.x > expanded.getMaxx() ||
+                    current.y < expanded.getMiny() || current.y > expanded.getMaxy()) {
                 continue;
             }
 
+            // 计算 polygon 距离
             List<Vertex> polygon = zone.getVertices();
             if (polygon == null || polygon.size() < 3) continue;
 
-            double distance = NoFlyZoneUtils.pointToPolygonDistance(current, polygon);
+            double distanceDeg = NoFlyZoneUtils.pointToPolygonDistance(current, polygon);
 
-            if (distance < minDistance) {
-                minDistance = distance;
+            // ⭐ 转成米
+            double distanceMeter = NoFlyZoneUtils.degDistanceToMeter(distanceDeg, current.y);
+
+            if (distanceMeter < minDistance) {
+                minDistance = distanceMeter;
                 nearestZone = zone;
             }
         }
@@ -63,9 +70,26 @@
         return NoFlyDistanceDTO.builder()
                 .boxSn(boxSn)
                 .zoneName(nearestZone.getName())
-                .distance(minDistance)
+                .distance(minDistance)              // 米
                 .inNoFlyZone(minDistance == 0)
                 .build();
+    }
+
+    // 外扩包围盒多少米
+    private ArdNoFlyBox expandBoxByMeter(ArdNoFlyBox box, double meter) {
+
+        // 计算经纬度偏移
+        double latShift = meter / 111320.0;  // 纬度方向
+        double lngShift = meter / (111320.0 * Math.cos(Math.toRadians(
+                (box.getMiny() + box.getMaxy()) / 2
+        ))); // 经度方向与纬度相关
+
+        return new ArdNoFlyBox(
+                box.getMinx() - lngShift,
+                box.getMiny() - latShift,
+                box.getMaxx() + lngShift,
+                box.getMaxy() + latShift
+        );
     }
 
 
@@ -73,4 +97,7 @@
     protected String getMessageType() {
         return "noFlyZoneDistance";
     }
+
+
+
 }

--
Gitblit v1.9.3