在 Leaflet / Mapbox 中更新图层
Updating layers in 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);
有没有更好的方法?
没有理由为了将其添加到地图而经历构建 GeoJSON
对象的中间步骤。根据您的具体需要,您可以这样做:
tweets.forEach(function(t) {
L.marker(this.getGeoPoint(t)).addTo(map);
}, this);
您应该管理 tweets
对象,使其仅包含地图上不可见的点。删除所有旧标记,以便您可以再次添加它们,当然会很慢。
我会看一下 Leaflet Realtime:
Put realtime data on a Leaflet map: live tracking GPS units, sensor data or just about anything.
您可以通过传递一个 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,但我不知道额外的抽象层是否会对性能产生任何影响。
编辑:这是一个示例fiddle,展示了 .addData 方法的工作原理:
http://jsfiddle.net/nathansnider/4mwrwo0t/
如果你添加 10,000 个点,它确实会明显变慢,而对于 15,000 个点,它真的很慢,但我怀疑这与点的添加方式无关,而是渲染这么多 circleMarkers 的需求。
如果您还没有,您可能想尝试使用新的 Leaflet 1.0 beta, which redraws vector layers faster and is generally much more responsive with large datasets. Compare this 15,000-point example using Leaflet 0.7.5 to the same code using Leaflet 1.0.0b2。并非一切都是固定的(弹出窗口需要很长时间才能打开),但是尝试拖动地图时延迟时间的差异非常显着。
我正在尝试实时制作地图可视化,我不断通过 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);
有没有更好的方法?
没有理由为了将其添加到地图而经历构建 GeoJSON
对象的中间步骤。根据您的具体需要,您可以这样做:
tweets.forEach(function(t) {
L.marker(this.getGeoPoint(t)).addTo(map);
}, this);
您应该管理 tweets
对象,使其仅包含地图上不可见的点。删除所有旧标记,以便您可以再次添加它们,当然会很慢。
我会看一下 Leaflet Realtime:
Put realtime data on a Leaflet map: live tracking GPS units, sensor data or just about anything.
您可以通过传递一个 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,但我不知道额外的抽象层是否会对性能产生任何影响。
编辑:这是一个示例fiddle,展示了 .addData 方法的工作原理:
http://jsfiddle.net/nathansnider/4mwrwo0t/
如果你添加 10,000 个点,它确实会明显变慢,而对于 15,000 个点,它真的很慢,但我怀疑这与点的添加方式无关,而是渲染这么多 circleMarkers 的需求。
如果您还没有,您可能想尝试使用新的 Leaflet 1.0 beta, which redraws vector layers faster and is generally much more responsive with large datasets. Compare this 15,000-point example using Leaflet 0.7.5 to the same code using Leaflet 1.0.0b2。并非一切都是固定的(弹出窗口需要很长时间才能打开),但是尝试拖动地图时延迟时间的差异非常显着。