问题
当使用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);
483

被折叠的 条评论
为什么被折叠?



