Skip to main content

坐标转换

很多使用Cesium开发的朋友都会遇到坐标转换的问题,比如: 将某种坐标转成另一种坐标怎么转,或怎样转的准。有部分坐标转换Cesium官方提供了一些工具,但是有些坐标转换工具还是没有提供,或者是源码里面有但没有文档。THEngine CoordTransform提供了坐标转换工具,方便大家使用。

一、坐标系

效果图


二、坐标系种类介绍

1. 地理坐标系(Geographic Coordinates, WGS84, EPSG:4326)

  • 描述:这是最常用的地理坐标系统,表示地理位置的经度(Longitude)、纬度(Latitude)和高度(Altitude)。Cesium 默认使用 WGS84 椭球体。
  • 用途
    • 输入和输出地理数据。
    • 定义地球表面的位置。
  • API
    • Cesium.Cartographic 表示地理坐标。
    • 示例:new Cesium.Cartographic(longitude, latitude, height)

2. 笛卡尔空间坐标系(Cartesian3, ECEF)

  • 描述:这是一种三维直角坐标系(Earth-Centered, Earth-Fixed, ECEF),以地球中心为原点,X、Y、Z 轴分别指向特定方向。它是 Cesium 内部计算的核心坐标系。
  • 用途
    • 内部位置计算。
    • 物理模拟(如卫星轨道、飞行轨迹等)。
  • API
    • Cesium.Cartesian3 表示笛卡尔坐标。
    • 转换工具:Cesium.Ellipsoid.WGS84.cartographicToCartesian()Cesium.Ellipsoid.WGS84.cartesianToCartographic()

3. 裁剪坐标系(Clip Space / NDC, Normalized Device Coordinates)

  • 描述:裁剪坐标是经过顶点着色器变换后的结果,范围通常是 [-1, 1](X、Y、Z 轴)。NDC 是标准化设备坐标,表示裁剪后的顶点位置。
  • 用途
    • GPU 在裁剪阶段会丢弃不在范围内的顶点。
    • 后续的视口变换将 NDC 映射到屏幕像素。
  • 特点
    • X、Y、Z 都被规范化到 [-1, 1]
    • Z 轴通常用于深度测试(Depth Test)。
  • 相关知识
    • 在 WebGL 中,顶点着色器输出的 gl_Position 就是在裁剪空间中的坐标。

4. 屏幕坐标系(Screen Space / Viewport Coordinates)

  • 描述:屏幕坐标是以像素为单位的二维坐标系,原点 (0, 0) 通常位于左上角或左下角(取决于具体的实现)。
  • 用途
    • 处理用户输入(如鼠标点击事件)。
    • 将 3D 场景中的点投影到屏幕上。
  • API
    • Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, position):将 WGS84 坐标转换为屏幕坐标。
    • Cesium.SceneTransforms.wgs84ToDrawingBufferCoordinates(scene, position):将 WGS84 坐标转换为绘图缓冲区坐标。

5. 视口坐标系(Viewport Coordinates)

  • 描述:视口坐标与屏幕坐标类似,但通常是指 WebGL 渲染上下文中的实际绘制区域。它的范围由 gl.viewport(x, y, width, height) 定义。
  • 用途
    • 控制渲染区域大小。
    • 实现多视口渲染(如分屏显示)。
  • 特点
    • 视口坐标与屏幕坐标可能不完全一致,尤其是在高分辨率显示器(如 Retina 屏幕)上,需要考虑设备像素比(Device Pixel Ratio)。

6. 局部坐标系(Local Coordinates)

  • 描述:局部坐标系是以某个物体为中心的相对坐标系,通常用于定义模型的顶点位置。
  • 用途
    • 模型加载和渲染。
    • 相对于某个物体的偏移计算。
  • 特点
    • 每个物体都有自己的局部坐标系。
    • 通过模型矩阵(Model Matrix)可以将局部坐标转换为世界坐标。

7. 世界坐标系(World Coordinates)

  • 描述:世界坐标系是场景中所有对象的全局参考框架,通常以地球中心为原点(ECEF)。
  • 用途
    • 统一管理场景中的所有对象。
    • 计算对象之间的相对位置。
  • 特点
    • 世界坐标系与笛卡尔坐标系(ECEF)一致。
    • 通过视图矩阵(View Matrix)可以将世界坐标转换为相机坐标。

8. 相机坐标系(Camera Coordinates)

  • 描述:相机坐标系是以相机为中心的坐标系,相机的位置为原点,相机的朝向决定了坐标轴的方向。
  • 用途
    • 模拟相机视角。
    • 进行视图变换。
  • 特点
    • 通过视图矩阵(View Matrix)从世界坐标系转换而来。
    • 相机坐标系通常用于光照计算和投影变换。

9. 投影坐标系(Projection Coordinates)

  • 描述:投影坐标系是将 3D 场景中的点投影到 2D 平面上的结果。Cesium 支持透视投影(Perspective Projection)和正交投影(Orthographic Projection)。
  • 用途
    • 渲染 3D 场景。
    • 模拟真实世界的视觉效果(透视投影)或保持比例(正交投影)。
  • 特点
    • 投影矩阵(Projection Matrix)用于从相机坐标转换到裁剪坐标。

三、THEngine CoordTransform坐标转换方法

1. toRadians方法

功能描述

将角度值从度转换为弧度。

参数

  • degrees:类型为 number,表示要转换的度数。

返回值

类型为 number,返回转换后的弧度数。

示例代码

const coordTransform = new CoordTransform();
const radians = coordTransform.toRadians(180);
console.log(radians); // 输出:3.141592653589793

2. toDegrees方法

功能描述

将角度值从弧度转换为度。

参数

  • radians:类型为 number,表示要转换的弧度数。

返回值

类型为 number,返回转换后的度数。

示例代码

const coordTransform = new CoordTransform();
const degrees = coordTransform.toDegrees(Math.PI);
console.log(degrees); // 输出:180

3. toDegreesCoor方法

功能描述

将包含弧度坐标的数组转换为包含经纬度坐标的数组。

参数

  • coor:类型为 Array<number>,是一个包含弧度坐标的数组,格式为 [x, y,z]

返回值

类型为 Array<number>,返回包含经纬度坐标的数组,格式为 [经度, 纬度,高度]

示例代码

const coordTransform = new CoordTransform();
const radianCoor = [0.523599, 0.349066,100]; // 示例弧度坐标
const degreeCoor = coordTransform.toDegreesCoor(radianCoor);
console.log(degreeCoor); // 输出:[30, 20,100](假设示例弧度对应此经纬度)

4. toRadiansCoor方法

功能描述

将包含经纬度坐标的数组转换为 Cesium.Cartographic 类型的弧度坐标对象。

参数

  • coor:类型为 Array<number>,是一个包含经纬度坐标的数组,格式为 [经度, 纬度, 高度(可选)]

返回值

类型为 Cesium.Cartographic,返回转换后的弧度坐标对象。

示例代码

const coordTransform = new CoordTransform();
const degreeCoor = [116.4074, 39.9042, 0]; // 示例经纬度坐标
const radianCoorObj = coordTransform.toRadiansCoor(degreeCoor);
console.log(radianCoorObj);
// 输出:Cesium.Cartographic 对象,包含转换后的弧度值和高度

5. Cartesian3_to_WGS84方法

功能描述

Cesium.Cartesian3 类型的笛卡尔坐标对象转换为经纬度坐标数组。

参数

  • position:类型为 Cesium.Cartesian3,表示笛卡尔坐标对象。

返回值

类型为 Array<number>,返回经纬度坐标数组,格式为 [经度, 纬度, 高度]

示例代码

const coordTransform = new CoordTransform();
const cartesian3 = new Cesium.Cartesian3(1.0, 2.0, 3.0); // 示例笛卡尔坐标
const wgs84Coor = coordTransform.Cartesian3_to_WGS84(cartesian3);
console.log(wgs84Coor);
// 输出:经纬度坐标数组(具体值取决于转换结果)

6. WGS84_to_Cartesian3方法

功能描述

将包含经纬度坐标的数组转换为 Cesium.Cartesian3 类型的笛卡尔坐标对象。

参数

  • position:类型为 Array<number>,是一个包含经纬度坐标的数组,格式为 [经度, 纬度, 高度]

返回值

类型为 Cesium.Cartesian3,返回笛卡尔坐标对象。

示例代码

const coordTransform = new CoordTransform();
const wgs84Coor = [116.4074, 39.9042, 0]; // 示例经纬度坐标
const cartesian3 = coordTransform.WGS84_to_Cartesian3(wgs84Coor);
console.log(cartesian3);
// 输出:Cesium.Cartesian3 对象,包含转换后的笛卡尔坐标值

7. Cartesian3_to_Cartographic方法

功能描述

Cesium.Cartesian3 类型的笛卡尔坐标对象转换为 Cesium.Cartographic 类型的弧度经纬度坐标对象。

参数

  • position:类型为 Cesium.Cartesian3,表示笛卡尔坐标对象。

返回值

类型为 Cesium.Cartographic,返回弧度经纬度坐标对象。

示例代码

const coordTransform = new CoordTransform();
const cartesian3 = new Cesium.Cartesian3(1.0, 2.0, 3.0); // 示例笛卡尔坐标
const cartographic = coordTransform.Cartesian3_to_Cartographic(cartesian3);
console.log(cartographic);
// 输出:Cesium.Cartographic 对象,包含转换后的弧度经纬度和高度

8. Cartographic_to_Cartesian3方法

功能描述

Cesium.Cartographic 类型的弧度经纬度坐标对象转换为 Cesium.Cartesian3 类型的笛卡尔坐标对象。

参数

  • position:类型为 Cesium.Cartographic,表示弧度经纬度坐标对象。

返回值

类型为 Cesium.Cartesian3,返回笛卡尔坐标对象。

示例代码

const coordTransform = new CoordTransform();
const cartographic = new Cesium.Cartographic(0.523599, 0.349066, 0); // 示例弧度经纬度坐标
const cartesian3 = coordTransform.Cartographic_to_Cartesian3(cartographic);
console.log(cartesian3);
// 输出:Cesium.Cartesian3 对象,包含转换后的笛卡尔坐标值

9. Cartesian3_to_Screen方法

功能描述

将世界坐标(Cesium.Cartesian3 类型)转换为当前视图的屏幕坐标点(Cesium.Cartesian2 类型)。

参数

  • cartesian3:类型为 Cesium.Cartesian3,表示世界坐标。
  • viewer:类型为 Cesium.Viewer,表示视图对象。

返回值

类型为 Cesium.Cartesian2,返回屏幕坐标点。

示例代码

const coordTransform = new CoordTransform();
const cartesian3 = new Cesium.Cartesian3(1.0, 2.0, 3.0); // 示例世界坐标
const viewer = new Cesium.Viewer('cesiumContainer'); // 假设存在视图对象
const screenPoint = coordTransform.Cartesian3_to_Screen(cartesian3, viewer);
console.log(screenPoint);
// 输出:Cesium.Cartesian2 对象,包含屏幕坐标值

10. Screen_to_Cartesian方法

功能描述

将屏幕坐标(Cesium.Cartesian2 类型)转换为笛卡尔坐标(Cesium.Cartesian3 类型),如果未找到对应的笛卡尔坐标则返回 null

参数

  • windowPosition:类型为 Cesium.Cartesian2,表示屏幕坐标。
  • viewer:类型为 Cesium.Viewer,表示视图对象。

返回值

类型为 Cesium.Cartesian3|null,返回笛卡尔坐标对象,如果未找到则返回 null

示例代码

const coordTransform = new CoordTransform();
const windowPosition = new Cesium.Cartesian2(100, 100); // 示例屏幕坐标
const viewer = new Cesium.Viewer('cesiumContainer'); // 假设存在视图对象
const cartesian3 = coordTransform.Screen_to_Cartesian(windowPosition, viewer);
console.log(cartesian3);
// 输出:Cesium.Cartesian3 对象或 null(取决于转换结果)

11. Cartesian3_to_EPSG3857方法

功能描述

将笛卡尔世界坐标(Cesium.Cartesian3 类型)转换为墨卡托坐标(Cesium.Cartographic 类型)。

参数

  • position:类型为 Cesium.Cartesian3,表示笛卡尔世界坐标。
  • viewer:类型为 Cesium.Viewer,表示视图对象。

返回值

类型为 Cesium.Cartographic,返回墨卡托坐标对象。

示例代码

const coordTransform = new CoordTransform();
const cartesian3 = new Cesium.Cartesian3(1.0, 2.0, 3.0); // 示例笛卡尔世界坐标
const viewer = new Cesium.Viewer('cesiumContainer'); // 假设存在视图对象
const cartographic = coordTransform.Cartesian3_to_EPSG3857(cartesian3, viewer);
console.log(cartographic);
// 输出:Cesium.Cartographic 对象,包含转换后的墨卡托坐标值

12. EPSG3857_to_Cartesian3方法

功能描述

将墨卡托坐标数组(格式为 [经度, 纬度, 高度(可选)])转换为笛卡尔世界坐标(Cesium.Cartesian3 类型)。

参数

  • coor:类型为 Array<number>,是一个包含墨卡托坐标的数组,格式为 [经度, 纬度, 高度(可选)]
  • viewer:类型为 Cesium.Viewer,表示视图对象。

返回值

类型为 Cesium.Cartesian3,返回笛卡尔世界坐标对象。

示例代码

const coordTransform = new CoordTransform();
const coor = [116.4074, 39.9042, 0]; // 示例墨卡托坐标
const viewer = new Cesium.Viewer('cesiumContainer'); // 假设存在视图对象
const cartesian3 = coordTransform.EPSG3857_to_Cartesian3(coor, viewer);
console.log(cartesian3);
// 输出:Cesium.Cartesian3 对象,包含转换后的笛卡尔世界坐标值

13. WGS84_to_EPSG3857方法

功能描述

将包含WGS84经纬度坐标的数组(格式为 [经度, 纬度, 高度(可选)])转换为包含EPSG3857坐标的数组(格式为 [x, y, z(可选)])。

参数

  • coor:类型为 Array<number>,是一个包含WGS84经纬度坐标的数组,格式为 [经度, 纬度, 高度(可选)]
  • viewer:类型为 Cesium.Viewer,表示视图对象。

返回值

类型为 Array<number>,返回包含EPSG3857坐标的数组,格式为 [x, y, z(可选)]

示例代码

const coordTransform = new CoordTransform();
const wgs84Coor = [116.4074, 39.9042, 0]; // 示例WGS84经纬度坐标
const viewer = new Cesium.Viewer('cesiumContainer'); // 假设存在视图对象
const epsg3857Coor = coordTransform.WGS84_to_EPSG3857(wgs84Coor, viewer);
console.log(epsg3857Coor);
// 输出:包含EPSG3857坐标的数组(具体值取决于转换结果)

14. EPSG3857_to_WGS84方法

功能描述

将包含EPSG3857坐标的数组(格式为 [x, y, z(可选)])转换为包含WGS84经纬度坐标的数组(格式为 [经度, 纬度, 高度(可选)])。

参数

  • coor:类型为 Array<number>,是一个包含EPSG3857坐标的数组,格式为 [x, y, z(可选)]
  • viewer:类型为 Cesium.Viewer,表示视图对象。

返回值

类型为 Array<number>,返回包含WGS84经纬度坐标的数组,格式为 [经度, 纬度, 高度(可选)]

示例代码

const coordTransform = new CoordTransform();
const epsg3857Coor = [123456.789, 987654.321, 0]; // 示例EPSG3857坐标
const viewer = new Cesium.Viewer('cesiumContainer'); // 假设存在视图对象
const wgs84Coor = coordTransform.EPSG3857_to_WGS84(epsg3857Coor, viewer);
console.log(wgs84Coor);
// 输出:包含WGS84经纬度坐标的数组(具体值取决于转换结果)

15. localTransforms方法

功能描述

根据输入的笛卡尔坐标对象或44矩阵,获取东-北-上局部坐标系的44矩阵。

参数

  • position:类型为 Cesium.Cartesian3|Cesium.Matrix4,可以是笛卡尔坐标对象或4*4矩阵。

返回值

类型为 Cesium.Matrix4,返回东-北-上局部坐标系的4*4矩阵。

示例代码

const coordTransform = new CoordTransform();
const cartesian3 = new Cesium.Cartesian3(1.0, 2.0, 3.0); // 示例笛卡尔坐标
const matrix = coordTransform.localTransforms(cartesian3);
console.log(matrix);
// 输出:Cesium.Matrix4 对象,包含东-北-上局部坐标系的4*4矩阵值

16. inverse_localTransforms方法

功能描述

获取东-北-上局部坐标系4*4矩阵的逆矩阵。

参数

  • position:类型为 Cesium.Cartesian3|Cesium.Matrix4,可以是笛卡尔坐标对象或44矩阵,用于获取对应的东-北-上局部坐标系44矩阵。

返回值

类型为 Cesium.Matrix4,返回东-北-上局部坐标系4*4逆矩阵。

示例代码

const coordTransform = new CoordTransform();
const cartesian3 = new Cesium.Cartesian3(1.0, 2.0, 3.0); // 示例笛卡尔坐标
const inverseMatrix = coordTransform.inverse_localTransforms(cartesian3);
console.log(inverseMatrix);
// 输出:Cesium.Matrix4 对象,包含东-北-上局部坐标系4*4逆矩阵值

17. Cartesian3_to_LocalCartesian3方法

功能描述

将世界坐标(Cesium.Cartesian3 类型)转换为局部坐标(Cesium.Cartesian3 类型)。

参数

  • transform:类型为 Cesium.Matrix4,表示东-北-上局部坐标系4*4矩阵。
  • position:类型为 Cesium.Cartesian3,表示世界坐标。

返回值

类型为 Cesium.Cartesian3,返回局部坐标。

示例代码

const coordTransform = new CoordTransform();
const transform = new Cesium.Matrix4(); // 假设存在东-北-上局部坐标系4*4矩阵
const cartesian3 = new Cesium.Cartesian3(1.0, 2.0, 3.0); // 示例世界坐标
const localCartesian3 = coordTransform.Cartesian3_to_LocalCartesian3(transform, cartesian3);
console.log(localCartesian3);
// 输出:Cesium.Cartesian3 对象,包含转换后的局部坐标值

以下是补充完整的 CoordTransform 类文档中 “18. LocalCartesian3_to_Cartesian3 方法” 之后的部分:

18. LocalCartesian3_to_Cartesian3方法

功能描述

将局部坐标(Cesium.Cartesian3 类型)转换为世界坐标(Cesium.Cartesian3 类型)。

参数

  • transform:类型为 Cesium.Matrix4,表示东-北-上局部坐标系4*4矩阵。
  • position:类型为 Cesium.Cartesian3,表示局部坐标。

返回值

类型为 Cesium.Cartesian3,返回世界坐标。

示例代码

const coordTransform = new CoordTransform();
const transform = new Cesium.Matrix4(); // 假设存在东-北-上局部坐标系4*4矩阵
const localCartesian3 = new Cesium.Cartesian3(1.0, 2.0, 3.0); // 示例局部坐标
const cartesian3 = coordTransform.LocalCartesian3_to_Cartesian3(transform, localCartesian3);
console.log(cartesian3);
// 输出:Cesium.Cartesian3 对象,包含转换后的世界坐标值

19. BD09_to_GCJ02方法

功能描述

将BD09坐标系下的经纬度坐标转换为GCJ02坐标系下的经纬度坐标。

参数

  • lng:类型为 number,表示BD09坐标系下的经度值。
  • lat:类型为 number,表示BD09坐标系下的纬度值。

返回值

类型为 Array<number>,返回包含GCJ02坐标系下经纬度的数组,格式为 [经度, 纬度]

示例代码

const coordTransform = new CoordTransform();
const bd09Lng = 116.4074; // 示例BD09经度
const bd09Lat = 39.9042; // 示例BD09纬度
const gcj02Coor = coordTransform.BD09_to_GCJ02(bd09Lng, bd09Lat);
console.log(gcj02Coor);
// 输出:包含GCJ02经纬度的数组(具体值取决于转换结果)

20. GCJ02_to_BD09方法

功能描述

将GCJ02坐标系下的经纬度坐标转换为BD09坐标系下的经纬度坐标。

参数

  • lng:类型为 number,表示GCJ02坐标系下的经度值。
  • lat:类型为 number,表示GCJ02坐标系下的纬度值。

返回值

类型为 Array<number>,返回包含BD09坐标系下经纬度的数组,格式为 [经度, 纬度]

示例代码

const coordTransform = new CoordTransform();
const gcj02Lng = 116.4074; // 示例GCJ02经度
const gcj02Lat = 39.9042; // 示例GCJ02纬度
const bd09Coor = coordTransform.GCJ02_to_BD09(gcj02Lng, gcj02Lat);
console.log(bd09Coor);
// 输出:包含BD09经纬度的数组(具体值取决于转换结果)

21. WGS84_to_GCJ02方法

功能描述

将WGS84坐标系下的经纬度坐标转换为GCJ02坐标系下的经纬度坐标。

参数

  • lng:类型为 number,表示WGS84坐标系下的经度值。
  • lat:类型为 number,表示WGS84坐标系下的纬度值。

返回值

类型为 Array<number>,返回包含GCJ02坐标系下经纬度的数组,格式为 [经度, 纬度]

示例代码

const coordTransform = new CoordTransform();
const wgs84Lng = 116.4074; // 示例WGS84经度
const wgs84Lat = 39.9042; // 示例WGS84纬度
const gcj02Coor = coordTransform.WGS84_to_GCJ02(wgs84Lng, wgs84Lat);
console.log(gcj02Coor);
// 输出:包含GCJ02经纬度的数组(具体值取决于转换结果)

22. GCJ02_to_WGS84方法

功能描述

将GCJ02坐标系下的经纬度坐标转换为WGS84坐标系下的经纬度坐标。

参数

  • lng:类型为 number,表示GCJ02坐标系下的经度值。
  • lat:类型为 number,表示GCJ02坐标系下的纬度值。

返回值

类型为 Array<number>,返回包含WGS84坐标系下经纬度的数组,格式为 [经度, 纬度]

示例代码

const coordTransform = new CoordTransform();
const gcj02Lng = 116.4074; // 示例GCJ02经度
const gcj02Lat = 39.9042; // 示例GCJ02纬度
const wgs84Coor = coordTransform.GCJ02_to_WGS84(gcj02Lng, gcj02Lat);
console.log(wgs84Coor);
// 输出:包含WGS84经纬度的数组(具体值取决于转换结果)