From f083281ab75f61390a04daa2484f330f8df4178f Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Thu, 29 Jan 2026 08:44:20 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawBufferCircleTool.js | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 236 insertions(+), 0 deletions(-)
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
new file mode 100644
index 0000000..ca5d4a9
--- /dev/null
+++ b/applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawBufferCircleTool.js
@@ -0,0 +1,236 @@
+import * as Cesium from 'cesium'
+import { MapTooltip } from '../Tooltip'
+import { ToolBase } from '../ToolBase'
+import { buildEllipsePositions } from '../shapeUtils'
+
+export class DrawBufferCircleTool extends ToolBase {
+ constructor(viewer) {
+ super(viewer)
+ this.tooltip = new MapTooltip(viewer)
+ this.dataSource = null
+ this.centerCartesian = null
+ this.radiusLevel1 = 0
+ this.radiusLevel2 = 0
+ this.radiusLevel3 = 0
+ this.circleLevel1Entity = null
+ this.circleLevel2Entity = null
+ this.circleLevel3Entity = null
+ this.circleLevel1OutlineEntity = null
+ this.circleLevel2OutlineEntity = null
+ this.circleLevel3OutlineEntity = null
+ this.isDrawing = false
+ this.drawStep = 0
+ this.isCompleted = false
+ }
+
+ start() {
+ this.dataSource = new Cesium.CustomDataSource('draw-buffer-circle')
+ this.viewer.dataSources.add(this.dataSource)
+ this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
+ this.handler.setInputAction(click => this.handleLeftClick(click), Cesium.ScreenSpaceEventType.LEFT_CLICK)
+ this.handler.setInputAction(movement => this.handleMouseMove(movement), Cesium.ScreenSpaceEventType.MOUSE_MOVE)
+ this.drawStep = 0
+ this.isCompleted = false
+ this.tooltip.show('单击设置中心点', { x: 0, y: 0 })
+ }
+
+ handleLeftClick(click) {
+ if (this.isCompleted) return
+ const position = this.getPositionFromScreen(click.position)
+ if (!position) return
+
+ if (this.drawStep === 0) {
+ this.centerCartesian = position
+ this.radiusLevel1 = 1
+ this.radiusLevel2 = 1
+ this.radiusLevel3 = 1
+ this.isDrawing = true
+ this.drawStep = 1
+ this.createEntities()
+ this.tooltip.show('单击设置一级缓冲圆', click.position)
+ return
+ }
+
+ if (this.drawStep === 1) {
+ const radius = Math.max(1, this.getSurfaceDistance(this.centerCartesian, position))
+ this.radiusLevel1 = radius
+ this.radiusLevel2 = radius
+ this.radiusLevel3 = radius
+ this.drawStep = 2
+ this.tooltip.show('单击设置二级缓冲圆', click.position)
+ return
+ }
+
+ if (this.drawStep === 2) {
+ const radius = Math.max(1, this.getSurfaceDistance(this.centerCartesian, position))
+ this.radiusLevel2 = Math.max(radius, this.radiusLevel1)
+ this.radiusLevel3 = this.radiusLevel2
+ this.drawStep = 3
+ this.tooltip.show('单击设置三级缓冲圆', click.position)
+ return
+ }
+
+ if (this.drawStep === 3) {
+ const radius = Math.max(1, this.getSurfaceDistance(this.centerCartesian, position))
+ this.radiusLevel3 = Math.max(radius, this.radiusLevel2)
+ this.isDrawing = false
+ this.drawStep = 0
+ this.isCompleted = true
+ const positions = buildEllipsePositions(this.centerCartesian, this.radiusLevel3, this.radiusLevel3)
+ this.notify('getPolygonPositions', {
+ positions,
+ meta: {
+ center: this.centerCartesian,
+ bufferRadii: [this.radiusLevel1, this.radiusLevel2, this.radiusLevel3],
+ },
+ })
+ this.tooltip.hide()
+ this.clearPreviewEntities()
+ }
+ }
+
+ handleMouseMove(movement) {
+ if (this.isCompleted) return
+ this.tooltip.move(movement.endPosition)
+ if (!this.isDrawing) return
+ const position = this.getPositionFromScreen(movement.endPosition)
+ if (!position) return
+ if (this.drawStep === 1) {
+ const radius = Math.max(1, this.getSurfaceDistance(this.centerCartesian, position))
+ this.radiusLevel1 = radius
+ this.radiusLevel2 = radius
+ this.radiusLevel3 = radius
+ return
+ }
+ if (this.drawStep === 2) {
+ const radius = Math.max(1, this.getSurfaceDistance(this.centerCartesian, position))
+ this.radiusLevel2 = Math.max(radius, this.radiusLevel1)
+ this.radiusLevel3 = this.radiusLevel2
+ return
+ }
+ if (this.drawStep === 3) {
+ const radius = Math.max(1, this.getSurfaceDistance(this.centerCartesian, position))
+ this.radiusLevel3 = Math.max(radius, this.radiusLevel2)
+ }
+ }
+
+ createEntities() {
+ if (this.circleLevel1Entity || this.circleLevel2Entity || this.circleLevel3Entity) return
+ this.circleLevel1Entity = this.dataSource.entities.add({
+ position: new Cesium.CallbackProperty(() => this.centerCartesian, false),
+ ellipse: {
+ 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),
+ },
+ })
+ }
+
+ clearPreviewEntities() {
+ if (!this.dataSource) return
+ this.dataSource.entities.removeAll()
+ this.circleLevel1Entity = null
+ this.circleLevel2Entity = null
+ this.circleLevel3Entity = null
+ this.circleLevel1OutlineEntity = null
+ this.circleLevel2OutlineEntity = null
+ this.circleLevel3OutlineEntity = null
+ }
+
+ getSurfaceDistance(startCartesian, endCartesian) {
+ const start = Cesium.Cartographic.fromCartesian(startCartesian)
+ const end = Cesium.Cartographic.fromCartesian(endCartesian)
+ const geodesic = new Cesium.EllipsoidGeodesic(start, end)
+ return geodesic.surfaceDistance
+ }
+
+ getPositionFromScreen(screenPosition) {
+ const scene = this.viewer.scene
+ const cartesian = scene.pickPosition(screenPosition)
+ if (cartesian) return cartesian
+ return scene.camera.pickEllipsoid(screenPosition, scene.globe.ellipsoid)
+ }
+
+ destroy() {
+ if (this.dataSource) {
+ this.dataSource.entities.removeAll()
+ this.viewer.dataSources.remove(this.dataSource)
+ this.dataSource = null
+ }
+ if (this.handler) {
+ this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
+ this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
+ this.handler.destroy()
+ this.handler = null
+ }
+ this.tooltip?.destroy()
+ this.tooltip = null
+ this.centerCartesian = null
+ this.radiusLevel1 = 0
+ this.radiusLevel2 = 0
+ this.radiusLevel3 = 0
+ this.isDrawing = false
+ this.drawStep = 0
+ this.isCompleted = false
+ }
+}
--
Gitblit v1.9.3