Leaflet js - 内存泄漏访问 GeoJSON REST Api
Leaflet js - memory leak accessing GeoJSON REST Api
使用Leaflet,我需要刷新地图移动(平移、缩放)后显示的功能。
我访问 GeoJSON REST Api 因此:
function getFeatures( map, layer, table, user ) {
var bounds = map.getBounds();
var style = layer.module.spatial.style || undefined;
var params = {
geojson: true,
bbox: bounds.toBBoxString(),
srs: 'EPSG:4326',
limit: 200 // limit returned features
};
fetch ('api/organisations/' + user.organisation + '/objects/' + table + '?'
+ new URLSearchParams (params))
.then( response => response.json())
.then( data => {
layer.addData (data)
})
.catch( err => {
console.log("Fetch error on table " + table + ': ' + err);
});
}
export default function(options, map, L, user) {
var layer = L.geoJson(null, { /*... styling, popup ...*/ });
map.on('moveend', function(evt) {
var map = evt.target;
getFeatures(map, layer, options._id, user );
});
}
/*
* ... in calling script:
*/
map.addLayer(layer);
一切正常,但内存使用量(在 Chrome devtools 中测量)稳步上升,性能变差。
我想我需要释放一些东西,大概是在我的“moveend”处理程序中,但一直无法找到任何建议我应该做什么的例子。
我试过 map.removeLayer(layer)
和 map.addLayer(layer)
两边 layer.addData (data)
,这没什么区别。
怎么办?
正在检查 leaflet.js 文档,图层似乎有一个 remove
method。但是为了调用它,您可能需要获取对 geojson 图层对象的引用。所以也许像下面这样?
function getFeatures( map, layer, table, user ) {
var bounds = map.getBounds();
var style = layer.module.spatial.style || undefined;
var params = {
geojson: true,
bbox: bounds.toBBoxString(),
srs: 'EPSG:4326',
limit: 200 // limit returned features
};
fetch ('api/organisations/' + user.organisation + '/objects/' + table + '?'
+ new URLSearchParams (params))
.then( response => response.json())
.then( data => {
layer.addData (data)
})
.catch( err => {
console.log("Fetch error on table " + table + ': ' + err);
});
}
let layer // not a huge fan of using var, but I believe you can use var here if you insist
export default function(options, map, L, user) {
if (!!layer) {
layer.remove()
}
layer = L.geoJson(null, { /*... styling, popup ...*/ });
map.on('moveend', function(evt) {
var map = evt.target;
getFeatures(map, layer, options._id, user );
});
}
/*
* ... in calling script:
*/
map.addLayer(layer);
您可能需要做一些去抖动,因为 getFeatures
等是一个异步调用,您可能会遇到一些竞争条件恶作剧。
感谢@pandamakes 的回答,我的代码是这样结束的:
let layer;
function getFeatures( map, L, options, user ) { // Called on every map pan/zoom
var table = options._id;
if (!! layer) {
layer.remove();
}
if(options.spatial.geometry == 'polygon') {
layer = L.geoJson(null, {
style: function (feature) {
return feature.style || undefined;
},
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.plats_namn);
}
});
} else {
layer = L.geoJson(null, {
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng, feature.style || undefined);
},
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.art);
}
});
}
/*
* Set the module on the source for filtering
*/
layer.module = options;
layer.name = name;
var bounds = map.getBounds();
var style = layer.module.spatial.style || undefined;
var params = {
geojson: true,
bbox: bounds.toBBoxString(),
srs: 'EPSG:4326'
style: style,
limit: 200
};
fetch ('api/organisations/' + user.organisation + '/objects/' + table + '?'
+ new URLSearchParams (params))
.then( response => response.json())
.then( data => {
layer.addData (data)
map.addLayer(layer)
})
.catch( err => {
console.log("Fetch error on table " + table + ': ' + err);
});
}
export default function(options, map, L, user) {
map.on('moveend', function(evt) {
var map = evt.target;
getFeatures(map, L, options, user );
});
}
不满意,但内存泄漏消失了...
最好在每个 pan/zoom 上简单地删除图层上的现有功能;我将研究这样做的可能性。
使用Leaflet,我需要刷新地图移动(平移、缩放)后显示的功能。
我访问 GeoJSON REST Api 因此:
function getFeatures( map, layer, table, user ) {
var bounds = map.getBounds();
var style = layer.module.spatial.style || undefined;
var params = {
geojson: true,
bbox: bounds.toBBoxString(),
srs: 'EPSG:4326',
limit: 200 // limit returned features
};
fetch ('api/organisations/' + user.organisation + '/objects/' + table + '?'
+ new URLSearchParams (params))
.then( response => response.json())
.then( data => {
layer.addData (data)
})
.catch( err => {
console.log("Fetch error on table " + table + ': ' + err);
});
}
export default function(options, map, L, user) {
var layer = L.geoJson(null, { /*... styling, popup ...*/ });
map.on('moveend', function(evt) {
var map = evt.target;
getFeatures(map, layer, options._id, user );
});
}
/*
* ... in calling script:
*/
map.addLayer(layer);
一切正常,但内存使用量(在 Chrome devtools 中测量)稳步上升,性能变差。
我想我需要释放一些东西,大概是在我的“moveend”处理程序中,但一直无法找到任何建议我应该做什么的例子。
我试过 map.removeLayer(layer)
和 map.addLayer(layer)
两边 layer.addData (data)
,这没什么区别。
怎么办?
正在检查 leaflet.js 文档,图层似乎有一个 remove
method。但是为了调用它,您可能需要获取对 geojson 图层对象的引用。所以也许像下面这样?
function getFeatures( map, layer, table, user ) {
var bounds = map.getBounds();
var style = layer.module.spatial.style || undefined;
var params = {
geojson: true,
bbox: bounds.toBBoxString(),
srs: 'EPSG:4326',
limit: 200 // limit returned features
};
fetch ('api/organisations/' + user.organisation + '/objects/' + table + '?'
+ new URLSearchParams (params))
.then( response => response.json())
.then( data => {
layer.addData (data)
})
.catch( err => {
console.log("Fetch error on table " + table + ': ' + err);
});
}
let layer // not a huge fan of using var, but I believe you can use var here if you insist
export default function(options, map, L, user) {
if (!!layer) {
layer.remove()
}
layer = L.geoJson(null, { /*... styling, popup ...*/ });
map.on('moveend', function(evt) {
var map = evt.target;
getFeatures(map, layer, options._id, user );
});
}
/*
* ... in calling script:
*/
map.addLayer(layer);
您可能需要做一些去抖动,因为 getFeatures
等是一个异步调用,您可能会遇到一些竞争条件恶作剧。
感谢@pandamakes 的回答,我的代码是这样结束的:
let layer;
function getFeatures( map, L, options, user ) { // Called on every map pan/zoom
var table = options._id;
if (!! layer) {
layer.remove();
}
if(options.spatial.geometry == 'polygon') {
layer = L.geoJson(null, {
style: function (feature) {
return feature.style || undefined;
},
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.plats_namn);
}
});
} else {
layer = L.geoJson(null, {
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng, feature.style || undefined);
},
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.art);
}
});
}
/*
* Set the module on the source for filtering
*/
layer.module = options;
layer.name = name;
var bounds = map.getBounds();
var style = layer.module.spatial.style || undefined;
var params = {
geojson: true,
bbox: bounds.toBBoxString(),
srs: 'EPSG:4326'
style: style,
limit: 200
};
fetch ('api/organisations/' + user.organisation + '/objects/' + table + '?'
+ new URLSearchParams (params))
.then( response => response.json())
.then( data => {
layer.addData (data)
map.addLayer(layer)
})
.catch( err => {
console.log("Fetch error on table " + table + ': ' + err);
});
}
export default function(options, map, L, user) {
map.on('moveend', function(evt) {
var map = evt.target;
getFeatures(map, L, options, user );
});
}
不满意,但内存泄漏消失了...
最好在每个 pan/zoom 上简单地删除图层上的现有功能;我将研究这样做的可能性。