PageSourceSearch

https://www.ea2cw.eus/locator/js/L.Maidenhead.js

js ea2cw.eus collected 2026-10-06 13:15:03 UTC 5,316 bytes, 137 lines download raw bytes

1/*
2 * L.Maidenhead displays a Maidenhead Locator of lines on the map.
3 * original script found here  https://github.com/ha8tks/Leaflet.Maidenhead
4 * corrected for leaflet by TK5EP january 2026 to remove "wrong listener :undefined" error
5 */
6
7L.Maidenhead = L.LayerGroup.extend({
8    options: {
9        // Line and label color
10        color: 'rgba(0, 255, 0, 0.6)',
11        // Redraw on move or moveend
12        redraw: 'move'
13    },
14
15    initialize: function (options) {
16        L.LayerGroup.prototype.initialize.call(this);
17        L.Util.setOptions(this, options);
18    },
19
20    onAdd: function (map) {
21        this._map = map;
22
23        // Création d'une référence stable pour l'écouteur d'événements
24        this._viewChangeHandler = function () {
25            this.redraw();
26        }.bind(this);
27
28        // Ajout de l'écouteur sur la map
29        this._map.on('viewreset ' + this.options.redraw, this._viewChangeHandler);
30
31        this.redraw();
32    },
33
34    onRemove: function (map) {
35        // Suppression de l'écouteur avec la référence correcte
36        if (this._viewChangeHandler) {
37            this._map.off('viewreset ' + this.options.redraw, this._viewChangeHandler);
38        }
39        // Nettoyage de tous les calques (rectangles et labels)
40        this.clearLayers();
41    },
42
43    redraw: function () {
44        if (!this._map) return this;
45
46        var map = this._map;
47      var d3 =  new Array(20, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1 / 24, 1 / 24, 1 / 24, 1 / 24, 1 / 24, 1 / 240, 1 / 240, 1 / 240, 1 / 240, 1 / 240 / 24, 1 / 240 / 24);
48      var lat_cor = new Array(0, 8, 8, 8, 10, 14, 6, 8, 8, 8, 1.4, 2.5, 3, 3.5, 4, 4, 3.5, 3.5, 3, 1.8, 1.6);
49       // var d3 = new Array(20,10,10,10,10,10,1 ,1 ,1 ,1 ,1/24,1/24,1/24,1/24,1/24,1/240,1/240,1/240,1/240/24,1/240/24,1/240/24 );
50       // var lat_cor = new Array(0 ,8 ,8 ,8 ,10,14,6 ,8 ,8 ,8 ,1.4 ,2.5 ,3 ,3.5 ,4 ,4 ,3.5 ,3.5 ,1.47 ,1.8 ,1.6 );
51       
52        var bounds = map.getBounds();
53        var zoom = map.getZoom();
54        var unit = d3[zoom];
55        var lcor = lat_cor[zoom];
56        var w = bounds.getWest();
57        var e = bounds.getEast();
58        var n = bounds.getNorth();
59        var s = bounds.getSouth();
60        var c = (zoom == 1) ? 2 : 0.1;
61        
62        if (n > 85) n = 85;
63        if (s < -85) s = -85;
64
65        var left = Math.floor(w / (unit * 2)) * (unit * 2);
66        var right = Math.ceil(e / (unit * 2)) * (unit * 2);
67        var top = Math.ceil(n / unit) * unit;
68        var bottom = Math.floor(s / unit) * unit;
69
70        // On vide les anciens tracés avant de redessiner
71        this.clearLayers();
72
73        for (var lon = left; lon < right; lon += (unit * 2)) {
74            for (var lat = bottom; lat < top; lat += unit) {
75                var rectBounds = [[lat, lon], [lat + unit, lon + (unit * 2)]];
76                
77                // Ajout du rectangle
78                this.addLayer(L.rectangle(rectBounds, {
79                    color: this.options.color,
80                    weight: 1,
81                    fill: false,
82                    interactive: false
83                }));
84
85                // Ajout du label
86                this.addLayer(this._getLabel(lon + unit - (unit / lcor), lat + (unit / 2) + (unit / lcor * c)));
87            }
88        }
89        return this;
90    },
91
92    _getLabel: function (lon, lat) {
93        var title_size = new Array(0, 10, 12, 16, 20, 26, 12, 16, 24, 36, 12, 14, 20, 36, 60, 12, 20, 36, 60, 12, 24);
94        var zoom = this._map.getZoom();
95        var size = title_size[zoom] + 'px';
96        var title = '<span style="cursor: default;"><font style="color:' + this.options.color + '; font-size:' + size + '; font-weight: 400; ">' + this._getLocator(lon, lat) + '</font></span>';
97        var myIcon = L.divIcon({ className: 'my-div-icon', html: title });
98        var marker = L.marker([lat, lon], { icon: myIcon, interactive: false });
99        return marker;
100    },
101
102    _getLocator: function (lon, lat) {
103        var ydiv_arr = new Array(10, 1, 1 / 24, 1 / 240, 1 / 240 / 24);
104        var d1 = "ABCDEFGHIJKLMNOPQR".split("");
105        var d2 = "ABCDEFGHIJKLMNOPQRSTUVWX".split("");
106        var d4 = new Array(0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5);
107        
108        var locator = "";
109        var x = lon;
110        var y = lat;
111        var precision = d4[this._map.getZoom()];
112
113        while (x < -180) { x += 360; }
114        while (x > 180) { x -= 360; }
115        x = x + 180;
116        y = y + 90;
117
118        locator = locator + d1[Math.floor(x / 20)] + d1[Math.floor(y / 10)];
119
120        for (var i = 0; i < 4; i = i + 1) {
121            if (precision > i + 1) {
122                var rlon = x % (ydiv_arr[i] * 2);
123                var rlat = y % (ydiv_arr[i]);
124                if ((i % 2) == 0) {
125                    locator += Math.floor(rlon / (ydiv_arr[i + 1] * 2)) + "" + Math.floor(rlat / (ydiv_arr[i + 1]));
126                } else {
127                    locator += d2[Math.floor(rlon / (ydiv_arr[i + 1] * 2))] + "" + d2[Math.floor(rlat / (ydiv_arr[i + 1]))];
128                }
129            }
130        }
131        return locator;
132    }
133});
134
135L.maidenhead = function (options) {
136    return new L.Maidenhead(options);
137};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.