坐标系
Cesium 中涉及多种坐标系,理解这些坐标系之间的关系和转换方法,是进行 Cesium 开发的关键基础
统一坐标系
Cesium 中所有坐标最终都基于WGS84 椭球体(World Geodetic System 1984),这是一种国际标准的地球参考模型,定义了地球的形状和大小。所有坐标系转换都以 WGS84
为基准进行计算。
常见坐标系
先了解一下,以北京天安门
坐标为例,介绍几种常见的坐标系及其转换方法。
坐标系 | 值示例 | 说明 |
---|---|---|
WGS84 经纬度 | { longitude: 116.3975°, latitude: 39.9075°, height: 50 } | 人类可读的地理坐标 |
弧度坐标 (Cartographic) | { longitude: 2.0313, latitude: 0.6964, height: 50 } | 经纬度的弧度表示 |
笛卡尔坐标 (Cartesian3) | Cartesian3(-2173633.5, 4387689.5, 4077985.0) | 地心直角坐标(单位:米) |
屏幕坐标 (Cartesian2) | { x: 640, y: 360 } (随窗口尺寸变化) | 相对于 Canvas 的像素位置 |
Web 墨卡托投影 | { x: 12958809.1, y: 4825922.9 } | 平面投影坐标(EPSG:3857) |
1. 地理坐标系(Cartographic)
定义:以经度、纬度和高度表示的坐标系。
参数说明:
- 经度(longitude):东西方向的角度,范围[-180°, 180°]
- 纬度(latitude):南北方向的角度,范围[-90°, 90°]
- 高度(height):相对于椭球面的高度,单位米
例:创建地理坐标,由经度、纬度和高度定义的位置,以弧度为单位
注意:我们正常所说的经纬度是角度,Cesium 中角度与弧度之间提供了转化方式
js
const cartographic = new Cesium.Cartographic(
Cesium.Math.toRadians(116.404), // 经度(弧度)
Cesium.Math.toRadians(39.915), // 纬度(弧度)
1000 // 高度(米)
);
// 经纬度与弧度转换(弧度转角度)
const lon = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
2 笛卡尔空间坐标系(Cartesian3)
定义:三维直角坐标系,原点位于地球中心。
坐标轴方向:
- X 轴:指向本初子午线与赤道的交点(0° 经度,0° 纬度)
- Y 轴:指向 90°E 经度与赤道的交点
- Z 轴:指向北极
代码示例:
javascript
// 直接创建笛卡尔坐标
const position = new Cesium.Cartesian3(x, y, z);
3 平面坐标系(Cartesian2)
定义:二维平面坐标系,用于表示屏幕或图像上的二维位置。
参数说明:
- x:水平方向坐标
- y:垂直方向坐标
代码示例:
javascript
// 创建屏幕坐标
const screenPosition = new Cesium.Cartesian2(100, 200);
转换方法(核心)
WGS84 ↔ Cartesian3
js
// 经纬度转笛卡尔坐标
const cartesian = Cesium.Cartesian3.fromDegrees(
116.3975, // 经度(度)
39.9075, // 纬度(度)
50 // 高度(米)
);
// 笛卡尔坐标转经纬度分两步
// 第一步:笛卡尔坐标转弧度坐标
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
// 第二步:弧度转度数
const longitude = Cesium.Math.toDegrees(cartographic.longitude); // 116.3975°
const latitude = Cesium.Math.toDegrees(cartographic.latitude); // 39.9075°
const height = cartographic.height; // 50米
console.log(longitude, latitude, height, "longitude, latitude, height");
经纬度 ↔ 弧度
- 弧度是一种用于测量角度的单位,它的定义是:1 弧度等于 180 度除以 π。
- Cesium 中提供了 Math 类,用于进行弧度和角度之间的转换。
js
// 经度转弧度
const lonRad = Cesium.Math.toRadians(116.3975); // ~2.0313 弧度
// 纬度转弧度
const latRad = Cesium.Math.toRadians(39.9075); // ~0.6964 弧度
// 弧度转度数
const lonDeg = Cesium.Math.toDegrees(lonRad); // 116.3975°
const latDeg = Cesium.Math.toDegrees(latRad); // 39.9075°
console.log(lonDeg, latDeg, "lonDeg, latDeg");
Cartesian3 ↔ 屏幕坐标
注意:API 已由
wgs84ToWindowCoordinates
更新为worldToWindowCoordinates
。
js
const cartesian = Cesium.Cartesian3.fromDegrees(
116.3975, // 经度(度)
39.9075, // 纬度(度)
50 // 高度(米)
);
// 笛卡尔坐标转屏幕坐标
const screenPos = Cesium.SceneTransforms.worldToWindowCoordinates(
viewer.scene,
cartesian
);
console.log(`屏幕坐标: (${screenPos.x}, ${screenPos.y})`);
// 屏幕坐标转笛卡尔坐标(地形表面)
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction((movement) => {
console.log(movement.position); // 屏幕坐标
console.log(viewer.scene.pickPosition(movement.position)); // Cartesian3
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
WGS84 ↔ Web 墨卡托投影
工作中可能会遇到 Web 墨卡托投影坐标,Cesium 也提供了转化方式
js
const projection = new Cesium.WebMercatorProjection();
// WGS84 转 Web 墨卡托
const cartographic = Cesium.Cartographic.fromDegrees(116.3975, 39.9075);
// WGS84 转 Web 墨卡托
const projected = projection.project(cartographic);
console.log(`投影坐标: (${projected.x}, ${projected.y})`);
// Web 墨卡托转 WGS84
const unprojected = projection.unproject(
new Cesium.Cartesian3(projected.x, projected.y)
);
console.log(`WGS84坐标: ${Cesium.Math.toDegrees(unprojected.longitude)}°,
${Cesium.Math.toDegrees(unprojected.latitude)}°`);
计算两点间距离
js
// 天安门坐标(带高度)
const cartesian = Cesium.Cartesian3.fromDegrees(
116.3975, // 经度(度)
39.9075, // 纬度(度)
50 // 高度(米)
);
// 故宫坐标(东经116.3972°, 北纬39.9163°)
const palaceCartesian = Cesium.Cartesian3.fromDegrees(116.3972, 39.9163);
// 计算直线距离(米)
const distance = Cesium.Cartesian3.distance(cartesian, palaceCartesian);
console.log(`直线距离: ${distance.toFixed(2)} 米`);
// 计算椭球面距离(沿地球表面)
const geodesic = new Cesium.EllipsoidGeodesic();
const carto1 = Cesium.Cartographic.fromCartesian(cartesian);
const carto2 = Cesium.Cartographic.fromCartesian(palaceCartesian);
geodesic.setEndPoints(carto1, carto2);
console.log(`地表距离: ${geodesic.surfaceDistance.toFixed(2)} 米`);
设置面坐标
返回 Cartesian3 位置数组
js
// 返回一个 Cartesian3 位置数组
const cartesian3 = new Cesium.Cartesian3.fromDegreesArray([
116.404,
39.915, // 第一个点的经度和纬度
116.404,
39.916, // 第二个点的经度和纬度
116.405,
39.916, // 第三个点的经度和纬度
]);
// 返回一个笛卡尔3位置数组,给定经度、纬度和高度值数组
const polygonWithHeights = new Cesium.Cartesian3.fromDegreesArrayHeights([
116.404,
39.915,
1000, // 第一个点的经度,纬度,高度
116.404,
39.916,
2000, // 第二个点的经度,纬度,高度
]);
总结
主要记住两个类:Cartographic 与 Cartesian3