/*
|
* @Author: shuishen 1109946754@qq.com
|
* @Date: 2025-04-15 22:41:40
|
* @LastEditors: shuishen 1109946754@qq.com
|
* @LastEditTime: 2025-04-17 19:43:36
|
* @FilePath: \command-center-dashboard\src\hooks\components\useMapHandlerClick.js
|
* @Description:
|
*
|
* Copyright (c) 2025 by shuishen, All Rights Reserved.
|
*/
|
import * as Cesium from 'cesium'
|
import { render } from 'vue'
|
import { useStore } from 'vuex'
|
|
import DevicePopUpBox from '@/hooks/components/DevicePopUpBox.vue'
|
import EventPopUpBox from '@/hooks/components/EventPopUpBox.vue'
|
|
/**
|
*
|
* @param {Object} options - 配置选项
|
*/
|
export function useMapHandlerClick (options = {}) {
|
const {
|
popupType = 'event-popup',
|
eventType = 'single-drone-event',
|
styleTransform = 'translate(-50%,-110%)',
|
getViewer
|
} = options
|
|
const store = useStore()
|
|
const popupData = {
|
'event-popup': EventPopUpBox,
|
'device-popup': DevicePopUpBox
|
}
|
|
const MapPopUpBox = popupData[popupType]
|
|
let viewer = null
|
let handler = null
|
let currentClickEntity = null
|
|
// 查找特定类型的实体
|
const findEntityByType = (entities, type) => {
|
let types = []
|
|
Array.isArray(type) ? types = type : types = [type]
|
|
return types.reduce((pre, curType) => {
|
let entity = entities.find(entity => entity?.properties?.customData?._value?.data?.type === curType)
|
|
return entity ? (pre.push({
|
type: curType,
|
entity
|
}), pre) : pre
|
}, [])
|
}
|
|
const publicEvent = (entity) => {
|
viewer.scene.postRender.addEventListener(labelBoxRender)
|
}
|
|
const typeEvent = {
|
'deviceAggregation': publicEvent,
|
'single-drone-event': publicEvent,
|
'event': publicEvent,
|
'device': (entity) => {
|
const device = entity.properties.customData._value.data
|
store.commit('setSingleUavHome', device)
|
}
|
}
|
|
// 左键单机事件
|
const singleMachineEvent = async click => {
|
let clickedEntities = viewer?.scene.drillPick(click.position).map(item => item.id)
|
if (!clickedEntities.length) return
|
|
let curClick = findEntityByType(clickedEntities, eventType)
|
|
removeLabel()
|
|
if (curClick.length > 0 && typeEvent[curClick[0].type]) {
|
currentClickEntity = curClick[0].entity
|
|
typeEvent[curClick[0].type](currentClickEntity)
|
}
|
}
|
|
// 事件初始化
|
const handlerInit = () => {
|
!viewer && (viewer = getViewer())
|
|
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(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 = () => {
|
if (!currentClickEntity) return
|
let dom = document.querySelector('#mapPopUpBox')
|
if (!dom) {
|
dom = getLabelDom(currentClickEntity.properties.customData._value.data)
|
}
|
const screenPosition = viewer?.scene.cartesianToCanvasCoordinates(currentClickEntity?.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 removeAll = () => {
|
removeHandler()
|
removeLabel()
|
}
|
|
// 自动清理
|
onUnmounted(() => {
|
removeAll()
|
})
|
|
return {
|
handlerInit,
|
removeAll,
|
removeLabel
|
}
|
}
|