diff --git a/externs/olx.js b/externs/olx.js index 9700718064..56d942a5d7 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -6036,7 +6036,8 @@ olx.tilegrid; /** - * @typedef {{extent: (ol.Extent|undefined), + * @typedef {{createTileCoordTransform: (undefined|function({extent: (ol.Extent|undefined)}):function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=):ol.TileCoord), + * extent: (ol.Extent|undefined), * minZoom: (number|undefined), * origin: (ol.Coordinate|undefined), * origins: (Array.|undefined), diff --git a/src/ol/source/bingmapssource.js b/src/ol/source/bingmapssource.js index e756fb8b11..30ad8200a3 100644 --- a/src/ol/source/bingmapssource.js +++ b/src/ol/source/bingmapssource.js @@ -115,7 +115,7 @@ ol.source.BingMaps.prototype.handleImageryMetadataResponse = var culture = this.culture_; this.tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform( - ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid), + tileGrid.createTileCoordTransform(), ol.TileUrlFunction.createFromTileUrlFunctions( goog.array.map( resource.imageUrlSubdomains, diff --git a/src/ol/source/tilejsonsource.js b/src/ol/source/tilejsonsource.js index 3bd3bc6478..2eb39b9463 100644 --- a/src/ol/source/tilejsonsource.js +++ b/src/ol/source/tilejsonsource.js @@ -76,7 +76,7 @@ ol.source.TileJSON.prototype.handleTileJSONResponse = function(tileJSON) { this.tileGrid = tileGrid; this.tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform( - ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid), + tileGrid.createTileCoordTransform(), ol.TileUrlFunction.createFromTemplates(tileJSON.tiles)); if (goog.isDef(tileJSON.attribution) && diff --git a/src/ol/source/tileutfgridsource.js b/src/ol/source/tileutfgridsource.js index 96c4e1c5d3..73baf3fecf 100644 --- a/src/ol/source/tileutfgridsource.js +++ b/src/ol/source/tileutfgridsource.js @@ -137,7 +137,7 @@ ol.source.TileUTFGrid.prototype.handleTileJSONResponse = function(tileJSON) { } this.tileUrlFunction_ = ol.TileUrlFunction.withTileCoordTransform( - ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid), + tileGrid.createTileCoordTransform(), ol.TileUrlFunction.createFromTemplates(grids)); if (goog.isDef(tileJSON.attribution)) { diff --git a/src/ol/source/xyzsource.js b/src/ol/source/xyzsource.js index 2c60a6178e..feb8ff29df 100644 --- a/src/ol/source/xyzsource.js +++ b/src/ol/source/xyzsource.js @@ -41,8 +41,7 @@ ol.source.XYZ = function(options) { * @private * @type {ol.TileCoordTransformType} */ - this.tileCoordTransform_ = - ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid); + this.tileCoordTransform_ = tileGrid.createTileCoordTransform(); if (goog.isDef(options.tileUrlFunction)) { this.setTileUrlFunction(options.tileUrlFunction); diff --git a/src/ol/tilegrid/tilegrid.js b/src/ol/tilegrid/tilegrid.js index 46c31d5d7c..fe07506242 100644 --- a/src/ol/tilegrid/tilegrid.js +++ b/src/ol/tilegrid/tilegrid.js @@ -2,6 +2,7 @@ goog.provide('ol.tilegrid.TileGrid'); goog.require('goog.array'); goog.require('goog.asserts'); +goog.require('goog.functions'); goog.require('goog.math'); goog.require('goog.object'); goog.require('ol'); @@ -69,10 +70,14 @@ ol.tilegrid.TileGrid = function(options) { goog.asserts.assert(this.origins_.length == this.resolutions_.length, 'number of origins and resolutions must be equal'); } - if (goog.isNull(this.origins_) && goog.isNull(this.origin_) && - goog.isDef(options.extent)) { - this.origin_ = ol.extent.getBottomLeft(options.extent); + + var extent = options.extent; + + if (goog.isDef(extent) && + goog.isNull(this.origin_) && goog.isNull(this.origins_)) { + this.origin_ = ol.extent.getBottomLeft(extent); } + goog.asserts.assert( (goog.isNull(this.origin_) && !goog.isNull(this.origins_)) || (!goog.isNull(this.origin_) && goog.isNull(this.origins_)), @@ -101,14 +106,24 @@ ol.tilegrid.TileGrid = function(options) { (!goog.isNull(this.tileSize_) && goog.isNull(this.tileSizes_)), 'either tileSize or tileSizes must be configured, never both'); - var extent = options.extent; - /** * @private * @type {ol.Extent} */ this.extent_ = goog.isDef(extent) ? extent : null; + + /** + * TileCoord transform function for use with this tile grid. Returns unaltered + * tile coordinates by default. + * @param {{extent: (ol.Extent|undefined)}=} opt_options Options. + * @return {function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=): + * ol.TileCoord} Tile coordinate transform. + */ + this.createTileCoordTransform = goog.isDef(options.createTileCoordTransform) ? + options.createTileCoordTransform : + goog.functions.identity; + /** * @private * @type {Array.} @@ -134,17 +149,9 @@ ol.tilegrid.TileGrid = function(options) { return tileRange; }, this); } else if (goog.isDef(extent)) { - var extentWidth = ol.extent.getWidth(extent); - var extentHeight = ol.extent.getHeight(extent); - var fullTileRanges = new Array(this.resolutions_.length); - var tileSize; - for (var z = 0, zz = fullTileRanges.length; z < zz; ++z) { - tileSize = ol.size.toSize(this.getTileSize(z), this.tmpSize_); - fullTileRanges[z] = new ol.TileRange( - 0, Math.ceil(extentWidth / tileSize[0] / this.resolutions_[z]) - 1, - 0, Math.ceil(extentHeight / tileSize[1] / this.resolutions_[z]) - 1); + if (!goog.isNull(extent)) { + this.calculateTileRanges_(extent); } - this.fullTileRanges_ = fullTileRanges; } /** @@ -163,16 +170,6 @@ ol.tilegrid.TileGrid = function(options) { ol.tilegrid.TileGrid.tmpTileCoord_ = [0, 0, 0]; -/** - * Source specific TileCoord transform function. May be implemented by - * subclasses. - * @param {{extent: (ol.Extent|undefined)}=} opt_options Options. - * @return {function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=): - * ol.TileCoord} Tile coordinate transform. - */ -ol.tilegrid.TileGrid.prototype.createTileCoordTransform = goog.abstractMethod; - - /** * @param {ol.TileCoord} tileCoord Tile coordinate. * @param {function(this: T, number, ol.TileRange): boolean} callback Callback. @@ -505,6 +502,25 @@ ol.tilegrid.TileGrid.prototype.getZForResolution = function(resolution) { }; +/** + * @param {!ol.Extent} extent Extent for this tile grid. + * @private + */ +ol.tilegrid.TileGrid.prototype.calculateTileRanges_ = function(extent) { + var extentWidth = ol.extent.getWidth(extent); + var extentHeight = ol.extent.getHeight(extent); + var fullTileRanges = new Array(this.resolutions_.length); + var tileSize; + for (var z = 0, zz = fullTileRanges.length; z < zz; ++z) { + tileSize = ol.size.toSize(this.getTileSize(z), this.tmpSize_); + fullTileRanges[z] = new ol.TileRange( + 0, Math.ceil(extentWidth / tileSize[0] / this.resolutions_[z]) - 1, + 0, Math.ceil(extentHeight / tileSize[1] / this.resolutions_[z]) - 1); + } + this.fullTileRanges_ = fullTileRanges; +}; + + /** * @param {ol.proj.Projection} projection Projection. * @return {ol.tilegrid.TileGrid} Default tile grid for the passed projection. @@ -562,6 +578,17 @@ ol.tilegrid.createXYZ = function(opt_options) { options.resolutions = ol.tilegrid.resolutionsFromExtent( options.extent, options.maxZoom, options.tileSize); delete options.maxZoom; + + /** + * @param {{extent: (ol.Extent|undefined)}=} opt_options Options. + * @return {function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=): + * ol.TileCoord} Tile coordinate transform. + * @this {ol.tilegrid.TileGrid} + */ + options.createTileCoordTransform = function(opt_options) { + return ol.tilegrid.createOriginTopLeftTileCoordTransform(this); + }; + return new ol.tilegrid.TileGrid(options); }; diff --git a/src/ol/tilegrid/zoomifytilegrid.js b/src/ol/tilegrid/zoomifytilegrid.js index 379e23c03e..03f566250a 100644 --- a/src/ol/tilegrid/zoomifytilegrid.js +++ b/src/ol/tilegrid/zoomifytilegrid.js @@ -19,61 +19,65 @@ goog.require('ol.tilegrid.TileGrid'); */ ol.tilegrid.Zoomify = function(opt_options) { var options = goog.isDef(opt_options) ? opt_options : options; + + /** + * @param {{extent: (ol.Extent|undefined)}=} opt_options Options. + * @return {function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=): + * ol.TileCoord} Tile coordinate transform. + * @this {ol.tilegrid.Zoomify} + */ + var createTileCoordTransform = function(opt_options) { + var options = goog.isDef(opt_options) ? opt_options : {}; + var minZ = this.minZoom; + var maxZ = this.maxZoom; + /** @type {Array.} */ + var tileRangeByZ = null; + if (goog.isDef(options.extent)) { + tileRangeByZ = new Array(maxZ + 1); + var z; + for (z = 0; z <= maxZ; ++z) { + if (z < minZ) { + tileRangeByZ[z] = null; + } else { + tileRangeByZ[z] = this.getTileRangeForExtentAndZ(options.extent, z); + } + } + } + return ( + /** + * @param {ol.TileCoord} tileCoord Tile coordinate. + * @param {ol.proj.Projection} projection Projection. + * @param {ol.TileCoord=} opt_tileCoord Destination tile coordinate. + * @return {ol.TileCoord} Tile coordinate. + */ + function(tileCoord, projection, opt_tileCoord) { + var z = tileCoord[0]; + if (z < minZ || maxZ < z) { + return null; + } + var n = Math.pow(2, z); + var x = tileCoord[1]; + if (x < 0 || n <= x) { + return null; + } + var y = tileCoord[2]; + if (y < -n || -1 < y) { + return null; + } + if (!goog.isNull(tileRangeByZ)) { + if (!tileRangeByZ[z].containsXY(x, -y - 1)) { + return null; + } + } + return ol.tilecoord.createOrUpdate(z, x, -y - 1, opt_tileCoord); + }); + }; + goog.base(this, { + createTileCoordTransform: createTileCoordTransform, origin: [0, 0], resolutions: options.resolutions }); }; goog.inherits(ol.tilegrid.Zoomify, ol.tilegrid.TileGrid); - - -/** - * @inheritDoc - */ -ol.tilegrid.Zoomify.prototype.createTileCoordTransform = function(opt_options) { - var options = goog.isDef(opt_options) ? opt_options : {}; - var minZ = this.minZoom; - var maxZ = this.maxZoom; - /** @type {Array.} */ - var tileRangeByZ = null; - if (goog.isDef(options.extent)) { - tileRangeByZ = new Array(maxZ + 1); - var z; - for (z = 0; z <= maxZ; ++z) { - if (z < minZ) { - tileRangeByZ[z] = null; - } else { - tileRangeByZ[z] = this.getTileRangeForExtentAndZ(options.extent, z); - } - } - } - return ( - /** - * @param {ol.TileCoord} tileCoord Tile coordinate. - * @param {ol.proj.Projection} projection Projection. - * @param {ol.TileCoord=} opt_tileCoord Destination tile coordinate. - * @return {ol.TileCoord} Tile coordinate. - */ - function(tileCoord, projection, opt_tileCoord) { - var z = tileCoord[0]; - if (z < minZ || maxZ < z) { - return null; - } - var n = Math.pow(2, z); - var x = tileCoord[1]; - if (x < 0 || n <= x) { - return null; - } - var y = tileCoord[2]; - if (y < -n || -1 < y) { - return null; - } - if (!goog.isNull(tileRangeByZ)) { - if (!tileRangeByZ[z].containsXY(x, -y - 1)) { - return null; - } - } - return ol.tilecoord.createOrUpdate(z, x, -y - 1, opt_tileCoord); - }); -};