cesium基础学习-坐标系统相互转换及相应的场景

你想了解在 Cesium 中不同坐标系之间的转换方法,以及这些转换在实际开发场景中的应用,这是 Cesium 开发中非常核心且基础的知识点。

一、Cesium 中常见的坐标系类型

在开始转换前,先明确 Cesium 中最常用的几种坐标系:

  1. WGS84 经纬度坐标[经度, 纬度, 高度](单位:度、米),比如 [116.403874, 39.914885, 50],是最通用的地理坐标。
  2. WGS84 弧度坐标 :经纬度转成弧度后的坐标,Cesium 内部计算常用,比如 Cesium.Math.toRadians(经度)
  3. Cartesian3 坐标 :笛卡尔直角坐标(单位:米),Cesium 场景中实体、相机等的核心坐标,格式为 (x, y, z)
  4. Cartographic 坐标 :Cesium 封装的地理坐标对象,包含 longitude(弧度经度)、latitude(弧度纬度)、height(高度)。
  5. 屏幕坐标[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]}`);

三、注意事项

  1. 高度基准:Cesium 默认使用 WGS84 椭球高度,如果需要使用大地高/海拔高度,需结合地形数据调整。
  2. 空值处理 :转换屏幕坐标→Cartesian3 时,如果点击的是天空(无地形),会返回 undefined,需提前判断。
  3. 性能优化:频繁转换(如鼠标移动时),可缓存转换结果,避免重复计算。

总结

  1. 核心转换关系:WGS84经纬度 ↔ Cartesian3 是 Cesium 中最基础、最常用的转换,前者用于业务数据存储/展示,后者用于 Cesium 内部渲染和交互。
  2. 场景对应
    • 添加实体/设置相机:经纬度 → Cartesian3;
    • 点击/拾取物体:Cartesian3 → 经纬度;
    • 鼠标交互/屏幕定位:屏幕坐标 ↔ Cartesian3;
    • 对接其他GIS系统:WGS84 ↔ 墨卡托等平面坐标。
  3. 关键APICesium.Cartesian3.fromDegrees()Cesium.Cartographic.fromCartesian()SceneTransforms.wgs84ToWindowCoordinates() 是转换的核心方法,需熟练掌握。
相关推荐
来两个炸鸡腿2 小时前
【Datawhale组队学习202601】Base-NLP task03 深入大模型架构
人工智能·学习·自然语言处理
代码游侠2 小时前
学习笔记——文件传输工具配置与Makefile详解
运维·前端·arm开发·笔记·学习
菜鸟‍2 小时前
【论文学习】MedDINOv3:如何将视觉基础模型适配于医学图像分割任务? || MACMD:基于多空洞上下文注意力与通道混合器解码的医学图像分割方法
深度学习·学习
flyyyya2 小时前
【AI学习从零至壹】langchain1.0中间件
人工智能·学习·中间件
不会写代码0002 小时前
Flutter 框架跨平台鸿蒙开发 - 学习计划制定器开发教程
学习·flutter·华为·harmonyos
云边散步2 小时前
godot2D游戏教程系列一(6)
笔记·学习·音视频
hssfscv2 小时前
Javaweb学习笔记——后端实战6登录功能1
笔记·后端·学习
Engineer邓祥浩2 小时前
设计模式学习(17) 23-15 访问者模式
学习·设计模式·访问者模式
好奇龙猫2 小时前
【日语学习-日语知识点小记-日本語体系構造-JLPT-N2前期阶段-第一阶段(6):单词语法】
学习