在openlayers 3上,如何在更新功能时暂停更改事件?

时间:2016-05-02 02:36:32

标签: javascript openlayers-3

基本上,我必须更新多个功能,特别是setGeometry,但每次在单个功能上应用更新时,都会触发更改事件,从而重新绘制图层。因此,如果有500个功能更新,该图层将重新绘制500次。 我想支付重绘事件,直到所有功能都更新。

更新: 我能想到的解决方法之一是:

  1. getFeatures()
  2. 清晰(真)
  3. (更新功能)
  4. addFeatures(特征)
  5. 但我不确定是否有比这更清洁的方式

2 个答案:

答案 0 :(得分:2)

简答:

var feature = layer.getFeatureById("myId");
var geometry = new ol.geom.Point(ol.proj.fromLonLat([lon, lat]));
feature.set(feature.getGeometryName(), geometry, true);
........
source.changed()

答案很长:

在查看 setGeometry 源代码(feature.js)之后,基本上它将使用 geometryName _ 上的 set 方法。因此,通过明确设置相同的属性并将 opt_silent 设置为true,它不会触发更改事件(object.js)。

完成更改后,只需在图层上触发更改事件。

答案 1 :(得分:1)

不要跳过更改事件

问题的基本前提 - 每个功能更改导致重新绘制图层 - 是不正确的。

当要素更改时,地图将请求在下一个动画帧上重绘。但是,如果在同一执行线程中更改了多个功能,则浏览器不会重绘任何内容,直到脚本完成。只需一次重绘,您就可以遍历并更改数百万个功能。

您可以通过收听postrender事件验证渲染完成的时间:

map.on('postrender', function(event){
  console.log('did render', new Date())
})

您可以按your answer中的建议设置几何体而不触发任何事件。但这样做可能会导致源中的空间索引损坏等问题。只有在您确定没有人对该更改感兴趣的情况下才能省略更改事件。

那有什么延迟?

话虽如此,更新大量功能仍然会受到性能影响。我写了this demo,它取代了所有功能'每个地图上的几何图形单击。在我的笔记本电脑上,更换所有10 000个几何图形大约需要600毫秒。在此期间,地图和浏览器没有响应,在下次重绘之前不会显示任何更新。重绘的持续时间取决于缩放级别。

在要素上设置几何图形时,它将:

  • 将几何图形添加到其属性
  • 删除以前几何体的所有侦听器。
  • 将更改侦听器添加到新几何体。
  • 触发更改事件以通知侦听器它已更改。

该功能的侦听器将是源,它将:

  • 更新空间索引(如果使用)。
  • 触发更改事件以通知侦听器它已更改。

我们会通知图层并最终通知地图,并将重绘排队。

可能的优化

如果您希望能够以更高效的方式更改许多功能,我建议您考虑:

禁用空间索引

docs所述,将useSpatialIndex设置为false可能会提高某些情况下的效果。如果没有空间索引,源对每个特征更改的计算量就会减少。但是,如果没有索引,源的其他用途可能会降低性能。

修改几何体而不是替换它

在几何图形上使用setCoordinates比在要素上使用setGeometry更快。可以跳过整个Geometry实例创建,并且不必修改任何侦听器。这假定您可以修改几何图形,例如,如果该要素是唯一的所有者'几何学。

尝试将功能修改拆分为较小的块

这与问题的意图相反。如果修改功能需要花费大量时间,则可能需要更频繁地触发渲染。这将使地图看起来更具响应性,并允许浏览器赶上处理事件和其他待处理任务。