forked from drone/command-center-dashboard

罗广辉
2025-04-21 2800fa4f32f3900509cb4d6eefaf2bfaf54efdd7
src/hooks/useSingleDroneMap/useSingleDroneMap.js
@@ -2,15 +2,18 @@
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2025-04-15 22:41:40
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2025-04-16 18:38:00
 * @LastEditTime: 2025-04-17 20:24:19
 * @FilePath: \command-center-dashboard\src\hooks\useSingleDroneMap\useSingleDroneMap.js
 * @Description: 
 * 
 * Copyright (c) 2025 by shuishen, All Rights Reserved. 
 */
import * as Cesium from 'cesium'
import endingImg from '@/assets/images/aiNowFly/ending.png'
import endingHighImg from '@/assets/images/aiNowFly/ending-high.png'
import { getEventImage } from '@/utils/stateToImageMap/event'
import { getDroneFlagImage } from '@/utils/stateToImageMap/drone'
import { useMapHandlerClick } from '@/hooks/components/useMapHandlerClick'
/**
 * 
@@ -24,8 +27,15 @@
  const { eventPositions, eventApi, eventApiParams } = options
  let viewer = null
  let handler = null
  let currentEntity = null
  const {
    handlerInit: mapHandlerInit,
    removeAll: removeMapHandlerAll
  } = useMapHandlerClick({
    getViewer () {
      return viewer
    }
  })
  // 初始化机场位置
  const initDroneEntity = (dronePosition) => {
@@ -33,7 +43,7 @@
    if (!lng || !lat) return
    const markerImg = status ? endingHighImg : endingImg
    const markerImg = getDroneFlagImage(status)
    const position = Cesium.Cartesian3.fromDegrees(+lng, +lat, 0)
    const droneEntity = viewer?.entities.add({
@@ -56,7 +66,7 @@
      properties: {
        customData: {
          data: {
            type: 'single-drone-event'
            type: 'single-drone-position'
          }
        }
      }
@@ -69,10 +79,12 @@
  }
  // 机巢事件地图撒点
  const initDroneEventEntity = (eventPositions = eventPositions) => {
  const initDroneEventEntity = (eventData = eventPositions) => {
    // 遍历特征并添加实体
    eventPositions.length && eventPositions.forEach((item, index) => {
    eventData.length && eventData.forEach((item, index) => {
      const { longitude, latitude, status, id } = item
      const curImg = getEventImage(status)
      const position = Cesium.Cartesian3.fromDegrees(+longitude, +latitude, 0)
@@ -80,14 +92,16 @@
        id: `single-drone-event-${index}`,
        position: position,
        billboard: {
          image: new Cesium.ConstantProperty(endingHighImg),
          width: 35,
          height: 35,
          image: new Cesium.ConstantProperty(curImg),
          width: 20,
          height: 20,
        },
        properties: {
          customData: {
            data: {
              type: 'single-drone-sign'
              ...item,
              eventId: id,
              type: 'single-drone-event'
            }
          }
        },
@@ -104,7 +118,7 @@
        ...eventApiParams,
      }
    ).then(res => {
      const result = res.data.data.records
      const result = res.data.data
      initDroneEventEntity(result)
    })
@@ -132,96 +146,22 @@
    })
  }
  // 查找特定类型的实体
  const findEntityByType = (entities, type) => {
    return entities.find(entity =>
      entity?.properties?.customData?._value?.data?.type === type
    )
  }
  // 左键单机事件
  const singleMachineEvent = async click => {
    let clickedEntities = viewer?.scene.drillPick(click.position).map(item => item.id)
    if (!clickedEntities.length) return
    const currentEntity = findEntityByType(clickedEntities, 'single-drone-event')
    removeLabel()
    if (currentEntity) {
      viewer?.scene.postRender.addEventListener(labelBoxRender)
    }
  }
  // 事件初始化
  const handlerInit = () => {
    if (handler) return
    handler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
    handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK)
  }
  // 事件移除
  const removeHandler = () => {
    handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    handler?.destroy()
    handler = null
  }
  // 获取弹框box
  const getLabelDom = data => {
    const vNode = h(EventPopUpBox, { 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 = () => {
    if (!currentEntity) return
    let dom = document.querySelector('#mapPopUpBox')
    if (!dom) {
      dom = getLabelDom(currentEntity.properties.customData._value.data)
    }
    const screenPosition = viewer?.scene.cartesianToCanvasCoordinates(currentEntity?.position?._value)
    if (screenPosition) {
      dom.style.left = `${screenPosition.x}px`
      dom.style.top = `${screenPosition.y}px`
      dom.style.display = 'block'
    }
  }
  const removeDom = () => {
    const dom = document.querySelector('#mapPopUpBox')
    if (dom && dom.parentNode) {
      dom.parentNode.removeChild(dom)
    }
  }
  // 移除弹框标签
  const removeLabel = () => {
    viewer?.scene.postRender.removeEventListener(labelBoxRender)
    removeDom()
  }
  const init = () => {
    viewer = window.$viewer
    handlerInit()
    mapHandlerInit()
  }
  const removeAll = () => {
    removeLayer()
    removeHandler()
    removeLabel()
    removeMapHandlerAll()
  }
  onMounted(async () => {
    await nextTick()
    init()
  })
  // 自动清理
  onUnmounted(() => {
    removeAll()