吉安感知网项目-前端
shuishen
2026-02-05 0e5b1764e3eb59e5f4aac4d380c6fda3f0c1e2fe
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()