import { config } from "../../../../config"; import LayerMgr3D from './layermgr3d'; import BaseMap from '../basemap'; import { SatelliteImage3D } from "./layers/SatelliteImage3D"; import { Dem3D } from "./layers/Dem3D"; import { Tiles3D } from "./layers/Tiles3D"; import { Water3D } from "./layers/Water3D"; import { BouaLayer3D } from "./layers/BouaLayer3D"; import { BouaMaskLayer3D } from "./layers/BouaMaskLayer3D"; import { VillagesBouaLayer3D } from "./layers/VillagesBouaLayer3D" import { getCameraViewPosition, getCameraViewCenter, getNewPosition } from './utils/cesutil' const { Cesium } = window; function __prepare_ces(dispatch) { Cesium.CesiumWidget.prototype.showErrorPanel = function (title, error) { dispatch && dispatch.map.setMode('2d'); if (title && title.indexOf('constructing') >= 0) { alert('无法初始化三维场景,如果一直出现此问题,请尝试下载最新的chrome浏览器'); } else { alert('三维场景渲染出现问题'); } }; } /** * OL 封装 */ export default class Map3D extends BaseMap { constructor({ divid, dispatch, mapCenter }) { super(); this.mapCenter = mapCenter; this.dispatch = dispatch; this.divid = divid; // div element id this._map = null; // openlayers map obj this.layerMgr = null; this.toolMgr = null; this.demo = null; this.list = [] } /** * 初始化地图、图层 */ init() { __prepare_ces(this.dispatch); const viewer = new Cesium.Viewer(this.divid, { shouldAnimate: true, //动画 scene3DOnly: true,//用于强制场景以 3D 模式运行,禁止切换至 2D 或 Columbus 视图 animation: false,//获取动画小部件。 baseLayerPicker: false,//获取BaseLayerPicker。 geocoder: false,//获取地理编码器 sceneModePicker: false,//Gets the SceneModePicker. fullscreenButton: false, homeButton: false, timeline: false, navigationHelpButton: false,//导航帮助按钮 shadows: false,//确定阴影是否由光源投射。 infoBox: false, skyAtmosphere: false,//去掉球边缘 selectionIndicator:false,//去掉选择指示器 }); viewer.clock.currentTime = Cesium.JulianDate.fromIso8601('2000-01-01T04:00:07Z');//设置当前时间 //设置地表透明 let globe = viewer.scene.globe; globe.depthTestAgainstTerrain = false;//关闭深度测试 //viewer.scene.skyAtmosphere.show = false; //关闭大气层阴影 viewer.scene.screenSpaceCameraController.minimumZoomDistance = 100; // viewer.scene.screenSpaceCameraController.maximumZoomDistance = 200000; viewer.scene.globe.enableLighting = false; //关闭光照 viewer.scene.light.intensity = 6 //默认光源强度,太低了模型显示效果差 viewer.shadows = false;//关闭阴影 viewer.scene.globe.depthTestAgainstTerrain = false;//解决地形遮挡entity问题 //优化项--关闭相关特效 viewer.scene.moon.show = false; //月亮 viewer.scene.fog.enabled = false; //雾 viewer.scene.sun.show = false; //太阳 viewer.scene.skyBox.show = false; //天空盒 viewer.resolutionScale = 1.0; //画面细度,默认值为1.0 viewer.scene.fxaa = false; viewer.scene.postProcessStages.fxaa.enabled = true; viewer.scene.globe.depthTestAgainstTerrain = true; viewer.scene.globe.baseColor = Cesium.Color.TRANSPARENT;//设置球的基础色 viewer.scene.globe.undergroundColor= Cesium.Color.BLACK.withAlpha(0.5);//设置球的地下色 viewer.scene.backgroundColor = Cesium.Color.BLACK; viewer.scene.screenSpaceCameraController.tiltEventTypes = [ Cesium.CameraEventType.RIGHT_DRAG, Cesium.CameraEventType.PINCH, { eventType: Cesium.CameraEventType.LEFT_DRAG, modifier: Cesium.KeyboardEventModifier.CTRL }, { eventType: Cesium.CameraEventType.RIGHT_DRAG, modifier: Cesium.KeyboardEventModifier.CTRL } ]; viewer.scene.screenSpaceCameraController.zoomEventTypes = [ Cesium.CameraEventType.MIDDLE_DRAG, Cesium.CameraEventType.WHEEL, Cesium.CameraEventType.PINCH ]; this.layerMgr = new LayerMgr3D(viewer); this.getLayer3D(viewer)//加载地图 let lastPosition = {x:null,y:null,z:null};//记录上次移动坐标 let moveStartTime = Date.now();//记录上次setMapCenter事件, 用于防抖 let flag = false //帧检测移动后改为true const timeInterval = 500; //防抖时间 viewer.scene.postRender.addEventListener(() => { this.dispatch.runtime.tickViewChanged(); // this.layerMgr.frameUpdate(); const currentPos = viewer.camera.position const { x, y, z } = lastPosition if(currentPos.x===x && currentPos.y===y && currentPos.z===z){ if(flag && (Date.now() - moveStartTime >= timeInterval)){ const { lon, lat, height:olZoom } = getCameraViewCenter(viewer)||{}; console.log(lon, lat, olZoom); if(lon && lat && olZoom){ this.dispatch.runtime.setMapCenter({ center: [lon, lat], zoom: olZoom, pitch: config.pitch3d, }) } flag = false moveStartTime = Date.now() } }else{ //在移动 lastPosition = { x: currentPos.x, y: currentPos.y, z: currentPos.z }; flag = true } }); let destination = Cesium.Cartesian3.fromDegrees(115.064,30.989,5000) //默认相机位置 if(this.mapCenter){ destination = getCameraViewPosition(this.mapCenter) } // 设置相机位置 viewer.camera.setView({ destination: destination, orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(config.pitch3d), roll: 0.0, } }); this._map = viewer; const toremove = document.getElementsByClassName('cesium-widget-credits'); if (toremove && toremove[0]) { toremove[0].style.display = 'none'; } } coordinateToPixel(lgtd, lttd, elev) { if(!this._map){ return } const pt = Cesium.Cartesian3.fromDegrees(lgtd, lttd, elev); const result = Cesium.SceneTransforms.worldToWindowCoordinates( this._map.scene, pt); if (!result) { return null } return [result.x, result.y, pt.x, pt.y, pt.z]; } /** * 组件卸载时,需要销毁map对象 */ destroy() { console.log('##############destroy##############'); if (!this.layerMgr) { return; } this.layerMgr.destroy(); if (this._map) { this._map.destroy(); this._map = null; } } /** * get layer obj */ getLayer(name) { return this.layerMgr.getLayer(name); } zoomTo(cameraTarget={}) { if (cameraTarget.center) { if(cameraTarget.fixed){//固定相机朝向 const camera = this._map.camera; const destination = getNewPosition(cameraTarget.center, cameraTarget.zoom, camera) if(!destination){ return } camera.flyTo({ destination: destination, orientation: { heading: camera.heading, pitch: camera.pitch, roll: 0.0, }, duration: 1, }); }else{ this._map.camera.flyTo({ destination: getCameraViewPosition(cameraTarget), orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(config.pitch3d), roll: 0.0, }, duration: 1.5, // 飞行时间,单位秒,可以根据需要调整 // 其他可选参数,例如: // maximumHeight: 10000, // 最大高度 // pitchAdjustHeight : 1000, // 在飞行过程中调整俯仰角的高度阈值 // flyOverLongitude: 100, // 飞越经度,用于控制飞行路径 }); } } else if (cameraTarget.bound) { const b = cameraTarget.bound; const p1 = Cesium.Cartesian3.fromDegrees(...b[0]); const p2 = Cesium.Cartesian3.fromDegrees(...b[1]); this._map.camera.flyToBoundingSphere(Cesium.BoundingSphere.fromPoints([p1, p2])); } } async getLayer3D(viewer) { Dem3D(viewer)//地形 SatelliteImage3D(viewer)//卫星地图 // Tiles3D(viewer)//倾斜摄影 // Water3D(viewer)//水面 VillagesBouaLayer3D(viewer)//乡镇边界 BouaLayer3D(viewer)//县界 BouaMaskLayer3D(viewer)//县界外遮罩层 } } // // 这是一个测试性能的工具留着 // let listenerExecutionTimes = []; // 记录每次执行的时间 // const start = performance.now(); // const end = performance.now(); // listenerExecutionTimes.push(end - start); // setInterval(() => { // if (listenerExecutionTimes.length > 0) { // const avg = listenerExecutionTimes.reduce((a, b) => a + b, 0) / listenerExecutionTimes.length; // console.log(`平均每帧监听函数执行时间: ${avg.toFixed(3)}ms`); // listenerExecutionTimes = []; // 清空 // } // }, 1000);