| | |
| | | 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'; |
| | | 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 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; |
| | | } |
| | | } |
| | | }; |
| | | // 确定缩放比例 |
| | | 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, |
| | | }, |
| | | }); |
| | | } |
| | | } |
| | | //散点机巢 |
| | | 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); // 黑色边框 |
| | | }); |
| | | }); |
| | | }; |
| | | // 聚合机巢 |
| | | 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; |
| | | }; |
| | | // 获取弹框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 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); |
| | | } |
| | | }; |
| | | // 左键单机事件 |
| | | 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); |
| | | } |
| | | }; |
| | | // 移除 点 和 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(); |
| | | // }); |
| | | // }); |
| | | // 移除所有监听事件,变量置空 |
| | | 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 }; |
| | | }; |
| | | return { init, removeAll } |
| | | } |