123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513 |
- /* 引入Cesium */
- // import * as Cesium from 'Cesium';
- //状态栏
- import StatusBar from "./StatusBar.js";
- import '../Assets/styles/base.css';
- /**
- * 场景视图
- */
- class jtMap3d {
- /**
- *
- * 初始化三维大球
- * @author joy
- * @param {Object} options 具有以下属性:
- * @param {String} options.container 包含球体小部件的 DOM 元素ID
- * @param {String} [options.imageryProviderType] 默认底图(世界影像)影像类型
- * @param {String} [options.imageryProviderUrl] 默认底图(世界影像)影像路径
- *
- * @example
- *
- * 例1:
- * const jtMap3d = new jtMap3d({container: "jtMap3dContainer"});
- *
- * 例2:
- * const jtMap3d = new jtMap3d({
- * container: "jtMap3dContainer",
- * imageryProviderType: "SingleTileImageryProvider",
- * imageryProviderUrl: "img/earth_3.jpg",
- * });
- *
- */
- constructor(options) {
- if (!Cesium.defined(options) || !Cesium.defined(options.container)) {
- throw new Cesium.DeveloperError("options.container is required.");
- }
- /* 设置token 这很重要 否则将导致地图无法加载 */
- Cesium.Ion.defaultAccessToken =
- 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxNzM5YjQ3MC03YmMxLTRmMjAtOTk4Yi0yNDMyMDZlOTQzYTYiLCJpZCI6NTU5MjAsImlhdCI6MTYyNDI0NTM5NX0.diydVWFzw5C5rQlHaFYkdDJoSorcdex81KpWcntyICo';
- /* 初始化地图控件 */
- this._viewer = this._initMap(options);
- /* 初始化变量 地图基础图层集合*/
- this._imageryLayers = this._viewer.imageryLayers;
- /* 初始化变量 地图原语集合 */
- this._primitives = this._viewer.scene.primitives;
- /* 初始化变量 地图绘制实体集合 */
- this._entities = this._viewer.entities;
- /* 初始化变量 数据源集合 */
- this._dataSources = this._viewer.dataSources; //数据源集合
- //默认天空盒子
- this._defaultSkyBox = this._viewer.scene.skyBox;
- this.statusBar = new StatusBar(this._viewer);
- console.log(Cesium.buildModuleUrl.getCesiumBaseUrl());
- }
- /**
- * 初始化球体查看小部件
- * @ignore 忽略注释,注释不生成Doc
- * @param {Object} options 具有以下属性:
- * @param {Element | String} options.container 包含球体小部件的 DOM 元素或 ID
- * @param {String} [options.imageryProviderType] 影像类型
- * @param {String} [options.imageryProviderUrl] 影像路径
- * @return {Viewer}
- */
- _initMap(options) {
- // //添加默认底图(世界影像)
- // var imageryProvider = new Cesium.SingleTileImageryProvider({
- // url: 'jt3dSDK/imgs/earth_3.jpg',
- // });
- // if (Cesium.defined(options.imageryProviderType)) {
- // if (Cesium.defined(options.imageryProviderUrl)) {
- // if (options.imageryProviderType == "SingleTileImageryProvider") {
- // imageryProvider = new Cesium.SingleTileImageryProvider({
- // url: options.imageryProviderUrl,
- // });
- // } else if (options.imageryProviderType == "OpenStreetMapImageryProvider") {
- // imageryProvider = new Cesium.OpenStreetMapImageryProvider({
- // url: options.imageryProviderUrl
- // });
- // } else if (options.imageryProviderType == "ArcGisMapServerImageryProvider") {
- // imageryProvider = new Cesium.ArcGisMapServerImageryProvider({
- // url: options.imageryProviderUrl
- // });
- // }
- // } else {
- // throw new Cesium.DeveloperError("imageryProviderType and imageryProviderUrl are required.");
- // }
- // }
- //球体查看器
- let viewer = new Cesium.Viewer(options.container, {
- animation: true, //是否显示动画控件(左下角时间圆盘)
- timeline: true, //是否显示时间线控件(下方时间条),默认true
- shadows: false, //阴影,是否让太阳投射阴影
- shouldAnimate: true, //是否允许动画,是否允许场景中的动画自动播放
- baseLayerPicker: false, //地图切换控件(底图以及地形图)是否显示,默认显示true
- navigationHelpButton: false, //是否显示帮助信息控件,默认true
- homeButton: false, //主页按钮,默认true
- fullscreenButton: false, //全屏按钮,默认显示true
- sceneModePicker: false, //是否显示3D/2D选择器
- scene3DOnly: true, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
- infoBox: false, //点击要素之后显示的信息,默认true
- clampToGround: true, //开启贴地
- geocoder: false, //地名查找,默认true
- // imageryProvider: imageryProvider,
- selectionIndicator: false, //选中元素显示,默认true选中元素显示,默认true
- contextOptions: {
- webgl: {
- alpha: true,
- depth: true,
- stencil: true,
- antialias: true,
- premultipliedAlpha: true,
- //通过canvas.toDataURL()实现截图需要将该项设置为true
- preserveDrawingBuffer: true,
- failIfMajorPerformanceCaveat: true
- }
- }
- });
- //隐藏版本信息
- viewer._cesiumWidget._creditContainer.style.display = "none";
- //是否显示地球
- viewer.scene.globe.show = true;
- //高程遮挡效果。地形不透明 地形检测,Cesium开启地形检测
- /* 此项设置为true可以查看哪些内容掉到地下了 正常情况下设置为false 否则会导致绘制的点只能看见一半 */
- viewer.scene.globe.depthTestAgainstTerrain = true;
- // 光照效果
- viewer.scene.globe.enableLighting = false;
- //启动主动渲染 这样地图加载完成后停止渲染 可节省CPU的开支(开启,以防部分动态效果失效)
- viewer.scene.requestRenderMode = false;
- //是否显示帧FPS
- viewer.scene.debugShowFramesPerSecond = true;
- //是否隐藏大气圈,如果显示大气圈,自定义天空盒子无效
- viewer.scene.skyAtmosphere.show = false;
- //是否显示星空(默认天空盒子)
- viewer.scene.skyBox.show = true;
- //是否显示太阳
- viewer.scene.sun.show = true;
- //是否显示有月亮
- viewer.scene.moon.show = false;
- //取消鼠标左键双击
- viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
- //右侧缺少一块(全屏按钮)
- // viewer.animation.container.style.visibility = 'hidden';
- // viewer.timeline.container.style.visibility = 'hidden';
- // 修改timeline时间 从儒略日改为北京时间
- viewer.animation.viewModel.dateFormatter = localeDateTimeFormatter;
- viewer.animation.viewModel.timeFormatter = localeTimeFormatter;
- viewer.timeline.makeLabel = localeDateTimeFormatter;
- //ignoredate 忽略日期
- function localeDateTimeFormatter(datetime, viewModel, ignoredate) {
- var julianDT = new Cesium.JulianDate();
- Cesium.JulianDate.addHours(datetime, 8, julianDT);
- var gregorianDT = Cesium.JulianDate.toGregorianDate(julianDT);
- var objDT;
- if (ignoredate) {
- objDT = '';
- } else {
- objDT = new Date(gregorianDT.year, gregorianDT.month - 1, gregorianDT.day);
- objDT = gregorianDT.year + '-' + objDT.toLocaleString('zh-cn', {
- month: 'short'
- }).split('月').join('-') + gregorianDT.day + ' ';
- if (viewModel || gregorianDT.hour + gregorianDT.minute === 0) {
- return objDT
- objDT += '';
- }
- }
- let hour, minute, second;
- if (gregorianDT.hour < 10) {
- hour = `0${gregorianDT.hour}`
- } else {
- hour = gregorianDT.hour
- }
- if (gregorianDT.minute < 10) {
- minute = `0${gregorianDT.minute}`
- } else {
- minute = gregorianDT.minute
- }
- if (gregorianDT.second < 10) {
- second = `0${gregorianDT.second}`
- } else {
- second = gregorianDT.second
- }
- // var millisecond = Math.round(gregorianDT.millisecond);
- // return objDT + hour + ":" + minute + ":" + second+ ":" + millisecond;
- return objDT + hour + ":" + minute + ":" + second;
- }
- function localeTimeFormatter(time, viewModel) {
- return localeDateTimeFormatter(time, viewModel, true)
- }
- return viewer;
- }
- /**
- * 初始化大球视窗范围
- * @ignore 忽略注释,注释不生成Doc
- * @param {Object} options 具有以下属性:
- * @param {Number} options.longitude 经度,以度为单位
- * @param {Number} options.latitude 纬度,以度为单位
- * @param {Number} [options.height=0.0] 椭球的高度,以米为单位
- * @param {Number} [options.heading=0.0] 指向,默认值0.0(北)
- * @param {Number} [options.pitch=-90] 视角,默认值-90(向下看)。俯仰,人如果在赤道上空,俯仰角为0可见地球。如果在北纬,俯仰角为负才能见地球
- * @param {Number} [options.roll=0.0] 翻滚
- */
- _setView(options) {
- if (!Cesium.defined(options.longitude) && !Cesium.defined(options.latitude)) {
- throw new Cesium.DeveloperError("longitude and latitude are required.");
- }
- Cesium.Check.typeOf.number("longitude", options.longitude);
- Cesium.Check.typeOf.number("latitude", options.latitude);
- this._viewer.camera.setView({ //设置视图 设置相机位置、方向和变换。
- //fromDegrees()将经纬度和高程转为世界坐标 摄像机在 WGS84(世界)坐标中的最终位置,或从自上而下视图可见的矩形。
- destination: Cesium.Cartesian3.fromDegrees(
- options.longitude,
- options.latitude,
- options.height
- ),
- orientation: {
- //此视角为观察者/相机 Math.toRadians() 将角度换成弧度。
- heading: Cesium.Math.toRadians(Cesium.defaultValue(options.heading, 0.0)),
- pitch: Cesium.Math.toRadians(Cesium.defaultValue(options.pitch, -90)),
- roll: options.roll,
- },
- });
- }
- /**
- * 获取中国范围坐标
- * @ignore 忽略注释,注释不生成Doc
- */
- _getChinaPostion() {
- return Cesium.Cartesian3.fromDegrees(116.435314, 40.960521, 10000000.0);
- }
- /**
- * 初始定位中国
- * @ignore 忽略注释,注释不生成Doc
- */
- _flytoChina() {
- this._viewer.camera.flyTo({
- destination: this._getChinaPostion(),
- duration: 8
- });
- }
- }
- /**
- * 通用对外公开函数
- */
- Object.assign(jtMap3d.prototype, /** @lends jtMap3d.prototype */ {
- /**
- * 初始化大球视窗范围,锁定为中国范围
- */
- setViewChina: function() {
- this._setView({
- longitude: 103.84, //经度
- latitude: 31.15, //维度
- height: 24000000, //高度
- heading: 0, // 偏航
- pitch: -90, // 俯仰,人如果在赤道上空,俯仰角为0可见地球。如果在北纬,俯仰角为负才能见地球
- roll: 0.0 // 翻滚
- });
- },
- /**
- * 初始化项目范围(即全图功能)
- * @param {Object} options 具有以下属性:
- * @param {Number} options.west=0.0 最西端的经度范围[-180.0,180.0]
- * @param {Number} options.south=0.0 最南端的纬度范围[-90.0,90.0]
- * @param {Number} options.east=0.0 最东端的经度范围[-180.0,180.0]
- * @param {Number} options.north=0.0 最北端的纬度范围[-90.0,90.0]
- * @param {Number} [options.isRemove=true] 定位完成后是否删除
- * @param {Number} [options.duration=3] 飞行时间
- * @param {Number} [options.heading=0]
- * @param {Number} [options.pitch=-90]
- * @param {Number} [options.range=0]
- */
- fullMap: function(options) {
- return new Promise((resolve, reject) => {
- let _self = this;
- this._entities.removeById("fullMapRectangle");
- // 初始化参数默认值
- options.isRemove = Cesium.defaultValue(options.isRemove, true);
- options.duration = Cesium.defaultValue(options.duration, 3);
- options.heading = Cesium.defaultValue(options.heading, 0);
- options.pitch = Cesium.defaultValue(options.pitch, -90);
- options.range = Cesium.defaultValue(options.range, 0.0);
- //left,bottom,right,top (西,南,东,北)
- var rectangle = Cesium.Rectangle.fromDegrees(options.west, options.south, options.east,
- options.north);
- //定义一个实体对象
- var fullMapEntity = this._entities.add({
- id: "fullMapRectangle",
- name: "fullMapRectangle",
- rectangle: {
- coordinates: rectangle,
- material: Cesium.Color.GREEN.withAlpha(0),
- height: 10.0,
- outline: false
- }
- });
- var flyPromise = this._viewer.flyTo(fullMapEntity, {
- duration: options.duration, //飞行时间
- offset: {
- heading: Cesium.Math.toRadians(options.heading),
- pitch: Cesium.Math.toRadians(options.pitch),
- range: options.range
- },
- });
- flyPromise.then(function(flyPromise) {
- if (flyPromise) {
- //飞行成功后,是否移除该实体
- if (options.isRemove) {
- fullMapEntity && (_self._entities.remove(fullMapEntity),
- fullMapEntity = null);
- }
- resolve(true);
- }
- })
- .catch(function(error) {
- console.log(error);
- });
- });
- },
- /**
- * 地图指北
- */
- setMapNorth() {
- let viewer = this._viewer;
- let pitch = Cesium.Math.toDegrees(viewer.camera.pitch).toFixed(0);
- // 中心点位置
- var center = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(viewer.canvas.clientWidth / 2, viewer.canvas.clientHeight / 2));
- var curPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(center);
- let centerX = curPosition.longitude * 180 / Math.PI;
- let centerY = curPosition.latitude * 180 / Math.PI;
- //相机姿态信息
- let cameraPointX = viewer.camera.positionCartographic.longitude * 180 / Math.PI;
- let cameraPointY = viewer.camera.positionCartographic.latitude * 180 / Math.PI;
- let cameraPointZ = viewer.camera.positionCartographic.height.toFixed(0);
- // 计算两点之间距离
- var satrt = Cesium.Cartographic.fromDegrees(cameraPointX, cameraPointY, cameraPointZ);
- var end = Cesium.Cartographic.fromDegrees(centerX, centerY, 0);
- var geodesic = new Cesium.EllipsoidGeodesic();
- geodesic.setEndPoints(satrt, end);
- var distance = geodesic.surfaceDistance;
- let range = Math.sqrt(Math.pow(distance, 2) + Math.pow(cameraPointZ - 0, 2));
- // 创建旋转中心点
- if (this.centerEntity) {
- viewer.entities.remove(this.centerEntity);
- }
- this.centerEntity = viewer.entities.add({
- position: Cesium.Cartesian3.fromDegrees(centerX, centerY, 0),
- point: {
- color: Cesium.Color.RED,
- pixelSize: 1
- }
- });
- //更新场景相关旋转、角度距离参数
- let offset = new Cesium.HeadingPitchRange(Cesium.Math.toRadians(0), Cesium.Math.toRadians(pitch), range);
- viewer.zoomTo(this.centerEntity, offset);
- },
- /**
- * 地图自旋
- * @param {Array/Cartesian3} points 绕点位置[lng,lat,height]经度,以度为单位,纬度,以度为单位
- * @param {Object} options 具有以下属性:
- * @param {Number} [options.speed=30] 设定绕行一周花费时间
- * @param {Number} [options.pitch] 设定相机角度,默认相机当前看点的角度,如果大于0那么则是从地底往上看,所以要为负值。-90(向下看,俯仰)。俯仰,人如果在赤道上空,俯仰角为0可见地球。如果在北纬,俯仰角为负才能见地球
- * @param {Number} [options.height] 设定相机距离点的距离,默认相机当前视角高度
- */
- setMapSpinByPoint(points, options) {
- let _self = this;
- let viewer = this._viewer;
- if (!Cesium.defined(points)) {
- throw new Cesium.DeveloperError("points is required.");
- }
- options = options || {};
- options.speed = Cesium.defaultValue(options.speed, 30);
- //绕点位置
- var position = points;
- if (points instanceof Cesium.Cartesian3) {
- position = points;
- } else {
- position = Cesium.Cartesian3.fromDegrees(points[0], points[1], points[2] || 0);
- }
- // 为更直观地展示查询的位置,在点击处添加对应点
- var entity = viewer.entities.add(
- new Cesium.Entity({
- point: new Cesium.PointGraphics({
- color: new Cesium.Color(1, 1, 0),
- pixelSize: 6,
- outlineColor: new Cesium.Color(0, 1, 1)
- }),
- position: position
- })
- )
- // 给定飞行一周所需时间,比如30s, 那么每秒转动度数
- var angle = 360 / options.speed;
- // 相机的当前heading
- var initialHeading = viewer.camera.heading;
- // 相机的当前pitch,相机看点的角度,如果大于0那么则是从地底往上看,所以要为负值
- var pitch = viewer.camera.pitch
- if (options.pitch) {
- pitch = Cesium.Math.toRadians(options.pitch);
- }
- // 给定相机距离点多少距离飞行
- var distance = viewer.camera.positionCartographic.height;
- if (options.height) {
- distance = options.height;
- }
- // 起始时间
- var startTime = Cesium.JulianDate.fromDate(new Date());
- // 结束时间,设置一个结束时间,意思是360秒之后时间结束
- // var stopTime = Cesium.JulianDate.addSeconds(startTime,angle, new Cesium.JulianDate());
- viewer.clock.startTime = startTime.clone(); // 开始时间
- // viewer.clock.stopTime = stopTime.clone(); // 结速时间
- viewer.clock.currentTime = startTime.clone(); // 当前时间
- viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; // 行为方式
- viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; // 时钟设置为当前系统时间; 忽略所有其他设置。
- var Exection = function TimeExecution() {
- // 当前已经过去的时间,单位s
- var delTime = Cesium.JulianDate.secondsDifference(viewer.clock.currentTime, viewer.clock.startTime);
- // 根据过去的时间,计算偏航角的变化
- var heading = Cesium.Math.toRadians(delTime * angle) + initialHeading;
- viewer.scene.camera.setView({
- destination: position, // 点的坐标
- orientation: {
- heading: heading,
- pitch: pitch,
- }
- });
- viewer.scene.camera.moveBackward(distance);
- if (Cesium.JulianDate.compare(viewer.clock.currentTime, viewer.clock.stopTime) >= 0) {
- viewer.clock.onTick.removeEventListener(Exection);
- }
- //监听点击事件
- var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
- handler.setInputAction(function(click) {
- viewer.clock.onTick.removeEventListener(Exection);
- viewer.entities.remove(entity);
- }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
- };
- viewer.clock.onTick.addEventListener(Exection);
- },
- });
- /* 输出 */
- export default jtMap3d;
|