Cesium 各高度的获取

本文详细介绍了在Cesium中获取地形和模型表面高度的方法,包括通过事件获取像素坐标转换后的地形高度,使用Cesium.sampleTerrain和Cesium.sampleTerrainMostDetailed异步获取精确高度。同时,还阐述了模型表面高度的同步和异步获取方式,以及sampleheight在获取地形和模型高度中的应用。
地形高度的获取
  • 通过事件获取到像素坐标,然后转为世界坐标,再求地形高度
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handler.setInputAction(function(evt
<think>我们正在讨论如何使用Cesium.Viewer获取当前高度。根据之前的对话历史和引用内容,我们可以总结出几种获取高度的方法: 根据引用[2]和引用[3],获取高度的方法有: 1. 使用`viewer.scene.globe.getHeight(cartographic)`:这是一个同步方法,适合实时获取高度。 2. 使用`Cesium.sampleTerrain`或`Cesium.sampleTerrainMostDetailed`:这些是异步方法,可以获取更精确的地形高度。 另外,引用[4]提到了地球表面的高度偏移量(`surfaceHeight`属性),但这不是直接获取高度的方法,而是设置地球表面整体偏移。 现在,用户的问题是如何使用Cesium.Viewer获取当前高度。这里的“当前高度”可能指的是当前相机位置的高度,或者地图中心点的高度,或者是鼠标点击点的高度。由于用户没有特别指明,我们可以假设用户需要获取当前相机位置的高度(海拔)。 ### 步骤: 1. 获取相机当前的笛卡尔坐标(世界坐标)。 2. 将笛卡尔坐标转换为地理坐标(弧度制的经纬度和高度)。 3. 从地理坐标中直接提取高度值。 注意:相机位置的高度是相对于椭球体的高度(椭球体高度),而如果我们想获取地形高度(即相机下方地面的海拔),则需要使用地形采样方法。 ### 方法1:获取相机的椭球体高度 ```javascript // 获取相机位置(笛卡尔坐标,世界坐标系) const position = viewer.camera.positionWC; // 将笛卡尔坐标转换为地理坐标(弧度制) const cartographic = Cesium.Cartographic.fromCartesian(position); // 此时cartographic.height就是相机相对于椭球体的高度(单位:米) const height = cartographic.height; console.log(`相机高度(椭球体高度): ${height} 米`); ``` ### 方法2:获取相机下方地形的海拔高度(异步) 如果我们想要知道相机正下方的地形高度,可以使用地形采样。注意:这个过程是异步的。 ```javascript // 获取相机位置的地理坐标(弧度制) const position = viewer.camera.positionWC; const cartographic = Cesium.Cartographic.fromCartesian(position); // 创建一个位置数组(因为sampleTerrain需要数组) const positions = [cartographic]; // 使用地形提供者采样 const terrainProvider = viewer.terrainProvider; // 设置采样精度级别,通常使用最高精度 Cesium.sampleTerrainMostDetailed(terrainProvider, positions) .then(function(updatedPositions) { if (updatedPositions && updatedPositions.length > 0) { const terrainHeight = updatedPositions[0].height; console.log(`相机下方地形高度: ${terrainHeight} 米`); } }) .catch(function(error) { console.error('获取地形高度失败', error); }); ``` ### 方法3:获取屏幕中心点的地形高度(考虑地图倾斜) 如果用户想要的是屏幕中心点的地形高度(无论地图是否倾斜),我们可以通过以下步骤: ```javascript // 获取画布中心点 const canvas = viewer.scene.canvas; const centerPixel = new Cesium.Cartesian2(canvas.width / 2, canvas.height / 2); // 获取中心点对应的射线 const ray = viewer.camera.getPickRay(centerPixel); if (ray) { // 获取射线与地形的交点 const position = viewer.scene.globe.pick(ray, viewer.scene); if (position) { const cartographic = Cesium.Cartographic.fromCartesian(position); // 如果没有加载地形,这里获取高度可能是椭球体高度 // 如果加载了地形,则是地形上的高度 console.log(`屏幕中心点高度: ${cartographic.height} 米`); } } ``` ### 说明: - **椭球体高度**:是相对于WGS84椭球体的高度。 - **地形高度**:是地球表面的实际海拔高度(包含地形起伏)。 - 当场景中加载了地形(如World Terrain)时,使用`globe.pick`会返回地形上的点,所以得到的高度是地形高度。 ### 注意事项: 1. 地形采样(`sampleTerrain`)需要地形图层支持,并且是异步操作。 2. 如果没有地形数据,`globe.pick`返回的将是椭球体表面。 3. 在获取高度时,注意单位是米。 ### 完整示例代码(获取相机位置的椭球体高度和地形高度): ```javascript // 获取相机椭球体高度 function getCameraEllipsoidHeight() { const cartographic = Cesium.Cartographic.fromCartesian(viewer.camera.positionWC); return cartographic.height; } // 获取相机下方地形高度(异步) function getTerrainHeightUnderCamera() { const cartographic = Cesium.Cartographic.fromCartesian(viewer.camera.positionWC); return new Promise((resolve, reject) => { Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, [cartographic]) .then(updatedPositions => resolve(updatedPositions[0].height)) .catch(reject); }); } // 使用示例 console.log('椭球体高度:', getCameraEllipsoidHeight()); getTerrainHeightUnderCamera().then(height => { console.log('地形高度:', height); }); ``` ### 引用说明: - 方法1直接使用`Cartographic.fromCartesian`获取椭球体高度,在引用[3]中有类似操作。 - 方法2使用`sampleTerrainMostDetailed`获取地形高度,参考自引用[2]和引用[3]。 - 方法3通过屏幕中心点获取地形高度,参考引用[2]中鼠标点击获取高度的方法。 §§相关问题§§ 1. 如何区分椭球体高度和地形高度? 2. 为什么有时候获取的地形高度为undefined? 3. 如何实时更新相机高度并显示? </think>### 使用 Cesium.Viewer 获取当前高度的方法 在 Cesium获取当前高度(通常是相机高度或地图中心点高度)有以下几种核心方法: #### 方法 1:直接获取相机高度(椭球体高度) ```javascript // 获取相机笛卡尔坐标 const cameraPosition = viewer.camera.positionWC; // 转换为地理坐标 const cartographic = Cesium.Cartographic.fromCartesian(cameraPosition); // 获取高度(相对于椭球体) const height = cartographic.height; // 单位:米 console.log(`当前相机高度:${height.toFixed(2)} 米`); ``` **特点**: - 获取的是相机相对于 WGS84 椭球体的高度[^1][^2] - 不考虑地形起伏 - 适用于高空视角(全球视图) #### 方法 2:获取地形高度(地表高程) ```javascript // 获取屏幕中心点坐标 const canvas = viewer.scene.canvas; const centerPixel = new Cesium.Cartesian2( canvas.width / 2, canvas.height / 2 ); // 获取射线与地形的交点 const ray = viewer.camera.getPickRay(centerPixel); const position = viewer.scene.globe.pick(ray, viewer.scene); if (position) { const cartographic = Cesium.Cartographic.fromCartesian(position); const terrainHeight = cartographic.height; // 地形高度 console.log(`地表高程:${terrainHeight.toFixed(2)} 米`); } ``` **特点**: - 精确获取地表高程(考虑地形起伏)[^2] - 需要地形服务支持(如 World Terrain) - 倾斜视角时仍能准确定位地表点 #### 方法 3:异步获取地形高度(高精度) ```javascript // 获取相机位置的地理坐标 const cartographic = Cesium.Cartographic.fromCartesian( viewer.camera.positionWC ); // 异步获取最高精度地形高度 Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, [cartographic]) .then(updatedPositions => { const preciseHeight = updatedPositions[0].height; console.log(`精准地形高度:${preciseHeight.toFixed(2)} 米`); }); ``` **特点**: - 获取最高精度地形数据(支持 LOD)[^3] - 异步操作不影响主线程 - 需要地形服务支持 #### 方法 4:实时高度监听 ```javascript // 监听相机变化事件 viewer.camera.changed.addEventListener(() => { const cartographic = Cesium.Cartographic.fromCartesian( viewer.camera.positionWC ); const height = cartographic.height; document.getElementById('height-display').innerText = `当前高度:${height.toFixed(0)} 米`; }); ``` ### 关键区别说明 | 方法 | 获取高度类型 | 是否考虑地形 | 精度 | 适用场景 | |-------------|-------------------|-------------|---------|----------------------| | 方法1 | 椭球体高度 | ❌ | 低 | 全球视图、高空操作 | | 方法2 | 地表高程 | ✅ | 中 | 倾斜视角、地表操作 | | 方法3 | 精准地表高程 | ✅ | 高 | 地形分析、精确定位 | ### 注意事项 1. **地形服务依赖**:方法 2-3 需要启用地形服务初始化: ```javascript const viewer = new Cesium.Viewer('cesiumContainer', { terrain: Cesium.Terrain.fromWorldTerrain() }); ``` 2. **高度偏移处理**:如果设置了地表偏移量,需考虑其影响: ```javascript const surfaceOffset = viewer.scene.globe.surfaceHeight; // 获取偏移量[^4] const actualHeight = terrainHeight - surfaceOffset; ``` 3. **空值处理**:海洋或未加载区域可能返回 `undefined`,需添加错误处理: ```javascript if (cartographic.height === undefined) { console.log("该位置无地形数据"); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

seelingzheng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值