坐标转换
很多使用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)。
- X、Y、Z 都被规范化到
- 相关知识:
- 在 WebGL 中,顶点着色器输出的
gl_Position
就是在裁剪空间中的坐标。
- 在 WebGL 中,顶点着色器输出的
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经纬度的数组(具体值取决于转换结果)