From da563dc595339d42e2135f63167906d6fa20e06c Mon Sep 17 00:00:00 2001
From: 张含笑 <zhx18749296735@163.com>
Date: Fri, 23 Jan 2026 09:34:55 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
applications/drone-command/src/components/map-container/device-map-container.vue | 580 ++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 444 insertions(+), 136 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 d34c53a..6e584a0 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
@@ -1,4 +1,4 @@
-<template>
+<template>
<div class="map-shell">
<CommonCesiumMap ref="mapRef" class="command-cesium map-container" :dom-id="props.containerId" :active="true"
:flat-mode="false" :terrain="true" :layer-mode="4" :contour="false" :boundary="false"
@@ -93,6 +93,7 @@
import { cockpitAggregationApi } from '@/api/dataCockpit'
import layerControlIcon from '@/assets/images/dataCockpit/layerControl.png'
import equipmentIcon from '@/assets/images/dataCockpit/map/equipment.png'
+import droneIcon from '@/assets/images/dataCockpit/map/drone.png'
import aggregationIcon from '@/assets/images/dataCockpit/map/aggregation.png'
import commandPostIcon from '@/assets/images/dataCockpit/map/command-post.png'
import popupClose from '@/assets/images/dataCockpit/map/popup-close.png'
@@ -121,19 +122,29 @@
const mapRef = ref(null)
let viewer = null
-const deviceEntityIds = new Set()
-const deviceEntityMap = new Map()
-let defenseZoneSource = null
-let partitionSource = null
+let cockpitPrimitiveLayer = null
+const devicePickMap = new Map()
+let deviceBillboardCollection = null
+let deviceRingOutlinePrimitives = []
+let deviceRingFillPrimitives = []
+let defenseZonePrimitive = null
+let defenseZoneOutlinePrimitive = null
+let partitionPrimitive = null
+let partitionOutlinePrimitive = null
let aggregationSource = null
-let commandPostSource = null
+let commandPostBillboardCollection = null
+let droneTrackBillboardCollection = null
+let droneTrackPolylineCollection = null
+let droneTrackTickHandler = null
+let droneTrackStartTime = null
+let droneTrackRuntime = []
const detailVisible = ref(true)
const clusterVisible = ref(false)
const countyCenterMap = new Map()
const showLayerPanel = ref(false)
const layerWrapRef = ref(null)
const selectedDevice = ref(null)
-let selectedDeviceEntity = null
+let selectedDeviceBillboard = null
let deviceClickHandler = null
let popupRenderHandler = null
const layerTreeProps = {
@@ -180,23 +191,101 @@
return { longitude, latitude }
}
+const ensureCockpitPrimitiveLayer = () => {
+ if (!viewer) return
+ if (!cockpitPrimitiveLayer) {
+ cockpitPrimitiveLayer = new Cesium.PrimitiveCollection({ destroyPrimitives: false })
+ viewer.scene.primitives.add(cockpitPrimitiveLayer)
+ }
+}
+
+const addCockpitPrimitive = primitive => {
+ if (!primitive) return
+ if (cockpitPrimitiveLayer) {
+ cockpitPrimitiveLayer.add(primitive)
+ return
+ }
+ viewer?.scene?.primitives?.add(primitive)
+}
+
+const removeCockpitPrimitive = (primitive, destroy = true) => {
+ if (!primitive) return
+ if (cockpitPrimitiveLayer) {
+ cockpitPrimitiveLayer.remove(primitive, destroy)
+ return
+ }
+ viewer?.scene?.primitives?.remove(primitive)
+}
+
+const reorderCockpitPrimitives = () => {
+ if (!viewer) return
+ ensureCockpitPrimitiveLayer()
+ cockpitPrimitiveLayer.removeAll(false)
+ if (defenseZonePrimitive) cockpitPrimitiveLayer.add(defenseZonePrimitive)
+ if (defenseZoneOutlinePrimitive) cockpitPrimitiveLayer.add(defenseZoneOutlinePrimitive)
+ if (partitionPrimitive) cockpitPrimitiveLayer.add(partitionPrimitive)
+ if (partitionOutlinePrimitive) cockpitPrimitiveLayer.add(partitionOutlinePrimitive)
+ if (deviceRingFillPrimitives.length) {
+ deviceRingFillPrimitives.forEach(primitive => cockpitPrimitiveLayer.add(primitive))
+ }
+ if (deviceRingOutlinePrimitives.length) {
+ deviceRingOutlinePrimitives.forEach(primitive => cockpitPrimitiveLayer.add(primitive))
+ }
+ if (droneTrackPolylineCollection) cockpitPrimitiveLayer.add(droneTrackPolylineCollection)
+ if (droneTrackBillboardCollection) cockpitPrimitiveLayer.add(droneTrackBillboardCollection)
+ if (deviceBillboardCollection) cockpitPrimitiveLayer.add(deviceBillboardCollection)
+ if (commandPostBillboardCollection) cockpitPrimitiveLayer.add(commandPostBillboardCollection)
+}
+
const clearDeviceEntities = () => {
if (!viewer) return
- deviceEntityIds.forEach(id => {
- viewer.entities.removeById(id)
- })
- deviceEntityIds.clear()
- deviceEntityMap.clear()
+ if (deviceBillboardCollection) {
+ deviceBillboardCollection.removeAll()
+ removeCockpitPrimitive(deviceBillboardCollection)
+ deviceBillboardCollection = null
+ }
+ if (deviceRingFillPrimitives.length) {
+ deviceRingFillPrimitives.forEach(primitive => removeCockpitPrimitive(primitive))
+ deviceRingFillPrimitives = []
+ }
+ if (deviceRingOutlinePrimitives.length) {
+ deviceRingOutlinePrimitives.forEach(primitive => removeCockpitPrimitive(primitive))
+ deviceRingOutlinePrimitives = []
+ }
+ devicePickMap.clear()
+}
+
+const ensureDeviceCollections = () => {
+ if (!viewer) return
+ ensureCockpitPrimitiveLayer()
+ if (!deviceBillboardCollection) {
+ deviceBillboardCollection = new Cesium.BillboardCollection()
+ addCockpitPrimitive(deviceBillboardCollection)
+ }
}
const clearDefenseZoneEntities = () => {
- if (!defenseZoneSource) return
- defenseZoneSource.entities.removeAll()
+ if (!viewer) return
+ if (defenseZonePrimitive) {
+ removeCockpitPrimitive(defenseZonePrimitive)
+ defenseZonePrimitive = null
+ }
+ if (defenseZoneOutlinePrimitive) {
+ removeCockpitPrimitive(defenseZoneOutlinePrimitive)
+ defenseZoneOutlinePrimitive = null
+ }
}
const clearPartitionEntities = () => {
- if (!partitionSource) return
- partitionSource.entities.removeAll()
+ if (!viewer) return
+ if (partitionPrimitive) {
+ removeCockpitPrimitive(partitionPrimitive)
+ partitionPrimitive = null
+ }
+ if (partitionOutlinePrimitive) {
+ removeCockpitPrimitive(partitionOutlinePrimitive)
+ partitionOutlinePrimitive = null
+ }
}
const clearAggregationEntities = () => {
@@ -205,20 +294,42 @@
}
const clearCommandPostEntities = () => {
- if (!commandPostSource) return
- commandPostSource.entities.removeAll()
+ if (!viewer) return
+ if (commandPostBillboardCollection) {
+ commandPostBillboardCollection.removeAll()
+ removeCockpitPrimitive(commandPostBillboardCollection)
+ commandPostBillboardCollection = null
+ }
+}
+
+const ensureCommandPostCollection = () => {
+ if (!viewer) return
+ ensureCockpitPrimitiveLayer()
+ if (!commandPostBillboardCollection) {
+ commandPostBillboardCollection = new Cesium.BillboardCollection()
+ addCockpitPrimitive(commandPostBillboardCollection)
+ }
}
const setDetailVisibility = visible => {
detailVisible.value = visible
- if (defenseZoneSource) defenseZoneSource.show = visible
- if (partitionSource) partitionSource.show = visible
- if (commandPostSource) commandPostSource.show = visible
+ if (defenseZonePrimitive) defenseZonePrimitive.show = visible
+ if (defenseZoneOutlinePrimitive) defenseZoneOutlinePrimitive.show = visible
+ if (partitionPrimitive) partitionPrimitive.show = visible
+ if (partitionOutlinePrimitive) partitionOutlinePrimitive.show = visible
+ if (commandPostBillboardCollection) commandPostBillboardCollection.show = visible
+ if (deviceBillboardCollection) deviceBillboardCollection.show = visible
+ if (deviceRingFillPrimitives.length) {
+ deviceRingFillPrimitives.forEach(primitive => {
+ primitive.show = visible
+ })
+ }
+ if (deviceRingOutlinePrimitives.length) {
+ deviceRingOutlinePrimitives.forEach(primitive => {
+ primitive.show = visible
+ })
+ }
if (!visible) closePopup()
- deviceEntityIds.forEach(id => {
- const entity = viewer?.entities?.getById(id)
- if (entity) entity.show = visible
- })
}
const setClusterVisibility = visible => {
@@ -237,12 +348,139 @@
})
}
+const buildSimulatedTrackPoints = base => {
+ ensureCountyCenterMap()
+ const anchor = base || { longitude: 116.397, latitude: 39.908 }
+ const offsets = [
+ [0, 0, 120],
+ [0.02, 0.012, 150],
+ [0.04, 0.006, 180],
+ [0.06, -0.008, 200],
+ [0.03, -0.02, 160],
+ [0.0, -0.015, 140],
+ [-0.02, -0.005, 120],
+ [-0.01, 0.01, 130],
+ ]
+ return offsets.map(item => ({
+ longitude: anchor.longitude + item[0],
+ latitude: anchor.latitude + item[1],
+ height: item[2],
+ }))
+}
+
+
+const clearDroneTrackEntities = () => {
+ if (!viewer) return
+ if (droneTrackBillboardCollection) {
+ droneTrackBillboardCollection.removeAll()
+ removeCockpitPrimitive(droneTrackBillboardCollection)
+ droneTrackBillboardCollection = null
+ }
+ if (droneTrackPolylineCollection) {
+ droneTrackPolylineCollection.removeAll()
+ removeCockpitPrimitive(droneTrackPolylineCollection)
+ droneTrackPolylineCollection = null
+ }
+ droneTrackRuntime = []
+ stopDroneTrackAnimation()
+}
+
+
+const ensureDroneTrackCollections = () => {
+ if (!viewer) return
+ ensureCockpitPrimitiveLayer()
+ if (!droneTrackBillboardCollection) {
+ droneTrackBillboardCollection = new Cesium.BillboardCollection()
+ addCockpitPrimitive(droneTrackBillboardCollection)
+ }
+ if (!droneTrackPolylineCollection) {
+ droneTrackPolylineCollection = new Cesium.PolylineCollection()
+ addCockpitPrimitive(droneTrackPolylineCollection)
+ }
+}
+
+const startDroneTrackAnimation = () => {
+ if (!viewer) return
+ stopDroneTrackAnimation()
+ droneTrackStartTime = Cesium.JulianDate.now()
+ droneTrackTickHandler = clock => {
+ if (!droneTrackRuntime.length) return
+ const current = clock.currentTime
+ const elapsed = Cesium.JulianDate.secondsDifference(current, droneTrackStartTime)
+ droneTrackRuntime.forEach(track => {
+ const duration = track.duration
+ if (duration <= 0) return
+ const t = ((elapsed % duration) + duration) % duration
+ const seg = Math.min(track.positions.length - 2, Math.floor(t / track.segmentDuration))
+ const ratio = (t - seg * track.segmentDuration) / track.segmentDuration
+ const pos = Cesium.Cartesian3.lerp(
+ track.positions[seg],
+ track.positions[seg + 1],
+ ratio,
+ new Cesium.Cartesian3()
+ )
+ track.billboard.position = pos
+ })
+ }
+ viewer.clock.onTick.addEventListener(droneTrackTickHandler)
+ viewer.clock.shouldAnimate = true
+}
+
+const stopDroneTrackAnimation = () => {
+ if (!viewer || !droneTrackTickHandler) return
+ viewer.clock.onTick.removeEventListener(droneTrackTickHandler)
+ droneTrackTickHandler = null
+}
+
+const renderSimulatedDroneTrack = () => {
+ if (!viewer) return
+ ensureCountyCenterMap()
+ ensureDroneTrackCollections()
+ droneTrackBillboardCollection.removeAll()
+ droneTrackPolylineCollection.removeAll()
+ droneTrackRuntime = []
+ const centers = Array.from(countyCenterMap.values())
+ const baseCenters = centers.length ? centers.slice(0, 4) : [{ longitude: 116.397, latitude: 39.908 }]
+ const segmentDuration = 6
+ baseCenters.forEach((center, trackIndex) => {
+ const points = buildSimulatedTrackPoints(center)
+ if (points.length < 2) return
+ const positions = points.map(point =>
+ Cesium.Cartesian3.fromDegrees(point.longitude, point.latitude, point.height)
+ )
+ droneTrackPolylineCollection.add({
+ positions,
+ width: 2,
+ material: Cesium.Material.fromType('Color', {
+ color: Cesium.Color.fromCssColorString('#2AEDBF'),
+ }),
+ })
+ const billboard = droneTrackBillboardCollection.add({
+ position: positions[0],
+ image: droneIcon,
+ width: 36,
+ height: 36,
+ verticalOrigin: Cesium.VerticalOrigin.CENTER,
+ })
+ droneTrackRuntime.push({
+ positions,
+ billboard,
+ segmentDuration,
+ duration: (points.length - 1) * segmentDuration,
+ })
+ })
+ viewer.clock.multiplier = 1
+ startDroneTrackAnimation()
+ reorderCockpitPrimitives()
+}
const RING_STYLES = [
{ inner: 0, outer: 2000, gradient: ['#FF361C', '#360B00'] }
]
const MATERIAL_TYPE = 'RadialGradientMaterial'
+const TEXTURED_VERTEX_FORMAT =
+ Cesium.MaterialAppearance?.MaterialSupport?.TEXTURED?.vertexFormat || Cesium.VertexFormat.POSITION_AND_ST
let materialRegistered = false
const registerRadialGradientMaterial = () => {
@@ -287,27 +525,39 @@
return positions
}
-const addDeviceRings = (center, baseId, visible) => {
+const addDeviceRings = (center, ringFillInstancesByStyle, ringOutlineInstancesByStyle) => {
+ if (!ringFillInstancesByStyle) return
+ const centerPosition = Cesium.Cartesian3.fromDegrees(center.longitude, center.latitude, 0)
RING_STYLES.forEach((ring, index) => {
- const outerPositions = buildCirclePositions(center, ring.outer)
- const holes = ring.inner
- ? [new Cesium.PolygonHierarchy(buildCirclePositions(center, ring.inner))]
- : []
- const entityId = `${baseId}-ring-${index}`
- deviceEntityIds.add(entityId)
- registerRadialGradientMaterial()
- const [startColor, endColor] = ring.gradient
- const color1 = Cesium.Color.fromCssColorString(startColor).withAlpha(0.34)
- const color2 = Cesium.Color.fromCssColorString(endColor).withAlpha(0.34)
- const material = new RadialGradientMaterialProperty(color1, color2)
- viewer.entities.add({
- id: entityId,
- show: visible,
- polygon: {
- hierarchy: new Cesium.PolygonHierarchy(outerPositions, holes),
- material,
- },
- })
+ if (!ringFillInstancesByStyle[index]) return
+ ringFillInstancesByStyle[index].push(
+ new Cesium.GeometryInstance({
+ geometry: new Cesium.EllipseGeometry({
+ center: centerPosition,
+ semiMajorAxis: ring.outer,
+ semiMinorAxis: ring.outer,
+ vertexFormat: TEXTURED_VERTEX_FORMAT,
+ }),
+ })
+ )
+ })
+ if (!ringOutlineInstancesByStyle) return
+ RING_STYLES.forEach((ring, index) => {
+ if (!ringOutlineInstancesByStyle[index]) return
+ const positions = buildCirclePositions(center, ring.outer)
+ ringOutlineInstancesByStyle[index].push(
+ new Cesium.GeometryInstance({
+ geometry: new Cesium.GroundPolylineGeometry({
+ positions,
+ width: 2,
+ }),
+ attributes: {
+ color: Cesium.ColorGeometryInstanceAttribute.fromColor(
+ Cesium.Color.fromCssColorString(ring.gradient[0]).withAlpha(0.8)
+ ),
+ },
+ })
+ )
})
}
@@ -348,29 +598,69 @@
const renderDeviceEntities = devices => {
if (!viewer) return
- clearDeviceEntities()
+ ensureCockpitPrimitiveLayer()
+ ensureDeviceCollections()
+ deviceBillboardCollection.removeAll()
+ if (deviceRingFillPrimitives.length) {
+ deviceRingFillPrimitives.forEach(primitive => removeCockpitPrimitive(primitive))
+ deviceRingFillPrimitives = []
+ }
+ if (deviceRingOutlinePrimitives.length) {
+ deviceRingOutlinePrimitives.forEach(primitive => removeCockpitPrimitive(primitive))
+ deviceRingOutlinePrimitives = []
+ }
+ devicePickMap.clear()
+ deviceBillboardCollection.show = detailVisible.value
+ const ringFillInstancesByStyle = RING_STYLES.map(() => [])
+ const ringOutlineInstancesByStyle = RING_STYLES.map(() => [])
devices.forEach((item, index) => {
const position = getDevicePosition(item)
if (!position) return
const entityId = `online-device-${item.id ?? index}-${index}`
- deviceEntityIds.add(entityId)
- addDeviceRings(position, entityId, detailVisible.value)
- const entity = viewer.entities.add({
- id: entityId,
- show: detailVisible.value,
+ addDeviceRings(position, ringFillInstancesByStyle, ringOutlineInstancesByStyle)
+ const billboard = deviceBillboardCollection.add({
position: Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, 0),
- billboard: {
- image: equipmentIcon,
- width: 40,
- height: 56,
- verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
- },
+ image: equipmentIcon,
+ width: 40,
+ height: 56,
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
})
- deviceEntityMap.set(entityId, { data: item, entity })
+ billboard.id = entityId
+ devicePickMap.set(entityId, { data: item, billboard })
})
- if (selectedDeviceEntity && !deviceEntityMap.has(selectedDeviceEntity.id)) {
+ if (selectedDeviceBillboard && !devicePickMap.has(selectedDeviceBillboard.id)) {
closePopup()
}
+ registerRadialGradientMaterial()
+ ringFillInstancesByStyle.forEach((instances, index) => {
+ if (!instances.length) return
+ const ring = RING_STYLES[index]
+ const material = Cesium.Material.fromType(MATERIAL_TYPE, {
+ color1: Cesium.Color.fromCssColorString(ring.gradient[0]).withAlpha(0.64),
+ color2: Cesium.Color.fromCssColorString(ring.gradient[1]).withAlpha(0.64),
+ })
+ const primitive = new Cesium.GroundPrimitive({
+ geometryInstances: instances,
+ appearance: new Cesium.MaterialAppearance({
+ material,
+ translucent: true,
+ }),
+ })
+ primitive.show = detailVisible.value
+ addCockpitPrimitive(primitive)
+ deviceRingFillPrimitives.push(primitive)
+ })
+ ringOutlineInstancesByStyle.forEach(instances => {
+ if (!instances.length) return
+ const primitive = new Cesium.GroundPolylinePrimitive({
+ geometryInstances: instances,
+ appearance: new Cesium.PolylineColorAppearance(),
+ })
+ primitive.show = detailVisible.value
+ addCockpitPrimitive(primitive)
+ deviceRingOutlinePrimitives.push(primitive)
+ })
+ reorderCockpitPrimitives()
}
const getDefenseZonePositions = geom => {
@@ -385,70 +675,87 @@
return list.map(item => Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude))
}
-const renderZonePolygons = ({ zones, source, idPrefix, lineColor, fillGradient }) => {
- if (!viewer || !source) return
+const buildZonePrimitives = (zones, lineColor, fillColor1, fillColor2) => {
+ if (!viewer) return { primitive: null, outlinePrimitive: null }
+ const polygonInstances = []
+ const lineInstances = []
registerRadialGradientMaterial()
- const borderColor = Cesium.Color.fromCssColorString(lineColor)
- const fillColorStart = Cesium.Color.fromCssColorString(fillGradient[0]).withAlpha(0.34)
- const fillColorEnd = Cesium.Color.fromCssColorString(fillGradient[1]).withAlpha(0.34)
- const fillMaterial = new RadialGradientMaterialProperty(fillColorStart, fillColorEnd)
- zones.forEach((zone, index) => {
+ ; (zones || []).forEach((zone, index) => {
if (!zone?.geom) return
const positions = getDefenseZonePositions(zone.geom)
if (!positions.length) return
- const entityId = `${idPrefix}-${zone.id ?? index}`
- const linePositions = positions.length > 1 ? [...positions, positions[0]] : positions
- source.entities.add({
- id: entityId,
- polygon: {
- hierarchy: new Cesium.PolygonHierarchy(positions),
- material: fillMaterial,
- outline: true,
- outlineColor: borderColor,
- heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
- },
- polyline: {
- positions: linePositions,
- clampToGround: true,
- width: 2,
- material: borderColor,
- },
+ const polygon = new Cesium.PolygonGeometry({
+ polygonHierarchy: new Cesium.PolygonHierarchy(positions),
+ vertexFormat: TEXTURED_VERTEX_FORMAT,
})
+ polygonInstances.push(
+ new Cesium.GeometryInstance({
+ geometry: polygon,
+ })
+ )
+ const linePositions = positions.length > 1 ? [...positions, positions[0]] : positions
+ lineInstances.push(
+ new Cesium.GeometryInstance({
+ geometry: new Cesium.GroundPolylineGeometry({
+ positions: linePositions,
+ width: 2,
+ }),
+ attributes: {
+ color: Cesium.ColorGeometryInstanceAttribute.fromColor(
+ Cesium.Color.fromCssColorString(lineColor)
+ ),
+ },
+ })
+ )
})
+ let primitive = null
+ if (polygonInstances.length) {
+ const baseColor1 = Cesium.Color.fromCssColorString(fillColor1)
+ const baseColor2 = Cesium.Color.fromCssColorString(fillColor2)
+ const material = Cesium.Material.fromType(MATERIAL_TYPE, {
+ color1: baseColor1.withAlpha(0.64),
+ color2: baseColor2.withAlpha(0.64),
+ })
+ primitive = new Cesium.GroundPrimitive({
+ geometryInstances: polygonInstances,
+ appearance: new Cesium.MaterialAppearance({
+ material,
+ translucent: true,
+ }),
+ })
+ addCockpitPrimitive(primitive)
+ }
+ let outlinePrimitive = null
+ if (lineInstances.length) {
+ outlinePrimitive = new Cesium.GroundPolylinePrimitive({
+ geometryInstances: lineInstances,
+ appearance: new Cesium.PolylineColorAppearance(),
+ })
+ addCockpitPrimitive(outlinePrimitive)
+ }
+ return { primitive, outlinePrimitive }
}
const renderDefenseZones = zones => {
if (!viewer) return
- if (!defenseZoneSource) {
- defenseZoneSource = new Cesium.CustomDataSource('defenseZoneSource')
- viewer.dataSources.add(defenseZoneSource)
- }
clearDefenseZoneEntities()
- defenseZoneSource.show = detailVisible.value
- renderZonePolygons({
- zones,
- source: defenseZoneSource,
- idPrefix: 'defense-zone',
- lineColor: '#19D266',
- fillGradient: ['#2AEDBF', '#012B11'],
- })
+ const result = buildZonePrimitives(zones, '#19D266', '#2AEDBF', '#012B11')
+ defenseZonePrimitive = result.primitive
+ defenseZoneOutlinePrimitive = result.outlinePrimitive
+ if (defenseZonePrimitive) defenseZonePrimitive.show = detailVisible.value
+ if (defenseZoneOutlinePrimitive) defenseZoneOutlinePrimitive.show = detailVisible.value
+ reorderCockpitPrimitives()
}
const renderPartitions = zones => {
if (!viewer) return
- if (!partitionSource) {
- partitionSource = new Cesium.CustomDataSource('partitionSource')
- viewer.dataSources.add(partitionSource)
- }
clearPartitionEntities()
- partitionSource.show = detailVisible.value
- renderZonePolygons({
- zones,
- source: partitionSource,
- idPrefix: 'partition-zone',
- lineColor: '#FFCD2A',
- fillGradient: ['#FFC609', '#583300'],
- })
+ const result = buildZonePrimitives(zones, '#FFCD2A', '#FFC609', '#583300')
+ partitionPrimitive = result.primitive
+ partitionOutlinePrimitive = result.outlinePrimitive
+ if (partitionPrimitive) partitionPrimitive.show = detailVisible.value
+ if (partitionOutlinePrimitive) partitionOutlinePrimitive.show = detailVisible.value
+ reorderCockpitPrimitives()
}
const loadDefenseZones = async () => {
@@ -517,19 +824,18 @@
const getPickedDevice = picks => {
for (const pick of picks) {
- const entityId = typeof pick?.id === 'string' ? pick.id : pick?.id?.id
- if (entityId && deviceEntityMap.has(entityId)) {
- return deviceEntityMap.get(entityId)
+ const pickId = pick?.id
+ const resolvedId = typeof pickId === 'string' ? pickId : pickId?.id
+ if (resolvedId && devicePickMap.has(resolvedId)) {
+ return devicePickMap.get(resolvedId)
}
}
return null
}
const updatePopupPosition = () => {
- if (!viewer || !selectedDeviceEntity) return
- const cartesian =
- selectedDeviceEntity.position?.getValue?.(Cesium.JulianDate.now()) ||
- selectedDeviceEntity.position?._value
+ if (!viewer || !selectedDeviceBillboard) return
+ const cartesian = selectedDeviceBillboard.position
if (!cartesian) return
const screenPosition = viewer.scene.cartesianToCanvasCoordinates(cartesian)
if (!screenPosition) return
@@ -558,7 +864,7 @@
return
}
selectedDevice.value = pickedDevice.data
- selectedDeviceEntity = pickedDevice.entity
+ selectedDeviceBillboard = pickedDevice.billboard
startPopupRender()
}
@@ -576,7 +882,7 @@
function closePopup () {
selectedDevice.value = null
- selectedDeviceEntity = null
+ selectedDeviceBillboard = null
stopPopupRender()
}
@@ -654,27 +960,21 @@
const renderCommandPosts = list => {
if (!viewer) return
- if (!commandPostSource) {
- commandPostSource = new Cesium.CustomDataSource('commandPostSource')
- viewer.dataSources.add(commandPostSource)
- }
- clearCommandPostEntities()
- commandPostSource.show = detailVisible.value
- ; (list || []).forEach((item, index) => {
- const position = getDevicePosition(item)
- if (!position) return
- commandPostSource.entities.add({
- id: `command-post-${item.id ?? index}`,
- position: Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, 0),
- billboard: {
- image: commandPostIcon,
- width: 40,
- height: 56,
- verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
- heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
- },
- })
+ ensureCommandPostCollection()
+ commandPostBillboardCollection.removeAll()
+ commandPostBillboardCollection.show = detailVisible.value
+ ; (list || []).forEach((item, index) => {
+ const position = getDevicePosition(item)
+ if (!position) return
+ commandPostBillboardCollection.add({
+ position: Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, 0),
+ image: commandPostIcon,
+ width: 40,
+ height: 56,
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
})
+ })
+ reorderCockpitPrimitives()
}
const loadAggregation = async () => {
@@ -724,6 +1024,7 @@
const handleMapReady = ({ viewer: mapViewer }) => {
viewer = mapViewer
+ ensureCockpitPrimitiveLayer()
const height = viewer?.camera?.positionCartographic?.height
const stage = height != null && height >= 100000 ? 'cluster' : 'detail'
updateStageDisplay(stage)
@@ -732,6 +1033,7 @@
loadPartitions()
loadAggregation()
loadCommandPosts()
+ renderSimulatedDroneTrack()
initDeviceClickHandler()
}
@@ -759,8 +1061,13 @@
clearPartitionEntities()
clearAggregationEntities()
clearCommandPostEntities()
+ clearDroneTrackEntities()
closePopup()
destroyDeviceClickHandler()
+ if (cockpitPrimitiveLayer && viewer?.scene?.primitives) {
+ viewer.scene.primitives.remove(cockpitPrimitiveLayer)
+ }
+ cockpitPrimitiveLayer = null
viewer = null
})
</script>
@@ -1092,3 +1399,4 @@
border-color: #a1a3d4;
}
</style>
+
--
Gitblit v1.9.3