Cesium case analysis (three) - Camera Camera

1 Overview

Cesium's Camera case demonstrated its controlling robots on the lens, it is possible to adjust the position of the view. Here we improved a bit this instance to be able to show their interest in the case of some points of interest, and summarizes the problems encountered.

2. Examples

2.1. Camera.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport"
        content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
    <meta name="description" content="Fly to a specified location or view a geographic rectangle.">
    <meta name="cesium-sandcastle-labels" content="Beginner, Tutorials, Showcases">
    <title>Cesium Demo</title>
    <script type="text/javascript" src="../Build/Cesium/Cesium.js"></script>
    <style>
        @import url(../Build/Cesium/Widgets/widgets.css);

        html,
        body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            overflow: hidden;
            font-family: sans-serif;
            background: #000;
        }

        .fullSize {
            display: block;
            position: absolute;
            top: 0;
            left: 0;
            border: none;
            width: 100%;
            height: 100%;
        }

        #toolbar {
            margin: 5px;
            padding: 2px 5px;
            position: absolute;
        }
    </style>
</head>

<body>
    <div id="cesiumContainer" class="fullSize"></div>
    <div id="toolbar">
        <select id = "camera_select", class="cesium-button">
            <option value="undefined">
                相机选项
            </option>
            <option value="undefined">
                飞行至某一点——武汉大学
            </option>
            <option value="undefined">
                飞行至某区域——武汉市
            </option>
            <option value="undefined">
                设置相机点——华中科技大学
            </option>
            <option value="undefined">
                设置相机区域——上海市
            </option>
            <option value="undefined">
                从武大飞向华科
            </option>
        </select>
    </div>
    <script src="Camera.js"></script>
</body>

</html>

On the basis of the digital code on the display assembly earth newly added view a drop-down list box control, select the option to view the current can be adjusted to a position corresponding to.

2.2. Camera.js

//Add your ion access token from cesium.com/ion/ 
Cesium.Ion.defaultAccessToken = '你在Cesium申请的key';

var tdtKey = "你在天地图申请的key";

'use strict';

//默认BING影像地图
var viewer = new Cesium.Viewer('cesiumContainer', {
    imageryProvider: Cesium.createWorldImagery({
        style: Cesium.IonWorldImageryStyle.AERIAL
    }),
    baseLayerPicker: false
});

//全球影像中文注记服务
var imageryLayers = viewer.scene.imageryLayers;
var tdtAnnoLayer = imageryLayers.addImageryProvider(new Cesium.WebMapTileServiceImageryProvider({
    url: "http://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={TileMatrix}&TILEROW={TileRow}&TILECOL={TileCol}&tk=" + tdtKey,
    layer: "tdtAnnoLayer",
    style: "default",
    format: "image/jpeg",
    tileMatrixSetID: "GoogleMapsCompatible"
}));

var camera_select = document.getElementById("camera_select");
if (camera_select) {
    camera_select.onchange = function gradeChange() {
        switch (camera_select.selectedIndex) {
            case 1:
                viewer.camera.flyTo({
                    destination: Cesium.Cartesian3.fromDegrees(114.35231209, 30.53542614, 5000.0),
                    orientation: {
                        heading: Cesium.Math.toRadians(0.0),
                        pitch: Cesium.Math.toRadians(-90.0),
                        roll: Cesium.Math.toRadians(0.0)
                    }
                });
                break;
            case 2:
                viewer.camera.flyTo({
                    destination: Cesium.Rectangle.fromDegrees(113.683333, 29.966667, 115.083333, 31.366667)
                });
                break;
            case 3:
                viewer.camera.setView({
                    destination: Cesium.Cartesian3.fromDegrees(114.40782845, 30.51011682, 5000.0),
                    orientation: {
                        heading: Cesium.Math.toRadians(0.0),
                        pitch: Cesium.Math.toRadians(-90.0),
                        roll: Cesium.Math.toRadians(0.0)
                    }
                });
                break;
            case 4:
                viewer.camera.setView({
                    destination: Cesium.Rectangle.fromDegrees(120.86667, 30.66667, 122.2, 31.883333)
                });
                break;
            case 5: {
                var whdxOptions = {
                    destination: Cesium.Cartesian3.fromDegrees(114.35231209, 30.53542614, 5000.0),
                    duration: 5,
                    orientation: {
                        heading: Cesium.Math.toRadians(0.0),
                        pitch: Cesium.Math.toRadians(-90.0),
                        roll: Cesium.Math.toRadians(0.0)
                    }
                };
                var hzkjdxOptions = {
                    destination: Cesium.Cartesian3.fromDegrees(114.40782845, 30.51011682, 5000.0),
                    orientation: {
                        heading: Cesium.Math.toRadians(0.0),
                        pitch: Cesium.Math.toRadians(-90.0),
                        roll: Cesium.Math.toRadians(0.0)
                    },
                    duration: 5,
                   //flyOverLongitude: Cesium.Math.toRadians(60.0)
                };

                whdxOptions.complete = function () {
                    setTimeout(function () {
                        viewer.camera.flyTo(hzkjdxOptions);
                    }, 1000);
                };

                // if (adjustPitch) {
                //     tokyoOptions.pitchAdjustHeight = 1000;
                //     laOptions.pitchAdjustHeight = 1000;
                // }

                viewer.camera.flyTo(whdxOptions);
            }
            break;
        default:
            break;
        }
    }
}

The code first adds Cesium.Viewer Bing the default image map and world map mark the Chinese; then get the drop-down list box control camera_select HTML pages according to id; Finally, according to the options adjust the camera view. Adjust the view here shows several ways.

2.2.1. Flight to a point

Set camera lens gradually from a current position to a point of flight through the Cesium.Camera flyTo () function is implemented, the specific function is defined as follows:

Cesium.Camera the flyTo () function is defined
Figure 1: Cesium.Camera of flyTo () function is defined

This function was introduced to key configuration object that destination, orientation of these two, respectively, the camera lens position and attitude. This embodiment corresponding code is as follows:

viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(114.35231209, 30.53542614, 5000.0),
    orientation: {
        heading: Cesium.Math.toRadians(0.0),
        pitch: Cesium.Math.toRadians(-90.0),
        roll: Cesium.Math.toRadians(0.0)
    }
});

This code set means that the camera view, the camera position to the latitude and longitude (114.35231209, 30.53542614), 5000 meters from the ground point; heading (heading) is set to 0 degrees, the pitch angle (Pitch) to -90 of the roll angle (roll) is set to 0 degrees. Display the actual page was gradually to a point:

Flight to near Wuhan University
Near the flight to Wuhan University: 2

此时数字地球会显示在武汉大学附近,视线看上去会垂直与地面,并且东西南北方向也基本上与常规地图一致。实际上当不设置姿态参数orientation只设置位置参数destination也能达到同样的效果,说明(0.0,-90.0,0.0)的三个姿态角是设置相机视图的默认值。在Cesium的设定中,heading、pitch、roll的定义如下:

The function definition Cesium.HeadingPitchRoll

这说明航向角(heading)是绕Z后负方向旋转的角度,俯仰角(pitch)是绕Y轴负方向旋转的角度,滚转角(roll)是绕X轴正方向旋转的角度。那么问题来了,这个定义里面的X、Y、Z轴的指的是什么呢?我这里认为这个函数蕴含了一种视图变换,使得基于相机的视空间坐标系成为一种类似于一种北东地站心坐标系(NED)坐标系,XYZ轴指的正是这个视空间坐标系的XYZ轴。在这个视空间坐标系中,Z轴垂直球面向下(Down),Y轴沿纬线指东(East),X轴沿经线向北(North),而位于视空间坐标系原点的相机的姿态为由南看向北。在这种情况下,只需要使相机绕Y轴正向旋转90度,也就是俯仰角(pitch)设为90,就可以得到视线垂直于地图,东西南北向正常的视图。

2.2.2. 飞行至某区域

flyTo()函数另外一个很有用的功能就是根据设定的范围显示视图,这在显示特定空间的视图时特别有用,例如加载的三维模型的范围,一个地区的范围等等。实现也很很简单,只需要给位置参数destination传入一个Cesium.Rectangle对象即可:

viewer.camera.flyTo({
    destination: Cesium.Rectangle.fromDegrees(113.683333, 29.966667, 115.083333, 31.366667)
});

将武汉市的经纬度范围传入,实际的显示结果如下:

Flight to Wuhan
图3:飞行至武汉市

2.2.3. 两地之间飞行

flyTo()函数还可以传入一个配置项complete,可以给其设定一个飞行结束后再运行的函数,通过这个配置项可以实现两地或多地飞行:

var whdxOptions = {
    destination: Cesium.Cartesian3.fromDegrees(114.35231209, 30.53542614, 5000.0),
    duration: 5,
    orientation: {
        heading: Cesium.Math.toRadians(0.0),
        pitch: Cesium.Math.toRadians(-90.0),
        roll: Cesium.Math.toRadians(0.0)
    }
};
var hzkjdxOptions = {
    destination: Cesium.Cartesian3.fromDegrees(114.40782845, 30.51011682, 5000.0),
    orientation: {
        heading: Cesium.Math.toRadians(0.0),
        pitch: Cesium.Math.toRadians(-90.0),
        roll: Cesium.Math.toRadians(0.0)
    },
    duration: 5,
    //flyOverLongitude: Cesium.Math.toRadians(60.0)
};

whdxOptions.complete = function () {
    setTimeout(function () {
        viewer.camera.flyTo(hzkjdxOptions);
    }, 1000);
};

// if (adjustPitch) {
//     tokyoOptions.pitchAdjustHeight = 1000;
//     laOptions.pitchAdjustHeight = 1000;
// }

viewer.camera.flyTo(whdxOptions);

这段代码分别定义了两个飞行配置项whdxOptions和hzkjdxOptions,并且给whdxOptions的complete项配置了一个函数,表示完成1S之后,自动进行hzkjdxOptions的飞行。运行结果如下图所示:

Wutai Fei line to the China Branch
图4:武大飞行至华科

2.2.4. 设置视图到某一点

设置当前视图通过setView()函数实现的,它跟flyTo()最大的不同是没有持续时间,没有飞行过程,是立即生效的。其具体的配置选项也比较相似,都是需要设置位置以及姿态:

viewer.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(114.40782845, 30.51011682, 5000.0),
    orientation: {
        heading: Cesium.Math.toRadians(0.0),
        pitch: Cesium.Math.toRadians(-90.0),
        roll: Cesium.Math.toRadians(0.0)
    }
});

2.2.5. 设置视图到某区域

设置具体的显示范围,也是立即生效,这两个部分因为与flyTo()函数比较类似,就不再具体讲解了。

viewer.camera.setView({
    destination: Cesium.Rectangle.fromDegrees(120.86667, 30.66667, 122.2, 31.883333)
});

3. 其他

3.1. 事件及相应函数

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

3.2. setReferenceFrame

自带案例Camera中还提供了另外一种视图控制方式:

function setReferenceFrame() {
    Sandcastle.declare(setReferenceFrame);

    var center = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883);
    var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center);

    // View in east-north-up frame
    var camera = viewer.camera;
    camera.constrainedAxis = Cesium.Cartesian3.UNIT_Z;
    camera.lookAtTransform(transform, new Cesium.Cartesian3(-120000.0, -120000.0, 120000.0));    

    // Show reference frame.  Not required.
    referenceFramePrimitive = scene.primitives.add(new Cesium.DebugModelMatrixPrimitive({
        modelMatrix: transform,
        length: 100000.0
    }));
}

这段代码的意思是选定一个经纬度的点,可以计算出以该点为中心的东北天(ENU)站心坐标系与地心坐标系的转换矩阵,将这个矩阵传入给Cesium.Camera的lookAtTransform函数,从而达到设置视图的目的。但是这样做会导致当前世界坐标系发生变化,当前漫游器的键鼠交互操作不再以地心坐标系原点为中心,而以站心坐标系的原点为中心,导致这个时候的键鼠交互操作难以操作。

3.3. viewInICRF

Cesium默认是基于ITRF,也就是国际地球地心参考框架。自带案例还提供了一种将其转换为ICRF参考框架的视图设置方式。关于ICRF我也不是很了解,查阅网上资料只知道是一种原点在太阳系的质心的天文参考框架,留待以后需要用到的时候再研究。

4. 参考

[1]. North to east / day Northeast The two navigation coordinate system and attitude converter
[2]. Cesium a camera -HeadingPitchRoll
[. 3]. Cesium class HeadingPitchRoll and heading, pitch, roll, etc. Parameter Description

Guess you like

Origin www.cnblogs.com/charlee44/p/12108726.html