我目前正在使用一个使用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,但没有运气.
实现这个的最佳方法是什么?其中一个选项是正确的方式还是有其他方法这样做我还没有发现?
[编辑]我添加了一个答案,我已经得到了,但仍然没有完成,并寻找答案.
我已经想出了一个很好的解决方案,但仍然有一个小问题。
我也做了一些展示实体的方法。我正在调用一种渲染和一种绘制。渲染使用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,几乎完美!
每当实体从使用常量回调属性“转换”为非常量回调属性时,它和同一类型的所有其他实体都会闪烁然后再次打开。我找不到更好的方法来进行这种转换。我觉得我一定还缺少一些东西。