Handle tile coordinate wrapping when reprojecting raster tiles

This commit is contained in:
Petr Sloup
2015-12-11 13:27:57 +01:00
parent c4237c7858
commit 9f5d85f2c6
4 changed files with 27 additions and 16 deletions

View File

@@ -33,9 +33,8 @@ ol.reproj.TileFunctionType;
* @param {ol.tilegrid.TileGrid} sourceTileGrid Source tile grid. * @param {ol.tilegrid.TileGrid} sourceTileGrid Source tile grid.
* @param {ol.proj.Projection} targetProj Target projection. * @param {ol.proj.Projection} targetProj Target projection.
* @param {ol.tilegrid.TileGrid} targetTileGrid Target tile grid. * @param {ol.tilegrid.TileGrid} targetTileGrid Target tile grid.
* @param {number} z Zoom level. * @param {ol.TileCoord} tileCoord Coordinate of the tile.
* @param {number} x X. * @param {ol.TileCoord} wrappedTileCoord Coordinate of the tile wrapped in X.
* @param {number} y Y.
* @param {number} pixelRatio Pixel ratio. * @param {number} pixelRatio Pixel ratio.
* @param {ol.reproj.TileFunctionType} getTileFunction * @param {ol.reproj.TileFunctionType} getTileFunction
* Function returning source tiles (z, x, y, pixelRatio). * Function returning source tiles (z, x, y, pixelRatio).
@@ -43,10 +42,11 @@ ol.reproj.TileFunctionType;
* @param {boolean=} opt_renderEdges Render reprojection edges. * @param {boolean=} opt_renderEdges Render reprojection edges.
*/ */
ol.reproj.Tile = function(sourceProj, sourceTileGrid, ol.reproj.Tile = function(sourceProj, sourceTileGrid,
targetProj, targetTileGrid, z, x, y, pixelRatio, getTileFunction, targetProj, targetTileGrid, tileCoord, wrappedTileCoord,
pixelRatio, getTileFunction,
opt_errorThreshold, opt_errorThreshold,
opt_renderEdges) { opt_renderEdges) {
goog.base(this, [z, x, y], ol.TileState.IDLE); goog.base(this, tileCoord, ol.TileState.IDLE);
/** /**
* @private * @private
@@ -84,6 +84,12 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid,
*/ */
this.targetTileGrid_ = targetTileGrid; this.targetTileGrid_ = targetTileGrid;
/**
* @private
* @type {ol.TileCoord}
*/
this.wrappedTileCoord_ = wrappedTileCoord ? wrappedTileCoord : tileCoord;
/** /**
* @private * @private
* @type {!Array.<ol.Tile>} * @type {!Array.<ol.Tile>}
@@ -102,7 +108,7 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid,
*/ */
this.sourceZ_ = 0; this.sourceZ_ = 0;
var targetExtent = targetTileGrid.getTileCoordExtent(this.getTileCoord()); var targetExtent = targetTileGrid.getTileCoordExtent(this.wrappedTileCoord_);
var maxTargetExtent = this.targetTileGrid_.getExtent(); var maxTargetExtent = this.targetTileGrid_.getExtent();
var maxSourceExtent = this.sourceTileGrid_.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 targetCenter = ol.extent.getCenter(limitedTargetExtent);
var sourceResolution = ol.reproj.calculateSourceResolution( var sourceResolution = ol.reproj.calculateSourceResolution(
@@ -248,15 +255,15 @@ ol.reproj.Tile.prototype.reproject_ = function() {
}, this); }, this);
this.sourceTiles_.length = 0; this.sourceTiles_.length = 0;
var tileCoord = this.getTileCoord(); var z = this.wrappedTileCoord_[0];
var z = tileCoord[0];
var size = this.targetTileGrid_.getTileSize(z); var size = this.targetTileGrid_.getTileSize(z);
var width = goog.isNumber(size) ? size : size[0]; var width = goog.isNumber(size) ? size : size[0];
var height = goog.isNumber(size) ? size : size[1]; var height = goog.isNumber(size) ? size : size[1];
var targetResolution = this.targetTileGrid_.getResolution(z); var targetResolution = this.targetTileGrid_.getResolution(z);
var sourceResolution = this.sourceTileGrid_.getResolution(this.sourceZ_); 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_, this.canvas_ = ol.reproj.render(width, height, this.pixelRatio_,
sourceResolution, this.sourceTileGrid_.getExtent(), sourceResolution, this.sourceTileGrid_.getExtent(),
targetResolution, targetExtent, this.triangulation_, sources, targetResolution, targetExtent, this.triangulation_, sources,

View File

@@ -204,17 +204,20 @@ ol.source.TileImage.prototype.getTile =
return this.getTileInternal(z, x, y, pixelRatio, projection); return this.getTileInternal(z, x, y, pixelRatio, projection);
} else { } else {
var cache = this.getTileCacheForProjection(projection); 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)) { if (cache.containsKey(tileCoordKey)) {
return /** @type {!ol.Tile} */ (cache.get(tileCoordKey)); return /** @type {!ol.Tile} */ (cache.get(tileCoordKey));
} else { } else {
var sourceProjection = this.getProjection(); var sourceProjection = this.getProjection();
var sourceTileGrid = this.getTileGridForProjection(sourceProjection); var sourceTileGrid = this.getTileGridForProjection(sourceProjection);
var targetTileGrid = this.getTileGridForProjection(projection); var targetTileGrid = this.getTileGridForProjection(projection);
var wrappedTileCoord =
this.getTileCoordForTileUrlFunction(tileCoord, projection);
var tile = new ol.reproj.Tile( var tile = new ol.reproj.Tile(
sourceProjection, sourceTileGrid, sourceProjection, sourceTileGrid,
projection, targetTileGrid, projection, targetTileGrid,
z, x, y, this.getTilePixelRatio(), tileCoord, wrappedTileCoord, this.getTilePixelRatio(),
goog.bind(function(z, x, y, pixelRatio) { goog.bind(function(z, x, y, pixelRatio) {
return this.getTileInternal(z, x, y, pixelRatio, sourceProjection); return this.getTileInternal(z, x, y, pixelRatio, sourceProjection);
}, this), this.reprojectionErrorThreshold_, }, this), this.reprojectionErrorThreshold_,

View File

@@ -21,7 +21,7 @@ describe('ol.reproj.Tile', function() {
return new ol.reproj.Tile( return new ol.reproj.Tile(
proj3857, ol.tilegrid.createForProjection(proj3857), proj4326, proj3857, ol.tilegrid.createForProjection(proj3857), proj4326,
ol.tilegrid.createForProjection(proj4326, 3, opt_tileSize), 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, return new ol.ImageTile([z, x, y], ol.TileState.IDLE,
'data:image/gif;base64,' + 'data:image/gif;base64,' +
'R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=', null, 'R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=', null,
@@ -48,7 +48,7 @@ describe('ol.reproj.Tile', function() {
var tile = new ol.reproj.Tile( var tile = new ol.reproj.Tile(
proj3857, ol.tilegrid.createForProjection(proj3857), proj3857, ol.tilegrid.createForProjection(proj3857),
proj4326, ol.tilegrid.createForProjection(proj4326), proj4326, ol.tilegrid.createForProjection(proj4326),
0, -1, 0, 1, function() { [0, -1, 0], null, 1, function() {
expect().fail('No tiles should be required'); expect().fail('No tiles should be required');
}); });
expect(tile.getState()).to.be(ol.TileState.EMPTY); expect(tile.getState()).to.be(ol.TileState.EMPTY);
@@ -60,7 +60,7 @@ describe('ol.reproj.Tile', function() {
var tile = new ol.reproj.Tile( var tile = new ol.reproj.Tile(
proj27700, ol.tilegrid.createForProjection(proj27700), proj27700, ol.tilegrid.createForProjection(proj27700),
proj4326, ol.tilegrid.createForProjection(proj4326), proj4326, ol.tilegrid.createForProjection(proj4326),
3, 2, -2, 1, function() { [3, 2, -2], null, 1, function() {
expect().fail('No tiles should be required'); expect().fail('No tiles should be required');
}); });
expect(tile.getState()).to.be(ol.TileState.EMPTY); expect(tile.getState()).to.be(ol.TileState.EMPTY);

View File

@@ -9,7 +9,8 @@ describe('ol.rendering.reproj.Tile', function() {
var tilesRequested = 0; var tilesRequested = 0;
var tile = new ol.reproj.Tile(sourceProjection, source.getTileGrid(), 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) { function(z, x, y, pixelRatio) {
tilesRequested++; tilesRequested++;
return source.getTile(z, x, y, pixelRatio, sourceProjection); return source.getTile(z, x, y, pixelRatio, sourceProjection);