From 5e6a4e8cb7202c401883209eab404c3cb0c3afe6 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Sat, 2 Sep 2017 13:20:50 -0600 Subject: [PATCH] Avoid unnecessary calls to tileGrid.getZForResolution() --- src/ol/renderer/canvas/tilelayer.js | 3 +- src/ol/renderer/webgl/tilelayer.js | 3 +- src/ol/tilegrid/tilegrid.js | 89 +++++++++++++++++--------- test/spec/ol/tilegrid/tilegrid.test.js | 41 ------------ 4 files changed, 60 insertions(+), 76 deletions(-) diff --git a/src/ol/renderer/canvas/tilelayer.js b/src/ol/renderer/canvas/tilelayer.js index 27901a3b4d..ab2d0a480b 100644 --- a/src/ol/renderer/canvas/tilelayer.js +++ b/src/ol/renderer/canvas/tilelayer.js @@ -147,8 +147,7 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(frameState, layer return false; } - var tileRange = tileGrid.getTileRangeForExtentAndResolution( - extent, tileResolution); + var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z); var imageExtent = tileGrid.getTileRangeExtent(z, tileRange); var tilePixelRatio = tileSource.getTilePixelRatio(pixelRatio); diff --git a/src/ol/renderer/webgl/tilelayer.js b/src/ol/renderer/webgl/tilelayer.js index e1f3b82eb8..6d1f554a5d 100644 --- a/src/ol/renderer/webgl/tilelayer.js +++ b/src/ol/renderer/webgl/tilelayer.js @@ -186,8 +186,7 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame = function(frameState, layerS var center = viewState.center; var extent = frameState.extent; - var tileRange = tileGrid.getTileRangeForExtentAndResolution( - extent, tileResolution); + var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z); var framebufferExtent; if (this.renderedTileRange_ && diff --git a/src/ol/tilegrid/tilegrid.js b/src/ol/tilegrid/tilegrid.js index 87e941c738..93b49ee7e7 100644 --- a/src/ol/tilegrid/tilegrid.js +++ b/src/ol/tilegrid/tilegrid.js @@ -138,7 +138,7 @@ ol.tilegrid.TileGrid.tmpTileCoord_ = [0, 0, 0]; * Call a function with each tile coordinate for a given extent and zoom level. * * @param {ol.Extent} extent Extent. - * @param {number} zoom Zoom level. + * @param {number} zoom Integer zoom level. * @param {function(ol.TileCoord)} callback Function called with each tile coordinate. * @api */ @@ -206,7 +206,7 @@ ol.tilegrid.TileGrid.prototype.getMinZoom = function() { /** * Get the origin for the grid at the given zoom level. - * @param {number} z Z. + * @param {number} z Integer zoom level. * @return {ol.Coordinate} Origin. * @api */ @@ -221,7 +221,7 @@ ol.tilegrid.TileGrid.prototype.getOrigin = function(z) { /** * Get the resolution for the given zoom level. - * @param {number} z Z. + * @param {number} z Integer zoom level. * @return {number} Resolution. * @api */ @@ -258,7 +258,8 @@ ol.tilegrid.TileGrid.prototype.getTileCoordChildTileRange = function(tileCoord, /** - * @param {number} z Z. + * Get the extent for a tile range. + * @param {number} z Integer zoom level. * @param {ol.TileRange} tileRange Tile range. * @param {ol.Extent=} opt_extent Temporary ol.Extent object. * @return {ol.Extent} Extent. @@ -276,34 +277,20 @@ ol.tilegrid.TileGrid.prototype.getTileRangeExtent = function(z, tileRange, opt_e /** + * Get a tile range for the given extent and integer zoom level. * @param {ol.Extent} extent Extent. - * @param {number} resolution Resolution. - * @param {ol.TileRange=} opt_tileRange Temporary tile range object. - * @return {ol.TileRange} Tile range. - */ -ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndResolution = function(extent, resolution, opt_tileRange) { - var tileCoord = ol.tilegrid.TileGrid.tmpTileCoord_; - this.getTileCoordForXYAndResolution_( - extent[0], extent[1], resolution, false, tileCoord); - var minX = tileCoord[1]; - var minY = tileCoord[2]; - this.getTileCoordForXYAndResolution_( - extent[2], extent[3], resolution, true, tileCoord); - return ol.TileRange.createOrUpdate( - minX, tileCoord[1], minY, tileCoord[2], opt_tileRange); -}; - - -/** - * @param {ol.Extent} extent Extent. - * @param {number} z Z. + * @param {number} z Integer zoom level. * @param {ol.TileRange=} opt_tileRange Temporary tile range object. * @return {ol.TileRange} Tile range. */ ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndZ = function(extent, z, opt_tileRange) { - var resolution = this.getResolution(z); - return this.getTileRangeForExtentAndResolution( - extent, resolution, opt_tileRange); + var tileCoord = ol.tilegrid.TileGrid.tmpTileCoord_; + this.getTileCoordForXYAndZ_(extent[0], extent[1], z, false, tileCoord); + var minX = tileCoord[1]; + var minY = tileCoord[2]; + this.getTileCoordForXYAndZ_(extent[2], extent[3], z, true, tileCoord); + return ol.TileRange.createOrUpdate( + minX, tileCoord[1], minY, tileCoord[2], opt_tileRange); }; @@ -360,9 +347,11 @@ ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndResolution = function(coor /** + * Note that this method should not be called for resolutions that correspond + * to an integer zoom level. Instead call the `getTileCoordForXYAndZ_` method. * @param {number} x X. * @param {number} y Y. - * @param {number} resolution Resolution. + * @param {number} resolution Resolution (for a non-integer zoom level). * @param {boolean} reverseIntersectionPolicy Instead of letting edge * intersections go to the higher tile coordinate, let edge intersections * go to the lower tile coordinate. @@ -396,6 +385,45 @@ ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndResolution_ = function( }; +/** + * Although there is repetition between this method and `getTileCoordForXYAndResolution_`, + * they should have separate implementations. This method is for integer zoom + * levels. The other method should only be called for resolutions corresponding + * to non-integer zoom levels. + * @param {number} x Map x coordinate. + * @param {number} y Map y coordinate. + * @param {number} z Integer zoom level. + * @param {boolean} reverseIntersectionPolicy Instead of letting edge + * intersections go to the higher tile coordinate, let edge intersections + * go to the lower tile coordinate. + * @param {ol.TileCoord=} opt_tileCoord Temporary ol.TileCoord object. + * @return {ol.TileCoord} Tile coordinate. + * @private + */ +ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndZ_ = function(x, y, z, reverseIntersectionPolicy, opt_tileCoord) { + var origin = this.getOrigin(z); + var resolution = this.getResolution(z); + var tileSize = ol.size.toSize(this.getTileSize(z), this.tmpSize_); + + var adjustX = reverseIntersectionPolicy ? 0.5 : 0; + var adjustY = reverseIntersectionPolicy ? 0 : 0.5; + var xFromOrigin = Math.floor((x - origin[0]) / resolution + adjustX); + var yFromOrigin = Math.floor((y - origin[1]) / resolution + adjustY); + var tileCoordX = xFromOrigin / tileSize[0]; + var tileCoordY = yFromOrigin / tileSize[1]; + + if (reverseIntersectionPolicy) { + tileCoordX = Math.ceil(tileCoordX) - 1; + tileCoordY = Math.ceil(tileCoordY) - 1; + } else { + tileCoordX = Math.floor(tileCoordX); + tileCoordY = Math.floor(tileCoordY); + } + + return ol.tilecoord.createOrUpdate(z, tileCoordX, tileCoordY, opt_tileCoord); +}; + + /** * Get a tile coordinate given a map coordinate and zoom level. * @param {ol.Coordinate} coordinate Coordinate. @@ -405,9 +433,8 @@ ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndResolution_ = function( * @api */ ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndZ = function(coordinate, z, opt_tileCoord) { - var resolution = this.getResolution(z); - return this.getTileCoordForXYAndResolution_( - coordinate[0], coordinate[1], resolution, false, opt_tileCoord); + return this.getTileCoordForXYAndZ_( + coordinate[0], coordinate[1], z, false, opt_tileCoord); }; diff --git a/test/spec/ol/tilegrid/tilegrid.test.js b/test/spec/ol/tilegrid/tilegrid.test.js index 8b760ad74f..650653a0ea 100644 --- a/test/spec/ol/tilegrid/tilegrid.test.js +++ b/test/spec/ol/tilegrid/tilegrid.test.js @@ -11,14 +11,12 @@ goog.require('ol.tilegrid.TileGrid'); describe('ol.tilegrid.TileGrid', function() { - var extent; var resolutions; var origin; var tileSize; beforeEach(function() { resolutions = [1000, 500, 250, 100]; - extent = [0, 0, 100000, 100000]; origin = [0, 0]; tileSize = 100; }); @@ -815,45 +813,6 @@ describe('ol.tilegrid.TileGrid', function() { }); }); - describe('getTileRangeForExtentAndResolution', function() { - it('returns the expected TileRange', function() { - var tileGrid = new ol.tilegrid.TileGrid({ - resolutions: resolutions, - origin: origin, - tileSize: tileSize - }); - var tileRange; - - tileRange = tileGrid.getTileRangeForExtentAndResolution(extent, - resolutions[0]); - expect(tileRange.minY).to.eql(0); - expect(tileRange.minX).to.eql(0); - expect(tileRange.maxX).to.eql(0); - expect(tileRange.maxY).to.eql(0); - - tileRange = tileGrid.getTileRangeForExtentAndResolution(extent, - resolutions[1]); - expect(tileRange.minX).to.eql(0); - expect(tileRange.minY).to.eql(0); - expect(tileRange.maxX).to.eql(1); - expect(tileRange.maxY).to.eql(1); - - tileRange = tileGrid.getTileRangeForExtentAndResolution(extent, - resolutions[2]); - expect(tileRange.minX).to.eql(0); - expect(tileRange.minY).to.eql(0); - expect(tileRange.maxX).to.eql(3); - expect(tileRange.maxY).to.eql(3); - - tileRange = tileGrid.getTileRangeForExtentAndResolution(extent, - resolutions[3]); - expect(tileRange.minX).to.eql(0); - expect(tileRange.minY).to.eql(0); - expect(tileRange.maxX).to.eql(9); - expect(tileRange.maxY).to.eql(9); - }); - }); - describe('getTileRangeForExtentAndZ', function() { it('returns the expected TileRange', function() { var tileGrid = new ol.tilegrid.TileGrid({