[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