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

288 lines
9.5 KiB
JavaScript
Raw Normal View History

2025-08-07 11:28:32 +08:00
import config from '../config';
import LayerMgr3D from './layermgr3d';
import BaseMap from '../basemap';
2025-08-07 18:42:39 +08:00
import Demo3D from './demo'
2025-08-07 11:28:32 +08:00
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;
2025-08-07 18:42:39 +08:00
this.demo = null;
2025-08-07 11:28:32 +08:00
// @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, {
2025-08-07 18:42:39 +08:00
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,//去掉球边缘
2025-08-07 11:28:32 +08:00
});
2025-08-07 18:42:39 +08:00
2025-08-07 11:28:32 +08:00
//设置地表透明
let globe = viewer.scene.globe;
2025-08-07 18:42:39 +08:00
globe.depthTestAgainstTerrain = false;//关闭深度测试
2025-08-07 11:28:32 +08:00
//viewer.scene.skyAtmosphere.show = false; //关闭大气层阴影
viewer.scene.screenSpaceCameraController.minimumZoomDistance = 100;
2025-08-07 18:42:39 +08:00
// viewer.scene.screenSpaceCameraController.maximumZoomDistance = 200000;
2025-08-07 11:28:32 +08:00
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
];
//加载倾斜摄影
2025-08-07 18:42:39 +08:00
// 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, //不可设置太高,目标机子空闲内存值以内,防止浏览器过于卡
// });
2025-08-07 11:28:32 +08:00
// 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,
}));*/
2025-08-07 18:42:39 +08:00
2025-08-07 11:28:32 +08:00
//监听地图移动完成事件
viewer.camera.moveEnd.addEventListener(() => {
//获取当前相机高度
let height = Math.ceil(viewer.camera.positionCartographic.height);
let zoom = heightToZoom(height);
console.log('地图变化监听事件',zoom);
});
this.layerMgr = new LayerMgr3D(viewer);
2025-08-07 18:42:39 +08:00
this.demo = new Demo3D()
this.demo.getGltf(viewer)
this.demo.getQxsy(viewer)
2025-08-07 11:28:32 +08:00
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) {
2025-08-07 18:42:39 +08:00
// 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];
2025-08-07 11:28:32 +08:00
}
/**
* 组件卸载时需要销毁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]));
}
}
}