With the prototype code below I'm adding a lot of features in steps into an osm. I'm loading about 8500 multipolygon features into it. Some of them have a lot of coordinates so that's round about 150MB of textual data in total. Loading them one by one leads to a crash of the browser. Loading it in chunks works but it is not fast either. Especially if you want to scroll or zoom after the loading has finished. I'm a bit shy about loading it all in one go as that's 150MB of data.
What options do I have to improve the experience? To be clear: I'm not talking about the loading itself. I'm talking about the rendering of the map with the features.
Here is the code stub:
addToMap = function (id, totalCount) {
var idTo = id+99;
jQuery.get('getData.php', {id: id, idTo: idTo}, function (result) {
var geojson;
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomToFeature
});
}
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
}
geojson = L.geoJson(result, {
style: getStyle,
onEachFeature: onEachFeature
}).addTo(map);
if (id < totalCount) {
jQuery('#count').html(idTo+' of '+totalCount);
addToMap(idTo+1, totalCount);
} else {
jQuery('#loader').remove();
}
}, 'json');
}
The secret to render a lot of stuff very very fast is... to not render a lot of stuff.
This might seem contradictory, but in reality it's very simple. You don't need to render everything, you just need to render:
By default, Leaflet does in fact simplify the vector geometries to save some time (douglas-peucker up to a couple of pixels), but it simplifies all the geometries (which is computationally expensive) and renders based only in the geometries' bounding boxes (which renders big geometries which are not visible, and renders all the points of big geometries for which only a tiny bit is visible).
Fortunately a couple of recent developments help with that: vector tiles and geojson-vt
. Do read https://www.mapbox.com/blog/introducing-geojson-vt/
The general idea is that the dataset is subject to a precomputation step (which takes a non-trivial amount of time but can be done off-thread), slicing the data up into tiles. Slicing in tiles means that only the visible part of big geometries will be shown, saving huge amounts of time. It will also run some line simplification, depending on the level of the tile pyramid.
These map tiles follow the same standard than raster tiles, so the visibility algorithms can be shared around.
To the best of my knowledge, there is only one working implementation of geojson-vt
and Leaflet: Leaflet.VectorGrid (or you can check the plugins list, which might contain more related plugins in the future). I suggest you have a look at it.
In addition to the other answers:
Convert your GeoJson to TopoJson to reduce the size of it. Here is one utility to do it - https://github.com/topojson/topojson
Based on your zoom level, display only parts of the features that are important or large enough. (as IvanSanchez wrote)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With