From 046a69a1a3b50079eae3663cd631bd062748ec4f Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Wed, 28 Jan 2026 14:40:36 +0800
Subject: [PATCH] feat:多边形绘制相关处理
---
applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditPolygonTool.js | 4 +
applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue | 101 ++++++++++++++++++++++++++++++++-
applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawEllipseTool.js | 7 ++
applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditRectangleTool.js | 4 +
applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawPolygonTool.js | 8 ++
applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawBufferCircleTool.js | 7 ++
applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditBufferCircleTool.js | 5 +
applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawRectangleTool.js | 8 ++
applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditEllipseTool.js | 5 +
9 files changed, 144 insertions(+), 5 deletions(-)
diff --git a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
index 28240d2..4b4b7cf 100644
--- a/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
+++ b/applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
@@ -18,7 +18,7 @@
>
<div class="panel-header">
<span>{{ drawTypeLabelMap[currentShapeType] || '区域' }}</span>
- <el-icon class="panel-close" @click.stop="showTypePanel = false"><Close /></el-icon>
+ <el-icon class="panel-close" @click.stop="handleTypePanelClose"><Close /></el-icon>
</div>
<div class="panel-body">
<span class="panel-label">区域类型</span>
@@ -27,7 +27,6 @@
popper-class="command-select-popper"
v-model="formData.areaType"
placeholder="请选择"
- clearable
@change="handleAreaTypeChange"
>
<el-option
@@ -301,12 +300,15 @@
buffer: '缓冲圆',
}
const showTypePanel = ref(false)
+const suppressTypePanelOnce = ref(false)
let viewer
let drawManager
let editManager
let activeTool
let pointList = []
let viewEntity
+let shapeDisplaySource
+const activeToolMode = ref('')
const rules = {
areaName: fieldRules(true, 50),
@@ -399,6 +401,7 @@
viewEntity = null
clearActiveTool()
hideTypePanel()
+ clearShapeDisplay()
}
}
)
@@ -436,10 +439,72 @@
viewer = map?.viewer || null
}
+function ensureShapeDisplaySource () {
+ if (!viewer) return null
+ if (!shapeDisplaySource) {
+ shapeDisplaySource = new Cesium.CustomDataSource('partition-shape-display')
+ viewer.dataSources.add(shapeDisplaySource)
+ }
+ return shapeDisplaySource
+}
+
+function clearShapeDisplay () {
+ if (!shapeDisplaySource) return
+ shapeDisplaySource.entities.removeAll()
+}
+
+function normalizeShapePoint (point) {
+ const lng = point?.lng ?? point?.longitude
+ const lat = point?.lat ?? point?.latitude
+ if (!Number.isFinite(Number(lng)) || !Number.isFinite(Number(lat))) return null
+ return {
+ lng: Number(lng),
+ lat: Number(lat),
+ height: Number.isFinite(Number(point?.height)) ? Number(point.height) : 0,
+ }
+}
+
+function buildShapePositions (points = []) {
+ const normalized = points.map(normalizeShapePoint).filter(Boolean)
+ return normalized.map(point =>
+ Cesium.Cartesian3.fromDegrees(point.lng, point.lat, point.height)
+ )
+}
+
+function renderShapeList () {
+ if (!viewer || !visible.value || readonly.value) {
+ clearShapeDisplay()
+ return
+ }
+ const dataSource = ensureShapeDisplaySource()
+ if (!dataSource) return
+ dataSource.entities.removeAll()
+ shapeList.value.forEach(shape => {
+ if (!shape?.points?.length) return
+ if (activeToolMode.value === 'edit' && shape.id === activeShapeId.value) return
+ const positions = buildShapePositions(shape.points)
+ if (positions.length < 3) return
+ dataSource.entities.add({
+ name: 'shape-display',
+ customData: { shapeId: shape.id, drawType: shape.drawType },
+ polygon: {
+ hierarchy: new Cesium.PolygonHierarchy(positions),
+ material: Cesium.Color.fromBytes(45, 140, 240, 99),
+ outline: false,
+ heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+ },
+ polyline: {
+ positions: positions.length ? [...positions, positions[0]] : positions,
+ clampToGround: true,
+ width: 2,
+ material: Cesium.Color.fromBytes(45, 140, 240, 255),
+ },
+ })
+ })
+}
+
// 绘制完成回调
const drawFinished = async data => {
- console.log(1)
-
if (!Array.isArray(data) || data.length < 3) {
pointList = []
formData.value.areaSize = null
@@ -459,7 +524,10 @@
formData.value.areaType = alarmAreaType
}
}
- showTypePanelAtCurrent()
+ if (!suppressTypePanelOnce.value) {
+ showTypePanelAtCurrent()
+ }
+ suppressTypePanelOnce.value = false
if (!activeShapeId.value) {
activeShapeId.value = `shape_${Date.now()}_${Math.random().toString(16).slice(2, 6)}`
@@ -476,6 +544,7 @@
} else {
shapeList.value.splice(targetIndex, 1, shapePayload)
}
+ renderShapeList()
}
function applyPolygonMetrics(points) {
@@ -508,6 +577,18 @@
showTypePanel.value = false
}
+function handleTypePanelClose () {
+ hideTypePanel()
+ if (readonly.value) return
+ if (activeToolMode.value !== 'edit') return
+ const positions = activeTool?.getPositions?.()
+ if (Array.isArray(positions) && positions.length >= 3) {
+ suppressTypePanelOnce.value = true
+ drawFinished(positions)
+ }
+ clearActiveTool()
+}
+
function handleAreaTypeChange (value) {
updateActiveShapeAreaType(value)
}
@@ -529,10 +610,13 @@
activeTool = null
drawManager?.destroy()
editManager?.destroy()
+ activeToolMode.value = ''
+ renderShapeList()
}
function startDraw (type) {
currentShapeType.value = type
+ activeToolMode.value = 'draw'
drawManager ||= new DrawManager(viewer)
activeTool = drawManager.start(type)
activeTool?.subscribe('getPolygonPositions', drawFinished)
@@ -540,6 +624,7 @@
function startEdit (type, points) {
currentShapeType.value = type
+ activeToolMode.value = 'edit'
editManager ||= new EditManager(viewer)
activeTool = editManager.start(type, points)
activeTool?.subscribe('getPolygonPositions', drawFinished)
@@ -552,6 +637,7 @@
viewEntity && viewer?.entities?.remove(viewEntity)
viewEntity = null
hideTypePanel()
+ renderShapeList()
if (dialogMode.value === 'edit' && pointList.length >= 3) {
const editPoints = _.cloneDeep(pointList)
if (editPoints.length > 1) {
@@ -581,10 +667,12 @@
formData.value.longitude = null
formData.value.latitude = null
hideTypePanel()
+ clearShapeDisplay()
}
function handleShapeEdit (row) {
if (!row?.points?.length) return
+ if (activeToolMode.value === 'edit' && activeShapeId.value === row.id) return
activeShapeId.value = row.id
currentShapeType.value = row.drawType
pointList = _.cloneDeep(row.points)
@@ -592,11 +680,13 @@
startEdit(row.drawType, row.points)
applyPolygonMetrics(pointList)
showTypePanelAtCurrent()
+ renderShapeList()
}
function handleShapeDelete (row) {
if (!row) return
shapeList.value = shapeList.value.filter(item => item.id !== row.id)
+ renderShapeList()
if (activeShapeId.value === row.id) {
activeShapeId.value = null
clearActiveTool()
@@ -673,6 +763,7 @@
activeShapeId.value = null
await nextTick()
initMap()
+ clearShapeDisplay()
viewEntity && viewer?.entities?.remove(viewEntity)
viewEntity = null
clearActiveTool()
diff --git a/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawBufferCircleTool.js b/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawBufferCircleTool.js
index 0d14a31..16cf36e 100644
--- a/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawBufferCircleTool.js
+++ b/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawBufferCircleTool.js
@@ -41,6 +41,7 @@
const positions = buildEllipsePositions(this.centerCartesian, this.radius, this.radius)
this.notify('getPolygonPositions', positions)
this.tooltip.hide()
+ this.clearPreviewEntities()
}
}
@@ -71,6 +72,12 @@
})
}
+ clearPreviewEntities() {
+ if (!this.dataSource) return
+ this.dataSource.entities.removeAll()
+ this.circleEntity = null
+ }
+
getSurfaceDistance(startCartesian, endCartesian) {
const start = Cesium.Cartographic.fromCartesian(startCartesian)
const end = Cesium.Cartographic.fromCartesian(endCartesian)
diff --git a/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawEllipseTool.js b/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawEllipseTool.js
index 14059ba..9ab98fb 100644
--- a/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawEllipseTool.js
+++ b/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawEllipseTool.js
@@ -51,6 +51,7 @@
const positions = buildEllipsePositions(this.centerCartesian, this.semiMajor, this.semiMinor)
this.notify('getPolygonPositions', positions)
this.tooltip.hide()
+ this.clearPreviewEntities()
}
}
@@ -99,6 +100,12 @@
})
}
+ clearPreviewEntities() {
+ if (!this.dataSource) return
+ this.dataSource.entities.removeAll()
+ this.ellipseEntity = null
+ }
+
getPositionFromScreen(screenPosition) {
const scene = this.viewer.scene
const cartesian = scene.pickPosition(screenPosition)
diff --git a/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawPolygonTool.js b/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawPolygonTool.js
index 96f60c3..dfddd03 100644
--- a/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawPolygonTool.js
+++ b/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawPolygonTool.js
@@ -176,6 +176,14 @@
this.floatPosition = null
this.notify('getPolygonPositions', this.positions)
this.tooltip.hide()
+ this.clearPreviewEntities()
+ }
+
+ clearPreviewEntities() {
+ if (!this.dataSource) return
+ this.dataSource.entities.removeAll()
+ this.polygonEntity = null
+ this.polylineEntity = null
}
getPositionFromScreen(screenPosition) {
diff --git a/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawRectangleTool.js b/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawRectangleTool.js
index bf297e0..4d1cbc8 100644
--- a/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawRectangleTool.js
+++ b/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawRectangleTool.js
@@ -45,6 +45,7 @@
const positions = this.getRectanglePositions()
this.notify('getPolygonPositions', positions)
this.tooltip.hide()
+ this.clearPreviewEntities()
}
}
@@ -94,6 +95,13 @@
return rectanglePositionsFromBounds(bounds)
}
+ clearPreviewEntities() {
+ if (!this.dataSource) return
+ this.dataSource.entities.removeAll()
+ this.rectangleEntity = null
+ this.outlineEntity = null
+ }
+
getPositionFromScreen(screenPosition) {
const scene = this.viewer.scene
const cartesian = scene.pickPosition(screenPosition)
diff --git a/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditBufferCircleTool.js b/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditBufferCircleTool.js
index cdf0f4e..abf1a5e 100644
--- a/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditBufferCircleTool.js
+++ b/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditBufferCircleTool.js
@@ -130,6 +130,11 @@
this.radiusEntity.position = this.getRadiusPoint()
}
+ getPositions() {
+ if (!this.centerCartesian) return []
+ return buildEllipsePositions(this.centerCartesian, this.radius, this.radius)
+ }
+
getRadiusPoint() {
const frame = Cesium.Transforms.eastNorthUpToFixedFrame(this.centerCartesian)
const local = new Cesium.Cartesian3(this.radius, 0, 0)
diff --git a/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditEllipseTool.js b/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditEllipseTool.js
index 457c0c7..a957b6c 100644
--- a/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditEllipseTool.js
+++ b/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditEllipseTool.js
@@ -154,6 +154,11 @@
this.minorEntity.position = this.getAxisPoint(0, this.semiMinor)
}
+ getPositions() {
+ if (!this.centerCartesian) return []
+ return buildEllipsePositions(this.centerCartesian, this.semiMajor, this.semiMinor)
+ }
+
getAxisPoint(eastMeters, northMeters) {
const frame = Cesium.Transforms.eastNorthUpToFixedFrame(this.centerCartesian)
const local = new Cesium.Cartesian3(eastMeters, northMeters, 0)
diff --git a/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditPolygonTool.js b/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditPolygonTool.js
index 77c226a..1b71743 100644
--- a/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditPolygonTool.js
+++ b/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditPolygonTool.js
@@ -142,6 +142,10 @@
})
}
+ getPositions() {
+ return this.positions.slice()
+ }
+
getPositionFromScreen(screenPosition) {
const scene = this.viewer.scene
const cartesian = scene.pickPosition(screenPosition)
diff --git a/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditRectangleTool.js b/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditRectangleTool.js
index 9513132..7e4c642 100644
--- a/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditRectangleTool.js
+++ b/applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditRectangleTool.js
@@ -124,6 +124,10 @@
})
}
+ getPositions() {
+ return rectanglePositionsFromBounds(this.bounds)
+ }
+
getCornerCartographics() {
return rectanglePositionsFromBounds(this.bounds).map(position =>
Cesium.Cartographic.fromCartesian(position)
--
Gitblit v1.9.3