Cesium | Ceisum双球体鹰眼图实现(Property与Camera实现)

前言

Cesium 并没有像二维的地图 api 系统一样向我们提供鹰眼图这样一个 gis 相关的功能,但在业务场景中却经常被要求添加鹰眼图,因为 Cesium 是一个三维球体,所以它的鹰眼图主要有两个方向:主视图三维球体鹰眼图二维平面和主视图鹰眼图均为球体。第一个方向在网上已有大神通过leaflet实现(指路:OverviewMapForCesium),这篇文章主要来实现一下第二个方向,双球体的鹰眼实现。

二维鹰眼.gif

实现效果

鹰眼.gif

思路

首先,既然是两个球体,那么主视图和鹰眼图要分别定义两个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相关小伙伴提出相关建议,共同学习~


Cesium | Ceisum双球体鹰眼图实现(Property与Camera实现)
https://moewang0321.github.io/2021/02/24/Ceisum双球体鹰眼图实现(Property与Camera实现)/
作者
Moe Wang
发布于
2021年2月24日
许可协议