我有一个大型地理数据库的地方的利益(兴趣点),我正在使用MapboxGL显示给用户。根据用户输入(过滤器和Map位置),我需要查询数据库,并动态显示结果给用户。
目前,我正在使用map.on('load',...)
添加源代码map.addSource(sourceId, ..)
每次用户平移、缩放或过滤Map时,我都会尝试根据从查询中接收到的数据更新Map上的点:
const source = map.getSource(sourceId) as GeoJSONSource;
if (source) {
source.setData({ type: 'FeatureCollection', features: features });
}
数据库的加载速度很快(而且是去抖的),但是返回的数据点很多,这会导致延迟,因为Mapbox每次调用setData
时都会计算每个点,这会导致大量的CPU使用。
我试着使用上面的方法debounce
,但是因为可能涉及到很多点,所以一旦调用setData
,仍然会有很大的滞后。
注意:我有两个层来聚集和显示点。但是,如果我删除它们,性能是相当的。它们不是瓶颈,数据库查询也不是。
有没有可能只将数据附加到源中,而不是每次都设置它?有没有更好的解决方案来动态地向用户可视化这些点?
谢谢!
1条答案
按热度按时间xam8gpfp1#
基于类似的情况,我的理解是,瓶颈实际上是当你调用
setData()
时,GeoJSON被插入到当前样式中(这变成了JSON的一个巨大部分),并且有一系列的处理被触发。如果可以通过简单的URL获取GeoJSON,您可以尝试将该URL传递给
setData()
,而不是先获取数据,然后再传递数据。是否可以只将数据追加到源,而不是每次都设置它?
在Mapbox GL JS中没有。你当然可以手动操作以减少网络流量,但你说这不是瓶颈。
是否有更好的解决方案来动态地向用户可视化这些点?
动态生成的矢量切片,例如来自PostGIS的
ST_AsMVT
。您还可以考虑加载一个大于视点的区域,并且仅在平移超出该区域时重复获取/更新循环。
您还可以缓存以前的获取操作,这样,如果用户向后平移已经加载的区域,您就不需要进行获取/更新。