Cesium 完美保存当前相机视角

本文介绍如何在Cesium中保存与恢复相机视角,包括位置、方向和视锥体等参数,确保能够准确地回到之前的观察状态。适用于图层树定位等应用场景。

1 需求

很多场景有这种需求,简单的如图层树的定位到图层,这就包含了实体对象、地图服务、模型服务、特定位置等。
常见的对象有:
Entity,Cesium3DTileset,ImageryLayer
目前Entity,Cesium3DTileset在对象生成时就有bounds属性,可以通过viewer.flyTo/zoomTo等方法来进行定位,而ImagerLayer本来官方可以通过下面方法实现,但从实际情况来看往往很多provider并没有指定rectangle,所以就有了下面的解决方案,保存当前相机视角,以便定位到服务

// Zoom to an imagery layer.
imageryLayer.getViewableRectangle().then(function (rectangle) {
    return camera.flyTo({
        destination: rectangle
    });
});

相机主要包含参数

var camera= {
      position: camera.position.clone(),
      direction: camera.direction.clone(),
      up: camera.up.clone(),
      right: camera.right.clone(),
      transform: camera.transform.clone(),
      frustum: camera.frustum.clone()
};

参考文章:Cesium 飞入相关方法

2 解决方案

核心涉及到camera的frustum(视锥体)保存问题。

// 保存相机视角
function saveCamera()
{
	let camera = {
        position: null,
        direction: null,
        up: null,
        frustum: null,
      };
      cameraposition = viewer.camera.positionWC.clone();
      camera.up = viewer.camera.up.clone();
      camera.direction = viewer.camera.direction.clone();
      camera.frustum = saveFrustum(
        viewer.camera.frustum.clone()
      );
    return camera  
}
// 更新相机视角
function updateCamera(camera)
{
    // 这里flyTo或者setView都可以
    viewer.camera.setView({
        destination: camera.position,
        orientation: {
            direction: camera.direction,
            up: camera.up
        }
    });
    loadFrustum(camera.frustum);
}
// 保存相机视角时的视锥体方法
function saveFrustum(frustum)
{
    var options = {};
    if(frustum.near != undefined)
    {
        options['near'] = frustum.near;
    }
    if(frustum.far != undefined)
    {
        options['far'] = frustum.far;
    }
    if(frustum.top != undefined)
    {
        options['top'] = frustum.top;
    }
    if(frustum.bottom != undefined)
    {
        options['bottom'] = frustum.bottom;
    }
    if(frustum.left != undefined)
    {
        options['left'] = frustum.left;
    }
    if(frustum.right != undefined)
    {
        options['right'] = frustum.right;
    }
    if(frustum.xOffset != undefined)
    {
        options['xOffset'] = frustum.xOffset;
    }
    if(frustum.yOffset != undefined)
    {
        options['yOffset'] = frustum.yOffset;
    }
    if(frustum.fov != undefined)
    {
        options['fov'] = frustum.fov;
    }
    if(frustum.aspectRatio != undefined)
    {
        options['aspectRatio'] = frustum.aspectRatio;
    }
    return options;
}
// 恢复相机视角时的视锥体方法
function loadFrustum(frustum)
{
    if(frustum.near != null)
    {
        viewer.camera.frustum.near = frustum.near;
    }
    if(frustum.far != null)
    {
        viewer.camera.frustum.far = frustum.far;
    }
    if(frustum.top != undefined)
    {
        viewer.camera.frustum.top = frustum.top;
    }
    if(frustum.bottom != undefined)
    {
        viewer.camera.frustum.bottom = frustum.bottom;
    }
    if(frustum.left != undefined)
    {
        viewer.camera.frustum.left = frustum.left;
    }
    if(frustum.right != undefined)
    {
        viewer.camera.frustum.right = frustum.right;
    }
    if(frustum.xOffset != undefined)
    {
        viewer.camera.frustum.xOffset = frustum.xOffset;
    }
    if(frustum.yOffset != undefined)
    {
        viewer.camera.frustum.yOffset = frustum.yOffset;
    }
    if(frustum.fov != undefined)
    {
        viewer.camera.frustum.fov = frustum.fov;
    }
    if(frustum.aspectRatio != undefined)
    {
        viewer.camera.frustum.aspectRatio = frustum.aspectRatio;
    }
}


3 参考文章

https://blog.csdn.net/qq_38937839/article/details/73277920
https://blog.csdn.net/lvye1221/article/details/100071903

4 备注

Cesium.Camera还提供了当前视图发生变化的事件changed、视图发生移动的事件moveStart/moveEnd,它们都可以通过addEventListener()给其添加相应的响应函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值