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 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 }; };