Cesium实时渲染原理浅析

背景

在地图的几何编辑场景中,我们通常需要快速渲染拖拽后的几何体,如果通过移除要素再添加要素的逻辑去更新,往往会有较低的效率。Cesium Entity是否提供了更高效的更新接口呢?答案是有的。

Cesium.CallbackProperty(callback, isConstant)

这个方法,适用于添加要素时,给属性赋值。有意思的是,这是一个回调函数,这个方法内,我们可以返回计算得到的最新属性值,Cesium会在每次渲染时自动调用该回调函数,以渲染最新几何。

以polygon为例:

this.entityCollections.add({
      polygon: {
        hierarchy: new Cesium.CallbackProperty(() => new Cesium.PolygonHierarchy(this.coors), false)
      },
    });

注意,这里需要使用箭头函数,this指向执行时的上下文。这样,只要this.coors始终在变化,渲染几何就会实时更新。

原理

CallbackProperty的源码如下:

/**
 * A {@link Property} whose value is lazily evaluated by a callback function.
 *
 * @alias CallbackProperty
 * @constructor
 *
 * @param {CallbackProperty.Callback} callback The function to be called when the property is evaluated.
 * @param {Boolean} isConstant <code>true</code> when the callback function returns the same value every time, <code>false</code> if the value will change.
 */
function CallbackProperty(callback, isConstant) {
  this._callback = undefined;
  this._isConstant = undefined;
  this._definitionChanged = new Event();
  this.setCallback(callback, isConstant);
}

// getValue方法很重要,会在渲染时获取值的时候判断如果值被定义了,就会调用property.getValue方法,这样就会始终获取callback的最新值
CallbackProperty.prototype.getValue = function (time, result) {
  return this._callback(time, result);
};

CallbackProperty.prototype.setCallback = function (callback, isConstant) {
  //>>includeStart('debug', pragmas.debug);
  if (!defined(callback)) {
    throw new DeveloperError("callback is required.");
  }
  if (!defined(isConstant)) {
    throw new DeveloperError("isConstant is required.");
  }
  //>>includeEnd('debug');

  var changed = this._callback !== callback || this._isConstant !== isConstant;

  this._callback = callback;
  this._isConstant = isConstant;

  if (changed) {
    this._definitionChanged.raiseEvent(this);
  }
};

export default CallbackProperty;

调用栈如下:
在这里插入图片描述
看下Property.getValueOrUndefined源码:

// 这段代码就是执行了CallbackProperty.getValue(),从而执行callback回调,callback是个箭头函数,因此this.coors如果是更新的,那么callback的结果也会是最新的位置
Property.getValueOrUndefined = function (property, time, result) {
  return defined(property) ? property.getValue(time, result) : undefined;
};

同理,Cesium.CallbackProperty方法也可以用在所有需要实时更新的属性位置,比如point的position属性。

注意,渲染必须是自动执行的,即在new Cesium.Viewer()时,useDefaultRenderLoop属性必须为true,或者直接不填(默认为true)。// True if this widget should control the render loop, false otherwise.

如果不填,必须手动在一些鼠标操作,例如mouseMove里写主动触发渲染的方法,否则,无法渲染,CallbackProperty也不会被执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

HouGISer

HouGiser需要你的鼓励~

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

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

打赏作者

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

抵扣说明:

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

余额充值