如何基于Leaflet.js上的可见切片加载/卸载标记?

时间:2018-05-31 19:58:41

标签: javascript leaflet

根据文档,我可以在创建地图时预先定义标记和其他对象集,然后显示。我不希望在JS代码中放置所有可能的标记/图像/矩形/等。我读过人们计算每个移动/缩放的瓷砖上的可见区域,做一个HTTP请求,服务器返回所需的标记。

但是,我想用另一种方式,因为它更有效:

1。例如,目前Leaflet会自动要求提示 0:0 0:1 ;

2。此外,它可以发出HTTP请求并询问服务器:“嘿,给我一些瓷砖标记 0:0 < / strong> 0:1 “。

3。完全删除瓷砖上已变得不可见的标记。

步骤2-3是否可行以及如果是?

1 个答案:

答案 0 :(得分:2)

您提出的问题与Leaflet.VectorGrid的工作方式非常相似:每个&#34; tile&#34;请求是矢量数据的请求,而不是光栅图像。实际上,也许使用protobuffer矢量切片是适用于您的场景的正确方法。

VectorGrid依赖L.GridLayer实现的逻辑来处理tile加载/卸载逻辑。

如果你坚持自己这样做,我建议先阅读Leaflet tutorials on creating plugins;查看Leaflet的L.GridLayer的源代码和VectorGrid,看看它们是如何工作的,然后是:

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(key);
    }
});