From 8a7fb9a519cae32d38ba66058d243aa7e6b6aeb2 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Tue, 27 Jan 2026 08:57:49 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
applications/drone-command/src/components/map-container/device-map-container.vue | 122 +++++++++++++++++++++++++++++-----------
1 files changed, 89 insertions(+), 33 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 a8f8566..f5813aa 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
@@ -2,8 +2,9 @@
<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"
- :show-admin-boundary="true" :zoom-to-boundary="true" :enable-stage-emit="true" :cluster-height="100000"
- @ready="handleMapReady" @stage-change="handleStageChange" />
+ :show-admin-boundary="true" :zoom-to-boundary="true" :enable-stage-emit="true"
+ :cluster-height="CLUSTER_HEIGHT" :detail-height="DETAIL_HEIGHT" @ready="handleMapReady"
+ @stage-change="handleStageChange" />
<div v-if="props.showLayerControl" class="layer-control-root" :class="{ collapsed: props.leftCollapsed }">
<div class="layer-control-wrap" ref="layerWrapRef">
<div class="layer-control" @click="toggleLayerPanel">
@@ -63,6 +64,9 @@
createRadialGradientMaterial,
getTexturedVertexFormat,
} from './device-map-materials'
+
+const CLUSTER_HEIGHT = 100000
+const DETAIL_HEIGHT = 10000
const props = defineProps({
onlineDevices: {
@@ -157,6 +161,14 @@
const latitude = Number(latitudeRaw)
if (!Number.isFinite(longitude) || !Number.isFinite(latitude)) return null
return { longitude, latitude }
+}
+
+const getDeviceRange = item => {
+ if (!item) return null
+ const rawRange = item.effectiveRangeKm ?? item.range ?? item.coverRadiusM
+ const range = Number(rawRange)
+ if (!Number.isFinite(range) || range <= 0) return null
+ return range
}
const ensureCockpitPrimitiveLayer = () => {
@@ -305,6 +317,20 @@
if (aggregationSource) aggregationSource.show = visible
}
+const setDroneVisibility = visible => {
+ if (droneTrackBillboardCollection) droneTrackBillboardCollection.show = visible
+ if (droneTrackPolylineCollection) droneTrackPolylineCollection.show = visible
+ if (!visible && selectedTargetType.value === 'drone') {
+ closePopup()
+ }
+}
+const getStageByHeight = height => {
+ if (height == null) return 'detail'
+ if (height >= CLUSTER_HEIGHT) return 'cluster'
+ if (height <= DETAIL_HEIGHT) return 'detail'
+ return 'mid'
+}
+
const ensureCountyCenterMap = () => {
if (countyCenterMap.size) return
const geojson = JSON.parse(jaGeojsonRaw)
@@ -316,24 +342,44 @@
})
}
-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],
+const buildSimulatedTrackPoints = () => {
+ return [
+ {
+ longitude: 114.963191,
+ latitude: 27.136716,
+ height: 120
+ },
+ {
+ longitude:114.957308,
+ latitude: 27.138452,
+ height: 120
+ },
+ {
+ longitude:114.952,
+ latitude: 27.136317,
+ height: 120
+ },
+ {
+ longitude:114.949293,
+ latitude: 27.133864,
+ height: 120
+ },
+ {
+ longitude:114.944666,
+ latitude: 27.130526,
+ height: 120
+ },
+ {
+ longitude:114.945909,
+ latitude:27.127845,
+ height: 120
+ },
+ {
+ longitude:114.962974,
+ latitude:27.136242,
+ height: 120
+ },
]
- return offsets.map(item => ({
- longitude: anchor.longitude + item[0],
- latitude: anchor.latitude + item[1],
- height: item[2],
- }))
}
@@ -422,13 +468,11 @@
const renderSimulatedDroneTrack = () => {
if (!viewer) return
clearDroneTrackEntities()
- ensureCountyCenterMap()
ensureDroneTrackCollections()
+ droneTrackBillboardCollection.show = detailVisible.value
+ droneTrackPolylineCollection.show = detailVisible.value
droneTrackRuntime = []
- const centers = Array.from(countyCenterMap.entries())
- const baseCenters = centers.length
- ? centers.slice(0, 4)
- : [['默认区域', { longitude: 116.397, latitude: 39.908 }]]
+ const baseCenters = [['默认区域', { longitude:114.958541, latitude: 27.121917 }]]
const segmentDuration = 6
const baseTrackColor = Cesium.Color.fromCssColorString('red')
baseCenters.forEach(([centerName, center], trackIndex) => {
@@ -454,7 +498,7 @@
})
const droneId = `drone-track-${trackIndex}`
const billboard = droneTrackBillboardCollection.add({
- position: positions[0],
+ position: positions[positions.length - 1],
image: droneIcon,
width: 36,
height: 36,
@@ -511,7 +555,8 @@
const position = getDevicePosition(item)
if (!position) return
const entityId = `online-device-${item.id ?? index}-${index}`
- addDeviceRings(position, ringFillInstancesByStyle, ringOutlineInstancesByStyle)
+ const rangeMeters = getDeviceRange(item)
+ addDeviceRings(position, ringFillInstancesByStyle, ringOutlineInstancesByStyle, rangeMeters)
const billboard = deviceBillboardCollection.add({
position: Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, 0),
image: equipmentIcon,
@@ -528,9 +573,20 @@
ringFillInstancesByStyle.forEach((instances, index) => {
if (!instances.length) return
const ring = RING_STYLES[index]
+ const alpha = ring.alpha ?? 0.64
+ const innerRatio =
+ typeof ring.innerRatio === 'number'
+ ? ring.innerRatio
+ : ring.inner && ring.outer
+ ? Math.min(Math.max(ring.inner / ring.outer, 0), 0.9)
+ : 0
const material = createRadialGradientMaterial(
- Cesium.Color.fromCssColorString(ring.gradient[0]).withAlpha(0.64),
- Cesium.Color.fromCssColorString(ring.gradient[1]).withAlpha(0.64)
+ Cesium.Color.fromCssColorString(ring.gradient[0]).withAlpha(alpha),
+ Cesium.Color.fromCssColorString(ring.gradient[1]).withAlpha(alpha),
+ {
+ gamma: 1.7,
+ innerCutoff: innerRatio,
+ }
)
const primitive = new Cesium.GroundPrimitive({
geometryInstances: instances,
@@ -629,7 +685,7 @@
const renderDefenseZones = zones => {
if (!viewer) return
clearDefenseZoneEntities()
- const result = buildZonePrimitives(zones, '#19D266', '#2AEDBF', '#012B11')
+ const result = buildZonePrimitives(zones, '#72F3FF', '#72F3FF', '#0A7C88')
defenseZonePrimitive = result.primitive
defenseZoneOutlinePrimitive = result.outlinePrimitive
if (defenseZonePrimitive) defenseZonePrimitive.show = detailVisible.value
@@ -640,7 +696,7 @@
const renderPartitions = zones => {
if (!viewer) return
clearPartitionEntities()
- const result = buildZonePrimitives(zones, '#FFCD2A', '#FFC609', '#583300')
+ const result = buildZonePrimitives(zones, '#FFD772', '#FFD772', '#A86B00')
partitionPrimitive = result.primitive
partitionOutlinePrimitive = result.outlinePrimitive
if (partitionPrimitive) partitionPrimitive.show = detailVisible.value
@@ -693,7 +749,7 @@
width: 66.73,
height: 43,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
- heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+ // disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
label: {
text: `${count}`,
@@ -706,7 +762,6 @@
pixelOffset: new Cesium.Cartesian2(0, -35),
disableDepthTestDistance: Number.POSITIVE_INFINITY,
- heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
})
})
@@ -855,13 +910,14 @@
const showCluster = stage === 'cluster'
setClusterVisibility(showCluster)
setDetailVisibility(!showCluster)
+ setDroneVisibility(!showCluster)
}
const handleMapReady = ({ viewer: mapViewer }) => {
viewer = mapViewer
ensureCockpitPrimitiveLayer()
const height = viewer?.camera?.positionCartographic?.height
- const stage = height != null && height >= 100000 ? 'cluster' : 'detail'
+ const stage = getStageByHeight(height)
updateStageDisplay(stage)
renderDeviceEntities(props.onlineDevices)
loadDefenseZones()
--
Gitblit v1.9.3