From 1416e30127d8b545aea13136e03f289d3306cef1 Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Sun, 16 Feb 2020 17:14:31 +0000 Subject: [PATCH] Add maxResolution option to createXYZ() include maxResolution in options test --- examples/xyz-esri-4326-512.html | 2 +- examples/xyz-esri-4326-512.js | 18 +++++------------- src/ol/source/VectorTile.js | 8 +++++--- src/ol/source/XYZ.js | 9 ++++++--- src/ol/tilegrid.js | 15 +++++++++------ test/spec/ol/tilegrid/tilegrid.test.js | 3 ++- 6 files changed, 28 insertions(+), 27 deletions(-) diff --git a/examples/xyz-esri-4326-512.html b/examples/xyz-esri-4326-512.html index 94225e4c71..7b467116e3 100644 --- a/examples/xyz-esri-4326-512.html +++ b/examples/xyz-esri-4326-512.html @@ -3,7 +3,7 @@ layout: example.html title: ArcGIS REST with 512x512 Tiles shortdesc: Example of a XYZ source in EPSG:4326 using Esri 512x512 tiles. docs: > - ArcGIS REST tile services with custom tile sizes (here: 512x512 pixels) and projection (here: EPSG:4326) are supported by `ol/source/XYZ`. A custom tile url function is used to handle zoom level offsets. + ArcGIS REST tile services with custom tile sizes (here: 512x512 pixels) and projection (here: EPSG:4326) are supported by `ol/source/XYZ`. tags: "xyz, esri, tilesize, custom projection" ---
diff --git a/examples/xyz-esri-4326-512.js b/examples/xyz-esri-4326-512.js index 2edc9d1ba0..407e2e3e6e 100644 --- a/examples/xyz-esri-4326-512.js +++ b/examples/xyz-esri-4326-512.js @@ -3,26 +3,18 @@ import View from '../src/ol/View.js'; import TileLayer from '../src/ol/layer/Tile.js'; import XYZ from '../src/ol/source/XYZ.js'; -// The tile size supported by the ArcGIS tile service. -const tileSize = 512; - -const urlTemplate = 'https://services.arcgisonline.com/arcgis/rest/services/' + - 'ESRI_Imagery_World_2D/MapServer/tile/{z}/{y}/{x}'; - const map = new Map({ target: 'map', layers: [ new TileLayer({ source: new XYZ({ attributions: 'Copyright:© 2013 ESRI, i-cubed, GeoEye', - maxZoom: 16, + url: 'https://services.arcgisonline.com/arcgis/rest/services/' + + 'ESRI_Imagery_World_2D/MapServer/tile/{z}/{y}/{x}', + maxZoom: 15, projection: 'EPSG:4326', - tileSize: tileSize, - tileUrlFunction: function(tileCoord) { - return urlTemplate.replace('{z}', (tileCoord[0] - 1).toString()) - .replace('{x}', tileCoord[1].toString()) - .replace('{y}', tileCoord[2].toString()); - }, + tileSize: 512, // the tile size supported by the ArcGIS tile service + maxResolution: 180 / 512, // Esri's tile grid fits 180 degrees on one 512 px tile wrapX: true }) }) diff --git a/src/ol/source/VectorTile.js b/src/ol/source/VectorTile.js index c4ac79a917..737883fadb 100644 --- a/src/ol/source/VectorTile.js +++ b/src/ol/source/VectorTile.js @@ -30,9 +30,10 @@ import TileCache from '../TileCache.js'; * @property {import("./State.js").default} [state] Source state. * @property {typeof import("../VectorTile.js").default} [tileClass] Class used to instantiate image tiles. * Default is {@link module:ol/VectorTile}. - * @property {number} [maxZoom=22] Optional max zoom level. - * @property {number} [minZoom] Optional min zoom level. - * @property {number|import("../size.js").Size} [tileSize=512] Optional tile size. + * @property {number} [maxZoom=22] Optional max zoom level. Not used if `tileGrid` is provided. + * @property {number} [minZoom] Optional min zoom level. Not used if `tileGrid` is provided. + * @property {number|import("../size.js").Size} [tileSize=512] Optional tile size. Not used if `tileGrid` is provided. + * @property {number} [maxResolution] Optional tile grid resolution at level zero. Not used if `tileGrid` is provided. * @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid. * @property {import("../Tile.js").LoadFunction} [tileLoadFunction] * Optional function to load a tile given a URL. Could look like this for pbf tiles: @@ -105,6 +106,7 @@ class VectorTile extends UrlTile { const tileGrid = options.tileGrid || createXYZ({ extent: extent, + maxResolution: options.maxResolution, maxZoom: options.maxZoom !== undefined ? options.maxZoom : 22, minZoom: options.minZoom, tileSize: options.tileSize || 512 diff --git a/src/ol/source/XYZ.js b/src/ol/source/XYZ.js index 6c550057a5..638bf5eb24 100644 --- a/src/ol/source/XYZ.js +++ b/src/ol/source/XYZ.js @@ -17,8 +17,9 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js'; * @property {import("../proj.js").ProjectionLike} [projection='EPSG:3857'] Projection. * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels). * Higher values can increase reprojection performance, but decrease precision. - * @property {number} [maxZoom=18] Optional max zoom level. - * @property {number} [minZoom=0] Optional min zoom level. + * @property {number} [maxZoom=42] Optional max zoom level. Not used if `tileGrid` is provided. + * @property {number} [minZoom=0] Optional min zoom level. Not used if `tileGrid` is provided. + * @property {number} [maxResolution] Optional tile grid resolution at level zero. Not used if `tileGrid` is provided. * @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid. * @property {import("../Tile.js").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is * ```js @@ -31,9 +32,10 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js'; * by 512px images (for retina/hidpi devices) then `tilePixelRatio` * should be set to `2`. * @property {number|import("../size.js").Size} [tileSize=[256, 256]] The tile size used by the tile service. + * Not used if `tileGrid` is provided. * @property {import("../Tile.js").UrlFunction} [tileUrlFunction] Optional function to get * tile URL given a tile coordinate and the projection. - * Required if url or urls are not provided. + * Required if `url` or `urls` are not provided. * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`, * and `{z}` placeholders. A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`, * may be used instead of defining each one separately in the `urls` option. @@ -78,6 +80,7 @@ class XYZ extends TileImage { const tileGrid = options.tileGrid !== undefined ? options.tileGrid : createXYZ({ extent: extentFromProjection(projection), + maxResolution: options.maxResolution, maxZoom: options.maxZoom, minZoom: options.minZoom, tileSize: options.tileSize diff --git a/src/ol/tilegrid.js b/src/ol/tilegrid.js index 94fa003229..c152636216 100644 --- a/src/ol/tilegrid.js +++ b/src/ol/tilegrid.js @@ -72,8 +72,9 @@ export function createForExtent(extent, opt_maxZoom, opt_tileSize, opt_corner) { /** * @typedef {Object} XYZOptions * @property {import("./extent.js").Extent} [extent] Extent for the tile grid. The origin for an XYZ tile grid is the - * top-left corner of the extent. The zero level of the grid is defined by the resolution at which one tile fits in the - * provided extent. If not provided, the extent of the EPSG:3857 projection is used. + * top-left corner of the extent. If `maxResolution` is not provided the zero level of the grid is defined by the resolution + * at which one tile fits in the provided extent. If not provided, the extent of the EPSG:3857 projection is used. + * @property {number} [maxResolution] Resolution at level zero. * @property {number} [maxZoom] Maximum zoom. The default is `42`. This determines the number of levels * in the grid set. For example, a `maxZoom` of 21 means there are 22 levels in the grid set. * @property {number} [minZoom=0] Minimum zoom. @@ -99,7 +100,8 @@ export function createXYZ(opt_options) { resolutions: resolutionsFromExtent( extent, xyzOptions.maxZoom, - xyzOptions.tileSize + xyzOptions.tileSize, + xyzOptions.maxResolution ) }; return new TileGrid(gridOptions); @@ -113,9 +115,10 @@ export function createXYZ(opt_options) { * DEFAULT_MAX_ZOOM). * @param {number|import("./size.js").Size=} opt_tileSize Tile size (default uses * DEFAULT_TILE_SIZE). + * @param {number=} opt_maxResolution Resolution at level zero. * @return {!Array} Resolutions array. */ -function resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize) { +function resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize, opt_maxResolution) { const maxZoom = opt_maxZoom !== undefined ? opt_maxZoom : DEFAULT_MAX_ZOOM; @@ -124,8 +127,8 @@ function resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize) { const tileSize = toSize(opt_tileSize !== undefined ? opt_tileSize : DEFAULT_TILE_SIZE); - const maxResolution = Math.max( - width / tileSize[0], height / tileSize[1]); + const maxResolution = opt_maxResolution > 0 ? opt_maxResolution : + Math.max(width / tileSize[0], height / tileSize[1]); const length = maxZoom + 1; const resolutions = new Array(length); diff --git a/test/spec/ol/tilegrid/tilegrid.test.js b/test/spec/ol/tilegrid/tilegrid.test.js index 33cc3e99dc..ff503e5315 100644 --- a/test/spec/ol/tilegrid/tilegrid.test.js +++ b/test/spec/ol/tilegrid/tilegrid.test.js @@ -404,16 +404,17 @@ describe('ol.tilegrid.TileGrid', function() { it('respects configuration options', function() { const tileGrid = createXYZ({ extent: [10, 20, 30, 40], + maxResolution: 10 / 128, minZoom: 1, maxZoom: 2, tileSize: 128 }); expect(tileGrid.getExtent()).to.eql([10, 20, 30, 40]); + expect(tileGrid.getResolutions()).to.eql([10 / 128, 5 / 128, 2.5 / 128]); expect(tileGrid.getMinZoom()).to.equal(1); expect(tileGrid.getMaxZoom()).to.equal(2); expect(tileGrid.getTileSize()).to.equal(128); }); - }); describe('getForProjection', function() {