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() 是转换的核心方法,需熟练掌握。
相关推荐
阿蒙Amon14 小时前
TypeScript学习-第10章:模块与命名空间
学习·ubuntu·typescript
AI绘画哇哒哒14 小时前
【干货收藏】深度解析AI Agent框架:设计原理+主流选型+项目实操,一站式学习指南
人工智能·学习·ai·程序员·大模型·产品经理·转行
戌中横15 小时前
JavaScript——预解析
前端·javascript·学习
●VON16 小时前
React Native for OpenHarmony:2048 小游戏的开发与跨平台适配实践
javascript·学习·react native·react.js·von
ZH154558913116 小时前
Flutter for OpenHarmony Python学习助手实战:自动化脚本开发的实现
python·学习·flutter
xcLeigh16 小时前
Python入门:Python3 requests模块全面学习教程
开发语言·python·学习·模块·python3·requests
xcLeigh16 小时前
Python入门:Python3 statistics模块全面学习教程
开发语言·python·学习·模块·python3·statistics
GHL28427109017 小时前
分析式AI学习
人工智能·学习·ai编程
lpruoyu17 小时前
【Android第一行代码学习笔记】Android架构_四大组件_权限_持久化_通知_异步_服务
android·笔记·学习
野犬寒鸦17 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法