tsg-web/src/views/Home/MapCtrl/Map3D/Map3D.js

288 lines
9.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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