Cesium 实时点云性能优化

问题

当使用Cesium加载实时点云时,当数据量大,并且推送比较频繁时,页面就会特别卡顿,我们其实可以用三个方面进行优化。

  • 加载点云的方式
  • 获取到新的点云时,进行点更新,删除多余点
  • 控制与cesium的交互
  • 控制点云加载时机

加载点云的方式

cesium 中可以使用Primitive和Entity加载点云。
Primitive是是一种用于创建和操作三维几何形状的底层API。Entity调用方便,封装完美是基于primitive的封装。primitive更接近底层可以绘制高级图形。
对于显示成千上万个点,由于加载性能等因素,Cesium官方推荐我们使用Primitive。
在cesium中加载实时点云时,使用new Cesium.PointPrimitiveCollection()加载。
let pointCloud = viewer.scene.primitives.add(new Cesium.PointPrimitiveCollection());
添加点
pointCloud .add({
position : Cesium.Cartesian3.fromDegrees(longitude, latitude),
color : color
});

获取到新的点云时,进行点更新,删除多余点

  • 首先需要将上一帧获取到的点云先存储起来
  • 获取到新的点云以后,先获取上一帧的Point然后进行位置更新
  • 按照新的点位进行循环,根据下标primitive.get(k)获取Point。然后更新点位position,当根据下标获取不到Point时,使用primitive.add进行新的Point的添加
  • 当上一帧点数比当前点云数量多时,remove多余点。

控制与cesium的交互

当感觉页面卡顿时,一般都是在鼠标进行操作时,会感觉页面会感觉卡顿很明显。我们可以通过控制在进行鼠标操作时,暂停实时点云的渲染,再操作完成后再继续点云渲染。

const canDrawPoint = () => {
  cannotDrawType = '';
  isCanDrawPoint = true;
}
const canNotDrawPoint = (type:string|number = '') => {
  cannotDrawType = type;
  isCanDrawPoint = false;
}
let mouseMoveTimer = null;
const setMouseMoveFun = () => {
  if(cannotDrawType !== ''){
    return;
  }
  if(!isCanDrawPoint){
    canDrawPoint();
  }
  if(mouseMoveTimer){
    clearTimeout(mouseMoveTimer);
  }
  mouseMoveTimer = setTimeout(() => {
    canNotDrawPoint();
  }, 1000 * 60 * 5)
}
downHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
downHandler.setInputAction(() => {canNotDrawPoint(Cesium.ScreenSpaceEventType.LEFT_DOWN)}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
downHandler.setInputAction(() => {canDrawPoint()}, Cesium.ScreenSpaceEventType.LEFT_UP);
downHandler.setInputAction(() => {canNotDrawPoint(Cesium.ScreenSpaceEventType.RIGHT_DOWN)}, Cesium.ScreenSpaceEventType.RIGHT_DOWN);
downHandler.setInputAction(() => {canDrawPoint()}, Cesium.ScreenSpaceEventType.RIGHT_UP);
downHandler.setInputAction(() => {canNotDrawPoint(Cesium.ScreenSpaceEventType.MIDDLE_DOWN)}, Cesium.ScreenSpaceEventType.MIDDLE_DOWN);
downHandler.setInputAction(() => {canDrawPoint()}, Cesium.ScreenSpaceEventType.MIDDLE_UP);
setMouseMoveFun();
downHandler.setInputAction(() => {setMouseMoveFun()}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
let wheelTimer = null;
downHandler.setInputAction(() => {
  if(wheelTimer){
    clearTimeout(wheelTimer);
  }else{
    canNotDrawPoint(Cesium.ScreenSpaceEventType.WHEEL);
  }
  wheelTimer = setTimeout(() => {
    canDrawPoint();
    wheelTimer = null;
  }, 1000)
}, Cesium.ScreenSpaceEventType.WHEEL);

在渲染点云的地方,通过isCanDrawPoint进行判断,是否进行渲染。

控制点云加载时机

当在点云推送时,数据推送比较频繁。会造成数据一直在处理,一直在渲染。我们可以改变渲染时机,不在获取到数据是就进行数据渲染。而是在获取到数据后,将数据先存起来。然后在场景更新之后和渲染场景之前进行数据渲染,使用viewer.scene.preRender。
添加事件:
viewer.scene.preRender.addEventListener(drawPointClouds);
移除事件:
viewer.scene.preRender.removeEventListener(drawPointClouds);

切记,有一点非常重要,如果是VUE项目,切记,请勿在data中添加并赋值任何cesium对象。性能损耗特别大!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值