diff --git a/src/ol/reproj/image.js b/src/ol/reproj/image.js index ed4a67f0bd..0a75c9b174 100644 --- a/src/ol/reproj/image.js +++ b/src/ol/reproj/image.js @@ -49,13 +49,16 @@ ol.reproj.Image = function(sourceProj, targetProj, this.canvas_ = this.context_.canvas; var transformInv = ol.proj.getTransform(targetProj, sourceProj); + var maxTargetExtent = targetProj.getExtent(); + var maxSourceExtent = sourceProj.getExtent(); /** * @private * @type {!ol.reproj.Triangulation} */ this.triangles_ = ol.reproj.triangulation.createForExtent( - targetExtent, transformInv); + targetExtent, transformInv, + maxTargetExtent, maxSourceExtent); /** * @private @@ -71,16 +74,15 @@ ol.reproj.Image = function(sourceProj, targetProj, var srcExtent = ol.reproj.triangulation.getSourceExtent(this.triangles_); - var idealSourceResolution = - targetProj.getPointResolution(targetResolution, - ol.extent.getCenter(targetExtent)) * - targetProj.getMetersPerUnit() / sourceProj.getMetersPerUnit(); + var targetCenter = ol.extent.getCenter(targetExtent); + var sourceResolution = ol.reproj.calculateSourceResolution( + sourceProj, targetProj, targetCenter, targetResolution); /** * @private * @type {ol.ImageBase} */ - this.srcImage_ = getImageFunction(srcExtent, idealSourceResolution, + this.srcImage_ = getImageFunction(srcExtent, sourceResolution, pixelRatio, sourceProj); /** diff --git a/src/ol/reproj/tile.js b/src/ol/reproj/tile.js index b63bb62bee..8ba73b0e47 100644 --- a/src/ol/reproj/tile.js +++ b/src/ol/reproj/tile.js @@ -4,6 +4,7 @@ goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.events'); goog.require('goog.events.EventType'); +goog.require('goog.math'); goog.require('goog.object'); goog.require('ol.Tile'); goog.require('ol.TileState'); @@ -56,16 +57,11 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid, */ this.targetTileGrid_ = targetTileGrid; - var targetExtent = targetTileGrid.getTileCoordExtent(this.getTileCoord()); - var targetResolution = targetTileGrid.getResolution(z); - var transformInv = ol.proj.getTransform(targetProj, sourceProj); - /** * @private * @type {!ol.reproj.Triangulation} */ - this.triangles_ = ol.reproj.triangulation.createForExtent( - targetExtent, transformInv); + this.triangles_ = []; /** * @private @@ -79,18 +75,48 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid, */ this.sourcesListenerKeys_ = null; - var idealSourceResolution = - targetProj.getPointResolution(targetResolution, - ol.extent.getCenter(targetExtent)) * - targetProj.getMetersPerUnit() / sourceProj.getMetersPerUnit(); - /** * @private * @type {number} */ - this.srcZ_ = sourceTileGrid.getZForResolution(idealSourceResolution); + this.srcZ_ = 0; + + + var targetExtent = targetTileGrid.getTileCoordExtent(this.getTileCoord()); + var maxTargetExtent = this.targetTileGrid_.getExtent(); + var maxSourceExtent = this.sourceTileGrid_.getExtent(); + + if (!ol.extent.intersects(maxTargetExtent, targetExtent)) { + // Tile is completely outside range -> EMPTY + // TODO: is it actually correct that the source even creates the tile ? + this.state = ol.TileState.EMPTY; + //return; + } + + var transformInv = ol.proj.getTransform(targetProj, sourceProj); + this.triangles_ = ol.reproj.triangulation.createForExtent( + targetExtent, transformInv, maxTargetExtent, maxSourceExtent); + + var targetCenter = ol.extent.getCenter(targetExtent); + var targetResolution = targetTileGrid.getResolution(z); + var sourceResolution = ol.reproj.calculateSourceResolution( + sourceProj, targetProj, targetCenter, targetResolution); + + if (!goog.math.isFiniteNumber(sourceResolution) || sourceResolution <= 0) { + // invalid sourceResolution -> EMPTY + // probably edges of the projections when no extent is defined + this.state = ol.TileState.EMPTY; + return; + } + + this.srcZ_ = sourceTileGrid.getZForResolution(sourceResolution); var srcExtent = ol.reproj.triangulation.getSourceExtent(this.triangles_); + var sourceProjExtent = sourceProj.getExtent(); + if (sourceProjExtent) { + srcExtent = ol.extent.getIntersection(srcExtent, sourceProjExtent); + } + if (!ol.extent.intersects(sourceTileGrid.getExtent(), srcExtent)) { this.state = ol.TileState.EMPTY; } else { @@ -103,6 +129,14 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid, srcRange.minY = Math.max(srcRange.minY, srcFullRange.minY); srcRange.maxY = Math.min(srcRange.maxY, srcFullRange.maxY); + if (srcRange.getWidth() * srcRange.getHeight() > 100) { + // Too many source tiles are needed -- something probably went wrong + // This sometimes happens for certain non-global projections + // if no extent is specified. + // TODO: detect somehow better? or at least make this a define + this.state = ol.TileState.ERROR; + return; + } for (var srcX = srcRange.minX; srcX <= srcRange.maxX; srcX++) { for (var srcY = srcRange.minY; srcY <= srcRange.maxY; srcY++) { var tile = getTileFunction(this.srcZ_, srcX, srcY, pixelRatio);