From 2b753410684ca6a3b49d1eb439b9fb205662e3d1 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Tue, 14 Apr 2015 22:54:57 +0200 Subject: [PATCH] Add support for non-square tiles --- changelog/upgrade-notes.md | 4 + examples_src/wms-custom-tilegrid-512x256.html | 13 +++ examples_src/wms-custom-tilegrid-512x256.js | 44 ++++++++++ externs/olx.js | 30 +++---- .../canvas/canvastilelayerrenderer.js | 54 +++++++----- src/ol/renderer/dom/domtilelayerrenderer.js | 26 ++++-- src/ol/renderer/webgl/webglmaprenderer.js | 26 ++++-- .../renderer/webgl/webgltilelayerrenderer.js | 19 ++++- src/ol/size.js | 57 +++++++++++++ src/ol/source/bingmapssource.js | 2 +- src/ol/source/tilearcgisrestsource.js | 14 ++-- src/ol/source/tiledebugsource.js | 12 +-- src/ol/source/tilesource.js | 12 ++- src/ol/source/tilewmssource.js | 23 ++--- src/ol/tilegrid/tilegrid.js | 83 +++++++++++-------- src/ol/tilegrid/wmtstilegrid.js | 8 +- src/ol/tilegrid/xyztilegrid.js | 7 +- test/spec/ol/size.test.js | 65 +++++++++++++++ test/spec/ol/source/tilewmssource.test.js | 16 ++++ 19 files changed, 396 insertions(+), 119 deletions(-) create mode 100644 examples_src/wms-custom-tilegrid-512x256.html create mode 100644 examples_src/wms-custom-tilegrid-512x256.js create mode 100644 test/spec/ol/size.test.js 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');