PageSourceSearch

https://transformap.co/vendor/PruneCluster/PruneCluster.js

js transformap.co collected 2026-10-03 19:28:07 UTC 41,150 bytes, 947 lines download raw bytes

1var __extends = (this && this.__extends) || function (d, b) {
2    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
3    function __() { this.constructor = d; }
4    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5};
6var PruneCluster;
7(function (PruneCluster_1) {
8    var Point = (function () {
9        function Point() {
10        }
11        return Point;
12    })();
13    PruneCluster_1.Point = Point;
14    var ClusterObject = (function () {
15        function ClusterObject() {
16        }
17        return ClusterObject;
18    })();
19    PruneCluster_1.ClusterObject = ClusterObject;
20    var hashCodeCounter = 1;
21    var maxHashCodeValue = Math.pow(2, 53) - 1;
22    var Marker = (function (_super) {
23        __extends(Marker, _super);
24        function Marker(lat, lng, data, category, weight, filtered) {
25            if (data === void 0) { data = {}; }
26            if (weight === void 0) { weight = 1; }
27            if (filtered === void 0) { filtered = false; }
28            _super.call(this);
29            this.data = data;
30            this.position = { lat: +lat, lng: +lng };
31            this.weight = weight;
32            this.category = category;
33            this.filtered = filtered;
34            this.hashCode = hashCodeCounter++;
35        }
36        Marker.prototype.Move = function (lat, lng) {
37            this.position.lat = +lat;
38            this.position.lng = +lng;
39        };
40        Marker.prototype.SetData = function (data) {
41            for (var key in data) {
42                this.data[key] = data[key];
43            }
44        };
45        return Marker;
46    })(ClusterObject);
47    PruneCluster_1.Marker = Marker;
48    var Cluster = (function (_super) {
49        __extends(Cluster, _super);
50        function Cluster(marker) {
51            _super.call(this);
52            this.stats = [0, 0, 0, 0, 0, 0, 0, 0];
53            this.data = {};
54            if (!marker) {
55                this.hashCode = 1;
56                if (Cluster.ENABLE_MARKERS_LIST) {
57                    this._clusterMarkers = [];
58                }
59                return;
60            }
61            if (Cluster.ENABLE_MARKERS_LIST) {
62                this._clusterMarkers = [marker];
63            }
64            this.lastMarker = marker;
65            this.hashCode = 31 + marker.hashCode;
66            this.population = 1;
67            if (marker.category !== undefined) {
68                this.stats[marker.category] = 1;
69            }
70            this.totalWeight = marker.weight;
71            this.position = {
72                lat: marker.position.lat,
73                lng: marker.position.lng
74            };
75            this.averagePosition = {
76                lat: marker.position.lat,
77                lng: marker.position.lng
78            };
79        }
80        Cluster.prototype.AddMarker = function (marker) {
81            if (Cluster.ENABLE_MARKERS_LIST) {
82                this._clusterMarkers.push(marker);
83            }
84            var h = this.hashCode;
85            h = ((h << 5) - h) + marker.hashCode;
86            if (h >= maxHashCodeValue) {
87                this.hashCode = h % maxHashCodeValue;
88            }
89            else {
90                this.hashCode = h;
91            }
92            this.lastMarker = marker;
93            var weight = marker.weight, currentTotalWeight = this.totalWeight, newWeight = weight + currentTotalWeight;
94            this.averagePosition.lat =
95                (this.averagePosition.lat * currentTotalWeight +
96                    marker.position.lat * weight) / newWeight;
97            this.averagePosition.lng =
98                (this.averagePosition.lng * currentTotalWeight +
99                    marker.position.lng * weight) / newWeight;
100            ++this.population;
101            this.totalWeight = newWeight;
102            if (marker.category !== undefined) {
103                this.stats[marker.category] = (this.stats[marker.category] + 1) || 1;
104            }
105        };
106        Cluster.prototype.Reset = function () {
107            this.hashCode = 1;
108            this.lastMarker = undefined;
109            this.population = 0;
110            this.totalWeight = 0;
111            this.stats = [0, 0, 0, 0, 0, 0, 0, 0];
112            if (Cluster.ENABLE_MARKERS_LIST) {
113                this._clusterMarkers = [];
114            }
115        };
116        Cluster.prototype.ComputeBounds = function (cluster) {
117            var proj = cluster.Project(this.position.lat, this.position.lng);
118            var size = cluster.Size;
119            var nbX = Math.floor(proj.x / size), nbY = Math.floor(proj.y / size), startX = nbX * size, startY = nbY * size;
120            var a = cluster.UnProject(startX, startY), b = cluster.UnProject(startX + size, startY + size);
121            this.bounds = {
122                minLat: b.lat,
123                maxLat: a.lat,
124                minLng: a.lng,
125                maxLng: b.lng
126            };
127        };
128        Cluster.prototype.GetClusterMarkers = function () {
129            return this._clusterMarkers;
130        };
131        Cluster.prototype.ApplyCluster = function (newCluster) {
132            this.hashCode = this.hashCode * 41 + newCluster.hashCode * 43;
133            if (this.hashCode > maxHashCodeValue) {
134                this.hashCode = this.hashCode = maxHashCodeValue;
135            }
136            var weight = newCluster.totalWeight, currentTotalWeight = this.totalWeight, newWeight = weight + currentTotalWeight;
137            this.averagePosition.lat =
138                (this.averagePosition.lat * currentTotalWeight +
139                    newCluster.averagePosition.lat * weight) / newWeight;
140            this.averagePosition.lng =
141                (this.averagePosition.lng * currentTotalWeight +
142                    newCluster.averagePosition.lng * weight) / newWeight;
143            this.population += newCluster.population;
144            this.totalWeight = newWeight;
145            this.bounds.minLat = Math.min(this.bounds.minLat, newCluster.bounds.minLat);
146            this.bounds.minLng = Math.min(this.bounds.minLng, newCluster.bounds.minLng);
147            this.bounds.maxLat = Math.max(this.bounds.maxLat, newCluster.bounds.maxLat);
148            this.bounds.maxLng = Math.max(this.bounds.maxLng, newCluster.bounds.maxLng);
149            for (var category in newCluster.stats) {
150                if (newCluster.stats.hasOwnProperty(category)) {
151                    if (this.stats.hasOwnProperty(category)) {
152                        this.stats[category] += newCluster.stats[category];
153                    }
154                    else {
155                        this.stats[category] = newCluster.stats[category];
156                    }
157                }
158            }
159            if (Cluster.ENABLE_MARKERS_LIST) {
160                this._clusterMarkers = this._clusterMarkers.concat(newCluster.GetClusterMarkers());
161            }
162        };
163        Cluster.ENABLE_MARKERS_LIST = false;
164        return Cluster;
165    })(ClusterObject);
166    PruneCluster_1.Cluster = Cluster;
167    function checkPositionInsideBounds(a, b) {
168        return (a.lat >= b.minLat && a.lat <= b.maxLat) &&
169            a.lng >= b.minLng && a.lng <= b.maxLng;
170    }
171    function insertionSort(list) {
172        for (var i = 1, j, tmp, tmpLng, length = list.length; i < length; ++i) {
173            tmp = list[i];
174            tmpLng = tmp.position.lng;
175            for (j = i - 1; j >= 0 && list[j].position.lng > tmpLng; --j) {
176                list[j + 1] = list[j];
177            }
178            list[j + 1] = tmp;
179        }
180    }
181    function shouldUseInsertionSort(total, nbChanges) {
182        if (nbChanges > 300) {
183            return false;
184        }
185        else {
186            return (nbChanges / total) < 0.2;
187        }
188    }
189    var PruneCluster = (function () {
190        function PruneCluster() {
191            this._markers = [];
192            this._nbChanges = 0;
193            this._clusters = [];
194            this.Size = 166;
195            this.ViewPadding = 0.2;
196        }
197        PruneCluster.prototype.RegisterMarker = function (marker) {
198            if (marker._removeFlag) {
199                delete marker._removeFlag;
200            }
201            this._markers.push(marker);
202            this._nbChanges += 1;
203        };
204        PruneCluster.prototype.RegisterMarkers = function (markers) {
205            var _this = this;
206            markers.forEach(function (marker) {
207                _this.RegisterMarker(marker);
208            });
209        };
210        PruneCluster.prototype._sortMarkers = function () {
211            var markers = this._markers, length = markers.length;
212            if (this._nbChanges && !shouldUseInsertionSort(length, this._nbChanges)) {
213                this._markers.sort(function (a, b) { return a.position.lng - b.position.lng; });
214            }
215            else {
216                insertionSort(markers);
217            }
218            this._nbChanges = 0;
219        };
220        PruneCluster.prototype._sortClusters = function () {
221            insertionSort(this._clusters);
222        };
223        PruneCluster.prototype._indexLowerBoundLng = function (lng) {
224            var markers = this._markers, it, step, first = 0, count = markers.length;
225            while (count > 0) {
226                step = Math.floor(count / 2);
227                it = first + step;
228                if (markers[it].position.lng < lng) {
229                    first = ++it;
230                    count -= step + 1;
231                }
232                else {
233                    count = step;
234                }
235            }
236            return first;
237        };
238        PruneCluster.prototype._resetClusterViews = function () {
239            for (var i = 0, l = this._clusters.length; i < l; ++i) {
240                var cluster = this._clusters[i];
241                cluster.Reset();
242                cluster.ComputeBounds(this);
243            }
244        };
245        PruneCluster.prototype.ProcessView = function (bounds) {
246            var heightBuffer = Math.abs(bounds.maxLat - bounds.minLat) * this.ViewPadding, widthBuffer = Math.abs(bounds.maxLng - bounds.minLng) * this.ViewPadding;
247            var extendedBounds = {
248                minLat: bounds.minLat - heightBuffer - heightBuffer,
249                maxLat: bounds.maxLat + heightBuffer + heightBuffer,
250                minLng: bounds.minLng - widthBuffer - widthBuffer,
251                maxLng: bounds.maxLng + widthBuffer + widthBuffer
252            };
253            this._sortMarkers();
254            this._resetClusterViews();
255            var firstIndex = this._indexLowerBoundLng(extendedBounds.minLng);
256            var markers = this._markers, clusters = this._clusters;
257            var workingClusterList = clusters.slice(0);
258            for (var i = firstIndex, l = markers.length; i < l; ++i) {
259                var marker = markers[i], markerPosition = marker.position;
260                if (markerPosition.lng > extendedBounds.maxLng) {
261                    break;
262                }
263                if (markerPosition.lat > extendedBounds.minLat &&
264                    markerPosition.lat < extendedBounds.maxLat &&
265                    !marker.filtered) {
266                    var clusterFound = false, cluster;
267                    for (var j = 0, ll = workingClusterList.length; j < ll; ++j) {
268                        cluster = workingClusterList[j];
269                        if (cluster.bounds.maxLng < marker.position.lng) {
270                            workingClusterList.splice(j, 1);
271                            --j;
272                            --ll;
273                            continue;
274                        }
275                        if (checkPositionInsideBounds(markerPosition, cluster.bounds)) {
276                            cluster.AddMarker(marker);
277                            clusterFound = true;
278                            break;
279                        }
280                    }
281                    if (!clusterFound) {
282                        cluster = new Cluster(marker);
283                        cluster.ComputeBounds(this);
284                        clusters.push(cluster);
285                        workingClusterList.push(cluster);
286                    }
287                }
288            }
289            var newClustersList = [];
290            for (i = 0, l = clusters.length; i < l; ++i) {
291                cluster = clusters[i];
292                if (cluster.population > 0) {
293                    newClustersList.push(cluster);
294                }
295            }
296            this._clusters = newClustersList;
297            this._sortClusters();
298            return this._clusters;
299        };
300        PruneCluster.prototype.RemoveMarkers = function (markers) {
301            if (!markers) {
302                this._markers = [];
303                return;
304            }
305            for (var i = 0, l = markers.length; i < l; ++i) {
306                markers[i]._removeFlag = true;
307            }
308            var newMarkersList = [];
309            for (i = 0, l = this._markers.length; i < l; ++i) {
310                if (!this._markers[i]._removeFlag) {
311                    newMarkersList.push(this._markers[i]);
312                }
313                else {
314                    delete this._markers[i]._removeFlag;
315                }
316            }
317            this._markers = newMarkersList;
318        };
319        PruneCluster.prototype.FindMarkersInArea = function (area) {
320            var aMinLat = area.minLat, aMaxLat = area.maxLat, aMinLng = area.minLng, aMaxLng = area.maxLng, markers = this._markers, result = [];
321            var firstIndex = this._indexLowerBoundLng(aMinLng);
322            for (var i = firstIndex, l = markers.length; i < l; ++i) {
323                var pos = markers[i].position;
324                if (pos.lng > aMaxLng) {
325                    break;
326                }
327                if (pos.lat >= aMinLat && pos.lat <= aMaxLat &&
328                    pos.lng >= aMinLng) {
329                    result.push(markers[i]);
330                }
331            }
332            return result;
333        };
334        PruneCluster.prototype.ComputeBounds = function (markers, withFiltered) {
335            if (withFiltered === void 0) { withFiltered = true; }
336            if (!markers || !markers.length) {
337                return null;
338            }
339            var rMinLat = Number.MAX_VALUE, rMaxLat = -Number.MAX_VALUE, rMinLng = Number.MAX_VALUE, rMaxLng = -Number.MAX_VALUE;
340            for (var i = 0, l = markers.length; i < l; ++i) {
341                if (!withFiltered && markers[i].filtered) {
342                    continue;
343                }
344                var pos = markers[i].position;
345                if (pos.lat < rMinLat)
346                    rMinLat = pos.lat;
347                if (pos.lat > rMaxLat)
348                    rMaxLat = pos.lat;
349                if (pos.lng < rMinLng)
350                    rMinLng = pos.lng;
351                if (pos.lng > rMaxLng)
352                    rMaxLng = pos.lng;
353            }
354            return {
355                minLat: rMinLat,
356                maxLat: rMaxLat,
357                minLng: rMinLng,
358                maxLng: rMaxLng
359            };
360        };
361        PruneCluster.prototype.FindMarkersBoundsInArea = function (area) {
362            return this.ComputeBounds(this.FindMarkersInArea(area));
363        };
364        PruneCluster.prototype.ComputeGlobalBounds = function (withFiltered) {
365            if (withFiltered === void 0) { withFiltered = true; }
366            return this.ComputeBounds(this._markers, withFiltered);
367        };
368        PruneCluster.prototype.GetMarkers = function () {
369            return this._markers;
370        };
371        PruneCluster.prototype.GetPopulation = function () {
372            return this._markers.length;
373        };
374        PruneCluster.prototype.ResetClusters = function () {
375            this._clusters = [];
376        };
377        return PruneCluster;
378    })();
379    PruneCluster_1.PruneCluster = PruneCluster;
380})(PruneCluster || (PruneCluster = {}));
381var PruneCluster;
382(function (PruneCluster) {
383})(PruneCluster || (PruneCluster = {}));
384var PruneClusterForLeaflet = (L.Layer ? L.Layer : L.Class).extend({
385    initialize: function (size, clusterMargin) {
386        var _this = this;
387        if (size === void 0) { size = 120; }
388        if (clusterMargin === void 0) { clusterMargin = 20; }
389        this.Cluster = new PruneCluster.PruneCluster();
390        this.Cluster.Size = size;
391        this.clusterMargin = Math.min(clusterMargin, size / 4);
392        this.Cluster.Project = function (lat, lng) {
393            return _this._map.project(new L.LatLng(lat, lng), Math.floor(_this._map.getZoom()));
394        };
395        this.Cluster.UnProject = function (x, y) {
396            return _this._map.unproject(new L.Point(x, y), Math.floor(_this._map.getZoom()));
397        };
398        this._objectsOnMap = [];
399        this.spiderfier = new PruneClusterLeafletSpiderfier(this);
400        this._hardMove = false;
401        this._resetIcons = false;
402        this._removeTimeoutId = 0;
403        this._markersRemoveListTimeout = [];
404    },
405    RegisterMarker: function (marker) {
406        this.Cluster.RegisterMarker(marker);
407    },
408    RegisterMarkers: function (markers) {
409        this.Cluster.RegisterMarkers(markers);
410    },
411    RemoveMarkers: function (markers) {
412        this.Cluster.RemoveMarkers(markers);
413    },
414    BuildLeafletCluster: function (cluster, position) {
415        var _this = this;
416        var m = new L.Marker(position, {
417            icon: this.BuildLeafletClusterIcon(cluster)
418        });
419        m._leafletClusterBounds = cluster.bounds;
420        m.on('click', function () {
421            var cbounds = m._leafletClusterBounds;
422            var markersArea = _this.Cluster.FindMarkersInArea(cbounds);
423            var b = _this.Cluster.ComputeBounds(markersArea);
424            if (b) {
425                var bounds = new L.LatLngBounds(new L.LatLng(b.minLat, b.maxLng), new L.LatLng(b.maxLat, b.minLng));
426                var zoomLevelBefore = _this._map.getZoom(), zoomLevelAfter = _this._map.getBoundsZoom(bounds, false, new L.Point(20, 20));
427                if (zoomLevelAfter === zoomLevelBefore) {
428                    var filteredBounds = [];
429                    for (var i = 0, l = _this._objectsOnMap.length; i < l; ++i) {
430                        var o = _this._objectsOnMap[i];
431                        if (o.data._leafletMarker !== m) {
432                            if (o.bounds.minLat >= cbounds.minLat &&
433                                o.bounds.maxLat <= cbounds.maxLat &&
434                                o.bounds.minLng >= cbounds.minLng &&
435                                o.bounds.maxLng <= cbounds.maxLng) {
436                                filteredBounds.push(o.bounds);
437                            }
438                        }
439                    }
440                    if (filteredBounds.length > 0) {
441                        var newMarkersArea = [];
442                        var ll = filteredBounds.length;
443                        for (i = 0, l = markersArea.length; i < l; ++i) {
444                            var markerPos = markersArea[i].position;
445                            var isFiltered = false;
446                            for (var j = 0; j < ll; ++j) {
447                                var currentFilteredBounds = filteredBounds[j];
448                                if (markerPos.lat >= currentFilteredBounds.minLat &&
449                                    markerPos.lat <= currentFilteredBounds.maxLat &&
450                                    markerPos.lng >= currentFilteredBounds.minLng &&
451                                    markerPos.lng <= currentFilteredBounds.maxLng) {
452                                    isFiltered = true;
453                                    break;
454                                }
455                            }
456                            if (!isFiltered) {
457                                newMarkersArea.push(markersArea[i]);
458                            }
459                        }
460                        markersArea = newMarkersArea;
461                    }
462                    if (markersArea.length < 200) {
463                        _this._map.fire('overlappingmarkers', {
464                            cluster: _this,
465                            markers: markersArea,
466                            center: m.getLatLng(),
467                            marker: m
468                        });
469                    }
470                    else if (zoomLevelAfter < _this._map.getMaxZoom()) {
471                        zoomLevelAfter++;
472                    }
473                    _this._map.setView(m.getLatLng(), zoomLevelAfter);
474                }
475                else {
476                    _this._map.fitBounds(bounds);
477                }
478            }
479        });
480        return m;
481    },
482    BuildLeafletClusterIcon: function (cluster) {
483        var c = 'prunecluster prunecluster-';
484        var iconSize = 38;
485        var maxPopulation = this.Cluster.GetPopulation();
486        if (cluster.population < Math.max(10, maxPopulation * 0.01)) {
487            c += 'small';
488        }
489        else if (cluster.population < Math.max(100, maxPopulation * 0.05)) {
490            c += 'medium';
491            iconSize = 40;
492        }
493        else {
494            c += 'large';
495            iconSize = 44;
496        }
497        return new L.DivIcon({
498            html: "<div><span>" + cluster.population + "</span></div>",
499            className: c,
500            iconSize: L.point(iconSize, iconSize)
501        });
502    },
503    BuildLeafletMarker: function (marker, position) {
504        var m = new L.Marker(position);
505        this.PrepareLeafletMarker(m, marker.data, marker.category);
506        return m;
507    },
508    PrepareLeafletMarker: function (marker, data, category) {
509        if (data.icon) {
510            if (typeof data.icon === 'function') {
511                marker.setIcon(data.icon(data, category));
512            }
513            else {
514                marker.setIcon(data.icon);
515            }
516        }
517        if (data.popup) {
518            var content = typeof data.popup === 'function' ? data.popup(data, category) : data.popup;
519            if (marker.getPopup()) {
520                marker.setPopupContent(content, data.popupOptions);
521            }
522            else {
523                marker.bindPopup(content, data.popupOptions);
524            }
525        }
526    },
527    onAdd: function (map) {
528        this._map = map;
529        map.on('movestart', this._moveStart, this);
530        map.on('moveend', this._moveEnd, this);
531        map.on('zoomend', this._zoomStart, this);
532        map.on('zoomend', this._zoomEnd, this);
533        this.ProcessView();
534        map.addLayer(this.spiderfier);
535    },
536    onRemove: function (map) {
537        map.off('movestart', this._moveStart, this);
538        map.off('moveend', this._moveEnd, this);
539        map.off('zoomend', this._zoomStart, this);
540        map.off('zoomend', this._zoomEnd, this);
541        for (var i = 0, l = this._objectsOnMap.length; i < l; ++i) {
542            map.removeLayer(this._objectsOnMap[i].data._leafletMarker);
543        }
544        this._objectsOnMap = [];
545        this.Cluster.ResetClusters();
546        map.removeLayer(this.spiderfier);
547        this._map = null;
548    },
549    _moveStart: function () {
550        this._moveInProgress = true;
551    },
552    _moveEnd: function (e) {
553        this._moveInProgress = false;
554        this._hardMove = e.hard;
555        this.ProcessView();
556    },
557    _zoomStart: function () {
558        this._zoomInProgress = true;
559    },
560    _zoomEnd: function () {
561        this._zoomInProgress = false;
562        this.ProcessView();
563    },
564    ProcessView: function () {
565        var _this = this;
566        if (!this._map || this._zoomInProgress || this._moveInProgress) {
567            return;
568        }
569        var map = this._map, bounds = map.getBounds(), zoom = Math.floor(map.getZoom()), marginRatio = this.clusterMargin / this.Cluster.Size, resetIcons = this._resetIcons;
570        var southWest = bounds.getSouthWest(), northEast = bounds.getNorthEast();
571        var clusters = this.Cluster.ProcessView({
572            minLat: southWest.lat,
573            minLng: southWest.lng,
574            maxLat: northEast.lat,
575            maxLng: northEast.lng
576        });
577        var objectsOnMap = this._objectsOnMap, newObjectsOnMap = [], markersOnMap = new Array(objectsOnMap.length);
578        for (var i = 0, l = objectsOnMap.length; i < l; ++i) {
579            var marker = objectsOnMap[i].data._leafletMarker;
580            markersOnMap[i] = marker;
581            marker._removeFromMap = true;
582        }
583        var clusterCreationList = [];
584        var clusterCreationListPopOne = [];
585        var opacityUpdateList = [];
586        var workingList = [];
587        for (i = 0, l = clusters.length; i < l; ++i) {
588            var icluster = clusters[i], iclusterData = icluster.data;
589            var latMargin = (icluster.bounds.maxLat - icluster.bounds.minLat) * marginRatio, lngMargin = (icluster.bounds.maxLng - icluster.bounds.minLng) * marginRatio;
590            for (var j = 0, ll = workingList.length; j < ll; ++j) {
591                var c = workingList[j];
592                if (c.bounds.maxLng < icluster.bounds.minLng) {
593                    workingList.splice(j, 1);
594                    --j;
595                    --ll;
596                    continue;
597                }
598                var oldMaxLng = c.averagePosition.lng + lngMargin, oldMinLat = c.averagePosition.lat - latMargin, oldMaxLat = c.averagePosition.lat + latMargin, newMinLng = icluster.averagePosition.lng - lngMargin, newMinLat = icluster.averagePosition.lat - latMargin, newMaxLat = icluster.averagePosition.lat + latMargin;
599                if (oldMaxLng > newMinLng && oldMaxLat > newMinLat && oldMinLat < newMaxLat) {
600                    iclusterData._leafletCollision = true;
601                    c.ApplyCluster(icluster);
602                    break;
603                }
604            }
605            if (!iclusterData._leafletCollision) {
606                workingList.push(icluster);
607            }
608        }
609        clusters.forEach(function (cluster) {
610            var m = undefined;
611            var data = cluster.data;
612            if (data._leafletCollision) {
613                data._leafletCollision = false;
614                data._leafletOldPopulation = 0;
615                data._leafletOldHashCode = 0;
616                return;
617            }
618            var position = new L.LatLng(cluster.averagePosition.lat, cluster.averagePosition.lng);
619            var oldMarker = data._leafletMarker;
620            if (oldMarker) {
621                if (cluster.population === 1 && data._leafletOldPopulation === 1 && cluster.hashCode === oldMarker._hashCode) {
622                    if (resetIcons || oldMarker._zoomLevel !== zoom || cluster.lastMarker.data.forceIconRedraw) {
623                        _this.PrepareLeafletMarker(oldMarker, cluster.lastMarker.data, cluster.lastMarker.category);
624                        if (cluster.lastMarker.data.forceIconRedraw) {
625                            cluster.lastMarker.data.forceIconRedraw = false;
626                        }
627                    }
628                    oldMarker.setLatLng(position);
629                    m = oldMarker;
630                }
631                else if (cluster.population > 1 && data._leafletOldPopulation > 1 && (oldMarker._zoomLevel === zoom ||
632                    data._leafletPosition.equals(position))) {
633                    oldMarker.setLatLng(position);
634                    if (resetIcons || cluster.population != data._leafletOldPopulation ||
635                        cluster.hashCode !== data._leafletOldHashCode) {
636                        var boundsCopy = {};
637                        L.Util.extend(boundsCopy, cluster.bounds);
638                        oldMarker._leafletClusterBounds = boundsCopy;
639                        oldMarker.setIcon(_this.BuildLeafletClusterIcon(cluster));
640                    }
641                    data._leafletOldPopulation = cluster.population;
642                    data._leafletOldHashCode = cluster.hashCode;
643                    m = oldMarker;
644                }
645            }
646            if (!m) {
647                if (cluster.population === 1) {
648                    clusterCreationListPopOne.push(cluster);
649                }
650                else {
651                    clusterCreationList.push(cluster);
652                }
653                data._leafletPosition = position;
654                data._leafletOldPopulation = cluster.population;
655                data._leafletOldHashCode = cluster.hashCode;
656            }
657            else {
658                m._removeFromMap = false;
659                newObjectsOnMap.push(cluster);
660                m._zoomLevel = zoom;
661                m._hashCode = cluster.hashCode;
662                m._population = cluster.population;
663                data._leafletMarker = m;
664                data._leafletPosition = position;
665            }
666        });
667        clusterCreationList = clusterCreationListPopOne.concat(clusterCreationList);
668        for (i = 0, l = objectsOnMap.length; i < l; ++i) {
669            icluster = objectsOnMap[i];
670            var idata = icluster.data;
671            marker = idata._leafletMarker;
672            if (idata._leafletMarker._removeFromMap) {
673                var remove = true;
674                if (marker._zoomLevel === zoom) {
675                    var pa = icluster.averagePosition;
676                    latMargin = (icluster.bounds.maxLat - icluster.bounds.minLat) * marginRatio,
677                        lngMargin = (icluster.bounds.maxLng - icluster.bounds.minLng) * marginRatio;
678                    for (j = 0, ll = clusterCreationList.length; j < ll; ++j) {
679                        var jcluster = clusterCreationList[j], jdata = jcluster.data;
680                        if (marker._population === 1 && jcluster.population === 1 &&
681                            marker._hashCode === jcluster.hashCode) {
682                            if (resetIcons || jcluster.lastMarker.data.forceIconRedraw) {
683                                this.PrepareLeafletMarker(marker, jcluster.lastMarker.data, jcluster.lastMarker.category);
684                                if (jcluster.lastMarker.data.forceIconRedraw) {
685                                    jcluster.lastMarker.data.forceIconRedraw = false;
686                                }
687                            }
688                            marker.setLatLng(jdata._leafletPosition);
689                            remove = false;
690                        }
691                        else {
692                            var pb = jcluster.averagePosition;
693                            var oldMinLng = pa.lng - lngMargin, newMaxLng = pb.lng + lngMargin;
694                            oldMaxLng = pa.lng + lngMargin;
695                            oldMinLat = pa.lat - latMargin;
696                            oldMaxLat = pa.lat + latMargin;
697                            newMinLng = pb.lng - lngMargin;
698                            newMinLat = pb.lat - latMargin;
699                            newMaxLat = pb.lat + latMargin;
700                            if ((marker._population > 1 && jcluster.population > 1) &&
701                                (oldMaxLng > newMinLng && oldMinLng < newMaxLng && oldMaxLat > newMinLat && oldMinLat < newMaxLat)) {
702                                marker.setLatLng(jdata._leafletPosition);
703                                marker.setIcon(this.BuildLeafletClusterIcon(jcluster));
704                                var poisson = {};
705                                L.Util.extend(poisson, jcluster.bounds);
706                                marker._leafletClusterBounds = poisson;
707                                jdata._leafletOldPopulation = jcluster.population;
708                                jdata._leafletOldHashCode = jcluster.hashCode;
709                                marker._population = jcluster.population;
710                                remove = false;
711                            }
712                        }
713                        if (!remove) {
714                            jdata._leafletMarker = marker;
715                            marker._removeFromMap = false;
716                            newObjectsOnMap.push(jcluster);
717                            clusterCreationList.splice(j, 1);
718                            --j;
719                            --ll;
720                            break;
721                        }
722                    }
723                }
724                if (remove) {
725                    if (!marker._removeFromMap)
726                        console.error("wtf");
727                }
728            }
729        }
730        for (i = 0, l = clusterCreationList.length; i < l; ++i) {
731            icluster = clusterCreationList[i],
732                idata = icluster.data;
733            var iposition = idata._leafletPosition;
734            var creationMarker;
735            if (icluster.population === 1) {
736                creationMarker = this.BuildLeafletMarker(icluster.lastMarker, iposition);
737            }
738            else {
739                creationMarker = this.BuildLeafletCluster(icluster, iposition);
740            }
741            creationMarker.addTo(map);
742            creationMarker.setOpacity(0);
743            opacityUpdateList.push(creationMarker);
744            idata._leafletMarker = creationMarker;
745            creationMarker._zoomLevel = zoom;
746            creationMarker._hashCode = icluster.hashCode;
747            creationMarker._population = icluster.population;
748            newObjectsOnMap.push(icluster);
749        }
750        window.setTimeout(function () {
751            for (i = 0, l = opacityUpdateList.length; i < l; ++i) {
752                var m = opacityUpdateList[i];
753                if (m._icon)
754                    L.DomUtil.addClass(m._icon, "prunecluster-anim");
755                if (m._shadow)
756                    L.DomUtil.addClass(m._shadow, "prunecluster-anim");
757                m.setOpacity(1);
758            }
759        }, 1);
760        if (this._hardMove) {
761            for (i = 0, l = markersOnMap.length; i < l; ++i) {
762                marker = markersOnMap[i];
763                if (marker._removeFromMap) {
764                    map.removeLayer(marker);
765                }
766            }
767        }
768        else {
769            if (this._removeTimeoutId !== 0) {
770                window.clearTimeout(this._removeTimeoutId);
771                for (i = 0, l = this._markersRemoveListTimeout.length; i < l; ++i) {
772                    map.removeLayer(this._markersRemoveListTimeout[i]);
773                }
774            }
775            var toRemove = [];
776            for (i = 0, l = markersOnMap.length; i < l; ++i) {
777                marker = markersOnMap[i];
778                if (marker._removeFromMap) {
779                    marker.setOpacity(0);
780                    toRemove.push(marker);
781                }
782            }
783            if (toRemove.length > 0) {
784                this._removeTimeoutId = window.setTimeout(function () {
785                    for (i = 0, l = toRemove.length; i < l; ++i) {
786                        map.removeLayer(toRemove[i]);
787                    }
788                    _this._removeTimeoutId = 0;
789                }, 300);
790            }
791            this._markersRemoveListTimeout = toRemove;
792        }
793        this._objectsOnMap = newObjectsOnMap;
794        this._hardMove = false;
795        this._resetIcons = false;
796    },
797    FitBounds: function (withFiltered) {
798        if (withFiltered === void 0) { withFiltered = true; }
799        var bounds = this.Cluster.ComputeGlobalBounds(withFiltered);
800        if (bounds) {
801            this._map.fitBounds(new L.LatLngBounds(new L.LatLng(bounds.minLat, bounds.maxLng), new L.LatLng(bounds.maxLat, bounds.minLng)));
802        }
803    },
804    GetMarkers: function () {
805        return this.Cluster.GetMarkers();
806    },
807    RedrawIcons: function (processView) {
808        if (processView === void 0) { processView = true; }
809        this._resetIcons = true;
810        if (processView) {
811            this.ProcessView();
812        }
813    }
814});
815var PruneClusterLeafletSpiderfier = (L.Layer ? L.Layer : L.Class).extend({
816    _2PI: Math.PI * 2,
817    _circleFootSeparation: 25,
818    _circleStartAngle: Math.PI / 6,
819    _spiralFootSeparation: 28,
820    _spiralLengthStart: 11,
821    _spiralLengthFactor: 5,
822    _spiralCountTrigger: 8,
823    spiderfyDistanceMultiplier: 1,
824    initialize: function (cluster) {
825        this._cluster = cluster;
826        this._currentMarkers = [];
827        this._multiLines = !!L.multiPolyline;
828        this._lines = this._multiLines ?
829            L.multiPolyline([], { weight: 1.5, color: '#222' }) :
830            L.polyline([], { weight: 1.5, color: '#222' });
831    },
832    onAdd: function (map) {
833        this._map = map;
834        this._map.on('overlappingmarkers', this.Spiderfy, this);
835        this._map.on('click', this.Unspiderfy, this);
836        this._map.on('zoomend', this.Unspiderfy, this);
837    },
838    Spiderfy: function (data) {
839        var _this = this;
840        if (data.cluster !== this._cluster) {
841            return;
842        }
843        this.Unspiderfy();
844        var markers = data.markers.filter(function (marker) {
845            return !marker.filtered;
846        });
847        this._currentCenter = data.center;
848        var centerPoint = this._map.latLngToLayerPoint(data.center);
849        var points;
850        if (markers.length >= this._spiralCountTrigger) {
851            points = this._generatePointsSpiral(markers.length, centerPoint);
852        }
853        else {
854            if (this._multiLines) {
855                centerPoint.y += 10;
856            }
857            points = this._generatePointsCircle(markers.length, centerPoint);
858        }
859        var polylines = [];
860        var leafletMarkers = [];
861        var projectedPoints = [];
862        for (var i = 0, l = points.length; i < l; ++i) {
863            var pos = this._map.layerPointToLatLng(points[i]);
864            var m = this._cluster.BuildLeafletMarker(markers[i], data.center);
865            m.setZIndexOffset(5000);
866            m.setOpacity(0);
867            this._currentMarkers.push(m);
868            this._map.addLayer(m);
869            leafletMarkers.push(m);
870            projectedPoints.push(pos);
871        }
872        window.setTimeout(function () {
873            for (i = 0, l = points.length; i < l; ++i) {
874                leafletMarkers[i].setLatLng(projectedPoints[i])
875                    .setOpacity(1);
876            }
877            var startTime = +new Date();
878            var interval = 42, duration = 290;
879            var anim = window.setInterval(function () {
880                polylines = [];
881                var now = +new Date();
882                var d = now - startTime;
883                if (d >= duration) {
884                    window.clearInterval(anim);
885                    stepRatio = 1.0;
886                }
887                else {
888                    var stepRatio = d / duration;
889                }
890                var center = data.center;
891                for (i = 0, l = points.length; i < l; ++i) {
892                    var p = projectedPoints[i], diffLat = p.lat - center.lat, diffLng = p.lng - center.lng;
893                    polylines.push([center, new L.LatLng(center.lat + diffLat * stepRatio, center.lng + diffLng * stepRatio)]);
894                }
895                _this._lines.setLatLngs(polylines);
896            }, interval);
897        }, 1);
898        this._lines.setLatLngs(polylines);
899        this._map.addLayer(this._lines);
900        if (data.marker) {
901            this._clusterMarker = data.marker.setOpacity(0.3);
902        }
903    },
904    _generatePointsCircle: function (count, centerPt) {
905        var circumference = this.spiderfyDistanceMultiplier * this._circleFootSeparation * (2 + count), legLength = cir
905cumference / this._2PI, angleStep = this._2PI / count, res = [], i, angle;
906        res.length = count;
907        for (i = count - 1; i >= 0; i--) {
908            angle = this._circleStartAngle + i * angleStep;
909            res[i] = new L.Point(Math.round(centerPt.x + legLength * Math.cos(angle)), Math.round(centerPt.y + legLength * Math.sin(angle)));
910        }
911        return res;
912    },
913    _generatePointsSpiral: function (count, centerPt) {
914        var legLength = this.spiderfyDistanceMultiplier * this._spiralLengthStart, separation = this.spiderfyDistanceMultiplier * this._spiralFootSeparation, lengthFactor = this.spiderfyDistanceMultiplier * this._spiralLengthFactor, angle = 0, res = [], i;
915        res.length = count;
916        for (i = count - 1; i >= 0; i--) {
917            angle += separation / legLength + i * 0.0005;
918            res[i] = new L.Point(Math.round(centerPt.x + legLength * Math.cos(angle)), Math.round(centerPt.y + legLength * Math.sin(angle)));
919            legLength += this._2PI * lengthFactor / angle;
920        }
921        return res;
922    },
923    Unspiderfy: function () {
924        var _this = this;
925        for (var i = 0, l = this._currentMarkers.length; i < l; ++i) {
926            this._currentMarkers[i].setLatLng(this._currentCenter).setOpacity(0);
927        }
928        var markers = this._currentMarkers;
929        window.setTimeout(function () {
930            for (i = 0, l = markers.length; i < l; ++i) {
931                _this._map.removeLayer(markers[i]);
932            }
933        }, 300);
934        this._currentMarkers = [];
935        this._map.removeLayer(this._lines);
936        if (this._clusterMarker) {
937            this._clusterMarker.setOpacity(1);
938        }
939    },
940    onRemove: function (map) {
941        this.Unspiderfy();
942        map.off('overlappingmarkers', this.Spiderfy, this);
943        map.off('click', this.Unspiderfy, this);
944        map.off('zoomend', this.Unspiderfy, this);
945    }
946});
947//# sourceMappingURL=PruneCluster.js.map

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.