diff --git a/debug/map/zoomlevels.html b/debug/map/zoomlevels.html
new file mode 100644
index 00000000..d5b8747e
--- /dev/null
+++ b/debug/map/zoomlevels.html
@@ -0,0 +1,45 @@
+
+
+
+ Leaflet debug page
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spec/suites/control/Control.LayersSpec.js b/spec/suites/control/Control.LayersSpec.js
index 78ea1585..92a96c43 100644
--- a/spec/suites/control/Control.LayersSpec.js
+++ b/spec/suites/control/Control.LayersSpec.js
@@ -11,11 +11,13 @@ describe("Control.Layers", function () {
layers = L.control.layers(baseLayers).addTo(map),
spy = jasmine.createSpy();
- map.on('baselayerchange', spy);
- happen.click(layers._baseLayersList.getElementsByTagName("input")[0]);
+ map.on('baselayerchange', spy)
+ .whenReady(function(){
+ happen.click(layers._baseLayersList.getElementsByTagName("input")[0]);
- expect(spy).toHaveBeenCalled();
- expect(spy.mostRecentCall.args[0].layer).toBe(baseLayers["Layer 1"]);
+ expect(spy).toHaveBeenCalled();
+ expect(spy.mostRecentCall.args[0].layer).toBe(baseLayers["Layer 1"]);
+ });
});
it("is not fired on input that doesn't change the base layer", function () {
diff --git a/spec/suites/layer/TileLayerSpec.js b/spec/suites/layer/TileLayerSpec.js
index 28517ad9..fddfffc0 100644
--- a/spec/suites/layer/TileLayerSpec.js
+++ b/spec/suites/layer/TileLayerSpec.js
@@ -1 +1,75 @@
-describe('TileLayer', noSpecs);
\ No newline at end of file
+
+describe('TileLayer', function () {
+ describe("#getMaxZoom, #getMinZoom", function () {
+ var map;
+ beforeEach(function () {
+ map = L.map(document.createElement('div'));
+ });
+ describe("when a tilelayer is added to a map with no other layers", function () {
+ it("should have the same zoomlevels as the tilelayer", function () {
+ var maxZoom = 10,
+ minZoom = 5;
+ map.setView([0, 0], 1);
+
+ L.tileLayer("{z}{x}{y}", {
+ maxZoom: maxZoom,
+ minZoom: minZoom
+ }).addTo(map);
+ expect(map.getMaxZoom() === maxZoom).toBeTruthy();
+ expect(map.getMinZoom() === minZoom).toBeTruthy();
+ });
+ });
+ describe("when a tilelayer is added to a map that already has a tilelayer", function () {
+ it("should have its zoomlevels updated to fit the new layer", function () {
+ map.setView([0, 0], 1);
+
+ L.tileLayer("{z}{x}{y}", { minZoom:10, maxZoom: 15 }).addTo(map);
+ expect(map.getMinZoom()).toBe(10);
+ expect(map.getMaxZoom()).toBe(15);
+
+ L.tileLayer("{z}{x}{y}", { minZoom:5, maxZoom: 10 }).addTo(map);
+ expect(map.getMinZoom()).toBe(5); // changed
+ expect(map.getMaxZoom()).toBe(15); // unchanged
+
+
+ L.tileLayer("{z}{x}{y}",{ minZoom:10, maxZoom: 20 }).addTo(map);
+ expect(map.getMinZoom()).toBe(5); // unchanged
+ expect(map.getMaxZoom()).toBe(20); // changed
+
+
+ L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 25 }).addTo(map);
+ expect(map.getMinZoom()).toBe(0); // changed
+ expect(map.getMaxZoom()).toBe(25); // changed
+ });
+ });
+ describe("when a tilelayer is removed from a map", function () {
+ it("it should have its zoomlevels updated to only fit the layers it currently has", function () {
+ var tiles = [ L.tileLayer("{z}{x}{y}", { minZoom:10, maxZoom: 15 }).addTo(map),
+ L.tileLayer("{z}{x}{y}", { minZoom:5, maxZoom: 10 }).addTo(map),
+ L.tileLayer("{z}{x}{y}", { minZoom:10, maxZoom: 20 }).addTo(map),
+ L.tileLayer("{z}{x}{y}", { minZoom:0, maxZoom: 25 }).addTo(map)
+ ];
+ map.whenReady(function() {
+ expect(map.getMinZoom()).toBe(0);
+ expect(map.getMaxZoom()).toBe(25);
+
+ map.removeLayer(tiles[0]);
+ expect(map.getMinZoom()).toBe(0);
+ expect(map.getMaxZoom()).toBe(25);
+
+ map.removeLayer(tiles[3]);
+ expect(map.getMinZoom()).toBe(5);
+ expect(map.getMaxZoom()).toBe(20);
+
+ map.removeLayer(tiles[2]);
+ expect(map.getMinZoom()).toBe(5);
+ expect(map.getMaxZoom()).toBe(10);
+
+ map.removeLayer(tiles[1]);
+ expect(map.getMinZoom()).toBe(0);
+ expect(map.getMaxZoom()).toBe(Infinity);
+ });
+ });
+ });
+ });
+});
\ No newline at end of file
diff --git a/src/control/Control.Layers.js b/src/control/Control.Layers.js
index ce83c915..cb6ecefe 100644
--- a/src/control/Control.Layers.js
+++ b/src/control/Control.Layers.js
@@ -220,6 +220,7 @@ L.Control.Layers = L.Control.extend({
}
if (baseLayer) {
+ this._map.setZoom(this._map.getZoom());
this._map.fire('baselayerchange', {layer: baseLayer});
}
diff --git a/src/map/Map.js b/src/map/Map.js
index 25817726..d94a72b3 100644
--- a/src/map/Map.js
+++ b/src/map/Map.js
@@ -148,11 +148,9 @@ L.Map = L.Class.extend({
this._layers[id] = layer;
// TODO getMaxZoom, getMinZoom in ILayer (instead of options)
- if (layer.options && !isNaN(layer.options.maxZoom)) {
- this._layersMaxZoom = Math.max(this._layersMaxZoom || 0, layer.options.maxZoom);
- }
- if (layer.options && !isNaN(layer.options.minZoom)) {
- this._layersMinZoom = Math.min(this._layersMinZoom || Infinity, layer.options.minZoom);
+ if(layer.options && (!isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom))){
+ this._zoomBoundLayers[id] = layer;
+ this._updateZoomLevels();
}
// TODO looks ugly, refactor!!!
@@ -178,6 +176,10 @@ L.Map = L.Class.extend({
layer.onRemove(this);
delete this._layers[id];
+ if(this._zoomBoundLayers[id]){
+ delete this._zoomBoundLayers[id];
+ this._updateZoomLevels();
+ }
// TODO looks ugly, refactor
if (this.options.zoomAnimation && L.TileLayer && (layer instanceof L.TileLayer)) {
@@ -477,6 +479,7 @@ L.Map = L.Class.extend({
layers = layers ? (layers instanceof Array ? layers : [layers]) : [];
this._layers = {};
+ this._zoomBoundLayers = {};
this._tileLayersNum = 0;
var i, len;
@@ -535,6 +538,28 @@ L.Map = L.Class.extend({
L.DomUtil.setPosition(this._mapPane, this._getMapPanePos().subtract(offset));
},
+ _updateZoomLevels: function () {
+ var i,
+ minZoom = Infinity,
+ maxZoom = -Infinity;
+
+ for (i in this._zoomBoundLayers) {
+ var layer = this._zoomBoundLayers[i];
+ if(!isNaN(layer.options.minZoom)){
+ minZoom = Math.min(minZoom, layer.options.minZoom);
+ }
+ if(!isNaN(layer.options.maxZoom)){
+ maxZoom = Math.max(maxZoom, layer.options.maxZoom);
+ }
+ }
+
+ if(i === undefined){ // we have no tilelayers
+ this._layersMaxZoom = this._layersMinZoom = undefined;
+ } else {
+ this._layersMaxZoom = maxZoom;
+ this._layersMinZoom = minZoom;
+ }
+ },
// map events