From cb43af5c2caf2184bbf1a8e417f44e9aeaa2fdd9 Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Thu, 29 Jan 2026 13:38:20 +0800
Subject: [PATCH] feat:增加设备特效椭球
---
applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditBufferCircleTool.js | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 201 insertions(+), 34 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..61e40b4 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'
@@ -9,26 +9,71 @@
lat: point.lat ?? point.latitude,
}))
+const resolveLngLat = point => {
+ if (!point) return null
+ const lng = point.lng ?? point.longitude
+ const lat = point.lat ?? point.latitude
+ if (Number.isFinite(lng) && Number.isFinite(lat)) {
+ return { lng: Number(lng), lat: Number(lat), height: Number(point.height) || 0 }
+ }
+ return null
+}
+
+const resolveCartesian = point => {
+ if (!point) return null
+ if (Number.isFinite(point.x) && Number.isFinite(point.y) && Number.isFinite(point.z)) {
+ return new Cesium.Cartesian3(point.x, point.y, point.z)
+ }
+ const lngLat = resolveLngLat(point)
+ if (!lngLat) return null
+ return Cesium.Cartesian3.fromDegrees(lngLat.lng, lngLat.lat, lngLat.height || 0)
+}
+
export class EditBufferCircleTool extends ToolBase {
constructor(viewer) {
super(viewer)
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)
- 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)
+ start(data = []) {
+ const inputPoints = Array.isArray(data?.points) ? data.points : data
+ const normalized = normalizePoints(inputPoints)
+ const metaCenter = resolveCartesian(data?.meta?.center)
+ if (metaCenter) {
+ this.centerCartesian = metaCenter
+ } else {
+ 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)
+ }
+ 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 +104,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 +118,114 @@
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],
+ controlPoints: [
+ this.centerCartesian,
+ this.getRadiusPoint(this.radiusLevel1),
+ this.getRadiusPoint(this.radiusLevel2),
+ this.getRadiusPoint(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 +240,66 @@
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],
+ controlPoints: [
+ this.centerCartesian,
+ this.getRadiusPoint(this.radiusLevel1),
+ this.getRadiusPoint(this.radiusLevel2),
+ this.getRadiusPoint(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 +340,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