diff --git a/src/ol/tilegrid/tilegrid.js b/src/ol/tilegrid/tilegrid.js index 738b8cbd90..9c08e6ee9c 100644 --- a/src/ol/tilegrid/tilegrid.js +++ b/src/ol/tilegrid/tilegrid.js @@ -365,8 +365,11 @@ ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndResolution_ = function( var origin = this.getOrigin(z); var tileSize = ol.size.toSize(this.getTileSize(z), this.tmpSize_); - var tileCoordX = scale * (x - origin[0]) / (resolution * tileSize[0]); - var tileCoordY = scale * (y - origin[1]) / (resolution * tileSize[1]); + var adjust = reverseIntersectionPolicy ? 0.5 : 0; + var xFromOrigin = ((x - origin[0]) / resolution + adjust) | 0; + var yFromOrigin = ((y - origin[1]) / resolution + adjust) | 0; + var tileCoordX = scale * xFromOrigin / tileSize[0]; + var tileCoordY = scale * yFromOrigin / tileSize[1]; if (reverseIntersectionPolicy) { tileCoordX = Math.ceil(tileCoordX) - 1; diff --git a/test/spec/ol/tilegrid/tilegrid.test.js b/test/spec/ol/tilegrid/tilegrid.test.js index a8b53c8860..14f8b14d83 100644 --- a/test/spec/ol/tilegrid/tilegrid.test.js +++ b/test/spec/ol/tilegrid/tilegrid.test.js @@ -269,7 +269,150 @@ describe('ol.tilegrid.TileGrid', function() { }); - describe('getTileCoordFromCoordAndZ', function() { + describe('#getTileCoordChildTileRange()', function() { + + var tileGrid; + beforeEach(function() { + tileGrid = ol.tilegrid.createForExtent( + ol.proj.get('EPSG:3857').getExtent(), 22); + }); + + it('returns the tile range for one zoom level deeper', function() { + var range; + + range = tileGrid.getTileCoordChildTileRange([0, 0, 0]); + expect(range.minX).to.be(0); + expect(range.maxX).to.be(1); + expect(range.minY).to.be(0); + expect(range.maxY).to.be(1); + + range = tileGrid.getTileCoordChildTileRange([0, 1, 0]); + expect(range.minX).to.be(2); + expect(range.maxX).to.be(3); + expect(range.minY).to.be(0); + expect(range.maxY).to.be(1); + + range = tileGrid.getTileCoordChildTileRange([0, 0, 1]); + expect(range.minX).to.be(0); + expect(range.maxX).to.be(1); + expect(range.minY).to.be(2); + expect(range.maxY).to.be(3); + + range = tileGrid.getTileCoordChildTileRange([0, -1, 0]); + expect(range.minX).to.be(-2); + expect(range.maxX).to.be(-1); + expect(range.minY).to.be(0); + expect(range.maxY).to.be(1); + + range = tileGrid.getTileCoordChildTileRange([0, 0, -1]); + expect(range.minX).to.be(0); + expect(range.maxX).to.be(1); + expect(range.minY).to.be(-2); + expect(range.maxY).to.be(-1); + }); + + it('returns null for z > maxZoom', function() { + var max = tileGrid.maxZoom; + var range = tileGrid.getTileCoordChildTileRange([max + 1, 0, 0]); + expect(range).to.be(null); + }); + + }); + + describe('#forEachTileCoordParentTileRange()', function() { + + var tileGrid; + beforeEach(function() { + tileGrid = ol.tilegrid.createForExtent( + ol.proj.get('EPSG:3857').getExtent(), 22); + }); + + it('iterates as expected', function() { + + var tileCoord = [5, 11, 21]; + var zs = [], tileRanges = []; + tileGrid.forEachTileCoordParentTileRange( + tileCoord, + function(z, tileRange) { + zs.push(z); + tileRanges.push(new ol.TileRange( + tileRange.minX, tileRange.maxX, + tileRange.minY, tileRange.maxY)); + return false; + }); + + expect(zs.length).to.eql(5); + expect(tileRanges.length).to.eql(5); + + expect(zs[0]).to.eql(4); + expect(tileRanges[0].minX).to.eql(5); + expect(tileRanges[0].maxX).to.eql(5); + expect(tileRanges[0].minY).to.eql(10); + expect(tileRanges[0].maxY).to.eql(10); + + expect(zs[1]).to.eql(3); + expect(tileRanges[1].minX).to.eql(2); + expect(tileRanges[1].maxX).to.eql(2); + expect(tileRanges[1].minY).to.eql(5); + expect(tileRanges[1].maxY).to.eql(5); + + expect(zs[2]).to.eql(2); + expect(tileRanges[2].minX).to.eql(1); + expect(tileRanges[2].maxX).to.eql(1); + expect(tileRanges[2].minY).to.eql(2); + expect(tileRanges[2].maxY).to.eql(2); + + expect(zs[3]).to.eql(1); + expect(tileRanges[3].minX).to.eql(0); + expect(tileRanges[3].maxX).to.eql(0); + expect(tileRanges[3].minY).to.eql(1); + expect(tileRanges[3].maxY).to.eql(1); + + expect(zs[4]).to.eql(0); + expect(tileRanges[4].minX).to.eql(0); + expect(tileRanges[4].maxX).to.eql(0); + expect(tileRanges[4].minY).to.eql(0); + expect(tileRanges[4].maxY).to.eql(0); + + }); + + }); + + describe('getResolution', function() { + + var tileGrid; + beforeEach(function() { + tileGrid = ol.tilegrid.createForExtent( + ol.proj.get('EPSG:3857').getExtent(), 22); + }); + + it('returns the correct resolution at the equator', function() { + // @see http://msdn.microsoft.com/en-us/library/aa940990.aspx + expect(tileGrid.getResolution(0)).to.roughlyEqual(156543.04, 1e-2); + expect(tileGrid.getResolution(1)).to.roughlyEqual(78271.52, 1e-2); + expect(tileGrid.getResolution(2)).to.roughlyEqual(39135.76, 1e-2); + expect(tileGrid.getResolution(3)).to.roughlyEqual(19567.88, 1e-2); + expect(tileGrid.getResolution(4)).to.roughlyEqual(9783.94, 1e-2); + expect(tileGrid.getResolution(5)).to.roughlyEqual(4891.97, 1e-2); + expect(tileGrid.getResolution(6)).to.roughlyEqual(2445.98, 1e-2); + expect(tileGrid.getResolution(7)).to.roughlyEqual(1222.99, 1e-2); + expect(tileGrid.getResolution(8)).to.roughlyEqual(611.50, 1e-2); + expect(tileGrid.getResolution(9)).to.roughlyEqual(305.75, 1e-2); + expect(tileGrid.getResolution(10)).to.roughlyEqual(152.87, 1e-2); + expect(tileGrid.getResolution(11)).to.roughlyEqual(76.44, 1e-2); + expect(tileGrid.getResolution(12)).to.roughlyEqual(38.22, 1e-2); + expect(tileGrid.getResolution(13)).to.roughlyEqual(19.11, 1e-2); + expect(tileGrid.getResolution(14)).to.roughlyEqual(9.55, 1e-2); + expect(tileGrid.getResolution(15)).to.roughlyEqual(4.78, 1e-2); + expect(tileGrid.getResolution(16)).to.roughlyEqual(2.39, 1e-2); + expect(tileGrid.getResolution(17)).to.roughlyEqual(1.19, 1e-2); + expect(tileGrid.getResolution(18)).to.roughlyEqual(0.60, 1e-2); + expect(tileGrid.getResolution(19)).to.roughlyEqual(0.30, 1e-2); + }); + + }); + + describe('#getTileCoordFromCoordAndZ()', function() { describe('Y North, X East', function() { it('returns the expected TileCoord', function() {