在Leaflet / Mapbox中更新图层

时间:2015-10-18 22:01:42

标签: leaflet mapbox

我试图实时制作地图可视化,我不断通过websockets获取新的点数。最初在地图上绘制这些标记似乎很简单,但我不确定在Mapbox上更新图层的正确方法是什么。

截至目前,每当我得到一个新点时,我会移除旧图层,创建一个新图层,然后将其添加到地图上。这种方法的问题在于它很慢并且对于大量的点(> 5000)它开始滞后。

    // remove layer
    if (this.pointsLayer != null) {
        map.removeLayer(this.pointsLayer);
    }

    // build geoJSON
    var geoJSON = { "type": "FeatureCollection", "features": [] };
    geoJSON["features"] = tweets.map(function(tweet) {
        return this.getGeoPoint(tweet);
    }.bind(this));

    // add geoJSON to layer
    this.pointsLayer = L.mapbox.featureLayer(geoJSON, {
        pointToLayer: function(feature, latlon) {
            return L.circleMarker(latlon,  {
                fillColor: '#AA5042',
                fillOpacity: 0.7,
                radius: 3,
                stroke: false
            });
        }
    }).addTo(map);

有更好的方法吗?

3 个答案:

答案 0 :(得分:2)

您可以通过传递false而不是真实数据来创建一个空的GeoJSON图层:

//create empty layer
this.pointsLayer = L.mapbox.featureLayer(false, {
    pointToLayer: function(feature, latlon) {
        return L.circleMarker(latlon,  {
            fillColor: '#AA5042',
            fillOpacity: 0.7,
            radius: 3,
            stroke: false
        });
    }
}).addTo(map);

然后使用.addData在新推文进来时更新它。例如:

// build geoJSON
var geoJSON = { "type": "FeatureCollection", "features": [] };
geoJSON["features"] = /**whatever function you use to build a single tweet's geoJSON**/

// add geoJSON to layer
this.pointsLayer.addData(geoJSON);

对于一条推文,我想你可以创建一个Feature而不是FeatureCollection,但我不知道这个额外的抽象层是否会对性能产生任何影响。

编辑:以下是显示工作中的.addData方法的示例:

http://jsfiddle.net/nathansnider/4mwrwo0t/

如果你增加10,000点,它确实会明显减慢,而对于15,000点来说,它确实很迟钝,但我怀疑与添加点的方式关系不大,因为需要渲染这么多circleMarkers。

如果您还没有,可能需要尝试使用新的Leaflet 1.0 beta,它可以更快地重绘矢量图层,并且通常对大型数据集的响应速度更快。将此15,000点示例using Leaflet 0.7.5与相同代码using Leaflet 1.0.0b2进行比较。并非一切都是固定的(弹出窗口需要花费很长时间才能打开),但尝试拖动地图时滞后时间的差异非常大。

答案 1 :(得分:1)

没有理由通过构建GeoJSON对象的中间步骤,只需将其添加到地图中即可。根据您的具体需求,您可以执行以下操作:

tweets.forEach(function(t) {
    L.marker(this.getGeoPoint(t)).addTo(map);
}, this);

您应该管理tweets对象,使其仅包含地图上尚未显示的点。删除所有旧标记,只是为了再次添加它们,当然会非常慢。

答案 2 :(得分:1)

我会看一下Leaflet Realtime:

  

将实时数据放在传单地图上:实时跟踪GPS单位,传感器数据或几乎所有内容。

https://github.com/perliedman/leaflet-realtime