基本上,我必须更新多个功能,特别是setGeometry,但每次在单个功能上应用更新时,都会触发更改事件,从而重新绘制图层。因此,如果有500个功能更新,该图层将重新绘制500次。 我想支付重绘事件,直到所有功能都更新。
更新: 我能想到的解决方法之一是:
但我不确定是否有比这更清洁的方式
答案 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实例创建,并且不必修改任何侦听器。这假定您可以修改几何图形,例如,如果该要素是唯一的所有者'几何学。
尝试将功能修改拆分为较小的块
这与问题的意图相反。如果修改功能需要花费大量时间,则可能需要更频繁地触发渲染。这将使地图看起来更具响应性,并允许浏览器赶上处理事件和其他待处理任务。