前言
Cesium 并没有像二维的地图 api 系统一样向我们提供鹰眼图这样一个 gis 相关的功能,但在业务场景中却经常被要求添加鹰眼图,因为 Cesium 是一个三维球体,所以它的鹰眼图主要有两个方向:主视图三维球体鹰眼图二维平面和主视图鹰眼图均为球体。第一个方向在网上已有大神通过leaflet
实现(指路:OverviewMapForCesium),这篇文章主要来实现一下第二个方向,双球体的鹰眼实现。
实现效果
思路
首先,既然是两个球体,那么主视图和鹰眼图要分别定义两个Viewer
生成两个球体,并将鹰眼图中的Viewer
所有额外功能组件全部配置为false
,只保留最干净的球体即可。
接着我们需要将球体的相机控制全部关闭,只通过主视图球体的操作来同步到鹰眼图的球体。
最后将这个球体放到 dom 中,展示在主视图下方即可。
实现
我们直接将鹰眼这个功能封装成一个类,即插即用,首先我们定义暴露出来的方法AddEyeMap
,接受两个参数,第一个是要插入鹰眼图的 DOM 的 id,第二个是主视图的Viewer
,方便我们进行同步。
1 2
| // 调用 Cesium.AddEyeMap("eyeContainer", Viewer)
|
1 2 3 4 5 6 7 8 9 10 11 12
| export default function AddEyeMap(domId, viewer) { if (!domId) return const dom = document.getElementById(domId) dom.classList.add('eye-map-style') if (!dom) { throw new Error(`${domId}不存在!`) } }
|
1 2 3 4 5 6 7 8 9
| .eye-map-style { width: 200px; height: 200px; position: absolute; bottom: 0; right: 0; border: 1px solid blue; z-index: 99999; }
|
在AddEyeMap
方法中,我们需要生成我们的鹰眼图球体,并进行相关配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class EyeMap { constructor(id) { this.viewer = new Cesium.Viewer(id, { animation: false, baseLayerPicker: false, fullscreenButton: false, geocoder: false, homeButton: false, sceneModePicker: false, selectionIndicator: false, timeline: false, navigationHelpButton: false, infoBox: false, navigationInstructionsInitiallyVisible: false, }) this.viewer._cesiumWidget._creditContainer.style.display = 'none' const control = this.viewer.scene.screenSpaceCameraController control.enableRotate = false control.enableTranslate = false control.enableZoom = false control.enableTilt = false control.enableLook = false } }
|
EyeMap
类实现了我们思路中的第二步,接着还需要给类一个同步视角的方法,利用主视图传递过来的Viewer
设置鹰眼图中的球体相机角度:
1 2 3 4 5 6 7 8 9 10 11
| EyeMap.prototype._sync = function(viewer){ this.viewer.camera.flyTo({ destination: viewer.camera.position, orientation: { heading: viewer.camera.heading, pitch: viewer.camera.pitch, roll: viewer.camera.roll, }, duration: 0.0, }) }
|
接下来我们在AddEyeMap
中 new 一个鹰眼球实例,并通过CallbackProperty
实现每时每刻与主视图同步:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| export default function AddEyeMap(id, viewer) { const eyeMap = new EyeMap(id) viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(0, 0), label: { text: new Cesium.CallbackProperty(() => { eyeMap._sync(viewer) return '' }, true), }, }) }
|
上述代码中我们通过添加了一个空字符串的label,利用它的CallbackProperty
实现了每时每刻调用syncViewer
方法来同步两个球的相机视角。
最后
本文实现了基本的双球鹰眼图,只提供一个实现思路,后续可以在此基础上对功能进行扩展。也欢迎研究Cesium和GIS相关小伙伴提出相关建议,共同学习~