cesium相机控制

cesium相机控制


Cesium中orientation函数用于设定方向,不仅是相机方向,还包括模型的方向等。position函数用于设定相机位置。

Cesium将Orientation定义为Object。它通常包含heading、pitch和roll,这三者并不是必选参数,不设置具体参数则自动设为相应默认值。 可通过HeadingPitchRoll API查看相应属性。

pitch:围绕X轴旋转,也叫俯仰角,因为绕X轴旋转,可以控制飞机俯仰角,往上飞或者往下飞。

yaw:围绕Y轴旋转,也叫偏航角,因为绕Y轴旋转,可以控制飞机飞行方向,往左飞还是往右飞。

roll:围绕Z轴旋转,也叫翻滚角,因为绕Z轴旋转,可以控制飞机做翻滚旋转。

Cesium中相机方向orientation设定原理与右手笛卡儿坐标系原理相同,用heading替换yaw,但是含义相同,都是指水平旋转,Cesium中以正北为参照,即x轴所在方向。

heading:默认方向为正北,正角度为向东旋转,即水平旋转,也叫偏航角。

pitch:默认旋转角度为一90,即朝向地面,正角度为平面之上,负角度为平面之下,即上下旋转,也叫俯仰角。

roll:默认旋转角度为0,左右旋转.正角度向右旋转,负角度向左旋转,也叫翻滚角。


cesium相机切换

// 切换地图相机方式 右键旋转 中键放大
    viewer.scene.screenSpaceCameraController.tiltEventTypes = [
        Cesium.CameraEventType.RIGHT_DRAG, Cesium.CameraEventType.PINCH,
        { eventType: Cesium.CameraEventType.LEFT_DRAG, modifier: Cesium.KeyboardEventModifier.CTRL },
        { eventType: Cesium.CameraEventType.RIGHT_DRAG, modifier: Cesium.KeyboardEventModifier.CTRL }
    ];
    viewer.scene.screenSpaceCameraController.zoomEventTypes = [Cesium.CameraEventType.MIDDLE_DRAG, Cesium.CameraEventType.WHEEL, Cesium.CameraEventType.PINCH];

获取当前相机信息

var head = viewer.scene.camera.heading 
var pitch = viewer.scene.camera.pitch
var roll  = viewer.scene.camera.roll
var info ={'head': head ,'pitch': pitch ,'roll': roll};
// 获取位置 wgs84的地心坐标系,x,y坐标值以弧度来表示
var position = viewer.scene.camera.positionCartographic //with longitude and latitude expressed in radians and height in meters.

//以下方式也可以获取相机位置只是返回的坐标系不一样
// var position = viewer.scene.camera.position //cartesian3 空间直角坐标系
// var ellipsoid = scene.globe.ellipsoid;
// var position =ellipsoid.cartesianToCartographic(viewer.scene.camera.position)//
// 弧度转经纬度
var longitude = Cesium.Math.toDegrees(position.longitude).toFixed(6)
var latitude =  Cesium.Math.toDegrees(position.latitude).toFixed(6)
var height = position.height
const resInfo = {lng: longitude, lat: latitude, h: height, mat: info}
console.log(resInfo);



相机系统方法


flyHome

将相机飞到主视图

 // Cesium 相机系统 --flyHome   将相机飞到主视图
loadFlyHome() {
    this.loadView()
    // 三秒后飞回主视图
    setInterval(() => {
        this.viewer.camera.flyHome(1)
    }, 3000)
}

viewer.zoomTo

异步设置摄像机以查看提供的一个或多个实体或数据源

viewer.zoomTo(entity ,{
            heading:opt.heading,
            pitch:opt.pitch,
            range:opt.range
        })
//或者 viewer.zoomTo(viewer.entities)
// 引入点云并移动镜头
var arr = viewer.scene.primitives.add(
     new Cesium.Cesium3DTileset({
         url: '点云json路径', //文件的路径
     })
);
// 定位过去
viewer.zoomTo(arr);

setView

setView通过定义相机飞行目的点三维坐标(经纬度和大地高)和视线方向,将视角直接切换到所设定的视城范围内,没有空中飞行的过程,适用于快速切幕视角

viewer.scene.camera.setView({
		// 经度 纬度 高度
        destination: Cesium.Cartesian3.fromDegrees(
            110.21714, 24.3903, 430
        ),
        // 朝向 仰角 倾斜
        orientation: {
            heading : 1.575128294766218,
            pitch : -0.3490679348077246, // Cesium.Math.toRadians(-35.0),
            roll : 3.7854342682663855e-7
        }
    })

viewBoundingSphere

viewBoundingSphere相机运动效果与setView类似,都是视域切换到目标点,没有视域飞行的过程,但是其设定方法与setView 有所不同。

viewBoundingSphere函数必须设定模型的外接圆,viewBoundingSphere这种方式适用于室内浏览,因为 家内空间较小,相机移动的幅度不易控制。

viewBoundingSphere可将相机固定在定点,视角绕点旋转360",实现定点环游。BoundingSphere简单说就是物体的外接球。

viewBoundingSphere默认将视点置于外接球球心,可以设置偏称。
以一个室内三维模型为例,加载数据完成后通过设定viewBoundingSphere实现定点环绕浏览

var tileset = new Cesium.Cesium3DTileset({
    url: 'http://192.168.1.243:8088/data/point/demo01/tileset.json',
});
tileset.readyPromise.then(function(tileset){
    primitives.add(tileset);
    viewer.scene.primitives.add(primitives);
    viewer.camera.viewBoundingSphere(tileset.boundingSphere,new Cesium.HeadingPitchRange(-2.57,0,2));
});

viewer.flyTo

空中飞行逐步切换视域,参数较少

viewer
      .flyTo(entity, {
        offset: {
          heading: opt.heading,
          pitch:opt.pitch,
          roll: opt.roll
        },
        duration: opt.duration // 设置飞行持续时间,默认会根据距离来计算
      })
      .then(e => {
        func & func();
      });

flyTo

setView是快速切换视角,fIyTo则具有空中飞行逐步切换视域的效果,可以设置飞行时间,相机则根据当前视点位置和目标视点位置自动设定飞行速度和飞行路线,实现巡游式视域切换

viewer.scene.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(
            110.21714, 24.3903, 430
        ),,  // 设置视点位置,建议使用谷歌地球坐标位置无偏差
    duration:2,   //设置飞行持续时间,默认值会根据距离计算(单位秒)
    orientation : {
        heading : Cesium.Math.toRadians(120.0),// 方向
        pitch : Cesium.Math.toRadians(-90.0),// 仰角角度
        roll : 0 // 倾斜角度
    },
    complete:function(){
        //到达位置后执行的回调函数
    },
    cancle:function(){
        //如果取消飞行则会调用此函数
    },
    pitchAdjustHeight: -90,// 如果摄像机飞越高于该值,则调整俯仰角,并将地球保持在视域中
    maximumHeight: 5000, // 相机最大飞行高度
    flyOverLongitude: 100, //相机飞向目的地的过程中,必须强制经过东经100°子午线
    easingFunction: Cesium.EasingFunction.LINEAR_NONE, // 默认运动方式是慢-快-慢
    // 使用缓动函数实现匀速运动
});

cancelFlight

取消当前的相机飞行并将相机留在其当前位置。如果没有进行任何飞行,则此功能不执行任何操作。

viewer.camera.cancelFlight() 

completeFlight

完成当前的相机飞行并将相机立即移动到其最终目的地。如果没有进行任何飞行,则此功能不执行任何操作。

viewer.camera.completeFlight() 

lookAt

lookAt函数也是将视角固定在所设置的目的地点上,用户可以通过鼠标任意旋转视角方向,但是不会改变其位置。

const center =  Cesium.Cartesian3.fromDegrees(110.2203, 24.3903, 350)  // 目标位置
const heading =   3.827657527141585// 水平旋转  -正北方向
const pitchs =  -0.5138211629018499 // 上下旋转  --俯视朝向
const range =  3.8// 目标点高度
viewer.camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitchs, range))

lookAtTransform

锁定目标旋转拍摄

// Lock camera to a point
// 围绕拍摄的目标点
var center = Cesium.Cartesian3.fromDegrees(110.2203, 24.3903, 230)
var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center);

// 相机位置初始化
viewer.scene.camera.lookAtTransform(transform, new Cesium.HeadingPitchRange(3.827657527141585, -0.5138211629018499, 200));

// 添加事件监听,围绕固定目标点旋转
const move = function(clock) {
    viewer.scene.camera.rotateRight(0.008);
}
viewer.clock.onTick.addEventListener(move);

停止拍摄时需要移除事件监听并解除锁定

// 移除事件监听
viewer.clock.onTick.removeEventListener(move)

// 两种解除相机锁定目标的方式
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
viewer.trackedEntity =undefined


键盘控制

三维场景开发中,通过键盘操纵相机视域移动是一个常规功能。Cesium为开发者定义了键盘事件,想要实现键盘事件需要设定相机参数,监听键盘事件并绑定相机参数。通常约定以下键盘事件:

W键向前移动相机
S键向后移动相机
A键向左移动相机
D键向右移动相机
Q键向上移动相机
E键向下移动相机

接下来通过具体代码设定键盘事件,实现相机移动翻转:

var ellipsoid = viewer.scene.globe.ellipsoid;//定义椭球

然后定义flags对象,设定具体相机事件。此处设置8个事件,分别是前移、后移、上移、下移左移、右移,左转和右转。

var flags= {
moveforward: false,
moveBackward: false,
moveUp: false,
noveDowm: false,
moveLeft: false,
noveRight: false, 
lokleft: false,
lokRight: false
};
// 将健盘健码绑定对应相机机事件
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';
    case 'G'.charCodeAt(0);
        return 'twistRight';
    case 'F'.charCodeAt(0);
        return 'twistLeft';
    case 37:
        return 'lookLeft';
    case 39:
        return 'lookRight';
    case 38:
        return 'lookUp';
    case 40:
        return 'lookDown';
    default:
        return undefined;
   }
}

// 监听键盘按下事件
document.addEventListener('keydown',function(e){
    var flagName = getFlagForKeyCode(e.keyCode);
    if(typeof flagName !== 'undefined'){
        flags[flagName] = true;
    }
},false);

// 监听键盘弹起事件
document.addEventListener('keyup',function(e){
    var flagName = getFlagForKeyCode(e.keyCode);
    if(typeof flagName !== 'undefined'){
        flags[flagName] = true;
    }
},false);

//监听不同键码事件,并控制相应的相机事件
viewer clock.onTick.addEventListener(function(clock){
var camera = viewer.camera;
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);
    }
if (flags.lookLeft) (
    camera.lookLeft(moveRate);
    }
if (flags.lookRight) (
    camera.lookRight(moveRate);
    }
if (flags.twistRight) (
    camera.twistRight(moveRate);
    }
if (flags.twistLeft) (
    camera.twistLeft(moveRate);
    }
if (flags.lookUp) (
    camera.lookUp(moveRate);
    }
if (flags.lookDown) (
    camera.lookDown(moveRate);
    }
});

这样就可以完成三维场景巡游

你可能感兴趣的:(WebGIS,计算机视觉,人工智能)