vendor: 76,390 bytes, lines 1-1839
1import { 2 __commonJS 3} from "./chunk-CX3I3NQG.js"; 4 5// node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js 6var require_leaflet_markercluster_src = __commonJS({ 7 "node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js"(exports, module) { 8 (function(global, factory) { 9 typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = global || self, factory((global.Leaflet = global.Leaflet || {}, global.Leaflet.markercluster = {}))); 10 })(exports, function(exports2) { 11 "use strict"; 12 var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({ 13 options: { 14 maxClusterRadius: 80, 15 //A cluster will cover at most this many pixels from its center 16 iconCreateFunction: null, 17 clusterPane: L.Marker.prototype.options.pane, 18 spiderfyOnEveryZoom: false, 19 spiderfyOnMaxZoom: true, 20 showCoverageOnHover: true, 21 zoomToBoundsOnClick: true, 22 singleMarkerMode: false, 23 disableClusteringAtZoom: null, 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 // Set to false to disable all animations (zoom and spiderfy). 28 // If false, option animateAddingMarkers below has no effect. 29 // If L.DomUtil.TRANSITION is falsy, this option has no effect. 30 animate: true, 31 //Whether to animate adding markers after adding the MarkerClusterGroup to the map 32 // If you are adding individual markers set to true, if adding bulk markers leave false for massive performance gains. 33 animateAddingMarkers: false, 34 // Make it possible to provide custom function to calculate spiderfy shape positions 35 spiderfyShapePositions: null, 36 //Increase to increase the distance away that spiderfied markers appear from the center 37 spiderfyDistanceMultiplier: 1, 38 // Make it possible to specify a polyline options on a spider leg 39 spiderLegPolylineOptions: { weight: 1.5, color: "#222", opacity: 0.5 }, 40 // When bulk adding layers, adds markers in chunks. Means addLayers may not add all the layers in the call, others will be loaded during setTimeouts 41 chunkedLoading: false, 42 chunkInterval: 200, 43 // process markers for a maximum of ~ n milliseconds (then trigger the chunkProgress callback) 44 chunkDelay: 50, 45 // at the end of each interval, give n milliseconds back to system/browser 46 chunkProgress: null, 47 // progress callback: function(processed, total, elapsed) (e.g. for a progress indicator) 48 //Options to pass to the L.Polygon constructor 49 polygonOptions: {} 50 }, 51 initialize: function(options) { 52 L.Util.setOptions(this, options); 53 if (!this.options.iconCreateFunction) { 54 this.options.iconCreateFunction = this._defaultIconCreateFunction; 55 } 56 this._featureGroup = L.featureGroup(); 57 this._featureGroup.addEventParent(this); 58 this._nonPointGroup = L.featureGroup(); 59 this._nonPointGroup.addEventParent(this); 60 this._inZoomAnimation = 0; 61 this._needsClustering = []; 62 this._needsRemoving = []; 63 this._currentShownBounds = null; 64 this._queue = []; 65 this._childMarkerEventHandlers = { 66 "dragstart": this._childMarkerDragStart, 67 "move": this._childMarkerMoved, 68 "dragend": this._childMarkerDragEnd 69 }; 70 var animate = L.DomUtil.TRANSITION && this.options.animate; 71 L.extend(this, animate ? this._withAnimation : this._noAnimation); 72 this._markerCluster = animate ? L.MarkerCluster : L.MarkerClusterNonAnimated; 73 }, 74 addLayer: function(layer) { 75 if (layer instanceof L.LayerGroup) { 76 return this.addLayers([layer]); 77 } 78 if (!layer.getLatLng) { 79 this._nonPointGroup.addLayer(layer); 80 this.fire("layeradd", { layer }); 81 return this; 82 } 83 if (!this._map) { 84 this._needsClustering.push(layer); 85 this.fire("layeradd", { layer }); 86 return this; 87 } 88 if (this.hasLayer(layer)) { 89 return this; 90 } 91 if (this._unspiderfy) { 92 this._unspiderfy(); 93 } 94 this._addLayer(layer, this._maxZoom); 95 this.fire("layeradd", { layer }); 96 this._topClusterLevel._recalculateBounds(); 97 this._refreshClustersIcons(); 98 var visibleLayer = layer, currentZoom = this._zoom; 99 if (layer.__parent) { 100 while (visibleLayer.__parent._zoom >= currentZoom) { 101 visibleLayer = visibleLayer.__parent; 102 } 103 } 104 if (this._currentShownBounds.contains(visibleLayer.getLatLng())) { 105 if (this.options.animateAddingMarkers) { 106 this._animationAddLayer(layer, visibleLayer); 107 } else { 108 this._animationAddLayerNonAnimated(layer, visibleLayer); 109 } 110 } 111 return this; 112 }, 113 removeLayer: function(layer) { 114 if (layer instanceof L.LayerGroup) { 115 return this.removeLayers([layer]); 116 } 117 if (!layer.getLatLng) { 118 this._nonPointGroup.removeLayer(layer); 119 this.fire("layerremove", { layer }); 120 return this; 121 } 122 if (!this._map) { 123 if (!this._arraySplice(this._needsClustering, layer) && this.hasLayer(layer)) { 124 this._needsRemoving.push({ layer, latlng: layer._latlng }); 125 } 126 this.fire("layerremove", { layer }); 127 return this; 128 } 129 if (!layer.__parent) { 130 return this; 131 } 132 if (this._unspiderfy) { 133 this._unspiderfy(); 134 this._unspiderfyLayer(layer); 135 } 136 this._removeLayer(layer, true); 137 this.fire("layerremove", { layer }); 138 this._topClusterLevel._recalculateBounds(); 139 this._refreshClustersIcons(); 140 layer.off(this._childMarkerEventHandlers, this); 141 if (this._featureGroup.hasLayer(layer)) { 142 this._featureGroup.removeLayer(layer); 143 if (layer.clusterShow) { 144 layer.clusterShow(); 145 } 146 } 147 return this; 148 }, 149 //Takes an array of markers and adds them in bulk 150 addLayers: function(layersArray, skipLayerAddEvent) { 151 if (!L.Util.isArray(layersArray)) { 152 return this.addLayer(layersArray); 153 } 154 var fg = this._featureGroup, npg = this._nonPointGroup, chunked = this.options.chunkedLoading, chunkInterval = this.options.chunkInterval, chunkProgress = this.options.chunkProgress, l = layersArray.length, offset = 0, originalArray = true, m; 155 if (this._map) { 156 var started = (/* @__PURE__ */ new Date()).getTime(); 157 var process = L.bind(function() { 158 var start = (/* @__PURE__ */ new Date()).getTime(); 159 if (this._map && this._unspiderfy) { 160 this._unspiderfy(); 161 } 162 for (; offset < l; offset++) { 163 if (chunked && offset % 200 === 0) { 164 var elapsed = (/* @__PURE__ */ new Date()).getTime() - start; 165 if (elapsed > chunkInterval) { 166 break; 167 } 168 } 169 m = layersArray[offset]; 170 if (m instanceof L.LayerGroup) { 171 if (originalArray) { 172 layersArray = layersArray.slice(); 173 originalArray = false; 174 } 175 this._extractNonGroupLayers(m, layersArray); 176 l = layersArray.length; 177 continue; 178 } 179 if (!m.getLatLng) { 180 npg.addLayer(m); 181 if (!skipLayerAddEvent) { 182 this.fire("layeradd", { layer: m }); 183 } 184 continue; 185 } 186 if (this.hasLayer(m)) { 187 continue; 188 } 189 this._addLayer(m, this._maxZoom); 190 if (!skipLayerAddEvent) { 191 this.fire("layeradd", { layer: m }); 192 } 193 if (m.__parent) { 194 if (m.__parent.getChildCount() === 2) { 195 var markers = m.__parent.getAllChildMarkers(), otherMarker = markers[0] === m ? markers[1] : markers[0]; 196 fg.removeLayer(otherMarker); 197 } 198 } 199 } 200 if (chunkProgress) { 201 chunkProgress(offset, l, (/* @__PURE__ */ new Date()).getTime() - started); 202 } 203 if (offset === l) { 204 this._topClusterLevel._recalculateBounds(); 205 this._refreshClustersIcons(); 206 this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds); 207 } else { 208 setTimeout(process, this.options.chunkDelay); 209 } 210 }, this); 211 process(); 212 } else { 213 var needsClustering = this._needsClustering; 214 for (; offset < l; offset++) { 215 m = layersArray[offset]; 216 if (m instanceof L.LayerGroup) { 217 if (originalArray) { 218 layersArray = layersArray.slice(); 219 originalArray = false; 220 } 221 this._extractNonGroupLayers(m, layersArray); 222 l = layersArray.length; 223 continue; 224 } 225 if (!m.getLatLng) { 226 npg.addLayer(m); 227 continue; 228 } 229 if (this.hasLayer(m)) { 230 continue; 231 } 232 needsClustering.push(m); 233 } 234 } 235 return this; 236 }, 237 //Takes an array of markers and removes them in bulk 238 removeLayers: function(layersArray) { 239 var i, m, l = layersArray.length, fg = this._featureGroup, npg = this._nonPointGroup, originalArray = true; 240 if (!this._map) { 241 for (i = 0; i < l; i++) { 242 m = layersArray[i]; 243 if (m instanceof L.LayerGroup) { 244 if (originalArray) { 245 layersArray = layersArray.slice(); 246 originalArray = false; 247 } 248 this._extractNonGroupLayers(m, layersArray); 249 l = layersArray.length; 250 continue; 251 } 252 this._arraySplice(this._needsClustering, m); 253 npg.removeLayer(m); 254 if (this.hasLayer(m)) { 255 this._needsRemoving.push({ layer: m, latlng: m._latlng }); 256 } 257 this.fire("layerremove", { layer: m }); 258 } 259 return this; 260 } 261 if (this._unspiderfy) { 262 this._unspiderfy(); 263 var layersArray2 = layersArray.slice(), l2 = l; 264 for (i = 0; i < l2; i++) { 265 m = layersArray2[i]; 266 if (m instanceof L.LayerGroup) { 267 this._extractNonGroupLayers(m, layersArray2); 268 l2 = layersArray2.length; 269 continue; 270 } 271 this._unspiderfyLayer(m); 272 } 273 } 274 for (i = 0; i < l; i++) { 275 m = layersArray[i]; 276 if (m instanceof L.LayerGroup) { 277 if (originalArray) { 278 layersArray = layersArray.slice(); 279 originalArray = false; 280 } 281 this._extractNonGroupLayers(m, layersArray); 282 l = layersArray.length; 283 continue; 284 } 285 if (!m.__parent) { 286 npg.removeLayer(m); 287 this.fire("layerremove", { layer: m }); 288 continue; 289 } 290 this._removeLayer(m, true, true); 291 this.fire("layerremove", { layer: m }); 292 if (fg.hasLayer(m)) { 293 fg.removeLayer(m); 294 if (m.clusterShow) { 295 m.clusterShow(); 296 } 297 } 298 } 299 this._topClusterLevel._recalculateBounds(); 300 this._refreshClustersIcons(); 301 this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds); 302 return this; 303 }, 304 //Removes all layers from the MarkerClusterGroup 305 clearLayers: function() { 306 if (!this._map) { 307 this._needsClustering = []; 308 this._needsRemoving = []; 309 delete this._gridClusters; 310 delete this._gridUnclustered; 311 } 312 if (this._noanimationUnspiderfy) { 313 this._noanimationUnspiderfy(); 314 } 315 this._featureGroup.clearLayers(); 316 this._nonPointGroup.clearLayers(); 317 this.eachLayer(function(marker) { 318 marker.off(this._childMarkerEventHandlers, this); 319 delete marker.__parent; 320 }, this); 321 if (this._map) { 322 this._generateInitialClusters(); 323 } 324 return this; 325 }, 326 //Override FeatureGroup.getBounds as it doesn't work 327 getBounds: function() { 328 var bounds = new L.LatLngBounds(); 329 if (this._topClusterLevel) { 330 bounds.extend(this._topClusterLevel._bounds); 331 } 332 for (var i = this._needsClustering.length - 1; i >= 0; i--) { 333 bounds.extend(this._needsClustering[i].getLatLng()); 334 } 335 bounds.extend(this._nonPointGroup.getBounds()); 336 return bounds; 337 }, 338 //Overrides LayerGroup.eachLayer 339 eachLayer: function(method, context) { 340 var markers = this._needsClustering.slice(), needsRemoving = this._needsRemoving, thisNeedsRemoving, i, j; 341 if (this._topClusterLevel) { 342 this._topClusterLevel.getAllChildMarkers(markers); 343 } 344 for (i = markers.length - 1; i >= 0; i--) { 345 thisNeedsRemoving = true; 346 for (j = needsRemoving.length - 1; j >= 0; j--) { 347 if (needsRemoving[j].layer === markers[i]) { 348 thisNeedsRemoving = false; 349 break; 350 } 351 } 352 if (thisNeedsRemoving) { 353 method.call(context, markers[i]); 354 } 355 } 356 this._nonPointGroup.eachLayer(method, context); 357 }, 358 //Overrides LayerGroup.getLayers 359 getLayers: function() { 360 var layers = []; 361 this.eachLayer(function(l) { 362 layers.push(l); 363 }); 364 return layers; 365 }, 366 //Overrides LayerGroup.getLayer, WARNING: Really bad performance 367 getLayer: function(id) { 368 var result = null; 369 id = parseInt(id, 10); 370 this.eachLayer(function(l) { 371 if (L.stamp(l) === id) { 372 result = l; 373 } 374 }); 375 return result; 376 }, 377 //Returns true if the given layer is in this MarkerClusterGroup 378 hasLayer: function(layer) { 379 if (!layer) { 380 return false; 381 } 382 var i, anArray = this._needsClustering; 383 for (i = anArray.length - 1; i >= 0; i--) { 384 if (anArray[i] === layer) { 385 return true; 386 } 387 } 388 anArray = this._needsRemoving; 389 for (i = anArray.length - 1; i >= 0; i--) { 390 if (anArray[i].layer === layer) { 391 return false; 392 } 393 } 394 return !!(layer.__parent && layer.__parent._group === this) || this._nonPointGroup.hasLayer(layer); 395 }, 396 //Zoom down to show the given layer (spiderfying if necessary) then calls the callback 397 zoomToShowLayer: function(layer, callback) { 398 var map = this._map; 399 if (typeof callback !== "function") { 400 callback = function() { 401 }; 402 } 403 var showMarker = function() { 404 if ((map.hasLayer(layer) || map.hasLayer(layer.__parent)) && !this._inZoomAnimation) { 405 this._map.off("moveend", showMarker, this); 406 this.off("animationend", showMarker, this); 407 if (map.hasLayer(layer)) { 408 callback(); 409 } else if (layer.__parent._icon) { 410 this.once("spiderfied", callback, this); 411 layer.__parent.spiderfy(); 412 } 413 } 414 }; 415 if (layer._icon && this._map.getBounds().contains(layer.getLatLng())) { 416 callback(); 417 } else if (layer.__parent._zoom < Math.round(this._map._zoom)) { 418 this._map.on("moveend", showMarker, this); 419 this._map.panTo(layer.getLatLng()); 420 } else { 421 this._map.on("moveend", showMarker, this); 422 this.on("animationend", showMarker, this); 423 layer.__parent.zoomToBounds(); 424 } 425 }, 426 //Overrides FeatureGroup.onAdd 427 onAdd: function(map) { 428 this._map = map; 429 var i, l, layer; 430 if (!isFinite(this._map.getMaxZoom())) { 431 throw "Map has no maxZoom specified"; 432 } 433 this._featureGroup.addTo(map); 434 this._nonPointGroup.addTo(map); 435 if (!this._gridClusters) { 436 this._generateInitialClusters(); 437 } 438 this._maxLat = map.options.crs.projection.MAX_LATITUDE; 439 for (i = 0, l = this._needsRemoving.length; i < l; i++) { 440 layer = this._needsRemoving[i]; 441 layer.newlatlng = layer.layer._latlng; 442 layer.layer._latlng = layer.latlng; 443 } 444 for (i = 0, l = this._needsRemoving.length; i < l; i++) { 445 layer = this._needsRemoving[i]; 446 this._removeLayer(layer.layer, true); 447 layer.layer._latlng = layer.newlatlng; 448 } 449 this._needsRemoving = []; 450 this._zoom = Math.round(this._map._zoom); 451 this._currentShownBounds = this._getExpandedVisibleBounds(); 452 this._map.on("zoomend", this._zoomEnd, this); 453 this._map.on("moveend", this._moveEnd, this); 454 if (this._spiderfierOnAdd) { 455 this._spiderfierOnAdd(); 456 } 457 this._bindEvents(); 458 l = this._needsClustering; 459 this._needsClustering = []; 460 this.addLayers(l, true); 461 }, 462 //Overrides FeatureGroup.onRemove 463 onRemove: function(map) { 464 map.off("zoomend", this._zoomEnd, this); 465 map.off("moveend", this._moveEnd, this); 466 this._unbindEvents(); 467 this._map._mapPane.className = this._map._mapPane.className.replace(" leaflet-cluster-anim", ""); 468 if (this._spiderfierOnRemove) { 469 this._spiderfierOnRemove(); 470 } 471 delete this._maxLat; 472 this._hideCoverage(); 473 this._featureGroup.remove(); 474 this._nonPointGroup.remove(); 475 this._featureGroup.clearLayers(); 476 this._map = null; 477 }, 478 getVisibleParent: function(marker) { 479 var vMarker = marker; 480 while (vMarker && !vMarker._icon) { 481 vMarker = vMarker.__parent; 482 } 483 return vMarker || null; 484 }, 485 //Remove the given object from the given array 486 _arraySplice: function(anArray, obj) { 487 for (var i = anArray.length - 1; i >= 0; i--) { 488 if (anArray[i] === obj) { 489 anArray.splice(i, 1); 490 return true; 491 } 492 } 493 }, 494 /** 495 * Removes a marker from all _gridUnclustered zoom levels, starting at the supplied zoom. 496 * @param marker to be removed from _gridUnclustered. 497 * @param z integer bottom start zoom level (included) 498 * @private 499 */ 500 _removeFromGridUnclustered: function(marker, z) { 501 var map = this._map, gridUnclustered = this._gridUnclustered, minZoom = Math.floor(this._map.getMinZoom()); 502 for (; z >= minZoom; z--) { 503 if (!gridUnclustered[z].removeObject(marker, map.project(marker.getLatLng(), z))) { 504 break; 505 } 506 } 507 }, 508 _childMarkerDragStart: function(e) { 509 e.target.__dragStart = e.target._latlng; 510 }, 511 _childMarkerMoved: function(e) { 512 if (!this._ignoreMove && !e.target.__dragStart) { 513 var isPopupOpen = e.target._popup && e.target._popup.isOpen(); 514 this._moveChild(e.target, e.oldLatLng, e.latlng); 515 if (isPopupOpen) { 516 e.target.openPopup(); 517 } 518 } 519 }, 520 _moveChild: function(layer, from, to) { 521 layer._latlng = from; 522 this.removeLayer(layer); 523 layer._latlng = to; 524 this.addLayer(layer); 525 }, 526 _childMarkerDragEnd: function(e) { 527 var dragStart = e.target.__dragStart; 528 delete e.target.__dragStart; 529 if (dragStart) { 530 this._moveChild(e.target, dragStart, e.target._latlng); 531 } 532 }, 533 //Internal function for removing a marker from everything. 534 //dontUpdateMap: set to true if you will handle updating the map manually (for bulk functions) 535 _removeLayer: function(marker, removeFromDistanceGrid, dontUpdateMap) { 536 var gridClusters = this._gridClusters, gridUnclustered = this._gridUnclustered, fg = this._featureGroup, map = this._map, minZoom = Math.floor(this._map.getMinZoom()); 537 if (removeFromDistanceGrid) { 538 this._removeFromGridUnclustered(marker, this._maxZoom); 539 } 540 var cluster = marker.__parent, markers = cluster._markers, otherMarker; 541 this._arraySplice(markers, marker); 542 while (cluster) { 543 cluster._childCount--; 544 cluster._boundsNeedUpdate = true; 545 if (cluster._zoom < minZoom) { 546 break; 547 } else if (removeFromDistanceGrid && cluster._childCount <= 1) { 548 otherMarker = cluster._markers[0] === marker ? cluster._markers[1] : cluster._markers[0]; 549 gridClusters[cluster._zoom].removeObject(cluster, map.project(cluster._cLatLng, cluster._zoom)); 550 gridUnclustered[cluster._zoom].addObject(otherMarker, map.project(otherMarker.getLatLng(), cluster._zoom)); 551 this._arraySplice(cluster.__parent._childClusters, cluster); 552 cluster.__parent._markers.push(otherMarker); 553 otherMarker.__parent = cluster.__parent; 554 if (cluster._icon) { 555 fg.removeLayer(cluster); 556 if (!dontUpdateMap) { 557 fg.addLayer(otherMarker); 558 } 559 } 560 } else { 561 cluster._iconNeedsUpdate = true; 562 } 563 cluster = cluster.__parent; 564 } 565 delete marker.__parent; 566 }, 567 _isOrIsParent: function(el, oel) { 568 while (oel) { 569 if (el === oel) { 570 return true; 571 } 572 oel = oel.parentNode; 573 } 574 return false; 575 }, 576 //Override L.Evented.fire 577 fire: function(type, data, propagate) { 578 if (data && data.layer instanceof L.MarkerCluster) { 579 if (data.originalEvent && this._isOrIsParent(data.layer._icon, data.originalEvent.relatedTarget)) { 580 return; 581 } 582 type = "cluster" + type; 583 } 584 L.FeatureGroup.prototype.fire.call(this, type, data, propagate); 585 }, 586 //Override L.Evented.listens 587 listens: function(type, propagate) { 588 return L.FeatureGroup.prototype.listens.call(this, type, propagate) || L.FeatureGroup.prototype.listens.call(this, "cluster" + type, propagate); 589 }, 590 //Default functionality 591 _defaultIconCreateFunction: function(cluster) { 592 var childCount = cluster.getChildCount(); 593 var c = " marker-cluster-"; 594 if (childCount < 10) { 595 c += "small"; 596 } else if (childCount < 100) { 597 c += "medium"; 598 } else { 599 c += "large"; 600 } 601 return new L.DivIcon({ html: "<div><span>" + childCount + "</span></div>", className: "marker-cluster" + c, iconSize: new L.Point(40, 40) }); 602 }, 603 _bindEvents: function() { 604 var map = this._map, spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom, showCoverageOnHover = this.options.showCoverageOnHover, zoomToBoundsOnClick = this.options.zoomToBoundsOnClick, spiderfyOnEveryZoom = this.options.spiderfyOnEveryZoom; 605 if (spiderfyOnMaxZoom || zoomToBoundsOnClick || spiderfyOnEveryZoom) { 606 this.on("clusterclick clusterkeypress", this._zoomOrSpiderfy, this); 607 } 608 if (showCoverageOnHover) { 609 this.on("clustermouseover", this._showCoverage, this); 610 this.on("clustermouseout", this._hideCoverage, this); 611 map.on("zoomend", this._hideCoverage, this); 612 } 613 }, 614 _zoomOrSpiderfy: function(e) { 615 var cluster = e.layer, bottomCluster = cluster; 616 if (e.type === "clusterkeypress" && e.originalEvent && e.originalEvent.keyCode !== 13) { 617 return; 618 } 619 while (bottomCluster._childClusters.length === 1) { 620 bottomCluster = bottomCluster._childClusters[0]; 621 } 622 if (bottomCluster._zoom === this._maxZoom && bottomCluster._childCount === cluster._childCount && this.options.spiderfyOnMaxZoom) { 623 cluster.spiderfy(); 624 } else if (this.options.zoomToBoundsOnClick) { 625 cluster.zoomToBounds(); 626 } 627 if (this.options.spiderfyOnEveryZoom) { 628 cluster.spiderfy(); 629 } 630 if (e.originalEvent && e.originalEvent.keyCode === 13) { 631 this._map._container.focus(); 632 } 633 }, 634 _showCoverage: function(e) { 635 var map = this._map; 636 if (this._inZoomAnimation) { 637 return; 638 } 639 if (this._shownPolygon) { 640 map.removeLayer(this._shownPolygon); 641 } 642 if (e.layer.getChildCount() > 2 && e.layer !== this._spiderfied) { 643 this._shownPolygon = new L.Polygon(e.layer.getConvexHull(), this.options.polygonOptions); 644 map.addLayer(this._shownPolygon); 645 } 646 }, 647 _hideCoverage: function() { 648 if (this._shownPolygon) { 649 this._map.removeLayer(this._shownPolygon); 650 this._shownPolygon = null; 651 } 652 }, 653 _unbindEvents: function() { 654 var spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom, showCoverageOnHover = this.options.showCoverageOnHover, zoomToBoundsOnClick = this.options.zoomToBoundsOnClick, spiderfyOnEveryZoom = this.options.spiderfyOnEveryZoom, map = this._map; 655 if (spiderfyOnMaxZoom || zoomToBoundsOnClick || spiderfyOnEveryZoom) { 656 this.off("clusterclick clusterkeypress", this._zoomOrSpiderfy, this); 657 } 658 if (showCoverageOnHover) { 659 this.off("clustermouseover", this._showCoverage, this); 660 this.off("clustermouseout", this._hideCoverage, this); 661 map.off("zoomend", this._hideCoverage, this); 662 } 663 }, 664 _zoomEnd: function() { 665 if (!this._map) { 666 return; 667 } 668 this._mergeSplitClusters(); 669 this._zoom = Math.round(this._map._zoom); 670 this._currentShownBounds = this._getExpandedVisibleBounds(); 671 }, 672 _moveEnd: function() { 673 if (this._inZoomAnimation) { 674 return; 675 } 676 var newBounds = this._getExpandedVisibleBounds(); 677 this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), this._zoom, newBounds); 678 this._topClusterLevel._recursivelyAddChildrenToMap(null, Math.round(this._map._zoom), newBounds); 679 this._currentShownBounds = newBounds; 680 return; 681 }, 682 _generateInitialClusters: function() { 683 var maxZoom = Math.ceil(this._map.getMaxZoom()), minZoom = Math.floor(this._map.getMinZoom()), radius = this.options.maxClusterRadius, radiusFn = radius; 684 if (typeof radius !== "function") { 685 radiusFn = function() { 686 return radius; 687 }; 688 } 689 if (this.options.disableClusteringAtZoom !== null) { 690 maxZoom = this.options.disableClusteringAtZoom - 1; 691 } 692 this._maxZoom = maxZoom; 693 this._gridClusters = {}; 694 this._gridUnclustered = {}; 695 for (var zoom = maxZoom; zoom >= minZoom; zoom--) { 696 this._gridClusters[zoom] = new L.DistanceGrid(radiusFn(zoom)); 697 this._gridUnclustered[zoom] = new L.DistanceGrid(radiusFn(zoom)); 698 } 699 this._topClusterLevel = new this._markerCluster(this, minZoom - 1); 700 }, 701 //Zoom: Zoom to start adding at (Pass this._maxZoom to start at the bottom) 702 _addLayer: function(layer, zoom) { 703 var gridClusters = this._gridClusters, gridUnclustered = this._gridUnclustered, minZoom = Math.floor(this._map.getMinZoom()), markerPoint, z; 704 if (this.options.singleMarkerMode) { 705 this._overrideMarkerIcon(layer); 706 } 707 layer.on(this._childMarkerEventHandlers, this); 708 for (; zoom >= minZoom; zoom--) { 709 markerPoint = this._map.project(layer.getLatLng(), zoom); 710 var closest = gridClusters[zoom].getNearObject(markerPoint); 711 if (closest) { 712 closest._addChild(layer); 713 layer.__parent = closest; 714 return; 715 } 716 closest = gridUnclustered[zoom].getNearObject(markerPoint); 717 if (closest) { 718 var parent = closest.__parent; 719 if (parent) { 720 this._removeLayer(closest, false); 721 } 722 var newCluster = new this._markerCluster(this, zoom, closest, layer); 723 gridClusters[zoom].addObject(newCluster, this._map.project(newCluster._cLatLng, zoom)); 724 closest.__parent = newCluster; 725 layer.__parent = newCluster; 726 var lastParent = newCluster; 727 for (z = zoom - 1; z > parent._zoom; z--) { 728 lastParent = new this._markerCluster(this, z, lastParent); 729 gridClusters[z].addObject(lastParent, this._map.project(closest.getLatLng(), z)); 730 } 731 parent._addChild(lastParent); 732 this._removeFromGridUnclustered(closest, zoom); 733 return; 734 } 735 gridUnclustered[zoom].addObject(layer, markerPoint); 736 } 737 this._topClusterLevel._addChild(layer); 738 layer.__parent = this._topClusterLevel; 739 return; 740 }, 741 /** 742 * Refreshes the icon of all "dirty" visible clusters. 743 * Non-visible "dirty" clusters will be updated when they are added to the map. 744 * @private 745 */ 746 _refreshClustersIcons: function() { 747 this._featureGroup.eachLayer(function(c) { 748 if (c instanceof L.MarkerCluster && c._iconNeedsUpdate) { 749 c._updateIcon(); 750 } 751 }); 752 }, 753 //Enqueue code to fire after the marker expand/contract has happened 754 _enqueue: function(fn) { 755 this._queue.push(fn); 756 if (!this._queueTimeout) { 757 this._queueTimeout = setTimeout(L.bind(this._processQueue, this), 300); 758 } 759 }, 760 _processQueue: function() { 761 for (var i = 0; i < this._queue.length; i++) { 762 this._queue[i].call(this); 763 } 764 this._queue.length = 0; 765 clearTimeout(this._queueTimeout); 766 this._queueTimeout = null; 767 }, 768 //Merge and split any existing clusters that are too big or small 769 _mergeSplitClusters: function() { 770 var mapZoom = Math.round(this._map._zoom); 771 this._processQueue(); 772 if (this._zoom < mapZoom && this._currentShownBounds.intersects(this._getExpandedVisibleBounds())) { 773 this._animationStart(); 774 this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), this._zoom, this._getExpandedVisibleBounds()); 775 this._animationZoomIn(this._zoom, mapZoom); 776 } else if (this._zoom > mapZoom) { 777 this._animationStart(); 778 this._animationZoomOut(this._zoom, mapZoom); 779 } else { 780 this._moveEnd(); 781 } 782 }, 783 //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) 784 _getExpandedVisibleBounds: function() { 785 if (!this.options.removeOutsideVisibleBounds) { 786 return this._mapBoundsInfinite; 787 } else if (L.Browser.mobile) { 788 return this._checkBoundsMaxLat(this._map.getBounds()); 789 } 790 return this._checkBoundsMaxLat(this._map.getBounds().pad(1)); 791 }, 792 /** 793 * Expands the latitude to Infinity (or -Infinity) if the input bounds reach the map projection maximum defined latitude 794 * (in the case of Web/Spherical Mercator, it is 85.0511287798 / see https://en.wikipedia.org/wiki/Web_Mercator#Formulas). 795 * Otherwise, the removeOutsideVisibleBounds option will remove markers beyond that limit, whereas the same markers without 796 * this option (or outside MCG) will have their position floored (ceiled) by the projection and rendered at that limit, 797 * making the user think that MCG "eats" them and never displays them again. 798 * @param bounds L.LatLngBounds 799 * @returns {L.LatLngBounds} 800 * @private 801 */ 802 _checkBoundsMaxLat: function(bounds) { 803 var maxLat = this._maxLat; 804 if (maxLat !== void 0) { 805 if (bounds.getNorth() >= maxLat) { 806 bounds._northEast.lat = Infinity; 807 } 808 if (bounds.getSouth() <= -maxLat) { 809 bounds._southWest.lat = -Infinity; 810 } 811 } 812 return bounds; 813 }, 814 //Shared animation code 815 _animationAddLayerNonAnimated: function(layer, newCluster) { 816 if (newCluster === layer) { 817 this._featureGroup.addLayer(layer); 818 } else if (newCluster._childCount === 2) { 819 newCluster._addToMap(); 820 var markers = newCluster.getAllChildMarkers(); 821 this._featureGroup.removeLayer(markers[0]); 822 this._featureGroup.removeLayer(markers[1]); 823 } else { 824 newCluster._updateIcon(); 825 } 826 }, 827 /** 828 * Extracts individual (i.e. non-group) layers from a Layer Group. 829 * @param group to extract layers from. 830 * @param output {Array} in which to store the extracted layers. 831 * @returns {*|Array} 832 * @private 833 */ 834 _extractNonGroupLayers: function(group, output) { 835 var layers = group.getLayers(), i = 0, layer; 836 output = output || []; 837 for (; i < layers.length; i++) { 838 layer = layers[i]; 839 if (layer instanceof L.LayerGroup) { 840 this._extractNonGroupLayers(layer, output); 841 continue; 842 } 843 output.push(layer); 844 } 845 return output; 846 }, 847 /** 848 * Implements the singleMarkerMode option. 849 * @param layer Marker to re-style using the Clusters iconCreateFunction. 850 * @returns {L.Icon} The newly created icon. 851 * @private 852 */ 853 _overrideMarkerIcon: function(layer) { 854 var icon = layer.options.icon = this.options.iconCreateFunction({ 855 getChildCount: function() { 856 return 1; 857 }, 858 getAllChildMarkers: function() { 859 return [layer]; 860 } 861 }); 862 return icon; 863 } 864 }); 865 L.MarkerClusterGroup.include({ 866 _mapBoundsInfinite: new L.LatLngBounds(new L.LatLng(-Infinity, -Infinity), new L.LatLng(Infinity, Infinity)) 867 }); 868 L.MarkerClusterGroup.include({ 869 _noAnimation: { 870 //Non Animated versions of everything 871 _animationStart: function() { 872 }, 873 _animationZoomIn: function(previousZoomLevel, newZoomLevel) { 874 this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), previousZoomLevel); 875 this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds()); 876 this.fire("animationend"); 877 }, 878 _animationZoomOut: function(previousZoomLevel, newZoomLevel) { 879 this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), previousZoomLevel); 880 this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds()); 881 this.fire("animationend"); 882 }, 883 _animationAddLayer: function(layer, newCluster) { 884 this._animationAddLayerNonAnimated(layer, newCluster); 885 } 886 }, 887 _withAnimation: { 888 //Animated versions here 889 _animationStart: function() { 890 this._map._mapPane.className += " leaflet-cluster-anim"; 891 this._inZoomAnimation++; 892 }, 893 _animationZoomIn: function(previousZoomLevel, newZoomLevel) { 894 var bounds = this._getExpandedVisibleBounds(), fg = this._featureGroup, minZoom = Math.floor(this._map.getMinZoom()), i; 895 this._ignoreMove = true; 896 this._topClusterLevel._recursively(bounds, previousZoomLevel, minZoom, function(c) { 897 var startPos = c._latlng, markers = c._markers, m; 898 if (!bounds.contains(startPos)) { 899 startPos = null; 900 } 901 if (c._isSingleParent() && previousZoomLevel + 1 === newZoomLevel) { 902 fg.removeLayer(c); 903 c._recursivelyAddChildrenToMap(null, newZoomLevel, bounds); 904 } else { 905 c.clusterHide(); 906 c._recursivelyAddChildrenToMap(startPos, newZoomLevel, bounds); 907 } 908 for (i = markers.length - 1; i >= 0; i--) { 909 m = markers[i]; 910 if (!bounds.contains(m._latlng)) { 911 fg.removeLayer(m); 912 } 913 } 914 }); 915 this._forceLayout(); 916 this._topClusterLevel._recursivelyBecomeVisible(bounds, newZoomLevel); 917 fg.eachLayer(function(n) { 918 if (!(n instanceof L.MarkerCluster) && n._icon) { 919 n.clusterShow(); 920 } 921 }); 922 this._topClusterLevel._recursively(bounds, previousZoomLevel, newZoomLevel, function(c) { 923 c._recursivelyRestoreChildPositions(newZoomLevel); 924 }); 925 this._ignoreMove = false; 926 this._enqueue(function() { 927 this._topClusterLevel._recursively(bounds, previousZoomLevel, minZoom, function(c) { 928 fg.removeLayer(c); 929 c.clusterShow(); 930 }); 931 this._animationEnd(); 932 }); 933 }, 934 _animationZoomOut: function(previousZoomLevel, newZoomLevel) { 935 this._animationZoomOutSingle(this._topClusterLevel, previousZoomLevel - 1, newZoomLevel); 936 this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds()); 937 this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), previousZoomLevel, this._getExpandedVisibleBounds()); 938 }, 939 _animationAddLayer: function(layer, newCluster) { 940 var me = this, fg = this._featureGroup; 941 fg.addLayer(layer); 942 if (newCluster !== layer) { 943 if (newCluster._childCount > 2) { 944 newCluster._updateIcon(); 945 this._forceLayout(); 946 this._animationStart(); 947 layer._setPos(this._map.latLngToLayerPoint(newCluster.getLatLng())); 948 layer.clusterHide(); 949 this._enqueue(function() { 950 fg.removeLayer(layer); 951 layer.clusterShow(); 952 me._animationEnd(); 953 }); 954 } else { 955 this._forceLayout(); 956 me._animationStart(); 957 me._animationZoomOutSingle(newCluster, this._map.getMaxZoom(), this._zoom); 958 } 959 } 960 } 961 }, 962 // Private methods for animated versions. 963 _animationZoomOutSingle: function(cluster, previousZoomLevel, newZoomLevel) { 964 var bounds = this._getExpandedVisibleBounds(), minZoom = Math.floor(this._map.getMinZoom()); 965 cluster._recursivelyAnimateChildrenInAndAddSelfToMap(bounds, minZoom, previousZoomLevel + 1, newZoomLevel); 966 var me = this; 967 this._forceLayout(); 968 cluster._recursivelyBecomeVisible(bounds, newZoomLevel); 969 this._enqueue(function() { 970 if (cluster._childCount === 1) { 971 var m = cluster._markers[0]; 972 this._ignoreMove = true; 973 m.setLatLng(m.getLatLng()); 974 this._ignoreMove = false; 975 if (m.clusterShow) { 976 m.clusterShow(); 977 } 978 } else { 979 cluster._recursively(bounds, newZoomLevel, minZoom, function(c) { 980 c._recursivelyRemoveChildrenFromMap(bounds, minZoom, previousZoomLevel + 1); 981 }); 982 } 983 me._animationEnd(); 984 }); 985 }, 986 _animationEnd: function() { 987 if (this._map) { 988 this._map._mapPane.className = this._map._mapPane.className.replace(" leaflet-cluster-anim", ""); 989 } 990 this._inZoomAnimation--; 991 this.fire("animationend"); 992 }, 993 //Force a browser layout of stuff in the map 994 // Should apply the current opacity and location to all elements so we can update them again for an animation 995 _forceLayout: function() { 996 L.Util.falseFn(document.body.offsetWidth); 997 } 998 }); 999 L.markerClusterGroup = function(options) { 1000 return new L.MarkerClusterGroup(options); 1001 }; 1002 var MarkerCluster = L.MarkerCluster = L.Marker.extend({ 1003 options: L.Icon.prototype.options, 1004 initialize: function(group, zoom, a, b) { 1005 L.Marker.prototype.initialize.call( 1006 this, 1007 a ? a._cLatLng || a.getLatLng() : new L.LatLng(0, 0), 1008 { icon: this, pane: group.options.clusterPane } 1009 ); 1010 this._group = group; 1011 this._zoom = zoom; 1012 this._markers = []; 1013 this._childClusters = []; 1014 this._childCount = 0; 1015 this._iconNeedsUpdate = true; 1016 this._boundsNeedUpdate = true; 1017 this._bounds = new L.LatLngBounds(); 1018 if (a) { 1019 this._addChild(a); 1020 } 1021 if (b) { 1022 this._addChild(b); 1023 } 1024 }, 1025 //Recursively retrieve all child markers of this cluster 1026 getAllChildMarkers: function(storageArray, ignoreDraggedMarker) { 1027 storageArray = storageArray || []; 1028 for (var i = this._childClusters.length - 1; i >= 0; i--) { 1029 this._childClusters[i].getAllChildMarkers(storageArray, ignoreDraggedMarker); 1030 } 1031 for (var j = this._markers.length - 1; j >= 0; j--) { 1032 if (ignoreDraggedMarker && this._markers[j].__dragStart) { 1033 continue; 1034 } 1035 storageArray.push(this._markers[j]); 1036 } 1037 return storageArray; 1038 }, 1039 //Returns the count of how many child markers we have 1040 getChildCount: function() { 1041 return this._childCount; 1042 }, 1043 //Zoom to the minimum of showing all of the child markers, or the extents of this cluster 1044 zoomToBounds: function(fitBoundsOptions) { 1045 var childClusters = this._childClusters.slice(), map = this._group._map, boundsZoom = map.getBoundsZoom(this._bounds), zoom = this._zoom + 1, mapZoom = map.getZoom(), i; 1046 while (childClusters.length > 0 && boundsZoom > zoom) { 1047 zoom++; 1048 var newClusters = []; 1049 for (i = 0; i < childClusters.length; i++) { 1050 newClusters = newClusters.concat(childClusters[i]._childClusters); 1051 } 1052 childClusters = newClusters; 1053 } 1054 if (boundsZoom > zoom) { 1055 this._group._map.setView(this._latlng, zoom); 1056 } else if (boundsZoom <= mapZoom) { 1057 this._group._map.setView(this._latlng, mapZoom + 1); 1058 } else { 1059 this._group._map.fitBounds(this._bounds, fitBoundsOptions); 1060 } 1061 }, 1062 getBounds: function() { 1063 var bounds = new L.LatLngBounds(); 1064 bounds.extend(this._bounds); 1065 return bounds; 1066 }, 1067 _updateIcon: function() { 1068 this._iconNeedsUpdate = true; 1069 if (this._icon) { 1070 this.setIcon(this); 1071 } 1072 }, 1073 //Cludge for Icon, we pretend to be an icon for performance 1074 createIcon: function() { 1075 if (this._iconNeedsUpdate) { 1076 this._iconObj = this._group.options.iconCreateFunction(this); 1077 this._iconNeedsUpdate = false; 1078 } 1079 return this._iconObj.createIcon(); 1080 }, 1081 createShadow: function() { 1082 return this._iconObj.createShadow(); 1083 }, 1084 _addChild: function(new1, isNotificationFromChild) { 1085 this._iconNeedsUpdate = true; 1086 this._boundsNeedUpdate = true; 1087 this._setClusterCenter(new1); 1088 if (new1 instanceof L.MarkerCluster) { 1089 if (!isNotificationFromChild) { 1090 this._childClusters.push(new1); 1091 new1.__parent = this; 1092 } 1093 this._childCount += new1._childCount; 1094 } else { 1095 if (!isNotificationFromChild) { 1096 this._markers.push(new1); 1097 } 1098 this._childCount++; 1099 } 1100 if (this.__parent) { 1101 this.__parent._addChild(new1, true); 1102 } 1103 }, 1104 /** 1105 * Makes sure the cluster center is set. If not, uses the child center if it is a cluster, or the marker position. 1106 * @param child L.MarkerCluster|L.Marker that will be used as cluster center if not defined yet. 1107 * @private 1108 */ 1109 _setClusterCenter: function(child) { 1110 if (!this._cLatLng) { 1111 this._cLatLng = child._cLatLng || child._latlng; 1112 } 1113 }, 1114 /** 1115 * Assigns impossible bounding values so that the next extend entirely determines the new bounds. 1116 * This method avoids having to trash the previous L.LatLngBounds object and to create a new one, which is much slower for this class. 1117 * As long as the bounds are not extended, most other methods would probably fail, as they would with bounds initialized but not extended. 1118 * @private 1119 */ 1120 _resetBounds: function() { 1121 var bounds = this._bounds; 1122 if (bounds._southWest) { 1123 bounds._southWest.lat = Infinity; 1124 bounds._southWest.lng = Infinity; 1125 } 1126 if (bounds._northEast) { 1127 bounds._northEast.lat = -Infinity; 1128 bounds._northEast.lng = -Infinity; 1129 } 1130 }, 1131 _recalculateBounds: function() { 1132 var markers = this._markers, childClusters = this._childClusters, latSum = 0, lngSum = 0, totalCount = this._childCount, i, child, childLatLng, childCount; 1133 if (totalCount === 0) { 1134 return; 1135 } 1136 this._resetBounds(); 1137 for (i = 0; i < markers.length; i++) { 1138 childLatLng = markers[i]._latlng; 1139 this._bounds.extend(childLatLng); 1140 latSum += childLatLng.lat; 1141 lngSum += childLatLng.lng; 1142 } 1143 for (i = 0; i < childClusters.length; i++) { 1144 child = childClusters[i]; 1145 if (child._boundsNeedUpdate) { 1146 child._recalculateBounds(); 1147 } 1148 this._bounds.extend(child._bounds); 1149 childLatLng = child._wLatLng; 1150 childCount = child._childCount; 1151 latSum += childLatLng.lat * childCount; 1152 lngSum += childLatLng.lng * childCount; 1153 } 1154 this._latlng = this._wLatLng = new L.LatLng(latSum / totalCount, lngSum / totalCount); 1155 this._boundsNeedUpdate = false; 1156 }, 1157 //Set our markers position as given and add it to the map 1158 _addToMap: function(startPos) { 1159 if (startPos) { 1160 this._backupLatlng = this._latlng; 1161 this.setLatLng(startPos); 1162 } 1163 this._group._featureGroup.addLayer(this); 1164 }, 1165 _recursivelyAnimateChildrenIn: function(bounds, center, maxZoom) { 1166 this._recursively( 1167 bounds, 1168 this._group._map.getMinZoom(), 1169 maxZoom - 1, 1170 function(c) { 1171 var markers = c._markers, i, m; 1172 for (i = markers.length - 1; i >= 0; i--) { 1173 m = markers[i]; 1174 if (m._icon) { 1175 m._setPos(center); 1176 m.clusterHide(); 1177 } 1178 } 1179 }, 1180 function(c) { 1181 var childClusters = c._childClusters, j, cm; 1182 for (j = childClusters.length - 1; j >= 0; j--) { 1183 cm = childClusters[j]; 1184 if (cm._icon) { 1185 cm._setPos(center); 1186 cm.clusterHide(); 1187 } 1188 } 1189 } 1190 ); 1191 }, 1192 _recursivelyAnimateChildrenInAndAddSelfToMap: function(bounds, mapMinZoom, previousZoomLevel, newZoomLevel) { 1193 this._recursively( 1194 bounds, 1195 newZoomLevel, 1196 mapMinZoom, 1197 function(c) { 1198 c._recursivelyAnimateChildrenIn(bounds, c._group._map.latLngToLayerPoint(c.getLatLng()).round(), previousZoomLevel); 1199 if (c._isSingleParent() && previousZoomLevel - 1 === newZoomLevel) { 1200 c.clusterShow(); 1201 c._recursivelyRemoveChildrenFromMap(bounds, mapMinZoom, previousZoomLevel); 1202 } else { 1203 c.clusterHide(); 1204 } 1205 c._addToMap(); 1206 } 1207 ); 1208 }, 1209 _recursivelyBecomeVisible: function(bounds, zoomLevel) { 1210 this._recursively(bounds, this._group._map.getMinZoom(), zoomLevel, null, function(c) { 1211 c.clusterShow(); 1212 }); 1213 }, 1214 _recursivelyAddChildrenToMap: function(startPos, zoomLevel, bounds) { 1215 this._recursively( 1216 bounds, 1217 this._group._map.getMinZoom() - 1, 1218 zoomLevel, 1219 function(c) { 1220 if (zoomLevel === c._zoom) { 1221 return; 1222 } 1223 for (var i = c._markers.length - 1; i >= 0; i--) { 1224 var nm = c._markers[i]; 1225 if (!bounds.contains(nm._latlng)) { 1226 continue; 1227 } 1228 if (startPos) { 1229 nm._backupLatlng = nm.getLatLng(); 1230 nm.setLatLng(startPos); 1231 if (nm.clusterHide) { 1232 nm.clusterHide(); 1233 } 1234 } 1235 c._group._featureGroup.addLayer(nm); 1236 } 1237 }, 1238 function(c) { 1239 c._addToMap(startPos); 1240 } 1241 ); 1242 }, 1243 _recursivelyRestoreChildPositions: function(zoomLevel) { 1244 for (var i = this._markers.length - 1; i >= 0; i--) { 1245 var nm = this._markers[i]; 1246 if (nm._backupLatlng) { 1247 nm.setLatLng(nm._backupLatlng); 1248 delete nm._backupLatlng; 1249 } 1250 } 1251 if (zoomLevel - 1 === this._zoom) { 1252 for (var j = this._childClusters.length - 1; j >= 0; j--) { 1253 this._childClusters[j]._restorePosition(); 1254 } 1255 } else { 1256 for (var k = this._childClusters.length - 1; k >= 0; k--) { 1257 this._childClusters[k]._recursivelyRestoreChildPositions(zoomLevel); 1258 } 1259 } 1260 }, 1261 _restorePosition: function() { 1262 if (this._backupLatlng) { 1263 this.setLatLng(this._backupLatlng); 1264 delete this._backupLatlng; 1265 } 1266 }, 1267 //exceptBounds: If set, don't remove any markers/clusters in it 1268 _recursivelyRemoveChildrenFromMap: function(previousBounds, mapMinZoom, zoomLevel, exceptBounds) { 1269 var m, i; 1270 this._recursively( 1271 previousBounds, 1272 mapMinZoom - 1, 1273 zoomLevel - 1, 1274 function(c) { 1275 for (i = c._markers.length - 1; i >= 0; i--) { 1276 m = c._markers[i]; 1277 if (!exceptBounds || !exceptBounds.contains(m._latlng)) { 1278 c._group._featureGroup.removeLayer(m); 1279 if (m.clusterShow) { 1280 m.clusterShow(); 1281 } 1282 } 1283 } 1284 }, 1285 function(c) { 1286 for (i = c._childClusters.length - 1; i >= 0; i--) { 1287 m = c._childClusters[i]; 1288 if (!exceptBounds || !exceptBounds.contains(m._latlng)) { 1289 c._group._featureGroup.removeLayer(m); 1290 if (m.clusterShow) { 1291 m.clusterShow(); 1292 } 1293 } 1294 } 1295 } 1296 ); 1297 }, 1298 //Run the given functions recursively to this and child clusters 1299 // boundsToApplyTo: a L.LatLngBounds representing the bounds of what clusters to recurse in to 1300 // zoomLevelToStart: zoom level to start running functions (inclusive) 1301 // zoomLevelToStop: zoom level to stop running functions (inclusive) 1302 // runAtEveryLevel: function that takes an L.MarkerCluster as an argument that should be applied on every level 1303 // runAtBottomLevel: function that takes an L.MarkerCluster as an argument that should be applied at only the bottom level 1304 _recursively: function(boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel) { 1305 var childClusters = this._childClusters, zoom = this._zoom, i, c; 1306 if (zoomLevelToStart <= zoom) { 1307 if (runAtEveryLevel) { 1308 runAtEveryLevel(this); 1309 } 1310 if (runAtBottomLevel && zoom === zoomLevelToStop) { 1311 runAtBottomLevel(this); 1312 } 1313 } 1314 if (zoom < zoomLevelToStart || zoom < zoomLevelToStop) { 1315 for (i = childClusters.length - 1; i >= 0; i--) { 1316 c = childClusters[i]; 1317 if (c._boundsNeedUpdate) { 1318 c._recalculateBounds(); 1319 } 1320 if (boundsToApplyTo.intersects(c._bounds)) { 1321 c._recursively(boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel); 1322 } 1323 } 1324 } 1325 }, 1326 //Returns true if we are the parent of only one cluster and that cluster is the same as us 1327 _isSingleParent: function() { 1328 return this._childClusters.length > 0 && this._childClusters[0]._childCount === this._childCount; 1329 } 1330 }); 1331 L.Marker.include({ 1332 clusterHide: function() { 1333 var backup = this.options.opacity; 1334 this.setOpacity(0); 1335 this.options.opacity = backup; 1336 return this; 1337 }, 1338 clusterShow: function() { 1339 return this.setOpacity(this.options.opacity); 1340 } 1341 }); 1342 L.DistanceGrid = function(cellSize) { 1343 this._cellSize = cellSize; 1344 this._sqCellSize = cellSize * cellSize; 1345 this._grid = {}; 1346 this._objectPoint = {}; 1347 }; 1348 L.DistanceGrid.prototype = { 1349 addObject: function(obj, point) { 1350 var x = this._getCoord(point.x), y = this._getCoord(point.y), grid = this._grid, row = grid[y] = grid[y] || {}, cell = row[x] = row[x] || [], stamp = L.Util.stamp(obj); 1351 this._objectPoint[stamp] = point; 1352 cell.push(obj); 1353 }, 1354 updateObject: function(obj, point) { 1355 this.removeObject(obj); 1356 this.addObject(obj, point); 1357 }, 1358 //Returns true if the object was found 1359 removeObject: function(obj, point) { 1360 var x = this._getCoord(point.x), y = this._getCoord(point.y), grid = this._grid, row = grid[y] = grid[y] || {}, cell = row[x] = row[x] || [], i, len; 1361 delete this._objectPoint[L.Util.stamp(obj)]; 1362 for (i = 0, len = cell.length; i < len; i++) { 1363 if (cell[i] === obj) { 1364 cell.splice(i, 1); 1365 if (len === 1) { 1366 delete row[x]; 1367 } 1368 return true; 1369 } 1370 } 1371 }, 1372 eachObject: function(fn, context) { 1373 var i, j, k, len, row, cell, removed, grid = this._grid; 1374 for (i in grid) { 1375 row = grid[i]; 1376 for (j in row) { 1377 cell = row[j]; 1378 for (k = 0, len = cell.length; k < len; k++) { 1379 removed = fn.call(context, cell[k]); 1380 if (removed) { 1381 k--; 1382 len--; 1383 } 1384 } 1385 } 1386 } 1387 }, 1388 getNearObject: function(point) { 1389 var x = this._getCoord(point.x), y = this._getCoord(point.y), i, j, k, row, cell, len, obj, dist, objectPoint = this._objectPoint, closestDistSq = this._sqCellSize, closest = null; 1390 for (i = y - 1; i <= y + 1; i++) { 1391 row = this._grid[i]; 1392 if (row) { 1393 for (j = x - 1; j <= x + 1; j++) { 1394 cell = row[j]; 1395 if (cell) { 1396 for (k = 0, len = cell.length; k < len; k++) { 1397 obj = cell[k]; 1398 dist = this._sqDist(objectPoint[L.Util.stamp(obj)], point); 1399 if (dist < closestDistSq || dist <= closestDistSq && closest === null) { 1400 closestDistSq = dist; 1401 closest = obj; 1402 } 1403 } 1404 } 1405 } 1406 } 1407 } 1408 return closest; 1409 }, 1410 _getCoord: function(x) { 1411 var coord = Math.floor(x / this._cellSize); 1412 return isFinite(coord) ? coord : x; 1413 }, 1414 _sqDist: function(p, p2) { 1415 var dx = p2.x - p.x, dy = p2.y - p.y; 1416 return dx * dx + dy * dy; 1417 } 1418 }; 1419 (function() { 1420 L.QuickHull = { 1421 /* 1422 * @param {Object} cpt a point to be measured from the baseline 1423 * @param {Array} bl the baseline, as represented by a two-element 1424 * array of latlng objects. 1425 * @returns {Number} an approximate distance measure 1426 */ 1427 getDistant: function(cpt, bl) { 1428 var vY = bl[1].lat - bl[0].lat, vX = bl[0].lng - bl[1].lng; 1429 return vX * (cpt.lat - bl[0].lat) + vY * (cpt.lng - bl[0].lng); 1430 }, 1431 /* 1432 * @param {Array} baseLine a two-element array of latlng objects 1433 * representing the baseline to project from 1434 * @param {Array} latLngs an array of latlng objects 1435 * @returns {Object} the maximum point and all new points to stay 1436 * in consideration for the hull. 1437 */ 1438 findMostDistantPointFromBaseLine: function(baseLine, latLngs) { 1439 var maxD = 0, maxPt = null, newPoints = [], i, pt, d; 1440 for (i = latLngs.length - 1; i >= 0; i--) { 1441 pt = latLngs[i]; 1442 d = this.getDistant(pt, baseLine); 1443 if (d > 0) { 1444 newPoints.push(pt); 1445 } else { 1446 continue; 1447 } 1448 if (d > maxD) { 1449 maxD = d; 1450 maxPt = pt; 1451 } 1452 } 1453 return { maxPoint: maxPt, newPoints }; 1454 }, 1455 /* 1456 * Given a baseline, compute the convex hull of latLngs as an array 1457 * of latLngs. 1458 * 1459 * @param {Array} latLngs 1460 * @returns {Array} 1461 */ 1462 buildConvexHull: function(baseLine, latLngs) { 1463 var convexHullBaseLines = [], t = this.findMostDistantPointFromBaseLine(baseLine, latLngs); 1464 if (t.maxPoint) { 1465 convexHullBaseLines = convexHullBaseLines.concat( 1466 this.buildConvexHull([baseLine[0], t.maxPoint], t.newPoints) 1467 ); 1468 convexHullBaseLines = convexHullBaseLines.concat( 1469 this.buildConvexHull([t.maxPoint, baseLine[1]], t.newPoints) 1470 ); 1471 return convexHullBaseLines; 1472 } else { 1473 return [baseLine[0]]; 1474 } 1475 }, 1476 /* 1477 * Given an array of latlngs, compute a convex hull as an array 1478 * of latlngs 1479 * 1480 * @param {Array} latLngs 1481 * @returns {Array} 1482 */ 1483 getConvexHull: function(latLngs) { 1484 var maxLat = false, minLat = false, maxLng = false, minLng = false, maxLatPt = null, minLatPt = null, maxLngPt = null, minLngPt = null, maxPt = null, minPt = null, i; 1485 for (i = latLngs.length - 1; i >= 0; i--) { 1486 var pt = latLngs[i]; 1487 if (maxLat === false || pt.lat > maxLat) { 1488 maxLatPt = pt; 1489 maxLat = pt.lat; 1490 } 1491 if (minLat === false || pt.lat < minLat) { 1492 minLatPt = pt; 1493 minLat = pt.lat; 1494 } 1495 if (maxLng === false || pt.lng > maxLng) { 1496 maxLngPt = pt; 1497 maxLng = pt.lng; 1498 } 1499 if (minLng === false || pt.lng < minLng) { 1500 minLngPt = pt; 1501 minLng = pt.lng; 1502 } 1503 } 1504 if (minLat !== maxLat) { 1505 minPt = minLatPt; 1506 maxPt = maxLatPt; 1507 } else { 1508 minPt = minLngPt; 1509 maxPt = maxLngPt; 1510 } 1511 var ch = [].concat( 1512 this.buildConvexHull([minPt, maxPt], latLngs), 1513 this.buildConvexHull([maxPt, minPt], latLngs) 1514 ); 1515 return ch; 1516 } 1517 }; 1518 })(); 1519 L.MarkerCluster.include({ 1520 getConvexHull: function() { 1521 var childMarkers = this.getAllChildMarkers(), points = [], p, i; 1522 for (i = childMarkers.length - 1; i >= 0; i--) { 1523 p = childMarkers[i].getLatLng(); 1524 points.push(p); 1525 } 1526 return L.QuickHull.getConvexHull(points); 1527 } 1528 }); 1529 L.MarkerCluster.include({ 1530 _2PI: Math.PI * 2, 1531 _circleFootSeparation: 25, 1532 //related to circumference of circle 1533 _circleStartAngle: 0, 1534 _spiralFootSeparation: 28, 1535 //related to size of spiral (experiment!) 1536 _spiralLengthStart: 11, 1537 _spiralLengthFactor: 5, 1538 _circleSpiralSwitchover: 9, 1539 //show spiral instead of circle from this marker count upwards. 1540 // 0 -> always spiral; Infinity -> always circle 1541 spiderfy: function() { 1542 if (this._group._spiderfied === this || this._group._inZoomAnimation) { 1543 return; 1544 } 1545 var childMarkers = this.getAllChildMarkers(null, true), group = this._group, map = group._map, center = map.latLngToLayerPoint(this._latlng), positions; 1546 this._group._unspiderfy(); 1547 this._group._spiderfied = this; 1548 if (this._group.options.spiderfyShapePositions) { 1549 positions = this._group.options.spiderfyShapePositions(childMarkers.length, center); 1550 } else if (childMarkers.length >= this._circleSpiralSwitchover) { 1551 positions = this._generatePointsSpiral(childMarkers.length, center); 1552 } else { 1553 center.y += 10; 1554 positions = this._generatePointsCircle(childMarkers.length, center); 1555 } 1556 this._animationSpiderfy(childMarkers, positions); 1557 }, 1558 unspiderfy: function(zoomDetails) { 1559 if (this._group._inZoomAnimation) { 1560 return; 1561 } 1562 this._animationUnspiderfy(zoomDetails); 1563 this._group._spiderfied = null; 1564 }, 1565 _generatePointsCircle: function(count, centerPt) { 1566 var circumference = this._group.options.spiderfyDistanceMultiplier * this._circleFootSeparation * (2 + count), legLength = circumference / this._2PI, angleStep = this._2PI / count, res = [], i, angle; 1567 legLength = Math.max(legLength, 35); 1568 res.length = count; 1569 for (i = 0; i < count; i++) { 1570 angle = this._circleStartAngle + i * angleStep; 1571 res[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round(); 1572 } 1573 return res; 1574 }, 1575 _generatePointsSpiral: function(count, centerPt) { 1576 var spiderfyDistanceMultiplier = this._group.options.spiderfyDistanceMultiplier, legLength = spiderfyDistanceMultiplier * this._spiralLengthStart, separation = spiderfyDistanceMultiplier * this._spiralFootSeparation, lengthFactor = spiderfyDistanceMultiplier * this._spiralLengthFactor * this._2PI, angle = 0, res = [], i; 1577 res.length = count; 1578 for (i = count; i >= 0; i--) { 1579 if (i < count) { 1580 res[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round(); 1581 } 1582 angle += separation / legLength + i * 5e-4; 1583 legLength += lengthFactor / angle; 1584 } 1585 return res; 1586 }, 1587 _noanimationUnspiderfy: function() { 1588 var group = this._group, map = group._map, fg = group._featureGroup, childMarkers = this.getAllChildMarkers(null, true), m, i; 1589 group._ignoreMove = true; 1590 this.setOpacity(1); 1591 for (i = childMarkers.length - 1; i >= 0; i--) { 1592 m = childMarkers[i]; 1593 fg.removeLayer(m); 1594 if (m._preSpiderfyLatlng) { 1595 m.setLatLng(m._preSpiderfyLatlng); 1596 delete m._preSpiderfyLatlng; 1597 } 1598 if (m.setZIndexOffset) { 1599 m.setZIndexOffset(0); 1600 } 1601 if (m._spiderLeg) { 1602 map.removeLayer(m._spiderLeg); 1603 delete m._spiderLeg; 1604 } 1605 } 1606 group.fire("unspiderfied", { 1607 cluster: this, 1608 markers: childMarkers 1609 }); 1610 group._ignoreMove = false; 1611 group._spiderfied = null; 1612 } 1613 }); 1614 L.MarkerClusterNonAnimated = L.MarkerCluster.extend({ 1615 _animationSpiderfy: function(childMarkers, positions) { 1616 var group = this._group, map = group._map, fg = group._featureGroup, legOptions = this._group.options.spiderLegPolylineOptions, i, m, leg, newPos; 1617 group._ignoreMove = true; 1618 for (i = 0; i < childMarkers.length; i++) { 1619 newPos = map.layerPointToLatLng(positions[i]); 1620 m = childMarkers[i]; 1621 leg = new L.Polyline([this._latlng, newPos], legOptions); 1622 map.addLayer(leg); 1623 m._spiderLeg = leg; 1624 m._preSpiderfyLatlng = m._latlng; 1625 m.setLatLng(newPos); 1626 if (m.setZIndexOffset) { 1627 m.setZIndexOffset(1e6); 1628 } 1629 fg.addLayer(m); 1630 } 1631 this.setOpacity(0.3); 1632 group._ignoreMove = false; 1633 group.fire("spiderfied", { 1634 cluster: this, 1635 markers: childMarkers 1636 }); 1637 }, 1638 _animationUnspiderfy: function() { 1639 this._noanimationUnspiderfy(); 1640 } 1641 }); 1642 L.MarkerCluster.include({ 1643 _animationSpiderfy: function(childMarkers, positions) { 1644 var me = this, group = this._group, map = group._map, fg = group._featureGroup, thisLayerLatLng = this._latlng, thisLayerPos = map.latLngToLayerPoint(thisLayerLatLng), svg = L.Path.SVG, legOptions = L.extend({}, this._group.options.spiderLegPolylineOptions), finalLegOpacity = legOptions.opacity, i, m, leg, legPath, legLength, newPos; 1645 if (finalLegOpacity === void 0) { 1646 finalLegOpacity = L.MarkerClusterGroup.prototype.options.spiderLegPolylineOptions.opacity; 1647 } 1648 if (svg) { 1649 legOptions.opacity = 0; 1650 legOptions.className = (legOptions.className || "") + " leaflet-cluster-spider-leg"; 1651 } else { 1652 legOptions.opacity = finalLegOpacity; 1653 } 1654 group._ignoreMove = true; 1655 for (i = 0; i < childMarkers.length; i++) { 1656 m = childMarkers[i]; 1657 newPos = map.layerPointToLatLng(positions[i]); 1658 leg = new L.Polyline([thisLayerLatLng, newPos], legOptions); 1659 map.addLayer(leg); 1660 m._spiderLeg = leg; 1661 if (svg) { 1662 legPath = leg._path; 1663 legLength = legPath.getTotalLength() + 0.1; 1664 legPath.style.strokeDasharray = legLength; 1665 legPath.style.strokeDashoffset = legLength; 1666 } 1667 if (m.setZIndexOffset) { 1668 m.setZIndexOffset(1e6); 1669 } 1670 if (m.clusterHide) { 1671 m.clusterHide(); 1672 } 1673 fg.addLayer(m); 1674 if (m._setPos) { 1675 m._setPos(thisLayerPos); 1676 } 1677 } 1678 group._forceLayout(); 1679 group._animationStart(); 1680 for (i = childMarkers.length - 1; i >= 0; i--) { 1681 newPos = map.layerPointToLatLng(positions[i]); 1682 m = childMarkers[i]; 1683 m._preSpiderfyLatlng = m._latlng; 1684 m.setLatLng(newPos); 1685 if (m.clusterShow) { 1686 m.clusterShow(); 1687 } 1688 if (svg) { 1689 leg = m._spiderLeg; 1690 legPath = leg._path; 1691 legPath.style.strokeDashoffset = 0; 1692 leg.setStyle({ opacity: finalLegOpacity }); 1693 } 1694 } 1695 this.setOpacity(0.3); 1696 group._ignoreMove = false; 1697 setTimeout(function() { 1698 group._animationEnd(); 1699 group.fire("spiderfied", { 1700 cluster: me, 1701 markers: childMarkers 1702 }); 1703 }, 200); 1704 }, 1705 _animationUnspiderfy: function(zoomDetails) { 1706 var me = this, group = this._group, map = group._map, fg = group._featureGroup, thisLayerPos = zoomDetails ? map._latLngToNewLayerPoint(this._latlng, zoomDetails.zoom, zoomDetails.center) : map.latLngToLayerPoint(this._latlng), childMarkers = this.getAllChildMarkers(null, true), svg = L.Path.SVG, m, i, leg, legPath, legLength, nonAnimatable; 1707 group._ignoreMove = true; 1708 group._animationStart(); 1709 this.setOpacity(1); 1710 for (i = childMarkers.length - 1; i >= 0; i--) { 1711 m = childMarkers[i]; 1712 if (!m._preSpiderfyLatlng) { 1713 continue; 1714 } 1715 m.closePopup(); 1716 m.setLatLng(m._preSpiderfyLatlng); 1717 delete m._preSpiderfyLatlng; 1718 nonAnimatable = true; 1719 if (m._setPos) { 1720 m._setPos(thisLayerPos); 1721 nonAnimatable = false; 1722 } 1723 if (m.clusterHide) { 1724 m.clusterHide(); 1725 nonAnimatable = false; 1726 } 1727 if (nonAnimatable) { 1728 fg.removeLayer(m); 1729 } 1730 if (svg) { 1731 leg = m._spiderLeg; 1732 legPath = leg._path; 1733 legLength = legPath.getTotalLength() + 0.1; 1734 legPath.style.strokeDashoffset = legLength; 1735 leg.setStyle({ opacity: 0 }); 1736 } 1737 } 1738 group._ignoreMove = false; 1739 setTimeout(function() { 1740 var stillThereChildCount = 0; 1741 for (i = childMarkers.length - 1; i >= 0; i--) { 1742 m = childMarkers[i]; 1743 if (m._spiderLeg) { 1744 stillThereChildCount++; 1745 } 1746 } 1747 for (i = childMarkers.length - 1; i >= 0; i--) { 1748 m = childMarkers[i]; 1749 if (!m._spiderLeg) { 1750 continue; 1751 } 1752 if (m.clusterShow) { 1753 m.clusterShow(); 1754 } 1755 if (m.setZIndexOffset) { 1756 m.setZIndexOffset(0); 1757 } 1758 if (stillThereChildCount > 1) { 1759 fg.removeLayer(m); 1760 } 1761 map.removeLayer(m._spiderLeg); 1762 delete m._spiderLeg; 1763 } 1764 group._animationEnd(); 1765 group.fire("unspiderfied", { 1766 cluster: me, 1767 markers: childMarkers 1768 }); 1769 }, 200); 1770 } 1771 }); 1772 L.MarkerClusterGroup.include({ 1773 //The MarkerCluster currently spiderfied (if any) 1774 _spiderfied: null, 1775 unspiderfy: function() { 1776 this._unspiderfy.apply(this, arguments); 1777 }, 1778 _spiderfierOnAdd: function() { 1779 this._map.on("click", this._unspiderfyWrapper, this); 1780 if (this._map.options.zoomAnimation) { 1781 this._map.on("zoomstart", this._unspiderfyZoomStart, this); 1782 } 1783 this._map.on("zoomend", this._noanimationUnspiderfy, this); 1784 if (!L.Browser.touch) { 1785 this._map.getRenderer(this); 1786 } 1787 }, 1788 _spiderfierOnRemove: function() { 1789 this._map.off("click", this._unspiderfyWrapper, this); 1790 this._map.off("zoomstart", this._unspiderfyZoomStart, this); 1791 this._map.off("zoomanim", this._unspiderfyZoomAnim, this); 1792 this._map.off("zoomend", this._noanimationUnspiderfy, this); 1793 this._noanimationUnspiderfy(); 1794 }, 1795 //On zoom start we add a zoomanim handler so that we are guaranteed to be last (after markers are animated) 1796 //This means we can define the animation they do rather than Markers doing an animation to their actual location 1797 _unspiderfyZoomStart: function() { 1798 if (!this._map) { 1799 return; 1800 } 1801 this._map.on("zoomanim", this._unspiderfyZoomAnim, this); 1802 }, 1803 _unspiderfyZoomAnim: function(zoomDetails) { 1804 if (L.DomUtil.hasClass(this._map._mapPane, "leaflet-touching")) { 1805 return; 1806 } 1807 this._map.off("zoomanim", this._unspiderfyZoomAnim, this); 1808 this._unspiderfy(zoomDetails); 1809 }, 1810 _unspiderfyWrapper: function() { 1811 this._unspiderfy(); 1812 }, 1813 _unspiderfy: function(zoomDetails) { 1814 if (this._spiderfied) { 1815 this._spiderfied.unspiderfy(zoomDetails); 1816 } 1817 }, 1818 _noanimationUnspiderfy: function() { 1819 if (this._spiderfied) { 1820 this._spiderfied._noanimationUnspiderfy(); 1821 } 1822 }, 1823 //If the given layer is currently being spiderfied then we unspiderfy it so it isn't on the map anymore etc 1824 _unspiderfyLayer: function(layer) { 1825 if (layer._spiderLeg) { 1826 this._featureGroup.removeLayer(layer); 1827 if (layer.clusterShow) { 1828 layer.clusterShow(); 1829 } 1830 if (layer.setZIndexOffset) { 1831 layer.setZIndexOffset(0); 1832 } 1833 this._map.removeLayer(layer._spiderLeg); 1834 delete layer._spiderLeg; 1835 } 1836 } 1837 }); 1838 L.MarkerClusterGroup.include({ 1839 /**
1840 * Updates the icon of all clusters which are parents of the given marker(s). 1841 * In singleMarkerMode, also updates the given marker(s) icon. 1842 * @param layers L.MarkerClusterGroup|L.LayerGroup|Array(L.Marker)|Map(L.Marker)| 1843 * L.MarkerCluster|L.Marker (optional) list of markers (or single marker) whose parent 1844 * clusters need to be updated. If not provided, retrieves all child markers of this. 1845 * @returns {L.MarkerClusterGroup} 1846 */ 1847 refreshClusters: function(layers) { 1848 if (!layers) { 1849 layers = this._topClusterLevel.getAllChildMarkers(); 1850 } else if (layers instanceof L.MarkerClusterGroup) { 1851 layers = layers._topClusterLevel.getAllChildMarkers(); 1852 } else if (layers instanceof L.LayerGroup) { 1853 layers = layers._layers; 1854 } else if (layers instanceof L.MarkerCluster) { 1855 layers = layers.getAllChildMarkers(); 1856 } else if (layers instanceof L.Marker) { 1857 layers = [layers]; 1858 } 1859 this._flagParentsIconsNeedUpdate(layers); 1860 this._refreshClustersIcons(); 1861 if (this.options.singleMarkerMode) { 1862 this._refreshSingleMarkerModeMarkers(layers); 1863 } 1864 return this; 1865 }, 1866 /** 1867 * Simply flags all parent clusters of the given markers as having a "dirty" icon. 1868 * @param layers Array(L.Marker)|Map(L.Marker) list of markers. 1869 * @private 1870 */ 1871 _flagParentsIconsNeedUpdate: function(layers) { 1872 var id, parent; 1873 for (id in layers) { 1874 parent = layers[id].__parent; 1875 while (parent) { 1876 parent._iconNeedsUpdate = true; 1877 parent = parent.__parent; 1878 } 1879 } 1880 }, 1881 /** 1882 * Re-draws the icon of the supplied markers. 1883 * To be used in singleMarkerMode only. 1884 * @param layers Array(L.Marker)|Map(L.Marker) list of markers. 1885 * @private 1886 */ 1887 _refreshSingleMarkerModeMarkers: function(layers) { 1888 var id, layer; 1889 for (id in layers) { 1890 layer = layers[id]; 1891 if (this.hasLayer(layer)) { 1892 layer.setIcon(this._overrideMarkerIcon(layer)); 1893 } 1894 } 1895 } 1896 }); 1897 L.Marker.include({ 1898 /** 1899 * Updates the given options in the marker's icon and refreshes the marker. 1900 * @param options map object of icon options. 1901 * @param directlyRefreshClusters boolean (optional) true to trigger 1902 * MCG.refreshClustersOf() right away with this single marker. 1903 * @returns {L.Marker} 1904 */ 1905 refreshIconOptions: function(options, directlyRefreshClusters) { 1906 var icon = this.options.icon; 1907 L.setOptions(icon, options); 1908 this.setIcon(icon); 1909 if (directlyRefreshClusters && this.__parent) { 1910 this.__parent._group.refreshClusters(this); 1911 } 1912 return this; 1913 } 1914 }); 1915 exports2.MarkerClusterGroup = MarkerClusterGroup; 1916 exports2.MarkerCluster = MarkerCluster; 1917 Object.defineProperty(exports2, "__esModule", { value: true }); 1918 }); 1919 } 1920}); 1921export default require_leaflet_markercluster_src(); 1922//# sourceMappingURL=chunk-SYNV5Y45.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.