import config from '../config'; import LayerMgr3D from './layermgr3d'; import BaseMap from '../basemap'; import Demo3D from './demo' import { ToolManager } from './ToolManager3D'; const { Cesium } = window; function __prepare_ces(dispatch) { Cesium.CesiumWidget.prototype.showErrorPanel = function (title) { dispatch && dispatch.map.setMode('2d'); if (title && title.indexOf('constructing') >= 0) { alert('无法初始化三维场景,如果一直出现此问题,请尝试下载最新的chrome浏览器'); } else { alert('三维场景渲染出现问题'); } }; } /*根据camera高度近似计算当前层级*/ const heightToZoom = ( height) => { var A = 40487.57; var B = 0.00007096758; var c = 91610.74; var D = -40467.74; return Math.round(D+(A-D)/(1+Math.pow( height/c,B)) ); } /** * OL 封装 */ export default class Map3D extends BaseMap { constructor({ divid, dispatch }) { super(); this.dispatch = dispatch; this.divid = divid; // div element id this._map = null; // openlayers map obj this.layerMgr = null; this.toolMgr = null; this.demo = null; // @ts-ignore const open = XMLHttpRequest.prototype.open; // @ts-ignore XMLHttpRequest.prototype.open = function (method, url, ...rest) { if (url.startsWith('http://res3dstatic7')) { url = url.replaceAll('+', '%2B'); } return open.call(this, method, url, ...rest); }; } /** * 初始化地图、图层 */ init() { __prepare_ces(this.dispatch); const tiandiKey = "efc861f25f96dc6e5f884f0403ebfefd"; //天地图key,官网申请 const baseUrl = "https://{s}.tianditu.gov.cn";//'https://t{0-7}.tianditu.gov.cn'; const viewer = new Cesium.Viewer(this.divid, { terrain: Cesium.Terrain.fromWorldTerrain({ requestVertexNormals: 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,//去掉球边缘 }); //设置地表透明 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.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 ]; //加载倾斜摄影 // var tileset = new Cesium.Cesium3DTileset({ // //url: 'http://res3dstatic7.cloudowr.cn/wufeng/3dtile/tileset.json', // url: localStorage.getItem('address')==="wufeng"? // 'service2/kshdata/1221wtz-3dtile-all/tileset.json': // "service2/kshdata/GRH/tileset.json", // maximumScreenSpaceError: 32, // maximumMemoryUsage: 100, //不可设置太高,目标机子空闲内存值以内,防止浏览器过于卡 // }); // fetch(`${process.env.PUBLIC_URL}/data/geojson/${localStorage.getItem('address')}/boua.geojson`) // .then(resp => resp.json()) // .then(data => { // let features = data.features; // let positionArray = []; // // 获取区域的经纬度坐标 // for (let i = 0; i < features[0].geometry.coordinates[0].length; i++) { // let coor = features[0].geometry.coordinates[0][i]; // positionArray.push(coor[0]); // positionArray.push(coor[1]); // } // // 遮罩 // let polygonEntity = new Cesium.Entity({ // polygon: { // hierarchy: { // // 添加外部区域为1/4半圆,设置为180会报错 [0, 0, 0, 90, 179, 90, 179, 0] // positions: Cesium.Cartesian3.fromDegreesArray([100, 0, 100, 89, 150, 89, 150, 0]), // // 中心挖空的“洞” // holes: [{ // positions: Cesium.Cartesian3.fromDegreesArray(positionArray) // }] // }, // material: Cesium.Color.BLACK.withAlpha(0.7) //new Cesium.Color(236,242,249, 1) // } // }); // // 边界线 // let lineEntity = new Cesium.Entity({ // polyline: { // positions: Cesium.Cartesian3.fromDegreesArray(positionArray), // width: 7, // material: Cesium.Color.fromCssColorString('#7AE3C8'),//边界线颜色//Cesium.Color.YELLOW //new Cesium.Color(122,227,200, 1) // clampToGround: true, // zIndex: 10 // } // }); // viewer.entities.add(polygonEntity); // viewer.entities.add(lineEntity); // //viewer.flyTo(lineEntity); // }); //添加到球体上 // viewer.scene.primitives.add(tileset); /*viewer.dataSources.add(Cesium.GeoJsonDataSource.load('http://res3dstatic4.cloudowr.cn/wufeng/geojson/boua.geojson', { stroke: Cesium.Color.PINK, strokeWidth: 3, clampToGround: true, }));*/ //监听地图移动完成事件 viewer.camera.moveEnd.addEventListener(() => { //获取当前相机高度 let height = Math.ceil(viewer.camera.positionCartographic.height); let zoom = heightToZoom(height); console.log('地图变化监听事件',zoom); }); this.layerMgr = new LayerMgr3D(viewer); this.demo = new Demo3D() this.demo.getGltf(viewer) this.demo.getQxsy(viewer) viewer.scene.postRender.addEventListener(() => { this.dispatch.runtime.tickViewChanged(); this.layerMgr.frameUpdate(); }); this.toolMgr = new ToolManager(viewer, this.dispatch); this.toolMgr.init(); viewer.camera.setView({ destination: Cesium.Cartesian3.fromDegrees(...config.homeCenter3D), orientation: { heading: Cesium.Math.toRadians(0), pitch: Cesium.Math.toRadians(-35.0), roll: 0.0 } }); // 限制相机高度 // 相机最低高度 const minimumHeight = 120; // 在渲染阶段前添加事件监听器 viewer.scene.preRender.addEventListener(function () { var eye = viewer.camera.positionCartographic; // 判断相机坐标是否小于阈值,若小于阈值,则保持视点方位,修改相机高度 if (eye.height < minimumHeight) { viewer.camera.setView({ destination: Cesium.Cartesian3.fromRadians(eye.longitude, eye.latitude, minimumHeight), orientation: { direction: viewer.camera.direction, up: viewer.camera.up } }); } }); this._map = viewer; const toremove = document.getElementsByClassName('cesium-widget-credits'); if (toremove && toremove[0]) { toremove[0].style.display = 'none'; } } coordinateToPixel(lgtd, lttd, elev) { // const pt = Cesium.Cartesian3.fromDegrees(lgtd, lttd, elev); // const result = Cesium.SceneTransforms.wgs84ToWindowCoordinates( // 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) { this._map.camera.flyToBoundingSphere(new Cesium.BoundingSphere( Cesium.Cartesian3.fromDegrees(cameraTarget.center[0], cameraTarget.center[1], cameraTarget.center[2] || 0), 800) ); } 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])); } } }