Cesium高阶学习六、深度图解析

一、Cesium中的深度图应用

深度图(depth map)是一种灰度图像,其存储的是每个像素点到相机的距离信息。
在这里插入图片描述
根据深度图信息,我们可以还原每个像素点的世界坐标。已知摄像机坐标 ,将每个像素点位置映射到世界坐标(以中心点相机位置为起始点进行偏移映射),然后根据距离平移到正确位置。
在这里插入图片描述

Cesium中从屏幕拾取坐标的相关操作就是基于深度图的,相关操作封装在Picking类中(源码位于Scene/Picking,我们使用Cesium深度图时,可以参考此类中的很多方法)
在这里插入图片描述

二、从深度图中解析坐标

当我们需要拾取指定范围内大量点坐标的时候,如果使用Cesium自带的Pick操作,性能会比较低。因为Cesium自带的Pick操作,每次只能拾取一个点,而每一次拾取都会执行一次离屏渲染,然后从深度图中还原坐标。所以这时候我们就可以结合离屏渲染和深度图,自己封装一次渲染批量拾取点的操作。比如现在有个需求,我们项目的研究区域是一个多山地区,现在需要从场景中获取这个区域的最高海拔和最低海拔。
在这里插入图片描述

一个最简单的思路就是对这个区域插值构建很多点,然后求取这些点的高度进行对比,批量拾取点的操作,通过离屏渲染和深度图的方法无疑是最优的选择。深度图渲染的操作,我们可以参考Picking类,总结如下:
a、创建一个Picking类,设置picking的相关信息
b、使用picking进行离屏渲染
c、从离屏渲染结果中获取结果

比如研究区的坐标范围如下:

let positions =[[110.91995822563997,30.018123228872216,966.0229851512511],[110.88602280929696,30.02746264223286,992.25539021267],[110.87475288470748,30.00061781074165,673.7384986001304],[110.88525405115537,29.97371359878412,260.02837273046464],[110.89486388986987,29.962314482553314,639.5892410593838],[110.91982562243348,29.973771216309125,722.7884451776592],[110.92939046684434,30.003520348332533,1077.5538168551436]]     ;
positions = Cesium.Cartesian3.fromDegreesArrayHeights([].concat.apply([], positions));
let entity = new Cesium.Entity({
    
    polygon: {
   
      hierarchy: new Cesium.PolygonHierarchy(positions),
        material: Cesium.Color.BLUE.withAlpha(0.6)
    },
})
viewer.entities.add(entity);
 //研究区的矩形范围 (此方法获取的范围比实际范围稍大,但是不影响)
let boundingRectangle = Cesium.BoundingRectangle.fromRectangle(Cesium.Rectangle.fromCartesianArray(positions));
let range = Math.max(boundingRectangle.width, boundingRectangle.height);//宽高的最大值

1、创建离屏渲染的相机:为了方便计算,我们一般用正交相机,将相机置于研究区的上空,方向从上往下。

//创建相机 (正交投影)
 const offscreenCamera = new Cesium.Camera(viewer.scene);
 //设置相机的位置
 let center = new Cesium.Cartesian3();
 let n = positions.length;
 let centerPosition = new Cesium.Cartesian3();
 positions.forEach(p => {
   
     centerPosition = Cesium.Cartesian3.add(centerPosition, p, centerPosition);
 })
 centerPosition = Cesium.Cartesian3.multiplyByScalar(centerPosition, 1 / n, centerPosition);//中心点

 //获取中心点的法线
 let normal = Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal(centerPosition);
 //中心点向上平移5000米 
 centerPosition = Cesium.Cartesian3.add(centerPosition, Cesium.Cartesian3.multiplyByScalar(normal, 5000, new Cesium.Cartesian3()), centerPosition);
 offscreenCamera.position = centerPosition;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Cesium进阶学习

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

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

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

打赏作者

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

抵扣说明:

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

余额充值