Cesium 镜头(Camera) - cytggit/Map-openlayers GitHub Wiki

基本介绍

Cesium提供了以下默认鼠标行为:

(1)单击并拖拽球体:旋转地球,镜头俯角不变
(2)单击并拖拽空间:滚动roll、俯仰pitch镜头
(3)右击并拖拽、中键滚动:缩放镜头
(4)中键拖拽:沿着地表的点旋转镜头

调用camera.setView()可以设置相机的位置和方向:

camera.setView( {  
    positionCartographic : new Cesium.Cartographic( longitude, latitude, height ),  
    heading : headingAngle,  
    pitch : pitchAngle,  
    roll : rollAngle  
} );  
   
//确保指定的东西南北范围进入视野  
var west = Cesium.Math.toRadians( -77.0 );  
var south = Cesium.Math.toRadians( 38.0 );  
var east = Cesium.Math.toRadians( -72.0 );  
var north = Cesium.Math.toRadians( 42.0 );  
var extent = new Cesium.Extent( west, south, east, north );  
camera.viewExtent( extent, Cesium.Ellipsoid.WGS84 );  

基本方法介绍

1)、相机对象表示当前镜头的位置(position)、方向(orientation)、参考坐标系(reference frame)、视见体(View Frustum)。

2)、move*、zoom*方法用于沿着镜头的原点(orientation )或者一个给定的矢量来变换(translate)镜头的位置。移动过程中方向保持固定:

3)、look*、twist*方法用于依照direction、up、right向量来旋转方向,旋转过程中位置保持不变:

4)、rotate*方法用于依据给定的矢量来变换位置、旋转方向。

setView方式

  • Cartesian 方式(加载从点看去的视野)

    // Cartesian 方式确定位置 
    view.camera.setView({
      destination :  Cesium.Cartesian3.fromDegrees(116.435314,39.960521, 15000.0), // 设置位置
      orientation: {
          heading : Cesium.Math.toRadians(20.0), // 方向
          pitch : Cesium.Math.toRadians(-90.0),// 倾斜角度
          roll : 0
      }
    });
    
  • Rectangle 方式(加载矩形视野区域)

    // rectangle 方式
    view.camera.setView({
      destination: Cesium.Rectangle.fromDegrees(0.0, 20.0, 10.0, 30.0),
      orientation: {
          heading : Cesium.Math.toRadians(20.0), // 方向
          pitch : Cesium.Math.toRadians(-90.0),// 倾斜角度
          roll : 0
      }
    });
    
  • flyTo

    通过调用Camera这个方法可以跳转镜头到指定位置。具体用法和上面类似

    view.camera.flyTo({
      destination :  Cesium.Cartesian3.fromDegrees(116.435314,39.960521, 15000.0), // 设置位置
      orientation: {
          heading : Cesium.Math.toRadians(20.0), // 方向
          pitch : Cesium.Math.toRadians(-90.0),// 倾斜角度
          roll : 0
      },
      duration:5, // 设置飞行持续时间,默认会根据距离来计算
      complete: function () {
          // 到达位置后执行的回调函数
          console.log('到达目的地');
      },
      cancle: function () {
          // 如果取消飞行则会调用此函数
          console.log('飞行取消')
      },
      pitchAdjustHeight: -90, // 如果摄像机飞越高于该值,则调整俯仰俯仰的俯仰角度,并将地球保持在视口中。
      maximumHeight:5000, // 相机最大飞行高度
      flyOverLongitude: 100, // 如果到达目的地有2种方式,设置具体值后会强制选择方向飞过这个经度
    });
    
  • lookAt

    lookAt(target, offect) //会将视角固定在设置的点上

    target Cartesian3 目标位置在世界坐标。

    offset Cartestian 或 HeadingPitchRange 以目标为中心的当地东北向参考系中的目标的偏移量

    var center = Cesium.Cartesian3.fromDegrees(-72.0, 40.0);
    var heading = Cesium.Math.toRadians(50.0);
    var pitch = Cesium.Math.toRadians(-20.0);
    var range = 5000.0;
    view.camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, range));
    

官网DEMO(覆写镜头移动)

var viewer = new Cesium.Viewer('cesiumDemo',{
    baseLayerPicker: false,
    imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
        url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'
    })
});

var scene = viewer.scene;
var canvas = viewer.canvas; // 获取画布
canvas.setAttribute('tabindex', '0'); // 需要把焦点放在画布上
canvas.onclick = function() {
    canvas.focus();
};
var ellipsoid = viewer.scene.globe.ellipsoid; // 获取地球球体对象

// 禁用默认的事件处理程序
// 如果为真,则允许用户旋转相机。如果为假,相机将锁定到当前标题。此标志仅适用于2D和3D。
scene.screenSpaceCameraController.enableRotate = false;
// 如果为true,则允许用户平移地图。如果为假,相机将保持锁定在当前位置。此标志仅适用于2D和Columbus视图模式。
scene.screenSpaceCameraController.enableTranslate = false;
// 如果为真,允许用户放大和缩小。如果为假,相机将锁定到距离椭圆体的当前距离
scene.screenSpaceCameraController.enableZoom = false;
// 如果为真,则允许用户倾斜相机。如果为假,相机将锁定到当前标题。这个标志只适用于3D和哥伦布视图。
scene.screenSpaceCameraController.enableTilt = false;
// 如果为true,则允许用户使用免费外观。如果错误,摄像机视图方向只能通过转换或旋转进行更改。此标志仅适用于3D和哥伦布视图模式。
scene.screenSpaceCameraController.enableLook = false;

// 鼠标开始位置
var startMousePosition;
// 鼠标位置
var mousePosition;
// 鼠标状态标志
var flags = {
    looking : false,//记录是否在查看地图,也就是记录是否点击了鼠标或键盘
    moveForward : false, // 向前
    moveBackward : false, // 向后
    moveUp : false,// 向上
    moveDown : false,// 向下
    moveLeft : false,// 向左
    moveRight : false// 向右
};

//监听用户的输入
var handler = new Cesium.ScreenSpaceEventHandler(canvas);

//当鼠标左键按下时执行(拿到鼠标按下时的位置)
handler.setInputAction(function(movement) {
    flags.looking = true;
    mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
//当鼠标移动时执行(拿到鼠标抬起时的位置)
handler.setInputAction(function(movement) {
    mousePosition = movement.endPosition;
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 处理鼠标左键弹起事件
handler.setInputAction(function(position) {
    flags.looking = false;
}, Cesium.ScreenSpaceEventType.LEFT_UP);

// 根据键盘按键返回标志
function getFlagForKeyCode(keyCode) {
    switch (keyCode) {
        case 'W'.charCodeAt(0):
            return 'moveForward';
        case 'S'.charCodeAt(0):
            return 'moveBackward';
        case 'Q'.charCodeAt(0):
            return 'moveUp';
        case 'E'.charCodeAt(0):
            return 'moveDown';
        case 'D'.charCodeAt(0):
            return 'moveRight';
        case 'A'.charCodeAt(0):
            return 'moveLeft';
        default:
            return undefined;
    }
}
// 监听键盘按下(keydown)事件
document.addEventListener('keydown', function(e) {
    // 获取键盘返回的标志
    var flagName = getFlagForKeyCode(e.keyCode);
    if (typeof flagName !== 'undefined') {
        flags[flagName] = true;
    }
}, false);

// 监听键盘弹起(keyup)时间
document.addEventListener('keyup', function(e) {
    // 获取键盘返回的标志
    var flagName = getFlagForKeyCode(e.keyCode);
    if (typeof flagName !== 'undefined') {
        flags[flagName] = false;
    }
}, false);

// 对onTick事件进行监听
// onTick事件:根据当前配置选项,从当前时间提前计时。应该每个帧都调用tick,而不管动画是否发生。
// 简单的说就是每过一帧都会执行这个事件
viewer.clock.onTick.addEventListener(function(clock) {
    // 获取实例的相机对象
    var camera = viewer.camera;

    //当按下鼠标左键时
    if (flags.looking) {
        // 获取画布的宽度
        var width = canvas.clientWidth;
        // 获取画布的高度
        var height = canvas.clientHeight;

        // 鼠标滑动的距离的x或y/网页可见区域的宽或者高
        var x = (mousePosition.x - startMousePosition.x) / width;
        var y = -(mousePosition.y - startMousePosition.y) / height;
        var lookFactor = 0.05;//这就是决定相机移动速度的参数
        
        //相机移动
        camera.lookRight(x * lookFactor);
        camera.lookUp(y * lookFactor);
    }

    // 获取相机高度,// 镜头移动的速度基于镜头离地球的高度
    // cartesianToCartographic(): 将笛卡尔坐标转化为地图坐标,方法返回Cartographic对象,包含经度、纬度、高度
    var cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;

    var moveRate = cameraHeight / 100.0;

    // 如果按下键盘就移动
    if (flags.moveForward) {
        camera.moveForward(moveRate);
    }
    if (flags.moveBackward) {
        camera.moveBackward(moveRate);
    }
    if (flags.moveUp) {
        camera.moveUp(moveRate);
    }
    if (flags.moveDown) {
        camera.moveDown(moveRate);
    }
    if (flags.moveLeft) {
        camera.moveLeft(moveRate);
    }
    if (flags.moveRight) {
        camera.moveRight(moveRate);
    }
});