forked from drone/command-center-dashboard

shuishen
2025-04-08 930dea71598c9a1efd9cd6bb91d9a42cf29c171f
feat: 增加PolyGradientMaterial材质,修改行政区显示材质
1 files modified
1 files added
572 ■■■■■ changed files
src/utils/cesium/Material/index.js 118 ●●●●● patch | view | raw | blame | history
src/views/Home/useMapAggregation/useMapAggregation.js 454 ●●●● patch | view | raw | blame | history
src/utils/cesium/Material/index.js
New file
@@ -0,0 +1,118 @@
import * as Cesium from 'cesium'
let pM = "PolyGradientMaterial"
Cesium.Material._materialCache.addMaterial(pM, {
  strict: true,
  fabric: {
    type: pM,
    uniforms: {
      color: new Cesium.Color(1.0, 1.0, 0.0, 0.5),
      diffusePower: 1.6,
      alphaPower: 1.5,
      center: new Cesium.Cartesian2(0.5, 0.5),
      isInner: false,
      globalAlpha: 1.0,
    },
    source: `
            uniform vec4 color;
            uniform float diffusePower;
            uniform float alphaPower;
            uniform float globalAlpha;
            uniform vec2 center;
            uniform bool isInner;
            czm_material czm_getMaterial(czm_materialInput materialInput) {
                czm_material material = czm_getDefaultMaterial(materialInput);
                vec2 st = materialInput.st;
                float alphaMars3D = distance(st, center);
                if(isInner) {
                    material.alpha = (1.0 - (color.a * alphaMars3D * alphaPower)) * globalAlpha;
                    if(material.alpha < 0.0) material.alpha = 0.0;
                } else {
                    material.alpha = color.a * alphaMars3D * alphaPower * globalAlpha;
                }
                material.diffuse = color.rgb * diffusePower;
                return material;
            }
        `,
  },
  translucent: true,
})
class MaterialProperty {
  constructor(options = {}) {
    this._definitionChanged = new Cesium.Event()
    this._color = undefined
    this._opacity = undefined
    this._alphaPower = undefined
    this.color = options.color || Cesium.Color.fromBytes(0, 255, 255, 255)
    this.opacity = options.opacity || 0.5
    this.alphaPower = options.alphaPower || 1.5
  }
  get isConstant () {
    return false
  }
  get definitionChanged () {
    return this._definitionChanged
  }
  getType (time) {
    return null
  }
  getValue (time, result) {
    result = Cesium.defaultValue(result, {})
    return result
  }
  equals (other) {
    return this === other
  }
}
class PolyGradientMaterial extends MaterialProperty {
  constructor(options = {}) {
    super(options)
  }
  getType (time) {
    return pM
  }
  getValue (time, result) {
    if (!result) {
      result = {}
    }
    result.color = Cesium.Property.getValueOrUndefined(this._color, time)
    result.globalAlpha = Cesium.Property.getValueOrUndefined(this._opacity, time)
    result.alphaPower = Cesium.Property.getValueOrUndefined(this._alphaPower, time)
    return result
  }
  equals (other) {
    return (
      this === other ||
      (other instanceof PolyGradientMaterial &&
        Cesium.Property.equals(this._color, other._color) &&
        Cesium.Property.equals(this._opacity, other._opacity) &&
        Cesium.Property.equals(this._alphaPower, other._alphaPower))
    )
  }
}
Object.defineProperties(PolyGradientMaterial.prototype, {
  color: Cesium.createPropertyDescriptor('color'),
  opacity: Cesium.createPropertyDescriptor('opacity'),
  alphaPower: Cesium.createPropertyDescriptor('alphaPower'),
})
export {
  PolyGradientMaterial
}
src/views/Home/useMapAggregation/useMapAggregation.js
@@ -1,28 +1,28 @@
import * as Cesium from 'cesium';
import aggregationImg from '@/assets/images/home/useUavHome/aggregation.png';
import uavImg from '@/assets/images/home/useUavHome/uavImg.png';
import * as Cesium from 'cesium'
import aggregationImg from '@/assets/images/home/useUavHome/aggregation.png'
import uavImg from '@/assets/images/home/useUavHome/uavImg.png'
import eventImg from '@/assets/images/home/useEventOperate/event.png';
import eventImg from '@/assets/images/home/useEventOperate/event.png'
import DevicePopUpBox from '@/views/Home/useMapAggregation/DevicePopUpBox.vue';
import EventPopUpBox from '@/views/Home/useMapAggregation/EventPopUpBox.vue';
import DevicePopUpBox from '@/views/Home/useMapAggregation/DevicePopUpBox.vue'
import EventPopUpBox from '@/views/Home/useMapAggregation/EventPopUpBox.vue'
import { render } from 'vue';
import { useStore } from 'vuex';
import { getCenterPoint } from '@/utils/cesium/mapUtil';
import cesiumOperation from '@/utils/cesium-tsa';
import { getDeviceRegion, getDeviceRegionCount, getEventDetails, getMapEvents } from '@/api/home/aggregation';
import { render } from 'vue'
import { useStore } from 'vuex'
import { getCenterPoint } from '@/utils/cesium/mapUtil'
import cesiumOperation from '@/utils/cesium-tsa'
import { getDeviceRegion, getDeviceRegionCount, getEventDetails, getMapEvents } from '@/api/home/aggregation'
import { PolyGradientMaterial } from '@/utils/cesium/Material'
/**
 * 机巢聚合功能
 */
export const useMapAggregation = type => {
  const { flyTo } = cesiumOperation();
  const { flyTo } = cesiumOperation()
  const singleImg = type === 'device' ? uavImg : eventImg;
  const mergeImg = type === 'device' ? aggregationImg : aggregationImg;
  const MapPopUpBox = type === 'device' ? DevicePopUpBox : EventPopUpBox;
  const styleTransform = type === 'device' ? 'translateY(-50%)' : 'translate(-50%,-110%)';
  const singleImg = type === 'device' ? uavImg : eventImg
  const mergeImg = type === 'device' ? aggregationImg : aggregationImg
  const MapPopUpBox = type === 'device' ? DevicePopUpBox : EventPopUpBox
  const styleTransform = type === 'device' ? 'translateY(-50%)' : 'translate(-50%,-110%)'
  let scalingJudgment = [
    { name: '县', splashedList: [], gJson: null, show: false, outline: {}, value: [0, 48651], height: 31753 },
@@ -36,186 +36,186 @@
      value: [314863, 3796280000],
      height: 1987280,
    },
  ];
  let viewer = null;
  let active = null;
  let handler = null;
  let positionC3 = null;
  let currentEntity = null;
  ]
  let viewer = null
  let active = null
  let handler = null
  let positionC3 = null
  let currentEntity = null
  const store = useStore();
  const userAreaCode = computed(() => store.state.user.userInfo.detail.areaCode);
  const selectedAreaCode = computed(() => store.state.user.selectedAreaCode);
  const store = useStore()
  const userAreaCode = computed(() => store.state.user.userInfo.detail.areaCode)
  const selectedAreaCode = computed(() => store.state.user.selectedAreaCode)
  // 确定缩放比例
  const determineScaling = () => {
    // console.log('确定缩放比例');
    if (!viewer) return;
    let height = viewer.camera.positionCartographic.height;
    if (!viewer) return
    let height = viewer.camera.positionCartographic.height
    // 根据高度展示对应的 gJson
    for (let [index, item] of scalingJudgment.entries()) {
      if (!item.show) return;
      if (!item.show) return
      if (height > item.value[0] && height <= item.value[1]) {
        if (active === item.name) return;
        active = item.name;
        removeEntities();
        removeLabel();
        renderOutline(item);
        if (!item.gJson && !item.splashedList?.length) return;
        item.gJson ? aggregation(item) : splashed(item);
        break;
        if (active === item.name) return
        active = item.name
        removeEntities()
        removeLabel()
        renderOutline(item)
        if (!item.gJson && !item.splashedList?.length) return
        item.gJson ? aggregation(item) : splashed(item)
        break
      }
    }
  };
  }
  // 转换为目录结构, 返回数组,
  function convertToHierarchy(code) {
    const codeStr = code.toString();
    const provinceCode = codeStr.slice(0, 2) + '0000';
    const cityCode = codeStr.slice(0, 4) + '00';
  function convertToHierarchy (code) {
    const codeStr = code.toString()
    const provinceCode = codeStr.slice(0, 2) + '0000'
    const cityCode = codeStr.slice(0, 4) + '00'
    if (codeStr.slice(2, 4) === '00' && codeStr.slice(4, 6) === '00') {
      return [provinceCode];
      return [provinceCode]
    } else if (codeStr.slice(4, 6) === '00') {
      return [provinceCode, cityCode];
      return [provinceCode, cityCode]
    }
    return [provinceCode, cityCode, code];
    return [provinceCode, cityCode, code]
  }
  // 获取设备聚合
  function getDeviceCount(areaCode) {
  function getDeviceCount (areaCode) {
    return getDeviceRegionCount({ areaCode }).then(res => {
      return (res?.data?.data || [])
    });
    })
  }
  // 获取设备散点
  function getDeviceList(areaCode) {
  function getDeviceList (areaCode) {
    return getDeviceRegion({ areaCode }).then(res => {
      return (res?.data?.data || []).map(i =>({...i,type}));
    });
      return (res?.data?.data || []).map(i => ({ ...i, type }))
    })
  }
  // 事件散点
  let eventList = []
  function processChildren(childrens) {
  function processChildren (childrens) {
    return (childrens || []).map(item => {
      const arr = processChildren(item.childrens);
      if (item.data){
      const arr = processChildren(item.childrens)
      if (item.data) {
        eventList = eventList.concat(item.data)
      }
      const returnObj = {
        total_device_count: item.number,
        region_code: item.id,
        region_name: item.name,
      };
      if (arr.length !== 0) {
        returnObj.childrens = arr;
      }
      return returnObj;
    });
      if (arr.length !== 0) {
        returnObj.childrens = arr
      }
      return returnObj
    })
  }
  // 获取事件聚合
  function getMapEventCount(areaCode) {
  function getMapEventCount (areaCode) {
    return getMapEvents({ areaCode }).then(res => {
      const resData= res?.data?.data
      if (resData?.data){
      const resData = res?.data?.data
      if (resData?.data) {
        eventList = resData?.data
        return []
      }
      return processChildren(resData?.childrens);
    });
      return processChildren(resData?.childrens)
    })
  }
  const findFun = (featItem, numItem) => Number(featItem.region_code.slice(0, 6)) === numItem.properties.adcode;
  const { VITE_APP_BASE,VITE_APP_ENV } = import.meta.env;
  const defaultDir =  `${VITE_APP_BASE}${VITE_APP_ENV === 'development' ? 'public/' : ''}geoJson/100000/`;
  const findFun = (featItem, numItem) => Number(featItem.region_code.slice(0, 6)) === numItem.properties.adcode
  const { VITE_APP_BASE, VITE_APP_ENV } = import.meta.env
  const defaultDir = `${VITE_APP_BASE}${VITE_APP_ENV === 'development' ? 'public/' : ''}geoJson/100000/`
  const getFiler = async url => {
    const res = await fetch(url);
    return  await res.json()
  };
    const res = await fetch(url)
    return await res.json()
  }
  const getOutLine = async (jsonPathPre, hierarchy) => {
    const parentGJson = await getFiler(`${defaultDir}${jsonPathPre}/index.json`);
    const parentGJson = await getFiler(`${defaultDir}${jsonPathPre}/index.json`)
    let features = parentGJson.features.find(
      item => item.properties.adcode === Number(hierarchy[hierarchy.length - 1])
    );
    return { type: 'FeatureCollection', features: [features] };
  };
    )
    return { type: 'FeatureCollection', features: [features] }
  }
  const injectData = (gJson, dataList) => {
    return {
      ...gJson,
      features: gJson.features.map(item => {
        const findData = dataList.find(item1 => findFun(item1, item))
        return { ...item, data: {...findData,type: type + 'Aggregation'} }
        return { ...item, data: { ...findData, type: type + 'Aggregation' } }
      }),
    };
  };
    }
  }
  const initMapData = async areaCode => {
    eventList = []
    if (!areaCode) return;
    const list = type === 'device' ? await getDeviceCount(areaCode) : await getMapEventCount(areaCode);
    if (!areaCode) return
    const list = type === 'device' ? await getDeviceCount(areaCode) : await getMapEventCount(areaCode)
    const splashedList = type === 'device'
      ? await getDeviceList(areaCode)
      : eventList.map(i=>({eventId:i.id,latitude:Number(i.latitude),longitude:Number(i.longitude),type:'event'}))
    const hierarchy = convertToHierarchy(areaCode.slice(0, 6));
    const jsonPath = hierarchy.join('/');
    const jsonPathPre = hierarchy.slice(0, hierarchy.length - 1).join('/');
    scalingJudgment = scalingJudgment.map(item => ({ ...item, show: true }));
    scalingJudgment[0].gJson = null;
    scalingJudgment[0].splashedList = splashedList;
    active = null;
      : eventList.map(i => ({ eventId: i.id, latitude: Number(i.latitude), longitude: Number(i.longitude), type: 'event' }))
    const hierarchy = convertToHierarchy(areaCode.slice(0, 6))
    const jsonPath = hierarchy.join('/')
    const jsonPathPre = hierarchy.slice(0, hierarchy.length - 1).join('/')
    scalingJudgment = scalingJudgment.map(item => ({ ...item, show: true }))
    scalingJudgment[0].gJson = null
    scalingJudgment[0].splashedList = splashedList
    active = null
    // 省
    if (hierarchy.length === 1) {
      const gJson1 = await getFiler(`${defaultDir}${jsonPath}/indexDistrict.json`);
      const gJson2 = await getFiler(`${defaultDir}${jsonPath}/index.json`);
      const gJson1 = await getFiler(`${defaultDir}${jsonPath}/indexDistrict.json`)
      const gJson2 = await getFiler(`${defaultDir}${jsonPath}/index.json`)
      scalingJudgment[1].gJson = {
        ...gJson1,
        features: gJson1.features.map(item => {
          const findData = list.flatMap(item => item.childrens || []).find(item1 => findFun(item1, item))
          return { ...item, data: {...findData,type: type + 'Aggregation'} }
          return { ...item, data: { ...findData, type: type + 'Aggregation' } }
        }),
      };
      scalingJudgment[2].gJson = injectData(gJson2, list);
      }
      scalingJudgment[2].gJson = injectData(gJson2, list)
    }
    // 市
    if (hierarchy.length === 2) {
      scalingJudgment[2].gJson = null;
      scalingJudgment[2].show = false;
      const gJson1 = await getFiler(`${defaultDir}${jsonPath}/index.json`);
      scalingJudgment[1].gJson = injectData(gJson1, list);
      scalingJudgment[2].gJson = null
      scalingJudgment[2].show = false
      const gJson1 = await getFiler(`${defaultDir}${jsonPath}/index.json`)
      scalingJudgment[1].gJson = injectData(gJson1, list)
    }
    // 区县
    if (hierarchy.length === 3) {
      scalingJudgment[1].gJson = null;
      scalingJudgment[1].show = false;
      scalingJudgment[2].gJson = null;
      scalingJudgment[2].show = false;
      scalingJudgment[1].gJson = null
      scalingJudgment[1].show = false
      scalingJudgment[2].gJson = null
      scalingJudgment[2].show = false
    }
    // 轮廓
    const outlineGJson = await getOutLine(jsonPathPre, hierarchy);
    scalingJudgment.forEach(item => item.show && (item.outline = outlineGJson));
    const [longitude,latitude] = outlineGJson.features[0].properties.centroid
    flyTo({ longitude, latitude }, 0, scalingJudgment[(hierarchy.length-3) * (-1)].height);
  };
    const outlineGJson = await getOutLine(jsonPathPre, hierarchy)
    scalingJudgment.forEach(item => item.show && (item.outline = outlineGJson))
    const [longitude, latitude] = outlineGJson.features[0].properties.centroid
    flyTo({ longitude, latitude }, 0, scalingJudgment[(hierarchy.length - 3) * (-1)].height)
  }
  watch(
    selectedAreaCode,
    async (newValue, oldValue) => {
      if (!viewer) return
      viewer.scene.postRender.removeEventListener(determineScaling)
      initMapData(newValue).then(()=>{
      initMapData(newValue).then(() => {
        viewer.scene.postRender.addEventListener(determineScaling)
      })
    },
    { deep: true }
  );
  )
  //散点机巢
  function splashed(row) {
    row.splashedList.forEach((item,index) => {
  function splashed (row) {
    row.splashedList.forEach((item, index) => {
      viewer.entities.add({
        id: `aggregation-splashed-${index}`,
        position: Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude),
@@ -240,40 +240,40 @@
            data: item,
          },
        },
      });
    });
      })
    })
  }
  // 渲染轮廓
  const renderOutline = item => {
    item.outline &&
    Cesium.GeoJsonDataSource.load(item.outline).then(dataSource => {
      viewer.dataSources.add(dataSource);
      const entities = dataSource.entities.values;
      entities.forEach(entity => {
        // 隐藏多边形填充
        entity.polygon.material = Cesium.Color.TRANSPARENT;
        entity.polygon.outline = false; // 关闭原生轮廓
        // 创建独立折线作为轮廓
        const positions = entity.polygon.hierarchy.getValue().positions;
        viewer.entities.add({
          polyline: {
            positions: positions,
            width: 5, // 直接设置宽度
            material: new Cesium.PolylineGlowMaterialProperty({
              glowPower: 0.5,
              color: Cesium.Color.AQUA,
            }),
            clampToGround: true, // 贴地显示
          },
        });
      });
    });
  };
      Cesium.GeoJsonDataSource.load(item.outline).then(dataSource => {
        viewer.dataSources.add(dataSource)
        const entities = dataSource.entities.values
        entities.forEach(entity => {
          // 隐藏多边形填充
          entity.polygon.material = Cesium.Color.TRANSPARENT
          entity.polygon.outline = false // 关闭原生轮廓
          // 创建独立折线作为轮廓
          const positions = entity.polygon.hierarchy.getValue().positions
          viewer.entities.add({
            polyline: {
              positions: positions,
              width: 5, // 直接设置宽度
              material: new Cesium.PolylineGlowMaterialProperty({
                glowPower: 0.5,
                color: Cesium.Color.AQUA,
              }),
              clampToGround: true, // 贴地显示
            },
          })
        })
      })
  }
  // 聚合机巢
  const aggregation = (item, flyTo) => {
    if (!item.gJson) return;
    if (!item.gJson) return
    const featuresList = item.gJson.features.map(item1 => {
      // const {lng,lat} = getCenterPoint(item1.geometry.coordinates[0][0])
      return {
@@ -282,11 +282,11 @@
        data: item1.data,
        id: item1.region_code,
      }
    });
    })
    // 遍历特征并添加实体
    featuresList.forEach((feature,index) => {
      if (!feature.position) return;
      const position = Cesium.Cartesian3.fromDegrees(feature.position[0], feature.position[1]);
    featuresList.forEach((feature, index) => {
      if (!feature.position) return
      const position = Cesium.Cartesian3.fromDegrees(feature.position[0], feature.position[1])
      viewer.entities.add({
        position: position,
        id: `aggregation-name-${index}`,
@@ -300,7 +300,7 @@
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
          pixelOffset: new Cesium.Cartesian2(0, -9),
        },
      });
      })
      viewer.entities.add({
        id: `aggregation-count-${index}`,
        position: position,
@@ -323,138 +323,148 @@
            data: feature.data,
          },
        },
      });
    });
      })
    })
    let arrColor = ["rgb(15,176,255)", "rgb(18,76,154)", "#40C4E4", "#42B2BE", "rgb(51,176,204)", "#8CB7E5", "rgb(0,244,188)", "#139FF0"]
    let index = 0
    function getColor () {
      return arrColor[++index % arrColor.length]
    }
    // 加载新的 GeoJSON 数据
    Cesium.GeoJsonDataSource.load(item.gJson).then(dataSource => {
      viewer.dataSources.add(dataSource);
      item.dataSource = dataSource; // 保存数据源以便后续删除
      viewer.dataSources.add(dataSource)
      item.dataSource = dataSource // 保存数据源以便后续删除
      // 获取数据源中的实体
      const entities = dataSource.entities.values;
      const entities = dataSource.entities.values
      entities.forEach(entity => {
        entity.polygon.material = new Cesium.ColorMaterialProperty(
          Cesium.Color.YELLOW.withAlpha(0) // 透明填充
        );
        entity.polygon.outline = new Cesium.ConstantProperty(true); // 显示边框
        entity.polygon.outlineColor = new Cesium.ConstantProperty(Cesium.Color.AQUAMARINE);
      });
        let material = new PolyGradientMaterial({
          color: Cesium.Color.fromCssColorString(getColor()),
          opacity: 0.7,
          alphaPower: 1.3
        })
        entity.polygon.material = material
        entity.polygon.outline = false // 显示边框
      })
      flyTo &&
      viewer.flyTo(dataSource, {
        offset: new Cesium.HeadingPitchRange(
          0, // heading: 0 (朝向不变)
          Cesium.Math.toRadians(-90), // pitch: -90° (垂直向下)
          0 // range: 0 (默认距离)
        ),
        duration: 0.5,
      });
    });
  };
        viewer.flyTo(dataSource, {
          offset: new Cesium.HeadingPitchRange(
            0, // heading: 0 (朝向不变)
            Cesium.Math.toRadians(-90), // pitch: -90° (垂直向下)
            0 // range: 0 (默认距离)
          ),
          duration: 0.5,
        })
    })
  }
  // 获取弹框box
  const getLabelDom = data => {
    const vNode = h(MapPopUpBox, { data, removeLabel });
    const tooltipContainer = document.createElement('div');
    tooltipContainer.id = 'mapPopUpBox';
    tooltipContainer.style.position = 'absolute';
    tooltipContainer.style.transform = styleTransform;
    tooltipContainer.style.pointerEvents = 'none';
    document.querySelector('.page-index').append(tooltipContainer);
    render(vNode, tooltipContainer);
    return tooltipContainer;
  };
    const vNode = h(MapPopUpBox, { data, removeLabel })
    const tooltipContainer = document.createElement('div')
    tooltipContainer.id = 'mapPopUpBox'
    tooltipContainer.style.position = 'absolute'
    tooltipContainer.style.transform = styleTransform
    tooltipContainer.style.pointerEvents = 'none'
    document.querySelector('.page-index').append(tooltipContainer)
    render(vNode, tooltipContainer)
    return tooltipContainer
  }
  // 弹框位置刷新
  const labelBoxRender = () => {
    let dom = document.querySelector('#mapPopUpBox');
    let dom = document.querySelector('#mapPopUpBox')
    if (!dom) {
      dom = getLabelDom(currentEntity.properties.customData._value.data);
      dom = getLabelDom(currentEntity.properties.customData._value.data)
    }
    const screenPosition = viewer.scene.cartesianToCanvasCoordinates(positionC3);
    const screenPosition = viewer.scene.cartesianToCanvasCoordinates(positionC3)
    if (screenPosition) {
      dom.style.left = `${screenPosition.x}px`;
      dom.style.top = `${screenPosition.y}px`;
      dom.style.display = 'block';
      dom.style.left = `${screenPosition.x}px`
      dom.style.top = `${screenPosition.y}px`
      dom.style.display = 'block'
    }
  };
  }
  // 左键单机事件
  const singleMachineEvent = async click => {
    const pickedObject = viewer.scene.pick(click.position);
    const pickedObject = viewer.scene.pick(click.position)
    if (Cesium.defined(pickedObject) && pickedObject.id) {
      const entity = pickedObject.id;
      currentEntity = entity;
      positionC3 = entity?.position?._value;
      if (!positionC3) return;
      removeLabel();
      const customData = entity.properties.customData._value.data;
      console.log('customData', customData);
      const entity = pickedObject.id
      currentEntity = entity
      positionC3 = entity?.position?._value
      if (!positionC3) return
      removeLabel()
      const customData = entity.properties.customData._value.data
      console.log('customData', customData)
      switch (customData.type) {
        case 'deviceAggregation':
          viewer.scene.postRender.addEventListener(labelBoxRender);
          break;
          viewer.scene.postRender.addEventListener(labelBoxRender)
          break
        case 'device':
          store.commit('setSingleUavHome', { id: '123' });
          break;
          store.commit('setSingleUavHome', { id: '123' })
          break
        case 'eventAggregation':
          break;
          break
        case 'event':
          viewer.scene.postRender.addEventListener(labelBoxRender);
          break;
          viewer.scene.postRender.addEventListener(labelBoxRender)
          break
        default:
          break;
          break
      }
    }
  };
  }
  const removeDom = () => {
    const dom = document.querySelector('#mapPopUpBox');
    const dom = document.querySelector('#mapPopUpBox')
    if (dom && dom.parentNode) {
      dom.parentNode.removeChild(dom);
      dom.parentNode.removeChild(dom)
    }
  };
  }
  // 移除 点 和 gjson 实体
  const removeEntities = () => {
    viewer.dataSources?.removeAll(true);
    viewer.dataSources?.removeAll(true)
    // viewer.entities?.removeAll();
    const entitiesIDs = viewer.entities.values.map(i=>i.id)
    const entitiesIDs = viewer.entities.values.map(i => i.id)
    entitiesIDs.forEach(item => {
        item.includes('aggregation-') && viewer.entities.removeById(item)
      item.includes('aggregation-') && viewer.entities.removeById(item)
    })
  };
  }
  // 移除弹框标签
  const removeLabel = () => {
    viewer.scene.postRender.removeEventListener(labelBoxRender);
    removeDom();
  };
    viewer.scene.postRender.removeEventListener(labelBoxRender)
    removeDom()
  }
  // 移除所有监听事件,变量置空
  const removeAll = () => {
    if (!viewer) return
    removeEntities();
    removeLabel();
    removeEntities()
    removeLabel()
    // viewer.camera.moveEnd.removeEventListener(determineScaling);
    viewer.scene.postRender.removeEventListener(determineScaling)
    handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    handler?.destroy();
    viewer = null;
    active = null;
    handler = null;
    positionC3 = null;
    currentEntity = null;
  };
    handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    handler?.destroy()
    viewer = null
    active = null
    handler = null
    positionC3 = null
    currentEntity = null
  }
  const init = () => {
    viewer = window.$viewer;
    viewer = window.$viewer
    viewer.scene.postRender.removeEventListener(determineScaling)
    initMapData(selectedAreaCode.value || userAreaCode.value).then(()=>{
    initMapData(selectedAreaCode.value || userAreaCode.value).then(() => {
      viewer.scene.postRender.addEventListener(determineScaling)
    })
    handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
    handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK)
  };
  onBeforeUnmount(() => {});
  }
  onBeforeUnmount(() => { })
  // onMounted(() => {
  //   nextTick(() => {
  //     viewer = window.$viewer;
@@ -463,5 +473,5 @@
  //   });
  // });
  return { init, removeAll };
};
  return { init, removeAll }
}