diff --git a/lib/OpenLayers/Layer.js b/lib/OpenLayers/Layer.js index 1314c2871b..b037391c88 100644 --- a/lib/OpenLayers/Layer.js +++ b/lib/OpenLayers/Layer.js @@ -663,9 +663,7 @@ OpenLayers.Layer = OpenLayers.Class({ } else { //maxResolution and numZoomLevels based calculation - - confProps.resolutions = []; - + // determine maxResolution if (confProps.minScale) { confProps.maxResolution = @@ -691,8 +689,9 @@ OpenLayers.Layer = OpenLayers.Class({ confProps.minResolution = Math.max(wRes, hRes); } - // determine numZoomLevels - if (confProps.minResolution != null) { + // determine numZoomLevels if not already set on the layer + if (confProps.minResolution != null && + this.options.numZoomLevels == undefined) { var ratio = confProps.maxResolution / confProps.minResolution; confProps.numZoomLevels = Math.floor(Math.log(ratio) / Math.log(2)) + 1; @@ -700,10 +699,26 @@ OpenLayers.Layer = OpenLayers.Class({ // now we have numZoomLevels and maxResolution, // we can populate the resolutions array + confProps.resolutions = new Array(confProps.numZoomLevels); + var base = 2; + if(typeof confProps.minResolution == "number" && + this.options.numZoomLevels > 1) { + /** + * If numZoomLevels is explicitly set in the layer options, + * respect it. If numZoomLevels is not specified, we use + * exponential scaling with a base of 2. If numZoomLevels + * is specified, we use exponential scaling and determine the + * appropriate base so minResolution is reached. + */ + base = Math.pow( + (confProps.maxResolution / confProps.minResolution), + (1 / (confProps.numZoomLevels - 1)) + ); + } for (var i=0; i < confProps.numZoomLevels; i++) { - var res = confProps.maxResolution / Math.pow(2, i); - confProps.resolutions.push(res); - } + var res = confProps.maxResolution / Math.pow(base, i); + confProps.resolutions[i] = res; + } } //sort resolutions array ascendingly diff --git a/tests/test_Layer.html b/tests/test_Layer.html index 3ee58d4deb..8498ba179a 100644 --- a/tests/test_Layer.html +++ b/tests/test_Layer.html @@ -118,6 +118,24 @@ t.eq(layer.maxResolution, maxResolution, "maxResolution set correctly"); t.eq(layer.numZoomLevels, numZoomLevels, "numZoomLevels set correctly"); } + + function test_Layer_initResolutions(t) { + t.plan(3); + var map = new OpenLayers.Map("map"); + var options = { + minResolution: 1, + maxResolution: 10, + numZoomLevels: 5 + }; + var layer = new OpenLayers.Layer("test", options); + layer.map = map; + layer.initResolutions(); + t.eq(layer.minResolution.toPrecision(9), (1).toPrecision(9), + "layer minResolution preserved"); + t.eq(layer.maxResolution.toPrecision(9), (10).toPrecision(9), + "layer maxResolution preserved"); + t.eq(layer.numZoomLevels, 5, "layer numZoomLevels preserved"); + } function test_05_Layer_visibility(t) {