From 0e5b1764e3eb59e5f4aac4d380c6fda3f0c1e2fe Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Thu, 05 Feb 2026 17:23:42 +0800
Subject: [PATCH] feat:多边形绘制及编辑增加交叉判断
---
applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue | 64 ++++++++++++++++++++++++++++++++
1 files changed, 64 insertions(+), 0 deletions(-)
diff --git a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
index 342b43c..0d7cb25 100644
--- a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
+++ b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
@@ -536,6 +536,60 @@
return Math.abs(left.lat - right.lat) < 0.000001 && Math.abs(left.lng - right.lng) < 0.000001
}
+function normalizePolygonPoints (points) {
+ if (!Array.isArray(points)) return []
+ const ring = points.filter(point => point && Number.isFinite(point.lng) && Number.isFinite(point.lat))
+ if (ring.length < 2) return ring
+ const first = ring[0]
+ const last = ring[ring.length - 1]
+ if (isSameWktPoint(first, last)) {
+ return ring.slice(0, -1)
+ }
+ return ring
+}
+
+function isSelfIntersectingPolygon (points) {
+ const ring = normalizePolygonPoints(points)
+ if (ring.length < 4) return false
+ const epsilon = 1e-12
+ const orientation = (a, b, c) => {
+ const value = (b.lat - a.lat) * (c.lng - b.lng) - (b.lng - a.lng) * (c.lat - b.lat)
+ if (Math.abs(value) < epsilon) return 0
+ return value > 0 ? 1 : 2
+ }
+ const onSegment = (a, b, c) =>
+ b.lng <= Math.max(a.lng, c.lng) + epsilon &&
+ b.lng + epsilon >= Math.min(a.lng, c.lng) &&
+ b.lat <= Math.max(a.lat, c.lat) + epsilon &&
+ b.lat + epsilon >= Math.min(a.lat, c.lat)
+ const segmentsIntersect = (p1, q1, p2, q2) => {
+ const o1 = orientation(p1, q1, p2)
+ const o2 = orientation(p1, q1, q2)
+ const o3 = orientation(p2, q2, p1)
+ const o4 = orientation(p2, q2, q1)
+ if (o1 !== o2 && o3 !== o4) return true
+ if (o1 === 0 && onSegment(p1, p2, q1)) return true
+ if (o2 === 0 && onSegment(p1, q2, q1)) return true
+ if (o3 === 0 && onSegment(p2, p1, q2)) return true
+ if (o4 === 0 && onSegment(p2, q1, q2)) return true
+ return false
+ }
+
+ const count = ring.length
+ for (let i = 0; i < count; i += 1) {
+ const p1 = ring[i]
+ const q1 = ring[(i + 1) % count]
+ for (let j = i + 1; j < count; j += 1) {
+ const p2 = ring[j]
+ const q2 = ring[(j + 1) % count]
+ const isAdjacent = j === i || j === i + 1 || (i === 0 && j === count - 1)
+ if (isAdjacent) continue
+ if (segmentsIntersect(p1, q1, p2, q2)) return true
+ }
+ }
+ return false
+}
+
function buildPolygonWktFromPoints (points) {
if (!Array.isArray(points) || points.length < 3) return null
const ring = points
@@ -928,6 +982,16 @@
const val = cartesian3Convert(item, viewer)
return { ...val, lng: val.longitude, lat: val.latitude }
})
+ if (currentShapeType.value === 'polygon' && isSelfIntersectingPolygon(pointList)) {
+ ElMessage.warning('多边形存在自相交,请调整后再保存')
+ if (activeToolMode.value === 'draw') {
+ pointList = []
+ activeShapeId.value = null
+ clearActiveTool()
+ startDraw('polygon')
+ }
+ return
+ }
const controlPoints = resolveControlPoints(meta, currentShapeType.value)
if (!activeAreaType.value) {
const detectAreaType = getDetectAreaTypeKey()
--
Gitblit v1.9.3