diff --git a/changelog/upgrade-notes.md b/changelog/upgrade-notes.md
index 9f7b60fd5a..d473ef0b5b 100644
--- a/changelog/upgrade-notes.md
+++ b/changelog/upgrade-notes.md
@@ -116,6 +116,10 @@
with the `imgSize` option and not with `size`. `size` is supposed to be used for the
size of a sub-rectangle in an image sprite.
+### Support for non-square tiles
+
+When using ´ol.tilegrid.TileGrid#getTileSize` on the tile grid of an `ol.source.BingMaps`, the return value will now be an `ol.Size` array instead of a number.
+
### v3.4.0
There should be nothing special required when upgrading from v3.3.0 to v3.4.0.
diff --git a/examples_src/wms-custom-tilegrid-512x256.html b/examples_src/wms-custom-tilegrid-512x256.html
new file mode 100644
index 0000000000..bb3ce43d3b
--- /dev/null
+++ b/examples_src/wms-custom-tilegrid-512x256.html
@@ -0,0 +1,13 @@
+---
+template: example.html
+title: WMS custom tile grid 512x256 example
+shortdesc: Example of a WMS layer with 512x256px tiles.
+docs: >
+ WMS can serve arbitrary tile sizes. This example uses a custom tile grid with non-square tiles.
+tags: "wms, tile, non-square"
+---
+
diff --git a/examples_src/wms-custom-tilegrid-512x256.js b/examples_src/wms-custom-tilegrid-512x256.js
new file mode 100644
index 0000000000..8a6226d030
--- /dev/null
+++ b/examples_src/wms-custom-tilegrid-512x256.js
@@ -0,0 +1,44 @@
+goog.require('ol.Map');
+goog.require('ol.View');
+goog.require('ol.extent');
+goog.require('ol.layer.Tile');
+goog.require('ol.proj');
+goog.require('ol.source.MapQuest');
+goog.require('ol.source.TileWMS');
+goog.require('ol.tilegrid.TileGrid');
+
+
+var projExtent = ol.proj.get('EPSG:3857').getExtent();
+var startResolution = ol.extent.getWidth(projExtent) / 256;
+var resolutions = new Array(22);
+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),
+ resolutions: resolutions,
+ tileSize: [512, 256]
+});
+
+var layers = [
+ new ol.layer.Tile({
+ 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},
+ serverType: 'geoserver',
+ tileGrid: tileGrid
+ })
+ })
+];
+var map = new ol.Map({
+ layers: layers,
+ target: 'map',
+ view: new ol.View({
+ center: [-10997148, 4569099],
+ zoom: 4
+ })
+});
diff --git a/externs/olx.js b/externs/olx.js
index ebf684f3b2..674b03b8ee 100644
--- a/externs/olx.js
+++ b/externs/olx.js
@@ -5145,7 +5145,7 @@ olx.source.WMTSOptions.prototype.wrapX;
* minZoom: (number|undefined),
* tileLoadFunction: (ol.TileLoadFunctionType|undefined),
* tilePixelRatio: (number|undefined),
- * tileSize: (number|undefined),
+ * tileSize: (number|ol.Size|undefined),
* tileUrlFunction: (ol.TileUrlFunctionType|undefined),
* url: (string|undefined),
* urls: (Array.|undefined),
@@ -5227,8 +5227,8 @@ olx.source.XYZOptions.prototype.tilePixelRatio;
/**
- * The tile size used by the tile service. Default is `256` pixels.
- * @type {number|undefined}
+ * The tile size used by the tile service. Default is `[256, 256]` pixels.
+ * @type {number|ol.Size|undefined}
* @api
*/
olx.source.XYZOptions.prototype.tileSize;
@@ -5924,8 +5924,8 @@ olx.tilegrid;
* origin: (ol.Coordinate|undefined),
* origins: (Array.|undefined),
* resolutions: !Array.,
- * tileSize: (number|undefined),
- * tileSizes: (Array.|undefined),
+ * tileSize: (number|ol.Size|undefined),
+ * tileSizes: (Array.|undefined),
* widths: (Array.|undefined)}}
* @api
*/
@@ -5968,8 +5968,8 @@ olx.tilegrid.TileGridOptions.prototype.resolutions;
/**
- * Tile size. Default is 256. (Only square tiles are supported.)
- * @type {number|undefined}
+ * Tile size. Default is `[256, 256]`.
+ * @type {number|ol.Size|undefined}
* @api stable
*/
olx.tilegrid.TileGridOptions.prototype.tileSize;
@@ -5978,7 +5978,7 @@ olx.tilegrid.TileGridOptions.prototype.tileSize;
/**
* Tile sizes. If given, the array length should match the length of the
* `resolutions` array, i.e. each resolution can have a different tile size.
- * @type {Array.|undefined}
+ * @type {Array.|undefined}
* @api stable
*/
olx.tilegrid.TileGridOptions.prototype.tileSizes;
@@ -6001,8 +6001,8 @@ olx.tilegrid.TileGridOptions.prototype.widths;
* origins: (Array.|undefined),
* resolutions: !Array.,
* matrixIds: !Array.,
- * tileSize: (number|undefined),
- * tileSizes: (Array.|undefined),
+ * tileSize: (number|ol.Size|undefined),
+ * tileSizes: (Array.|undefined),
* widths: (Array.|undefined)}}
* @api
*/
@@ -6047,7 +6047,7 @@ olx.tilegrid.WMTSOptions.prototype.matrixIds;
/**
* Tile size.
- * @type {number|undefined}
+ * @type {number|ol.Size|undefined}
* @api
*/
olx.tilegrid.WMTSOptions.prototype.tileSize;
@@ -6056,7 +6056,7 @@ olx.tilegrid.WMTSOptions.prototype.tileSize;
/**
* Tile sizes. The length of this array needs to match the length of the
* `resolutions` array.
- * @type {Array.|undefined}
+ * @type {Array.|undefined}
* @api
*/
olx.tilegrid.WMTSOptions.prototype.tileSizes;
@@ -6078,7 +6078,7 @@ olx.tilegrid.WMTSOptions.prototype.widths;
* @typedef {{extent: (ol.Extent|undefined),
* maxZoom: (number|undefined),
* minZoom: (number|undefined),
- * tileSize: (number|undefined)}}
+ * tileSize: (number|ol.Size|undefined)}}
* @api
*/
olx.tilegrid.XYZOptions;
@@ -6114,8 +6114,8 @@ olx.tilegrid.XYZOptions.prototype.minZoom;
/**
- * Tile size in pixels. Default is 256. (Only square tiles are supported.)
- * @type {number|undefined}
+ * Tile size in pixels. Default is `[256, 256]`.
+ * @type {number|ol.Size|undefined}
* @api
*/
olx.tilegrid.XYZOptions.prototype.tileSize;
diff --git a/src/ol/renderer/canvas/canvastilelayerrenderer.js b/src/ol/renderer/canvas/canvastilelayerrenderer.js
index 7c6bc6d77b..129fe6cdda 100644
--- a/src/ol/renderer/canvas/canvastilelayerrenderer.js
+++ b/src/ol/renderer/canvas/canvastilelayerrenderer.js
@@ -14,6 +14,7 @@ goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.layer.Tile');
goog.require('ol.renderer.canvas.Layer');
+goog.require('ol.size');
goog.require('ol.tilecoord');
goog.require('ol.vec.Mat4');
@@ -74,7 +75,13 @@ ol.renderer.canvas.TileLayer = function(tileLayer) {
* @private
* @type {number}
*/
- this.renderedTileSize_ = NaN;
+ this.renderedTileWidth_ = NaN;
+
+ /**
+ * @private
+ * @type {number}
+ */
+ this.renderedTileHeight_ = NaN;
/**
* @private
@@ -88,6 +95,12 @@ ol.renderer.canvas.TileLayer = function(tileLayer) {
*/
this.renderedTiles_ = null;
+ /**
+ * @private
+ * @type {ol.Size}
+ */
+ this.tmpSize_ = [0, 0];
+
};
goog.inherits(ol.renderer.canvas.TileLayer, ol.renderer.canvas.Layer);
@@ -190,7 +203,8 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
var z = tileGrid.getZForResolution(viewState.resolution);
var tilePixelSize =
tileSource.getTilePixelSize(z, frameState.pixelRatio, projection);
- var tilePixelRatio = tilePixelSize / tileGrid.getTileSize(z);
+ var tilePixelRatio = tilePixelSize[0] /
+ ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize_)[0];
var tileResolution = tileGrid.getResolution(z);
var tilePixelResolution = tileResolution / tilePixelRatio;
var center = viewState.center;
@@ -214,8 +228,8 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
extent, tileResolution);
- var canvasWidth = tilePixelSize * tileRange.getWidth();
- var canvasHeight = tilePixelSize * tileRange.getHeight();
+ var canvasWidth = tilePixelSize[0] * tileRange.getWidth();
+ var canvasHeight = tilePixelSize[1] * tileRange.getHeight();
var canvas, context;
if (goog.isNull(this.canvas_)) {
@@ -240,7 +254,8 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
context = this.context_;
if (this.canvasSize_[0] < canvasWidth ||
this.canvasSize_[1] < canvasHeight ||
- this.renderedTileSize_ !== tilePixelSize ||
+ this.renderedTileWidth_ !== tilePixelSize[0] ||
+ this.renderedTileHeight_ !== tilePixelSize[1] ||
(this.canvasTooBig_ && (this.canvasSize_[0] > canvasWidth ||
this.canvasSize_[1] > canvasHeight))) {
// Canvas is too small or tileSize has changed, resize it.
@@ -264,14 +279,15 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
var canvasTileRange, canvasTileRangeWidth, minX, minY;
if (goog.isNull(this.renderedCanvasTileRange_)) {
- canvasTileRangeWidth = canvasWidth / tilePixelSize;
- var canvasTileRangeHeight = canvasHeight / tilePixelSize;
+ canvasTileRangeWidth = canvasWidth / tilePixelSize[0];
+ var canvasTileRangeHeight = canvasHeight / tilePixelSize[1];
minX = tileRange.minX -
Math.floor((canvasTileRangeWidth - tileRange.getWidth()) / 2);
minY = tileRange.minY -
Math.floor((canvasTileRangeHeight - tileRange.getHeight()) / 2);
this.renderedCanvasZ_ = z;
- this.renderedTileSize_ = tilePixelSize;
+ this.renderedTileWidth_ = tilePixelSize[0];
+ this.renderedTileHeight_ = tilePixelSize[1];
this.renderedCanvasTileRange_ = new ol.TileRange(
minX, minX + canvasTileRangeWidth - 1,
minY, minY + canvasTileRangeHeight - 1);
@@ -332,9 +348,9 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
var i, ii;
for (i = 0, ii = tilesToClear.length; i < ii; ++i) {
tile = tilesToClear[i];
- x = tilePixelSize * (tile.tileCoord[1] - canvasTileRange.minX);
- y = tilePixelSize * (canvasTileRange.maxY - tile.tileCoord[2]);
- context.clearRect(x, y, tilePixelSize, tilePixelSize);
+ x = tilePixelSize[0] * (tile.tileCoord[1] - canvasTileRange.minX);
+ y = tilePixelSize[1] * (canvasTileRange.maxY - tile.tileCoord[2]);
+ context.clearRect(x, y, tilePixelSize[0], tilePixelSize[1]);
}
/** @type {Array.} */
@@ -359,18 +375,18 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
(tile.tileCoord[2] - canvasTileRange.minY) * canvasTileRangeWidth +
(tile.tileCoord[1] - canvasTileRange.minX);
if (this.renderedTiles_[index] != tile) {
- x = tilePixelSize * (tile.tileCoord[1] - canvasTileRange.minX);
- y = tilePixelSize * (canvasTileRange.maxY - tile.tileCoord[2]);
+ x = tilePixelSize[0] * (tile.tileCoord[1] - canvasTileRange.minX);
+ y = tilePixelSize[1] * (canvasTileRange.maxY - tile.tileCoord[2]);
tileState = tile.getState();
if (tileState == ol.TileState.EMPTY ||
(tileState == ol.TileState.ERROR && !useInterimTilesOnError) ||
!opaque) {
- context.clearRect(x, y, tilePixelSize, tilePixelSize);
+ context.clearRect(x, y, tilePixelSize[0], tilePixelSize[1]);
}
if (tileState == ol.TileState.LOADED) {
context.drawImage(tile.getImage(),
- tileGutter, tileGutter, tilePixelSize, tilePixelSize,
- x, y, tilePixelSize, tilePixelSize);
+ tileGutter, tileGutter, tilePixelSize[0], tilePixelSize[1],
+ x, y, tilePixelSize[0], tilePixelSize[1]);
}
this.renderedTiles_[index] = tile;
}
@@ -382,15 +398,15 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
x = (tileExtent[0] - origin[0]) / tilePixelResolution;
y = (origin[1] - tileExtent[3]) / tilePixelResolution;
- width = scale * tilePixelSize;
- height = scale * tilePixelSize;
+ width = scale * tilePixelSize[0];
+ height = scale * tilePixelSize[1];
tileState = tile.getState();
if (tileState == ol.TileState.EMPTY || !opaque) {
context.clearRect(x, y, width, height);
}
if (tileState == ol.TileState.LOADED) {
context.drawImage(tile.getImage(),
- tileGutter, tileGutter, tilePixelSize, tilePixelSize,
+ tileGutter, tileGutter, tilePixelSize[0], tilePixelSize[1],
x, y, width, height);
}
interimTileRange =
diff --git a/src/ol/renderer/dom/domtilelayerrenderer.js b/src/ol/renderer/dom/domtilelayerrenderer.js
index 1a58594f7e..89b7861f70 100644
--- a/src/ol/renderer/dom/domtilelayerrenderer.js
+++ b/src/ol/renderer/dom/domtilelayerrenderer.js
@@ -21,6 +21,7 @@ goog.require('ol.dom.BrowserFeature');
goog.require('ol.extent');
goog.require('ol.layer.Tile');
goog.require('ol.renderer.dom.Layer');
+goog.require('ol.size');
goog.require('ol.tilecoord');
goog.require('ol.tilegrid.TileGrid');
goog.require('ol.vec.Mat4');
@@ -342,6 +343,12 @@ ol.renderer.dom.TileLayerZ_ = function(tileGrid, tileCoordOrigin) {
*/
this.transform_ = goog.vec.Mat4.createNumberIdentity();
+ /**
+ * @private
+ * @type {ol.Size}
+ */
+ this.tmpSize_ = [0, 0];
+
};
@@ -360,7 +367,8 @@ ol.renderer.dom.TileLayerZ_.prototype.addTile = function(tile, tileGutter) {
if (tileCoordKey in this.tiles_) {
return;
}
- var tileSize = this.tileGrid_.getTileSize(tileCoordZ);
+ var tileSize = ol.size.toSize(
+ this.tileGrid_.getTileSize(tileCoordZ), this.tmpSize_);
var image = tile.getImage(this);
var imageStyle = image.style;
// Bootstrap sets the style max-width: 100% for all images, which
@@ -373,25 +381,25 @@ ol.renderer.dom.TileLayerZ_.prototype.addTile = function(tile, tileGutter) {
tileElement = goog.dom.createElement(goog.dom.TagName.DIV);
tileElementStyle = tileElement.style;
tileElementStyle.overflow = 'hidden';
- tileElementStyle.width = tileSize + 'px';
- tileElementStyle.height = tileSize + 'px';
+ tileElementStyle.width = tileSize[0] + 'px';
+ tileElementStyle.height = tileSize[1] + 'px';
imageStyle.position = 'absolute';
imageStyle.left = -tileGutter + 'px';
imageStyle.top = -tileGutter + 'px';
- imageStyle.width = (tileSize + 2 * tileGutter) + 'px';
- imageStyle.height = (tileSize + 2 * tileGutter) + 'px';
+ imageStyle.width = (tileSize[0] + 2 * tileGutter) + 'px';
+ imageStyle.height = (tileSize[1] + 2 * tileGutter) + 'px';
goog.dom.appendChild(tileElement, image);
} else {
- imageStyle.width = tileSize + 'px';
- imageStyle.height = tileSize + 'px';
+ imageStyle.width = tileSize[0] + 'px';
+ imageStyle.height = tileSize[1] + 'px';
tileElement = image;
tileElementStyle = imageStyle;
}
tileElementStyle.position = 'absolute';
tileElementStyle.left =
- ((tileCoordX - this.tileCoordOrigin_[1]) * tileSize) + 'px';
+ ((tileCoordX - this.tileCoordOrigin_[1]) * tileSize[0]) + 'px';
tileElementStyle.top =
- ((this.tileCoordOrigin_[2] - tileCoordY) * tileSize) + 'px';
+ ((this.tileCoordOrigin_[2] - tileCoordY) * tileSize[1]) + 'px';
if (goog.isNull(this.documentFragment_)) {
this.documentFragment_ = document.createDocumentFragment();
}
diff --git a/src/ol/renderer/webgl/webglmaprenderer.js b/src/ol/renderer/webgl/webglmaprenderer.js
index 730c1863e9..c90f09536a 100644
--- a/src/ol/renderer/webgl/webglmaprenderer.js
+++ b/src/ol/renderer/webgl/webglmaprenderer.js
@@ -71,7 +71,13 @@ ol.renderer.webgl.Map = function(container, map) {
* @private
* @type {number}
*/
- this.clipTileCanvasSize_ = 0;
+ this.clipTileCanvasWidth_ = 0;
+
+ /**
+ * @private
+ * @type {number}
+ */
+ this.clipTileCanvasHeight_ = 0;
/**
* @private
@@ -158,7 +164,7 @@ ol.renderer.webgl.Map = function(container, map) {
this.tileTextureQueue_.reprioritize();
var element = this.tileTextureQueue_.dequeue();
var tile = /** @type {ol.Tile} */ (element[0]);
- var tileSize = /** @type {number} */ (element[3]);
+ var tileSize = /** @type {ol.Size} */ (element[3]);
var tileGutter = /** @type {number} */ (element[4]);
this.bindTileTexture(
tile, tileSize, tileGutter, goog.webgl.LINEAR, goog.webgl.LINEAR);
@@ -179,7 +185,7 @@ goog.inherits(ol.renderer.webgl.Map, ol.renderer.Map);
/**
* @param {ol.Tile} tile Tile.
- * @param {number} tileSize Tile size.
+ * @param {ol.Size} tileSize Tile size.
* @param {number} tileGutter Tile gutter.
* @param {number} magFilter Mag filter.
* @param {number} minFilter Min filter.
@@ -209,15 +215,17 @@ ol.renderer.webgl.Map.prototype.bindTileTexture =
if (tileGutter > 0) {
var clipTileCanvas = this.clipTileContext_.canvas;
var clipTileContext = this.clipTileContext_;
- if (this.clipTileCanvasSize_ != tileSize) {
- clipTileCanvas.width = tileSize;
- clipTileCanvas.height = tileSize;
- this.clipTileCanvasSize_ = tileSize;
+ if (this.clipTileCanvasWidth_ !== tileSize[0] ||
+ this.clipTileCanvasHeight_ !== tileSize[1]) {
+ clipTileCanvas.width = tileSize[0];
+ clipTileCanvas.height = tileSize[1];
+ this.clipTileCanvasWidth_ = tileSize[0];
+ this.clipTileCanvasHeight_ = tileSize[1];
} else {
- clipTileContext.clearRect(0, 0, tileSize, tileSize);
+ clipTileContext.clearRect(0, 0, tileSize[0], tileSize[1]);
}
clipTileContext.drawImage(tile.getImage(), tileGutter, tileGutter,
- tileSize, tileSize, 0, 0, tileSize, tileSize);
+ tileSize[0], tileSize[1], 0, 0, tileSize[0], tileSize[1]);
gl.texImage2D(goog.webgl.TEXTURE_2D, 0,
goog.webgl.RGBA, goog.webgl.RGBA,
goog.webgl.UNSIGNED_BYTE, clipTileCanvas);
diff --git a/src/ol/renderer/webgl/webgltilelayerrenderer.js b/src/ol/renderer/webgl/webgltilelayerrenderer.js
index 43f623d286..6627a31584 100644
--- a/src/ol/renderer/webgl/webgltilelayerrenderer.js
+++ b/src/ol/renderer/webgl/webgltilelayerrenderer.js
@@ -16,6 +16,7 @@ goog.require('ol.layer.Tile');
goog.require('ol.math');
goog.require('ol.renderer.webgl.Layer');
goog.require('ol.renderer.webgl.tilelayer.shader');
+goog.require('ol.size');
goog.require('ol.tilecoord');
goog.require('ol.vec.Mat4');
goog.require('ol.webgl.Buffer');
@@ -80,6 +81,12 @@ ol.renderer.webgl.TileLayer = function(mapRenderer, tileLayer) {
*/
this.renderedRevision_ = -1;
+ /**
+ * @private
+ * @type {ol.Size}
+ */
+ this.tmpSize_ = [0, 0];
+
};
goog.inherits(ol.renderer.webgl.TileLayer, ol.renderer.webgl.Layer);
@@ -160,7 +167,8 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame =
var tilePixelSize =
tileSource.getTilePixelSize(z, frameState.pixelRatio, projection);
- var pixelRatio = tilePixelSize / tileGrid.getTileSize(z);
+ var pixelRatio = tilePixelSize[0] /
+ ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize_)[0];
var tilePixelResolution = tileResolution / pixelRatio;
var tileGutter = tileSource.getGutter();
@@ -186,12 +194,15 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame =
var tileRangeSize = tileRange.getSize();
var maxDimension = Math.max(
- tileRangeSize[0] * tilePixelSize, tileRangeSize[1] * tilePixelSize);
+ tileRangeSize[0] * tilePixelSize[0],
+ tileRangeSize[1] * tilePixelSize[1]);
var framebufferDimension = ol.math.roundUpToPowerOfTwo(maxDimension);
var framebufferExtentDimension = tilePixelResolution * framebufferDimension;
var origin = tileGrid.getOrigin(z);
- var minX = origin[0] + tileRange.minX * tilePixelSize * tilePixelResolution;
- var minY = origin[1] + tileRange.minY * tilePixelSize * tilePixelResolution;
+ var minX = origin[0] +
+ tileRange.minX * tilePixelSize[0] * tilePixelResolution;
+ var minY = origin[1] +
+ tileRange.minY * tilePixelSize[1] * tilePixelResolution;
framebufferExtent = [
minX, minY,
minX + framebufferExtentDimension, minY + framebufferExtentDimension
diff --git a/src/ol/size.js b/src/ol/size.js
index 2fb84be2a7..12d367d9f8 100644
--- a/src/ol/size.js
+++ b/src/ol/size.js
@@ -2,6 +2,9 @@ goog.provide('ol.Size');
goog.provide('ol.size');
+goog.require('goog.asserts');
+
+
/**
* An array of numbers representing a size: `[width, height]`.
* @typedef {Array.}
@@ -10,6 +13,23 @@ goog.provide('ol.size');
ol.Size;
+/**
+ * Returns a buffered size.
+ * @param {ol.Size} size Size.
+ * @param {number} buffer Buffer.
+ * @param {ol.Size=} opt_size Optional reusable size array.
+ * @return {ol.Size}
+ */
+ol.size.buffer = function(size, buffer, opt_size) {
+ if (!goog.isDef(opt_size)) {
+ opt_size = [0, 0];
+ }
+ opt_size[0] = size[0] + 2 * buffer;
+ opt_size[1] = size[1] + 2 * buffer;
+ return opt_size;
+};
+
+
/**
* Compares sizes for equality.
* @param {ol.Size} a Size.
@@ -19,3 +39,40 @@ ol.Size;
ol.size.equals = function(a, b) {
return a[0] == b[0] && a[1] == b[1];
};
+
+
+/**
+ * Returns a size scaled by a ratio. The result will be an array of integers.
+ * @param {ol.Size} size Size.
+ * @param {number} ratio Ratio.
+ * @param {ol.Size=} opt_size Optional reusable size array.
+ * @return {ol.Size}
+ */
+ol.size.scale = function(size, ratio, opt_size) {
+ if (!goog.isDef(opt_size)) {
+ opt_size = [0, 0];
+ }
+ opt_size[0] = (size[0] * ratio + 0.5) | 0;
+ opt_size[1] = (size[1] * ratio + 0.5) | 0;
+ return opt_size;
+};
+
+
+/**
+ * @param {number|ol.Size} size Width and height.
+ * @param {ol.Size=} opt_size Optional reusable size array.
+ * @return {ol.Size} Size.
+ */
+ol.size.toSize = function(size, opt_size) {
+ if (goog.isArray(size)) {
+ return size;
+ } else {
+ if (!goog.isDef(opt_size)) {
+ opt_size = [0, 0];
+ }
+ goog.asserts.assert(goog.isNumber(size));
+ opt_size[0] = size;
+ opt_size[1] = size;
+ return opt_size;
+ }
+};
diff --git a/src/ol/source/bingmapssource.js b/src/ol/source/bingmapssource.js
index cf72fce7dd..406102c437 100644
--- a/src/ol/source/bingmapssource.js
+++ b/src/ol/source/bingmapssource.js
@@ -107,7 +107,7 @@ ol.source.BingMaps.prototype.handleImageryMetadataResponse =
extent: ol.tilegrid.extentFromProjection(sourceProjection),
minZoom: resource.zoomMin,
maxZoom: maxZoom,
- tileSize: resource.imageWidth
+ tileSize: [resource.imageWidth, resource.imageHeight]
});
this.tileGrid = tileGrid;
diff --git a/src/ol/source/tilearcgisrestsource.js b/src/ol/source/tilearcgisrestsource.js
index b07281c88e..4f1a108ab0 100644
--- a/src/ol/source/tilearcgisrestsource.js
+++ b/src/ol/source/tilearcgisrestsource.js
@@ -11,6 +11,7 @@ goog.require('ol.TileCoord');
goog.require('ol.TileUrlFunction');
goog.require('ol.extent');
goog.require('ol.proj');
+goog.require('ol.size');
goog.require('ol.source.TileImage');
goog.require('ol.tilecoord');
@@ -86,7 +87,7 @@ ol.source.TileArcGISRest.prototype.getParams = function() {
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {number} tileSize Tile size.
+ * @param {ol.Size} tileSize Tile size.
* @param {ol.Extent} tileExtent Tile extent.
* @param {number} pixelRatio Pixel ratio.
* @param {ol.proj.Projection} projection Projection.
@@ -106,7 +107,7 @@ ol.source.TileArcGISRest.prototype.getRequestUrl_ =
// ArcGIS Server only wants the numeric portion of the projection ID.
var srid = projection.getCode().split(':').pop();
- params['SIZE'] = tileSize + ',' + tileSize;
+ params['SIZE'] = tileSize[0] + ',' + tileSize[1];
params['BBOX'] = tileExtent.join(',');
params['BBOXSR'] = srid;
params['IMAGESR'] = srid;
@@ -143,7 +144,7 @@ ol.source.TileArcGISRest.prototype.getRequestUrl_ =
* @param {number} z Z.
* @param {number} pixelRatio Pixel ratio.
* @param {ol.proj.Projection} projection Projection.
- * @return {number} Size.
+ * @return {ol.Size} Size.
*/
ol.source.TileArcGISRest.prototype.getTilePixelSize =
function(z, pixelRatio, projection) {
@@ -151,7 +152,7 @@ ol.source.TileArcGISRest.prototype.getTilePixelSize =
if (pixelRatio == 1) {
return tileSize;
} else {
- return (tileSize * pixelRatio + 0.5) | 0;
+ return ol.size.scale(tileSize, pixelRatio, this.tmpSize);
}
};
@@ -207,10 +208,11 @@ ol.source.TileArcGISRest.prototype.tileUrlFunction_ =
var tileExtent = tileGrid.getTileCoordExtent(
tileCoord, this.tmpExtent_);
- var tileSize = tileGrid.getTileSize(tileCoord[0]);
+ var tileSize = ol.size.toSize(
+ tileGrid.getTileSize(tileCoord[0]), this.tmpSize);
if (pixelRatio != 1) {
- tileSize = (tileSize * pixelRatio + 0.5) | 0;
+ tileSize = ol.size.scale(tileSize, pixelRatio, this.tmpSize);
}
// Apply default params and override with user specified values.
diff --git a/src/ol/source/tiledebugsource.js b/src/ol/source/tiledebugsource.js
index ae49401d95..b035f37efd 100644
--- a/src/ol/source/tiledebugsource.js
+++ b/src/ol/source/tiledebugsource.js
@@ -4,6 +4,7 @@ goog.require('ol.Tile');
goog.require('ol.TileCoord');
goog.require('ol.TileState');
goog.require('ol.dom');
+goog.require('ol.size');
goog.require('ol.source.Tile');
goog.require('ol.tilecoord');
goog.require('ol.tilegrid.TileGrid');
@@ -23,9 +24,10 @@ ol.DebugTile_ = function(tileCoord, tileGrid) {
/**
* @private
- * @type {number}
+ * @type {ol.Size}
*/
- this.tileSize_ = tileGrid.getTileSize(tileCoord[0]);
+ this.tileSize_ = ol.size.toSize(
+ tileGrid.getTileSize(tileCoord[0]));
/**
* @private
@@ -47,17 +49,17 @@ ol.DebugTile_.prototype.getImage = function(opt_context) {
} else {
var tileSize = this.tileSize_;
- var context = ol.dom.createCanvasContext2D(tileSize, tileSize);
+ var context = ol.dom.createCanvasContext2D(tileSize[0], tileSize[1]);
context.strokeStyle = 'black';
- context.strokeRect(0.5, 0.5, tileSize + 0.5, tileSize + 0.5);
+ context.strokeRect(0.5, 0.5, tileSize[0] + 0.5, tileSize[1] + 0.5);
context.fillStyle = 'black';
context.textAlign = 'center';
context.textBaseline = 'middle';
context.font = '24px sans-serif';
context.fillText(ol.tilecoord.toString(this.tileCoord),
- tileSize / 2, tileSize / 2);
+ tileSize[0] / 2, tileSize[1] / 2);
this.canvasByContext_[key] = context.canvas;
return context.canvas;
diff --git a/src/ol/source/tilesource.js b/src/ol/source/tilesource.js
index 4e8d0988c8..0a9a546b11 100644
--- a/src/ol/source/tilesource.js
+++ b/src/ol/source/tilesource.js
@@ -8,6 +8,7 @@ goog.require('ol.Extent');
goog.require('ol.TileCache');
goog.require('ol.TileRange');
goog.require('ol.TileState');
+goog.require('ol.size');
goog.require('ol.source.Source');
goog.require('ol.tilecoord');
goog.require('ol.tilegrid.TileGrid');
@@ -74,6 +75,12 @@ ol.source.Tile = function(options) {
*/
this.tileCache = new ol.TileCache();
+ /**
+ * @protected
+ * @type {ol.Size}
+ */
+ this.tmpSize = [0, 0];
+
/**
* @private
* @type {boolean|undefined}
@@ -202,12 +209,13 @@ ol.source.Tile.prototype.getTileGridForProjection = function(projection) {
* @param {number} z Z.
* @param {number} pixelRatio Pixel ratio.
* @param {ol.proj.Projection} projection Projection.
- * @return {number} Tile size.
+ * @return {ol.Size} Tile size.
*/
ol.source.Tile.prototype.getTilePixelSize =
function(z, pixelRatio, projection) {
var tileGrid = this.getTileGridForProjection(projection);
- return tileGrid.getTileSize(z) * this.tilePixelRatio_;
+ return ol.size.scale(ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize),
+ this.tilePixelRatio_, this.tmpSize);
};
diff --git a/src/ol/source/tilewmssource.js b/src/ol/source/tilewmssource.js
index aa41a1b5ff..8cdcd9ca58 100644
--- a/src/ol/source/tilewmssource.js
+++ b/src/ol/source/tilewmssource.js
@@ -15,6 +15,7 @@ goog.require('ol.TileCoord');
goog.require('ol.TileUrlFunction');
goog.require('ol.extent');
goog.require('ol.proj');
+goog.require('ol.size');
goog.require('ol.source.TileImage');
goog.require('ol.source.wms');
goog.require('ol.source.wms.ServerType');
@@ -148,11 +149,12 @@ ol.source.TileWMS.prototype.getGetFeatureInfoUrl =
var tileResolution = tileGrid.getResolution(tileCoord[0]);
var tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent_);
- var tileSize = tileGrid.getTileSize(tileCoord[0]);
+ var tileSize = ol.size.toSize(
+ tileGrid.getTileSize(tileCoord[0]), this.tmpSize);
var gutter = this.gutter_;
if (gutter !== 0) {
- tileSize += 2 * gutter;
+ tileSize = ol.size.buffer(tileSize, gutter, this.tmpSize);
tileExtent = ol.extent.buffer(tileExtent,
tileResolution * gutter, tileExtent);
}
@@ -207,7 +209,7 @@ ol.source.TileWMS.prototype.getParams = function() {
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
- * @param {number} tileSize Tile size.
+ * @param {ol.Size} tileSize Tile size.
* @param {ol.Extent} tileExtent Tile extent.
* @param {number} pixelRatio Pixel ratio.
* @param {ol.proj.Projection} projection Projection.
@@ -224,8 +226,8 @@ ol.source.TileWMS.prototype.getRequestUrl_ =
return undefined;
}
- params['WIDTH'] = tileSize;
- params['HEIGHT'] = tileSize;
+ params['WIDTH'] = tileSize[0];
+ params['HEIGHT'] = tileSize[1];
params[this.v13_ ? 'CRS' : 'SRS'] = projection.getCode();
@@ -282,7 +284,7 @@ ol.source.TileWMS.prototype.getRequestUrl_ =
* @param {number} z Z.
* @param {number} pixelRatio Pixel ratio.
* @param {ol.proj.Projection} projection Projection.
- * @return {number} Size.
+ * @return {ol.Size} Size.
*/
ol.source.TileWMS.prototype.getTilePixelSize =
function(z, pixelRatio, projection) {
@@ -290,7 +292,7 @@ ol.source.TileWMS.prototype.getTilePixelSize =
if (pixelRatio == 1 || !this.hidpi_ || !goog.isDef(this.serverType_)) {
return tileSize;
} else {
- return (tileSize * pixelRatio + 0.5) | 0;
+ return ol.size.scale(tileSize, pixelRatio, this.tmpSize);
}
};
@@ -372,17 +374,18 @@ ol.source.TileWMS.prototype.tileUrlFunction_ =
var tileResolution = tileGrid.getResolution(tileCoord[0]);
var tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent_);
- var tileSize = tileGrid.getTileSize(tileCoord[0]);
+ var tileSize = ol.size.toSize(
+ tileGrid.getTileSize(tileCoord[0]), this.tmpSize);
var gutter = this.gutter_;
if (gutter !== 0) {
- tileSize += 2 * gutter;
+ tileSize = ol.size.buffer(tileSize, gutter, this.tmpSize);
tileExtent = ol.extent.buffer(tileExtent,
tileResolution * gutter, tileExtent);
}
if (pixelRatio != 1) {
- tileSize = (tileSize * pixelRatio + 0.5) | 0;
+ tileSize = ol.size.scale(tileSize, pixelRatio, this.tmpSize);
}
var baseParams = {
diff --git a/src/ol/tilegrid/tilegrid.js b/src/ol/tilegrid/tilegrid.js
index ff0f894cff..b8a112e5b4 100644
--- a/src/ol/tilegrid/tilegrid.js
+++ b/src/ol/tilegrid/tilegrid.js
@@ -15,6 +15,7 @@ goog.require('ol.proj');
goog.require('ol.proj.METERS_PER_UNIT');
goog.require('ol.proj.Projection');
goog.require('ol.proj.Units');
+goog.require('ol.size');
goog.require('ol.tilecoord');
@@ -75,7 +76,7 @@ ol.tilegrid.TileGrid = function(options) {
/**
* @private
- * @type {Array.}
+ * @type {Array.}
*/
this.tileSizes_ = null;
if (goog.isDef(options.tileSizes)) {
@@ -86,16 +87,23 @@ ol.tilegrid.TileGrid = function(options) {
/**
* @private
- * @type {number|undefined}
+ * @type {number|ol.Size}
*/
this.tileSize_ = goog.isDef(options.tileSize) ?
options.tileSize :
- goog.isNull(this.tileSizes_) ? ol.DEFAULT_TILE_SIZE : undefined;
+ goog.isNull(this.tileSizes_) ? ol.DEFAULT_TILE_SIZE : null;
goog.asserts.assert(
- (!goog.isDef(this.tileSize_) && !goog.isNull(this.tileSizes_)) ||
- (goog.isDef(this.tileSize_) && goog.isNull(this.tileSizes_)),
+ (goog.isNull(this.tileSize_) && !goog.isNull(this.tileSizes_)) ||
+ (!goog.isNull(this.tileSize_) && goog.isNull(this.tileSizes_)),
'either tileSize or tileSizes must be configured, never both');
+
+ /**
+ * @private
+ * @type {ol.Size}
+ */
+ this.tmpSize_ = [0, 0];
+
/**
* @private
* @type {Array.}
@@ -245,11 +253,11 @@ ol.tilegrid.TileGrid.prototype.getTileRangeExtent =
function(z, tileRange, opt_extent) {
var origin = this.getOrigin(z);
var resolution = this.getResolution(z);
- var tileSize = this.getTileSize(z);
- var minX = origin[0] + tileRange.minX * tileSize * resolution;
- var maxX = origin[0] + (tileRange.maxX + 1) * tileSize * resolution;
- var minY = origin[1] + tileRange.minY * tileSize * resolution;
- var maxY = origin[1] + (tileRange.maxY + 1) * tileSize * resolution;
+ var tileSize = ol.size.toSize(this.getTileSize(z), this.tmpSize_);
+ var minX = origin[0] + tileRange.minX * tileSize[0] * resolution;
+ var maxX = origin[0] + (tileRange.maxX + 1) * tileSize[0] * resolution;
+ var minY = origin[1] + tileRange.minY * tileSize[1] * resolution;
+ var maxY = origin[1] + (tileRange.maxY + 1) * tileSize[1] * resolution;
return ol.extent.createOrUpdate(minX, minY, maxX, maxY, opt_extent);
};
@@ -295,10 +303,10 @@ ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndZ =
ol.tilegrid.TileGrid.prototype.getTileCoordCenter = function(tileCoord) {
var origin = this.getOrigin(tileCoord[0]);
var resolution = this.getResolution(tileCoord[0]);
- var tileSize = this.getTileSize(tileCoord[0]);
+ var tileSize = ol.size.toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);
return [
- origin[0] + (tileCoord[1] + 0.5) * tileSize * resolution,
- origin[1] + (tileCoord[2] + 0.5) * tileSize * resolution
+ origin[0] + (tileCoord[1] + 0.5) * tileSize[0] * resolution,
+ origin[1] + (tileCoord[2] + 0.5) * tileSize[1] * resolution
];
};
@@ -312,11 +320,11 @@ ol.tilegrid.TileGrid.prototype.getTileCoordExtent =
function(tileCoord, opt_extent) {
var origin = this.getOrigin(tileCoord[0]);
var resolution = this.getResolution(tileCoord[0]);
- var tileSize = this.getTileSize(tileCoord[0]);
- var minX = origin[0] + tileCoord[1] * tileSize * resolution;
- var minY = origin[1] + tileCoord[2] * tileSize * resolution;
- var maxX = minX + tileSize * resolution;
- var maxY = minY + tileSize * resolution;
+ var tileSize = ol.size.toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);
+ var minX = origin[0] + tileCoord[1] * tileSize[0] * resolution;
+ var minY = origin[1] + tileCoord[2] * tileSize[1] * resolution;
+ var maxX = minX + tileSize[0] * resolution;
+ var maxY = minY + tileSize[1] * resolution;
return ol.extent.createOrUpdate(minX, minY, maxX, maxY, opt_extent);
};
@@ -355,10 +363,10 @@ ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndResolution_ = function(
var z = this.getZForResolution(resolution);
var scale = resolution / this.getResolution(z);
var origin = this.getOrigin(z);
- var tileSize = this.getTileSize(z);
+ var tileSize = ol.size.toSize(this.getTileSize(z), this.tmpSize_);
- var tileCoordX = scale * (x - origin[0]) / (resolution * tileSize);
- var tileCoordY = scale * (y - origin[1]) / (resolution * tileSize);
+ var tileCoordX = scale * (x - origin[0]) / (resolution * tileSize[0]);
+ var tileCoordY = scale * (y - origin[1]) / (resolution * tileSize[1]);
if (reverseIntersectionPolicy) {
tileCoordX = Math.ceil(tileCoordX) - 1;
@@ -421,9 +429,10 @@ ol.tilegrid.TileGrid.prototype.getTileRange =
/**
- * Get the tile size for a zoom level.
+ * 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.
* @param {number} z Z.
- * @return {number} Tile size.
+ * @return {number|ol.Size} Tile size.
* @api stable
*/
ol.tilegrid.TileGrid.prototype.getTileSize = function(z) {
@@ -476,7 +485,7 @@ ol.tilegrid.TileGrid.prototype.isGlobal = function(z, projection) {
if (goog.isDef(width)) {
var projTileGrid = ol.tilegrid.getForProjection(projection);
var projExtent = projection.getExtent();
- return this.getTileSize(z) * width ==
+ return ol.size.toSize(this.getTileSize(z), this.tmpSize_)[0] * width ==
projTileGrid.getTileSize(z) *
projTileGrid.getTileRangeForExtentAndZ(projExtent, z).getWidth();
} else {
@@ -503,7 +512,8 @@ ol.tilegrid.getForProjection = function(projection) {
* @param {ol.Extent} extent Extent.
* @param {number=} opt_maxZoom Maximum zoom level (default is
* ol.DEFAULT_MAX_ZOOM).
- * @param {number=} opt_tileSize Tile size (default uses ol.DEFAULT_TILE_SIZE).
+ * @param {number|ol.Size=} opt_tileSize Tile size (default uses
+ * ol.DEFAULT_TILE_SIZE).
* @param {ol.extent.Corner=} opt_corner Extent corner (default is
* ol.extent.Corner.BOTTOM_LEFT).
* @return {ol.tilegrid.TileGrid} TileGrid instance.
@@ -511,24 +521,24 @@ ol.tilegrid.getForProjection = function(projection) {
ol.tilegrid.createForExtent =
function(extent, opt_maxZoom, opt_tileSize, opt_corner) {
var tileSize = goog.isDef(opt_tileSize) ?
- opt_tileSize : ol.DEFAULT_TILE_SIZE;
+ ol.size.toSize(opt_tileSize) : ol.tilegrid.DEFAULT_TILE_SIZE;
var corner = goog.isDef(opt_corner) ?
opt_corner : ol.extent.Corner.BOTTOM_LEFT;
var resolutions = ol.tilegrid.resolutionsFromExtent(
- extent, opt_maxZoom, tileSize);
+ extent, opt_maxZoom, ol.size.toSize(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];
+ widths[z] = extentWidth / tileSize[0] / resolutions[z];
}
return new ol.tilegrid.TileGrid({
origin: ol.extent.getCorner(extent, corner),
resolutions: resolutions,
- tileSize: tileSize,
+ tileSize: goog.isDef(opt_tileSize) ? opt_tileSize : ol.DEFAULT_TILE_SIZE,
widths: widths
});
};
@@ -539,7 +549,7 @@ ol.tilegrid.createForExtent =
* @param {ol.Extent} extent Extent.
* @param {number=} opt_maxZoom Maximum zoom level (default is
* ol.DEFAULT_MAX_ZOOM).
- * @param {number=} opt_tileSize Tile size (default uses ol.DEFAULT_TILE_SIZE).
+ * @param {ol.Size=} opt_tileSize Tile size (default uses ol.DEFAULT_TILE_SIZE).
* @return {!Array.} Resolutions array.
*/
ol.tilegrid.resolutionsFromExtent =
@@ -551,9 +561,9 @@ ol.tilegrid.resolutionsFromExtent =
var width = ol.extent.getWidth(extent);
var tileSize = goog.isDef(opt_tileSize) ?
- opt_tileSize : ol.DEFAULT_TILE_SIZE;
+ opt_tileSize : ol.tilegrid.DEFAULT_TILE_SIZE;
var maxResolution = Math.max(
- width / tileSize, height / tileSize);
+ width / tileSize[0], height / tileSize[1]);
var length = maxZoom + 1;
var resolutions = new Array(length);
@@ -568,7 +578,7 @@ ol.tilegrid.resolutionsFromExtent =
* @param {ol.proj.ProjectionLike} projection Projection.
* @param {number=} opt_maxZoom Maximum zoom level (default is
* ol.DEFAULT_MAX_ZOOM).
- * @param {number=} opt_tileSize Tile size (default uses ol.DEFAULT_TILE_SIZE).
+ * @param {ol.Size=} opt_tileSize Tile size (default uses ol.DEFAULT_TILE_SIZE).
* @param {ol.extent.Corner=} opt_corner Extent corner (default is
* ol.extent.Corner.BOTTOM_LEFT).
* @return {ol.tilegrid.TileGrid} TileGrid instance.
@@ -597,3 +607,10 @@ ol.tilegrid.extentFromProjection = function(projection) {
}
return extent;
};
+
+
+/**
+ * @const
+ * @type {ol.Size}
+ */
+ol.tilegrid.DEFAULT_TILE_SIZE = ol.size.toSize(ol.DEFAULT_TILE_SIZE);
diff --git a/src/ol/tilegrid/wmtstilegrid.js b/src/ol/tilegrid/wmtstilegrid.js
index 95e5d999c8..6770358784 100644
--- a/src/ol/tilegrid/wmtstilegrid.js
+++ b/src/ol/tilegrid/wmtstilegrid.js
@@ -81,7 +81,7 @@ ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
var matrixIds = [];
/** @type {!Array.} */
var origins = [];
- /** @type {!Array.} */
+ /** @type {!Array.} */
var tileSizes = [];
/** @type {!Array.} */
var widths = [];
@@ -118,10 +118,8 @@ ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
metersPerUnit);
var tileWidth = elt[tileWidthPropName];
var tileHeight = elt[tileHeightPropName];
- goog.asserts.assert(tileWidth == tileHeight,
- 'square tiles are assumed, tileWidth (%s) == tileHeight (%s)',
- tileWidth, tileHeight);
- tileSizes.push(tileWidth);
+ tileSizes.push(tileWidth == tileHeight ?
+ tileWidth : [tileWidth, tileHeight]);
widths.push(elt['MatrixWidth']);
});
diff --git a/src/ol/tilegrid/xyztilegrid.js b/src/ol/tilegrid/xyztilegrid.js
index 6fec56bcd6..b10a398c67 100644
--- a/src/ol/tilegrid/xyztilegrid.js
+++ b/src/ol/tilegrid/xyztilegrid.js
@@ -8,6 +8,7 @@ goog.require('ol.extent');
goog.require('ol.extent.Corner');
goog.require('ol.proj');
goog.require('ol.proj.EPSG3857');
+goog.require('ol.size');
goog.require('ol.tilecoord');
goog.require('ol.tilegrid.TileGrid');
@@ -26,8 +27,12 @@ goog.require('ol.tilegrid.TileGrid');
ol.tilegrid.XYZ = function(options) {
var extent = goog.isDef(options.extent) ?
options.extent : ol.proj.EPSG3857.EXTENT;
+ var tileSize;
+ if (goog.isDef(options.tileSize)) {
+ tileSize = ol.size.toSize(options.tileSize);
+ }
var resolutions = ol.tilegrid.resolutionsFromExtent(
- extent, options.maxZoom, options.tileSize);
+ extent, options.maxZoom, tileSize);
goog.base(this, {
minZoom: options.minZoom,
diff --git a/test/spec/ol/size.test.js b/test/spec/ol/size.test.js
new file mode 100644
index 0000000000..cd21e9d6b0
--- /dev/null
+++ b/test/spec/ol/size.test.js
@@ -0,0 +1,65 @@
+goog.provide('ol.test.size');
+
+
+describe('ol.size', function() {
+
+ describe('#buffer()', function() {
+
+ it('buffers a size', function() {
+ var size = [50, 75];
+ var bufferedSize = ol.size.buffer(size, 20);
+ expect(bufferedSize).to.eql([90, 115]);
+ });
+
+ it('reuses an existing array', function() {
+ var reuse = [0, 0];
+ var size = [50, 50];
+ var bufferedSize = ol.size.buffer(size, 20, reuse);
+ expect(bufferedSize).to.equal(reuse);
+ });
+
+ });
+
+ describe('#scale()', function() {
+
+ it('scales a size and rounds the result', function() {
+ var size = [50, 75];
+ var scaledSize = ol.size.scale(size, 1.75);
+ expect(scaledSize).to.eql([88, 131]);
+ });
+
+ it('reuses an existing array', function() {
+ var reuse = [0, 0];
+ var size = [50, 50];
+ var scaledSize = ol.size.scale(size, 1.75, reuse);
+ expect(scaledSize).to.equal(reuse);
+ });
+
+ });
+
+ describe('#toSize()', function() {
+
+ it('creates a size array from a number', function() {
+ var size = ol.size.toSize(512);
+ expect(size).to.eql([512, 512]);
+ });
+
+ it('reuses an existing array', function() {
+ var sizeArray = [0, 0];
+ var size = ol.size.toSize(512, sizeArray);
+ expect(size).to.equal(sizeArray);
+ });
+
+ it('returns a size array unaltered', function() {
+ var sizeArray = [512, 256];
+ var size = ol.size.toSize(sizeArray);
+ expect(size).to.equal(sizeArray);
+ size = ol.size.toSize(sizeArray, [0, 0]);
+ expect(size).to.equal(sizeArray);
+ });
+
+ });
+
+});
+
+goog.require('ol.size');
diff --git a/test/spec/ol/source/tilewmssource.test.js b/test/spec/ol/source/tilewmssource.test.js
index 069248be8e..8a5c547218 100644
--- a/test/spec/ol/source/tilewmssource.test.js
+++ b/test/spec/ol/source/tilewmssource.test.js
@@ -129,6 +129,21 @@ describe('ol.source.TileWMS', function() {
expect(queryData.get('BBOX')).to.be('-45,-45,0,0');
});
+ it('works with non-square tiles', function() {
+ options.tileGrid = new ol.tilegrid.TileGrid({
+ tileSize: [640, 320],
+ resolutions: [1.40625, 0.703125, 0.3515625, 0.17578125],
+ origin: [-180, -90]
+ });
+ var source = new ol.source.TileWMS(options);
+ var tileCoord = [3, 3, 1];
+ var url = source.tileUrlFunction(tileCoord, 1, ol.proj.get('EPSG:4326'));
+ var uri = new goog.Uri(url);
+ var queryData = uri.getQueryData();
+ expect(queryData.get('WIDTH')).to.be('640');
+ expect(queryData.get('HEIGHT')).to.be('320');
+ });
+
});
describe('#getGetFeatureInfo', function() {
@@ -205,3 +220,4 @@ goog.require('goog.Uri');
goog.require('ol.ImageTile');
goog.require('ol.source.TileWMS');
goog.require('ol.proj');
+goog.require('ol.tilegrid.TileGrid');