diff --git a/src/ol/source/tilejsonsource.js b/src/ol/source/tilejsonsource.js index 01982fd896..2730c7be2b 100644 --- a/src/ol/source/tilejsonsource.js +++ b/src/ol/source/tilejsonsource.js @@ -75,7 +75,8 @@ ol.source.TileJSON.prototype.handleTileJSONResponse = function(tileJSON) { }); this.tileGrid = tileGrid; - this.tileUrlFunction = ol.TileUrlFunction.createFromTemplates(tileJSON.tiles); + this.tileUrlFunction = + ol.TileUrlFunction.createFromTemplates(tileJSON.tiles, tileGrid); if (tileJSON.attribution !== undefined && goog.isNull(this.getAttributions())) { diff --git a/src/ol/source/tileutfgridsource.js b/src/ol/source/tileutfgridsource.js index 2d0715b6e7..a25e568cc7 100644 --- a/src/ol/source/tileutfgridsource.js +++ b/src/ol/source/tileutfgridsource.js @@ -136,7 +136,8 @@ ol.source.TileUTFGrid.prototype.handleTileJSONResponse = function(tileJSON) { return; } - this.tileUrlFunction_ = ol.TileUrlFunction.createFromTemplates(grids); + this.tileUrlFunction_ = + ol.TileUrlFunction.createFromTemplates(grids, tileGrid); if (tileJSON.attribution !== undefined) { var attributionExtent = extent !== undefined ? diff --git a/src/ol/source/tilevectorsource.js b/src/ol/source/tilevectorsource.js index 0f2864e10f..d13778c07c 100644 --- a/src/ol/source/tilevectorsource.js +++ b/src/ol/source/tilevectorsource.js @@ -341,7 +341,7 @@ ol.source.TileVector.prototype.setTileUrlFunction = function(tileUrlFunction) { */ ol.source.TileVector.prototype.setUrl = function(url) { this.setTileUrlFunction(ol.TileUrlFunction.createFromTemplates( - ol.TileUrlFunction.expandUrl(url))); + ol.TileUrlFunction.expandUrl(url), this.tileGrid_)); }; @@ -349,5 +349,6 @@ ol.source.TileVector.prototype.setUrl = function(url) { * @param {Array.} urls URLs. */ ol.source.TileVector.prototype.setUrls = function(urls) { - this.setTileUrlFunction(ol.TileUrlFunction.createFromTemplates(urls)); + this.setTileUrlFunction( + ol.TileUrlFunction.createFromTemplates(urls, this.tileGrid_)); }; diff --git a/src/ol/source/xyzsource.js b/src/ol/source/xyzsource.js index 7b8bdbb0c6..1863cdb574 100644 --- a/src/ol/source/xyzsource.js +++ b/src/ol/source/xyzsource.js @@ -87,7 +87,7 @@ ol.source.XYZ.prototype.getUrls = function() { */ ol.source.XYZ.prototype.setUrl = function(url) { this.setTileUrlFunction(ol.TileUrlFunction.createFromTemplates( - ol.TileUrlFunction.expandUrl(url))); + ol.TileUrlFunction.expandUrl(url), this.tileGrid)); this.urls_ = [url]; }; @@ -97,6 +97,7 @@ ol.source.XYZ.prototype.setUrl = function(url) { * @param {Array.} urls URLs. */ ol.source.XYZ.prototype.setUrls = function(urls) { - this.setTileUrlFunction(ol.TileUrlFunction.createFromTemplates(urls)); + this.setTileUrlFunction( + ol.TileUrlFunction.createFromTemplates(urls, this.tileGrid)); this.urls_ = urls; }; diff --git a/src/ol/tileurlfunction.js b/src/ol/tileurlfunction.js index 0c1c98a196..f208ba592e 100644 --- a/src/ol/tileurlfunction.js +++ b/src/ol/tileurlfunction.js @@ -33,9 +33,10 @@ ol.TileCoordTransformType; /** * @param {string} template Template. + * @param {ol.tilegrid.TileGrid} tileGrid Tile grid. * @return {ol.TileUrlFunctionType} Tile URL function. */ -ol.TileUrlFunction.createFromTemplate = function(template) { +ol.TileUrlFunction.createFromTemplate = function(template, tileGrid) { var zRegEx = /\{z\}/g; var xRegEx = /\{x\}/g; var yRegEx = /\{y\}/g; @@ -52,15 +53,19 @@ ol.TileUrlFunction.createFromTemplate = function(template) { return undefined; } else { return template.replace(zRegEx, tileCoord[0].toString()) - .replace(xRegEx, tileCoord[1].toString()) - .replace(yRegEx, function() { - var y = -tileCoord[2] - 1; - return y.toString(); - }) - .replace(dashYRegEx, function() { - var y = (1 << tileCoord[0]) + tileCoord[2]; - return y.toString(); - }); + .replace(xRegEx, tileCoord[1].toString()) + .replace(yRegEx, function() { + var y = -tileCoord[2] - 1; + return y.toString(); + }) + .replace(dashYRegEx, function() { + var z = tileCoord[0]; + var range = tileGrid.getFullTileRange(z); + goog.asserts.assert(range, + 'The {-y} template requires a tile grid with extent'); + var y = range.getHeight() + tileCoord[2]; + return y.toString(); + }); } }); }; @@ -68,11 +73,17 @@ ol.TileUrlFunction.createFromTemplate = function(template) { /** * @param {Array.} templates Templates. + * @param {ol.tilegrid.TileGrid} tileGrid Tile grid. * @return {ol.TileUrlFunctionType} Tile URL function. */ -ol.TileUrlFunction.createFromTemplates = function(templates) { - return ol.TileUrlFunction.createFromTileUrlFunctions( - templates.map(ol.TileUrlFunction.createFromTemplate)); +ol.TileUrlFunction.createFromTemplates = function(templates, tileGrid) { + var len = templates.length; + var tileUrlFunctions = new Array(len); + for (var i = 0; i < len; ++i) { + tileUrlFunctions[i] = ol.TileUrlFunction.createFromTemplate( + templates[i], tileGrid); + } + return ol.TileUrlFunction.createFromTileUrlFunctions(tileUrlFunctions); }; diff --git a/test/spec/ol/tileurlfunction.test.js b/test/spec/ol/tileurlfunction.test.js index 37b3516fee..2c1bad89f9 100644 --- a/test/spec/ol/tileurlfunction.test.js +++ b/test/spec/ol/tileurlfunction.test.js @@ -28,29 +28,45 @@ describe('ol.TileUrlFunction', function() { }); describe('createFromTemplate', function() { + var tileGrid = ol.tilegrid.createXYZ(); it('creates expected URL', function() { - var tileUrl = ol.TileUrlFunction.createFromTemplate('{z}/{x}/{y}'); + var tileUrl = ol.TileUrlFunction.createFromTemplate( + '{z}/{x}/{y}', tileGrid); expect(tileUrl([3, 2, -2])).to.eql('3/2/1'); expect(tileUrl(null)).to.be(undefined); }); it('accepts {-y} placeholder', function() { - var tileUrl = ol.TileUrlFunction.createFromTemplate('{z}/{x}/{-y}'); + var tileUrl = ol.TileUrlFunction.createFromTemplate( + '{z}/{x}/{-y}', tileGrid); expect(tileUrl([3, 2, -3])).to.eql('3/2/5'); }); + it('returns correct value for {-y} with custom tile grids', function() { + var customTileGrid = new ol.tilegrid.TileGrid({ + extent: [-180, -90, 180, 90], + origin: [-180, -90], + resolutions: [360 / 256, 360 / 512, 360 / 1024, 360 / 2048] + }); + var tileUrl = ol.TileUrlFunction.createFromTemplate( + '{z}/{x}/{-y}', customTileGrid); + expect(tileUrl([3, 2, -3])).to.eql('3/2/1'); + }); it('replaces multiple placeholder occurrences', function() { - var tileUrl = ol.TileUrlFunction.createFromTemplate('{z}/{z}{x}{y}'); + var tileUrl = ol.TileUrlFunction.createFromTemplate( + '{z}/{z}{x}{y}', tileGrid); expect(tileUrl([3, 2, -2])).to.eql('3/321'); }); }); describe('createFromTemplates', function() { + var tileGrid = ol.tilegrid.createXYZ(); it('creates expected URL', function() { var templates = [ 'http://tile-1/{z}/{x}/{y}', 'http://tile-2/{z}/{x}/{y}', 'http://tile-3/{z}/{x}/{y}' ]; - var tileUrlFunction = ol.TileUrlFunction.createFromTemplates(templates); + var tileUrlFunction = ol.TileUrlFunction.createFromTemplates( + templates, tileGrid); var tileCoord = [3, 2, -2]; sinon.stub(ol.tilecoord, 'hash', function() { return 3; }); @@ -68,10 +84,11 @@ describe('ol.TileUrlFunction', function() { }); describe('createFromTileUrlFunctions', function() { + var tileGrid = ol.tilegrid.createXYZ(); it('creates expected URL', function() { var tileUrl = ol.TileUrlFunction.createFromTileUrlFunctions([ - ol.TileUrlFunction.createFromTemplate('a'), - ol.TileUrlFunction.createFromTemplate('b') + ol.TileUrlFunction.createFromTemplate('a', tileGrid), + ol.TileUrlFunction.createFromTemplate('b', tileGrid) ]); var tileUrl1 = tileUrl([1, 0, 0]); var tileUrl2 = tileUrl([1, 0, 1]); @@ -84,3 +101,4 @@ describe('ol.TileUrlFunction', function() { goog.require('ol.TileCoord'); goog.require('ol.TileUrlFunction'); +goog.require('ol.tilegrid.TileGrid');