吉安感知网项目-前端
罗广辉
2026-01-17 c53aab006b9db28e62381dba4fca4d77ec3566b0
applications/drone-command/src/components/map-container/device-map-container.vue
@@ -1,5 +1,18 @@
<template>
   <div class="command-cesium map-container" :id="props.containerId"></div>
   <CommonCesiumMap
      ref="mapRef"
      class="command-cesium map-container"
      :dom-id="props.containerId"
      :active="true"
      :flat-mode="false"
      :terrain="false"
      :layer-mode="4"
      :contour="false"
      :boundary="false"
      :show-admin-boundary="true"
      :zoom-to-boundary="true"
      @ready="handleMapReady"
   />
   <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">
@@ -25,11 +38,10 @@
<script setup>
import * as Cesium from 'cesium'
import { PublicCesium } from '@/utils/cesium/publicCesium'
import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue'
import { geomAnalysis } from '@ztzf/utils'
import { fwDefenseZonePageApi } from '@/views/areaManage/defenseZone/defenseZoneApi'
import { fwAreaDividePageApi } from '@/views/areaManage/partition/partitionApi'
import jaGeojsonRaw from '@/assets/geojson/ja.geojson?raw'
import layerControlIcon from '@/assets/images/dataCockpit/layerControl.png'
import equipmentIcon from '@/assets/images/dataCockpit/map/equipment.png'
@@ -54,15 +66,11 @@
const DEFAULT_ZONE_PAGE_SIZE = 999
let viewInstance = null
const mapRef = ref(null)
let viewer = null
const deviceEntityIds = new Set()
let defenseZoneSource = null
let partitionSource = null
let adminBoundarySource = null
let adminBoundaryLabelSource = null
let adminBoundaryLineSource = null
let adminBoundaryFlyDone = false
const showLayerPanel = ref(false)
const layerWrapRef = ref(null)
const layerTreeProps = {
@@ -127,20 +135,6 @@
   partitionSource.entities.removeAll()
}
const clearAdminBoundaryEntities = () => {
   if (!adminBoundarySource) return
   adminBoundarySource.entities.removeAll()
}
const clearAdminBoundaryLabels = () => {
   if (!adminBoundaryLabelSource) return
   adminBoundaryLabelSource.entities.removeAll()
}
const clearAdminBoundaryLines = () => {
   if (!adminBoundaryLineSource) return
   adminBoundaryLineSource.entities.removeAll()
}
const RING_STYLES = [
   { inner: 0, outer: 2000, gradient: ['#FF361C', '#360B00'] }
@@ -263,8 +257,9 @@
         position: Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, 0),
         billboard: {
            image: equipmentIcon,
            width: 40.34,
            height: 40.34,
            width: 40,
            height: 56,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
         },
      })
   })
@@ -366,83 +361,6 @@
   }
}
const loadAdminBoundary = async () => {
   if (!viewer) return
   try {
      if (adminBoundarySource) {
         viewer.dataSources.remove(adminBoundarySource)
         adminBoundarySource = null
      }
      if (adminBoundaryLabelSource) {
         viewer.dataSources.remove(adminBoundaryLabelSource)
         adminBoundaryLabelSource = null
      }
      if (adminBoundaryLineSource) {
         viewer.dataSources.remove(adminBoundaryLineSource)
         adminBoundaryLineSource = null
      }
      const geojson = JSON.parse(jaGeojsonRaw)
      adminBoundarySource = await Cesium.GeoJsonDataSource.load(geojson, {
         stroke: Cesium.Color.fromCssColorString('#FFFFFF'),
         strokeWidth: 2,
         fill: Cesium.Color.fromCssColorString('#FFFFFF').withAlpha(0.05),
         clampToGround: true,
      })
      viewer.dataSources.add(adminBoundarySource)
      if (!adminBoundaryFlyDone) {
         adminBoundaryFlyDone = true
         viewer.flyTo(adminBoundarySource, {
            duration: 0,
            offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-75), 0),
         })
      }
      adminBoundaryLineSource = new Cesium.CustomDataSource('adminBoundaryLineSource')
      adminBoundarySource.entities.values.forEach(entity => {
         const polygon = entity.polygon
         if (!polygon) return
         const hierarchy = polygon.hierarchy?.getValue?.(viewer.clock.currentTime)
         const positions = hierarchy?.positions
         if (!positions?.length) return
         adminBoundaryLineSource.entities.add({
            polyline: {
               positions,
               clampToGround: true,
               width: 2,
               material: Cesium.Color.WHITE,
            },
         })
      })
      viewer.dataSources.add(adminBoundaryLineSource)
      adminBoundaryLabelSource = new Cesium.CustomDataSource('adminBoundaryLabelSource')
      geojson.features?.forEach(feature => {
         const name = feature?.properties?.name
         const point = feature?.properties?.centroid || feature?.properties?.center
         if (!name || !Array.isArray(point) || point.length < 2) return
         adminBoundaryLabelSource.entities.add({
            position: Cesium.Cartesian3.fromDegrees(point[0], point[1]),
            label: {
               text: name,
               font: '14px Source Han Sans CN',
               fillColor: Cesium.Color.WHITE,
               outlineColor: Cesium.Color.BLACK.withAlpha(0.6),
               outlineWidth: 2,
               style: Cesium.LabelStyle.FILL_AND_OUTLINE,
               heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
               verticalOrigin: Cesium.VerticalOrigin.CENTER,
               horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
               disableDepthTestDistance: Number.POSITIVE_INFINITY,
            },
         })
      })
      viewer.dataSources.add(adminBoundaryLabelSource)
   } catch (error) {
      clearAdminBoundaryEntities()
      clearAdminBoundaryLabels()
      clearAdminBoundaryLines()
   }
}
watch(
   () => props.onlineDevices,
@@ -464,6 +382,13 @@
   showLayerPanel.value = !showLayerPanel.value
}
const handleMapReady = ({ viewer: mapViewer }) => {
   viewer = mapViewer
   renderDeviceEntities(props.onlineDevices)
   loadDefenseZones()
   loadPartitions()
}
const handleClickOutside = event => {
   if (!showLayerPanel.value) return
   const target = event.target
@@ -473,19 +398,8 @@
onMounted(() => {
   document.addEventListener('click', handleClickOutside)
   viewInstance = new PublicCesium({
      dom: props.containerId,
      flatMode: false,
      terrain: false,
      layerMode: 4,
      contour: false,
   })
   viewer = viewInstance.getViewer()
   renderDeviceEntities(props.onlineDevices)
   loadDefenseZones()
   loadPartitions()
   loadAdminBoundary()
   const map = mapRef.value?.getMap()
   if (map?.viewer) handleMapReady(map)
})
onBeforeUnmount(() => {
@@ -493,14 +407,6 @@
   clearDeviceEntities()
   clearDefenseZoneEntities()
   clearPartitionEntities()
   clearAdminBoundaryEntities()
   clearAdminBoundaryLabels()
   clearAdminBoundaryLines()
   if (viewInstance) {
      viewInstance?.viewerDestroy()
      viewInstance = null
   }
   viewer = null
})
</script>