Merge pull request #3559 from ahocevar/tile-width-height

Add support for non-square tiles
This commit is contained in:
Andreas Hocevar
2015-04-16 09:26:27 +02:00
23 changed files with 444 additions and 121 deletions

View File

@@ -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
The return value of ´ol.tilegrid.TileGrid#getTileSize()` will now be an `ol.Size` array instead of a number if non-square tiles (i.e. an `ol.Size` array instead of a number as `tilsSize`) are used. To always get an `ol.Size`, the new `ol.size.toSize()` was added.
### v3.4.0
There should be nothing special required when upgrading from v3.3.0 to v3.4.0.

View File

@@ -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"
---
<div class="row-fluid">
<div class="span12">
<div id="map" class="map"></div>
</div>
</div>

View File

@@ -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
})
});

View File

@@ -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.<string>|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.<ol.Coordinate>|undefined),
* resolutions: !Array.<number>,
* tileSize: (number|undefined),
* tileSizes: (Array.<number>|undefined),
* tileSize: (number|ol.Size|undefined),
* tileSizes: (Array.<number|ol.Size>|undefined),
* widths: (Array.<number>|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.<number>|undefined}
* @type {Array.<number|ol.Size>|undefined}
* @api stable
*/
olx.tilegrid.TileGridOptions.prototype.tileSizes;
@@ -6001,8 +6001,8 @@ olx.tilegrid.TileGridOptions.prototype.widths;
* origins: (Array.<ol.Coordinate>|undefined),
* resolutions: !Array.<number>,
* matrixIds: !Array.<string>,
* tileSize: (number|undefined),
* tileSizes: (Array.<number>|undefined),
* tileSize: (number|ol.Size|undefined),
* tileSizes: (Array.<number|ol.Size>|undefined),
* widths: (Array.<number>|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.<number>|undefined}
* @type {Array.<number|ol.Size>|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;

View File

@@ -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.<number>} */
@@ -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 =

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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.<number>}
@@ -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,45 @@ 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;
};
/**
* Returns an `ol.Size` array for the passed in number (meaning: square) or
* `ol.Size` array.
* (meaning: non-square),
* @param {number|ol.Size} size Width and height.
* @param {ol.Size=} opt_size Optional reusable size array.
* @return {ol.Size} Size.
* @api stable
*/
ol.size.toSize = function(size, opt_size) {
if (goog.isArray(size)) {
return size;
} else {
goog.asserts.assert(goog.isNumber(size));
if (!goog.isDef(opt_size)) {
opt_size = [size, size];
} else {
opt_size[0] = size;
opt_size[1] = size;
}
return opt_size;
}
};

View File

@@ -107,7 +107,8 @@ ol.source.BingMaps.prototype.handleImageryMetadataResponse =
extent: ol.tilegrid.extentFromProjection(sourceProjection),
minZoom: resource.zoomMin,
maxZoom: maxZoom,
tileSize: resource.imageWidth
tileSize: resource.imageWidth == resource.imageHeight ?
resource.imageWidth : [resource.imageWidth, resource.imageHeight]
});
this.tileGrid = tileGrid;

View File

@@ -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.

View File

@@ -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;

View File

@@ -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);
};

View File

@@ -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 = {

View File

@@ -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.<number>}
* @type {Array.<number|ol.Size>}
*/
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.<number>}
@@ -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,11 @@ 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. To always
* get an `ol.Size`, run the result through `ol.size.toSize()`.
* @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 +486,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 +513,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 +522,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.size.toSize(ol.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 +550,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.<number>} Resolutions array.
*/
ol.tilegrid.resolutionsFromExtent =
@@ -551,9 +562,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.size.toSize(ol.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 +579,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.

View File

@@ -81,7 +81,7 @@ ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
var matrixIds = [];
/** @type {!Array.<ol.Coordinate>} */
var origins = [];
/** @type {!Array.<number>} */
/** @type {!Array.<ol.Size>} */
var tileSizes = [];
/** @type {!Array.<number>} */
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']);
});

View File

@@ -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,

65
test/spec/ol/size.test.js Normal file
View File

@@ -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');

View File

@@ -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');

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

View File

@@ -4,14 +4,14 @@ describe('ol.rendering.layer.Tile', function() {
var target, map;
function createMap(renderer) {
function createMap(renderer, opt_center) {
target = createMapDiv(50, 50);
map = new ol.Map({
target: target,
renderer: renderer,
view: new ol.View({
center: ol.proj.transform(
center: goog.isDef(opt_center) ? opt_center : ol.proj.transform(
[-122.416667, 37.783333], 'EPSG:4326', 'EPSG:3857'),
zoom: 5
})
@@ -144,6 +144,50 @@ describe('ol.rendering.layer.Tile', function() {
});
});
});
describe('tile layer with non-square tiles', function() {
var source;
beforeEach(function() {
source = new ol.source.TileImage({
tileUrlFunction: function(tileCoord, ratio, projection) {
return 'spec/ol/data/tiles/512x256/' + tileCoord[0] + '/' +
tileCoord[1] + '/' + tileCoord[2] + '.png';
},
tileGrid: new ol.tilegrid.TileGrid({
origin: [-20037508.342789244, -20037508.342789244],
resolutions: [
156543.03392804097, 78271.51696402048, 39135.75848201024,
19567.87924100512, 9783.93962050256, 4891.96981025128
],
tileSize: [512, 256]
})
});
});
afterEach(function() {
disposeMap(map);
});
it('renders correcly using the canvas renderer', function(done) {
map = createMap('canvas', [-10997148, 4569099]);
waitForTiles([source], {}, function() {
expectResemble(map, 'spec/ol/layer/expected/512x256-canvas.png',
IMAGE_TOLERANCE, done);
});
});
it('renders correcly using the webgl renderer', function(done) {
assertWebGL();
map = createMap('webgl', [-10997148, 4569099]);
waitForTiles([source], {}, function() {
expectResemble(map, 'spec/ol/layer/expected/512x256-webgl.png',
IMAGE_TOLERANCE, done);
});
});
});
});
goog.require('goog.array');
@@ -152,4 +196,6 @@ goog.require('ol.proj');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.layer.Tile');
goog.require('ol.source.TileImage');
goog.require('ol.source.XYZ');
goog.require('ol.tilegrid.TileGrid');