import * as Cesium from 'cesium'; import data2 from '@/assets/images/home/homeRight/data2.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 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, }, }) } } // 聚合机巢 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 } // 弹框位置刷新 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) } } // 移除 点 和 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(); // }); // }); return { init, removeAll } }