liusuyi
2025-12-12 595e2bc9f191b4f58aab035cd4731e84ac03db91
ard-system/src/main/java/com/ard/data/noflyzone/utils/NoFlyZoneUtils.java
@@ -15,6 +15,72 @@
public class NoFlyZoneUtils {
    /**
     * 计算点到多边形的最近距离
     */
    public static double pointToPolygonDistance(Vertex point, List<Vertex> polygon) {
        // 如果在多边形内部,距离为 0
        if (isPointInPolygon(point, polygon)) {
            return 0;
        }
        double minDistance = Double.MAX_VALUE;
        int n = polygon.size();
        for (int i = 0; i < n; i++) {
            Vertex a = polygon.get(i);
            Vertex b = polygon.get((i + 1) % n); // 下一点,最后一条边连接第一个点
            double dist = pointToSegmentDistance(point, a, b);
            minDistance = Math.min(minDistance, dist);
        }
        return minDistance;
    }
    /**
     * 计算点到线段的距离
     */
    public static double pointToSegmentDistance(Vertex p, Vertex a, Vertex b) {
        double x = p.x, y = p.y;
        double x1 = a.x, y1 = a.y;
        double x2 = b.x, y2 = b.y;
        double dx = x2 - x1;
        double dy = y2 - y1;
        if (dx == 0 && dy == 0) {
            // A 和 B 是同一个点
            dx = x - x1;
            dy = y - y1;
            return Math.sqrt(dx * dx + dy * dy);
        }
        // 投影参数 t(0-1之间表示在线段内部)
        double t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);
        if (t < 0) {
            // 最近点是 A
            dx = x - x1;
            dy = y - y1;
        } else if (t > 1) {
            // 最近点是 B
            dx = x - x2;
            dy = y - y2;
        } else {
            // 最近点在线段中间
            double projX = x1 + t * dx;
            double projY = y1 + t * dy;
            dx = x - projX;
            dy = y - projY;
        }
        return Math.sqrt(dx * dx + dy * dy);
    }
    /**
     * 判断点是否在多边形内(射线法)
     */
@@ -76,6 +142,18 @@
    private static boolean onSegment(Vertex p1, Vertex p2, Vertex q) {
        return q.x <= Math.max(p1.x, p2.x) && q.x >= Math.min(p1.x, p2.x)
                && q.y <= Math.max(p1.y, p2.y) && q.y >= Math.min(p1.y, p2.y);
    }
    /**
     * 判断点是否在矩形内
     */
    public static boolean isInsideBox(Vertex point, ArdNoFlyBox box) {
        if (point == null || box == null) return false;
        return point.x >= box.getMinx() &&
                point.x <= box.getMaxx() &&
                point.y >= box.getMiny() &&
                point.y <= box.getMaxy();
    }
@@ -166,5 +244,8 @@
        return vertexes;
    }
    public static double degDistanceToMeter(double deg, double lat) {
        // 1° ≈ 111320 米,但是经度和纬度不一样,这里用纬度做修正
        return deg * 111320.0 * Math.cos(Math.toRadians(lat));
    }
}