From 4b8b4906a8983c811954a074702b0024e7694588 Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Wed, 28 Jan 2026 16:06:50 +0800
Subject: [PATCH] feat:区域划分地图绘制相关处理

---
 applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditBufferCircleTool.js |  190 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 160 insertions(+), 30 deletions(-)

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 abf1a5e..1808125 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
@@ -1,4 +1,4 @@
-import * as Cesium from 'cesium'
+import * as Cesium from 'cesium'
 import { MapTooltip } from '../Tooltip'
 import { ToolBase } from '../ToolBase'
 import { buildEllipsePositions, cartesianToLocal } from '../shapeUtils'
@@ -15,20 +15,40 @@
 		this.tooltip = new MapTooltip(viewer)
 		this.dataSource = null
 		this.centerCartesian = null
-		this.radius = 0
+		this.radiusLevel1 = 0
+		this.radiusLevel2 = 0
+		this.radiusLevel3 = 0
 		this.dragType = null
-		this.circleEntity = null
+		this.circleLevel1Entity = null
+		this.circleLevel2Entity = null
+		this.circleLevel3Entity = null
+		this.circleLevel1OutlineEntity = null
+		this.circleLevel2OutlineEntity = null
+		this.circleLevel3OutlineEntity = null
 		this.centerEntity = null
-		this.radiusEntity = null
+		this.radiusLevel1Entity = null
+		this.radiusLevel2Entity = null
+		this.radiusLevel3Entity = null
 	}
 
-	start(points = []) {
-		const normalized = normalizePoints(points)
+	start(data = []) {
+		const inputPoints = Array.isArray(data?.points) ? data.points : data
+		const normalized = normalizePoints(inputPoints)
 		if (!normalized.length) return
 		const centerLng = normalized.reduce((sum, p) => sum + p.lng, 0) / normalized.length
 		const centerLat = normalized.reduce((sum, p) => sum + p.lat, 0) / normalized.length
 		this.centerCartesian = Cesium.Cartesian3.fromDegrees(centerLng, centerLat)
-		this.radius = this.estimateRadius(normalized)
+		const radii = Array.isArray(data?.meta?.bufferRadii) ? data.meta.bufferRadii : null
+		if (radii?.length) {
+			const [r1, r2, r3] = radii
+			this.radiusLevel1 = Number.isFinite(r1) && r1 > 0 ? r1 : 1
+			this.radiusLevel2 = Number.isFinite(r2) && r2 > 0 ? Math.max(r2, this.radiusLevel1) : this.radiusLevel1
+			this.radiusLevel3 = Number.isFinite(r3) && r3 > 0 ? Math.max(r3, this.radiusLevel2) : this.radiusLevel2
+		} else {
+			this.radiusLevel3 = this.estimateRadius(normalized)
+			this.radiusLevel2 = this.radiusLevel3
+			this.radiusLevel1 = this.radiusLevel3
+		}
 
 		this.dataSource = new Cesium.CustomDataSource('edit-buffer-circle')
 		this.viewer.dataSources.add(this.dataSource)
@@ -59,7 +79,9 @@
 		const picked = this.viewer.scene.pick(evt.position)?.id
 		if (!picked) return
 		if (picked.customType === 'circle-center') this.dragType = 'center'
-		if (picked.customType === 'circle-radius') this.dragType = 'radius'
+		if (picked.customType === 'circle-radius-1') this.dragType = 'radius-1'
+		if (picked.customType === 'circle-radius-2') this.dragType = 'radius-2'
+		if (picked.customType === 'circle-radius-3') this.dragType = 'radius-3'
 		if (this.dragType) this.disableMapControl()
 	}
 
@@ -71,34 +93,108 @@
 
 		if (this.dragType === 'center') {
 			this.centerCartesian = position
-			this.updateRadiusPoint()
+			this.updateRadiusPoints()
 			return
 		}
 
 		const local = cartesianToLocal(this.centerCartesian, position)
-		this.radius = Math.max(1, Math.sqrt(local.x * local.x + local.y * local.y))
-		this.updateRadiusPoint()
+		const radius = Math.max(1, Math.sqrt(local.x * local.x + local.y * local.y))
+		if (this.dragType === 'radius-1') {
+			this.radiusLevel1 = radius
+			if (this.radiusLevel2 < this.radiusLevel1) this.radiusLevel2 = this.radiusLevel1
+			if (this.radiusLevel3 < this.radiusLevel2) this.radiusLevel3 = this.radiusLevel2
+		}
+		if (this.dragType === 'radius-2') {
+			this.radiusLevel2 = Math.max(radius, this.radiusLevel1)
+			if (this.radiusLevel3 < this.radiusLevel2) this.radiusLevel3 = this.radiusLevel2
+		}
+		if (this.dragType === 'radius-3') {
+			this.radiusLevel3 = Math.max(radius, this.radiusLevel2)
+		}
+		this.updateRadiusPoints()
 	}
 
 	handleLeftUp() {
 		if (!this.dragType) return
 		this.dragType = null
 		this.enableMapControl()
-		const positions = buildEllipsePositions(this.centerCartesian, this.radius, this.radius)
-		this.notify('getPolygonPositions', positions)
+		const positions = buildEllipsePositions(this.centerCartesian, this.radiusLevel3, this.radiusLevel3)
+		this.notify('getPolygonPositions', {
+			positions,
+			meta: {
+				center: this.centerCartesian,
+				bufferRadii: [this.radiusLevel1, this.radiusLevel2, this.radiusLevel3],
+			},
+		})
 	}
 
 	createEntities() {
-		this.circleEntity = this.dataSource.entities.add({
+		this.circleLevel1Entity = this.dataSource.entities.add({
 			position: new Cesium.CallbackProperty(() => this.centerCartesian, false),
 			ellipse: {
-				semiMajorAxis: new Cesium.CallbackProperty(() => this.radius, false),
-				semiMinorAxis: new Cesium.CallbackProperty(() => this.radius, false),
-				material: Cesium.Color.fromBytes(45, 140, 240, 99),
-				outline: true,
-				outlineColor: Cesium.Color.fromBytes(45, 140, 240, 255),
-				outlineWidth: 2,
+				semiMajorAxis: new Cesium.CallbackProperty(() => this.radiusLevel1, false),
+				semiMinorAxis: new Cesium.CallbackProperty(() => this.radiusLevel1, false),
+				material: Cesium.Color.fromBytes(247, 20, 20, 128),
+				outline: false,
 				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+			},
+		})
+		this.circleLevel1OutlineEntity = this.dataSource.entities.add({
+			polyline: {
+				positions: new Cesium.CallbackProperty(() => {
+					if (!this.centerCartesian || this.radiusLevel1 <= 0) return []
+					const positions = buildEllipsePositions(this.centerCartesian, this.radiusLevel1, this.radiusLevel1)
+					return positions.length ? [...positions, positions[0]] : positions
+				}, false),
+				clampToGround: true,
+				width: 2,
+				material: Cesium.Color.fromBytes(255, 0, 0, 255),
+			},
+		})
+
+		this.circleLevel2Entity = this.dataSource.entities.add({
+			position: new Cesium.CallbackProperty(() => this.centerCartesian, false),
+			ellipse: {
+				semiMajorAxis: new Cesium.CallbackProperty(() => this.radiusLevel2, false),
+				semiMinorAxis: new Cesium.CallbackProperty(() => this.radiusLevel2, false),
+				material: Cesium.Color.fromBytes(255, 235, 59, 128),
+				outline: false,
+				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+			},
+		})
+		this.circleLevel2OutlineEntity = this.dataSource.entities.add({
+			polyline: {
+				positions: new Cesium.CallbackProperty(() => {
+					if (!this.centerCartesian || this.radiusLevel2 <= 0) return []
+					const positions = buildEllipsePositions(this.centerCartesian, this.radiusLevel2, this.radiusLevel2)
+					return positions.length ? [...positions, positions[0]] : positions
+				}, false),
+				clampToGround: true,
+				width: 2,
+				material: Cesium.Color.fromBytes(255, 235, 59, 255),
+			},
+		})
+
+		this.circleLevel3Entity = this.dataSource.entities.add({
+			position: new Cesium.CallbackProperty(() => this.centerCartesian, false),
+			ellipse: {
+				semiMajorAxis: new Cesium.CallbackProperty(() => this.radiusLevel3, false),
+				semiMinorAxis: new Cesium.CallbackProperty(() => this.radiusLevel3, false),
+				material: Cesium.Color.fromBytes(25, 178, 230, 128),
+				outline: false,
+				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+			},
+		})
+		this.circleLevel3OutlineEntity = this.dataSource.entities.add({
+			polyline: {
+				positions: new Cesium.CallbackProperty(() => {
+					if (!this.centerCartesian || this.radiusLevel3 <= 0) return []
+					const positions = buildEllipsePositions(this.centerCartesian, this.radiusLevel3, this.radiusLevel3)
+					return positions.length ? [...positions, positions[0]] : positions
+				}, false),
+				clampToGround: true,
+				width: 2,
+				material: Cesium.Color.fromBytes(0, 251, 255, 255),
 			},
 		})
 
@@ -113,31 +209,60 @@
 			customType: 'circle-center',
 		})
 
-		this.radiusEntity = this.dataSource.entities.add({
-			position: new Cesium.CallbackProperty(() => this.getRadiusPoint(), false),
+		this.radiusLevel1Entity = this.dataSource.entities.add({
+			position: new Cesium.CallbackProperty(() => this.getRadiusPoint(this.radiusLevel1), false),
 			point: {
 				pixelSize: 10,
 				color: Cesium.Color.fromBytes(255, 255, 255, 200),
 				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
 				disableDepthTestDistance: Number.POSITIVE_INFINITY,
 			},
-			customType: 'circle-radius',
+			customType: 'circle-radius-1',
+		})
+
+		this.radiusLevel2Entity = this.dataSource.entities.add({
+			position: new Cesium.CallbackProperty(() => this.getRadiusPoint(this.radiusLevel2), false),
+			point: {
+				pixelSize: 10,
+				color: Cesium.Color.fromBytes(255, 255, 255, 200),
+				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+				disableDepthTestDistance: Number.POSITIVE_INFINITY,
+			},
+			customType: 'circle-radius-2',
+		})
+
+		this.radiusLevel3Entity = this.dataSource.entities.add({
+			position: new Cesium.CallbackProperty(() => this.getRadiusPoint(this.radiusLevel3), false),
+			point: {
+				pixelSize: 10,
+				color: Cesium.Color.fromBytes(255, 255, 255, 200),
+				heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+				disableDepthTestDistance: Number.POSITIVE_INFINITY,
+			},
+			customType: 'circle-radius-3',
 		})
 	}
 
-	updateRadiusPoint() {
-		if (!this.radiusEntity) return
-		this.radiusEntity.position = this.getRadiusPoint()
+	updateRadiusPoints() {
+		if (this.radiusLevel1Entity) this.radiusLevel1Entity.position = this.getRadiusPoint(this.radiusLevel1)
+		if (this.radiusLevel2Entity) this.radiusLevel2Entity.position = this.getRadiusPoint(this.radiusLevel2)
+		if (this.radiusLevel3Entity) this.radiusLevel3Entity.position = this.getRadiusPoint(this.radiusLevel3)
 	}
 
 	getPositions() {
 		if (!this.centerCartesian) return []
-		return buildEllipsePositions(this.centerCartesian, this.radius, this.radius)
+		return {
+			positions: buildEllipsePositions(this.centerCartesian, this.radiusLevel3, this.radiusLevel3),
+			meta: {
+				center: this.centerCartesian,
+				bufferRadii: [this.radiusLevel1, this.radiusLevel2, this.radiusLevel3],
+			},
+		}
 	}
 
-	getRadiusPoint() {
+	getRadiusPoint(radius) {
 		const frame = Cesium.Transforms.eastNorthUpToFixedFrame(this.centerCartesian)
-		const local = new Cesium.Cartesian3(this.radius, 0, 0)
+		const local = new Cesium.Cartesian3(radius, 0, 0)
 		return Cesium.Matrix4.multiplyByPoint(frame, local, new Cesium.Cartesian3())
 	}
 
@@ -178,7 +303,12 @@
 		this.tooltip?.destroy()
 		this.tooltip = null
 		this.centerCartesian = null
-		this.radius = 0
+		this.radiusLevel1 = 0
+		this.radiusLevel2 = 0
+		this.radiusLevel3 = 0
+		this.circleLevel1OutlineEntity = null
+		this.circleLevel2OutlineEntity = null
+		this.circleLevel3OutlineEntity = null
 		this.dragType = null
 	}
 }

--
Gitblit v1.9.3