铯中动态形状的最佳和最高效的实现

Zac*_*Zac 7 cesium

我目前正在使用一个使用Cesium Viewer的应用程序.我需要能够显示将动态更新的形状集合.我无法理解这样做的最佳方法.

我目前正在使用实体并使用CallbackProperties来允许更新形状.

您可以通过这个到沙堡来了解我是如何做到这一点的.有一个多边形对象被用作cesiumCallback的基础,它正在被另一段代码编辑.(用setTimeout模拟)

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

var polygon = {};
polygon.coordinates = [
    {longitude: 0, latitude: 0, altitude: 0},
    {longitude: 10, latitude: 10, altitude: 0},
    {longitude: 10, latitude: 0, altitude: 0}
];


// converts generic style options to cesium one (aka color -> material)
var polOpts = {};

 // function for getting location
polOpts.hierarchy = new Cesium.CallbackProperty(function() {
  var hierarchy = [];
  for (var i = 0; i < polygon.coordinates.length; i++) {
       var coordinate = polygon.coordinates[i];
       hierarchy.push(Cesium.Cartesian3.fromDegrees(coordinate.longitude, coordinate.latitude, coordinate.altitude));
  }
  return hierarchy;
}, false);

viewer.entities.add({polygon: polOpts});

setInterval(function(polygon){
       polygon.coordinates[0].longitude--;
}.bind(this, polygon), 1000);
Run Code Online (Sandbox Code Playgroud)

传入的多边形是一个通常描述多边形的类,因此它有一个坐标和样式选项数组,以及一个调用此方法renderPolygon传递的render方法.这种渲染形状的方法适用于我需要的所有东西,但效果不是很好.形状更新有两种情况,一种形状将在很长一段时间内更新,速度很慢,例如每几秒一次.另一种形状将在几秒钟内多次更新,如数千,然后长时间不再更换,如果有的话.

我有两个想法来解决这个问题.

想法1:有两个方法,一个renderDynamicPolygon和一个renderStaticPolygon.renderDynamicPolygon方法将使用cesiumCallbackProperties执行上述功能.这将用于在更新的短时间内多次更新的形状.一旦更新完成,renderStaticPolygon方法将替换使用具有常量值的callbackProperties的实体属性.

这会产生许多其他工作以确保形状处于正确状态,并且无法帮助长时间缓慢更新的形状.

想法2:与原语的工作方式类似,我尝试删除旧实体,并在每次需要更新时再次添加更新的属性,但这会导致闪烁,与基元不同,我找不到异步属性实体.

我也尝试过使用原语.它适用于折线,我只需删除旧折线并添加一个带有更新属性的新线.我也使用async = false来确保没有闪烁.我遇到的这个问题并非所有形状都可以使用基元创建.(这是真的?)

我尝试的另一件事是使用几何和实例使用几何实例.在完成cesium网站上的教程之后,我能够渲染一些形状,并且可以更新外观,但发现几乎不可能弄清楚如何正确更新形状,并且很难让它们到达看起来正确.形状需要具有正确的形状,填充颜色和不透明度以及笔触颜色,不透明度和重量.我试图使用polygonOutlineGeometry,但没有运气.

实现这个的最佳方法是什么?其中一个选项是正确的方式还是有其他方法这样做我还没有发现?


[编辑]我添加了一个答案,我已经得到了,但仍然没有完成,并寻找答案.

Zac*_*Zac 3

我已经想出了一个很好的解决方案,但仍然有一个小问题。

我也做了一些展示实体的方法。我正在调用一种渲染和一种绘制。渲染使用Cesium.CallbackProperty和 属性,绘制使用。isConstanttrueisConstantProperty false

然后我创建了一个函数来将实体从渲染更改为绘制,反之亦然。它遍历实体回调属性,并使用 setCallback 属性用正确的函数和 isConstant 值覆盖该属性。

示例:我根据定义的圆形对象创建一个椭圆形。

// isConst is True if it is being "painted" and false if it is being "rendered"
ellipse: lenz.util.extend(this._getStyleOptions(circle), {
  semiMinorAxis: new Cesium.CallbackProperty(
    this._getRadius.bind(this, circle),
    isConst
  ),
  semiMajorAxis: new Cesium.CallbackProperty(
    this._getRadius.bind(this, circle),
    isConst
  ),
})
Run Code Online (Sandbox Code Playgroud)

因此,当更新形状时(当用户绘制形状时),形状将在 isConstant 为 false 的情况下渲染。然后,当绘图完成后,使用如下代码将其转换为绘制版本:

existingEntity.ellipse.semiMinorAxis.setCallback(
  this._getRadius.bind(this, circle),
  isConst
);
                            existingEntity.ellipse.semiMajorAxis.setCallback(
  this._getRadius.bind(this, circle, 1),
  isConst
);
Run Code Online (Sandbox Code Playgroud)

这在性能方面非常有效。我能够绘制数百种形状,而框架根本不会下降太多。我附上了更改前后包含 612 个实体的铯图的屏幕截图,使用 chrome 渲染工具时的帧速率位于右上角。

之前:锁定在 fps 0.9 注意:我编辑了 ui 的其余部分,女巫让地球仪看起来被切断了,抱歉 在此输入图像描述

更改后:fps 保持在 59.9,几乎完美!

在此输入图像描述

每当实体从使用常量回调属性“转换”为非常量回调属性时,它和同一类型的所有其他实体都会闪烁然后再次打开。我找不到更好的方法来进行这种转换。我觉得我一定还缺少一些东西。