android getHeight()与headView.getMeasuredHeight()

本文介绍了两种获取视图高度的方法:getMeasuredHeight()用于获取原始测量高度;getHeight()则返回视图在屏幕上的实际高度。这两种方法在不同场景下有着不同的应用。

1.getMeasuredHeight() 返回原始测量高度

2.getHeight(),返回在屏幕上显示的高度

<think> 我们遇到了一个错误:'TypeError: scene.globe.getHeight(...).then is not a function'。这个错误表明我们试图在`scene.globe.getHeight`的返回值上调用`.then`方法,但实际上这个返回值并不是一个Promise对象。在Cesium中,`getHeight`方法有两种调用方式:同步和异步。根据Cesium文档,`getHeight`方法在没有提供回调函数时返回一个Promise,但如果提供了回调函数,则返回undefined。另外,在较新的版本中,`getHeight`方法返回Promise,但如果没有地形数据或者地形未加载,可能会返回undefined或者直接抛出异常。 然而,我们的调用方式如下: ```javascript scene.globe.getHeight(cartographic).then(...) ``` 这个错误通常发生在以下情况: 1. 我们使用的Cesium版本较老,`getHeight`方法还不支持返回Promise(即版本低于1.63)。在1.63版本之前,`getHeight`方法只接受回调函数,并不返回Promise。 2. 传入的`cartographic`参数无效,导致函数返回undefined。 ### 解决方案 #### 方法1:使用回调函数(兼容旧版) 在旧版Cesium中(1.63之前),`getHeight`方法只支持回调函数方式: ```javascript scene.globe.getHeight(cartographic, function(error, terrainHeight) { if (error) { console.error(error); // 处理错误,可能是地形服务不可用或者参数无效 return; } // 计算离地高度 const heightAboveTerrain = cartographic.height - terrainHeight; console.log(heightAboveTerrain); }); ``` #### 方法2:升级Cesium(推荐) 如果使用的Cesium版本低于1.63,建议升级到1.63或更高版本。从Cesium 1.63开始,`getHeight`方法在没有提供回调函数时将返回一个Promise[^1]。因此,在新版本中,我们可以按照以下方式使用: ```javascript scene.globe.getHeight(cartographic) .then(function(terrainHeight) { const heightAboveTerrain = cartographic.height - terrainHeight; console.log(heightAboveTerrain); }) .catch(function(error) { console.error(error); }); ``` #### 方法3:检查参数有效性 确保传入的`cartographic`参数是有效的`Cartographic`对象(包含经度、纬度、高度)。如果参数无效,`getHeight`可能返回undefined,从而导致调用`.then`出错。 ```javascript // 检查cartographic是否有效 if (!cartographic) { console.error('cartographic is undefined'); return; } ``` #### 方法4:检查地形服务状态 如果地形服务不可用(例如未设置地形提供器),则`getHeight`可能无法正常工作。确保已经设置了地形提供器: ```javascript viewer.terrainProvider = new Cesium.CesiumTerrainProvider({ url: Cesium.IonResource.fromAssetId(1) // 使用Cesium World Terrain }); ``` ### 实际代码修正 根据上述分析,修改之前的函数`getCameraHeightAboveTerrain`: ```javascript function getCameraHeightAboveTerrain(viewer) { return new Promise((resolve) => { const scene = viewer.scene; const cameraPosition = viewer.camera.position; const cartographic = Cesium.Cartographic.fromCartesian(cameraPosition); // 检查cartographic是否有效 if (!cartographic) { resolve(0); // 或者根据情况返回其他值 return; } // 方法1:使用回调函数(兼容旧版) if (typeof scene.globe.getHeight !== 'function') { console.error('scene.globe.getHeight is not a function'); resolve(cartographic.height); return; } // 判断getHeight是否返回Promise(新版) const heightResult = scene.globe.getHeight(cartographic); if (heightResult && typeof heightResult.then === 'function') { // 新版:返回Promise heightResult.then(terrainHeight => { if (terrainHeight === undefined) { resolve(cartographic.height); } else { resolve(cartographic.height - terrainHeight); } }).catch(() => { resolve(cartographic.height); }); } else if (typeof heightResult === 'number') { // 注意:实际上,同步返回数字的情况在Cesium中不存在,这里只是为了示例另一种可能性 resolve(cartographic.height - heightResult); } else { // 旧版:使用回调函数 scene.globe.getHeight(cartographic, (error, terrainHeight) => { if (error || terrainHeight === undefined) { resolve(cartographic.height); } else { resolve(cartographic.height - terrainHeight); } }); } }); } ``` ### 注意事项 1. **版本兼容性**:建议在项目中固定Cesium版本,并查阅对应版本的文档。 2. **错误处理**:地形高度可能无法获取(如无地形服务、未加载完成等),此时应回退到椭球高度。 3. **参数验证**:确保传入的参数是有效的经纬度坐标。 ### 引用说明 在解决此问题的过程中,我们注意到Cesium版本更新导致API使用方式的变化[^1]。在实际开发中,应参考对应版本的官方文档。 §§相关问题§§ 1. 如何检测当前使用的Cesium版本? 2. Cesium中地形提供器(TerrainProvider)有哪些类型? 3. 在Cesium中如何自定义地形数据? 4. 如何处理Cesium中的异步操作错误? </think> ### 解决 `TypeError: scene.globe.getHeight(...).then is not a function` 错误 在 Cesium 中使用 `scene.globe.getHeight()` 时出现此错误,通常是由于 **API 使用方式错误** 或 **版本兼容性问题** 导致的。以下是完整的解决方案: --- ### 问题原因分析 1. **API 调用方式错误**: - `getHeight()` 在 Cesium 1.63+ 版本中返回 `Promise`,但旧版本仅支持回调函数 - 错误地将同步方法当作异步方法使用 2. **参数类型错误**: - `getHeight()` 要求参数必须是 `Cartographic` 类型(经纬度高程坐标) - 传入 `Cartesian3`(笛卡尔坐标)会触发错误 3. **地形服务未加载**: - 未设置有效的 `TerrainProvider` - 地形数据尚未完成加载 4. **Cesium 版本问题**: - 低于 1.63 的版本不支持 `.then()` 语法 --- ### 解决方案 #### 方法 1:使用正确参数类型(推荐) ```javascript function getTerrainHeight(position) { // 确保转换为 Cartographic 类型 const cartographic = Cesium.Cartographic.fromCartesian(position); // 新版 API(1.63+)使用 Promise const heightPromise = viewer.scene.globe.getHeight(cartographic); if (heightPromise instanceof Promise) { return heightPromise; } // 旧版 API 使用回调函数 else { return new Promise(resolve => { viewer.scene.globe.getHeight(cartographic, (height) => { resolve(height || 0); }); }); } } // 使用示例 getTerrainHeight(cameraPosition) .then(terrainHeight => { const altitude = Cartographic.fromCartesian(cameraPosition).height; console.log("离地高度:", (altitude - terrainHeight).toFixed(2)); }) .catch(error => console.error("地形获取失败:", error)); ``` #### 方法 2:检查地形服务状态 ```javascript // 确保已设置地形服务 viewer.terrainProvider = new Cesium.CesiumTerrainProvider({ url: Cesium.IonResource.fromAssetId(1) // 使用 Cesium 全球地形 }); // 等待地形就绪 viewer.terrainProvider.readyPromise.then(() => { // 安全调用 getHeight() }); ``` #### 方法 3:处理兼容性问题 ```javascript function safeGetHeight(cartographic) { return new Promise((resolve, reject) => { const result = viewer.scene.globe.getHeight(cartographic); // 处理不同版本返回值 if (typeof result === "number") { resolve(result); // 同步返回数字 } else if (result instanceof Promise) { result.then(resolve).catch(reject); // Promise 处理 } else if (typeof result === "undefined") { // 回调函数模式 viewer.scene.globe.getHeight(cartographic, height => { height ? resolve(height) : reject("高度获取失败"); }); } else { reject("不支持的返回类型"); } }); } ``` --- ### 关键验证点 1. **坐标类型检查**: ```javascript console.log(Cartographic.fromCartesian(position)); // 应输出 { longitude, latitude, height } ``` 2. **地形服务验证**: ```javascript console.log(viewer.terrainProvider.ready); // 应为 true console.log(viewer.terrainProvider.availability); // 应有覆盖范围 ``` 3. **版本检测**: ```javascript console.log(Cesium.VERSION); // 低于 1.63 需用回调函数 ``` --- ### 错误处理最佳实践 ```javascript try { const terrainHeight = await getTerrainHeight(position); if (terrainHeight === undefined) { throw new Error("地形服务返回空值"); } // 计算高度差 const altitude = Cartographic.fromCartesian(position).height; return altitude - terrainHeight; } catch (error) { console.error("高度计算失败:", error); // 降级处理:返回椭球高度 return Cartographic.fromCartesian(position).height; } ``` > 在实际应用中,离地高度计算需要有效的地形服务支持。当使用 Cesium World Terrain 时,需确保已配置正确的 Ion 认证[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值