Cesium量算-贴地形距离

文章介绍了如何利用Cesium库来精确计算两点间的贴地形距离。通过将起始点和终点转换为制图坐标,进行经纬度插值,然后使用Cesium.sampleTerrainMostDetailed获取每个插值点在地形上的位置,最后计算这些点之间的距离总和得到贴地形距离。这种方法相比直线距离能更准确地反映实际地形地貌对路径的影响。
摘要由CSDN通过智能技术生成

Cesium量算-贴地形距离

查了很多贴地距离计算的,但试了下都测不准,还是自己写一个吧。
找了个地形比较夸张的地方测试了下,贴地距离比直线距离将近多两百米
在这里插入图片描述
在这里插入图片描述

主要思路:

  1. 起始点转成制图坐标(Cesium.Cartographic),用制图坐标的经纬度做插值,生成一组插值坐标
  2. 通过Cesium.sampleTerrainMostDetailed 获取每个插值在地形表面上的采样点,采样点也是Cesium.Cartographic,但此时是有高度的,正是我们需要的。
  3. 遍历采样点,每两个点计算出一个距离,把这些距离加起来就是总的贴地形距离。可以想象出插值量越大就会越精准,但计算时间会越长。
/**
 * @description 计算贴地形距离
 * @param {Cesium.Viewer} viewer
 * @param {Cesium.Cartesian3} start
 * @param {Cesium.Cartesian3} end
 * @returns {number}
 */
function getTerrainDistance(viewer, start, end) {
  return new Promise((resolve) => {
    //制图坐标插值(不贴附地形)
    let lerpArray = [];
    //插值数量,我这里根据两点间直线距离来插,每1米插一下,插的越多越精准
    let splitNum = parseInt(Cesium.Cartesian3.distance(start, end));

    let startCartographic = Cesium.Cartographic.fromCartesian(start);
    let startDegrees = [startCartographic.longitude, startCartographic.latitude];
    let endCartographic = Cesium.Cartographic.fromCartesian(end);
    let endDegrees = [endCartographic.longitude, endCartographic.latitude];

    lerpArray.push(new Cesium.Cartographic(startDegrees[0], startDegrees[1]));

    for (let i = 1; i <= splitNum - 1; i++) {
      let x = Cesium.Math.lerp(startDegrees[0], endDegrees[0], i / splitNum);
      let y = Cesium.Math.lerp(startDegrees[1], endDegrees[1], i / splitNum);
      lerpArray.push(new Cesium.Cartographic(x, y));
    }

    //地形细节采样:传入 目标地形 和 制图坐标插值组(不贴附地形) 获取 贴地形的制图坐标插值组 再计算距离
    Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, lerpArray).then((cartographicArr) => {
      getDetailedTerrainDistance(cartographicArr).then((distance) => {
        resolve(distance);
      });
    });
  });
}


/**
 * @description 根据制图坐标计算距离
 * @param {Array.<Cesium.Cartographic>} cartographicArr 制图坐标数组
 * @returns {number} 距离值
 */
function getDetailedTerrainDistance(cartographicArr) {
  return new Promise((resolve) => {
    let terrainDistance = 0;
    cartographicArr.map((currentCartographic, index) => {
      if (index == cartographicArr.length - 1) {
        return;
      }
      let nextCartographic = cartographicArr[index + 1];
      let currentPosition = Cesium.Cartesian3.fromRadians(currentCartographic.longitude, currentCartographic.latitude, currentCartographic.height);
      let nextPosition = Cesium.Cartesian3.fromRadians(nextCartographic.longitude, nextCartographic.latitude, nextCartographic.height);
      terrainDistance += Cesium.Cartesian3.distance(currentPosition, nextPosition);
    });
    resolve(terrainDistance);
  });
}
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值