From e4439e5d0a2cba9983f013bd044fe4e22c7b7077 Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Wed, 11 Feb 2026 16:35:06 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 applications/drone-command/src/components/map-container/device-map-container.vue |  145 ++++++++++++++---------------------------------
 1 files changed, 44 insertions(+), 101 deletions(-)

diff --git a/applications/drone-command/src/components/map-container/device-map-container.vue b/applications/drone-command/src/components/map-container/device-map-container.vue
index 2c0181c..cb4e5a2 100644
--- a/applications/drone-command/src/components/map-container/device-map-container.vue
+++ b/applications/drone-command/src/components/map-container/device-map-container.vue
@@ -77,6 +77,7 @@
 const DETAIL_HEIGHT = 10000
 const POLYGON_HEIGHT_M = 0.2
 const DRONE_TRACK_DURATION_S = 30 * 60
+const FIXED_DRONE_TRACK_IDS = ['6000000000602', '6000000000601']
 
 const props = defineProps({
 	allDevices: {
@@ -131,8 +132,8 @@
 let favoritePulseElapsed = 0
 const favoritePulseEntities = []
 const pulseBaseColor = Cesium.Color.fromCssColorString('#FF3B30')
-const PULSE_MIN_RADIUS_M = 2
-const PULSE_MAX_RADIUS_M = 30
+const PULSE_MIN_RADIUS_M = 20
+const PULSE_MAX_RADIUS_M = 80
 const PULSE_DURATION_S = 1.4
 const detailVisible = ref(true)
 const clusterVisible = ref(false)
@@ -216,93 +217,17 @@
 	return canvas
 }
 
-class PulseSphereMaterialProperty {
-	constructor(color, speed = 1.2, bands = 3.0, softness = 0.18) {
-		this._definitionChanged = new Cesium.Event()
-		this.color = color
-		this.speed = speed
-		this.bands = bands
-		this.softness = softness
-	}
-	get isConstant() {
-		return true
-	}
-	get definitionChanged() {
-		return this._definitionChanged
-	}
-	getType() {
-		return 'PulseSphereMaterial'
-	}
-	getValue(_time, result = {}) {
-		result.color = this.color
-		result.time = (performance.now() / 1000) * this.speed
-		result.bands = this.bands
-		result.softness = this.softness
-		return result
-	}
-	equals(other) {
-		return (
-			other instanceof PulseSphereMaterialProperty &&
-			Cesium.Color.equals(this.color, other.color) &&
-			this.speed === other.speed &&
-			this.bands === other.bands &&
-			this.softness === other.softness
-		)
-	}
-}
-
-let pulseSphereMaterial = null
-const getPulseSphereMaterial = () => {
-	if (pulseSphereMaterial) return pulseSphereMaterial
-	Cesium.Material._materialCache.addMaterial('PulseSphereMaterial', {
-		fabric: {
-			type: 'PulseSphereMaterial',
-			uniforms: {
-				color: pulseBaseColor.withAlpha(0.45),
-				time: 0,
-				bands: 3.0,
-				softness: 0.18,
-			},
-			source: `
-				czm_material czm_getMaterial(czm_materialInput materialInput)
-				{
-					czm_material material = czm_getDefaultMaterial(materialInput);
-					vec3 normalEC = normalize(materialInput.normalEC);
-					vec3 viewEC = normalize(-materialInput.positionToEyeEC);
-					float ndv = max(dot(normalEC, viewEC), 0.0);
-					float fresnel = pow(1.0 - ndv, 1.6);
-					float wave = sin((ndv * bands + time) * 6.2831853);
-					float ring = smoothstep(-softness, softness, wave);
-					float alpha = (ring * 0.6 + fresnel * 0.4) * color.a;
-					material.diffuse = color.rgb;
-					material.alpha = alpha;
-					return material;
-				}
-			`,
-		},
-		translucent: () => true,
-	})
-	pulseSphereMaterial = new PulseSphereMaterialProperty(pulseBaseColor.withAlpha(0.45), 1.1, 3.2, 0.22)
-	return pulseSphereMaterial
-}
-
 const createFavoritePulseEntity = (billboard) => {
 	if (!viewer || !billboard) return
-	const material = getPulseSphereMaterial()
 	const pulse = {
-		material,
 		offset: Math.random() * PULSE_DURATION_S,
 		entity: null,
 	}
-	const getPulseRadius3D = () => {
-		const radius = getPulseRadius(pulse)
-		return new Cesium.Cartesian3(radius, radius, radius)
-	}
 	pulse.entity = viewer.entities.add({
 		position: new Cesium.CallbackProperty(() => getBillboardPosition(billboard), false),
-		ellipsoid: {
-			radii: new Cesium.CallbackProperty(() => getPulseRadius3D(), false),
-			material,
+		point: {
+			pixelSize: new Cesium.CallbackProperty(() => getPulseRadius(pulse), false),
+			color: pulseBaseColor.withAlpha(0.4),
 		},
 	})
 	favoritePulseEntities.push(pulse)
@@ -378,10 +303,10 @@
 	if (deviceRingOutlinePrimitives.length) {
 		deviceRingOutlinePrimitives.forEach(primitive => cockpitPrimitiveLayer.add(primitive))
 	}
+	if (commandPostBillboardCollection) cockpitPrimitiveLayer.add(commandPostBillboardCollection)
+	if (deviceBillboardCollection) cockpitPrimitiveLayer.add(deviceBillboardCollection)
 	if (droneTrackPolylineCollection) cockpitPrimitiveLayer.add(droneTrackPolylineCollection)
 	if (droneTrackBillboardCollection) cockpitPrimitiveLayer.add(droneTrackBillboardCollection)
-	if (deviceBillboardCollection) cockpitPrimitiveLayer.add(deviceBillboardCollection)
-	if (commandPostBillboardCollection) cockpitPrimitiveLayer.add(commandPostBillboardCollection)
 }
 
 const clearDeviceEntities = () => {
@@ -541,7 +466,7 @@
 			},
 			{
 				longitude: 114.963974,
-				latitude:  27.132677,
+				latitude: 27.132677,
 				height: 320
 			},
 			{
@@ -588,29 +513,29 @@
 				height: 400
 			},
 			{
-				longitude: 114.925836, 
+				longitude: 114.925836,
 				latitude: 27.096102,
 				height: 400
 			},
 			{
-				longitude: 114.928384, 
+				longitude: 114.928384,
 				latitude: 27.095866,
 				height: 400
 			},
 			{
-				longitude: 114.929874, 
+				longitude: 114.929874,
 				latitude: 27.096095,
 				height: 400
 			},
 			{
-				longitude: 114.931048, 
+				longitude: 114.931048,
 				latitude: 27.097666,
 				height: 400
 			},
-		]
+		],
 	]
 
-	return basePoints[center.trackIndex]
+	return basePoints[center.trackIndex] || basePoints[1]
 }
 
 
@@ -704,11 +629,11 @@
 		const pos = isEntityPosition
 			? getBillboardPosition(track.billboard)
 			: Cesium.Cartesian3.lerp(
-					track.positions[seg],
-					track.positions[seg + 1],
-					ratio,
-					new Cesium.Cartesian3()
-			  )
+				track.positions[seg],
+				track.positions[seg + 1],
+				ratio,
+				new Cesium.Cartesian3()
+			)
 		if (!pos) return
 		if (!isEntityPosition) {
 			track.billboard.position = pos
@@ -794,7 +719,9 @@
 	droneTrackPolylineCollection.show = detailVisible.value
 	droneTrackRuntime = []
 	const baseTrackColor = Cesium.Color.fromCssColorString('red')
-		; (list || []).forEach((item, trackIndex) => {
+		; (FIXED_DRONE_TRACK_IDS || []).forEach((trackId, trackIndex) => {
+			const item = (list || []).find(entry => String(entry?.id) === String(trackId))
+			if (!item) return
 			const position = getDevicePosition(item)
 			if (!position) return
 			const points = buildSimulatedTrackPoints({ ...position, height: item.flightHeightM, trackIndex })
@@ -818,7 +745,7 @@
 				width: 3,
 				material: trackMaterial,
 			})
-			const droneId = `drone-alarm-${item?.alarmRecordId ?? item?.id ?? trackIndex}`
+			const droneId = `drone-alarm-${trackId}`
 			const startTime = viewer.clock.startTime
 			const stopTime = viewer.clock.stopTime
 			const positionProperty = new Cesium.SampledPositionProperty()
@@ -921,6 +848,7 @@
 				width: 40,
 				height: 56,
 				verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+				disableDepthTestDistance: Number.POSITIVE_INFINITY,
 			})
 			billboard.id = entry.entityId
 			devicePickMap.set(entry.entityId, { data: entry.data, billboard })
@@ -1049,7 +977,7 @@
 	if (!trimmed) return null
 	try {
 		return JSON.parse(trimmed)
-	} catch (error) {}
+	} catch (error) { }
 	return null
 }
 
@@ -1102,7 +1030,7 @@
 						.filter(radius => Number.isFinite(radius) && radius > 0)
 					radii.forEach((radius, levelIndex) => {
 						const positions = buildEllipsePositions(centerCartesian, radius, radius)
-					const style = BUFFER_LEVEL_STYLES[levelIndex] || BUFFER_LEVEL_STYLES[BUFFER_LEVEL_STYLES.length - 1]
+						const style = BUFFER_LEVEL_STYLES[levelIndex] || BUFFER_LEVEL_STYLES[BUFFER_LEVEL_STYLES.length - 1]
 						if (positions.length >= 3) {
 							shapes.push({
 								positions,
@@ -1310,6 +1238,7 @@
 				width: 40,
 				height: 56,
 				verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+				disableDepthTestDistance: Number.POSITIVE_INFINITY,
 			})
 		})
 	}
@@ -1402,7 +1331,7 @@
 	setDroneVisibility(!showCluster)
 }
 
-const handleMapReady = ({ viewer: mapViewer, publicCesium: mapPublic }) => {
+const  handleMapReady = async ({ viewer: mapViewer, publicCesium: mapPublic }) => {
 	if (mapReadyHandled) return
 	mapReadyHandled = true
 	viewer = mapViewer
@@ -1412,10 +1341,10 @@
 	const height = viewer?.camera?.positionCartographic?.height
 	const stage = getStageByHeight(height)
 	updateStageDisplay(stage)
+	await loadCommandPosts()
 	renderDeviceEntities(props.allDevices)
 	loadPartitions()
 	loadAggregation()
-	loadCommandPosts()
 	renderSimulatedDroneTrack(props.alarmDrones)
 	initDeviceClickHandler()
 }
@@ -1453,6 +1382,20 @@
 	viewer = null
 	publicCesium = null
 })
+
+const getMap = () => {
+	return mapRef.value?.getMap()
+}
+
+// 暴露给父组件调用
+const flyTo = (options) => {
+	mapRef.value?.flyToPoint(options)
+}
+
+defineExpose({
+	getMap,
+	flyTo
+})
 </script>
 
 <style lang="scss" scoped>

--
Gitblit v1.9.3