吉安感知网项目-前端
shuishen
2026-01-16 efb3b5e84ed4493f82f30ed3c3dcdff0fd5a8083
applications/task-work-order/src/utils/cesium/publicCesium.js
@@ -70,6 +70,7 @@
 * @param {boolean} [options.flyToContour=false] - 是否飞行到轮廓,默认为 false
 * @param {number} [options.multiple=1.4] - 范围倍数
 * @param {number} [options.dockOptions={}] - 机巢显示
 * @param {array} [options.terrainLoadCallback] - 地形加载回调
 * @param {array} [options.boundaryChange] - 边界改变事件
 * @param {array} [options.boundaryColor] - 边界颜色
 * @param {array} [options.dockRangeType] - 机巢范围类型 1显示覆盖圆;2显示覆盖圈
@@ -92,15 +93,14 @@
         dom,
         flatMode = true,
         terrain = false,
         layerMode = 0,
         layerMode = 17,
         contour = true,
         flyToContour = false,
         multiple = 1.4,
         dockOptions = {},
         boundaryColor = '#7FFFD4',
         boundaryChange,
         terrainLoadCallback,
         boundaryColor = '#7FFFD4',
         dockRangeType = 1,
         useDockHeight = false
      } = options
@@ -120,6 +120,10 @@
         baseLayer: false,
         fullscreenButton: false,
      }
      // 尝试解决出现多个id相同的dom
      const domIdList = document.querySelectorAll(`#${dom}`)
      if (domIdList.length>1) domIdList[1].remove()
      this.viewer = new Viewer(dom, viewerOptions)
      this.viewerDom = dom
@@ -143,33 +147,47 @@
      this.viewer?.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK) // 禁用双击
      if (terrain) {
         // 正则:第一位非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)
            }
         }
         try {
            Cesium.CesiumTerrainProvider.fromUrl(`${import.meta.env.VITE_APP_TERRAIN_URL}${result}`, {
               requestVertexNormals: true, // 启用地形法线增强立体感
               requestWaterMask: true, // 启用水体遮罩效果
            }).then(terrainProvider => {
               this.viewer.terrainProvider = terrainProvider
            })
            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)
         }
@@ -180,6 +198,12 @@
      this.switchFlatMode(flatMode)
      this.switchContour(contour)
      flyToContour && this.flyToContour(contour)
      if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
         let dpr = window.devicePixelRatio
         while (dpr >= 2.0) dpr /= 2.0 // 避免过高缩放导致模糊
         this.viewer.resolutionScale = dpr // 设置分辨率缩放比例
      }
   }
   getViewer () {
@@ -188,53 +212,69 @@
   // 销毁viewer
   viewerDestroy (removeDom = true) {
      if (!this.viewer) return
      // // 👇 关键:先停止所有动态行为
      // this.viewer.clock.shouldAnimate = false;
      // this.viewer.scene.requestRenderMode = false;
      // // 取消所有可能的 pending 渲染
      // if (this.viewer.cesiumWidget) {
      //    this.viewer.cesiumWidget.render = () => {}; // 空函数覆盖
      // }
      // // 清理实体和图层
      // this.viewer?.entities.removeAll();
      // this.viewer?.imageryLayers.removeAll();
      // // 清理数据源
      // try {
      //    const dataSources = this.viewer.dataSources;
      //    while (dataSources.length > 0) {
      //       dataSources.remove(dataSources.get(0));
      //    }
      // } catch (e) {
      //    console.warn('清理数据源时出错:', e);
      // }
      // // 清理场景中的图元
      // try {
      //    this.viewer?.scene.primitives.removeAll();
      // } catch (e) {
      //    console.warn('清理图元时出错:', e);
      // }
      // // 获取webgl上下文
      // let gl = this.viewer?.scene.context._originalGLContext
      // if (gl) {
      //    try {
      //       gl.canvas.width = 1
      //       gl.canvas.height = 1
      //       gl.getExtension("WEBGL_lose_context").loseContext()
      //    } catch (e) {
      //       console.warn('释放WebGL上下文时出错:', e)
      //    }
      //    gl = null
      // }
      this.viewer?.destroy() // 销毁Viewer实例
      this.viewer = null
      smallMpaCenterDistance = null
      if (this.viewer) {
         this.viewer?.entities.removeAll()
         this.viewer?.imageryLayers.removeAll()
         this.viewer?.dataSources.removeAll()
         // try {
         //    this.viewer?.scene?.primitives?.removeAll()
         //    this.viewer?.entities?.removeAll()
         // } catch (e) {
         //    console.warn('清理资源时出错:', e)
         //    console.log(this.viewer, 1111111111111)
         // }
         // 获取webgl上下文
         let gl = this.viewer?.scene.context._originalGLContext
         gl.canvas.width = 1
         gl.canvas.height = 1
         gl.getExtension("WEBGL_lose_context").loseContext()
         gl = null
         this.viewer?.destroy() // 销毁Viewer实例
         this.viewer = null
         var cesiumContainer = document.getElementById(this.viewerDom)
         if (cesiumContainer && removeDom) {
            cesiumContainer.remove() // 移除与地图相关的DOM元素
            this.viewerDom = null
         }
      var cesiumContainer = document.getElementById(this.viewerDom)
      if (cesiumContainer && removeDom) {
         cesiumContainer.remove() // 移除与地图相关的DOM元素
         this.viewerDom = null
      }
   }
   setShowDock (sns) {
      this.boundary?.setShowDock(sns)
   }
   setDockCoverColor (sns) {
      this.boundary?.setDockCoverColor(sns)
   }
   // 切换轮廓显示
   async switchContour (open) {
      if (open) {
         await this.boundary?.openContour()
      } else {
         this.boundary?.closeContour()
      }
   }
   // // 飞向轮廓居中
   // 飞向轮廓居中
   flyToContour () {
      this.boundary?.flyToBoundary()
   }
@@ -257,7 +297,7 @@
      this.globalBaseMapLayers?.forEach(item => {
         if (item.mapLayer) item.mapLayer.show = false
      })
      // store.state.common.mapSetting.mode = mode
      store.state.common.mapSetting.mode = mode
      // 标准地图(天地图矢量)加载
      if (mode === 0) {
         mapLayers.push(
@@ -324,9 +364,7 @@
         this.viewer?.imageryLayers.lowerToBottom(find.mapLayer)
      })
   }
   // 设置或重置滤镜
   setCurrentLayerFilter (data, mode) {
      if (mode === 17) {
         data.mapLayer.brightness = 0.6 // 亮度(默认值)