Cesium基础-表面距离量算(依地形量算、依模型表面量算)

gis中的三维,少不了表面量算和空间量算。

表面量算:依地形起伏、贴模型表面变化的长度、面积等量算。

空间量算:欧式直线距离或椭球曲面距离、横截面面积。

空间距离:很简单,计算两点的直线距离即可。

空间面积:取中间点,或质心,与各个边组成三角形。计算每个三角形的面积。(该方法不适用与自相交的多边形)

今天主要探讨表面距离的计算思路:

实现代码:

  /**
   * 计算线段的表面距离
   * @param startPoint  -线段起点的屏幕坐标
   * @param endPoint    -线段终点的屏幕坐标
   * @returns 表面距离
   */
  private calculateSurfaceDistance(
    startPoint: Cesium.Cartesian2,
    endPoint: Cesium.Cartesian2
  ):number{
    let resultDistance =0;
    const sampleWindowPoints = [startPoint];
    const length =Math.sqrt(Math.pow(endPoint.x - startPoint.x,2) + (endPoint.y - startPoint.y,2)) ;
    for(let ii = 50; ii <= length; ii ++){
      const tempPositon = findWindowPositionByPixelInterval(startPoint,endPoint,ii);
      sampleWindowPoints.push(tempPositon);
    }
    sampleWindowPoints.push(endPoint);
    for(let jj =0; jj < sampleWindowPoints.length-1; jj ++){
      resultDistance += this.calculateDetailSurfaceLength(sampleWindowPoints[jj + 1],sampleWindowPoints[jj]);
    }
    return resultDistance;
  }

 /**
   * 计算细分后的,每一小段的笛卡尔坐标距离(也就是大地坐标系距离)
   * @param startPoint -每一段线段起点
   * @param endPoint -每一段线段终点
   * @returns 表面距离
   */
  private calculateDetailSurfaceLength(startPoint:Cesium.Cartesian2,endPoint:Cesium.Cartesian2):number{
      let innerS = 0;
      const surfaceStartCartesian3 = pickCartesian(this.viewer,startPoint);
      const surfaceEndCartesian3 = pickCartesian(this.viewer,endPoint);
      if(typeof(surfaceStartCartesian3.cartesian) !== 'undefined' && typeof(surfaceEndCartesian3.cartesian) !== 'undefined'){
        const cartographicStart = Cesium.Cartographic.fromCartesian(surfaceStartCartesian3.cartesian); 
        const cartographicEnd = Cesium.Cartographic.fromCartesian(surfaceEndCartesian3.cartesian); 
        const geoD = new Cesium.EllipsoidGeodesic();
        geoD.setEndPoints(cartographicStart,cartographicEnd);
        innerS = geoD.surfaceDistance;
        innerS = Math.sqrt(
          Math.pow(innerS, 2) +
            Math.pow(cartographicStart.height - cartographicEnd.height, 2)
        );   
      }
      return innerS;
  }

/**
 * 获取线段上距起点一定距离出的线上点坐标(屏幕坐标)
 * @param startPosition  -线段起点(屏幕坐标)
 * @param endPosition -线段终点(屏幕坐标)
 * @param interval -距起点距离
 * @returns -结果坐标(屏幕坐标)
 */
export function findWindowPositionByPixelInterval(startPosition:Cesium.Cartesian2,endPosition:Cesium.Cartesian2,interval:number):Cesium.Cartesian2{
    let result = new Cesium.Cartesian2(0,0);
    const length = Math.sqrt(Math.pow(endPosition.x - startPosition.x,2) + Math.pow(endPosition.y - startPosition.y,2));
    if(length< interval){
        return result;
    }else{
       const x = (interval/length)*(endPosition.x - startPosition.x) + startPosition.x;
       //alert(interval/length)
       const y = (interval/length)*(endPosition.y - startPosition.y) + startPosition.y;
       result.x = x;
       result.y = y;
    }
    return result;
}

看下表面距离和空间距离的结果对比:

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值