leaflet-markercluster-rails 0.2.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +7 -2
- data/lib/leaflet-markercluster-rails/version.rb +1 -1
- data/vendor/assets/javascripts/leaflet.markercluster-src.js +339 -207
- data/vendor/assets/javascripts/leaflet.markercluster.js +4 -4
- data/vendor/assets/stylesheets/leaflet.markercluster.css +5 -5
- data/vendor/assets/stylesheets/leaflet.markercluster.default.css +25 -25
- data/vendor/assets/stylesheets/leaflet.markercluster.default.ie.css +12 -13
- metadata +2 -2
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Engine wrapper for the Leaflet MarkerCluster library by @danzel.
|
4
4
|
|
5
|
-
https://github.com/
|
5
|
+
https://github.com/Leaflet/Leaflet.markercluster
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -20,9 +20,14 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
Provides the
|
23
|
+
Provides the following assets:
|
24
24
|
|
25
25
|
leaflet.markercluster.js
|
26
26
|
leaflet.markercluster.css
|
27
27
|
leaflet.markercluster.default.css
|
28
28
|
leaflet.markercluster.ie.css
|
29
|
+
|
30
|
+
## License
|
31
|
+
MIT License, full text of license see [here][License]
|
32
|
+
|
33
|
+
[License]: https://github.com/scpike/leaflet-markercluster-rails/blob/master/LICENSE.txt "LICENSE"
|
@@ -1,11 +1,9 @@
|
|
1
1
|
/*
|
2
|
-
|
3
|
-
Leaflet.markercluster
|
4
|
-
|
2
|
+
Leaflet.markercluster, Provides Beautiful Animated Marker Clustering functionality for Leaflet, a JS library for interactive maps.
|
3
|
+
https://github.com/Leaflet/Leaflet.markercluster
|
4
|
+
(c) 2012-2013, Dave Leaver, smartrak
|
5
5
|
*/
|
6
|
-
(function (window, undefined) {
|
7
|
-
|
8
|
-
|
6
|
+
(function (window, document, undefined) {
|
9
7
|
/*
|
10
8
|
* L.MarkerClusterGroup extends L.FeatureGroup by clustering the markers contained within
|
11
9
|
*/
|
@@ -23,6 +21,10 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
23
21
|
|
24
22
|
disableClusteringAtZoom: null,
|
25
23
|
|
24
|
+
// Setting this to false prevents the removal of any clusters outside of the viewpoint, which
|
25
|
+
// is the default behaviour for performance reasons.
|
26
|
+
removeOutsideVisibleBounds: true,
|
27
|
+
|
26
28
|
//Whether to animate adding markers after adding the MarkerClusterGroup to the map
|
27
29
|
// If you are adding individual markers set to true, if adding bulk markers leave false for massive performance gains.
|
28
30
|
animateAddingMarkers: false,
|
@@ -40,10 +42,15 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
40
42
|
this.options.iconCreateFunction = this._defaultIconCreateFunction;
|
41
43
|
}
|
42
44
|
|
43
|
-
L.
|
45
|
+
this._featureGroup = L.featureGroup();
|
46
|
+
this._featureGroup.on(L.FeatureGroup.EVENTS, this._propagateEvent, this);
|
47
|
+
|
48
|
+
this._nonPointGroup = L.featureGroup();
|
49
|
+
this._nonPointGroup.on(L.FeatureGroup.EVENTS, this._propagateEvent, this);
|
44
50
|
|
45
51
|
this._inZoomAnimation = 0;
|
46
52
|
this._needsClustering = [];
|
53
|
+
this._needsRemoving = []; //Markers removed while we aren't on the map need to be kept track of
|
47
54
|
//The bounds of the currently shown area (from _getExpandedVisibleBounds) Updated on zoom/move
|
48
55
|
this._currentShownBounds = null;
|
49
56
|
},
|
@@ -53,13 +60,17 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
53
60
|
if (layer instanceof L.LayerGroup) {
|
54
61
|
var array = [];
|
55
62
|
for (var i in layer._layers) {
|
56
|
-
|
57
|
-
array.push(layer._layers[i]);
|
58
|
-
}
|
63
|
+
array.push(layer._layers[i]);
|
59
64
|
}
|
60
65
|
return this.addLayers(array);
|
61
66
|
}
|
62
67
|
|
68
|
+
//Don't cluster non point data
|
69
|
+
if (!layer.getLatLng) {
|
70
|
+
this._nonPointGroup.addLayer(layer);
|
71
|
+
return this;
|
72
|
+
}
|
73
|
+
|
63
74
|
if (!this._map) {
|
64
75
|
this._needsClustering.push(layer);
|
65
76
|
return this;
|
@@ -69,6 +80,7 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
69
80
|
return this;
|
70
81
|
}
|
71
82
|
|
83
|
+
|
72
84
|
//If we have already clustered we'll need to add this one to a cluster
|
73
85
|
|
74
86
|
if (this._unspiderfy) {
|
@@ -98,8 +110,16 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
98
110
|
|
99
111
|
removeLayer: function (layer) {
|
100
112
|
|
113
|
+
//Non point layers
|
114
|
+
if (!layer.getLatLng) {
|
115
|
+
this._nonPointGroup.removeLayer(layer);
|
116
|
+
return this;
|
117
|
+
}
|
118
|
+
|
101
119
|
if (!this._map) {
|
102
|
-
this._arraySplice(this._needsClustering, layer)
|
120
|
+
if (!this._arraySplice(this._needsClustering, layer) && this.hasLayer(layer)) {
|
121
|
+
this._needsRemoving.push(layer);
|
122
|
+
}
|
103
123
|
return this;
|
104
124
|
}
|
105
125
|
|
@@ -115,9 +135,11 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
115
135
|
//Remove the marker from clusters
|
116
136
|
this._removeLayer(layer, true);
|
117
137
|
|
118
|
-
if (layer
|
119
|
-
|
120
|
-
layer.setOpacity
|
138
|
+
if (this._featureGroup.hasLayer(layer)) {
|
139
|
+
this._featureGroup.removeLayer(layer);
|
140
|
+
if (layer.setOpacity) {
|
141
|
+
layer.setOpacity(1);
|
142
|
+
}
|
121
143
|
}
|
122
144
|
|
123
145
|
return this;
|
@@ -125,19 +147,29 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
125
147
|
|
126
148
|
//Takes an array of markers and adds them in bulk
|
127
149
|
addLayers: function (layersArray) {
|
128
|
-
var i, l, m
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
}
|
150
|
+
var i, l, m,
|
151
|
+
onMap = this._map,
|
152
|
+
fg = this._featureGroup,
|
153
|
+
npg = this._nonPointGroup;
|
133
154
|
|
134
155
|
for (i = 0, l = layersArray.length; i < l; i++) {
|
135
156
|
m = layersArray[i];
|
136
157
|
|
158
|
+
//Not point data, can't be clustered
|
159
|
+
if (!m.getLatLng) {
|
160
|
+
npg.addLayer(m);
|
161
|
+
continue;
|
162
|
+
}
|
163
|
+
|
137
164
|
if (this.hasLayer(m)) {
|
138
165
|
continue;
|
139
166
|
}
|
140
167
|
|
168
|
+
if (!onMap) {
|
169
|
+
this._needsClustering.push(m);
|
170
|
+
continue;
|
171
|
+
}
|
172
|
+
|
141
173
|
this._addLayer(m, this._maxZoom);
|
142
174
|
|
143
175
|
//If we just made a cluster of size 2 then we need to remove the other marker from the map (if it is) or we never will
|
@@ -145,33 +177,36 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
145
177
|
if (m.__parent.getChildCount() === 2) {
|
146
178
|
var markers = m.__parent.getAllChildMarkers(),
|
147
179
|
otherMarker = markers[0] === m ? markers[1] : markers[0];
|
148
|
-
|
180
|
+
fg.removeLayer(otherMarker);
|
149
181
|
}
|
150
182
|
}
|
151
183
|
}
|
152
184
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
m._updateIcon();
|
185
|
+
if (onMap) {
|
186
|
+
//Update the icons of all those visible clusters that were affected
|
187
|
+
fg.eachLayer(function (c) {
|
188
|
+
if (c instanceof L.MarkerCluster && c._iconNeedsUpdate) {
|
189
|
+
c._updateIcon();
|
159
190
|
}
|
160
|
-
}
|
161
|
-
}
|
191
|
+
});
|
162
192
|
|
163
|
-
|
193
|
+
this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);
|
194
|
+
}
|
164
195
|
|
165
196
|
return this;
|
166
197
|
},
|
167
198
|
|
168
199
|
//Takes an array of markers and removes them in bulk
|
169
200
|
removeLayers: function (layersArray) {
|
170
|
-
var i, l, m
|
201
|
+
var i, l, m,
|
202
|
+
fg = this._featureGroup,
|
203
|
+
npg = this._nonPointGroup;
|
171
204
|
|
172
205
|
if (!this._map) {
|
173
206
|
for (i = 0, l = layersArray.length; i < l; i++) {
|
174
|
-
|
207
|
+
m = layersArray[i];
|
208
|
+
this._arraySplice(this._needsClustering, m);
|
209
|
+
npg.removeLayer(m);
|
175
210
|
}
|
176
211
|
return this;
|
177
212
|
}
|
@@ -180,28 +215,28 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
180
215
|
m = layersArray[i];
|
181
216
|
|
182
217
|
if (!m.__parent) {
|
218
|
+
npg.removeLayer(m);
|
183
219
|
continue;
|
184
220
|
}
|
185
221
|
|
186
222
|
this._removeLayer(m, true, true);
|
187
223
|
|
188
|
-
if (m
|
189
|
-
|
190
|
-
m.setOpacity
|
224
|
+
if (fg.hasLayer(m)) {
|
225
|
+
fg.removeLayer(m);
|
226
|
+
if (m.setOpacity) {
|
227
|
+
m.setOpacity(1);
|
228
|
+
}
|
191
229
|
}
|
192
230
|
}
|
193
231
|
|
194
232
|
//Fix up the clusters and markers on the map
|
195
233
|
this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);
|
196
234
|
|
197
|
-
|
198
|
-
if (
|
199
|
-
|
200
|
-
if (m instanceof L.MarkerCluster) {
|
201
|
-
m._updateIcon();
|
202
|
-
}
|
235
|
+
fg.eachLayer(function (c) {
|
236
|
+
if (c instanceof L.MarkerCluster) {
|
237
|
+
c._updateIcon();
|
203
238
|
}
|
204
|
-
}
|
239
|
+
});
|
205
240
|
|
206
241
|
return this;
|
207
242
|
},
|
@@ -217,16 +252,13 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
217
252
|
delete this._gridUnclustered;
|
218
253
|
}
|
219
254
|
|
220
|
-
if (this.
|
221
|
-
this.
|
255
|
+
if (this._noanimationUnspiderfy) {
|
256
|
+
this._noanimationUnspiderfy();
|
222
257
|
}
|
223
258
|
|
224
259
|
//Remove all the visible layers
|
225
|
-
|
226
|
-
|
227
|
-
L.FeatureGroup.prototype.removeLayer.call(this, this._layers[i]);
|
228
|
-
}
|
229
|
-
}
|
260
|
+
this._featureGroup.clearLayers();
|
261
|
+
this._nonPointGroup.clearLayers();
|
230
262
|
|
231
263
|
this.eachLayer(function (marker) {
|
232
264
|
delete marker.__parent;
|
@@ -250,6 +282,13 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
250
282
|
bounds.extend(this._needsClustering[i].getLatLng());
|
251
283
|
}
|
252
284
|
}
|
285
|
+
|
286
|
+
//TODO: Can remove this isValid test when leaflet 0.6 is released
|
287
|
+
var nonPointBounds = this._nonPointGroup.getBounds();
|
288
|
+
if (nonPointBounds.isValid()) {
|
289
|
+
bounds.extend(nonPointBounds);
|
290
|
+
}
|
291
|
+
|
253
292
|
return bounds;
|
254
293
|
},
|
255
294
|
|
@@ -265,20 +304,32 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
265
304
|
for (i = markers.length - 1; i >= 0; i--) {
|
266
305
|
method.call(context, markers[i]);
|
267
306
|
}
|
307
|
+
|
308
|
+
this._nonPointGroup.eachLayer(method, context);
|
268
309
|
},
|
269
310
|
|
270
311
|
//Returns true if the given layer is in this MarkerClusterGroup
|
271
312
|
hasLayer: function (layer) {
|
272
|
-
if (
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
313
|
+
if (!layer) {
|
314
|
+
return false;
|
315
|
+
}
|
316
|
+
|
317
|
+
var i, anArray = this._needsClustering;
|
318
|
+
|
319
|
+
for (i = anArray.length - 1; i >= 0; i--) {
|
320
|
+
if (anArray[i] === layer) {
|
321
|
+
return true;
|
322
|
+
}
|
323
|
+
}
|
324
|
+
|
325
|
+
anArray = this._needsRemoving;
|
326
|
+
for (i = anArray.length - 1; i >= 0; i--) {
|
327
|
+
if (anArray[i] === layer) {
|
328
|
+
return false;
|
278
329
|
}
|
279
330
|
}
|
280
331
|
|
281
|
-
return !!(layer.__parent && layer.__parent._group === this);
|
332
|
+
return !!(layer.__parent && layer.__parent._group === this) || this._nonPointGroup.hasLayer(layer);
|
282
333
|
},
|
283
334
|
|
284
335
|
//Zoom down to show the given layer (spiderfying if necessary) then calls the callback
|
@@ -322,13 +373,35 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
322
373
|
//Overrides FeatureGroup.onAdd
|
323
374
|
onAdd: function (map) {
|
324
375
|
this._map = map;
|
376
|
+
var i, l, layer;
|
377
|
+
|
378
|
+
if (!isFinite(this._map.getMaxZoom())) {
|
379
|
+
throw "Map has no maxZoom specified";
|
380
|
+
}
|
381
|
+
|
382
|
+
this._featureGroup.onAdd(map);
|
383
|
+
this._nonPointGroup.onAdd(map);
|
325
384
|
|
326
385
|
if (!this._gridClusters) {
|
327
386
|
this._generateInitialClusters();
|
328
387
|
}
|
329
388
|
|
330
|
-
for (
|
331
|
-
|
389
|
+
for (i = 0, l = this._needsRemoving.length; i < l; i++) {
|
390
|
+
layer = this._needsRemoving[i];
|
391
|
+
this._removeLayer(layer, true);
|
392
|
+
}
|
393
|
+
this._needsRemoving = [];
|
394
|
+
|
395
|
+
for (i = 0, l = this._needsClustering.length; i < l; i++) {
|
396
|
+
layer = this._needsClustering[i];
|
397
|
+
|
398
|
+
//If the layer doesn't have a getLatLng then we can't cluster it, so add it to our child featureGroup
|
399
|
+
if (!layer.getLatLng) {
|
400
|
+
this._featureGroup.addLayer(layer);
|
401
|
+
continue;
|
402
|
+
}
|
403
|
+
|
404
|
+
|
332
405
|
if (layer.__parent) {
|
333
406
|
continue;
|
334
407
|
}
|
@@ -336,6 +409,7 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
336
409
|
}
|
337
410
|
this._needsClustering = [];
|
338
411
|
|
412
|
+
|
339
413
|
this._map.on('zoomend', this._zoomEnd, this);
|
340
414
|
this._map.on('moveend', this._moveEnd, this);
|
341
415
|
|
@@ -358,8 +432,8 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
358
432
|
|
359
433
|
//Overrides FeatureGroup.onRemove
|
360
434
|
onRemove: function (map) {
|
361
|
-
|
362
|
-
|
435
|
+
map.off('zoomend', this._zoomEnd, this);
|
436
|
+
map.off('moveend', this._moveEnd, this);
|
363
437
|
|
364
438
|
this._unbindEvents();
|
365
439
|
|
@@ -371,22 +445,28 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
371
445
|
}
|
372
446
|
|
373
447
|
//Clean up all the layers we added to the map
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
}
|
448
|
+
this._featureGroup.onRemove(map);
|
449
|
+
this._nonPointGroup.onRemove(map);
|
450
|
+
|
451
|
+
this._featureGroup.clearLayers();
|
379
452
|
|
380
453
|
this._map = null;
|
381
454
|
},
|
382
455
|
|
456
|
+
getVisibleParent: function (marker) {
|
457
|
+
var vMarker = marker;
|
458
|
+
while (vMarker !== null && !vMarker._icon) {
|
459
|
+
vMarker = vMarker.__parent;
|
460
|
+
}
|
461
|
+
return vMarker;
|
462
|
+
},
|
383
463
|
|
384
464
|
//Remove the given object from the given array
|
385
465
|
_arraySplice: function (anArray, obj) {
|
386
466
|
for (var i = anArray.length - 1; i >= 0; i--) {
|
387
467
|
if (anArray[i] === obj) {
|
388
468
|
anArray.splice(i, 1);
|
389
|
-
return;
|
469
|
+
return true;
|
390
470
|
}
|
391
471
|
}
|
392
472
|
},
|
@@ -396,6 +476,7 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
396
476
|
_removeLayer: function (marker, removeFromDistanceGrid, dontUpdateMap) {
|
397
477
|
var gridClusters = this._gridClusters,
|
398
478
|
gridUnclustered = this._gridUnclustered,
|
479
|
+
fg = this._featureGroup,
|
399
480
|
map = this._map;
|
400
481
|
|
401
482
|
//Remove the marker from distance clusters it might be in
|
@@ -436,9 +517,9 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
436
517
|
|
437
518
|
if (cluster._icon) {
|
438
519
|
//Cluster is currently on the map, need to put the marker on the map instead
|
439
|
-
|
520
|
+
fg.removeLayer(cluster);
|
440
521
|
if (!dontUpdateMap) {
|
441
|
-
|
522
|
+
fg.addLayer(otherMarker);
|
442
523
|
}
|
443
524
|
}
|
444
525
|
} else {
|
@@ -454,12 +535,12 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
454
535
|
delete marker.__parent;
|
455
536
|
},
|
456
537
|
|
457
|
-
//Overrides FeatureGroup._propagateEvent
|
458
538
|
_propagateEvent: function (e) {
|
459
|
-
if (e.
|
539
|
+
if (e.layer instanceof L.MarkerCluster) {
|
460
540
|
e.type = 'cluster' + e.type;
|
461
541
|
}
|
462
|
-
|
542
|
+
|
543
|
+
this.fire(e.type, e);
|
463
544
|
},
|
464
545
|
|
465
546
|
//Default functionality
|
@@ -479,58 +560,60 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
479
560
|
},
|
480
561
|
|
481
562
|
_bindEvents: function () {
|
482
|
-
var
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
showCoverageOnHover = this.options.showCoverageOnHover,
|
487
|
-
zoomToBoundsOnClick = this.options.zoomToBoundsOnClick;
|
563
|
+
var map = this._map,
|
564
|
+
spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom,
|
565
|
+
showCoverageOnHover = this.options.showCoverageOnHover,
|
566
|
+
zoomToBoundsOnClick = this.options.zoomToBoundsOnClick;
|
488
567
|
|
489
568
|
//Zoom on cluster click or spiderfy if we are at the lowest level
|
490
569
|
if (spiderfyOnMaxZoom || zoomToBoundsOnClick) {
|
491
|
-
this.on('clusterclick',
|
492
|
-
if (map.getMaxZoom() === map.getZoom()) {
|
493
|
-
if (spiderfyOnMaxZoom) {
|
494
|
-
a.layer.spiderfy();
|
495
|
-
}
|
496
|
-
} else if (zoomToBoundsOnClick) {
|
497
|
-
a.layer.zoomToBounds();
|
498
|
-
}
|
499
|
-
}, this);
|
570
|
+
this.on('clusterclick', this._zoomOrSpiderfy, this);
|
500
571
|
}
|
501
572
|
|
502
573
|
//Show convex hull (boundary) polygon on mouse over
|
503
574
|
if (showCoverageOnHover) {
|
504
|
-
this.on('clustermouseover',
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
map.
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
575
|
+
this.on('clustermouseover', this._showCoverage, this);
|
576
|
+
this.on('clustermouseout', this._hideCoverage, this);
|
577
|
+
map.on('zoomend', this._hideCoverage, this);
|
578
|
+
map.on('layerremove', this._hideCoverageOnRemove, this);
|
579
|
+
}
|
580
|
+
},
|
581
|
+
|
582
|
+
_zoomOrSpiderfy: function (e) {
|
583
|
+
var map = this._map;
|
584
|
+
if (map.getMaxZoom() === map.getZoom()) {
|
585
|
+
if (this.options.spiderfyOnMaxZoom) {
|
586
|
+
e.layer.spiderfy();
|
587
|
+
}
|
588
|
+
} else if (this.options.zoomToBoundsOnClick) {
|
589
|
+
e.layer.zoomToBounds();
|
590
|
+
}
|
591
|
+
},
|
592
|
+
|
593
|
+
_showCoverage: function (e) {
|
594
|
+
var map = this._map;
|
595
|
+
if (this._inZoomAnimation) {
|
596
|
+
return;
|
597
|
+
}
|
598
|
+
if (this._shownPolygon) {
|
599
|
+
map.removeLayer(this._shownPolygon);
|
600
|
+
}
|
601
|
+
if (e.layer.getChildCount() > 2 && e.layer !== this._spiderfied) {
|
602
|
+
this._shownPolygon = new L.Polygon(e.layer.getConvexHull(), this.options.polygonOptions);
|
603
|
+
map.addLayer(this._shownPolygon);
|
604
|
+
}
|
605
|
+
},
|
606
|
+
|
607
|
+
_hideCoverage: function () {
|
608
|
+
if (this._shownPolygon) {
|
609
|
+
this._map.removeLayer(this._shownPolygon);
|
610
|
+
this._shownPolygon = null;
|
611
|
+
}
|
612
|
+
},
|
613
|
+
|
614
|
+
_hideCoverageOnRemove: function (e) {
|
615
|
+
if (e.layer === this) {
|
616
|
+
this._hideCoverage();
|
534
617
|
}
|
535
618
|
},
|
536
619
|
|
@@ -541,13 +624,13 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
541
624
|
map = this._map;
|
542
625
|
|
543
626
|
if (spiderfyOnMaxZoom || zoomToBoundsOnClick) {
|
544
|
-
this.off('clusterclick',
|
627
|
+
this.off('clusterclick', this._zoomOrSpiderfy, this);
|
545
628
|
}
|
546
629
|
if (showCoverageOnHover) {
|
547
|
-
this.off('clustermouseover',
|
548
|
-
this.off('clustermouseout',
|
549
|
-
map.off('zoomend',
|
550
|
-
map.off('layerremove',
|
630
|
+
this.off('clustermouseover', this._showCoverage, this);
|
631
|
+
this.off('clustermouseout', this._hideCoverage, this);
|
632
|
+
map.off('zoomend', this._hideCoverage, this);
|
633
|
+
map.off('layerremove', this._hideCoverageOnRemove, this);
|
551
634
|
}
|
552
635
|
},
|
553
636
|
|
@@ -656,7 +739,7 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
656
739
|
|
657
740
|
return;
|
658
741
|
}
|
659
|
-
|
742
|
+
|
660
743
|
//Didn't manage to cluster in at this zoom, record us as a marker here and continue upwards
|
661
744
|
gridUnclustered[zoom].addObject(layer, markerPoint);
|
662
745
|
}
|
@@ -684,9 +767,13 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
684
767
|
this._moveEnd();
|
685
768
|
}
|
686
769
|
},
|
687
|
-
|
770
|
+
|
688
771
|
//Gets the maps visible bounds expanded in each direction by the size of the screen (so the user cannot see an area we do not cover in one pan)
|
689
772
|
_getExpandedVisibleBounds: function () {
|
773
|
+
if (!this.options.removeOutsideVisibleBounds) {
|
774
|
+
return this.getBounds();
|
775
|
+
}
|
776
|
+
|
690
777
|
var map = this._map,
|
691
778
|
bounds = map.getBounds(),
|
692
779
|
sw = bounds._southWest,
|
@@ -702,13 +789,13 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
|
|
702
789
|
//Shared animation code
|
703
790
|
_animationAddLayerNonAnimated: function (layer, newCluster) {
|
704
791
|
if (newCluster === layer) {
|
705
|
-
|
792
|
+
this._featureGroup.addLayer(layer);
|
706
793
|
} else if (newCluster._childCount === 2) {
|
707
794
|
newCluster._addToMap();
|
708
795
|
|
709
796
|
var markers = newCluster.getAllChildMarkers();
|
710
|
-
|
711
|
-
|
797
|
+
this._featureGroup.removeLayer(markers[0]);
|
798
|
+
this._featureGroup.removeLayer(markers[1]);
|
712
799
|
} else {
|
713
800
|
newCluster._updateIcon();
|
714
801
|
}
|
@@ -749,6 +836,7 @@ L.MarkerClusterGroup.include(!L.DomUtil.TRANSITION ? {
|
|
749
836
|
_animationZoomIn: function (previousZoomLevel, newZoomLevel) {
|
750
837
|
var me = this,
|
751
838
|
bounds = this._getExpandedVisibleBounds(),
|
839
|
+
fg = this._featureGroup,
|
752
840
|
i;
|
753
841
|
|
754
842
|
//Add all children of current clusters to map and remove those clusters from map
|
@@ -757,8 +845,12 @@ L.MarkerClusterGroup.include(!L.DomUtil.TRANSITION ? {
|
|
757
845
|
markers = c._markers,
|
758
846
|
m;
|
759
847
|
|
848
|
+
if (!bounds.contains(startPos)) {
|
849
|
+
startPos = null;
|
850
|
+
}
|
851
|
+
|
760
852
|
if (c._isSingleParent() && previousZoomLevel + 1 === newZoomLevel) { //Immediately add the new child and remove us
|
761
|
-
|
853
|
+
fg.removeLayer(c);
|
762
854
|
c._recursivelyAddChildrenToMap(null, newZoomLevel, bounds);
|
763
855
|
} else {
|
764
856
|
//Fade out old cluster
|
@@ -771,27 +863,22 @@ L.MarkerClusterGroup.include(!L.DomUtil.TRANSITION ? {
|
|
771
863
|
for (i = markers.length - 1; i >= 0; i--) {
|
772
864
|
m = markers[i];
|
773
865
|
if (!bounds.contains(m._latlng)) {
|
774
|
-
|
866
|
+
fg.removeLayer(m);
|
775
867
|
}
|
776
868
|
}
|
777
869
|
|
778
870
|
});
|
779
871
|
|
780
872
|
this._forceLayout();
|
781
|
-
var j, n;
|
782
873
|
|
783
874
|
//Update opacities
|
784
875
|
me._topClusterLevel._recursivelyBecomeVisible(bounds, newZoomLevel);
|
785
876
|
//TODO Maybe? Update markers in _recursivelyBecomeVisible
|
786
|
-
|
787
|
-
if (
|
788
|
-
n
|
789
|
-
|
790
|
-
if (!(n instanceof L.MarkerCluster) && n._icon) {
|
791
|
-
n.setOpacity(1);
|
792
|
-
}
|
877
|
+
fg.eachLayer(function (n) {
|
878
|
+
if (!(n instanceof L.MarkerCluster) && n._icon) {
|
879
|
+
n.setOpacity(1);
|
793
880
|
}
|
794
|
-
}
|
881
|
+
});
|
795
882
|
|
796
883
|
//update the positions of the just added clusters/markers
|
797
884
|
me._topClusterLevel._recursively(bounds, previousZoomLevel, newZoomLevel, function (c) {
|
@@ -803,12 +890,12 @@ L.MarkerClusterGroup.include(!L.DomUtil.TRANSITION ? {
|
|
803
890
|
setTimeout(function () {
|
804
891
|
//update the positions of the just added clusters/markers
|
805
892
|
me._topClusterLevel._recursively(bounds, previousZoomLevel, 0, function (c) {
|
806
|
-
|
893
|
+
fg.removeLayer(c);
|
807
894
|
c.setOpacity(1);
|
808
895
|
});
|
809
896
|
|
810
897
|
me._animationEnd();
|
811
|
-
},
|
898
|
+
}, 200);
|
812
899
|
},
|
813
900
|
|
814
901
|
_animationZoomOut: function (previousZoomLevel, newZoomLevel) {
|
@@ -841,20 +928,19 @@ L.MarkerClusterGroup.include(!L.DomUtil.TRANSITION ? {
|
|
841
928
|
//If we were in a cluster animation at the time then the opacity and position of our child could be wrong now, so fix it
|
842
929
|
m.setLatLng(m.getLatLng());
|
843
930
|
m.setOpacity(1);
|
844
|
-
|
845
|
-
|
931
|
+
} else {
|
932
|
+
cluster._recursively(bounds, newZoomLevel, 0, function (c) {
|
933
|
+
c._recursivelyRemoveChildrenFromMap(bounds, previousZoomLevel + 1);
|
934
|
+
});
|
846
935
|
}
|
847
|
-
|
848
|
-
cluster._recursively(bounds, newZoomLevel, 0, function (c) {
|
849
|
-
c._recursivelyRemoveChildrenFromMap(bounds, previousZoomLevel + 1);
|
850
|
-
});
|
851
936
|
me._animationEnd();
|
852
|
-
},
|
937
|
+
}, 200);
|
853
938
|
},
|
854
939
|
_animationAddLayer: function (layer, newCluster) {
|
855
|
-
var me = this
|
940
|
+
var me = this,
|
941
|
+
fg = this._featureGroup;
|
856
942
|
|
857
|
-
|
943
|
+
fg.addLayer(layer);
|
858
944
|
if (newCluster !== layer) {
|
859
945
|
if (newCluster._childCount > 2) { //Was already a cluster
|
860
946
|
|
@@ -866,11 +952,11 @@ L.MarkerClusterGroup.include(!L.DomUtil.TRANSITION ? {
|
|
866
952
|
layer.setOpacity(0);
|
867
953
|
|
868
954
|
setTimeout(function () {
|
869
|
-
|
955
|
+
fg.removeLayer(layer);
|
870
956
|
layer.setOpacity(1);
|
871
957
|
|
872
958
|
me._animationEnd();
|
873
|
-
},
|
959
|
+
}, 200);
|
874
960
|
|
875
961
|
} else { //Just became a cluster
|
876
962
|
this._forceLayout();
|
@@ -891,6 +977,10 @@ L.MarkerClusterGroup.include(!L.DomUtil.TRANSITION ? {
|
|
891
977
|
}
|
892
978
|
});
|
893
979
|
|
980
|
+
L.markerClusterGroup = function (options) {
|
981
|
+
return new L.MarkerClusterGroup(options);
|
982
|
+
};
|
983
|
+
|
894
984
|
|
895
985
|
L.MarkerCluster = L.Marker.extend({
|
896
986
|
initialize: function (group, zoom, a, b) {
|
@@ -941,6 +1031,11 @@ L.MarkerCluster = L.Marker.extend({
|
|
941
1031
|
this._group._map.fitBounds(this._bounds);
|
942
1032
|
},
|
943
1033
|
|
1034
|
+
getBounds: function () {
|
1035
|
+
var bounds = new L.LatLngBounds();
|
1036
|
+
bounds.extend(this._bounds);
|
1037
|
+
return bounds;
|
1038
|
+
},
|
944
1039
|
|
945
1040
|
_updateIcon: function () {
|
946
1041
|
this._iconNeedsUpdate = true;
|
@@ -1021,9 +1116,9 @@ L.MarkerCluster = L.Marker.extend({
|
|
1021
1116
|
this._backupLatlng = this._latlng;
|
1022
1117
|
this.setLatLng(startPos);
|
1023
1118
|
}
|
1024
|
-
|
1119
|
+
this._group._featureGroup.addLayer(this);
|
1025
1120
|
},
|
1026
|
-
|
1121
|
+
|
1027
1122
|
_recursivelyAnimateChildrenIn: function (bounds, center, maxZoom) {
|
1028
1123
|
this._recursively(bounds, 0, maxZoom - 1,
|
1029
1124
|
function (c) {
|
@@ -1097,10 +1192,12 @@ L.MarkerCluster = L.Marker.extend({
|
|
1097
1192
|
nm._backupLatlng = nm.getLatLng();
|
1098
1193
|
|
1099
1194
|
nm.setLatLng(startPos);
|
1100
|
-
nm.setOpacity
|
1195
|
+
if (nm.setOpacity) {
|
1196
|
+
nm.setOpacity(0);
|
1197
|
+
}
|
1101
1198
|
}
|
1102
1199
|
|
1103
|
-
|
1200
|
+
c._group._featureGroup.addLayer(nm);
|
1104
1201
|
}
|
1105
1202
|
},
|
1106
1203
|
function (c) {
|
@@ -1147,8 +1244,10 @@ L.MarkerCluster = L.Marker.extend({
|
|
1147
1244
|
for (i = c._markers.length - 1; i >= 0; i--) {
|
1148
1245
|
m = c._markers[i];
|
1149
1246
|
if (!exceptBounds || !exceptBounds.contains(m._latlng)) {
|
1150
|
-
|
1151
|
-
m.setOpacity
|
1247
|
+
c._group._featureGroup.removeLayer(m);
|
1248
|
+
if (m.setOpacity) {
|
1249
|
+
m.setOpacity(1);
|
1250
|
+
}
|
1152
1251
|
}
|
1153
1252
|
}
|
1154
1253
|
},
|
@@ -1157,8 +1256,10 @@ L.MarkerCluster = L.Marker.extend({
|
|
1157
1256
|
for (i = c._childClusters.length - 1; i >= 0; i--) {
|
1158
1257
|
m = c._childClusters[i];
|
1159
1258
|
if (!exceptBounds || !exceptBounds.contains(m._latlng)) {
|
1160
|
-
|
1161
|
-
m.setOpacity
|
1259
|
+
c._group._featureGroup.removeLayer(m);
|
1260
|
+
if (m.setOpacity) {
|
1261
|
+
m.setOpacity(1);
|
1262
|
+
}
|
1162
1263
|
}
|
1163
1264
|
}
|
1164
1265
|
}
|
@@ -1288,20 +1389,16 @@ L.DistanceGrid.prototype = {
|
|
1288
1389
|
grid = this._grid;
|
1289
1390
|
|
1290
1391
|
for (i in grid) {
|
1291
|
-
|
1292
|
-
row = grid[i];
|
1392
|
+
row = grid[i];
|
1293
1393
|
|
1294
|
-
|
1295
|
-
|
1296
|
-
cell = row[j];
|
1394
|
+
for (j in row) {
|
1395
|
+
cell = row[j];
|
1297
1396
|
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
}
|
1304
|
-
}
|
1397
|
+
for (k = 0, len = cell.length; k < len; k++) {
|
1398
|
+
removed = fn.call(context, cell[k]);
|
1399
|
+
if (removed) {
|
1400
|
+
k--;
|
1401
|
+
len--;
|
1305
1402
|
}
|
1306
1403
|
}
|
1307
1404
|
}
|
@@ -1561,6 +1658,34 @@ L.MarkerCluster.include({
|
|
1561
1658
|
legLength += this._2PI * lengthFactor / angle;
|
1562
1659
|
}
|
1563
1660
|
return res;
|
1661
|
+
},
|
1662
|
+
|
1663
|
+
_noanimationUnspiderfy: function () {
|
1664
|
+
var group = this._group,
|
1665
|
+
map = group._map,
|
1666
|
+
fg = group._featureGroup,
|
1667
|
+
childMarkers = this.getAllChildMarkers(),
|
1668
|
+
m, i;
|
1669
|
+
|
1670
|
+
this.setOpacity(1);
|
1671
|
+
for (i = childMarkers.length - 1; i >= 0; i--) {
|
1672
|
+
m = childMarkers[i];
|
1673
|
+
|
1674
|
+
fg.removeLayer(m);
|
1675
|
+
|
1676
|
+
if (m._preSpiderfyLatlng) {
|
1677
|
+
m.setLatLng(m._preSpiderfyLatlng);
|
1678
|
+
delete m._preSpiderfyLatlng;
|
1679
|
+
}
|
1680
|
+
if (m.setZIndexOffset) {
|
1681
|
+
m.setZIndexOffset(0);
|
1682
|
+
}
|
1683
|
+
|
1684
|
+
if (m._spiderLeg) {
|
1685
|
+
map.removeLayer(m._spiderLeg);
|
1686
|
+
delete m._spiderLeg;
|
1687
|
+
}
|
1688
|
+
}
|
1564
1689
|
}
|
1565
1690
|
});
|
1566
1691
|
|
@@ -1569,6 +1694,7 @@ L.MarkerCluster.include(!L.DomUtil.TRANSITION ? {
|
|
1569
1694
|
_animationSpiderfy: function (childMarkers, positions) {
|
1570
1695
|
var group = this._group,
|
1571
1696
|
map = group._map,
|
1697
|
+
fg = group._featureGroup,
|
1572
1698
|
i, m, leg, newPos;
|
1573
1699
|
|
1574
1700
|
for (i = childMarkers.length - 1; i >= 0; i--) {
|
@@ -1577,9 +1703,11 @@ L.MarkerCluster.include(!L.DomUtil.TRANSITION ? {
|
|
1577
1703
|
|
1578
1704
|
m._preSpiderfyLatlng = m._latlng;
|
1579
1705
|
m.setLatLng(newPos);
|
1580
|
-
m.setZIndexOffset
|
1706
|
+
if (m.setZIndexOffset) {
|
1707
|
+
m.setZIndexOffset(1000000); //Make these appear on top of EVERYTHING
|
1708
|
+
}
|
1581
1709
|
|
1582
|
-
|
1710
|
+
fg.addLayer(m);
|
1583
1711
|
|
1584
1712
|
|
1585
1713
|
leg = new L.Polyline([this._latlng, newPos], { weight: 1.5, color: '#222' });
|
@@ -1591,24 +1719,7 @@ L.MarkerCluster.include(!L.DomUtil.TRANSITION ? {
|
|
1591
1719
|
},
|
1592
1720
|
|
1593
1721
|
_animationUnspiderfy: function () {
|
1594
|
-
|
1595
|
-
map = group._map,
|
1596
|
-
childMarkers = this.getAllChildMarkers(),
|
1597
|
-
m, i;
|
1598
|
-
|
1599
|
-
this.setOpacity(1);
|
1600
|
-
for (i = childMarkers.length - 1; i >= 0; i--) {
|
1601
|
-
m = childMarkers[i];
|
1602
|
-
|
1603
|
-
L.FeatureGroup.prototype.removeLayer.call(group, m);
|
1604
|
-
|
1605
|
-
m.setLatLng(m._preSpiderfyLatlng);
|
1606
|
-
delete m._preSpiderfyLatlng;
|
1607
|
-
m.setZIndexOffset(0);
|
1608
|
-
|
1609
|
-
map.removeLayer(m._spiderLeg);
|
1610
|
-
delete m._spiderLeg;
|
1611
|
-
}
|
1722
|
+
this._noanimationUnspiderfy();
|
1612
1723
|
}
|
1613
1724
|
} : {
|
1614
1725
|
//Animated versions here
|
@@ -1620,6 +1731,7 @@ L.MarkerCluster.include(!L.DomUtil.TRANSITION ? {
|
|
1620
1731
|
var me = this,
|
1621
1732
|
group = this._group,
|
1622
1733
|
map = group._map,
|
1734
|
+
fg = group._featureGroup,
|
1623
1735
|
thisLayerPos = map.latLngToLayerPoint(this._latlng),
|
1624
1736
|
i, m, leg, newPos;
|
1625
1737
|
|
@@ -1627,12 +1739,18 @@ L.MarkerCluster.include(!L.DomUtil.TRANSITION ? {
|
|
1627
1739
|
for (i = childMarkers.length - 1; i >= 0; i--) {
|
1628
1740
|
m = childMarkers[i];
|
1629
1741
|
|
1630
|
-
|
1631
|
-
m.setOpacity
|
1632
|
-
|
1633
|
-
|
1742
|
+
//If it is a marker, add it now and we'll animate it out
|
1743
|
+
if (m.setOpacity) {
|
1744
|
+
m.setZIndexOffset(1000000); //Make these appear on top of EVERYTHING
|
1745
|
+
m.setOpacity(0);
|
1746
|
+
|
1747
|
+
fg.addLayer(m);
|
1634
1748
|
|
1635
|
-
|
1749
|
+
m._setPos(thisLayerPos);
|
1750
|
+
} else {
|
1751
|
+
//Vectors just get immediately added
|
1752
|
+
fg.addLayer(m);
|
1753
|
+
}
|
1636
1754
|
}
|
1637
1755
|
|
1638
1756
|
group._forceLayout();
|
@@ -1649,7 +1767,10 @@ L.MarkerCluster.include(!L.DomUtil.TRANSITION ? {
|
|
1649
1767
|
//Move marker to new position
|
1650
1768
|
m._preSpiderfyLatlng = m._latlng;
|
1651
1769
|
m.setLatLng(newPos);
|
1652
|
-
|
1770
|
+
|
1771
|
+
if (m.setOpacity) {
|
1772
|
+
m.setOpacity(1);
|
1773
|
+
}
|
1653
1774
|
|
1654
1775
|
|
1655
1776
|
//Add Legs.
|
@@ -1709,19 +1830,20 @@ L.MarkerCluster.include(!L.DomUtil.TRANSITION ? {
|
|
1709
1830
|
setTimeout(function () {
|
1710
1831
|
group._animationEnd();
|
1711
1832
|
group.fire('spiderfied');
|
1712
|
-
},
|
1833
|
+
}, 200);
|
1713
1834
|
},
|
1714
1835
|
|
1715
1836
|
_animationUnspiderfy: function (zoomDetails) {
|
1716
1837
|
var group = this._group,
|
1717
1838
|
map = group._map,
|
1839
|
+
fg = group._featureGroup,
|
1718
1840
|
thisLayerPos = zoomDetails ? map._latLngToNewLayerPoint(this._latlng, zoomDetails.zoom, zoomDetails.center) : map.latLngToLayerPoint(this._latlng),
|
1719
1841
|
childMarkers = this.getAllChildMarkers(),
|
1720
1842
|
svg = L.Path.SVG && this.SVG_ANIMATION,
|
1721
1843
|
m, i, a;
|
1722
1844
|
|
1723
1845
|
group._animationStart();
|
1724
|
-
|
1846
|
+
|
1725
1847
|
//Make us visible and bring the child markers back in
|
1726
1848
|
this.setOpacity(1);
|
1727
1849
|
for (i = childMarkers.length - 1; i >= 0; i--) {
|
@@ -1736,9 +1858,12 @@ L.MarkerCluster.include(!L.DomUtil.TRANSITION ? {
|
|
1736
1858
|
m.setLatLng(m._preSpiderfyLatlng);
|
1737
1859
|
delete m._preSpiderfyLatlng;
|
1738
1860
|
//Hack override the location to be our center
|
1739
|
-
m.
|
1740
|
-
|
1741
|
-
|
1861
|
+
if (m.setOpacity) {
|
1862
|
+
m._setPos(thisLayerPos);
|
1863
|
+
m.setOpacity(0);
|
1864
|
+
} else {
|
1865
|
+
fg.removeLayer(m);
|
1866
|
+
}
|
1742
1867
|
|
1743
1868
|
//Animate the spider legs back in
|
1744
1869
|
if (svg) {
|
@@ -1776,18 +1901,20 @@ L.MarkerCluster.include(!L.DomUtil.TRANSITION ? {
|
|
1776
1901
|
}
|
1777
1902
|
|
1778
1903
|
|
1779
|
-
m.setOpacity
|
1780
|
-
|
1904
|
+
if (m.setOpacity) {
|
1905
|
+
m.setOpacity(1);
|
1906
|
+
m.setZIndexOffset(0);
|
1907
|
+
}
|
1781
1908
|
|
1782
1909
|
if (stillThereChildCount > 1) {
|
1783
|
-
|
1910
|
+
fg.removeLayer(m);
|
1784
1911
|
}
|
1785
1912
|
|
1786
1913
|
map.removeLayer(m._spiderLeg);
|
1787
1914
|
delete m._spiderLeg;
|
1788
1915
|
}
|
1789
1916
|
group._animationEnd();
|
1790
|
-
},
|
1917
|
+
}, 200);
|
1791
1918
|
}
|
1792
1919
|
});
|
1793
1920
|
|
@@ -1854,10 +1981,16 @@ L.MarkerClusterGroup.include({
|
|
1854
1981
|
}
|
1855
1982
|
},
|
1856
1983
|
|
1984
|
+
_noanimationUnspiderfy: function () {
|
1985
|
+
if (this._spiderfied) {
|
1986
|
+
this._spiderfied._noanimationUnspiderfy();
|
1987
|
+
}
|
1988
|
+
},
|
1989
|
+
|
1857
1990
|
//If the given layer is currently being spiderfied then we unspiderfy it so it isn't on the map anymore etc
|
1858
1991
|
_unspiderfyLayer: function (layer) {
|
1859
1992
|
if (layer._spiderLeg) {
|
1860
|
-
|
1993
|
+
this._featureGroup.removeLayer(layer);
|
1861
1994
|
|
1862
1995
|
layer.setOpacity(1);
|
1863
1996
|
//Position will be fixed up immediately in _animationUnspiderfy
|
@@ -1870,5 +2003,4 @@ L.MarkerClusterGroup.include({
|
|
1870
2003
|
});
|
1871
2004
|
|
1872
2005
|
|
1873
|
-
|
1874
|
-
}(this));
|
2006
|
+
}(window, document));
|