diff --git a/lib/OpenLayers/Layer.js b/lib/OpenLayers/Layer.js index b0995ea55e..bd77ae1bc9 100644 --- a/lib/OpenLayers/Layer.js +++ b/lib/OpenLayers/Layer.js @@ -206,22 +206,6 @@ OpenLayers.Layer.prototype = { setMap: function(map) { this.map = map; - var properties = new Array( - 'projection', 'units', - 'scales', 'resolutions', - 'maxScale', 'minScale', - 'maxResolution', 'minResolution', - 'minExtent', 'maxExtent', - 'numZoomLevels' - ); - if (this.map.maxZoomLevel && !this.numZoomLevels) { - this.numZoomLevels = this.map.maxZoomLevel + 1; - } - for(var i=0; i < properties.length; i++) { - if (this[properties[i]] == null) { - this[properties[i]] = this.map[properties[i]]; - } - } this.initResolutions(); this.inRange = this.calculateInRange(); @@ -322,75 +306,127 @@ OpenLayers.Layer.prototype = { * @private */ initResolutions: function() { - - if ((this.scales != null) || (this.resolutions != null)) { + + // These are the relevant options which are used for calculating + // resolutions information. + // + var props = new Array( + 'projection', 'units', + 'scales', 'resolutions', + 'maxScale', 'minScale', + 'maxResolution', 'minResolution', + 'minExtent', 'maxExtent', + 'numZoomLevels', 'maxZoomLevel' + ); + + // First we create a new object where we will store all of the + // resolution-related properties that we find in either the layer's + // 'options' array or from the map. + // + var confProps = new Object(); + for(var i=0; i < props.length; i++) { + var property = props[i]; + confProps[property] = this.options[property] || this.map[property]; + } + + // If numZoomLevels hasn't been set and the maxZoomLevel *has*, + // then use maxZoomLevel to calculate numZoomLevels + // + if ( (!confProps.numZoomLevels) && (confProps.maxZoomLevel) ) { + confProps.numZoomLevels = confProps.maxZoomLevel + 1; + } + + // First off, we take whatever hodge-podge of values we have and + // calculate/distill them down into a resolutions[] array + // + if ((confProps.scales != null) || (confProps.resolutions != null)) { //preset levels - if (this.scales != null) { - this.resolutions = new Array(); - for(var i = 0; i < this.scales.length; i++) { - this.resolutions[i] = - OpenLayers.Util.getResolutionFromScale(this.scales[i], - this.units); + if (confProps.scales != null) { + confProps.resolutions = new Array(); + for(var i = 0; i < confProps.scales.length; i++) { + var scale = confProps.scales[i]; + confProps.resolutions[i] = + OpenLayers.Util.getResolutionFromScale(scale, + confProps.units); } } - this.numZoomLevels = this.resolutions.length; + confProps.numZoomLevels = confProps.resolutions.length; } else { - //maxResolution and numZoomLevels + //maxResolution and numZoomLevels based calculation - this.resolutions = new Array(); + confProps.resolutions = new Array(); // determine maxResolution - if (this.minScale) { - this.maxResolution = - OpenLayers.Util.getResolutionFromScale(this.minScale, - this.units); - } else if (this.maxResolution == "auto") { + if (confProps.minScale) { + confProps.maxResolution = + OpenLayers.Util.getResolutionFromScale(confProps.minScale, + confProps.units); + } else if (confProps.maxResolution == "auto") { var viewSize = this.map.getSize(); - var wRes = this.maxExtent.getWidth() / viewSize.w; - var hRes = this.maxExtent.getHeight()/ viewSize.h; - this.maxResolution = Math.max(wRes, hRes); + var wRes = confProps.maxExtent.getWidth() / viewSize.w; + var hRes = confProps.maxExtent.getHeight()/ viewSize.h; + confProps.maxResolution = Math.max(wRes, hRes); } // determine minResolution - if (this.maxScale != null) { - this.minResolution = - OpenLayers.Util.getResolutionFromScale(this.maxScale); - } else if ((this.minResolution == "auto") && - (this.minExtent != null)){ + if (confProps.maxScale != null) { + confProps.minResolution = + OpenLayers.Util.getResolutionFromScale(confProps.maxScale); + } else if ( (confProps.minResolution == "auto") && + (confProps.minExtent != null) ) { var viewSize = this.map.getSize(); - var wRes = this.minExtent.getWidth() / viewSize.w; - var hRes = this.minExtent.getHeight()/ viewSize.h; - this.minResolution = Math.max(wRes, hRes); + var wRes = confProps.minExtent.getWidth() / viewSize.w; + var hRes = confProps.minExtent.getHeight()/ viewSize.h; + confProps.minResolution = Math.max(wRes, hRes); } // determine numZoomLevels - if (this.minResolution != null) { - var ratio = this.maxResolution / this.minResolution; - this.numZoomLevels = + if (confProps.minResolution != null) { + var ratio = confProps.maxResolution / confProps.minResolution; + confProps.numZoomLevels = Math.floor(Math.log(ratio) / Math.log(2)) + 1; } // now we have numZoomLevels and maxResolution, // we can populate the resolutions array - for (var i=0; i < this.numZoomLevels; i++) { - this.resolutions.push(this.maxResolution / Math.pow(2, i)); + for (var i=0; i < confProps.numZoomLevels; i++) { + var res = confProps.maxResolution / Math.pow(2, i) + confProps.resolutions.push(res); } } - - this.resolutions.sort( function(a,b) { - return(b-a); - }); - - this.minResolution = this.resolutions[this.resolutions.length - 1]; - this.maxResolution = this.resolutions[0]; - this.minScale = - OpenLayers.Util.getScaleFromResolution(this.maxResolution, - this.units); - this.maxScale = - OpenLayers.Util.getScaleFromResolution(this.minResolution, - this.units); + //sort resolutions array ascendingly + // + confProps.resolutions.sort( function(a, b) { return(b-a); } ); + + // now set our newly calculated values back to the layer + // Note: We specifically do *not* set them to layer.options, which we + // will preserve as it was when we added this layer to the map. + // this way cloned layers reset themselves to new map div + // dimensions) + // + this.projection = confProps.projection; + this.units = confProps.units; + + this.resolutions = confProps.resolutions; + this.maxResolution = confProps.resolutions[0]; + var lastIndex = confProps.resolutions.length - 1; + this.minResolution = confProps.resolutions[lastIndex]; + + this.scales = new Array(); + for(var i = 0; i < confProps.resolutions.length; i++) { + this.scales[i] = + OpenLayers.Util.getScaleFromResolution(confProps.resolutions[i], + confProps.units); + } + this.minScale = this.scales[0]; + this.maxScale = this.scales[this.scales.length - 1]; + + this.minExtent = confProps.minExtent; + this.maxExtent = confProps.maxExtent; + + this.numZoomLevels = confProps.numZoomLevels; }, /** diff --git a/tests/test_Layer.html b/tests/test_Layer.html index 41057d7470..4d8a363130 100644 --- a/tests/test_Layer.html +++ b/tests/test_Layer.html @@ -33,18 +33,23 @@ } function test_02_Layer_clone (t) { - t.plan( 6 ); + t.plan( 8 ); - var map = new OpenLayers.Map('map'); - var options = { chicken: 151, foo: "bar" }; + var mapone = new OpenLayers.Map('map'); + var options = { chicken: 151, foo: "bar", maxResolution: "auto" }; var layer = new OpenLayers.Layer('Test Layer', options); - map.addLayer(layer); + mapone.addLayer(layer); // randomly assigned property layer.chocolate = 5; var clone = layer.clone(); + t.ok( clone.map == null, "cloned layer has map property set to null") + + var maptwo = new OpenLayers.Map('map2'); + maptwo.addLayer(clone); + t.ok( clone instanceof OpenLayers.Layer, "new OpenLayers.Layer returns object" ); t.eq( clone.name, "Test Layer", "default clone.name is correct" ); t.ok( ((clone.options["chicken"] == 151) && (clone.options["foo"] == "bar")), "clone.options correctly set" ); @@ -53,8 +58,8 @@ layer.addOptions({chicken:152}); t.eq(clone.options["chicken"], 151, "made a clean copy of options"); - - t.ok( clone.map == null, "cloned layer has map property set to null") + t.ok( (layer.maxResolution != clone.maxResolution), "maxresolution of clone reset to new map div"); + t.ok( (layer.minResolution != clone.minResolution), "minresolution of clone reset to new map div"); } @@ -174,6 +179,7 @@ -
+
+