forked from drone/command-center-dashboard

shuishen
2025-04-02 e14358f85a7d32a753225f253ff223d17cf36c25
src/views/Home/useEventOperate/useEventOperate.js
@@ -1,214 +1,214 @@
import * as Cesium from 'cesium';
import data2 from '@/assets/images/home/homeRight/data2.png';
import data1 from '@/assets/images/home/homeRight/data1.png';
import eventImg from '@/assets/images/home/useEventOperate/event.png';
import jiangxishi from '@/assets/geojson/jiangxishi.json';
import jiangxi from '@/assets/geojson/jiangxi.json';
import zg from '@/assets/geojson/zg.json';
import EventPopUpBox from './EventPopUpBox.vue';
import { render } from 'vue';
import store from '@/store';
import * as Cesium from 'cesium'
import data2 from '@/assets/images/home/homeRight/data2.png'
import data1 from '@/assets/images/home/homeRight/data1.png'
import eventImg from '@/assets/images/home/useEventOperate/event.png'
import jiangxishi from '@/assets/geojson/jiangxishi.json'
import jiangxi from '@/assets/geojson/jiangxi.json'
import zg from '@/assets/geojson/zg.json'
import EventPopUpBox from './EventPopUpBox.vue'
import { render } from 'vue'
import store from '@/store'
/**
 * 事件聚合功能
 */
export const useEventOperate = () => {
  const scalingJudgment = [
    { name: '县', value: [0, 48651], gJson: null },
    { name: '市', value: [48651, 314863], gJson: jiangxishi },
    { name: '省', value: [314863, 1169651], gJson: jiangxi },
    { name: '国', value: [1169651, 37962800], gJson: zg },
  ];
  let viewer = null;
  let active = null;
  let handler = null;
  let positionC3 = null;
  const listenerHeight = () => {
    determineScaling();
    viewer.camera.moveEnd.addEventListener(determineScaling);
  };
   const scalingJudgment = [
      { name: '县', value: [0, 48651], gJson: null },
      { name: '市', value: [48651, 314863], gJson: jiangxishi },
      { name: '省', value: [314863, 1169651], gJson: jiangxi },
      { name: '国', value: [1169651, 37962800], gJson: zg },
   ]
   let viewer = null
   let active = null
   let handler = null
   let positionC3 = null
   const listenerHeight = () => {
      determineScaling()
      viewer.camera.moveEnd.addEventListener(determineScaling)
   }
  // 确定缩放比例
  const determineScaling = () => {
    if(!viewer) return
    let height = viewer.camera.positionCartographic.height;
    // 根据高度展示对应的 gJson
    for (let item of scalingJudgment) {
      if (height > item.value[0] && height <= item.value[1]) {
        if (active !== item.name) {
          removeEntities();
          removeLabel();
          active = item.name;
          item.gJson ? aggregation(item) : splashed();
        }
        break;
      }
    }
  };
   // 确定缩放比例
   const determineScaling = () => {
      if (!viewer) return
      let height = viewer.camera.positionCartographic.height
      // 根据高度展示对应的 gJson
      for (let item of scalingJudgment) {
         if (height > item.value[0] && height <= item.value[1]) {
            if (active !== item.name) {
               removeEntities()
               removeLabel()
               active = item.name
               item.gJson ? aggregation(item) : splashed()
            }
            break
         }
      }
   }
  //散点机巢
  function splashed() {
    for (let i = 0; i < 50; i++) {
      viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(
          115.89 + Math.random() * 0.2,
          28.68 + Math.random() * 0.2
        ),
        label: {
          // 随机整数
          text: Math.floor(Math.random() * 100) + '号事件',
          font: '14pt monospace',
          fillColor: Cesium.Color.WHITE,
          outlineColor: Cesium.Color.BLACK,
          outlineWidth: 2,
          style: Cesium.LabelStyle.FILL_AND_OUTLINE,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
          pixelOffset: new Cesium.Cartesian2(0, -9),
        },
        billboard: {
          image: new Cesium.ConstantProperty(eventImg),
          width: 24,
          height: 24,
        },
      });
    }
  }
   //散点机巢
   function splashed() {
      for (let i = 0; i < 50; i++) {
         viewer.entities.add({
            position: Cesium.Cartesian3.fromDegrees(
               115.89 + Math.random() * 0.2,
               28.68 + Math.random() * 0.2
            ),
            label: {
               // 随机整数
               text: Math.floor(Math.random() * 100) + '号事件',
               font: '14pt monospace',
               fillColor: Cesium.Color.WHITE,
               outlineColor: Cesium.Color.BLACK,
               outlineWidth: 2,
               style: Cesium.LabelStyle.FILL_AND_OUTLINE,
               verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
               pixelOffset: new Cesium.Cartesian2(0, -9),
            },
            billboard: {
               image: new Cesium.ConstantProperty(eventImg),
               width: 24,
               height: 24,
            },
         })
      }
   }
  // 聚合机巢
  const aggregation = item => {
    const featuresList = item.gJson.features.map(item => ({
      name: item.properties.name,
      position: item.properties.center,
    }));
    // 遍历特征并添加实体
    featuresList.forEach(feature => {
      if (!feature.position) return;
      const position = Cesium.Cartesian3.fromDegrees(feature.position[0], feature.position[1]);
      viewer.entities.add({
        id: feature.id,
        position: position,
        label: {
          // 随机整数
          text: Math.floor(Math.random() * 100) + '个事件',
          font: '14pt monospace',
          fillColor: Cesium.Color.WHITE,
          outlineColor: Cesium.Color.BLACK,
          outlineWidth: 2,
          style: Cesium.LabelStyle.FILL_AND_OUTLINE,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
          pixelOffset: new Cesium.Cartesian2(0, -9),
        },
        billboard: {
          image: new Cesium.ConstantProperty(data2),
          width: 24,
          height: 24,
        },
        properties: {
          id: feature.id,
          customData: {
            name: feature.name,
          },
        },
      });
    });
    // 加载新的 GeoJSON 数据
    Cesium.GeoJsonDataSource.load(item.gJson).then(dataSource => {
      viewer.dataSources.add(dataSource);
      item.dataSource = dataSource; // 保存数据源以便后续删除
      // 获取数据源中的实体
      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.YELLOW); // 黑色边框
      });
    });
  };
   // 聚合机巢
   const aggregation = item => {
      const featuresList = item.gJson.features.map(item => ({
         name: item.properties.name,
         position: item.properties.center,
      }))
      // 遍历特征并添加实体
      featuresList.forEach(feature => {
         if (!feature.position) return
         const position = Cesium.Cartesian3.fromDegrees(feature.position[0], feature.position[1])
         viewer.entities.add({
            id: feature.id,
            position: position,
            label: {
               // 随机整数
               text: Math.floor(Math.random() * 100) + '个事件',
               font: '14pt monospace',
               fillColor: Cesium.Color.WHITE,
               outlineColor: Cesium.Color.BLACK,
               outlineWidth: 2,
               style: Cesium.LabelStyle.FILL_AND_OUTLINE,
               verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
               pixelOffset: new Cesium.Cartesian2(0, -9),
            },
            billboard: {
               image: new Cesium.ConstantProperty(data2),
               width: 24,
               height: 24,
            },
            properties: {
               id: feature.id,
               customData: {
                  name: feature.name,
               },
            },
         })
      })
      // 加载新的 GeoJSON 数据
      Cesium.GeoJsonDataSource.load(item.gJson).then(dataSource => {
         viewer.dataSources.add(dataSource)
         item.dataSource = dataSource // 保存数据源以便后续删除
         // 获取数据源中的实体
         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.YELLOW) // 黑色边框
         })
      })
   }
  // 获取弹框box
  const getLabelDom = () => {
    const vNode = h(EventPopUpBox, { data: '参数', removeLabel });
    const tooltipContainer = document.createElement('div');
    tooltipContainer.id = 'mapPopUpBox';
    tooltipContainer.style.position = 'absolute';
    tooltipContainer.style.transform = 'translate(-50%,-110%)';
    tooltipContainer.style.pointerEvents = 'none';
    document.querySelector('.page-index').append(tooltipContainer);
    render(vNode, tooltipContainer);
    return tooltipContainer;
  };
   // 获取弹框box
   const getLabelDom = () => {
      const vNode = h(EventPopUpBox, { data: '参数', removeLabel })
      const tooltipContainer = document.createElement('div')
      tooltipContainer.id = 'mapPopUpBox'
      tooltipContainer.style.position = 'absolute'
      tooltipContainer.style.transform = 'translate(-50%,-110%)'
      tooltipContainer.style.pointerEvents = 'none'
      document.querySelector('.page-index').append(tooltipContainer)
      render(vNode, tooltipContainer)
      return tooltipContainer
   }
  // 弹框位置刷新
  const labelBox = () => {
    store.commit('setSingleUavHome', {
      id: '123'
    });
    let dom = document.querySelector('#mapPopUpBox');
    if (!dom) {
      dom = getLabelDom();
    }
    const screenPosition = viewer.scene.cartesianToCanvasCoordinates(positionC3);
    if (screenPosition) {
      dom.style.left = `${screenPosition.x}px`;
      dom.style.top = `${screenPosition.y}px`;
      dom.style.display = 'block';
    }
  };
   // 弹框位置刷新
   const labelBox = () => {
      store.commit('setSingleUavHome', {
         id: '123',
      })
      let dom = document.querySelector('#mapPopUpBox')
      if (!dom) {
         dom = getLabelDom()
      }
      const screenPosition = viewer.scene.cartesianToCanvasCoordinates(positionC3)
      if (screenPosition) {
         dom.style.left = `${screenPosition.x}px`
         dom.style.top = `${screenPosition.y}px`
         dom.style.display = 'block'
      }
   }
  // 左键单机事件
  const singleMachineEvent = click => {
    const pickedObject = viewer.scene.pick(click.position);
    if (Cesium.defined(pickedObject) && pickedObject.id) {
      const entity = pickedObject.id;
      positionC3 = entity?.position?._value;
      if (!positionC3) return;
      viewer.scene.postRender.removeEventListener(labelBox);
      viewer.scene.postRender.addEventListener(labelBox);
    }
  };
   // 左键单机事件
   const singleMachineEvent = click => {
      const pickedObject = viewer.scene.pick(click.position)
      if (Cesium.defined(pickedObject) && pickedObject.id) {
         const entity = pickedObject.id
         positionC3 = entity?.position?._value
         if (!positionC3) return
         viewer.scene.postRender.removeEventListener(labelBox)
         viewer.scene.postRender.addEventListener(labelBox)
      }
   }
  // 移除 点 和 gjson 实体
  const removeEntities = () => {
    viewer.dataSources?.removeAll(true);
    viewer.entities?.removeAll();
  };
  // 移除弹框标签
  const removeLabel = () => {
    viewer.scene.postRender.removeEventListener(labelBox);
    const dom = document.querySelector('#mapPopUpBox');
    if (dom && dom.parentNode) {
      dom.parentNode.removeChild(dom);
    }
  };
   // 移除 点 和 gjson 实体
   const removeEntities = () => {
      viewer.dataSources?.removeAll(true)
      viewer.entities?.removeAll()
   }
   // 移除弹框标签
   const removeLabel = () => {
      viewer.scene.postRender.removeEventListener(labelBox)
      const dom = document.querySelector('#mapPopUpBox')
      if (dom && dom.parentNode) {
         dom.parentNode.removeChild(dom)
      }
   }
  // 移除所有监听事件,变量置空
  const removeAll = () => {
    removeEntities();
    removeLabel();
    viewer.camera.moveEnd.removeEventListener(determineScaling);
    handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    handler?.destroy();
    viewer = null;
    active = null
    handler = null;
    positionC3 = null;
  };
  const init = () => {
    viewer = window.$viewer;
    handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    listenerHeight();
  };
  // onMounted(() => {
  //   nextTick(() => {
  //     viewer = window.$viewer;
  //     handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
  //     handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  //     listenerHeight();
  //   });
  // });
   // 移除所有监听事件,变量置空
   const removeAll = () => {
      removeEntities()
      removeLabel()
      viewer.camera.moveEnd.removeEventListener(determineScaling)
      handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
      handler?.destroy()
      viewer = null
      active = null
      handler = null
      positionC3 = null
   }
   const init = () => {
      viewer = window.$viewer
      handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
      handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK)
      listenerHeight()
   }
   // onMounted(() => {
   //   nextTick(() => {
   //     viewer = window.$viewer;
   //     handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
   //     handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK);
   //     listenerHeight();
   //   });
   // });
  return { init,removeAll };
};
   return { init, removeAll }
}