你想了解在 Cesium 中不同坐标系之间的转换方法,以及这些转换在实际开发场景中的应用,这是 Cesium 开发中非常核心且基础的知识点。
一、Cesium 中常见的坐标系类型
在开始转换前,先明确 Cesium 中最常用的几种坐标系:
- WGS84 经纬度坐标 :
[经度, 纬度, 高度](单位:度、米),比如[116.403874, 39.914885, 50],是最通用的地理坐标。 - WGS84 弧度坐标 :经纬度转成弧度后的坐标,Cesium 内部计算常用,比如
Cesium.Math.toRadians(经度)。 - Cartesian3 坐标 :笛卡尔直角坐标(单位:米),Cesium 场景中实体、相机等的核心坐标,格式为
(x, y, z)。 - Cartographic 坐标 :Cesium 封装的地理坐标对象,包含
longitude(弧度经度)、latitude(弧度纬度)、height(高度)。 - 屏幕坐标 :
[x, y](单位:像素),对应 Canvas 画布上的二维坐标。
二、核心坐标转换方法(附场景)
下面结合实际开发场景,给出常用的转换代码和说明:
1. WGS84 经纬度 → Cartesian3(最常用)
应用场景:添加实体(如点、模型、广告牌)、设置相机位置、绘制图形时,需要将地理坐标转成 Cesium 内部的笛卡尔坐标。
javascript
// 初始化Cesium场景(基础代码)
const viewer = new Cesium.Viewer('cesiumContainer');
// 1. 方法1:直接转换(推荐)
const lon = 116.403874; // 经度
const lat = 39.914885; // 纬度
const height = 50; // 高度(米)
const cartesian3 = Cesium.Cartesian3.fromDegrees(lon, lat, height);
// 2. 方法2:分步转换(先转弧度,再转Cartographic,最后转Cartesian3)
const radiansLon = Cesium.Math.toRadians(lon);
const radiansLat = Cesium.Math.toRadians(lat);
const cartographic = new Cesium.Cartographic(radiansLon, radiansLat, height);
const cartesian3_2 = Cesium.Ellipsoid.WGS84.cartographicToCartesian(cartographic);
// 场景示例:添加一个点实体
viewer.entities.add({
position: cartesian3,
point: {
pixelSize: 10,
color: Cesium.Color.RED
}
});
2. Cartesian3 → WGS84 经纬度
应用场景:点击场景中的物体,获取其地理坐标;相机移动后,获取当前相机位置的经纬度。
javascript
// 假设已有一个Cartesian3坐标(比如相机位置)
const cameraPosition = viewer.camera.position;
// 转换为Cartographic(弧度)
const cartographic = Cesium.Cartographic.fromCartesian(cameraPosition);
// 转成经纬度(度)
const lon = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
const height = cartographic.height;
console.log(`经度:${lon.toFixed(6)}, 纬度:${lat.toFixed(6)}, 高度:${height.toFixed(2)}米`);
// 场景示例:点击场景获取经纬度
viewer.screenSpaceEventHandler.setInputAction(function(event) {
const ray = viewer.camera.getPickRay(event.position);
const cartesian3 = viewer.scene.globe.pick(ray, viewer.scene);
if (cartesian3) {
const cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
const lon = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
alert(`点击位置:经度${lon.toFixed(6)},纬度${lat.toFixed(6)}`);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
3. 屏幕坐标 ↔ Cartesian3
应用场景:鼠标悬浮时显示物体的位置提示;根据屏幕像素位置,定位到场景中的三维位置。
javascript
// 1. 屏幕坐标 → Cartesian3(场景地面坐标)
const screenPosition = new Cesium.Cartesian2(500, 300); // 屏幕像素坐标[x,y]
const cartesian3 = viewer.scene.globe.pick(
viewer.camera.getPickRay(screenPosition),
viewer.scene
);
// 2. Cartesian3 → 屏幕坐标
if (cartesian3) {
const screenCoord = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
viewer.scene,
cartesian3
);
console.log(`三维坐标对应的屏幕位置:x=${screenCoord.x}, y=${screenCoord.y}`);
}
// 场景示例:鼠标移动时显示当前位置经纬度
viewer.screenSpaceEventHandler.setInputAction(function(event) {
const cartesian3 = viewer.scene.globe.pick(
viewer.camera.getPickRay(event.endPosition),
viewer.scene
);
if (cartesian3) {
const cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
const lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(6);
const lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(6);
document.getElementById('positionTip').innerText = `当前位置:${lon}, ${lat}`;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
4. 平面坐标(如墨卡托)↔ WGS84
应用场景:对接其他GIS系统(如高德、百度地图)的墨卡托坐标,需要转换为Cesium支持的WGS84。
javascript
// 需引入第三方库(如proj4),Cesium本身不直接支持墨卡托转换,示例:
// 1. 墨卡托(米)→ WGS84经纬度
const proj4 = require('proj4');
// 定义墨卡托投影和WGS84投影
proj4.defs('EPSG:3857', '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs');
proj4.defs('EPSG:4326', '+proj=longlat +datum=WGS84 +no_defs');
// 墨卡托坐标[x,y]
const mercatorCoord = [12948872.34, 4863072.15];
// 转换为WGS84经纬度
const wgs84Coord = proj4('EPSG:3857', 'EPSG:4326', mercatorCoord);
console.log(`经度:${wgs84Coord[0]}, 纬度:${wgs84Coord[1]}`);
// 2. WGS84经纬度 → 墨卡托
const wgs84 = [116.403874, 39.914885];
const mercator = proj4('EPSG:4326', 'EPSG:3857', wgs84);
console.log(`墨卡托X:${mercator[0]}, 墨卡托Y:${mercator[1]}`);
三、注意事项
- 高度基准:Cesium 默认使用 WGS84 椭球高度,如果需要使用大地高/海拔高度,需结合地形数据调整。
- 空值处理 :转换屏幕坐标→Cartesian3 时,如果点击的是天空(无地形),会返回
undefined,需提前判断。 - 性能优化:频繁转换(如鼠标移动时),可缓存转换结果,避免重复计算。
总结
- 核心转换关系:WGS84经纬度 ↔ Cartesian3 是 Cesium 中最基础、最常用的转换,前者用于业务数据存储/展示,后者用于 Cesium 内部渲染和交互。
- 场景对应 :
- 添加实体/设置相机:经纬度 → Cartesian3;
- 点击/拾取物体:Cartesian3 → 经纬度;
- 鼠标交互/屏幕定位:屏幕坐标 ↔ Cartesian3;
- 对接其他GIS系统:WGS84 ↔ 墨卡托等平面坐标。
- 关键API :
Cesium.Cartesian3.fromDegrees()、Cesium.Cartographic.fromCartesian()、SceneTransforms.wgs84ToWindowCoordinates()是转换的核心方法,需熟练掌握。