我正在参与掘金创作者训练营第4期,点击了解活动详情,一起学习吧!
前言
Cesium 并没有像二维的地图 api 系统一样向我们提供鹰眼图这样一个 gis 相关的功能,但在业务场景中却经常被要求添加鹰眼图,因为 Cesium 是一个三维球体,所以它的鹰眼图主要有两个方向:主视图三维球体鹰眼图二维平面和主视图鹰眼图均为球体。第一个方向在网上已有大神通过leaflet
实现(指路:OverviewMapForCesium),这篇文章主要来实现一下第二个方向,双球体的鹰眼实现。
实现效果
思路
首先,既然是两个球体,那么主视图和鹰眼图要分别定义两个Viewer
生成两个球体,并将鹰眼图中的Viewer
所有额外功能组件全部配置为false
,只保留最干净的球体即可。
接着我们需要将球体的相机控制全部关闭,只通过主视图球体的操作来同步到鹰眼图的球体。
最后将这个球体放到 dom 中,展示在主视图下方即可。
实现
我们直接将鹰眼这个功能封装成一个类,即插即用,首先我们定义暴露出来的方法AddEyeMap
,接受两个参数,第一个是要插入鹰眼图的 DOM 的 id,第二个是主视图的Viewer
,方便我们进行同步。
// 调用
Cesium.AddEyeMap("eyeContainer", Viewer)
复制代码
// 暴露方法
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}不存在!`)
}
// ……
}
复制代码
.eye-map-style {
width: 200px;
height: 200px;
position: absolute;
bottom: 0;
right: 0;
border: 1px solid blue;
z-index: 99999;
}
复制代码
在AddEyeMap
方法中,我们需要生成我们的鹰眼图球体,并进行相关配置:
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
设置鹰眼图中的球体相机角度:
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
实现每时每刻与主视图同步:
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相关小伙伴提出相关建议,共同学习~
相关文章
\