cesium 二维下获取相机位置

在 Cesium 应用开发中,获取相机位置是一个非常常见的需求,无论是用于保存当前视图状态、实现自定义导航控制,还是进行位置计算。然而,在 Cesium 的不同显示模式(2D、3D、Columbus View)下,获取相机位置的方法存在一些差异。本文将重点介绍在 2D 模式下如何正确获取相机位置,以及相关坐标系的转换。

Cesium 中的坐标系统

在深入讨论之前,我们需要先了解 Cesium 中的两种主要坐标系统:

  1. 笛卡尔坐标系(Cartesian3):以地球中心为原点的三维直角坐标系,单位为米。
  2. 地理坐标系(Cartographic):使用经度、纬度和高度表示的坐标系,经纬度以弧度为单位。

在不同的场景中,可能需要在这两种坐标系之间进行转换。

2D 模式与 3D 模式的区别

Cesium 支持三种显示模式:

  • 3D 模式:完整的三维球体表示
  • 2D 模式:平面地图表示
  • Columbus View:2.5D 视图,介于 2D 和 3D 之间

在 3D 模式下,viewer.camera.position直接返回相机在地心坐标系中的位置(Cartesian3 对象)。但在 2D 模式下,由于场景被投影到平面上,相机位置的处理方式不同,需要特别注意。

获取不同模式下的相机位置

下面是一段在不同模式下获取相机位置的代码:

1
2
3
4
5
6
7
8
9
var newPostion;
if (this._viewer.scene.mode === this._cesium.SceneMode.SCENE2D) {
var cameraHeight = this._viewer.scene.camera.positionCartographic.height;
var longitude = this._viewer.scene.camera.positionCartographic.longitude;
var latitude = this._viewer.scene.camera.positionCartographic.latitude;
newPostion = this._cesium.Cartesian3.fromRadians(longitude, latitude, cameraHeight);
} else {
newPostion = this._viewer.camera.position.clone();
}

这段代码的核心逻辑是:

  1. 首先检查当前场景是否处于 2D 模式
  2. 如果是 2D 模式:
    • 获取相机的地理坐标(经度、纬度、高度)
    • 使用Cartesian3.fromRadians将地理坐标转换回笛卡尔坐标
  3. 如果不是 2D 模式(即 3D 或 Columbus View):
    • 直接克隆相机当前位置作为结果

代码详解

让我们深入分析一下代码的每一部分:

模式判断

1
if (this._viewer.scene.mode === this._cesium.SceneMode.SCENE2D) {

这一行通过比较当前场景模式与 Cesium 预定义的SceneMode.SCENE2D常量来判断是否处于 2D 模式。Cesium 提供了三种场景模式常量:

  • SceneMode.SCENE2D:2D 平面模式
  • SceneMode.SCENE3D:3D 球体模式
  • SceneMode.COLUMBUS_VIEW:Columbus View (2.5D)模式

2D 模式下的位置获取

1
2
3
var cameraHeight = this._viewer.scene.camera.positionCartographic.height;
var longitude = this._viewer.scene.camera.positionCartographic.longitude;
var latitude = this._viewer.scene.camera.positionCartographic.latitude;

在 2D 模式下,我们通过camera.positionCartographic获取相机的地理坐标信息,它包含:

  • longitude:经度(弧度)
  • latitude:纬度(弧度)
  • height:高度(米)

需要注意的是,positionCartographic返回的经纬度是弧度制,而不是常见的度数制。

坐标转换

1
newPostion = this._cesium.Cartesian3.fromRadians(longitude, latitude, cameraHeight);

这一行使用Cartesian3.fromRadians方法将经纬度(弧度制)和高度转换为笛卡尔坐标(Cartesian3 对象)。这样我们就获得了与 3D 模式下格式一致的相机位置。

3D 模式下的位置获取

1
newPostion = this._viewer.camera.position.clone();

在 3D 模式下,我们可以直接使用camera.position获取相机位置,它返回一个 Cartesian3 对象。这里使用clone()方法创建一个副本,避免后续操作直接修改相机的实际位置。

作者

wangyawei

发布于

2025-03-16

更新于

2025-03-21

许可协议