From d60b1396df45de76c6bae6aa75c15602dd4c2570 Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Sat, 31 Jan 2026 14:22:27 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue | 89 ++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 85 insertions(+), 4 deletions(-)
diff --git a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
index 92c6ef8..9f490c4 100644
--- a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
+++ b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
@@ -266,7 +266,7 @@
const formRef = ref(null) // 表单实例
const formData = ref(initForm()) // 表单数据
const visible = defineModel() // 弹框显隐
-const dialogMode = ref('add') // 弹框模式
+const dialogMode = ref() // 弹框模式
const submitting = ref(false) // 提交中
const readonly = computed(() => dialogMode.value === 'view')
const route = useRoute()
@@ -301,6 +301,9 @@
let shapeDisplaySource
const deviceRangePrimitiveMap = new Map()
const activeToolMode = ref('')
+const suppressDeviceFly = ref(false)
+let lastSelectedDeviceIds = []
+let deviceRangeRenderToken = 0
const rules = {
areaName: fieldRules(true, 50),
@@ -482,6 +485,8 @@
async function renderDeviceRanges (rows) {
if (!viewer) return
+ deviceRangeRenderToken += 1
+ const renderToken = deviceRangeRenderToken
const selectedRows = Array.isArray(rows) ? rows : []
const nextIds = new Set(selectedRows.map(row => String(row?.id)))
for (const [id, primitive] of deviceRangePrimitiveMap.entries()) {
@@ -504,9 +509,11 @@
return { row, primitive }
})
)
+ if (renderToken !== deviceRangeRenderToken) return
primitives.forEach(({ row, primitive }) => {
if (!primitive) return
const id = String(row?.id)
+ if (!nextIds.has(id)) return
deviceRangePrimitiveMap.set(id, primitive)
viewer.scene.primitives.add(primitive)
})
@@ -668,6 +675,69 @@
material: style.outline,
},
})
+ })
+}
+
+function pushRadiusBoundingPoints (positions, center, radius) {
+ if (!center || !Number.isFinite(Number(radius)) || radius <= 0) return
+ const resolved = resolveLngLatPoint(center) || {}
+ const lng = Number(resolved.lng ?? resolved.longitude)
+ const lat = Number(resolved.lat ?? resolved.latitude)
+ if (!Number.isFinite(lng) || !Number.isFinite(lat)) return
+ const baseLat = Cesium.Math.toRadians(lat)
+ const earthRadius = Cesium.Ellipsoid.WGS84.maximumRadius
+ const deltaLat = radius / earthRadius
+ const deltaLng = radius / (earthRadius * Math.max(Math.cos(baseLat), 0.000001))
+ const points = [
+ { lng: Cesium.Math.toDegrees(Cesium.Math.toRadians(lng) + deltaLng), lat },
+ { lng: Cesium.Math.toDegrees(Cesium.Math.toRadians(lng) - deltaLng), lat },
+ { lng, lat: Cesium.Math.toDegrees(baseLat + deltaLat) },
+ { lng, lat: Cesium.Math.toDegrees(baseLat - deltaLat) },
+ ]
+ points.forEach(point => {
+ positions.push(Cesium.Cartesian3.fromDegrees(point.lng, point.lat, resolved.height || 0))
+ })
+}
+
+function collectShapeBoundingPositions () {
+ const positions = []
+ if (!viewer || !shapeList.value.length) return positions
+ shapeList.value.forEach(shape => {
+ let points = getShapeDisplayPoints(shape)
+ if (!Array.isArray(points) || !points.length) {
+ points = resolveControlPoints(shape?.meta, shape?.drawType)
+ }
+ if (Array.isArray(points) && points.length) {
+ points.forEach(point => {
+ const resolved = resolveLngLatPoint(point)
+ const normalized = normalizeShapePoint(resolved)
+ if (!normalized) return
+ positions.push(Cesium.Cartesian3.fromDegrees(normalized.lng, normalized.lat, normalized.height))
+ })
+ }
+ if (shape?.drawType === 'buffer' && shape?.meta?.center && Array.isArray(shape?.meta?.bufferRadii)) {
+ const maxRadius = Math.max(...shape.meta.bufferRadii.filter(item => Number.isFinite(item)))
+ pushRadiusBoundingPoints(positions, shape.meta.center, maxRadius)
+ }
+ if (shape?.drawType === 'ellipse' && shape?.meta?.center) {
+ const major = Number(shape?.meta?.semiMajor)
+ const minor = Number(shape?.meta?.semiMinor)
+ const radius = Number.isFinite(major) && Number.isFinite(minor) ? Math.max(major, minor) : null
+ pushRadiusBoundingPoints(positions, shape.meta.center, radius)
+ }
+ })
+ return positions
+}
+
+function fitViewToShapeList () {
+ if (!viewer || !shapeList.value.length) return
+ const positions = collectShapeBoundingPositions()
+ if (positions.length < 2) return
+ const boundingSphere = Cesium.BoundingSphere.fromPoints(positions)
+ const range = Math.max(boundingSphere.radius * 2.4, 200)
+ viewer.camera.flyToBoundingSphere(boundingSphere, {
+ duration: 0,
+ offset: new Cesium.HeadingPitchRange(viewer.camera.heading, Cesium.Math.toRadians(-90), range),
})
}
@@ -970,6 +1040,7 @@
if (!viewer) return
if (shapeList.value.length) {
renderShapeList()
+ fitViewToShapeList()
return
}
if (!formData.value?.geom) return
@@ -1010,9 +1081,15 @@
const ids = rows.map(item => item.id)
formData.value.deviceIds = ids.join(',')
renderDeviceRanges(rows)
- const target = rows[rows.length - 1]
- if (target) {
- void flyToDevice(target)
+ if (suppressDeviceFly.value) {
+ lastSelectedDeviceIds = [...ids]
+ return
+ }
+ const prevSet = new Set(lastSelectedDeviceIds)
+ const addedRow = rows.find(row => !prevSet.has(row.id))
+ lastSelectedDeviceIds = [...ids]
+ if (addedRow) {
+ void flyToDevice(addedRow)
}
}
@@ -1074,7 +1151,11 @@
viewPolygon()
}
await nextTick()
+ suppressDeviceFly.value = true
syncDeviceSelection()
+ lastSelectedDeviceIds = selectedDeviceRows.value.map(row => row.id)
+ await nextTick()
+ suppressDeviceFly.value = false
if (!readonly.value) {
renderDeviceRanges(selectedDeviceRows.value)
}
--
Gitblit v1.9.3