Cesium里关于Primitive位置更新问题

在Cesium里面,我们可以用Entity加载实体的方式,来通过CallbackProperty来更新实体的位置,但是如果涉及到大量实体(比如线)位置更新的话,用Entity会造成一定的性能问题。

我们可以用Primitive来绘制大量实体,但是Primitive中没有位置更新的回调方法,只能先移除再重新创建。创建primitive时,我们可以指定异步方式,当我们设置asynchronous: false时,是同步创建,可以在创建时移除,缺点是大量渲染会造成阻塞。但是如果指定异步方式,就会出现渲染闪烁的问题,因为无法确定primitive在哪一帧才能创建完成。

对于这个问题,我们可以利用primitive.ready属性来判断primitive何时创建完成,但是需要通过setInterval等轮询方式来进行更新。这里我们以绘制polyline为例,写一个管理器来对polyline数据进行位置更新,以下是示例代码:

var viewer = new Cesium.Viewer('cesiumContainer', {
});

var scene = viewer.scene;
scene.debugShowFramesPerSecond = true;

    viewer.scene.globe.depthTestAgainstTerrain = true;


    const currentPosition = { long: -105, lat: 19 };
    const MOVEMENT = 0.08;
    const UPDATE_INTERVAL = 500;
    const MAX_POLYLINE_SEGMENTS = 2;
    const MAX_POLYLINES = 50;

    class PolylineManager {

      constructor(currentPosition) {
        this.primitive = null;
        this.posModification = 0;
        this.initialPositions = [];
        this.colors = [];
        for (let i = 0; i <= MAX_POLYLINES; i++) {
          const color = `rgb(${Math.random() * 100 + 100}, ${Math.random() * 200}, ${Math.random() * 50})`;
          this.colors.push(
            Cesium.Color.fromCssColorString(color).withAlpha(0.5)
          );
          this.initialPositions.push({
            ...currentPosition,
            long: currentPosition.long + i * 0.2
          });
        }
        this.nextPrimitive = this.getNextLineSegmentPrimitive();
        viewer.scene.groundPrimitives.add(this.nextPrimitive);
      }

      getNextLineSegmentPrimitive() {
        const geometryInstances = [];
        for (let i = 0; i < MAX_POLYLINES; i++) {
          const currentPosition = this.initialPositions[i];
          const color = this.colors[i];
          const positionDegrees = [];
          for (let i = 0; i < MAX_POLYLINE_SEGMENTS; i++) {
            positionDegrees.push(currentPosition.long, currentPosition.lat + MOVEMENT * this.posModification + i + 1);
            positionDegrees.push(currentPosition.long, currentPosition.lat + MOVEMENT * this.posModification + i);
          }
          const geometryInstance = new Cesium.GeometryInstance({
            geometry: new Cesium.GroundPolylineGeometry({
              positions: Cesium.Cartesian3.fromDegreesArray(positionDegrees),
              width : 2.0,
            }),
            attributes: {
              color: Cesium.ColorGeometryInstanceAttribute.fromColor(color),
            }
          });
          geometryInstances.push(geometryInstance);
        }
        this.posModification++;


        return new Cesium.GroundPolylinePrimitive({
          geometryInstances,
          show: false,
          appearance : new Cesium.PolylineColorAppearance(),
          asynchronous: true,
          releaseGeometryInstances: true
        });
      }

      update() {
        if (this.nextPrimitive.ready) {
          viewer.scene.groundPrimitives.remove(this.primitive);
          this.nextPrimitive.show = true;
          this.primitive = this.nextPrimitive;
          
          this.nextPrimitive = this.getNextLineSegmentPrimitive();
          viewer.scene.groundPrimitives.add(this.nextPrimitive);
        }
      }
    }

    function run() {
        var initialPosition = Cesium.Cartesian3.fromDegrees(currentPosition.long, currentPosition.lat, 15000.0);
        var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(45, -20.0, 0.0);
        viewer.scene.camera.setView({
          destination: initialPosition,
          orientation: initialOrientation,
          endTransform: Cesium.Matrix4.IDENTITY
        });
        const manager = new PolylineManager(currentPosition);
        manager.update();

        setInterval(() => {
          manager.update();
        }, UPDATE_INTERVAL);
    }

    run();
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

搞GIS图形的sky.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值