Use top-left corner of extent for all generated tile grids

This commit is contained in:
Andreas Hocevar
2015-06-18 09:47:53 +02:00
parent e3a8dc89de
commit a753d282cc
7 changed files with 99 additions and 66 deletions

View File

@@ -74,7 +74,7 @@ ol.tilegrid.TileGrid = function(options) {
if (goog.isDef(extent) &&
goog.isNull(this.origin_) && goog.isNull(this.origins_)) {
this.origin_ = ol.extent.getBottomLeft(extent);
this.origin_ = ol.extent.getTopLeft(extent);
}
goog.asserts.assert(
@@ -527,13 +527,13 @@ ol.tilegrid.getForProjection = function(projection) {
* @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).
* ol.extent.Corner.TOP_LEFT).
* @return {ol.tilegrid.TileGrid} TileGrid instance.
*/
ol.tilegrid.createForExtent =
function(extent, opt_maxZoom, opt_tileSize, opt_corner) {
var corner = goog.isDef(opt_corner) ?
opt_corner : ol.extent.Corner.BOTTOM_LEFT;
opt_corner : ol.extent.Corner.TOP_LEFT;
var resolutions = ol.tilegrid.resolutionsFromExtent(
extent, opt_maxZoom, opt_tileSize);

View File

@@ -15,7 +15,7 @@ describe('ol.source.TileArcGISRest', function() {
it('returns a tile with the expected URL', function() {
var source = new ol.source.TileArcGISRest(options);
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:3857'));
var tile = source.getTile(3, 2, -7, 1, ol.proj.get('EPSG:3857'));
expect(tile).to.be.an(ol.ImageTile);
var uri = new goog.Uri(tile.src_);
expect(uri.getScheme()).to.be('http');
@@ -23,8 +23,8 @@ describe('ol.source.TileArcGISRest', function() {
expect(uri.getPath()).to.be('/MapServer/export');
var queryData = uri.getQueryData();
expect(queryData.get('BBOX')).to.be(
'-10018754.171394622,-15028131.257091932,' +
'-5009377.085697311,-10018754.17139462');
'-10018754.171394622,-15028131.257091936,' +
'-5009377.085697311,-10018754.171394624');
expect(queryData.get('FORMAT')).to.be('PNG32');
expect(queryData.get('SIZE')).to.be('256,256');
expect(queryData.get('IMAGESR')).to.be('3857');
@@ -39,7 +39,7 @@ describe('ol.source.TileArcGISRest', function() {
'http://test2.com/MapServer'];
var source = new ol.source.TileArcGISRest(options);
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:3857'));
var tile = source.getTile(3, 2, -7, 1, ol.proj.get('EPSG:3857'));
expect(tile).to.be.an(ol.ImageTile);
var uri = new goog.Uri(tile.src_);
expect(uri.getScheme()).to.be('http');
@@ -47,8 +47,8 @@ describe('ol.source.TileArcGISRest', function() {
expect(uri.getPath()).to.be('/MapServer/export');
var queryData = uri.getQueryData();
expect(queryData.get('BBOX')).to.be(
'-10018754.171394622,-15028131.257091932,' +
'-5009377.085697311,-10018754.17139462');
'-10018754.171394622,-15028131.257091936,' +
'-5009377.085697311,-10018754.171394624');
expect(queryData.get('FORMAT')).to.be('PNG32');
expect(queryData.get('SIZE')).to.be('256,256');
expect(queryData.get('IMAGESR')).to.be('3857');
@@ -60,7 +60,7 @@ describe('ol.source.TileArcGISRest', function() {
it('returns a tile with the expected URL for ImageServer', function() {
options.url = 'http://example.com/ImageServer';
var source = new ol.source.TileArcGISRest(options);
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:3857'));
var tile = source.getTile(3, 2, -7, 1, ol.proj.get('EPSG:3857'));
expect(tile).to.be.an(ol.ImageTile);
var uri = new goog.Uri(tile.src_);
expect(uri.getScheme()).to.be('http');
@@ -68,8 +68,8 @@ describe('ol.source.TileArcGISRest', function() {
expect(uri.getPath()).to.be('/ImageServer/exportImage');
var queryData = uri.getQueryData();
expect(queryData.get('BBOX')).to.be(
'-10018754.171394622,-15028131.257091932,' +
'-5009377.085697311,-10018754.17139462');
'-10018754.171394622,-15028131.257091936,' +
'-5009377.085697311,-10018754.171394624');
expect(queryData.get('FORMAT')).to.be('PNG32');
expect(queryData.get('SIZE')).to.be('256,256');
expect(queryData.get('IMAGESR')).to.be('3857');
@@ -81,7 +81,7 @@ describe('ol.source.TileArcGISRest', function() {
options.params.FORMAT = 'png';
options.params.TRANSPARENT = false;
var source = new ol.source.TileArcGISRest(options);
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:4326'));
var tile = source.getTile(3, 2, -3, 1, ol.proj.get('EPSG:4326'));
var uri = new goog.Uri(tile.src_);
var queryData = uri.getQueryData();
expect(queryData.get('FORMAT')).to.be('png');
@@ -91,7 +91,7 @@ describe('ol.source.TileArcGISRest', function() {
it('allows adding rest option', function() {
options.params.LAYERS = 'show:1,3,4';
var source = new ol.source.TileArcGISRest(options);
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:4326'));
var tile = source.getTile(3, 2, -3, 1, ol.proj.get('EPSG:4326'));
var uri = new goog.Uri(tile.src_);
var queryData = uri.getQueryData();
expect(queryData.get('LAYERS')).to.be('show:1,3,4');
@@ -104,7 +104,7 @@ describe('ol.source.TileArcGISRest', function() {
var source = new ol.source.TileArcGISRest(options);
source.updateParams({ 'TEST': 'value' });
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:3857'));
var tile = source.getTile(3, 2, -7, 1, ol.proj.get('EPSG:3857'));
var uri = new goog.Uri(tile.src_);
var queryData = uri.getQueryData();
@@ -117,7 +117,7 @@ describe('ol.source.TileArcGISRest', function() {
var source = new ol.source.TileArcGISRest(options);
source.updateParams({ 'TEST': 'newValue' });
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:3857'));
var tile = source.getTile(3, 2, -7, 1, ol.proj.get('EPSG:3857'));
var uri = new goog.Uri(tile.src_);
var queryData = uri.getQueryData();

View File

@@ -123,14 +123,14 @@ describe('ol.source.Tile', function() {
wrapX: true
});
var tileCoord = tileSource.getTileCoordForTileUrlFunction([6, -31, 22]);
expect(tileCoord).to.eql([6, 33, 22]);
var tileCoord = tileSource.getTileCoordForTileUrlFunction([6, -31, -23]);
expect(tileCoord).to.eql([6, 33, -23]);
tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 33, 22]);
expect(tileCoord).to.eql([6, 33, 22]);
tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 33, -23]);
expect(tileCoord).to.eql([6, 33, -23]);
tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 97, 22]);
expect(tileCoord).to.eql([6, 33, 22]);
tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 97, -23]);
expect(tileCoord).to.eql([6, 33, -23]);
});
it('returns the expected tile coordinate - {wrapX: false}', function() {
@@ -139,13 +139,13 @@ describe('ol.source.Tile', function() {
wrapX: false
});
var tileCoord = tileSource.getTileCoordForTileUrlFunction([6, -31, 22]);
var tileCoord = tileSource.getTileCoordForTileUrlFunction([6, -31, -23]);
expect(tileCoord).to.eql(null);
tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 33, 22]);
expect(tileCoord).to.eql([6, 33, 22]);
tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 33, -23]);
expect(tileCoord).to.eql([6, 33, -23]);
tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 97, 22]);
tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 97, -23]);
expect(tileCoord).to.eql(null);
});
});

View File

@@ -17,7 +17,7 @@ describe('ol.source.TileWMS', function() {
it('returns a tile with the expected URL', function() {
var source = new ol.source.TileWMS(options);
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:3857'));
var tile = source.getTile(3, 2, -7, 1, ol.proj.get('EPSG:3857'));
expect(tile).to.be.an(ol.ImageTile);
var uri = new goog.Uri(tile.src_);
expect(uri.getScheme()).to.be('http');
@@ -25,8 +25,8 @@ describe('ol.source.TileWMS', function() {
expect(uri.getPath()).to.be('/wms');
var queryData = uri.getQueryData();
expect(queryData.get('BBOX')).to.be(
'-10018754.171394622,-15028131.257091932,' +
'-5009377.085697311,-10018754.17139462');
'-10018754.171394622,-15028131.257091936,' +
'-5009377.085697311,-10018754.171394624');
expect(queryData.get('CRS')).to.be('EPSG:3857');
expect(queryData.get('FORMAT')).to.be('image/png');
expect(queryData.get('HEIGHT')).to.be('256');
@@ -44,13 +44,13 @@ describe('ol.source.TileWMS', function() {
it('returns a larger tile when a gutter is specified', function() {
options.gutter = 16;
var source = new ol.source.TileWMS(options);
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:3857'));
var tile = source.getTile(3, 2, -7, 1, ol.proj.get('EPSG:3857'));
expect(tile).to.be.an(ol.ImageTile);
var uri = new goog.Uri(tile.src_);
var queryData = uri.getQueryData();
var bbox = queryData.get('BBOX').split(',');
var expected = [-10331840.239250705, -15341217.324948015,
-4696291.017841229, -9705668.103538537];
var expected = [-10331840.239250705, -15341217.324948018,
-4696291.017841229, -9705668.103538541];
for (var i = 0, ii = bbox.length; i < ii; ++i) {
expect(parseFloat(bbox[i])).to.roughlyEqual(expected[i], 1e-9);
}
@@ -61,7 +61,7 @@ describe('ol.source.TileWMS', function() {
it('sets the SRS query value instead of CRS if version < 1.3', function() {
options.params.VERSION = '1.2';
var source = new ol.source.TileWMS(options);
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:4326'));
var tile = source.getTile(3, 2, -3, 1, ol.proj.get('EPSG:4326'));
var uri = new goog.Uri(tile.src_);
var queryData = uri.getQueryData();
expect(queryData.get('CRS')).to.be(undefined);
@@ -72,7 +72,7 @@ describe('ol.source.TileWMS', function() {
options.params.FORMAT = 'image/jpeg';
options.params.TRANSPARENT = false;
var source = new ol.source.TileWMS(options);
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:4326'));
var tile = source.getTile(3, 2, -3, 1, ol.proj.get('EPSG:4326'));
var uri = new goog.Uri(tile.src_);
var queryData = uri.getQueryData();
expect(queryData.get('FORMAT')).to.be('image/jpeg');
@@ -82,7 +82,7 @@ describe('ol.source.TileWMS', function() {
it('does not add a STYLES= option if one is specified', function() {
options.params.STYLES = 'foo';
var source = new ol.source.TileWMS(options);
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:4326'));
var tile = source.getTile(3, 2, -3, 1, ol.proj.get('EPSG:4326'));
var uri = new goog.Uri(tile.src_);
var queryData = uri.getQueryData();
expect(queryData.get('STYLES')).to.be('foo');
@@ -90,7 +90,7 @@ describe('ol.source.TileWMS', function() {
it('changes the BBOX order for EN axis orientations', function() {
var source = new ol.source.TileWMS(options);
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('EPSG:4326'));
var tile = source.getTile(3, 2, -3, 1, ol.proj.get('EPSG:4326'));
var uri = new goog.Uri(tile.src_);
var queryData = uri.getQueryData();
expect(queryData.get('BBOX')).to.be('-45,-90,0,-45');
@@ -99,7 +99,7 @@ describe('ol.source.TileWMS', function() {
it('uses EN BBOX order if version < 1.3', function() {
options.params.VERSION = '1.1.0';
var source = new ol.source.TileWMS(options);
var tile = source.getTile(3, 2, 1, 1, ol.proj.get('CRS:84'));
var tile = source.getTile(3, 2, -3, 1, ol.proj.get('CRS:84'));
var uri = new goog.Uri(tile.src_);
var queryData = uri.getQueryData();
expect(queryData.get('BBOX')).to.be('-90,-45,-45,0');
@@ -108,7 +108,7 @@ describe('ol.source.TileWMS', function() {
it('sets FORMAT_OPTIONS when the server is GeoServer', function() {
options.serverType = ol.source.wms.ServerType.GEOSERVER;
var source = new ol.source.TileWMS(options);
var tile = source.getTile(3, 2, 1, 2, ol.proj.get('CRS:84'));
var tile = source.getTile(3, 2, -3, 2, ol.proj.get('CRS:84'));
var uri = new goog.Uri(tile.src_);
var queryData = uri.getQueryData();
expect(queryData.get('FORMAT_OPTIONS')).to.be('dpi:180');
@@ -118,7 +118,7 @@ describe('ol.source.TileWMS', function() {
options.serverType = ol.source.wms.ServerType.GEOSERVER;
var source = new ol.source.TileWMS(options);
options.params.FORMAT_OPTIONS = 'param1:value1';
var tile = source.getTile(3, 2, 1, 2, ol.proj.get('CRS:84'));
var tile = source.getTile(3, 2, -3, 2, ol.proj.get('CRS:84'));
var uri = new goog.Uri(tile.src_);
var queryData = uri.getQueryData();
expect(queryData.get('FORMAT_OPTIONS')).to.be('param1:value1;dpi:180');
@@ -128,7 +128,7 @@ describe('ol.source.TileWMS', function() {
function() {
options.serverType = ol.source.wms.ServerType.GEOSERVER;
var source = new ol.source.TileWMS(options);
var tile = source.getTile(3, 2, 1, 1.325, ol.proj.get('CRS:84'));
var tile = source.getTile(3, 2, -3, 1.325, ol.proj.get('CRS:84'));
var uri = new goog.Uri(tile.src_);
var queryData = uri.getQueryData();
expect(queryData.get('FORMAT_OPTIONS')).to.be('dpi:119');
@@ -141,7 +141,7 @@ describe('ol.source.TileWMS', function() {
it('returns a tile if it is contained within layers extent', function() {
options.extent = [-80, -40, -50, -10];
var source = new ol.source.TileWMS(options);
var tileCoord = [3, 2, 1];
var tileCoord = [3, 2, -3];
var url = source.tileUrlFunction(tileCoord, 1, ol.proj.get('EPSG:4326'));
var uri = new goog.Uri(url);
var queryData = uri.getQueryData();
@@ -151,7 +151,7 @@ describe('ol.source.TileWMS', function() {
it('returns a tile if it intersects layers extent', function() {
options.extent = [-80, -40, -40, -10];
var source = new ol.source.TileWMS(options);
var tileCoord = [3, 3, 1];
var tileCoord = [3, 3, -3];
var url = source.tileUrlFunction(tileCoord, 1, ol.proj.get('EPSG:4326'));
var uri = new goog.Uri(url);
var queryData = uri.getQueryData();
@@ -165,7 +165,7 @@ describe('ol.source.TileWMS', function() {
origin: [-180, -90]
});
var source = new ol.source.TileWMS(options);
var tileCoord = [3, 3, 1];
var tileCoord = [3, 3, -3];
var url = source.tileUrlFunction(tileCoord, 1, ol.proj.get('EPSG:4326'));
var uri = new goog.Uri(url);
var queryData = uri.getQueryData();
@@ -190,8 +190,8 @@ describe('ol.source.TileWMS', function() {
expect(uri.getPath()).to.be('/wms');
var queryData = uri.getQueryData();
expect(queryData.get('BBOX')).to.be(
'-10018754.171394622,-15028131.257091932,' +
'-5009377.085697311,-10018754.17139462');
'-10018754.171394622,-15028131.257091936,' +
'-5009377.085697311,-10018754.171394624');
expect(queryData.get('CRS')).to.be('EPSG:3857');
expect(queryData.get('FORMAT')).to.be('image/png');
expect(queryData.get('HEIGHT')).to.be('256');
@@ -222,8 +222,8 @@ describe('ol.source.TileWMS', function() {
expect(uri.getPath()).to.be('/wms');
var queryData = uri.getQueryData();
expect(queryData.get('BBOX')).to.be(
'-10018754.171394622,-15028131.257091932,' +
'-5009377.085697311,-10018754.17139462');
'-10018754.171394622,-15028131.257091936,' +
'-5009377.085697311,-10018754.171394624');
expect(queryData.get('CRS')).to.be('EPSG:3857');
expect(queryData.get('FORMAT')).to.be('image/png');
expect(queryData.get('HEIGHT')).to.be('256');

View File

@@ -47,21 +47,21 @@ describe('ol.TileCoord', function() {
resolutions: [2, 1],
minZoom: 1
});
expect(ol.tilecoord.withinExtentAndZ([0, 0, 0], tileGrid)).to.be(false);
expect(ol.tilecoord.withinExtentAndZ([1, 0, 0], tileGrid)).to.be(true);
expect(ol.tilecoord.withinExtentAndZ([2, 0, 0], tileGrid)).to.be(false);
expect(ol.tilecoord.withinExtentAndZ([0, 0, -1], tileGrid)).to.be(false);
expect(ol.tilecoord.withinExtentAndZ([1, 0, -1], tileGrid)).to.be(true);
expect(ol.tilecoord.withinExtentAndZ([2, 0, -1], tileGrid)).to.be(false);
});
it('restricts by extent when extent defines tile ranges', function() {
var tileGrid = new ol.tilegrid.TileGrid({
extent: [10, 20, 30, 40],
sizes: [[3, 3]],
sizes: [[3, -3]],
tileSize: 10,
resolutions: [1]
});
expect(ol.tilecoord.withinExtentAndZ([0, 1, 1], tileGrid)).to.be(true);
expect(ol.tilecoord.withinExtentAndZ([0, 2, 0], tileGrid)).to.be(false);
expect(ol.tilecoord.withinExtentAndZ([0, 0, 2], tileGrid)).to.be(false);
expect(ol.tilecoord.withinExtentAndZ([0, 1, -2], tileGrid)).to.be(true);
expect(ol.tilecoord.withinExtentAndZ([0, 2, -1], tileGrid)).to.be(false);
expect(ol.tilecoord.withinExtentAndZ([0, 0, -3], tileGrid)).to.be(false);
});
it('restricts by extent when sizes define tile ranges', function() {
@@ -79,6 +79,21 @@ describe('ol.TileCoord', function() {
expect(ol.tilecoord.withinExtentAndZ([0, 0, 3], tileGrid)).to.be(false);
});
it('restricts by extent when sizes (neg y) define tile ranges', function() {
var tileGrid = new ol.tilegrid.TileGrid({
origin: [10, 40],
sizes: [[3, -3]],
tileSize: 10,
resolutions: [1]
});
expect(ol.tilecoord.withinExtentAndZ([0, 0, -1], tileGrid)).to.be(true);
expect(ol.tilecoord.withinExtentAndZ([0, -1, -1], tileGrid)).to.be(false);
expect(ol.tilecoord.withinExtentAndZ([0, 0, 0], tileGrid)).to.be(false);
expect(ol.tilecoord.withinExtentAndZ([0, 2, -3], tileGrid)).to.be(true);
expect(ol.tilecoord.withinExtentAndZ([0, 3, -1], tileGrid)).to.be(false);
expect(ol.tilecoord.withinExtentAndZ([0, 0, -4], tileGrid)).to.be(false);
});
it('does not restrict by extent with no extent or sizes', function() {
var tileGrid = new ol.tilegrid.TileGrid({
origin: [10, 20],

View File

@@ -205,16 +205,16 @@ describe('ol.tilegrid.TileGrid', function() {
});
});
it('assumes bottom left corner of extent as origin', function() {
expect(tileGrid.getOrigin()).to.eql([10, 20]);
it('assumes top left corner of extent as origin', function() {
expect(tileGrid.getOrigin()).to.eql([10, 40]);
});
it('calculates full tile ranges from extent', function() {
var fullTileRange = tileGrid.getFullTileRange(0);
expect(fullTileRange.minX).to.equal(0);
expect(fullTileRange.maxX).to.equal(1);
expect(fullTileRange.minY).to.equal(0);
expect(fullTileRange.maxY).to.equal(1);
expect(fullTileRange.minY).to.equal(-2);
expect(fullTileRange.maxY).to.equal(-1);
});
});
@@ -223,7 +223,7 @@ describe('ol.tilegrid.TileGrid', function() {
beforeEach(function() {
tileGrid = new ol.tilegrid.TileGrid({
extent: [10, 20, 30, 40],
sizes: [[3, 3]],
sizes: [[3, -3]],
tileSize: 10,
resolutions: [1]
});
@@ -237,8 +237,8 @@ describe('ol.tilegrid.TileGrid', function() {
var fullTileRange = tileGrid.getFullTileRange(0);
expect(fullTileRange.minX).to.equal(0);
expect(fullTileRange.maxX).to.equal(2);
expect(fullTileRange.minY).to.equal(0);
expect(fullTileRange.maxY).to.equal(2);
expect(fullTileRange.minY).to.equal(-3);
expect(fullTileRange.maxY).to.equal(-1);
});
});
@@ -253,13 +253,31 @@ describe('ol.tilegrid.TileGrid', function() {
});
});
it('calculates correct minX and maxX for negative heights', function() {
it('calculates correct minY and maxY for negative heights', function() {
var fullTileRange = tileGrid.getFullTileRange(0);
expect(fullTileRange.minY).to.equal(-3);
expect(fullTileRange.maxY).to.equal(-1);
});
});
describe('create with bottom-left origin and sizes', function() {
var tileGrid;
beforeEach(function() {
tileGrid = new ol.tilegrid.TileGrid({
origin: [10, 10],
sizes: [[3, 3]],
tileSize: 10,
resolutions: [1]
});
});
it('calculates correct minX and maxX for positive heights', function() {
var fullTileRange = tileGrid.getFullTileRange(0);
expect(fullTileRange.minY).to.equal(0);
expect(fullTileRange.maxY).to.equal(2);
});
});
describe('create with extent and origin', function() {
it('uses both origin and extent', function() {
var tileGrid = new ol.tilegrid.TileGrid({
@@ -281,7 +299,7 @@ describe('ol.tilegrid.TileGrid', function() {
var resolutions = grid.getResolutions();
expect(resolutions.length).to.be(ol.DEFAULT_MAX_ZOOM + 1);
expect(grid.getOrigin()).to.eql([-100, -100]);
expect(grid.getOrigin()).to.eql([-100, 100]);
});
});
@@ -324,12 +342,12 @@ describe('ol.tilegrid.TileGrid', function() {
ol.DEFAULT_TILE_SIZE / Math.pow(2, 5));
});
it('assumes origin is bottom-left', function() {
it('assumes origin is top-left', function() {
var projection = ol.proj.get('EPSG:3857');
var grid = ol.tilegrid.createForProjection(projection);
var origin = grid.getOrigin();
var half = ol.proj.EPSG3857.HALF_SIZE;
expect(origin).to.eql([-half, -half]);
expect(origin).to.eql([-half, half]);
});
it('accepts bottom-left as corner', function() {

View File

@@ -56,7 +56,7 @@ describe('ol.rendering.layer.Image', function() {
source = new ol.source.ImageStatic({
url: 'spec/ol/data/tiles/osm/5/5/12.png',
imageExtent: ol.tilegrid.createXYZ().getTileCoordExtent(
[5, 5, 32 - 12 - 1]),
[5, 5, -12 - 1]),
projection: ol.proj.get('EPSG:3857')
});
});