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