Cesium针对DEM和3Dtiles通视分析(两个点之间是否能看见)

16 篇文章 21 订阅

Cesium通视分析

tip:利用两点间的插值计算,点A到点B之间,直线距离的高度是否大于地形高度为依据判断是否通视。

  • 1、3Dtiles 的通视
const startPoint = car3ToLatLon(points[0]);
const endPoint = car3ToLatLon(points[1]);
// const h_asc = (startPoint.height >= endPoint.height) ? false : true; //两个点 哪个点高
const pointSum = this.pointsNum
let cartesians = new Array(pointSum), offset;
for (let i = 0; i < pointSum; ++i) {
    offset = i / (pointSum - 1)
    cartesians[i] = Cesium.Cartesian3.lerp(points[0], points[1], offset, new Cesium.Cartesian3())
}
const cartesians_clone = cartesians.map(d => d.clone())
//启动异步 Scene#clampToHeight查询3Dtitle下的位置信息高度等。
this.viewer.scene.clampToHeightMostDetailed(cartesians).then((clampedCartesians: Cesium.Cartesian3[])=> {
// 可视终点
  let line_s_index = 0, position_updated:any,
  p_update_degree, p_degree, heightArr = [], entityHeightArr = []
  const length = clampedCartesians.length-1
  for (let i = 1; i < length; i++) {
      const position_updated = clampedCartesians[i];
      p_update_degree = car3ToLatLon(position_updated)
      p_degree = car3ToLatLon(cartesians_clone[i])
      heightArr.push(p_degree.height)
      entityHeightArr.push(p_update_degree.height)
  }
  this.heightArr = heightArr
  this.entityHeightArr = entityHeightArr
  for (let i = 1; i < length; i++) {
     position_updated = clampedCartesians[i];
      // 会有找不到的情况
      if(!line_s_index && position_updated) {
          p_update_degree = car3ToLatLon(position_updated)
          p_degree = car3ToLatLon(cartesians_clone[i])
          if (p_update_degree.height > p_degree.height) {
              line_s_index = i;
              break;
          }
      }
  }
  let line_e_index = line_s_index;
  if (callback) {
      this.isTrue = !!line_s_index
      const labelText = `起点坐标:${startPoint.lon.toFixed(2)} | ${startPoint.lat.toFixed(2)}| ${startPoint.height.toFixed()}
      \n终点坐标:${endPoint.lon.toFixed(2)} | ${endPoint.lat.toFixed(2)}| ${endPoint.height.toFixed()}
      \n通视结果: ${line_s_index > 0 ? '否' : '是'}`
      callback({
          'line_s_end': cartesians_clone[line_s_index],
          'line_e_start': cartesians_clone[line_e_index],
          'labelResult': labelText
      })
  }
})
    

3Dtiles 通视
在这里插入图片描述

可以看到直线上每一个点的高度都比3D tiles上的高度高,顾能够看到。

2、基于DEM通视

tip:同理,比较地形上的高度,与线段上的高度。

// 获取经纬度
        const startPoint = car3ToLatLon(points[0]);
        const endPoint = car3ToLatLon(points[1]);
        // const h_asc = (startPoint.height >= endPoint.height) ? false : true; //两个点 哪个点高
        const pointSum = this.pointsNum
        let pts:[number,number,number][] = []
        let cartesians = new Array(pointSum);
        let offset, x, y, height;
        for (let i = 0; i< pointSum; ++i) {
            offset = i / (pointSum - 1)
            x = Cesium.Math.lerp(startPoint.lon, endPoint.lon, offset)
            y = Cesium.Math.lerp(startPoint.lat, endPoint.lat, offset)
            height = Cesium.Math.lerp(startPoint.height, endPoint.height, offset)
            pts.push([x, y, height])
            //使用提供的笛卡尔坐标计算t处的线性插值或外推(开始点,结束点,插值多少,存储在哪)
            cartesians[i] = Cesium.Cartesian3.lerp(points[0], points[1], offset, new Cesium.Cartesian3())
        }
        const cartesians_clone = cartesians.map(d => d.clone())
        const terrainProvider = Cesium.createWorldTerrain() //加载高程地址 可以是自定义的
        const positions = pts.map(d=> Cesium.Cartographic.fromDegrees(...d))
        //根据地形算某经纬点的高度
        //查询完成后,可解析为提供的位置列表的承诺。这个 如果地形提供商的`availability`属性未定义,则promise将拒绝
        const promise:any = Cesium.sampleTerrainMostDetailed(terrainProvider, positions);
        (<any>Cesium).when(promise, (updatedPositions: any)=> {
            //可视终点
            let line_s_index = 0, position_updated = null, heightArr:number[] = [], entityHeightArr = [];
            const length = updatedPositions.length-1
            for (let i = 1; i < length; i++) {
               const position_updated = updatedPositions[i]
               entityHeightArr.push( position_updated.height)
               heightArr.push(pts[i][2])
            }
            this.heightArr = heightArr
            this.entityHeightArr = entityHeightArr
            for (let i = 1; i < length; i++) {
                position_updated = updatedPositions[i]
                if(!line_s_index && position_updated && position_updated.height > pts[i][2]) {
                    line_s_index = i
                    break;
                }
            }
            let line_e_index = line_s_index;
            if (callback) {
                this.isTrue = !!line_s_index
                const labelText = `起点坐标:${startPoint.lon.toFixed(2)} | ${startPoint.lat.toFixed(2)}| ${startPoint.height.toFixed()}
                \n终点坐标:${endPoint.lon.toFixed(2)} | ${endPoint.lat.toFixed(2)}| ${endPoint.height.toFixed()}
                \n通视结果: ${line_s_index > 0 ? '否' : '是'}`
                callback({
                    'line_s_end': cartesians_clone[line_s_index],
                    'line_e_start': cartesians_clone[line_e_index],
                    'labelResult': labelText
                })
            }
        })

在这里插入图片描述
在这里插入图片描述

  • 当然插值越多,计算出来的结果就越接近准确值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值