吉安感知网项目-前端
shuishen
2026-02-03 89380e6260a75d1d3b94de687ebcc2f50d50659d
applications/drone-command/src/components/map-container/common-cesium-map.vue
@@ -1,9 +1,11 @@
<template>
   <div :id="mapId" class="common-cesium-map"></div>
   <div :id="mapId" class="common-cesium-map" @contextmenu.prevent></div>
</template>
<script setup>
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
import * as Cesium from 'cesium'
import { onBeforeUnmount, onMounted, watch } from 'vue'
import { PublicCesium } from '@/utils/cesium/publicCesium'
import { loadJaAdminBoundary, removeJaAdminBoundary } from '@/utils/cesium/adminBoundary'
@@ -60,8 +62,13 @@
const emit = defineEmits(['ready', 'height-change', 'stage-change'])
const mapId = props.domId || `common-cesium-map-${Math.random().toString(36).slice(2, 10)}`
const viewInstance = ref(null)
const viewer = ref(null)
let viewInstance = null
let viewer = null
const ADMIN_BOUNDARY_NAMES = {
   boundary: 'jaBoundarySource',
   line: 'jaBoundaryLineSource',
   label: 'jaBoundaryLabelSource',
}
let adminBoundarySources = null
let initialized = false
let removeCameraListener = null
@@ -69,7 +76,7 @@
const initMap = async () => {
   if (initialized) return
   initialized = true
   viewInstance.value = new PublicCesium({
   viewInstance = new PublicCesium({
      dom: mapId,
      flatMode: props.flatMode,
      terrain: props.terrain,
@@ -77,16 +84,16 @@
      boundary: props.boundary,
      contour: props.contour,
   })
   viewer.value = viewInstance.value.getViewer()
   viewer = viewInstance.getViewer()
   if (props.showAdminBoundary) {
      adminBoundarySources = await loadJaAdminBoundary(viewer.value, {
      adminBoundarySources = await loadJaAdminBoundary(viewer, {
         zoomTo: props.zoomToBoundary,
      })
   }
   if (props.enableStageEmit) {
      let lastStage = ''
      const onCameraChanged = () => {
         const height = viewer.value?.camera?.positionCartographic?.height
         const height = viewer?.camera?.positionCartographic?.height
         if (height == null) return
         emit('height-change', height)
         let stage = 'mid'
@@ -97,10 +104,10 @@
            emit('stage-change', stage)
         }
      }
      viewer.value?.camera?.changed?.addEventListener(onCameraChanged)
      removeCameraListener = () => viewer.value?.camera?.changed?.removeEventListener(onCameraChanged)
      viewer?.camera?.changed?.addEventListener(onCameraChanged)
      removeCameraListener = () => viewer?.camera?.changed?.removeEventListener(onCameraChanged)
   }
   emit('ready', { viewer: viewer.value, publicCesium: viewInstance.value })
   emit('ready', { viewer, publicCesium: viewInstance })
}
watch(
@@ -116,15 +123,87 @@
onBeforeUnmount(() => {
   if (removeCameraListener) removeCameraListener()
   removeJaAdminBoundary(viewer.value, adminBoundarySources)
   viewInstance.value?.viewerDestroy?.()
   removeJaAdminBoundary(viewer, adminBoundarySources)
   adminBoundarySources = null
   viewInstance?.viewerDestroy?.()
})
const getMap = () => ({ viewer: viewer.value, publicCesium: viewInstance.value })
const getViewer = () => viewer.value
const getPublicCesium = () => viewInstance.value
const setAdminBoundaryVisible = async visible => {
   if (!viewer) return
   const removeByNames = () => {
      Object.values(ADMIN_BOUNDARY_NAMES).forEach(name => {
         const sources = viewer.dataSources.getByName(name) || []
         sources.forEach(source => viewer.dataSources.remove(source))
      })
   }
   const resolveSources = () => {
      if (adminBoundarySources) return adminBoundarySources
      const boundarySource = viewer.dataSources.getByName(ADMIN_BOUNDARY_NAMES.boundary)?.[0] ?? null
      const lineSource = viewer.dataSources.getByName(ADMIN_BOUNDARY_NAMES.line)?.[0] ?? null
      const labelSource = viewer.dataSources.getByName(ADMIN_BOUNDARY_NAMES.label)?.[0] ?? null
      if (boundarySource || lineSource || labelSource) {
         adminBoundarySources = { boundarySource, lineSource, labelSource }
      }
      return adminBoundarySources
   }
   const setVisible = (source, next) => {
      if (!source) return
      source.show = next
      source.entities?.values?.forEach(entity => {
         entity.show = next
      })
   }
   const sources = resolveSources()
   if (!visible) {
      if (sources) {
         removeJaAdminBoundary(viewer, sources)
         adminBoundarySources = null
      }
      removeByNames()
      return
   }
   if (sources) {
      const { boundarySource, lineSource, labelSource } = sources
      setVisible(boundarySource, true)
      setVisible(lineSource, true)
      setVisible(labelSource, true)
      return
   }
   adminBoundarySources = await loadJaAdminBoundary(viewer, {
      zoomTo: false,
   })
}
defineExpose({ getMap, getViewer, getPublicCesium })
const zoomToAdminBoundary = async () => {
   if (!viewer) return
   const resolveSources = () => {
      if (adminBoundarySources) return adminBoundarySources
      const boundarySource = viewer.dataSources.getByName(ADMIN_BOUNDARY_NAMES.boundary)?.[0] ?? null
      const lineSource = viewer.dataSources.getByName(ADMIN_BOUNDARY_NAMES.line)?.[0] ?? null
      const labelSource = viewer.dataSources.getByName(ADMIN_BOUNDARY_NAMES.label)?.[0] ?? null
      if (boundarySource || lineSource || labelSource) {
         adminBoundarySources = { boundarySource, lineSource, labelSource }
      }
      return adminBoundarySources
   }
   let sources = resolveSources()
   if (!sources?.boundarySource) {
      sources = await loadJaAdminBoundary(viewer, { zoomTo: false })
      adminBoundarySources = sources
   }
   const target = sources?.boundarySource
   if (!target) return
   await viewer.flyTo(target, {
      duration: 0,
      offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-75), 0),
   })
}
const getMap = () => ({ viewer, publicCesium: viewInstance })
const getViewer = () => viewer
const getPublicCesium = () => viewInstance
defineExpose({ getMap, getViewer, getPublicCesium, setAdminBoundaryVisible, zoomToAdminBoundary })
</script>
<style scoped lang="scss">