forked from drone/command-center-dashboard

shuishen
2025-04-16 07338b582b08850ceb2fd3cc22692464eea3a20b
feat:hook调整
4 files deleted
1 files added
585 ■■■■■ changed files
src/hooks/useSingleDroneMap/index.js 77 ●●●●● patch | view | raw | blame | history
src/hooks/useSingleDroneMap/useMapEvents.js 56 ●●●●● patch | view | raw | blame | history
src/hooks/useSingleDroneMap/useMapMarkers.js 147 ●●●●● patch | view | raw | blame | history
src/hooks/useSingleDroneMap/useMapPopup.js 67 ●●●●● patch | view | raw | blame | history
src/hooks/useSingleDroneMap/useSingleDroneMap.js 238 ●●●●● patch | view | raw | blame | history
src/hooks/useSingleDroneMap/index.js
File was deleted
src/hooks/useSingleDroneMap/useMapEvents.js
File was deleted
src/hooks/useSingleDroneMap/useMapMarkers.js
File was deleted
src/hooks/useSingleDroneMap/useMapPopup.js
File was deleted
src/hooks/useSingleDroneMap/useSingleDroneMap.js
New file
@@ -0,0 +1,238 @@
/*
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2025-04-15 22:41:40
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2025-04-16 18:31:11
 * @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'
/**
 *
 * @param {Object} options - 配置选项
 */
export function useSingleDroneMap (options = {
  eventPositions: [],
  eventApi: null,
  eventApiParams: {}
}) {
  const { eventPositions, eventApi, eventApiParams } = options
  let viewer = null
  let handler = null
  let currentEntity = null
  // 初始化机场位置
  const initDroneEntity = (dronePosition) => {
    const { lng, lat, status } = dronePosition
    if (!lng || !lat) return
    const markerImg = status ? endingHighImg : endingImg
    const position = Cesium.Cartesian3.fromDegrees(+lng, +lat, 0)
    const droneEntity = viewer?.entities.add({
      id: `single-drone-position`,
      position: position,
      billboard: {
        image: new Cesium.ConstantProperty(markerImg),
        width: 35,
        height: 35,
      },
      ellipse: {
        semiMinorAxis: 5000,
        semiMajorAxis: 5000,
        outline: true,
        material: Cesium.Color.CORNFLOWERBLUE.withAlpha(0.3),
      },
      properties: {
        customData: {
          data: {
            type: 'single-drone-event'
          }
        }
      }
    })
    viewer?.flyTo(droneEntity, {
      offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-60), 0),
      duration: 0.5,
    })
  }
  // 机巢事件地图撒点
  const initDroneEventEntity = (eventPositions = eventPositions) => {
    // 遍历特征并添加实体
    eventPositions.length && eventPositions.forEach((item, index) => {
      const { longitude, latitude, status, id } = item
      const position = Cesium.Cartesian3.fromDegrees(+longitude, +latitude, 0)
      viewer?.entities.add({
        id: `single-drone-event-${index}`,
        position: position,
        billboard: {
          image: new Cesium.ConstantProperty(endingHighImg),
          width: 35,
          height: 35,
        },
        properties: {
          customData: {
            data: {
              type: 'single-drone-sign'
            }
          }
        },
      })
    })
  }
  // 调用传入api
  const initEventApiEntity = () => {
    removeEventLayer()
    eventApi(
      {
        ...eventApiParams,
      }
    ).then(res => {
      const result = res.data.data.records
      initDroneEventEntity(result)
    })
  }
  // 事件地图撒点加载方式
  const initEventLayer = () => {
    eventApi ? initEventApiEntity() : initDroneEventEntity()
  }
  const removeEventLayer = () => {
    // entities移除
    const entitiesIDs = viewer?.entities.values.map(i => i.id)
    entitiesIDs && entitiesIDs.forEach(item => {
      item.includes('single-drone-event') && viewer?.entities.removeById(item)
    })
  }
  // 移除当前地图所有entity
  const removeLayer = () => {
    // entities移除
    const entitiesIDs = viewer?.entities.values.map(i => i.id)
    entitiesIDs.forEach(item => {
      item.includes('single-drone-') && viewer?.entities.removeById(item)
    })
  }
  // 查找特定类型的实体
  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
    console.log(viewer, window, 111111)
    handlerInit()
  }
  const removeAll = () => {
    removeLayer()
    removeHandler()
    removeLabel()
  }
  // 自动清理
  onUnmounted(() => {
    removeAll()
  })
  return {
    init,
    removeAll,
    initEventLayer,
    initDroneEntity,
  }
}