| | |
| | | |
| | | 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); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 判断点是否在多边形内(射线法) |
| | | */ |
| | |
| | | |
| | | |
| | | /** |
| | | * 判断点是否在矩形内 |
| | | */ |
| | | 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(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 根据 GeoJSON(FeatureCollection)计算外接矩形 |
| | | */ |
| | | @SuppressWarnings("unchecked") |