From 59953b8eb6fefad3679e46c5f16ca104dddd0ef8 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Fri, 20 Aug 2010 19:40:53 +0000 Subject: [PATCH] Adding a zoomOffset property to XYZ and TMS layers. This allows you to have a map with a maximum resolution that differs from the maximum cache resolution (if you want to show a subset of OSM for example). r=ahocevar (closes #2616) git-svn-id: http://svn.openlayers.org/trunk/openlayers@10650 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- examples/xyz-offset.html | 33 +++++++++++++++++++++++ examples/xyz-offset.js | 37 ++++++++++++++++++++++++++ lib/OpenLayers/Layer/TMS.js | 16 ++++++++++- lib/OpenLayers/Layer/XYZ.js | 14 +++++++++- tests/Layer/TMS.html | 53 +++++++++++++++++++++++++++++++++++++ tests/Layer/XYZ.html | 41 ++++++++++++++++++++++++++++ 6 files changed, 192 insertions(+), 2 deletions(-) create mode 100644 examples/xyz-offset.html create mode 100644 examples/xyz-offset.js diff --git a/examples/xyz-offset.html b/examples/xyz-offset.html new file mode 100644 index 0000000000..8ba464e8c7 --- /dev/null +++ b/examples/xyz-offset.html @@ -0,0 +1,33 @@ + + + + OpenLayers XYZ with Offset + + + + + + +

XYZ Layer with Offset

+ +
Using a limited set of levels from an XYZ layer with zoomOffset.
+ +
+ +
+

+ The XYZ layer allows a zoomOffset to be set if you want to have + a maximum resolution for the map that differs from the maxiumum + resolution of the cached tiles. This example uses only 6 of the + levels in the cache, starting with the ninth level (index of 8) + in the cache. To do this, the layer is constructed with a + zoomOffset of 8. When the map zoom level is zero, the level + with index 8 will be requested from the cache. +

+

+ See the + xyz-offset.js source to see how this is done. +

+
+ + diff --git a/examples/xyz-offset.js b/examples/xyz-offset.js new file mode 100644 index 0000000000..6e7fa94745 --- /dev/null +++ b/examples/xyz-offset.js @@ -0,0 +1,37 @@ +var map, layer; + +// if tiles are not available, hide images +//OpenLayers.Util.onImageLoadError = function() { +// this.style.display = "none"; +//} + +// called on body load +function init() { + + var extent = new OpenLayers.Bounds( + -13758743.4295939, 5591455.28887228, -13531302.3472101 , 5757360.4178881 + ); + + map = new OpenLayers.Map({ + div: "map", + maxExtent: new OpenLayers.Bounds( + -128 * 156543.0339, -128 * 156543.0339, + 128 * 156543.0339, 128 * 156543.0339 + ), + restrictedExtent: extent, + maxResolution: 611.496226171875, // corresponds to level 8 in the cache + numZoomLevels: 6, + projection: new OpenLayers.Projection("EPSG:900913"), + units: "m", + layers: [ + new OpenLayers.Layer.XYZ( + "ESRI", + "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Portland/ESRI_LandBase_WebMercator/MapServer/tile/${z}/${y}/${x}", + {zoomOffset: 8} // since our map maxResolution differs from cache max resolution + ) + ] + }); + + map.zoomToExtent(extent); + +} diff --git a/lib/OpenLayers/Layer/TMS.js b/lib/OpenLayers/Layer/TMS.js index 6d4d14884e..089d9e48bd 100644 --- a/lib/OpenLayers/Layer/TMS.js +++ b/lib/OpenLayers/Layer/TMS.js @@ -41,6 +41,20 @@ OpenLayers.Layer.TMS = OpenLayers.Class(OpenLayers.Layer.Grid, { */ serverResolutions: null, + /** + * APIProperty: zoomOffset + * {Number} If your cache has more zoom levels than you want to provide + * access to with this layer, supply a zoomOffset. This zoom offset + * is added to the current map zoom level to determine the level + * for a requested tile. For example, if you supply a zoomOffset + * of 3, when the map is at the zoom 0, tiles will be requested from + * level 3 of your cache. Default is 0 (assumes cache level and map + * zoom are equivalent). Using is an alternative to + * setting if you only want to expose a subset + * of the server resolutions. + */ + zoomOffset: 0, + /** * Constructor: OpenLayers.Layer.TMS * @@ -107,7 +121,7 @@ OpenLayers.Layer.TMS = OpenLayers.Class(OpenLayers.Layer.Grid, { var y = Math.round((bounds.bottom - this.tileOrigin.lat) / (res * this.tileSize.h)); var z = this.serverResolutions != null ? OpenLayers.Util.indexOf(this.serverResolutions, res) : - this.map.getZoom(); + this.map.getZoom() + this.zoomOffset; var path = this.serviceVersion + "/" + this.layername + "/" + z + "/" + x + "/" + y + "." + this.type; var url = this.url; if (url instanceof Array) { diff --git a/lib/OpenLayers/Layer/XYZ.js b/lib/OpenLayers/Layer/XYZ.js index fe4f25d17f..780994b934 100644 --- a/lib/OpenLayers/Layer/XYZ.js +++ b/lib/OpenLayers/Layer/XYZ.js @@ -31,6 +31,18 @@ OpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, { */ sphericalMercator: false, + /** + * APIProperty: zoomOffset + * {Number} If your cache has more zoom levels than you want to provide + * access to with this layer, supply a zoomOffset. This zoom offset + * is added to the current map zoom level to determine the level + * for a requested tile. For example, if you supply a zoomOffset + * of 3, when the map is at the zoom 0, tiles will be requested from + * level 3 of your cache. Default is 0 (assumes cache level and map + * zoom are equivalent). + */ + zoomOffset: 0, + /** * Constructor: OpenLayers.Layer.XYZ * @@ -101,7 +113,7 @@ OpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, { / (res * this.tileSize.w)); var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h)); - var z = this.map.getZoom(); + var z = this.map.getZoom() + this.zoomOffset; var url = this.url; var s = '' + x + y + z; diff --git a/tests/Layer/TMS.html b/tests/Layer/TMS.html index b94dd5b4e6..e8205da8f3 100644 --- a/tests/Layer/TMS.html +++ b/tests/Layer/TMS.html @@ -166,6 +166,59 @@ map.destroy(); } + function test_zoomOffset(t) { + + t.plan(2); + + var offset, zoom; + + // test offset of 2 + offset = 2; + zoom = 3; + + var map = new OpenLayers.Map({ + div: "map", + maxResolution: OpenLayers.Map.prototype.maxResolution / Math.pow(2, offset) + }); + var layer = new OpenLayers.Layer.TMS("TMS", "", { + layername: "basic", + type: "png", + zoomOffset: offset + }); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0, 0), zoom); + + var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + level = parseInt(tileurl.split("/")[2]); + t.eq(parseInt(tileurl.split("/")[2]), zoom + offset, "correct level for offset 2"); + + map.destroy(); + + // test offset of -1 + offset = -1; + zoom = 3; + + var map = new OpenLayers.Map({ + div: "map", + maxResolution: OpenLayers.Map.prototype.maxResolution / Math.pow(2, offset) + }); + var layer = new OpenLayers.Layer.TMS("TMS", "", { + layername: "basic", + type: "png", + zoomOffset: offset + }); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0, 0), zoom); + + var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + level = parseInt(tileurl.split("/")[2]); + t.eq(parseInt(tileurl.split("/")[2]), zoom + offset, "correct level for offset -1"); + + map.destroy(); + + + } + function test_Layer_TMS_setMap(t) { t.plan(3); diff --git a/tests/Layer/XYZ.html b/tests/Layer/XYZ.html index 99b4616f66..364b147fe6 100644 --- a/tests/Layer/XYZ.html +++ b/tests/Layer/XYZ.html @@ -148,6 +148,47 @@ map.destroy(); } + function test_zoomOffset(t) { + + t.plan(2); + + var offset; + + // test offset of 2 + offset = 2; + + var map = new OpenLayers.Map({ + div: "map", + maxResolution: OpenLayers.Map.prototype.maxResolution / Math.pow(2, offset) + }); + var layer = new OpenLayers.Layer.XYZ(name, url, {zoomOffset: offset}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 7); + + var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/261/63.png", "correct URL for offset of 2"); + + map.destroy(); + + // test offset of -1 + offset = -1; + + var map = new OpenLayers.Map({ + div: "map", + maxResolution: OpenLayers.Map.prototype.maxResolution / Math.pow(2, offset) + }); + var layer = new OpenLayers.Layer.XYZ(name, url, {zoomOffset: offset}); + map.addLayer(layer); + map.setCenter(new OpenLayers.LonLat(0,0), 10); + + var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125)); + t.eq(tileurl, "http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/261/63.png", "correct URL for offset of -1"); + + map.destroy(); + + + } + function test_Layer_XYZ_destroy (t) { t.plan( 3 );