From 9f5d85f2c6f96e64497f53d1c49834135dadd3da Mon Sep 17 00:00:00 2001 From: Petr Sloup Date: Fri, 11 Dec 2015 13:27:57 +0100 Subject: [PATCH] Handle tile coordinate wrapping when reprojecting raster tiles --- src/ol/reproj/tile.js | 27 ++++++++++++++-------- src/ol/source/tileimagesource.js | 7 ++++-- test/spec/ol/reproj/tile.test.js | 6 ++--- test_rendering/spec/ol/reproj/tile.test.js | 3 ++- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/ol/reproj/tile.js b/src/ol/reproj/tile.js index a1c819d620..c657c08649 100644 --- a/src/ol/reproj/tile.js +++ b/src/ol/reproj/tile.js @@ -33,9 +33,8 @@ ol.reproj.TileFunctionType; * @param {ol.tilegrid.TileGrid} sourceTileGrid Source tile grid. * @param {ol.proj.Projection} targetProj Target projection. * @param {ol.tilegrid.TileGrid} targetTileGrid Target tile grid. - * @param {number} z Zoom level. - * @param {number} x X. - * @param {number} y Y. + * @param {ol.TileCoord} tileCoord Coordinate of the tile. + * @param {ol.TileCoord} wrappedTileCoord Coordinate of the tile wrapped in X. * @param {number} pixelRatio Pixel ratio. * @param {ol.reproj.TileFunctionType} getTileFunction * Function returning source tiles (z, x, y, pixelRatio). @@ -43,10 +42,11 @@ ol.reproj.TileFunctionType; * @param {boolean=} opt_renderEdges Render reprojection edges. */ ol.reproj.Tile = function(sourceProj, sourceTileGrid, - targetProj, targetTileGrid, z, x, y, pixelRatio, getTileFunction, + targetProj, targetTileGrid, tileCoord, wrappedTileCoord, + pixelRatio, getTileFunction, opt_errorThreshold, opt_renderEdges) { - goog.base(this, [z, x, y], ol.TileState.IDLE); + goog.base(this, tileCoord, ol.TileState.IDLE); /** * @private @@ -84,6 +84,12 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid, */ this.targetTileGrid_ = targetTileGrid; + /** + * @private + * @type {ol.TileCoord} + */ + this.wrappedTileCoord_ = wrappedTileCoord ? wrappedTileCoord : tileCoord; + /** * @private * @type {!Array.} @@ -102,7 +108,7 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid, */ this.sourceZ_ = 0; - var targetExtent = targetTileGrid.getTileCoordExtent(this.getTileCoord()); + var targetExtent = targetTileGrid.getTileCoordExtent(this.wrappedTileCoord_); var maxTargetExtent = this.targetTileGrid_.getExtent(); var maxSourceExtent = this.sourceTileGrid_.getExtent(); @@ -126,7 +132,8 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid, } } - var targetResolution = targetTileGrid.getResolution(z); + var targetResolution = targetTileGrid.getResolution( + this.wrappedTileCoord_[0]); var targetCenter = ol.extent.getCenter(limitedTargetExtent); var sourceResolution = ol.reproj.calculateSourceResolution( @@ -248,15 +255,15 @@ ol.reproj.Tile.prototype.reproject_ = function() { }, this); this.sourceTiles_.length = 0; - var tileCoord = this.getTileCoord(); - var z = tileCoord[0]; + var z = this.wrappedTileCoord_[0]; var size = this.targetTileGrid_.getTileSize(z); var width = goog.isNumber(size) ? size : size[0]; var height = goog.isNumber(size) ? size : size[1]; var targetResolution = this.targetTileGrid_.getResolution(z); var sourceResolution = this.sourceTileGrid_.getResolution(this.sourceZ_); - var targetExtent = this.targetTileGrid_.getTileCoordExtent(tileCoord); + var targetExtent = this.targetTileGrid_.getTileCoordExtent( + this.wrappedTileCoord_); this.canvas_ = ol.reproj.render(width, height, this.pixelRatio_, sourceResolution, this.sourceTileGrid_.getExtent(), targetResolution, targetExtent, this.triangulation_, sources, diff --git a/src/ol/source/tileimagesource.js b/src/ol/source/tileimagesource.js index 3b77c6b542..b9df921f8b 100644 --- a/src/ol/source/tileimagesource.js +++ b/src/ol/source/tileimagesource.js @@ -204,17 +204,20 @@ ol.source.TileImage.prototype.getTile = return this.getTileInternal(z, x, y, pixelRatio, projection); } else { var cache = this.getTileCacheForProjection(projection); - var tileCoordKey = this.getKeyZXY(z, x, y); + var tileCoord = [z, x, y]; + var tileCoordKey = this.getKeyZXY.apply(this, tileCoord); if (cache.containsKey(tileCoordKey)) { return /** @type {!ol.Tile} */ (cache.get(tileCoordKey)); } else { var sourceProjection = this.getProjection(); var sourceTileGrid = this.getTileGridForProjection(sourceProjection); var targetTileGrid = this.getTileGridForProjection(projection); + var wrappedTileCoord = + this.getTileCoordForTileUrlFunction(tileCoord, projection); var tile = new ol.reproj.Tile( sourceProjection, sourceTileGrid, projection, targetTileGrid, - z, x, y, this.getTilePixelRatio(), + tileCoord, wrappedTileCoord, this.getTilePixelRatio(), goog.bind(function(z, x, y, pixelRatio) { return this.getTileInternal(z, x, y, pixelRatio, sourceProjection); }, this), this.reprojectionErrorThreshold_, diff --git a/test/spec/ol/reproj/tile.test.js b/test/spec/ol/reproj/tile.test.js index 1354b804fb..27d35b4740 100644 --- a/test/spec/ol/reproj/tile.test.js +++ b/test/spec/ol/reproj/tile.test.js @@ -21,7 +21,7 @@ describe('ol.reproj.Tile', function() { return new ol.reproj.Tile( proj3857, ol.tilegrid.createForProjection(proj3857), proj4326, ol.tilegrid.createForProjection(proj4326, 3, opt_tileSize), - 3, 2, -2, pixelRatio, function(z, x, y, pixelRatio) { + [3, 2, -2], null, pixelRatio, function(z, x, y, pixelRatio) { return new ol.ImageTile([z, x, y], ol.TileState.IDLE, 'data:image/gif;base64,' + 'R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=', null, @@ -48,7 +48,7 @@ describe('ol.reproj.Tile', function() { var tile = new ol.reproj.Tile( proj3857, ol.tilegrid.createForProjection(proj3857), proj4326, ol.tilegrid.createForProjection(proj4326), - 0, -1, 0, 1, function() { + [0, -1, 0], null, 1, function() { expect().fail('No tiles should be required'); }); expect(tile.getState()).to.be(ol.TileState.EMPTY); @@ -60,7 +60,7 @@ describe('ol.reproj.Tile', function() { var tile = new ol.reproj.Tile( proj27700, ol.tilegrid.createForProjection(proj27700), proj4326, ol.tilegrid.createForProjection(proj4326), - 3, 2, -2, 1, function() { + [3, 2, -2], null, 1, function() { expect().fail('No tiles should be required'); }); expect(tile.getState()).to.be(ol.TileState.EMPTY); diff --git a/test_rendering/spec/ol/reproj/tile.test.js b/test_rendering/spec/ol/reproj/tile.test.js index 9e0d02905f..a7cc30a627 100644 --- a/test_rendering/spec/ol/reproj/tile.test.js +++ b/test_rendering/spec/ol/reproj/tile.test.js @@ -9,7 +9,8 @@ describe('ol.rendering.reproj.Tile', function() { var tilesRequested = 0; var tile = new ol.reproj.Tile(sourceProjection, source.getTileGrid(), - ol.proj.get(targetProjection), targetTileGrid, z, x, y, pixelRatio, + ol.proj.get(targetProjection), targetTileGrid, + [z, x, y], null, pixelRatio, function(z, x, y, pixelRatio) { tilesRequested++; return source.getTile(z, x, y, pixelRatio, sourceProjection);