From afbb44a7f2fe594d37cba5ee83cd0c49963e85a9 Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Fri, 30 Jan 2026 13:50:03 +0800
Subject: [PATCH] feat:首页数据驾驶舱加载调整处理
---
applications/drone-command/src/components/map-container/device-map-container.vue | 273 ++++++++++++++++++++++++++++++++++-------------------
1 files changed, 174 insertions(+), 99 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 d877826..82c1f57 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
@@ -69,11 +69,13 @@
createRadialGradientMaterial,
getTexturedVertexFormat,
} from './device-map-materials'
+import { getPointPositionsHeight } from '@/utils/cesium/mapUtil'
import dzIcon from '@/assets/images/dataCockpit/map/dz-map-layer.png'
import yxIcon from '@/assets/images/dataCockpit/map/yx-map-layer.png'
const CLUSTER_HEIGHT = 100000
const DETAIL_HEIGHT = 10000
+const POLYGON_HEIGHT_M = 0.2
const props = defineProps({
onlineDevices: {
@@ -112,8 +114,8 @@
let deviceRingFillPrimitives = []
let defenseZonePrimitive = null
let defenseZoneOutlinePrimitive = null
-let partitionPrimitive = null
-let partitionOutlinePrimitive = null
+let partitionFillPrimitives = []
+let partitionOutlinePrimitives = []
let aggregationSource = null
let commandPostBillboardCollection = null
let droneTrackBillboardCollection = null
@@ -284,8 +286,12 @@
cockpitPrimitiveLayer.removeAll(false)
if (defenseZonePrimitive) cockpitPrimitiveLayer.add(defenseZonePrimitive)
if (defenseZoneOutlinePrimitive) cockpitPrimitiveLayer.add(defenseZoneOutlinePrimitive)
- if (partitionPrimitive) cockpitPrimitiveLayer.add(partitionPrimitive)
- if (partitionOutlinePrimitive) cockpitPrimitiveLayer.add(partitionOutlinePrimitive)
+ if (partitionFillPrimitives.length) {
+ partitionFillPrimitives.forEach(primitive => cockpitPrimitiveLayer.add(primitive))
+ }
+ if (partitionOutlinePrimitives.length) {
+ partitionOutlinePrimitives.forEach(primitive => cockpitPrimitiveLayer.add(primitive))
+ }
if (deviceRingFillPrimitives.length) {
deviceRingFillPrimitives.forEach(primitive => cockpitPrimitiveLayer.add(primitive))
}
@@ -339,13 +345,13 @@
const clearPartitionEntities = () => {
if (!viewer) return
- if (partitionPrimitive) {
- removeCockpitPrimitive(partitionPrimitive)
- partitionPrimitive = null
+ if (partitionFillPrimitives.length) {
+ partitionFillPrimitives.forEach(primitive => removeCockpitPrimitive(primitive))
+ partitionFillPrimitives = []
}
- if (partitionOutlinePrimitive) {
- removeCockpitPrimitive(partitionOutlinePrimitive)
- partitionOutlinePrimitive = null
+ if (partitionOutlinePrimitives.length) {
+ partitionOutlinePrimitives.forEach(primitive => removeCockpitPrimitive(primitive))
+ partitionOutlinePrimitives = []
}
}
@@ -382,8 +388,16 @@
detailVisible.value = visible
if (defenseZonePrimitive) defenseZonePrimitive.show = visible
if (defenseZoneOutlinePrimitive) defenseZoneOutlinePrimitive.show = visible
- if (partitionPrimitive) partitionPrimitive.show = visible
- if (partitionOutlinePrimitive) partitionOutlinePrimitive.show = visible
+ if (partitionFillPrimitives.length) {
+ partitionFillPrimitives.forEach(primitive => {
+ primitive.show = visible
+ })
+ }
+ if (partitionOutlinePrimitives.length) {
+ partitionOutlinePrimitives.forEach(primitive => {
+ primitive.show = visible
+ })
+ }
if (commandPostBillboardCollection) commandPostBillboardCollection.show = visible
if (deviceBillboardCollection) deviceBillboardCollection.show = visible
if (deviceRingFillPrimitives.length) {
@@ -793,49 +807,76 @@
return list.map(item => Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude))
}
+const elevatePositions = async (positions, height = POLYGON_HEIGHT_M) => {
+ if (!Array.isArray(positions) || !positions.length) return []
+ if (!viewer) return positions
+ const points = positions
+ .map(pos => {
+ const carto = Cesium.Cartographic.fromCartesian(pos)
+ if (!carto) return null
+ return {
+ lng: Cesium.Math.toDegrees(carto.longitude),
+ lat: Cesium.Math.toDegrees(carto.latitude),
+ }
+ })
+ .filter(Boolean)
+ if (!points.length) return positions
+ const heights = await getPointPositionsHeight(points, viewer)
+ return heights.map(item => Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude, (item.ASL ?? 0) + height))
+}
+
const getAreaTypeStyle = areaType => {
return AREA_TYPE_STYLE_MAP?.[String(areaType)] || DEFAULT_AREA_STYLE
}
-const buildZonePrimitives = (zones, lineColor, fillColor1, fillColor2) => {
+const buildZonePrimitives = async (zones, lineColor, fillColor1, fillColor2) => {
if (!viewer) return { primitive: null, outlinePrimitive: null }
const polygonInstances = []
const lineInstances = []
+ const positionGroups = []
const texturedVertexFormat = getTexturedVertexFormat()
- ; (zones || []).forEach((zone, index) => {
+ ; (zones || []).forEach(zone => {
if (!zone?.geom) return
const positions = getDefenseZonePositions(zone.geom)
if (!positions.length) return
- const polygon = new Cesium.PolygonGeometry({
- polygonHierarchy: new Cesium.PolygonHierarchy(positions),
- vertexFormat: texturedVertexFormat,
- })
- 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)
- ),
- },
- })
- )
+ positionGroups.push(positions)
})
+ if (!positionGroups.length) return { primitive: null, outlinePrimitive: null }
+ const elevatedGroups = await Promise.all(positionGroups.map(group => elevatePositions(group)))
+ elevatedGroups.forEach(elevatedPositions => {
+ if (!elevatedPositions.length) return
+ const polygon = new Cesium.PolygonGeometry({
+ polygonHierarchy: new Cesium.PolygonHierarchy(elevatedPositions),
+ perPositionHeight: true,
+ vertexFormat: texturedVertexFormat,
+ })
+ polygonInstances.push(
+ new Cesium.GeometryInstance({
+ geometry: polygon,
+ })
+ )
+ const linePositions =
+ elevatedPositions.length > 1 ? [...elevatedPositions, elevatedPositions[0]] : elevatedPositions
+ lineInstances.push(
+ new Cesium.GeometryInstance({
+ geometry: new Cesium.PolylineGeometry({
+ 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 = createRadialGradientMaterial(baseColor1.withAlpha(0.64), baseColor2.withAlpha(0.64))
- primitive = new Cesium.GroundPrimitive({
+ primitive = new Cesium.Primitive({
geometryInstances: polygonInstances,
appearance: new Cesium.MaterialAppearance({
material,
@@ -846,7 +887,7 @@
}
let outlinePrimitive = null
if (lineInstances.length) {
- outlinePrimitive = new Cesium.GroundPolylinePrimitive({
+ outlinePrimitive = new Cesium.Primitive({
geometryInstances: lineInstances,
appearance: new Cesium.PolylineColorAppearance(),
})
@@ -855,58 +896,84 @@
return { primitive, outlinePrimitive }
}
-const buildPartitionPrimitives = shapes => {
- if (!viewer) return { primitive: null, outlinePrimitive: null }
- const polygonInstances = []
- const lineInstances = []
- const vertexFormat = Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
+const buildPartitionPrimitives = async shapes => {
+ if (!viewer) return { primitives: [], outlinePrimitives: [] }
+ const vertexFormat = getTexturedVertexFormat()
+ const groups = new Map()
+ const tasks = []
; (shapes || []).forEach(shape => {
if (!shape?.positions || shape.positions.length < 3) return
+ const outlineColor = shape.outlineColor
+ const fillColor = shape.fillColor
+ const key = `${outlineColor.toCssColorString()}|${fillColor.toCssColorString()}`
+ if (!groups.has(key)) {
+ groups.set(key, { outlineColor, fillColor, polygonInstances: [], lineInstances: [] })
+ }
+ const group = groups.get(key)
const positions = shape.positions
- const polygon = new Cesium.PolygonGeometry({
- polygonHierarchy: new Cesium.PolygonHierarchy(positions),
- vertexFormat,
+ tasks.push(
+ elevatePositions(positions).then(elevatedPositions => {
+ if (!elevatedPositions.length) return
+ const polygon = new Cesium.PolygonGeometry({
+ polygonHierarchy: new Cesium.PolygonHierarchy(elevatedPositions),
+ perPositionHeight: true,
+ vertexFormat,
+ })
+ group.polygonInstances.push(
+ new Cesium.GeometryInstance({
+ geometry: polygon,
+ })
+ )
+ const linePositions =
+ elevatedPositions.length > 1
+ ? [...elevatedPositions, elevatedPositions[0]]
+ : elevatedPositions
+ group.lineInstances.push(
+ new Cesium.GeometryInstance({
+ geometry: new Cesium.PolylineGeometry({
+ positions: linePositions,
+ width: 2,
+ }),
+ attributes: {
+ color: Cesium.ColorGeometryInstanceAttribute.fromColor(outlineColor),
+ },
+ })
+ )
+ })
+ )
+ })
+
+ if (tasks.length) await Promise.all(tasks)
+
+ const primitives = []
+ const outlinePrimitives = []
+ groups.forEach(group => {
+ if (group.polygonInstances.length) {
+ const material = createRadialGradientMaterial(group.outlineColor, group.fillColor, {
+ gamma: 1.7,
+ innerCutoff: 0,
})
- polygonInstances.push(
- new Cesium.GeometryInstance({
- geometry: polygon,
- attributes: {
- color: Cesium.ColorGeometryInstanceAttribute.fromColor(shape.fillColor),
- },
- })
- )
- 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(
- shape.outlineColor
- ),
- },
- })
- )
- })
- let primitive = null
- if (polygonInstances.length) {
- primitive = new Cesium.GroundPrimitive({
- geometryInstances: polygonInstances,
- appearance: new Cesium.PerInstanceColorAppearance({ translucent: true, flat: 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 primitive = new Cesium.Primitive({
+ geometryInstances: group.polygonInstances,
+ appearance: new Cesium.MaterialAppearance({
+ material,
+ translucent: true,
+ }),
+ })
+ addCockpitPrimitive(primitive)
+ primitives.push(primitive)
+ }
+ if (group.lineInstances.length) {
+ const outlinePrimitive = new Cesium.Primitive({
+ geometryInstances: group.lineInstances,
+ appearance: new Cesium.PolylineColorAppearance(),
+ })
+ addCockpitPrimitive(outlinePrimitive)
+ outlinePrimitives.push(outlinePrimitive)
+ }
+ })
+
+ return { primitives, outlinePrimitives }
}
const parseGeomJson = geomJson => {
@@ -995,10 +1062,10 @@
return shapes
}
-const renderDefenseZones = zones => {
+const renderDefenseZones = async zones => {
if (!viewer) return
clearDefenseZoneEntities()
- const result = buildZonePrimitives(zones, '#72F3FF', '#72F3FF', '#0A7C88')
+ const result = await buildZonePrimitives(zones, '#72F3FF', '#72F3FF', '#0A7C88')
defenseZonePrimitive = result.primitive
defenseZoneOutlinePrimitive = result.outlinePrimitive
if (defenseZonePrimitive) defenseZonePrimitive.show = detailVisible.value
@@ -1006,15 +1073,23 @@
reorderCockpitPrimitives()
}
-const renderPartitions = zones => {
+const renderPartitions = async zones => {
if (!viewer) return
clearPartitionEntities()
const shapes = resolvePartitionShapes(zones)
- const result = buildPartitionPrimitives(shapes)
- partitionPrimitive = result.primitive
- partitionOutlinePrimitive = result.outlinePrimitive
- if (partitionPrimitive) partitionPrimitive.show = detailVisible.value
- if (partitionOutlinePrimitive) partitionOutlinePrimitive.show = detailVisible.value
+ const result = await buildPartitionPrimitives(shapes)
+ partitionFillPrimitives = result.primitives
+ partitionOutlinePrimitives = result.outlinePrimitives
+ if (partitionFillPrimitives.length) {
+ partitionFillPrimitives.forEach(primitive => {
+ primitive.show = detailVisible.value
+ })
+ }
+ if (partitionOutlinePrimitives.length) {
+ partitionOutlinePrimitives.forEach(primitive => {
+ primitive.show = detailVisible.value
+ })
+ }
reorderCockpitPrimitives()
}
@@ -1022,9 +1097,9 @@
if (!viewer) return
try {
const res = await fwDefenseZonePageApi({ current: 1, size: DEFAULT_ZONE_PAGE_SIZE })
- renderDefenseZones(res?.data?.data?.records ?? [])
+ await renderDefenseZones(res?.data?.data?.records ?? [])
} catch (error) {
- renderDefenseZones([])
+ await renderDefenseZones([])
}
}
@@ -1032,9 +1107,9 @@
if (!viewer) return
try {
const res = await fwAreaDivideListApi()
- renderPartitions(res?.data?.data ?? [])
+ await renderPartitions(res?.data?.data ?? [])
} catch (error) {
- renderPartitions([])
+ await renderPartitions([])
}
}
--
Gitblit v1.9.3