diff --git a/dist/leaflet.markercluster-src.js b/dist/leaflet.markercluster-src.js index c3ab1b4404..fd438b53e2 100644 --- a/dist/leaflet.markercluster-src.js +++ b/dist/leaflet.markercluster-src.js @@ -31,6 +31,10 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({ //Increase to increase the distance away that spiderfied markers appear from the center spiderfyDistanceMultiplier: 1, + //When bulk adding layers, runs chunks at a time. Means addLayers may not add all the layers in the call, others will be loaded during setTimeouts + chunkedLoading: false, + chunkSize: 500, + //Options to pass to the L.Polygon constructor polygonOptions: {} }, @@ -157,52 +161,76 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({ //Takes an array of markers and adds them in bulk addLayers: function (layersArray) { - var i, l, m, - onMap = this._map, - fg = this._featureGroup, - npg = this._nonPointGroup; + var fg = this._featureGroup, + npg = this._nonPointGroup, + chunkSize = this.options.chunkSize, + newMarkers, i, l, m; - for (i = 0, l = layersArray.length; i < l; i++) { - m = layersArray[i]; + if (this._map) { + var start = 0; + var end = this.options.chunkedLoading && chunkSize < layersArray.length ? chunkSize : layersArray.length; + var process = L.bind(function () { + for (i = start; i < end; i++) { + m = layersArray[i]; - //Not point data, can't be clustered - if (!m.getLatLng) { - npg.addLayer(m); - continue; - } + //Not point data, can't be clustered + if (!m.getLatLng) { + npg.addLayer(m); + continue; + } - if (this.hasLayer(m)) { - continue; - } + if (this.hasLayer(m)) { + continue; + } - if (!onMap) { - this._needsClustering.push(m); - continue; - } + this._addLayer(m, this._maxZoom); - this._addLayer(m, this._maxZoom); - - //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 - if (m.__parent) { - if (m.__parent.getChildCount() === 2) { - var markers = m.__parent.getAllChildMarkers(), - otherMarker = markers[0] === m ? markers[1] : markers[0]; - fg.removeLayer(otherMarker); + //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 + if (m.__parent) { + if (m.__parent.getChildCount() === 2) { + var markers = m.__parent.getAllChildMarkers(), + otherMarker = markers[0] === m ? markers[1] : markers[0]; + fg.removeLayer(otherMarker); + } + } } - } - } - if (onMap) { - //Update the icons of all those visible clusters that were affected - fg.eachLayer(function (c) { - if (c instanceof L.MarkerCluster && c._iconNeedsUpdate) { - c._updateIcon(); + if (end === layersArray.length) { + //Update the icons of all those visible clusters that were affected + this._featureGroup.eachLayer(function (c) { + if (c instanceof L.MarkerCluster && c._iconNeedsUpdate) { + c._updateIcon(); + } + }); + + this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds); + } else { + start = end; + end = Math.min(end + chunkSize, layersArray.length); + setTimeout(process, 0); } - }); + }, this); - this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds); + process(); + } else { + newMarkers = []; + for (i = 0, l = layersArray.length; i < l; i++) { + m = layersArray[i]; + + //Not point data, can't be clustered + if (!m.getLatLng) { + npg.addLayer(m); + continue; + } + + if (this.hasLayer(m)) { + continue; + } + + newMarkers.push(m); + } + this._needsClustering = this._needsClustering.concat(newMarkers); } - return this; }, @@ -418,23 +446,9 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({ } this._needsRemoving = []; - for (i = 0, l = this._needsClustering.length; i < l; i++) { - layer = this._needsClustering[i]; - - //If the layer doesn't have a getLatLng then we can't cluster it, so add it to our child featureGroup - if (!layer.getLatLng) { - this._featureGroup.addLayer(layer); - continue; - } - - - if (layer.__parent) { - continue; - } - this._addLayer(layer, this._maxZoom); - } - this._needsClustering = []; - + //Remember the current zoom level and bounds + this._zoom = this._map.getZoom(); + this._currentShownBounds = this._getExpandedVisibleBounds(); this._map.on('zoomend', this._zoomEnd, this); this._map.on('moveend', this._moveEnd, this); @@ -445,15 +459,10 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({ this._bindEvents(); - //Actually add our markers to the map: - - //Remember the current zoom level and bounds - this._zoom = this._map.getZoom(); - this._currentShownBounds = this._getExpandedVisibleBounds(); - - //Make things appear on the map - this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds); + l = this._needsClustering; + this._needsClustering = []; + this.addLayers(l); }, //Overrides FeatureGroup.onRemove @@ -631,7 +640,7 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({ e.layer.zoomToBounds(); } - // Focus the map again for keyboard users. + // Focus the map again for keyboard users. if (e.originalEvent && e.originalEvent.keyCode === 13) { map._container.focus(); } diff --git a/example/marker-clustering-realworld.10000.html b/example/marker-clustering-realworld.10000.html index 873a0f654f..462e8483ea 100644 --- a/example/marker-clustering-realworld.10000.html +++ b/example/marker-clustering-realworld.10000.html @@ -27,7 +27,7 @@ latlng = L.latLng(-37.89, 175.46); var map = L.map('map', {center: latlng, zoom: 13, layers: [cloudmade]}); - var markers = L.markerClusterGroup(); + var markers = L.markerClusterGroup({ chunkedLoading: true }); for (var i = 0; i < addressPoints.length; i++) { var a = addressPoints[i]; diff --git a/example/marker-clustering-realworld.50000.html b/example/marker-clustering-realworld.50000.html index 0f7c7e662a..ff73a8824a 100644 --- a/example/marker-clustering-realworld.50000.html +++ b/example/marker-clustering-realworld.50000.html @@ -18,6 +18,7 @@ +
Mouse over a cluster to see the bounds of its children and click a cluster to zoom to those bounds