diff --git a/examples/wms-custom-tilegrid-512x256.js b/examples/wms-custom-tilegrid-512x256.js
index 8a6226d030..5c7d86644a 100644
--- a/examples/wms-custom-tilegrid-512x256.js
+++ b/examples/wms-custom-tilegrid-512x256.js
@@ -15,7 +15,7 @@ for (var i = 0, ii = resolutions.length; i < ii; ++i) {
resolutions[i] = startResolution / Math.pow(2, i);
}
var tileGrid = new ol.tilegrid.TileGrid({
- origin: ol.extent.getBottomLeft(projExtent),
+ extent: [-13884991, 2870341, -7455066, 6338219],
resolutions: resolutions,
tileSize: [512, 256]
});
@@ -25,7 +25,6 @@ var layers = [
source: new ol.source.MapQuest({layer: 'sat'})
}),
new ol.layer.Tile({
- extent: [-13884991, 2870341, -7455066, 6338219],
source: new ol.source.TileWMS({
url: 'http://demo.boundlessgeo.com/geoserver/wms',
params: {'LAYERS': 'topp:states', 'TILED': true},
diff --git a/examples/wms-tiled-wrap-180.js b/examples/wms-tiled-wrap-180.js
index fdf864b7e8..bf606e013f 100644
--- a/examples/wms-tiled-wrap-180.js
+++ b/examples/wms-tiled-wrap-180.js
@@ -13,8 +13,7 @@ var layers = [
source: new ol.source.TileWMS({
url: 'http://demo.boundlessgeo.com/geoserver/ne/wms',
params: {'LAYERS': 'ne:ne_10m_admin_0_countries', 'TILED': true},
- serverType: 'geoserver',
- wrapX: true
+ serverType: 'geoserver'
})
})
];
diff --git a/externs/olx.js b/externs/olx.js
index f258393c28..ed472c0581 100644
--- a/externs/olx.js
+++ b/externs/olx.js
@@ -4942,11 +4942,10 @@ olx.source.TileWMSOptions.prototype.urls;
/**
- * Whether to wrap the world horizontally. The default, `undefined`, is to
- * request out-of-bounds tiles from the server. This works well in e.g.
- * GeoServer. When set to `false`, only one world will be rendered. When set to
- * `true`, tiles will be requested for one world only, but they will be wrapped
- * horizontally to render multiple worlds.
+ * Whether to wrap the world horizontally. When set to `false`, only one world
+ * will be rendered. When `true`, tiles will be requested for one world only,
+ * but they will be wrapped horizontally to render multiple worlds. The default
+ * is `true`.
* @type {boolean|undefined}
* @api
*/
@@ -6014,18 +6013,30 @@ olx.tilegrid;
/**
- * @typedef {{minZoom: (number|undefined),
+ * @typedef {{extent: (ol.Extent|undefined),
+ * minZoom: (number|undefined),
* origin: (ol.Coordinate|undefined),
* origins: (Array.
|undefined),
* resolutions: !Array.,
+ * sizes: (Array.|undefined),
* tileSize: (number|ol.Size|undefined),
- * tileSizes: (Array.|undefined),
- * widths: (Array.|undefined)}}
+ * tileSizes: (Array.|undefined)}}
* @api
*/
olx.tilegrid.TileGridOptions;
+/**
+ * Extent for the tile grid. No tiles outside this extent will be requested by
+ * {@link ol.source.Tile} sources. When no `origin` or `origins` are
+ * configured, the `origin` will be set to the bottom-left corner of the extent.
+ * When no `sizes` are configured, they will be calculated from the extent.
+ * @type {ol.Extent|undefined}
+ * @api
+ */
+olx.tilegrid.TileGridOptions.prototype.extent;
+
+
/**
* Minimum zoom. Default is 0.
* @type {number|undefined}
@@ -6035,7 +6046,7 @@ olx.tilegrid.TileGridOptions.prototype.minZoom;
/**
- * Origin. Default is null.
+ * Origin, i.e. the bottom-left corner of the grid. Default is null.
* @type {ol.Coordinate|undefined}
* @api stable
*/
@@ -6043,8 +6054,9 @@ olx.tilegrid.TileGridOptions.prototype.origin;
/**
- * Origins. If given, the array length should match the length of the
- * `resolutions` array, i.e. each resolution can have a different origin.
+ * Origins, i.e. the bottom-left corners of the grid for each zoom level. If
+ * given, the array length should match the length of the `resolutions` array,
+ * i.e. each resolution can have a different origin.
* @type {Array.|undefined}
* @api stable
*/
@@ -6061,6 +6073,17 @@ olx.tilegrid.TileGridOptions.prototype.origins;
olx.tilegrid.TileGridOptions.prototype.resolutions;
+/**
+ * Number of tile rows and columns of the grid for each zoom level. This setting
+ * is only needed for tile coordinate transforms that need to work with origins
+ * other than the bottom-left corner of the grid. No tiles outside this range
+ * will be requested by sources. If an `extent` is also configured, it takes
+ * precedence.
+ * @type {Array.|undefined}
+ */
+olx.tilegrid.TileGridOptions.prototype.sizes;
+
+
/**
* Tile size. Default is `[256, 256]`.
* @type {number|ol.Size|undefined}
@@ -6079,32 +6102,32 @@ olx.tilegrid.TileGridOptions.prototype.tileSizes;
/**
- * Number of tile columns that cover the grid's extent for each zoom level. Only
- * required when used with a source that has `wrapX` set to `true`, and only
- * when the grid's origin differs from the one of the projection's extent. The
- * array length has to match the length of the `resolutions` array, i.e. each
- * resolution will have a matching entry here.
- * @type {Array.|undefined}
- * @api
- */
-olx.tilegrid.TileGridOptions.prototype.widths;
-
-
-/**
- * @typedef {{origin: (ol.Coordinate|undefined),
+ * @typedef {{extent: (ol.Extent|undefined),
+ * origin: (ol.Coordinate|undefined),
* origins: (Array.|undefined),
* resolutions: !Array.,
* matrixIds: !Array.,
+ * sizes: (Array.|undefined),
* tileSize: (number|ol.Size|undefined),
- * tileSizes: (Array.|undefined),
- * widths: (Array.|undefined)}}
+ * tileSizes: (Array.|undefined)}}
* @api
*/
olx.tilegrid.WMTSOptions;
/**
- * Origin.
+ * Extent for the tile grid. No tiles outside this extent will be requested by
+ * {@link ol.source.WMTS} sources. When no `origin` or `origins` are
+ * configured, the `origin` will be calculated from the extent.
+ * When no `sizes` are configured, they will be calculated from the extent.
+ * @type {ol.Extent|undefined}
+ * @api
+ */
+olx.tilegrid.WMTSOptions.prototype.extent;
+
+
+/**
+ * Origin, i.e. the top-left corner of the grid.
* @type {ol.Coordinate|undefined}
* @api
*/
@@ -6112,7 +6135,8 @@ olx.tilegrid.WMTSOptions.prototype.origin;
/**
- * Origins. The length of this array needs to match the length of the
+ * Origins, i.e. the top-left corners of the grid for each zoom level. The
+ * length of this array needs to match the length of the
* `resolutions` array.
* @type {Array.|undefined}
* @api
@@ -6139,6 +6163,18 @@ olx.tilegrid.WMTSOptions.prototype.resolutions;
olx.tilegrid.WMTSOptions.prototype.matrixIds;
+/**
+ * Number of tile rows and columns of the grid for each zoom level. The values
+ * here are the `TileMatrixWidth` and `TileMatrixHeight` advertised in the
+ * GetCapabilities response of the WMTS, and define the grid's extent together
+ * with the `origin`. An `extent` can be configured in addition, and will
+ * further limit the extent for which tile requests are made by sources.
+ * @type {Array.|undefined}
+ * @api
+ */
+olx.tilegrid.WMTSOptions.prototype.sizes;
+
+
/**
* Tile size.
* @type {number|ol.Size|undefined}
diff --git a/src/ol/attribution.js b/src/ol/attribution.js
index 4963fa08d6..9f069828c6 100644
--- a/src/ol/attribution.js
+++ b/src/ol/attribution.js
@@ -78,8 +78,8 @@ ol.Attribution.prototype.intersectsAnyTileRange =
if (testTileRange.intersects(tileRange)) {
return true;
}
- var extentTileRange = tileGrid.getTileRange(
- parseInt(zKey, 10), projection);
+ var extentTileRange = tileGrid.getTileRangeForExtentAndZ(
+ projection.getExtent(), parseInt(zKey, 10));
var width = extentTileRange.getWidth();
if (tileRange.minX < extentTileRange.minX ||
tileRange.maxX > extentTileRange.maxX) {
diff --git a/src/ol/source/source.js b/src/ol/source/source.js
index e215cb40e9..a6aeab177c 100644
--- a/src/ol/source/source.js
+++ b/src/ol/source/source.js
@@ -75,9 +75,9 @@ ol.source.Source = function(options) {
/**
* @private
- * @type {boolean|undefined}
+ * @type {boolean}
*/
- this.wrapX_ = options.wrapX;
+ this.wrapX_ = goog.isDef(options.wrapX) ? options.wrapX : false;
};
goog.inherits(ol.source.Source, ol.Object);
diff --git a/src/ol/source/tileimagesource.js b/src/ol/source/tileimagesource.js
index 0b549a1f9c..1701f19e86 100644
--- a/src/ol/source/tileimagesource.js
+++ b/src/ol/source/tileimagesource.js
@@ -93,7 +93,8 @@ ol.source.TileImage.prototype.getTile =
} else {
goog.asserts.assert(projection, 'argument projection is truthy');
var tileCoord = [z, x, y];
- var urlTileCoord = this.getWrapXTileCoord(tileCoord, projection);
+ var urlTileCoord = this.getTileCoordForTileUrlFunction(
+ tileCoord, projection);
var tileUrl = goog.isNull(urlTileCoord) ? undefined :
this.tileUrlFunction(urlTileCoord, pixelRatio, projection);
var tile = new this.tileClass(
diff --git a/src/ol/source/tilesource.js b/src/ol/source/tilesource.js
index e81a4261b3..a0179d5ad6 100644
--- a/src/ol/source/tilesource.js
+++ b/src/ol/source/tilesource.js
@@ -2,6 +2,7 @@ goog.provide('ol.source.Tile');
goog.provide('ol.source.TileEvent');
goog.provide('ol.source.TileOptions');
+goog.require('goog.asserts');
goog.require('goog.events.Event');
goog.require('ol.Attribution');
goog.require('ol.Extent');
@@ -216,28 +217,23 @@ ol.source.Tile.prototype.getTilePixelSize =
/**
- * Handles x-axis wrapping. When `wrapX` is `undefined` or the projection is not
- * a global projection, `tileCoord` will be returned unaltered. When `wrapX` is
- * `true`, the tile coordinate will be wrapped horizontally.
- * When `wrapX` is `false`, `null` will be returned for tiles that are
- * outside the projection extent.
+ * Handles x-axis wrapping and returns a tile coordinate when it is within
+ * the resolution and extent range.
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @param {ol.proj.Projection=} opt_projection Projection.
- * @return {ol.TileCoord} Tile coordinate.
+ * @return {ol.TileCoord} Tile coordinate to be passed to the tileUrlFunction or
+ * null if no tile URL should be created for the passed `tileCoord`.
*/
-ol.source.Tile.prototype.getWrapXTileCoord =
+ol.source.Tile.prototype.getTileCoordForTileUrlFunction =
function(tileCoord, opt_projection) {
var projection = goog.isDef(opt_projection) ?
opt_projection : this.getProjection();
var tileGrid = this.getTileGridForProjection(projection);
- var wrapX = this.getWrapX();
- if (goog.isDef(wrapX) && tileGrid.isGlobal(tileCoord[0], projection)) {
- return wrapX ?
- ol.tilecoord.wrapX(tileCoord, tileGrid, projection) :
- ol.tilecoord.clipX(tileCoord, tileGrid, projection);
- } else {
- return tileCoord;
+ goog.asserts.assert(!goog.isNull(tileGrid), 'tile grid needed');
+ if (this.getWrapX()) {
+ tileCoord = ol.tilecoord.wrapX(tileCoord, tileGrid, projection);
}
+ return ol.tilecoord.restrictByExtentAndZ(tileCoord, tileGrid);
};
diff --git a/src/ol/source/tilewmssource.js b/src/ol/source/tilewmssource.js
index d655a2e179..b2fa897e0a 100644
--- a/src/ol/source/tilewmssource.js
+++ b/src/ol/source/tilewmssource.js
@@ -49,7 +49,7 @@ ol.source.TileWMS = function(opt_options) {
tileGrid: options.tileGrid,
tileLoadFunction: options.tileLoadFunction,
tileUrlFunction: goog.bind(this.tileUrlFunction_, this),
- wrapX: options.wrapX
+ wrapX: goog.isDef(options.wrapX) ? options.wrapX : true
});
var urls = options.urls;
diff --git a/src/ol/source/wmtssource.js b/src/ol/source/wmtssource.js
index 53eb1f3bcb..7eb25cdb2b 100644
--- a/src/ol/source/wmtssource.js
+++ b/src/ol/source/wmtssource.js
@@ -11,7 +11,6 @@ goog.require('ol.TileUrlFunctionType');
goog.require('ol.extent');
goog.require('ol.proj');
goog.require('ol.source.TileImage');
-goog.require('ol.tilecoord');
goog.require('ol.tilegrid.WMTS');
@@ -181,31 +180,8 @@ ol.source.WMTS = function(options) {
goog.array.map(this.urls_, createFromWMTSTemplate)) :
ol.TileUrlFunction.nullTileUrlFunction;
- var tmpExtent = ol.extent.createEmpty();
tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform(
- /**
- * @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.proj.Projection} projection Projection.
- * @param {ol.TileCoord=} opt_tileCoord Tile coordinate.
- * @return {ol.TileCoord} Tile coordinate.
- */
- function(tileCoord, projection, opt_tileCoord) {
- goog.asserts.assert(!goog.isNull(tileGrid),
- 'tileGrid must not be null');
- if (tileGrid.getResolutions().length <= tileCoord[0]) {
- return null;
- }
- var x = tileCoord[1];
- var y = -tileCoord[2] - 1;
- var tileExtent = tileGrid.getTileCoordExtent(tileCoord, tmpExtent);
- var extent = projection.getExtent();
-
- if (!ol.extent.intersects(tileExtent, extent) ||
- ol.extent.touches(tileExtent, extent)) {
- return null;
- }
- return ol.tilecoord.createOrUpdate(tileCoord[0], x, y, opt_tileCoord);
- },
+ ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid),
tileUrlFunction);
goog.base(this, {
@@ -450,9 +426,6 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) {
goog.asserts.assert(!goog.isNull(matrixSetObj),
'found matrixSet in Contents/TileMatrixSet');
- var tileGrid = ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet(
- matrixSetObj);
-
var projection;
if (goog.isDef(config['projection'])) {
projection = ol.proj.get(config['projection']);
@@ -461,6 +434,19 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) {
/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3'));
}
+ var projectionExtent = projection.getExtent();
+ var extent;
+ if (!goog.isNull(projectionExtent)) {
+ var projectionExtentWgs84 = ol.proj.transformExtent(
+ projectionExtent, projection, 'EPSG:4326');
+ if (ol.extent.containsExtent(projectionExtentWgs84, wgs84BoundingBox)) {
+ extent = ol.proj.transformExtent(
+ wgs84BoundingBox, 'EPSG:4326', projection);
+ }
+ }
+ var tileGrid = ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet(
+ matrixSetObj, extent);
+
/** @type {!Array.} */
var urls = [];
var requestEncoding = config['requestEncoding'];
diff --git a/src/ol/tilecoord.js b/src/ol/tilecoord.js
index 09f7da088f..ebc1044add 100644
--- a/src/ol/tilecoord.js
+++ b/src/ol/tilecoord.js
@@ -3,7 +3,7 @@ goog.provide('ol.tilecoord');
goog.require('goog.array');
goog.require('goog.asserts');
-goog.require('goog.math');
+goog.require('ol.extent');
/**
@@ -149,25 +149,42 @@ ol.tilecoord.toString = function(tileCoord) {
*/
ol.tilecoord.wrapX = function(tileCoord, tileGrid, projection) {
var z = tileCoord[0];
- var x = tileCoord[1];
- var tileRange = tileGrid.getTileRange(z, projection);
- if (x < tileRange.minX || x > tileRange.maxX) {
- x = goog.math.modulo(x, tileRange.getWidth());
- return [z, x, tileCoord[2]];
+ var center = tileGrid.getTileCoordCenter(tileCoord);
+ var projectionExtent = ol.tilegrid.extentFromProjection(projection);
+ if (!ol.extent.containsCoordinate(projectionExtent, center)) {
+ var worldWidth = ol.extent.getWidth(projectionExtent);
+ var worldsAway = Math.ceil((projectionExtent[0] - center[0]) / worldWidth);
+ center[0] += worldWidth * worldsAway;
+ return tileGrid.getTileCoordForCoordAndZ(center, z);
+ } else {
+ return tileCoord;
}
- return tileCoord;
};
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
- * @param {ol.proj.Projection} projection Projection.
+ * @param {!ol.tilegrid.TileGrid} tileGrid Tile grid.
* @return {ol.TileCoord} Tile coordinate.
*/
-ol.tilecoord.clipX = function(tileCoord, tileGrid, projection) {
+ol.tilecoord.restrictByExtentAndZ = function(tileCoord, tileGrid) {
var z = tileCoord[0];
var x = tileCoord[1];
- var tileRange = tileGrid.getTileRange(z, projection);
- return (x < tileRange.minX || x > tileRange.maxX) ? null : tileCoord;
+ var y = tileCoord[2];
+
+ if (tileGrid.getMinZoom() > z || z > tileGrid.getMaxZoom()) {
+ return null;
+ }
+ var extent = tileGrid.getExtent();
+ var tileRange;
+ if (goog.isNull(extent)) {
+ tileRange = tileGrid.getFullTileRange(z);
+ } else {
+ tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
+ }
+ if (goog.isNull(tileRange)) {
+ return tileCoord;
+ } else {
+ return tileRange.containsXY(x, y) ? tileCoord : null;
+ }
};
diff --git a/src/ol/tilegrid/tilegrid.js b/src/ol/tilegrid/tilegrid.js
index 9c08e6ee9c..507fbbf614 100644
--- a/src/ol/tilegrid/tilegrid.js
+++ b/src/ol/tilegrid/tilegrid.js
@@ -4,6 +4,7 @@ goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.functions');
goog.require('goog.math');
+goog.require('goog.object');
goog.require('ol');
goog.require('ol.Coordinate');
goog.require('ol.TileCoord');
@@ -69,6 +70,10 @@ 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);
+ }
goog.asserts.assert(
(goog.isNull(this.origin_) && !goog.isNull(this.origins_)) ||
(!goog.isNull(this.origin_) && goog.isNull(this.origins_)),
@@ -97,6 +102,51 @@ 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;
+
+ /**
+ * @private
+ * @type {Array.}
+ */
+ this.fullTileRanges_ = null;
+
+ if (goog.isDef(options.sizes)) {
+ goog.asserts.assert(options.sizes.length == this.resolutions_.length,
+ 'number of sizes and resolutions must be equal');
+ this.fullTileRanges_ = goog.array.map(options.sizes, function(size, z) {
+ goog.asserts.assert(size[0] > 0, 'width must be > 0');
+ goog.asserts.assert(size[1] !== 0, 'height must not be 0');
+ var tileRange = new ol.TileRange(0, size[0] - 1, 0, size[1] - 1);
+ if (tileRange.maxY < tileRange.minY) {
+ tileRange.minY = size[1];
+ tileRange.maxY = -1;
+ }
+ if (this.minZoom <= z && z <= this.maxZoom && goog.isDef(extent)) {
+ goog.asserts.assert(tileRange.containsTileRange(
+ this.getTileRangeForExtentAndZ(extent, z)),
+ 'extent tile range must not exceed tilegrid width and height');
+ }
+ 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);
+ }
+ this.fullTileRanges_ = fullTileRanges;
+ }
/**
* @private
@@ -104,17 +154,6 @@ ol.tilegrid.TileGrid = function(options) {
*/
this.tmpSize_ = [0, 0];
- /**
- * @private
- * @type {Array.}
- */
- this.widths_ = null;
- if (goog.isDef(options.widths)) {
- this.widths_ = options.widths;
- goog.asserts.assert(this.widths_.length == this.resolutions_.length,
- 'number of widths and resolutions must be equal');
- }
-
};
@@ -161,6 +200,15 @@ ol.tilegrid.TileGrid.prototype.forEachTileCoordParentTileRange =
};
+/**
+ * Get the extent for this tile grid, if it was configured.
+ * @return {ol.Extent} Extent.
+ */
+ol.tilegrid.TileGrid.prototype.getExtent = function() {
+ return this.extent_;
+};
+
+
/**
* Get the maximum zoom level for the grid.
* @return {number} Max zoom.
@@ -412,25 +460,6 @@ 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);
-};
-
-
/**
* Get the tile size for a zoom level. The type of the return value matches the
* `tileSize` or `tileSizes` that the tile grid was configured with. To always
@@ -455,15 +484,16 @@ 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.
+ * @return {ol.TileRange} Extent tile range for the specified zoom level.
*/
-ol.tilegrid.TileGrid.prototype.getWidth = function(z) {
- if (!goog.isNull(this.widths_)) {
+ol.tilegrid.TileGrid.prototype.getFullTileRange = function(z) {
+ if (goog.isNull(this.fullTileRanges_)) {
+ return null;
+ } else {
goog.asserts.assert(this.minZoom <= z && z <= this.maxZoom,
'z is not in allowed range (%s <= %s <= %s',
this.minZoom, z, this.maxZoom);
- return this.widths_[z];
+ return this.fullTileRanges_[z];
}
};
@@ -478,26 +508,6 @@ 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 ol.size.toSize(this.getTileSize(z), this.tmpSize_)[0] * 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.
@@ -611,3 +621,36 @@ ol.tilegrid.extentFromProjection = function(projection) {
}
return extent;
};
+
+
+/**
+ * @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
+ * @return {function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=):
+ * ol.TileCoord} Tile coordinate transform.
+ */
+ol.tilegrid.createOriginTopLeftTileCoordTransform = function(tileGrid) {
+ goog.asserts.assert(!goog.isNull(tileGrid), 'tileGrid required');
+ 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) {
+ if (goog.isNull(tileCoord)) {
+ return null;
+ }
+ var z = tileCoord[0];
+ var fullTileRange = tileGrid.getFullTileRange(z);
+ var height;
+ if (goog.isNull(fullTileRange) || fullTileRange.minY < 0) {
+ height = 0;
+ } else {
+ height = fullTileRange.getHeight();
+ }
+ return ol.tilecoord.createOrUpdate(
+ z, tileCoord[1], height - tileCoord[2] - 1, opt_tileCoord);
+ }
+ );
+};
diff --git a/src/ol/tilegrid/wmtstilegrid.js b/src/ol/tilegrid/wmtstilegrid.js
index 6770358784..74838aa2e9 100644
--- a/src/ol/tilegrid/wmtstilegrid.js
+++ b/src/ol/tilegrid/wmtstilegrid.js
@@ -32,12 +32,13 @@ ol.tilegrid.WMTS = function(options) {
// FIXME: should the matrixIds become optionnal?
goog.base(this, {
+ extent: options.extent,
origin: options.origin,
origins: options.origins,
resolutions: options.resolutions,
tileSize: options.tileSize,
tileSizes: options.tileSizes,
- widths: options.widths
+ sizes: options.sizes
});
};
@@ -69,11 +70,13 @@ ol.tilegrid.WMTS.prototype.getMatrixIds = function() {
* Create a tile grid from a WMTS capabilities matrix set.
* @param {Object} matrixSet An object representing a matrixSet in the
* capabilities document.
+ * @param {ol.Extent=} opt_extent An optional extent to restrict the tile
+ * ranges the server provides.
* @return {ol.tilegrid.WMTS} WMTS tileGrid instance.
* @api
*/
ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
- function(matrixSet) {
+ function(matrixSet, opt_extent) {
/** @type {!Array.} */
var resolutions = [];
@@ -83,8 +86,8 @@ ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
var origins = [];
/** @type {!Array.} */
var tileSizes = [];
- /** @type {!Array.} */
- var widths = [];
+ /** @type {!Array.} */
+ var sizes = [];
var supportedCRSPropName = 'SupportedCRS';
var matrixIdsPropName = 'TileMatrix';
@@ -108,26 +111,30 @@ ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
goog.array.forEach(matrixSet[matrixIdsPropName],
function(elt, index, array) {
matrixIds.push(elt[identifierPropName]);
+ var resolution = elt[scaleDenominatorPropName] * 0.28E-3 /
+ metersPerUnit;
+ var tileWidth = elt[tileWidthPropName];
+ var tileHeight = elt[tileHeightPropName];
+ var matrixHeight = elt['MatrixHeight'];
if (switchOriginXY) {
origins.push([elt[topLeftCornerPropName][1],
elt[topLeftCornerPropName][0]]);
} else {
origins.push(elt[topLeftCornerPropName]);
}
- resolutions.push(elt[scaleDenominatorPropName] * 0.28E-3 /
- metersPerUnit);
- var tileWidth = elt[tileWidthPropName];
- var tileHeight = elt[tileHeightPropName];
+ resolutions.push(resolution);
tileSizes.push(tileWidth == tileHeight ?
tileWidth : [tileWidth, tileHeight]);
- widths.push(elt['MatrixWidth']);
+ // top-left origin, so height is negative
+ sizes.push([elt['MatrixWidth'], -matrixHeight]);
});
return new ol.tilegrid.WMTS({
+ extent: opt_extent,
origins: origins,
resolutions: resolutions,
matrixIds: matrixIds,
tileSizes: tileSizes,
- widths: widths
+ sizes: sizes
});
};
diff --git a/test/spec/ol/source/tilesource.test.js b/test/spec/ol/source/tilesource.test.js
index ddd2b610b1..b6c2a99030 100644
--- a/test/spec/ol/source/tilesource.test.js
+++ b/test/spec/ol/source/tilesource.test.js
@@ -115,22 +115,7 @@ describe('ol.source.Tile', function() {
});
- describe('#getWrapXTileCoord()', function() {
-
- it('returns the expected tile coordinate - {wrapX: undefined}', function() {
- var tileSource = new ol.source.Tile({
- projection: 'EPSG:3857'
- });
-
- var tileCoord = tileSource.getWrapXTileCoord([6, -31, 22]);
- expect(tileCoord).to.eql([6, -31, 22]);
-
- tileCoord = tileSource.getWrapXTileCoord([6, 33, 22]);
- expect(tileCoord).to.eql([6, 33, 22]);
-
- tileCoord = tileSource.getWrapXTileCoord([6, 97, 22]);
- expect(tileCoord).to.eql([6, 97, 22]);
- });
+ describe('#getTileCoordForTileUrlFunction()', function() {
it('returns the expected tile coordinate - {wrapX: true}', function() {
var tileSource = new ol.source.Tile({
@@ -138,13 +123,13 @@ describe('ol.source.Tile', function() {
wrapX: true
});
- var tileCoord = tileSource.getWrapXTileCoord([6, -31, 22]);
+ var tileCoord = tileSource.getTileCoordForTileUrlFunction([6, -31, 22]);
expect(tileCoord).to.eql([6, 33, 22]);
- tileCoord = tileSource.getWrapXTileCoord([6, 33, 22]);
+ tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 33, 22]);
expect(tileCoord).to.eql([6, 33, 22]);
- tileCoord = tileSource.getWrapXTileCoord([6, 97, 22]);
+ tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 97, 22]);
expect(tileCoord).to.eql([6, 33, 22]);
});
@@ -154,13 +139,13 @@ describe('ol.source.Tile', function() {
wrapX: false
});
- var tileCoord = tileSource.getWrapXTileCoord([6, -31, 22]);
+ var tileCoord = tileSource.getTileCoordForTileUrlFunction([6, -31, 22]);
expect(tileCoord).to.eql(null);
- tileCoord = tileSource.getWrapXTileCoord([6, 33, 22]);
+ tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 33, 22]);
expect(tileCoord).to.eql([6, 33, 22]);
- tileCoord = tileSource.getWrapXTileCoord([6, 97, 22]);
+ tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 97, 22]);
expect(tileCoord).to.eql(null);
});
});
diff --git a/test/spec/ol/source/xyzsource.test.js b/test/spec/ol/source/xyzsource.test.js
index e5d7cab36c..866f3c20b5 100644
--- a/test/spec/ol/source/xyzsource.test.js
+++ b/test/spec/ol/source/xyzsource.test.js
@@ -66,15 +66,18 @@ describe('ol.source.XYZ', function() {
it('returns the expected URL', function() {
var projection = xyzTileSource.getProjection();
var tileUrl = xyzTileSource.tileUrlFunction(
- xyzTileSource.getWrapXTileCoord([6, -31, -23], projection));
+ xyzTileSource.getTileCoordForTileUrlFunction(
+ [6, -31, 41], projection));
expect(tileUrl).to.eql('6/33/22');
tileUrl = xyzTileSource.tileUrlFunction(
- xyzTileSource.getWrapXTileCoord([6, 33, -23], projection));
+ xyzTileSource.getTileCoordForTileUrlFunction(
+ [6, 33, 41], projection));
expect(tileUrl).to.eql('6/33/22');
tileUrl = xyzTileSource.tileUrlFunction(
- xyzTileSource.getWrapXTileCoord([6, 97, -23], projection));
+ xyzTileSource.getTileCoordForTileUrlFunction(
+ [6, 97, 41], projection));
expect(tileUrl).to.eql('6/33/22');
});
@@ -83,14 +86,20 @@ describe('ol.source.XYZ', function() {
describe('crop y', function() {
it('returns the expected URL', function() {
+ var projection = xyzTileSource.getProjection();
var tileUrl = xyzTileSource.tileUrlFunction(
- [6, 33, -87]);
+ xyzTileSource.getTileCoordForTileUrlFunction(
+ [6, 33, 150], projection));
expect(tileUrl).to.be(undefined);
- tileUrl = xyzTileSource.tileUrlFunction([6, 33, -23]);
+ tileUrl = xyzTileSource.tileUrlFunction(
+ xyzTileSource.getTileCoordForTileUrlFunction(
+ [6, 33, 41], projection));
expect(tileUrl).to.eql('6/33/22');
- tileUrl = xyzTileSource.tileUrlFunction([6, 33, 41]);
+ tileUrl = xyzTileSource.tileUrlFunction(
+ xyzTileSource.getTileCoordForTileUrlFunction(
+ [6, 33, -23], projection));
expect(tileUrl).to.be(undefined);
});
diff --git a/test/spec/ol/tilecoord.test.js b/test/spec/ol/tilecoord.test.js
index d46c3483c8..f2bd42411d 100644
--- a/test/spec/ol/tilecoord.test.js
+++ b/test/spec/ol/tilecoord.test.js
@@ -46,7 +46,79 @@ describe('ol.TileCoord', function() {
ol.tilecoord.hash(tileCoord2));
});
});
+
+ describe('restrictByExtentAndZ', function() {
+
+ it('restricts by z', function() {
+ var tileGrid = new ol.tilegrid.TileGrid({
+ extent: [10, 20, 30, 40],
+ tileSize: 10,
+ resolutions: [2, 1],
+ minZoom: 1
+ });
+ expect(ol.tilecoord.restrictByExtentAndZ([0, 0, 0], tileGrid))
+ .to.equal(null);
+ expect(ol.tilecoord.restrictByExtentAndZ([1, 0, 0], tileGrid))
+ .to.eql([1, 0, 0]);
+ expect(ol.tilecoord.restrictByExtentAndZ([2, 0, 0], tileGrid))
+ .to.equal(null);
+ });
+
+ it('restricts by extent when extent defines tile ranges', function() {
+ var tileGrid = new ol.tilegrid.TileGrid({
+ extent: [10, 20, 30, 40],
+ sizes: [[3, 3]],
+ tileSize: 10,
+ resolutions: [1]
+ });
+ expect(ol.tilecoord.restrictByExtentAndZ([0, 1, 1], tileGrid))
+ .to.eql([0, 1, 1]);
+ expect(ol.tilecoord.restrictByExtentAndZ([0, 2, 0], tileGrid))
+ .to.equal(null);
+ expect(ol.tilecoord.restrictByExtentAndZ([0, 0, 2], tileGrid))
+ .to.equal(null);
+ });
+
+ it('restricts by extent when sizes define tile ranges', function() {
+ var tileGrid = new ol.tilegrid.TileGrid({
+ origin: [10, 20],
+ sizes: [[3, 3]],
+ tileSize: 10,
+ resolutions: [1]
+ });
+ expect(ol.tilecoord.restrictByExtentAndZ([0, 0, 0], tileGrid))
+ .to.eql([0, 0, 0]);
+ expect(ol.tilecoord.restrictByExtentAndZ([0, -1, 0], tileGrid))
+ .to.equal(null);
+ expect(ol.tilecoord.restrictByExtentAndZ([0, 0, -1], tileGrid))
+ .to.equal(null);
+ expect(ol.tilecoord.restrictByExtentAndZ([0, 2, 2], tileGrid))
+ .to.eql([0, 2, 2]);
+ expect(ol.tilecoord.restrictByExtentAndZ([0, 3, 0], tileGrid))
+ .to.equal(null);
+ expect(ol.tilecoord.restrictByExtentAndZ([0, 0, 3], tileGrid))
+ .to.equal(null);
+ });
+
+ it('does not restrict by extent with no extent or sizes', function() {
+ var tileGrid = new ol.tilegrid.TileGrid({
+ origin: [10, 20],
+ tileSize: 10,
+ resolutions: [1]
+ });
+ expect(ol.tilecoord.restrictByExtentAndZ([0, Infinity, 0], tileGrid))
+ .to.eql([0, Infinity, 0]);
+ expect(ol.tilecoord.restrictByExtentAndZ([0, 0, Infinity], tileGrid))
+ .to.eql([0, 0, Infinity]);
+ expect(ol.tilecoord.restrictByExtentAndZ([0, -Infinity, 0], tileGrid))
+ .to.eql([0, -Infinity, 0]);
+ expect(ol.tilecoord.restrictByExtentAndZ([0, 0, Infinity], tileGrid))
+ .to.eql([0, 0, Infinity]);
+ });
+ });
+
});
goog.require('ol.TileCoord');
goog.require('ol.tilecoord');
+goog.require('ol.tilegrid.TileGrid');
diff --git a/test/spec/ol/tilegrid/tilegrid.test.js b/test/spec/ol/tilegrid/tilegrid.test.js
index 14f8b14d83..e476a58726 100644
--- a/test/spec/ol/tilegrid/tilegrid.test.js
+++ b/test/spec/ol/tilegrid/tilegrid.test.js
@@ -150,6 +150,129 @@ describe('ol.tilegrid.TileGrid', function() {
});
});
+ describe('create with extent exceeding tile ranges', function() {
+ it('throws an exception', function() {
+ expect(function() {
+ return new ol.tilegrid.TileGrid({
+ extent: [10, 20, 30, 40],
+ sizes: [[1, 1]],
+ tileSize: 10,
+ resolutions: [1]
+ });
+ }).to.throwException();
+ expect(function() {
+ return new ol.tilegrid.TileGrid({
+ extent: [10, 20, 30, 40],
+ origin: [10, 40], // top-left origin
+ sizes: [[3, 3]], // would have to be [[3, -3]] for this to not throw
+ tileSize: 10,
+ resolutions: [1]
+ });
+ }).to.throwException();
+ });
+ });
+
+ describe('create with origin', function() {
+ var tileGrid;
+ beforeEach(function() {
+ tileGrid = new ol.tilegrid.TileGrid({
+ origin: [10, 20],
+ tileSize: 10,
+ resolutions: [1]
+ });
+ });
+
+ it('returns the configured origin', function() {
+ expect(tileGrid.getOrigin()).to.eql([10, 20]);
+ });
+
+ it('returns null for an unknown extent', function() {
+ expect(tileGrid.getExtent()).to.equal(null);
+ });
+
+ it('returns null for an unknown full tile range', function() {
+ expect(tileGrid.getFullTileRange(0)).to.equal(null);
+ });
+ });
+
+ describe('create with extent', function() {
+ var tileGrid;
+ beforeEach(function() {
+ tileGrid = new ol.tilegrid.TileGrid({
+ extent: [10, 20, 30, 40],
+ tileSize: 10,
+ resolutions: [1]
+ });
+ });
+
+ it('assumes bottom left corner of extent as origin', function() {
+ expect(tileGrid.getOrigin()).to.eql([10, 20]);
+ });
+
+ it('calculates full tile ranges from extent', function() {
+ var fullTileRange = tileGrid.getFullTileRange(0);
+ expect(fullTileRange.minX).to.equal(0);
+ expect(fullTileRange.maxX).to.equal(1);
+ expect(fullTileRange.minY).to.equal(0);
+ expect(fullTileRange.maxY).to.equal(1);
+ });
+ });
+
+ describe('create with extent and sizes', function() {
+ var tileGrid;
+ beforeEach(function() {
+ tileGrid = new ol.tilegrid.TileGrid({
+ extent: [10, 20, 30, 40],
+ sizes: [[3, 3]],
+ tileSize: 10,
+ resolutions: [1]
+ });
+ });
+
+ it('returns the configured extent', function() {
+ expect(tileGrid.getExtent()).to.eql([10, 20, 30, 40]);
+ });
+
+ it('calculates full tile ranges from sizes', function() {
+ var fullTileRange = tileGrid.getFullTileRange(0);
+ expect(fullTileRange.minX).to.equal(0);
+ expect(fullTileRange.maxX).to.equal(2);
+ expect(fullTileRange.minY).to.equal(0);
+ expect(fullTileRange.maxY).to.equal(2);
+ });
+ });
+
+ describe('create with top-left origin and sizes', function() {
+ var tileGrid;
+ beforeEach(function() {
+ tileGrid = new ol.tilegrid.TileGrid({
+ origin: [10, 40],
+ sizes: [[3, -3]],
+ tileSize: 10,
+ resolutions: [1]
+ });
+ });
+
+ it('calculates correct minX and maxX for negative heights', function() {
+ var fullTileRange = tileGrid.getFullTileRange(0);
+ expect(fullTileRange.minY).to.equal(-3);
+ expect(fullTileRange.maxY).to.equal(-1);
+ });
+ });
+
+ describe('create with extent and origin', function() {
+ it('uses both origin and extent', function() {
+ var tileGrid = new ol.tilegrid.TileGrid({
+ origin: [0, 0],
+ extent: [10, 20, 30, 40],
+ tileSize: 10,
+ resolutions: [1]
+ });
+ expect(tileGrid.getOrigin()).to.eql([0, 0]);
+ expect(tileGrid.getExtent()).to.eql([10, 20, 30, 40]);
+ });
+ });
+
describe('createForExtent', function() {
it('allows creation of tile grid from extent', function() {
var extent = ol.extent.createOrUpdate(-100, -100, 100, 100);
@@ -247,6 +370,78 @@ describe('ol.tilegrid.TileGrid', function() {
});
+ describe('createOriginTopLeftTileCoordTransform', function() {
+
+ it('transforms y to -y-1 for top-left origins', function() {
+ var tileGrid = new ol.tilegrid.TileGrid({
+ origin: [10, 40],
+ sizes: [[2, -2], [4, -4]],
+ resolutions: [1, 0.5],
+ tileSize: 10
+ });
+ var transformFn =
+ ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid);
+ expect(transformFn([0, 0, -2])).to.eql([0, 0, 1]);
+ expect(transformFn([0, 0, -1])).to.eql([0, 0, 0]);
+ expect(transformFn([1, 0, -4])).to.eql([1, 0, 3]);
+ expect(transformFn([1, 0, -1])).to.eql([1, 0, 0]);
+ });
+
+ it('transforms y to -y-1 when origin corner is not specified', function() {
+ var tileGrid1 = new ol.tilegrid.TileGrid({
+ origin: [10, 20],
+ resolutions: [1, 0.5],
+ tileSize: 10
+ });
+ var tileGrid = new ol.tilegrid.TileGrid({
+ origin: [10, 40],
+ resolutions: [1, 0.5],
+ tileSize: 10
+ });
+ var transformFn1 =
+ ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid);
+ var transformFn2 =
+ ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid1);
+ expect(transformFn1([0, 0, -2])).to.eql([0, 0, 1]);
+ expect(transformFn2([0, 0, -2])).to.eql([0, 0, 1]);
+ expect(transformFn1([0, 0, -1])).to.eql([0, 0, 0]);
+ expect(transformFn2([0, 0, -1])).to.eql([0, 0, 0]);
+ expect(transformFn1([1, 0, -4])).to.eql([1, 0, 3]);
+ expect(transformFn2([1, 0, -4])).to.eql([1, 0, 3]);
+ expect(transformFn1([1, 0, -1])).to.eql([1, 0, 0]);
+ expect(transformFn2([1, 0, -1])).to.eql([1, 0, 0]);
+ });
+
+ it('transforms y to height-y-1 for bottom-left origins', function() {
+ var tileGrid1 = new ol.tilegrid.TileGrid({
+ extent: [10, 20, 30, 40],
+ resolutions: [1, 0.5],
+ tileSize: 10
+ });
+ var tileGrid2 = new ol.tilegrid.TileGrid({
+ origin: [10, 20],
+ sizes: [[2, 2], [4, 4]],
+ resolutions: [1, 0.5],
+ tileSize: 10
+ });
+ var transformFn1 =
+ ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid1);
+ var transformFn2 =
+ ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid2);
+ expect(tileGrid1.getFullTileRange(0).getHeight()).to.equal(2);
+ expect(transformFn1([0, 0, 0])).to.eql([0, 0, 1]);
+ expect(transformFn2([0, 0, 0])).to.eql([0, 0, 1]);
+ expect(transformFn1([0, 0, 1])).to.eql([0, 0, 0]);
+ expect(transformFn2([0, 0, 1])).to.eql([0, 0, 0]);
+ expect(tileGrid1.getFullTileRange(1).getHeight()).to.equal(4);
+ expect(transformFn1([1, 0, 0])).to.eql([1, 0, 3]);
+ expect(transformFn2([1, 0, 0])).to.eql([1, 0, 3]);
+ expect(transformFn1([1, 0, 3])).to.eql([1, 0, 0]);
+ expect(transformFn2([1, 0, 3])).to.eql([1, 0, 0]);
+ });
+
+ });
+
describe('getForProjection', function() {
it('gets the default tile grid for a projection', function() {
@@ -839,7 +1034,7 @@ describe('ol.tilegrid.TileGrid', function() {
});
});
- describe('getZForResolution (approcimate)', function() {
+ describe('getZForResolution (approximate)', function() {
it('returns the expected z value', function() {
var tileGrid = new ol.tilegrid.TileGrid({
resolutions: resolutions,
@@ -874,4 +1069,5 @@ goog.require('ol.proj');
goog.require('ol.proj.EPSG3857');
goog.require('ol.proj.Projection');
goog.require('ol.proj.Units');
+goog.require('ol.TileRange');
goog.require('ol.tilegrid.TileGrid');
diff --git a/test/spec/ol/tilegrid/wmtstilegrid.test.js b/test/spec/ol/tilegrid/wmtstilegrid.test.js
index 1e03436c23..966dacb59e 100644
--- a/test/spec/ol/tilegrid/wmtstilegrid.test.js
+++ b/test/spec/ol/tilegrid/wmtstilegrid.test.js
@@ -42,27 +42,17 @@ describe('ol.tilegrid.WMTS', function() {
expect(tileGrid.origins_).to.be.an('array');
expect(tileGrid.origins_).to.have.length(20);
expect(tileGrid.origins_).to.eql(
- [[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
- [-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
- [-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
- [-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
- [-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
- [-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
- [-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
- [-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
- [-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
- [-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428]
- ]);
+ goog.array.repeat([-20037508.3428, 20037508.3428], 20));
expect(tileGrid.tileSizes_).to.be.an('array');
expect(tileGrid.tileSizes_).to.have.length(20);
expect(tileGrid.tileSizes_).to.eql(
- [256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256]);
+ goog.array.repeat(256, 20));
});
});
});
+goog.require('goog.array');
goog.require('ol.format.WMTSCapabilities');
goog.require('ol.tilegrid.WMTS');