相机控制主要是用于相机的飞行定位,例如系统初始化位置定位、视点切换、设备定位、报警事件定位等,这些都是通过对相机进行操作实现的。Cesium虽然提供了很多种方法用于实现相机的飞行定位,但这些方法都是基于Viewer、Camera这两个类实现的。
Viewer类
在Viewer类里面有两个方法用于实现相机的飞行定位,分别是flyTo、zoomTo方法。这两个方法第一个参数都是 target ,类型可以是Entity、DataSource、ImageryLayer、Cesium3DTileset等;flyTo方法的第二个参数是 options ,它是一个包含duration(飞行持续时间)、maximumHeight(飞行中的最大高度)、offset(HeadingPitchRange类型)的对象,而 zoomTo 方法的第二个参数是 offset ,即上面 options 中的 offset ,也是一个HeadingPitchRange类型的对象。Viewer类中的相机定位方法如下图所示:
Camera类
Camera 类对应的相机定位方法比较多,包括如下图所示的五个方法,每个方法的参数及参数类型都用不同的颜色区分开来。其中,options对象参数只列出了主要的属性,想查看全部参数请查阅官方 API 文档。
不管是Viewer类还是Camera类中的方法都能实现相机的定位功能,根据实际情况选择其一或组合使用。其中viewer.flyTo()、camera.flyTo()、camera.flyToBoundingSphere()这三个方法会有一个飞行动画的效果,所以会有飞行持续时间参数duration,默认是3秒。
相机参数
我们不管使用哪种方式,基本上都是先确定相机要飞到的某一个位置,如点、矩形、包围球等,然后再结合相机的三个参数heading、pitch、roll或range实现某一位置视角的计算。下面主要介绍这三个参数。
我们知道Cesium使用的是笛卡尔空间直角坐标系,X、Y、Z三个轴的正方向如下图所示:
相机的三个参数heading、pitch、roll的值是针对于坐标轴旋转的弧度数,示意图如下所示:
- heading:偏航角(弧度)
绕负Z轴旋转,顺时针为正,默认为正北方向0,其中正角向东增加。控制机体头的朝向位置,即左右方向的改变。
- pitch:俯仰角(弧度)
绕负Y轴旋转,顺时针为正,默认为俯视-90。正俯仰角在飞机上方,负俯仰角在飞机下方。可简单理解成前空翻、后空翻。
- roll:翻滚角(弧度)
绕正x轴旋转,顺时针为正,默认为0。可简单理解成侧空翻。
- range:范围(米)
代表相机距离目标的距离。
示例应用
问题:已知某一矩形范围 [110.2,35.6,112.3,36.7] ,要求相机倾斜25度,实现矩形位置飞行定位。
下面采用两种方法实现,并附上核心代码。
方法一:viewer.flyTo
var entity = viewer.entities.add({
rectangle: {
coordinates: rect,
material: Cesium.Color.GREEN.withAlpha(1.0),
height: 10.0,
outline: false,
},
});
var heading = Cesium.Math.toRadians(0.0);
var pitch = Cesium.Math.toRadians(-25.0);
var roll = Cesium.Math.toRadians(0);
var range = 0;
viewer.flyTo(entity, {
offset: new Cesium.HeadingPitchRange(heading, pitch, range),
});
方法二:camera.flyTo
var rect = Cesium.Rectangle.fromDegrees(110.2, 35.6, 112.3, 36.7);
viewer.camera.flyTo({
destination: rect,
orientation: new Cesium.HeadingPitchRoll(heading, pitch, roll),
});
咦???很奇怪,方法二竟然定位错误!!!但鼠标稍微往上拖拽一下,就能看到绿色的矩形。是什么原因造成的呢?问题出现在pitch值不是相机的默认值。
当相机的pitch不是默认值的时候,就会出现相机定位的位置不在屏幕中心的问题,但这时候使用viewer.flyTo方法来实现定位就能解决此问题。所以,建议采用方法一实现相机的飞行定位。
微信扫描下方二维码,获取更多资讯。