diff --git a/src/ol/renderer/canvas/canvastilelayerrenderer.js b/src/ol/renderer/canvas/canvastilelayerrenderer.js index 3ebc5ecb7e..0d3bdd4df1 100644 --- a/src/ol/renderer/canvas/canvastilelayerrenderer.js +++ b/src/ol/renderer/canvas/canvastilelayerrenderer.js @@ -67,7 +67,7 @@ ol.renderer.canvas.TileLayer.prototype.composeFrame = function( var source = layer.getSource(); goog.asserts.assertInstanceof(source, ol.source.Tile, 'source is an ol.source.Tile'); - var tileGutter = source.getGutter(); + var tileGutter = source.getGutter(projection); var opaque = source.getOpaque(projection); var transform = this.getTransform(frameState, 0); diff --git a/src/ol/renderer/dom/domtilelayerrenderer.js b/src/ol/renderer/dom/domtilelayerrenderer.js index 3b61b771b3..d111d45ccc 100644 --- a/src/ol/renderer/dom/domtilelayerrenderer.js +++ b/src/ol/renderer/dom/domtilelayerrenderer.js @@ -94,7 +94,7 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame = function(frameState, layerSta 'layer is an instance of ol.layer.Tile'); var tileSource = tileLayer.getSource(); var tileGrid = tileSource.getTileGridForProjection(projection); - var tileGutter = tileSource.getGutter(); + var tileGutter = tileSource.getGutter(projection); var z = tileGrid.getZForResolution(viewState.resolution); var tileResolution = tileGrid.getResolution(z); var center = viewState.center; diff --git a/src/ol/renderer/webgl/webgltilelayerrenderer.js b/src/ol/renderer/webgl/webgltilelayerrenderer.js index 5848b7130a..609dfcd92f 100644 --- a/src/ol/renderer/webgl/webgltilelayerrenderer.js +++ b/src/ol/renderer/webgl/webgltilelayerrenderer.js @@ -169,7 +169,7 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame = function(frameState, layerS var pixelRatio = tilePixelSize[0] / ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize_)[0]; var tilePixelResolution = tileResolution / pixelRatio; - var tileGutter = tileSource.getGutter(); + var tileGutter = tileSource.getGutter(projection); var center = viewState.center; var extent; diff --git a/src/ol/reproj/image.js b/src/ol/reproj/image.js index 4d8b81581a..99c3899ab8 100644 --- a/src/ol/reproj/image.js +++ b/src/ol/reproj/image.js @@ -163,7 +163,7 @@ ol.reproj.Image.prototype.reproject_ = function() { this.targetResolution_, this.targetExtent_, this.triangulation_, [{ extent: this.sourceImage_.getExtent(), image: this.sourceImage_.getImage() - }]); + }], 0); } this.state = sourceState; this.changed(); diff --git a/src/ol/reproj/reproj.js b/src/ol/reproj/reproj.js index 03013e6b1d..506aa10475 100644 --- a/src/ol/reproj/reproj.js +++ b/src/ol/reproj/reproj.js @@ -101,12 +101,13 @@ ol.reproj.enlargeClipPoint_ = function(centroidX, centroidY, x, y) { * @param {Array.<{extent: ol.Extent, * image: (HTMLCanvasElement|Image|HTMLVideoElement)}>} sources * Array of sources. + * @param {number} gutter Gutter of the sources. * @param {boolean=} opt_renderEdges Render reprojection edges. * @return {HTMLCanvasElement} Canvas with reprojected data. */ ol.reproj.render = function(width, height, pixelRatio, sourceResolution, sourceExtent, targetResolution, targetExtent, - triangulation, sources, opt_renderEdges) { + triangulation, sources, gutter, opt_renderEdges) { var context = ol.dom.createCanvasContext2D(Math.round(pixelRatio * width), Math.round(pixelRatio * height)); @@ -136,9 +137,12 @@ ol.reproj.render = function(width, height, pixelRatio, var srcWidth = ol.extent.getWidth(src.extent); var srcHeight = ol.extent.getHeight(src.extent); - stitchContext.drawImage(src.image, - xPos * stitchScale, yPos * stitchScale, - srcWidth * stitchScale, srcHeight * stitchScale); + stitchContext.drawImage( + src.image, + gutter, gutter, + src.image.width - 2 * gutter, src.image.height - 2 * gutter, + xPos * stitchScale, yPos * stitchScale, + srcWidth * stitchScale, srcHeight * stitchScale); }); var targetTopLeft = ol.extent.getTopLeft(targetExtent); diff --git a/src/ol/reproj/tile.js b/src/ol/reproj/tile.js index 75331bf6f5..fc3c2f8b88 100644 --- a/src/ol/reproj/tile.js +++ b/src/ol/reproj/tile.js @@ -35,6 +35,7 @@ ol.reproj.TileFunctionType; * @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 {number} gutter Gutter of the source tiles. * @param {ol.reproj.TileFunctionType} getTileFunction * Function returning source tiles (z, x, y, pixelRatio). * @param {number=} opt_errorThreshold Acceptable reprojection error (in px). @@ -42,7 +43,7 @@ ol.reproj.TileFunctionType; */ ol.reproj.Tile = function(sourceProj, sourceTileGrid, targetProj, targetTileGrid, tileCoord, wrappedTileCoord, - pixelRatio, getTileFunction, + pixelRatio, gutter, getTileFunction, opt_errorThreshold, opt_renderEdges) { goog.base(this, tileCoord, ol.TileState.IDLE); @@ -59,6 +60,12 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid, */ this.pixelRatio_ = pixelRatio; + /** + * @private + * @type {number} + */ + this.gutter_ = gutter; + /** * @private * @type {HTMLCanvasElement} @@ -269,7 +276,7 @@ ol.reproj.Tile.prototype.reproject_ = function() { this.canvas_ = ol.reproj.render(width, height, this.pixelRatio_, sourceResolution, this.sourceTileGrid_.getExtent(), targetResolution, targetExtent, this.triangulation_, sources, - this.renderEdges_); + this.gutter_, this.renderEdges_); this.state = ol.TileState.LOADED; } diff --git a/src/ol/source/tileimagesource.js b/src/ol/source/tileimagesource.js index d860aa5260..13066682b2 100644 --- a/src/ol/source/tileimagesource.js +++ b/src/ol/source/tileimagesource.js @@ -120,6 +120,29 @@ ol.source.TileImage.prototype.expireCache = function(projection, usedTiles) { }; +/** + * @inheritDoc + */ +ol.source.TileImage.prototype.getGutter = function(projection) { + if (ol.ENABLE_RASTER_REPROJECTION && + this.getProjection() && projection && + !ol.proj.equivalent(this.getProjection(), projection)) { + return 0; + } else { + return this.getGutterInternal(); + } +}; + + +/** + * @protected + * @return {number} Gutter. + */ +ol.source.TileImage.prototype.getGutterInternal = function() { + return 0; +}; + + /** * @inheritDoc */ @@ -230,6 +253,7 @@ ol.source.TileImage.prototype.getTile = function(z, x, y, pixelRatio, projection sourceProjection, sourceTileGrid, projection, targetTileGrid, tileCoord, wrappedTileCoord, this.getTilePixelRatio(pixelRatio), + this.getGutterInternal(), function(z, x, y, pixelRatio) { return this.getTileInternal(z, x, y, pixelRatio, sourceProjection); }.bind(this), this.reprojectionErrorThreshold_, diff --git a/src/ol/source/tilesource.js b/src/ol/source/tilesource.js index 144fc7a8ff..88e793352e 100644 --- a/src/ol/source/tilesource.js +++ b/src/ol/source/tilesource.js @@ -147,9 +147,10 @@ ol.source.Tile.prototype.forEachLoadedTile = function(projection, z, tileRange, /** + * @param {ol.proj.Projection} projection Projection. * @return {number} Gutter. */ -ol.source.Tile.prototype.getGutter = function() { +ol.source.Tile.prototype.getGutter = function(projection) { return 0; }; diff --git a/src/ol/source/tilewmssource.js b/src/ol/source/tilewmssource.js index b35a17b2f7..f23c0babfa 100644 --- a/src/ol/source/tilewmssource.js +++ b/src/ol/source/tilewmssource.js @@ -177,7 +177,7 @@ ol.source.TileWMS.prototype.getGetFeatureInfoUrl = function(coordinate, resoluti /** * @inheritDoc */ -ol.source.TileWMS.prototype.getGutter = function() { +ol.source.TileWMS.prototype.getGutterInternal = function() { return this.gutter_; }; diff --git a/test/spec/ol/reproj/tile.test.js b/test/spec/ol/reproj/tile.test.js index ef404c6084..2102b1bb24 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], null, pixelRatio, function(z, x, y, pixelRatio) { + [3, 2, -2], null, pixelRatio, 0, 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], null, 1, function() { + [0, -1, 0], null, 1, 0, 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], null, 1, function() { + [3, 2, -2], null, 1, 0, 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 34506d1f1d..041923d6a3 100644 --- a/test_rendering/spec/ol/reproj/tile.test.js +++ b/test_rendering/spec/ol/reproj/tile.test.js @@ -5,12 +5,13 @@ describe('ol.rendering.reproj.Tile', function() { function testSingleTile(source, targetProjection, targetTileGrid, z, x, y, pixelRatio, expectedUrl, expectedRequests, done) { var sourceProjection = source.getProjection(); + var sourceGutter = source.getGutter(sourceProjection); var tilesRequested = 0; var tile = new ol.reproj.Tile(sourceProjection, source.getTileGrid(), ol.proj.get(targetProjection), targetTileGrid, - [z, x, y], null, pixelRatio, + [z, x, y], null, pixelRatio, sourceGutter, function(z, x, y, pixelRatio) { tilesRequested++; return source.getTile(z, x, y, pixelRatio, sourceProjection);