diff --git a/externs/olx.js b/externs/olx.js
index 33c38bf9cc..42cc2d2a67 100644
--- a/externs/olx.js
+++ b/externs/olx.js
@@ -6479,7 +6479,8 @@ olx.tilegrid;
* origins: (Array.
|undefined),
* resolutions: !Array.,
* tileSize: (number|undefined),
- * tileSizes: (Array.|undefined)}}
+ * tileSizes: (Array.|undefined),
+ * widths: (Array.|undefined)}}
* @api
*/
olx.tilegrid.TileGridOptions;
@@ -6535,13 +6536,23 @@ olx.tilegrid.TileGridOptions.prototype.tileSize;
olx.tilegrid.TileGridOptions.prototype.tileSizes;
+/**
+ * Widths in tiles. If given, the array length should match the length of the
+ * `resolutions` array, i.e. each resolution will have a number of tile columns.
+ * @type {Array.|undefined}
+ * @api
+ */
+olx.tilegrid.TileGridOptions.prototype.widths;
+
+
/**
* @typedef {{origin: (ol.Coordinate|undefined),
* origins: (Array.|undefined),
* resolutions: !Array.,
* matrixIds: !Array.,
* tileSize: (number|undefined),
- * tileSizes: (Array.|undefined)}}
+ * tileSizes: (Array.|undefined),
+ * widths: (Array.|undefined)}}
* @api
*/
olx.tilegrid.WMTSOptions;
@@ -6595,6 +6606,15 @@ olx.tilegrid.WMTSOptions.prototype.tileSize;
olx.tilegrid.WMTSOptions.prototype.tileSizes;
+/**
+ * Widths in tiles. If given, the array length should match the length of the
+ * `resolutions` array, i.e. each resolution will have a number of tile columns.
+ * @type {Array.|undefined}
+ * @api
+ */
+olx.tilegrid.WMTSOptions.prototype.widths;
+
+
/**
* @typedef {{extent: (ol.Extent|undefined),
* maxZoom: (number|undefined),
diff --git a/src/ol/attribution.js b/src/ol/attribution.js
index d234c36515..aeeb7bdf12 100644
--- a/src/ol/attribution.js
+++ b/src/ol/attribution.js
@@ -77,8 +77,8 @@ ol.Attribution.prototype.intersectsAnyTileRange =
if (testTileRange.intersects(tileRange)) {
return true;
}
- var extentTileRange = tileGrid.getTileRangeForExtentAndZ(
- ol.tilegrid.extentFromProjection(projection), parseInt(zKey, 10));
+ var extentTileRange = tileGrid.getTileRange(
+ parseInt(zKey, 10), projection);
var width = extentTileRange.getWidth();
if (tileRange.minX < extentTileRange.minX ||
tileRange.maxX > extentTileRange.maxX) {
diff --git a/src/ol/source/tilesource.js b/src/ol/source/tilesource.js
index 78c81d8071..bdb602a7d3 100644
--- a/src/ol/source/tilesource.js
+++ b/src/ol/source/tilesource.js
@@ -224,12 +224,11 @@ ol.source.Tile.prototype.getWrapXTileCoord =
function(tileCoord, opt_projection) {
var projection = goog.isDef(opt_projection) ?
opt_projection : this.getProjection();
- if (goog.isDef(this.wrapX_) && projection.isGlobal()) {
- var tileGrid = this.getTileGridForProjection(projection);
- var extent = ol.tilegrid.extentFromProjection(projection);
+ var tileGrid = this.getTileGridForProjection(projection);
+ if (goog.isDef(this.wrapX_) && tileGrid.isGlobal(tileCoord[0], projection)) {
return this.wrapX_ ?
- ol.tilecoord.wrapX(tileCoord, tileGrid, extent) :
- ol.tilecoord.clipX(tileCoord, tileGrid, extent);
+ ol.tilecoord.wrapX(tileCoord, tileGrid, projection) :
+ ol.tilecoord.clipX(tileCoord, tileGrid, projection);
} else {
return tileCoord;
}
diff --git a/src/ol/tilecoord.js b/src/ol/tilecoord.js
index 1ddc43b005..03e451ab94 100644
--- a/src/ol/tilecoord.js
+++ b/src/ol/tilecoord.js
@@ -143,15 +143,15 @@ ol.tilecoord.toString = function(tileCoord) {
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @param {ol.tilegrid.TileGrid} tilegrid Tile grid.
- * @param {ol.Extent} extent Extent.
+ * @param {ol.proj.Projection} projection Projection.
* @return {ol.TileCoord} Tile coordinate.
*/
ol.tilecoord.wrapX = (function() {
var tmpTileCoord = [0, 0, 0];
- return function(tileCoord, tileGrid, extent) {
+ return function(tileCoord, tileGrid, projection) {
var z = tileCoord[0];
var x = tileCoord[1];
- var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
+ var tileRange = tileGrid.getTileRange(z, projection);
if (x < tileRange.minX || x > tileRange.maxX) {
x = goog.math.modulo(x, tileRange.getWidth());
return ol.tilecoord.createOrUpdate(z, x, tileCoord[2], tmpTileCoord);
@@ -164,11 +164,12 @@ ol.tilecoord.wrapX = (function() {
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
- * @param {ol.Extent} extent Extent.
+ * @param {ol.proj.Projection} projection Projection.
* @return {ol.TileCoord} Tile coordinate.
*/
-ol.tilecoord.clipX = function(tileCoord, tileGrid, extent) {
+ol.tilecoord.clipX = function(tileCoord, tileGrid, projection) {
+ var z = tileCoord[0];
var x = tileCoord[1];
- var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, tileCoord[0]);
+ var tileRange = tileGrid.getTileRange(z, projection);
return (x < tileRange.minX || x > tileRange.maxX) ? null : tileCoord;
};
diff --git a/src/ol/tilegrid/tilegrid.js b/src/ol/tilegrid/tilegrid.js
index 1e0039770c..8169dc1c06 100644
--- a/src/ol/tilegrid/tilegrid.js
+++ b/src/ol/tilegrid/tilegrid.js
@@ -92,6 +92,16 @@ ol.tilegrid.TileGrid = function(options) {
(!goog.isDef(this.tileSize_) && !goog.isNull(this.tileSizes_)) ||
(goog.isDef(this.tileSize_) && goog.isNull(this.tileSizes_)));
+ /**
+ * @private
+ * @type {Array.}
+ */
+ this.widths_ = null;
+ if (goog.isDef(options.widths)) {
+ this.widths_ = options.widths;
+ goog.asserts.assert(this.widths_.length == this.resolutions_.length);
+ }
+
};
@@ -373,6 +383,25 @@ ol.tilegrid.TileGrid.prototype.getTileCoordResolution = function(tileCoord) {
};
+/**
+ * @param {number} z Zoom level.
+ * @param {ol.proj.Projection} projection Projection.
+ * @param {ol.TileRange=} opt_tileRange Tile range.
+ * @return {ol.TileRange} Tile range.
+ */
+ol.tilegrid.TileGrid.prototype.getTileRange =
+ function(z, projection, opt_tileRange) {
+ var projectionExtentTileRange = this.getTileRangeForExtentAndZ(
+ ol.tilegrid.extentFromProjection(projection), z);
+ var width = this.getWidth(z);
+ if (!goog.isDef(width)) {
+ width = projectionExtentTileRange.getWidth();
+ }
+ return ol.TileRange.createOrUpdate(
+ 0, width - 1, 0, projectionExtentTileRange.getHeight(), opt_tileRange);
+};
+
+
/**
* @param {number} z Z.
* @return {number} Tile size.
@@ -389,6 +418,19 @@ ol.tilegrid.TileGrid.prototype.getTileSize = function(z) {
};
+/**
+ * @param {number} z Zoom level.
+ * @return {number|undefined} Width for the specified zoom level or `undefined`
+ * if unknown.
+ */
+ol.tilegrid.TileGrid.prototype.getWidth = function(z) {
+ if (!goog.isNull(this.widths_)) {
+ goog.asserts.assert(this.minZoom <= z && z <= this.maxZoom);
+ return this.widths_[z];
+ }
+};
+
+
/**
* @param {number} resolution Resolution.
* @return {number} Z.
@@ -399,6 +441,26 @@ ol.tilegrid.TileGrid.prototype.getZForResolution = function(resolution) {
};
+/**
+ * @param {number} z Zoom level.
+ * @param {ol.proj.Projection} projection Projection.
+ * @return {boolean} Whether the tile grid is defined for the whole globe when
+ * used with the provided `projection` at zoom level `z`.
+ */
+ol.tilegrid.TileGrid.prototype.isGlobal = function(z, projection) {
+ var width = this.getWidth(z);
+ if (goog.isDef(width)) {
+ var projTileGrid = ol.tilegrid.getForProjection(projection);
+ var projExtent = projection.getExtent();
+ return this.getTileSize(z) * width ==
+ projTileGrid.getTileSize(z) *
+ projTileGrid.getTileRangeForExtentAndZ(projExtent, z).getWidth();
+ } else {
+ return projection.isGlobal();
+ }
+};
+
+
/**
* @param {ol.proj.Projection} projection Projection.
* @return {ol.tilegrid.TileGrid} Default tile grid for the passed projection.
@@ -433,10 +495,17 @@ ol.tilegrid.createForExtent =
var resolutions = ol.tilegrid.resolutionsFromExtent(
extent, opt_maxZoom, tileSize);
+ var widths = new Array(resolutions.length);
+ var extentWidth = ol.extent.getWidth(extent);
+ for (var z = resolutions.length - 1; z >= 0; --z) {
+ widths[z] = extentWidth / tileSize / resolutions[z];
+ }
+
return new ol.tilegrid.TileGrid({
origin: ol.extent.getCorner(extent, corner),
resolutions: resolutions,
- tileSize: tileSize
+ tileSize: tileSize,
+ widths: widths
});
};
diff --git a/src/ol/tilegrid/wmtstilegrid.js b/src/ol/tilegrid/wmtstilegrid.js
index 228d25715a..9f381c1682 100644
--- a/src/ol/tilegrid/wmtstilegrid.js
+++ b/src/ol/tilegrid/wmtstilegrid.js
@@ -34,7 +34,8 @@ ol.tilegrid.WMTS = function(options) {
origins: options.origins,
resolutions: options.resolutions,
tileSize: options.tileSize,
- tileSizes: options.tileSizes
+ tileSizes: options.tileSizes,
+ widths: options.widths
});
};
@@ -77,6 +78,8 @@ ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
var origins = [];
/** @type {!Array.} */
var tileSizes = [];
+ /** @type {!Array.} */
+ var widths = [];
var supportedCRSPropName = 'SupportedCRS';
var matrixIdsPropName = 'TileMatrix';
@@ -112,12 +115,14 @@ ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
var tileHeight = elt[tileHeightPropName];
goog.asserts.assert(tileWidth == tileHeight);
tileSizes.push(tileWidth);
+ widths.push(elt['MatrixWidth']);
});
return new ol.tilegrid.WMTS({
origins: origins,
resolutions: resolutions,
matrixIds: matrixIds,
- tileSizes: tileSizes
+ tileSizes: tileSizes,
+ widths: widths
});
};