[Pkg-javascript-commits] [leaflet-markercluster] 100/128: Add support for maps with negative minZoom. Fixes #704

Jonas Smedegaard dr at jones.dk
Sun Apr 16 06:26:08 UTC 2017


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository leaflet-markercluster.

commit 63c64817714d35d8c27a57dca9d7ef88cefa6db7
Author: danzel <dave at smartrak.co.nz>
Date:   Thu Jan 26 09:47:29 2017 +1300

    Add support for maps with negative minZoom. Fixes #704
---
 spec/index.html                        |   1 +
 spec/suites/supportNegativeZoomSpec.js | 124 +++++++++++++++++++++++++++++++++
 src/MarkerCluster.js                   |   2 +-
 src/MarkerClusterGroup.js              |  32 +++++----
 4 files changed, 145 insertions(+), 14 deletions(-)

diff --git a/spec/index.html b/spec/index.html
index ff372c9..65924b5 100644
--- a/spec/index.html
+++ b/spec/index.html
@@ -65,6 +65,7 @@
 	<script type="text/javascript" src="suites/zoomAnimationSpec.js"></script>
 
 	<script type="text/javascript" src="suites/RememberOpacity.js"></script>
+	<script type="text/javascript" src="suites/supportNegativeZoomSpec.js"></script>
 
 	<script type="text/javascript" src="suites/RefreshSpec.js"></script>
 	<script type="text/javascript" src="suites/removeOutsideVisibleBoundsSpec.js"></script>
diff --git a/spec/suites/supportNegativeZoomSpec.js b/spec/suites/supportNegativeZoomSpec.js
new file mode 100644
index 0000000..1e88a1c
--- /dev/null
+++ b/spec/suites/supportNegativeZoomSpec.js
@@ -0,0 +1,124 @@
+describe('things behave correctly with negative minZoom', function () {
+
+	/**
+	 * Avoid as much as possible creating and destroying objects for each test.
+	 * Instead, try re-using them, except for the ones under test of course.
+	 * PhantomJS does not perform garbage collection for the life of the page,
+	 * i.e. during the entire test process (Karma runs all tests in a single page).
+	 * http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
+	 *
+	 * The `beforeEach` and `afterEach do not seem to cause much issue.
+	 * => they can still be used to initialize some setup between each test.
+	 * Using them keeps a readable spec/index.
+	 *
+	 * But refrain from re-creating div and map every time. Re-use those objects.
+	 */
+
+	/////////////////////////////
+	// SETUP FOR EACH TEST
+	/////////////////////////////
+
+	beforeEach(function () {
+
+		// Nothing for this test suite.
+
+	});
+
+	afterEach(function () {
+
+		if (group instanceof L.MarkerClusterGroup) {
+			group.clearLayers();
+			map.removeLayer(group);
+		}
+
+		// Throw away group as it can be assigned with different configurations between tests.
+		group = null;
+
+	});
+
+
+	/////////////////////////////
+	// PREPARATION CODE
+	/////////////////////////////
+
+	var div, map, group;
+
+	div = document.createElement('div');
+	div.style.width = '200px';
+	div.style.height = '200px';
+	document.body.appendChild(div);
+
+	map = L.map(div, { minZoom: -3, maxZoom: 18 });
+
+	map.setView(L.latLng(0, 0), -3);
+
+
+	/////////////////////////////
+	// TESTS
+	/////////////////////////////
+
+	it('shows a single marker added to the group before the group is added to the map', function () {
+
+		group = new L.MarkerClusterGroup();
+
+		var marker = new L.Marker([1.5, 1.5]);
+
+		group.addLayer(marker);
+		map.addLayer(group);
+
+		expect(marker._icon).to.not.be(undefined);
+		expect(marker._icon.parentNode).to.be(map._panes.markerPane);
+	});
+
+	it('shows a single marker added to the group after the group is added to the map', function () {
+
+		group = new L.MarkerClusterGroup();
+
+		var marker = new L.Marker([1.5, 1.5]);
+
+		map.addLayer(group);
+		group.addLayer(marker);
+
+		expect(marker._icon).to.not.be(undefined);
+		expect(marker._icon.parentNode).to.be(map._panes.markerPane);
+	});
+
+	it('creates a cluster when 2 overlapping markers are added before the group is added to the map', function () {
+
+		group = new L.MarkerClusterGroup();
+		var marker = new L.Marker([1.5, 1.5]);
+		var marker2 = new L.Marker([1.5, 1.5]);
+
+		group.addLayer(marker);
+		group.addLayer(marker2);
+		map.addLayer(group);
+
+		expect(marker._icon).to.be(undefined);
+		expect(marker2._icon).to.be(undefined);
+
+		expect(map._panes.markerPane.childNodes.length).to.be(1);
+	});
+	it('creates a cluster when 2 overlapping markers are added after the group is added to the map', function () {
+
+		group = new L.MarkerClusterGroup();
+		var marker = new L.Marker([1.5, 1.5]);
+		var marker2 = new L.Marker([1.5, 1.5]);
+
+		map.addLayer(group);
+		group.addLayer(marker);
+		group.addLayer(marker2);
+
+		expect(marker._icon).to.be(null); //Null as was added and then removed
+		expect(marker2._icon).to.be(undefined);
+
+		expect(map._panes.markerPane.childNodes.length).to.be(1);
+	});
+
+	/////////////////////////////
+	// CLEAN UP CODE
+	/////////////////////////////
+
+	map.remove();
+	document.body.removeChild(div);
+
+});
diff --git a/src/MarkerCluster.js b/src/MarkerCluster.js
index 8c73cac..c953124 100644
--- a/src/MarkerCluster.js
+++ b/src/MarkerCluster.js
@@ -267,7 +267,7 @@ L.MarkerCluster = L.Marker.extend({
 	},
 
 	_recursivelyAddChildrenToMap: function (startPos, zoomLevel, bounds) {
-		this._recursively(bounds, -1, zoomLevel,
+		this._recursively(bounds, this._group._map.getMinZoom() - 1, zoomLevel,
 			function (c) {
 				if (zoomLevel === c._zoom) {
 					return;
diff --git a/src/MarkerClusterGroup.js b/src/MarkerClusterGroup.js
index d3a82e0..493ec6e 100644
--- a/src/MarkerClusterGroup.js
+++ b/src/MarkerClusterGroup.js
@@ -647,10 +647,11 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
 	 * @private
 	 */
 	_removeFromGridUnclustered: function (marker, z) {
-		var map             = this._map,
-		    gridUnclustered = this._gridUnclustered;
+		var map = this._map,
+		    gridUnclustered = this._gridUnclustered,
+			minZoom = this._map.getMinZoom();
 
-		for (; z >= 0; z--) {
+		for (; z >= minZoom; z--) {
 			if (!gridUnclustered[z].removeObject(marker, map.project(marker.getLatLng(), z))) {
 				break;
 			}
@@ -689,7 +690,8 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
 		var gridClusters = this._gridClusters,
 			gridUnclustered = this._gridUnclustered,
 			fg = this._featureGroup,
-			map = this._map;
+			map = this._map,
+			minZoom = this._map.getMinZoom();
 
 		//Remove the marker from distance clusters it might be in
 		if (removeFromDistanceGrid) {
@@ -708,7 +710,7 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
 			cluster._childCount--;
 			cluster._boundsNeedUpdate = true;
 
-			if (cluster._zoom < 0) {
+			if (cluster._zoom < minZoom) {
 				//Top level, do nothing
 				break;
 			} else if (removeFromDistanceGrid && cluster._childCount <= 1) { //Cluster no longer required
@@ -891,6 +893,7 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
 
 	_generateInitialClusters: function () {
 		var maxZoom = this._map.getMaxZoom(),
+			minZoom = this._map.getMinZoom(),
 			radius = this.options.maxClusterRadius,
 			radiusFn = radius;
 	
@@ -909,19 +912,20 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
 		this._gridUnclustered = {};
 	
 		//Set up DistanceGrids for each zoom
-		for (var zoom = maxZoom; zoom >= 0; zoom--) {
+		for (var zoom = maxZoom; zoom >= minZoom; zoom--) {
 			this._gridClusters[zoom] = new L.DistanceGrid(radiusFn(zoom));
 			this._gridUnclustered[zoom] = new L.DistanceGrid(radiusFn(zoom));
 		}
 
 		// Instantiate the appropriate L.MarkerCluster class (animated or not).
-		this._topClusterLevel = new this._markerCluster(this, -1);
+		this._topClusterLevel = new this._markerCluster(this, minZoom - 1);
 	},
 
 	//Zoom: Zoom to start adding at (Pass this._maxZoom to start at the bottom)
 	_addLayer: function (layer, zoom) {
 		var gridClusters = this._gridClusters,
 		    gridUnclustered = this._gridUnclustered,
+			minZoom = this._map.getMinZoom(),
 		    markerPoint, z;
 
 		if (this.options.singleMarkerMode) {
@@ -933,7 +937,7 @@ L.MarkerClusterGroup = L.FeatureGroup.extend({
 		layer.on('dragend', this._childMarkerDragEnd, this);
 
 		//Find the lowest zoom level to slot this one in
-		for (; zoom >= 0; zoom--) {
+		for (; zoom >= minZoom; zoom--) {
 			markerPoint = this._map.project(layer.getLatLng(), zoom); // calculate pixel position
 
 			//Try find a cluster close by
@@ -1173,13 +1177,14 @@ L.MarkerClusterGroup.include({
 
 		_animationZoomIn: function (previousZoomLevel, newZoomLevel) {
 			var bounds = this._getExpandedVisibleBounds(),
-			    fg     = this._featureGroup,
+			    fg = this._featureGroup,
+				minZoom = this._map.getMinZoom(),
 			    i;
 
 			this._ignoreMove = true;
 
 			//Add all children of current clusters to map and remove those clusters from map
-			this._topClusterLevel._recursively(bounds, previousZoomLevel, 0, function (c) {
+			this._topClusterLevel._recursively(bounds, previousZoomLevel, minZoom, function (c) {
 				var startPos = c._latlng,
 				    markers  = c._markers,
 				    m;
@@ -1229,7 +1234,7 @@ L.MarkerClusterGroup.include({
 			//Remove the old clusters and close the zoom animation
 			this._enqueue(function () {
 				//update the positions of the just added clusters/markers
-				this._topClusterLevel._recursively(bounds, previousZoomLevel, 0, function (c) {
+				this._topClusterLevel._recursively(bounds, previousZoomLevel, minZoom, function (c) {
 					fg.removeLayer(c);
 					c.clusterShow();
 				});
@@ -1281,7 +1286,8 @@ L.MarkerClusterGroup.include({
 
 	// Private methods for animated versions.
 	_animationZoomOutSingle: function (cluster, previousZoomLevel, newZoomLevel) {
-		var bounds = this._getExpandedVisibleBounds();
+		var bounds = this._getExpandedVisibleBounds(),
+			minZoom = this._map.getMinZoom();
 
 		//Animate all of the markers in the clusters to move to their cluster center point
 		cluster._recursivelyAnimateChildrenInAndAddSelfToMap(bounds, previousZoomLevel + 1, newZoomLevel);
@@ -1307,7 +1313,7 @@ L.MarkerClusterGroup.include({
 					m.clusterShow();
 				}
 			} else {
-				cluster._recursively(bounds, newZoomLevel, 0, function (c) {
+				cluster._recursively(bounds, newZoomLevel, minZoom, function (c) {
 					c._recursivelyRemoveChildrenFromMap(bounds, previousZoomLevel + 1);
 				});
 			}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/leaflet-markercluster.git



More information about the Pkg-javascript-commits mailing list