diff --git a/examples/urban.html b/examples/urban.html index ed2156b3fd..6531b10fd7 100644 --- a/examples/urban.html +++ b/examples/urban.html @@ -11,15 +11,15 @@ + + + +
+ + diff --git a/lib/OpenLayers/Control/PanZoomBar.js b/lib/OpenLayers/Control/PanZoomBar.js index 8a7e01de43..a4fdb08fb2 100644 --- a/lib/OpenLayers/Control/PanZoomBar.js +++ b/lib/OpenLayers/Control/PanZoomBar.js @@ -28,9 +28,28 @@ OpenLayers.Control.PanZoomBar.prototype = // put code here to catch "changebaselayer" event from map, because // we are going to have to redraw this thing each time, because - // maxZoom will/might change. + // numZoomLevels will/might change. }, + /** + * @param {OpenLayers.Map} map + */ + setMap: function(map) { + OpenLayers.Control.PanZoom.prototype.setMap.apply(this, arguments); + + this.map.events.register("changebaselayer", this, this.redraw); + }, + + /** clear the div and start over. + * + */ + redraw: function() { + if (this.div != null) { + this.div.innerHTML = ""; + } + this.draw(); + }, + /** * @param {OpenLayers.Pixel} px */ @@ -65,7 +84,7 @@ OpenLayers.Control.PanZoomBar.prototype = var id = "OpenLayers_Control_PanZoomBar_Slider" + this.map.id; var slider = OpenLayers.Util.createAlphaImageDiv(id, centered.add(-1, - (this.map.getMaxZoomLevel())*this.zoomStopHeight), + (this.map.getNumZoomLevels()-1) * this.zoomStopHeight), new OpenLayers.Size(20,9), imgLocation+"slider.png", "absolute"); @@ -79,7 +98,7 @@ OpenLayers.Control.PanZoomBar.prototype = this.sliderEvents.register("click", this, this.doubleClick); sz = new OpenLayers.Size(); - sz.h = this.zoomStopHeight*(this.map.getMaxZoomLevel()+1); + sz.h = this.zoomStopHeight * this.map.getNumZoomLevels(); sz.w = this.zoomStopWidth; var div = null @@ -115,7 +134,7 @@ OpenLayers.Control.PanZoomBar.prototype = this.map.events.register("zoomend", this, this.moveZoomBar); centered = centered.add(0, - this.zoomStopHeight*(this.map.getMaxZoomLevel()+1)); + this.zoomStopHeight * this.map.getNumZoomLevels()); return centered; }, /* @@ -136,7 +155,7 @@ OpenLayers.Control.PanZoomBar.prototype = var y = evt.xy.y; var top = Position.page(evt.object)[1]; var levels = Math.floor((y - top)/this.zoomStopHeight); - this.map.zoomTo(this.map.getMaxZoomLevel() - levels); + this.map.zoomTo((this.map.getNumZoomLevels() -1) - levels); Event.stop(evt); }, @@ -198,8 +217,8 @@ OpenLayers.Control.PanZoomBar.prototype = */ moveZoomBar:function() { var newTop = - (this.map.getMaxZoomLevel() - this.map.getZoom()) * this.zoomStopHeight - + this.startTop + 1; + ((this.map.getNumZoomLevels()-1) - this.map.getZoom()) * + this.zoomStopHeight + this.startTop + 1; this.slider.style.top = newTop + "px"; }, diff --git a/lib/OpenLayers/Layer.js b/lib/OpenLayers/Layer.js index 52b6aedbcb..ad316fb1db 100644 --- a/lib/OpenLayers/Layer.js +++ b/lib/OpenLayers/Layer.js @@ -51,10 +51,7 @@ OpenLayers.Layer.prototype = { maxResolution: null, /** @type int */ - minZoomLevel: null, - - /** @type int */ - maxZoomLevel: null, + numZoomLevels: null, /** @type float */ minScale: null, @@ -178,12 +175,12 @@ OpenLayers.Layer.prototype = { this.map = map; var properties = new Array( - 'projection', 'minExtent', 'maxExtent', - 'minScale', 'maxScale', + 'projection', 'units', + 'scales', 'resolutions', + 'maxScale', 'minScale', 'maxResolution', 'minResolution', - 'minZoomLevel', 'maxZoomLevel', 'units', - 'scales', 'resolutions' - + 'minExtent', 'maxExtent', + 'numZoomLevels' ); for(var i=0; i < properties.length; i++) { if (this[properties[i]] == null) { @@ -251,19 +248,11 @@ OpenLayers.Layer.prototype = { }, /** - * @returns The minimum zoom level that can be reached in this layer + * @returns The total number of zoom levels this layer can reach * @type int */ - getMinZoomLevel: function() { - return this.minZoomLevel; - }, - - /** - * @returns The maximum zoom level that can be reached in this layer - * @type int - */ - getMaxZoomLevel: function() { - return this.maxZoomLevel; + getNumZoomLevels: function() { + return this.numZoomLevels; }, /********************************************************/ diff --git a/lib/OpenLayers/Layer/Google.js b/lib/OpenLayers/Layer/Google.js index 3aaeefd480..16f02ab176 100644 --- a/lib/OpenLayers/Layer/Google.js +++ b/lib/OpenLayers/Layer/Google.js @@ -49,10 +49,7 @@ OpenLayers.Layer.Google.prototype = // OPTIONS /** @type int */ - minZoomLevel: -1, - - /** @type int */ - maxZoomLevel: 16, + numZoomLevels: 16, /** diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 36cf1023ed..59a417b943 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -444,12 +444,9 @@ OpenLayers.Layer.Grid.prototype = var zoom = Math.floor( (Math.log(maxRes/degPerPixel)) / Math.log(2) ); - var maxZoomLevel = this.map.getMaxZoomLevel(); - var minZoomLevel = this.map.getMinZoomLevel(); - //make sure zoom is within bounds - zoom = Math.min( Math.max(zoom, minZoomLevel), - maxZoomLevel ); + zoom = Math.min( Math.max(zoom, 0), + this.getNumZoomLevels() - 1); return zoom; }, diff --git a/lib/OpenLayers/Layer/HTTPRequest.js b/lib/OpenLayers/Layer/HTTPRequest.js index b6ba775398..5fd2492162 100644 --- a/lib/OpenLayers/Layer/HTTPRequest.js +++ b/lib/OpenLayers/Layer/HTTPRequest.js @@ -36,10 +36,17 @@ OpenLayers.Layer.HTTPRequest.prototype = this.params = Object.extend( new Object(), params); }, + /** When the layer is added to the map, once it has taken all the + * relevant properties from the map (in Layer.setMap()), we will + * make the call to initialize the layer's resolutions array. + * + * @param {OpenLayers.Map} map + */ setMap: function(map) { OpenLayers.Layer.prototype.setMap.apply(this, arguments); this.initResolutions(); }, + /** * */ @@ -131,31 +138,78 @@ OpenLayers.Layer.HTTPRequest.prototype = return requestString; }, + /** This method's responsibility is to set up the 'resolutions' array + * for the layer -- this array is what the layer will use to interface + * between the zoom levels of the map and the resolution display of the + * layer. + * + * The user has several options that determine how the array is set up. + * + * For a detailed explanation, see the following wiki from the + * openlayers.org homepage: + * + * http://trac.openlayers.org/wiki/SettingZoomLevels + * + * @private + */ initResolutions: function() { - 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); - this.maxZoomLevel = this.resolutions.length; - } else if (this.resolutions != null) { - this.maxZoomLevel = this.resolutions.length; + + if ((this.scales != null) || (this.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); + } + } + this.numZoomLevels = this.resolutions.length; + } else { + //maxResolution and numZoomLevels + this.resolutions = new Array(); - if (this.minScale) - this.maxResolution = OpenLayers.Util.getResolutionFromScale(this.minScale, this.units); - var maxRes = this.getMaxResolution(); - if (this.maxScale) { - /* This will cause this.map.getMaxZoomLevel() to be set the next time - * it is called, which means that the next portion here will succeed. */ - var minRes = OpenLayers.Util.getResolutionFromScale(this.maxScale); - this.maxZoomLevel = Math.floor(Math.log(maxRes/minRes) / Math.log(2)); - } - for (var i=this.getMinZoomLevel(); i <= this.getMaxZoomLevel(); i++) { - this.resolutions.push(maxRes / Math.pow(2, i)); + + // determine maxResolution + if (this.minScale) { + this.maxResolution = + OpenLayers.Util.getResolutionFromScale(this.minScale, + this.units); + } else if (this.maxResolution == "auto") { + var maxExtent = this.getMaxExtent(); + var viewSize = this.map.getSize(); + var wRes = maxExtent.getWidth() / viewSize.w; + var hRes = maxExtent.getHeight()/ viewSize.h; + this.maxResolution = Math.max(wRes, hRes); + } + + // determine numZoomLevels + + if (this.maxScale != null) { + this.minResolution = + OpenLayers.Util.getResolutionFromScale(this.maxScale); + } + + if (this.minResolution != null) { + var ratio = this.maxResolution / this.minResolution; + this.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)); } } }, + /** + * @returns The currently selected resolution of the map, taken from the + * resolutions array, indexed by current zoom level. + * @type float + */ getResolution: function() { var zoom = this.map.getZoom(); diff --git a/lib/OpenLayers/Layer/VirtualEarth.js b/lib/OpenLayers/Layer/VirtualEarth.js index 9ba8dbc01c..a021b36d14 100644 --- a/lib/OpenLayers/Layer/VirtualEarth.js +++ b/lib/OpenLayers/Layer/VirtualEarth.js @@ -14,6 +14,9 @@ OpenLayers.Layer.VirtualEarth.prototype = /** @type VEMap */ vemap: null, + /** @type int */ + numZoomLevels: 17, + /** * @constructor * @@ -211,12 +214,9 @@ OpenLayers.Layer.VirtualEarth.prototype = var zoom = Math.floor( (Math.log(maxRes/degPerPixel)) / Math.log(2) ); - var maxZoomLevel = this.map.getMaxZoomLevel(); - var minZoomLevel = this.map.getMinZoomLevel(); - //make sure zoom is within bounds - zoom = Math.min( Math.max(zoom, minZoomLevel), - maxZoomLevel ); + zoom = Math.min( Math.max(zoom, 0), + this.numZoomLevels-1); return zoom; }, diff --git a/lib/OpenLayers/Map.js b/lib/OpenLayers/Map.js index 8e7606c086..3269d6574c 100644 --- a/lib/OpenLayers/Map.js +++ b/lib/OpenLayers/Map.js @@ -78,33 +78,38 @@ OpenLayers.Map.prototype = { // Options + /** @type OpenLayers.Size */ + tileSize: null, + /** @type String */ projection: "EPSG:4326", - /** @type OpenLayers.Bounds */ - maxExtent: null, - + /** @type String */ + units: 'degrees', + /** default max is 360 deg / 256 px, which corresponds to * zoom level 0 on gmaps * * @type float */ maxResolution: 1.40625, - /** @type int */ - minZoomLevel: 0, - - /** @type int */ - maxZoomLevel: 16, + /** @type float */ + minResolution: null, - /** @type OpenLayers.Size */ - tileSize: null, + /** @type float */ + maxScale: null, - /** @type String */ - units: 'degrees', - - /** @type Float */ + /** @type float */ minScale: null, + + /** @type OpenLayers.Bounds */ + maxExtent: null, + /** @type OpenLayers.Bounds */ + minExtent: null, + + /** @type int */ + numZoomLevels: 16, /** @@ -207,16 +212,6 @@ OpenLayers.Map.prototype = { // now add the options declared by the user // (these will override defaults) Object.extend(this, options); - - // if maxResolution is specified as "auto", calculate it - // based on the maxExtent and the viewSize - // - if (this.maxResolution == "auto" || this.maxResolution == null) { - var maxExtent = this.getMaxExtent(); - var viewSize = this.getSize(); - this.maxResolution = Math.max(maxExtent.getWidth() / viewSize.w, - maxExtent.getHeight() / viewSize.h ); - } }, /** @@ -647,8 +642,8 @@ OpenLayers.Map.prototype = { */ isValidZoomLevel: function(zoomLevel) { return ( (zoomLevel != null) && - (zoomLevel >= this.getMinZoomLevel()) && - (zoomLevel <= this.getMaxZoomLevel()) ); + (zoomLevel >= 0) && + (zoomLevel < this.getNumZoomLevels()) ); }, /** @@ -684,15 +679,9 @@ OpenLayers.Map.prototype = { */ getProjection: function() { var projection = null; - if (this.baseLayer != null) { projection = this.baseLayer.getProjection(); } - - if (projection == null) { - projection = this.projection; - } - return projection; }, @@ -702,15 +691,9 @@ OpenLayers.Map.prototype = { */ getMaxResolution: function() { var maxResolution = null; - if (this.baseLayer != null) { maxResolution = this.baseLayer.getMaxResolution(); } - - if (maxResolution == null) { - maxResolution = this.maxResolution; - } - return maxResolution; }, @@ -719,55 +702,25 @@ OpenLayers.Map.prototype = { */ getMaxExtent: function () { var maxExtent = null; - if (this.baseLayer != null) { maxExtent = this.baseLayer.getMaxExtent(); - } - - if (maxExtent == null) { - maxExtent = this.maxExtent; - } - + } return maxExtent; }, /** - * @returns The maximum zoom level that can be reached in the map + * @returns The total number of zoom levels that can be displayed by the + * current baseLayer. * @type int */ - getMaxZoomLevel: function() { - var maxZoomLevel = null; - + getNumZoomLevels: function() { + var numZoomLevels = null; if (this.baseLayer != null) { - maxZoomLevel = this.baseLayer.getMaxZoomLevel(); + numZoomLevels = this.baseLayer.getNumZoomLevels(); } - - if (maxZoomLevel == null) { - maxZoomLevel = this.maxZoomLevel; - } - - return maxZoomLevel; + return numZoomLevels; }, - /** - * @returns The minimum zoom level that can be reached in the map - * @type int - */ - getMinZoomLevel: function() { - var minZoomLevel = null; - - if (this.baseLayer != null) { - minZoomLevel = this.baseLayer.getMinZoomLevel(); - } - - if (minZoomLevel == null) { - minZoomLevel = this.minZoomLevel; - } - - return minZoomLevel; - }, - - /********************************************************/ /* */ /* Baselayer Functions */ @@ -787,7 +740,6 @@ OpenLayers.Map.prototype = { */ getExtent: function () { var extent = null; - if (this.baseLayer != null) { extent = this.baseLayer.getExtent(); } @@ -801,7 +753,6 @@ OpenLayers.Map.prototype = { */ getResolution: function () { var resolution = null; - if (this.baseLayer != null) { resolution = this.baseLayer.getResolution(); } @@ -815,7 +766,6 @@ OpenLayers.Map.prototype = { */ getScale: function () { var scale = null; - if (this.baseLayer != null) { var res = this.getResolution(); var units = this.baseLayer.units; @@ -835,7 +785,6 @@ OpenLayers.Map.prototype = { */ getZoomForExtent: function (bounds) { zoom = null; - if (this.baseLayer != null) { zoom = this.baseLayer.getZoomForExtent(bounds); } diff --git a/tests/test_Layer.html b/tests/test_Layer.html index 0959e8d9c1..8b17d8b2bb 100644 --- a/tests/test_Layer.html +++ b/tests/test_Layer.html @@ -89,19 +89,17 @@ function test_04_Layer_StandardOptionsAccessors (t) { - t.plan( 5 ); + t.plan( 4 ); var projection = "chicken"; var maxExtent = new OpenLayers.Bounds(50,50,100,100); var maxResolution = 1.5726; - var minZoomLevel = 5; - var maxZoomLevel = 15; + var numZoomLevels = 11; var options = { projection: projection, maxExtent: maxExtent, maxResolution: maxResolution, - minZoomLevel: minZoomLevel, - maxZoomLevel: maxZoomLevel + numZoomLevels: numZoomLevels, }; var layer = new OpenLayers.Layer('Test Layer', options); @@ -109,8 +107,7 @@ t.eq(layer.getProjection(), projection, "getProjection() works"); t.ok(layer.getMaxExtent().equals(maxExtent), "getMaxExtent() works"); t.eq(layer.getMaxResolution(), maxResolution, "getMaxResolution() works"); - t.eq(layer.getMinZoomLevel(), minZoomLevel, "getMinZoomLevel() works"); - t.eq(layer.getMaxZoomLevel(), maxZoomLevel, "getMaxZoomLevel() works"); + t.eq(layer.getNumZoomLevels(), numZoomLevels, "getNumZoomLevels() works"); } function test_05_Layer_visibility(t) { diff --git a/tests/test_Map.html b/tests/test_Map.html index 11ccc79ec9..2cc49f35ee 100644 --- a/tests/test_Map.html +++ b/tests/test_Map.html @@ -27,7 +27,7 @@ t.ok( map.controls instanceof Array, "map.controls is an Array" ); t.ok( map.events instanceof OpenLayers.Events, "map.events is an OpenLayers.Events" ); t.ok( map.getMaxExtent() instanceof OpenLayers.Bounds, "map.maxExtent is an OpenLayers.Bounds" ); - t.ok( map.getMaxZoomLevel() > 0, "map.maxZoomLevel is set" ); + t.ok( map.getNumZoomLevels() > 0, "map has a default numZoomLevels" ); } function test_02_Map_center(t) { t.plan(3); @@ -63,8 +63,8 @@ } function test_04_Map_options(t) { t.plan(2); - map = new OpenLayers.Map($('map'), {maxZoomLevel: 5, maxResolution: 3.14159}); - t.eq( map.maxZoomLevel, 5, "map.maxZoomLevel set correctly via options hashtable" ); + map = new OpenLayers.Map($('map'), {numZoomLevels: 6, maxResolution: 3.14159}); + t.eq( map.numZoomLevels, 6, "map.numZoomLevels set correctly via options hashtable" ); t.eq( map.maxResolution, 3.14159, "map.maxResolution set correctly via options hashtable" ); } function test_05_Map_center(t) { @@ -151,14 +151,6 @@ } t.ok(!found, "popup.div successfully removed from the map's viewPort"); } - function test_10_Map_auto_res(t) { - t.plan(2); - map = new OpenLayers.Map($('map'), {maxZoomLevel: 5, maxResolution: 'auto'}); - t.eq( map.maxResolution, 1/3, "map.maxResolution set correctly via auto" ); - map = new OpenLayers.Map($('map'), {maxZoomLevel: 5, maxResolution: null}); - t.eq( map.maxResolution, 1/3, "map.maxResolution set correctly via null" ); - } - /*** THIS IS A GOOD TEST, BUT IT SHOULD BE MOVED TO WMS. * Also, it won't work until we figure out the viewSize bug