吉安感知网项目-前端
shuishen
2026-02-03 89380e6260a75d1d3b94de687ebcc2f50d50659d
applications/drone-command/src/utils/cesium/publicCesium.js
@@ -2,6 +2,7 @@
import * as Cesium from 'cesium'
import { Cartesian3, Terrain, Viewer } from 'cesium'
import store from '@/store/index'
import jaGeojsonRaw from '@/assets/geojson/ja.geojson?raw'
import getBaseConfig from '@/buildConfig/config'
@@ -32,6 +33,36 @@
/**
 * 公共的Cesium (蓝色,2d)
 */
const DEFAULT_VIEW_RECTANGLE = (() => {
   try {
      const geojson = JSON.parse(jaGeojsonRaw)
      let west = Infinity
      let east = -Infinity
      let south = Infinity
      let north = -Infinity
      const walk = coords => {
         if (!Array.isArray(coords)) return
         if (typeof coords[0] === 'number' && typeof coords[1] === 'number') {
            const lng = coords[0]
            const lat = coords[1]
            if (!Number.isFinite(lng) || !Number.isFinite(lat)) return
            west = Math.min(west, lng)
            east = Math.max(east, lng)
            south = Math.min(south, lat)
            north = Math.max(north, lat)
            return
         }
         coords.forEach(walk)
      }
      geojson?.features?.forEach(feature => walk(feature?.geometry?.coordinates))
      if ([west, east, south, north].every(Number.isFinite)) {
         return Cesium.Rectangle.fromDegrees(west, south, east, north)
      }
   } catch (error) {}
   return Cesium.Rectangle.fromDegrees(66, 4, 135, 53.55)
})()
// 封装的不用管
let cn = {
@@ -83,6 +114,9 @@
      this.handlerRightEvents = { handler: null }
      this.handlerMouseMoveEvents = { handler: null }
      this.viewer = null
      this.terrainProvider = null
      this.terrainLoading = null
      this.terrainEnabled = false
      this.globalBaseMapLayers = []
      this.boundary = null
      this.init(options)
@@ -100,13 +134,13 @@
         dockOptions = {},
         boundaryChange,
         terrainLoadCallback,
         boundaryColor = '#7FFFD4',
         boundaryColor = '#00F9EC',
         dockRangeType = 1,
         useDockHeight = false
      } = options
      Cesium.Camera.DEFAULT_VIEW_FACTOR = -0.45
      // 西南东北,默认显示中国
      Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(66, 4, 135, 53.55)
      Cesium.Camera.DEFAULT_VIEW_RECTANGLE = DEFAULT_VIEW_RECTANGLE
      const viewerOptions = {
         infoBox: false, // 禁用沙箱,解决控制台报错
         animation: false, // 左下角的动画仪表盘
@@ -146,52 +180,7 @@
      this.viewer?.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK) // 禁用双击
      if (terrain) {
         try {
            const noTerrainMechanism = ['1962779164650135554']
            if (noTerrainMechanism.includes(store.state.user.userInfo?.deptId)) {
               // 使用Cesium World Terrain
               Cesium.createWorldTerrainAsync({
                  requestWaterMask: false,    // 请求水域效果
                  requestVertexNormals: true // 请求光照和地形法线
               }).then(terrainProvider => {
                  this.viewer.terrainProvider = terrainProvider
                  terrainLoadCallback?.()
               })
            } else {
               /*// 正则:第一位非0,第二位任意数字,后10位都是0
               const re = /^[1-9]\d0{10}$/
               let result = null
               // 1️⃣先判断 areaCode
               if (re.test(store.state.user.userInfo.detail.areaCode)) {
                  result = store.state.user.userInfo.detail.areaCode.slice(0, 6)
               } else {
                  // 2️⃣如果不满足,从 ancestors 里找
                  const matchedItems = store.state.user.userInfo.detail.ancestors
                     .split(',')
                     .filter(item => re.test(item)) // 过滤出符合条件的
                  // 取第一个符合条件的前6位(可以改成 last one 看需求)
                  if (matchedItems.length > 0) {
                     result = matchedItems[0].slice(0, 6)
                  }
               }
               // 使用公司地形
               Cesium.CesiumTerrainProvider.fromUrl(`${import.meta.env.VITE_APP_TERRAIN_URL}${result}`, {
                  requestVertexNormals: true, // 启用地形法线增强立体感
                  requestWaterMask: true, // 启用水体遮罩效果
               }).then(terrainProvider => {
                  this.viewer.terrainProvider = terrainProvider
                  terrainLoadCallback?.()
               })*/
            }
         } catch (error) {
            console.error('地形加载失败:', error)
         }
      }
      this.setTerrainVisible(terrain, terrainLoadCallback)
      this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = 4500000
      this.switchLayers(layerMode)
@@ -210,6 +199,40 @@
      return this.viewer
   }
   async ensureTerrainProvider () {
      if (this.terrainProvider) return this.terrainProvider
      if (this.terrainLoading) return this.terrainLoading
      this.terrainLoading = Cesium.CesiumTerrainProvider.fromUrl(
         `${import.meta.env.VITE_APP_TERRAIN_URL}ja_terrain`,
         {
            requestVertexNormals: true, // 启用地形法线增强立体感
            requestWaterMask: true, // 启用水体遮罩效果
         }
      ).then(provider => {
         this.terrainProvider = provider
         return provider
      })
      return this.terrainLoading
   }
   async setTerrainVisible (visible, terrainLoadCallback) {
      if (!this.viewer) return
      if (!visible) {
         this.viewer.terrainProvider = new Cesium.EllipsoidTerrainProvider()
         this.terrainEnabled = false
         return
      }
      try {
         const provider = await this.ensureTerrainProvider()
         if (!this.viewer) return
         this.viewer.terrainProvider = provider
         this.terrainEnabled = true
         terrainLoadCallback?.()
      } catch (error) {
         this.terrainEnabled = false
      }
   }
   // 销毁viewer
   viewerDestroy (removeDom = true) {
      if (!this.viewer) return