1. 程式人生 > >Leaflet 1.2 bug featureGroup 初始化問題

Leaflet 1.2 bug featureGroup 初始化問題

javascript leaflet grouplayer bug

最新項目在使用 Leaflet 做地圖,需要增加標註,意外發現,Leaflet竟然沒有良好的 label 功能,還好,Leaflet 的 Plugins 中有不少擴展。

最後選擇“Leaflet.LabelTextCollision”,demo采用的是 Leaflet version "1.0.1+ffcfcc1" 。當我把 Leaflet 換成 1.2.0 以後,

var p = L.polyline(
[ [ 35.695786, 139.749213 ],
[ 35.696786, 139.748213 ],
[ 35.695786, 139.747213 ] ], {
weight : 12,
color : '#fe57a1',
text : 'Leaflet.LabelTextCollision!!!!!!!!'
}).addTo(map);
var layers = L.featureGroup().addTo(map);
for ( var index in data) {
var d = data[index];
var latlng = L.latLng(d[0], d[1]);
var c = L.circleMarker(latlng, {
radius : 0,
text : latlng.toString()
});
layers.addLayer(c);
if (index == 3000) {
break;
}
}


其中“}).addTo(map);”和“layers.addLayer(c);”都會報錯,其中一個報錯截圖如下

技術分享圖片

定位問題到指定位置

技術分享圖片


後來,我從 Leaflet 的各個版本源碼頁找到了 1.01 和 1.2.0 的源碼,經比較,發現 1.0.1 中 canvas.js 的寫法

L.Canvas = L.Renderer.extend({
    onAdd: function () {
        L.Renderer.prototype.onAdd.call(this);
        this._layers = this._layers || {};
        // Redraw vectors since canvas is cleared upon removal,
        // in case of removing the renderer itself from the map.
        this._draw();
    },


在 1.2.0 中的 canvas.js 改為

export var Canvas = Renderer.extend({
    getEvents: function () {
        var events = Renderer.prototype.getEvents.call(this);
        events.viewprereset = this._onViewPreReset;
        return events;
    },
    _onViewPreReset: function () {
        // Set a flag so that a viewprereset+moveend+viewreset only updates&redraws once
        this._postponeUpdatePaths = true;
    },
    onAdd: function () {
        Renderer.prototype.onAdd.call(this);
        // Redraw vectors since canvas is cleared upon removal,
        // in case of removing the renderer itself from the map.
        this._draw();
    },

以及 Renderer.js 的

export var Renderer = Layer.extend({
    // @section
    // @aka Renderer options
    options: {
        // @option padding: Number = 0.1
        // How much to extend the clip area around the map view (relative to its size)
        // e.g. 0.1 would be 10% of map view in each direction
        padding: 0.1
    },
    initialize: function (options) {
        Util.setOptions(this, options);
        Util.stamp(this);
        this._layers = this._layers || {};
    },

所以問題就顯而易見 ,是在代碼重構的時候,將 this._layers 初始化提升到了父類初始化中,然而,Javascript 的編碼並不能保證初始化函數一定被調用,就比如我這次遇到的

var layers = L.featureGroup().addTo(map);

修改方案:

在 1.2.0 的 leaflet-src.js 文件的 11710 行,插入代碼

this._layers = this._layers || {};

即為

技術分享圖片


運行結果

技術分享圖片

至此,問題解決

Leaflet 1.2 bug featureGroup 初始化問題