Reputation: 2812
According to the documentation I can pre-define the set of markers and other objects while creating the map, which then will be displayed. I do not wish to put all the possible markers/images/rectangles/etc in the JS code. I've read that people calculate the visible area on every tiles moving/zooming, do a HTTP request and server returns needed markers.
However, I would like to use another way, as it is a little more efficient:
1. For example, currently Leaflet automatically asks for the tiles 0:0 and 0:1;
2. In addition it could make a HTTP request and ask the server: "Hey, give me also the markers for the tiles 0:0 and 0:1".
3. Completely remove markers which are on the tiles which have become invisible.
Are the steps 2-3 possible and how if Yes?
Upvotes: 2
Views: 1349
Reputation: 19069
What you're asking looks pretty similar to how Leaflet.VectorGrid works: each "tile" request is a request for vector data, not for a raster image. In fact, perhaps using protobuffer vector tiles is the right approach for your scenario.
VectorGrid relies on the logic implemented by L.GridLayer
to handle the tile loading/unloading logic.
If you insist on doing this yourself, I suggest reading the Leaflet tutorials on creating plugins first; have a look to the source code for Leaflet's L.GridLayer
and for VectorGrid to see how those work, and then something like:
L.GridLayer.MarkerLoader = L.GridLayer.extend({
initialize: funcion(url, options) {
this._url = url;
this._markerStore = {};
L.GridLayer.prototype.initialize.call(this, options);
},
createTile: function(coords, done) {
var key = this._tileCoordsToKey(coords);
var data = {
s: this._getSubdomain(coords),
x: coords.x,
y: coords.y,
z: coords.z
};
var tileUrl = L.Util.template(this._url, L.extend(data, this.options));
fetch(tileUrl).then(function(response){
// Parse the response, with either response.json()
// or response.text() or response.blob().
// See https://developer.mozilla.org/en-US/docs/Web/API/Response
// Create a bunch of markers based on the parsed response
// The specific syntax depends on the format of the data structure
var markers = data.map(function(point){
return L.marker(point);
});
// Add those markers to a L.LayerGroup, add that LayerGroup
// to a dictionary (to remove it later), and finally add it to the map
var group = L.layerGroup(markers);
this._markerStore[key] = group;
// Mark the tile as ready
done();
});
// Return an empty <div> as a tile. Real data will be loaded async and
// put in LayerGroups anyway.
return L.DomUtil.createElement('div');
},
_removeTile: function(key) {
// Whenever a tile is pruned, remove the corresponding LayerGroup
// from the map and from the _markerStore dictionary
this._markerStore[key].remove();
delete this._markerStore[key];
return L.GridLayer.prototype._removeTile.call(this, key);
}
});
Upvotes: 3