diff --git a/src/ol/layer/TileLayer.js b/src/ol/layer/TileLayer.js index dec560ef78..c87a318d0c 100644 --- a/src/ol/layer/TileLayer.js +++ b/src/ol/layer/TileLayer.js @@ -50,6 +50,18 @@ ol.layer.TileLayer = function() { */ this.tileOriginCorner_ = 'bl'; + /** + * @private + * @type {number|undefined} + */ + this.maxResolution_ = undefined; + + /** + * @private + * @type {number|undefined} + */ + this.numZoomLevels_ = undefined; + /** * @protected * @type {Array.} @@ -121,6 +133,20 @@ ol.layer.TileLayer.prototype.getTileOrigin = function() { return null; }; +/** + * Get layer resolutions. Return null if the layer has no resolutions. + * @return {Array.} + */ +ol.layer.TileLayer.prototype.getResolutions = function() { + if (goog.isNull(this.resolutions_) && goog.isDef(this.maxResolution_)) { + this.resolutions_ = []; + for (var i = 0; i < this.numZoomLevels_; i++) { + this.resolutions_[i] = this.maxResolution_ / Math.pow(2, i); + } + } + return this.resolutions_; +}; + /** * Set layer projection. * @param {ol.Projection} projection @@ -165,6 +191,22 @@ ol.layer.TileLayer.prototype.setTileOriginCorner = function(tileOriginCorner) { this.tileOriginCorner_ = tileOriginCorner; }; +/** + * Set maximum resolution. + * @param {number} maxResolution + */ +ol.layer.TileLayer.prototype.setMaxResolution = function(maxResolution) { + this.maxResolution_ = maxResolution; +}; + +/** + * Set the number of zoom levels. + * @param {number} numZoomLevels + */ +ol.layer.TileLayer.prototype.setNumZoomLevels = function(numZoomLevels) { + this.numZoomLevels_ = numZoomLevels; +}; + /** * Set resolutions for the layer. * @param {Array.} resolutions diff --git a/src/ol/layer/XYZ.js b/src/ol/layer/XYZ.js index e26e81f26a..b9f1200347 100644 --- a/src/ol/layer/XYZ.js +++ b/src/ol/layer/XYZ.js @@ -24,16 +24,7 @@ ol.layer.XYZ = function(url) { goog.base(this); - this.setResolutions([ - 156543.03390625, 78271.516953125, 39135.7584765625, - 19567.87923828125, 9783.939619140625, 4891.9698095703125, - 2445.9849047851562, 1222.9924523925781, 611.4962261962891, - 305.74811309814453, 152.87405654907226, 76.43702827453613, - 38.218514137268066, 19.109257068634033, 9.554628534317017, - 4.777314267158508, 2.388657133579254, 1.194328566789627, - 0.5971642833948135, 0.29858214169740677, 0.14929107084870338, - 0.07464553542435169 - ]); + this.setMaxResolution(156543.03390625); }; goog.inherits(ol.layer.XYZ, ol.layer.TileLayer); @@ -45,8 +36,9 @@ goog.inherits(ol.layer.XYZ, ol.layer.TileLayer); */ ol.layer.XYZ.prototype.getData = function(bounds, resolution) { var me = this, - zoom = me.zoomForResolution(resolution); - resolution = me.resolutions_[zoom]; + zoomAndRes = me.getZoomAndRes(resolution), + zoom = zoomAndRes[0]; + resolution = zoomAndRes[1]; // define some values used for the actual tiling var boundsMinX = bounds.getMinX(), @@ -88,7 +80,7 @@ ol.layer.XYZ.prototype.getData = function(bounds, resolution) { tileRight, tileTop, this.projection_); url = me.url_.replace('{x}', offsetX + x + '') .replace('{y}', offsetY + y + '') - .replace('{z}', zoom); + .replace('{z}', zoom + ''); tile = new ol.Tile(url, tileBounds); tiles[y][x] = tile; } @@ -98,13 +90,15 @@ ol.layer.XYZ.prototype.getData = function(bounds, resolution) { }; /** - * Get the zoom level (z) for the given resolution. + * Get the zoom level (z) and layer resolution for the given resolution. * @param {number} resolution + * @return {Array.} */ -ol.layer.XYZ.prototype.zoomForResolution = function(resolution) { +ol.layer.XYZ.prototype.getZoomAndRes = function(resolution) { var delta = Number.POSITIVE_INFINITY, currentDelta, - resolutions = this.resolutions_; + resolutions = this.getResolutions(), + zoom; for (var i=resolutions.length-1; i>=0; --i) { currentDelta = Math.abs(resolutions[i] - resolution); if (currentDelta > delta) { @@ -112,5 +106,6 @@ ol.layer.XYZ.prototype.zoomForResolution = function(resolution) { } delta = currentDelta; } - return i + 1; + zoom = i + 1; + return [zoom, resolutions[zoom]]; }; diff --git a/test/spec/api/map.test.js b/test/spec/api/map.test.js index 0b6b9db149..1c16b6b94a 100644 --- a/test/spec/api/map.test.js +++ b/test/spec/api/map.test.js @@ -145,7 +145,7 @@ describe("ol.map", function() { it("provides feedback when you mess up", function() { var map; - if (ol.DEBUG) { + if (goog.DEBUG) { // misspelling expect(function() { map = ol.map({ diff --git a/test/spec/ol/layer/TileLayer.test.js b/test/spec/ol/layer/TileLayer.test.js index 4f0f31fcc7..e252258b90 100644 --- a/test/spec/ol/layer/TileLayer.test.js +++ b/test/spec/ol/layer/TileLayer.test.js @@ -16,7 +16,7 @@ describe('ol.layer.TileLayer', function() { layer = new ol.layer.TileLayer(); }); - describe('with tileOriginX and tileOriginY set', function() { + describe('with tileOriginX and tileOriginY', function() { beforeEach(function() { layer.setTileOrigin(1, 2); @@ -29,7 +29,7 @@ describe('ol.layer.TileLayer', function() { }); - describe('with extent set', function() { + describe('with extent', function() { beforeEach(function() { layer.setExtent(new ol.Bounds(-180, -90, 180, 90)); @@ -42,7 +42,7 @@ describe('ol.layer.TileLayer', function() { }); - describe('with extent and tileOriginCorner set', function() { + describe('with tileOriginCorner and extent', function() { beforeEach(function() { layer.setExtent(new ol.Bounds(-180, -90, 180, 90)); @@ -56,6 +56,81 @@ describe('ol.layer.TileLayer', function() { }); + describe('with tileOriginCorner, without extent', function() { + + beforeEach(function() { + layer.setTileOriginCorner('tr'); + }); + + it('throws an error or return null', function() { + var origin; + if (goog.DEBUG) { + expect(function() { + origin = layer.getTileOrigin(); + }).toThrow(); + } else { + expect(function() { + origin = layer.getTileOrigin(); + }).not.toThrow(); + expect(origin).toBeNull(); + } + }); + + }); + + describe('with bad tileOriginCorner', function() { + + beforeEach(function() { + layer.setTileOriginCorner('foo'); + }); + + it('returns the expected origin', function() { + if (goog.DEBUG) { + expect(function() { + var origin = layer.getTileOrigin(); + }).toThrow(); + } else { + expect(function() { + var origin = layer.getTileOrigin(); + }).not.toThrow(); + } + }); + + }); }); + describe('get resolutions', function() { + var layer; + + beforeEach(function() { + layer = new ol.layer.TileLayer(); + }); + + describe('with resolutions set', function() { + + beforeEach(function() { + layer.setResolutions([1, 0.5, 0.25]); + }); + + it('returns the expected resolutions', function() { + var resolutions = layer.getResolutions(); + expect(resolutions).toEqual([1, 0.5, 0.25]); + }); + + }); + + describe('with maxResolution and numZoomLevels set', function() { + + beforeEach(function() { + layer.setMaxResolution(1); + layer.setNumZoomLevels(3); + }); + + it('returns the expected resolutions', function() { + var resolutions = layer.getResolutions(); + expect(resolutions).toEqual([1, 0.5, 0.25]); + }); + + }); + }); });