Merge pull request #10678 from mike-000/patch-7
Add maxResolution option to ol/tilegrid.createXYZ() and ol/source/XYZ
This commit is contained in:
@@ -3,7 +3,7 @@ layout: example.html
|
|||||||
title: ArcGIS REST with 512x512 Tiles
|
title: ArcGIS REST with 512x512 Tiles
|
||||||
shortdesc: Example of a XYZ source in EPSG:4326 using Esri 512x512 tiles.
|
shortdesc: Example of a XYZ source in EPSG:4326 using Esri 512x512 tiles.
|
||||||
docs: >
|
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"
|
tags: "xyz, esri, tilesize, custom projection"
|
||||||
---
|
---
|
||||||
<div id="map" class="map"></div>
|
<div id="map" class="map"></div>
|
||||||
|
|||||||
@@ -3,26 +3,18 @@ import View from '../src/ol/View.js';
|
|||||||
import TileLayer from '../src/ol/layer/Tile.js';
|
import TileLayer from '../src/ol/layer/Tile.js';
|
||||||
import XYZ from '../src/ol/source/XYZ.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({
|
const map = new Map({
|
||||||
target: 'map',
|
target: 'map',
|
||||||
layers: [
|
layers: [
|
||||||
new TileLayer({
|
new TileLayer({
|
||||||
source: new XYZ({
|
source: new XYZ({
|
||||||
attributions: 'Copyright:© 2013 ESRI, i-cubed, GeoEye',
|
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',
|
projection: 'EPSG:4326',
|
||||||
tileSize: tileSize,
|
tileSize: 512, // the tile size supported by the ArcGIS tile service
|
||||||
tileUrlFunction: function(tileCoord) {
|
maxResolution: 180 / 512, // Esri's tile grid fits 180 degrees on one 512 px tile
|
||||||
return urlTemplate.replace('{z}', (tileCoord[0] - 1).toString())
|
|
||||||
.replace('{x}', tileCoord[1].toString())
|
|
||||||
.replace('{y}', tileCoord[2].toString());
|
|
||||||
},
|
|
||||||
wrapX: true
|
wrapX: true
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -30,9 +30,10 @@ import TileCache from '../TileCache.js';
|
|||||||
* @property {import("./State.js").default} [state] Source state.
|
* @property {import("./State.js").default} [state] Source state.
|
||||||
* @property {typeof import("../VectorTile.js").default} [tileClass] Class used to instantiate image tiles.
|
* @property {typeof import("../VectorTile.js").default} [tileClass] Class used to instantiate image tiles.
|
||||||
* Default is {@link module:ol/VectorTile}.
|
* Default is {@link module:ol/VectorTile}.
|
||||||
* @property {number} [maxZoom=22] Optional max zoom level.
|
* @property {number} [maxZoom=22] Optional max zoom level. Not used if `tileGrid` is provided.
|
||||||
* @property {number} [minZoom] Optional min zoom level.
|
* @property {number} [minZoom] Optional min zoom level. Not used if `tileGrid` is provided.
|
||||||
* @property {number|import("../size.js").Size} [tileSize=512] Optional tile size.
|
* @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("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.
|
||||||
* @property {import("../Tile.js").LoadFunction} [tileLoadFunction]
|
* @property {import("../Tile.js").LoadFunction} [tileLoadFunction]
|
||||||
* Optional function to load a tile given a URL. Could look like this for pbf tiles:
|
* 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({
|
const tileGrid = options.tileGrid || createXYZ({
|
||||||
extent: extent,
|
extent: extent,
|
||||||
|
maxResolution: options.maxResolution,
|
||||||
maxZoom: options.maxZoom !== undefined ? options.maxZoom : 22,
|
maxZoom: options.maxZoom !== undefined ? options.maxZoom : 22,
|
||||||
minZoom: options.minZoom,
|
minZoom: options.minZoom,
|
||||||
tileSize: options.tileSize || 512
|
tileSize: options.tileSize || 512
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js';
|
|||||||
* @property {import("../proj.js").ProjectionLike} [projection='EPSG:3857'] Projection.
|
* @property {import("../proj.js").ProjectionLike} [projection='EPSG:3857'] Projection.
|
||||||
* @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
|
* @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
|
||||||
* Higher values can increase reprojection performance, but decrease precision.
|
* Higher values can increase reprojection performance, but decrease precision.
|
||||||
* @property {number} [maxZoom=18] Optional max zoom level.
|
* @property {number} [maxZoom=42] Optional max zoom level. Not used if `tileGrid` is provided.
|
||||||
* @property {number} [minZoom=0] Optional min zoom level.
|
* @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("../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
|
* @property {import("../Tile.js").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is
|
||||||
* ```js
|
* ```js
|
||||||
@@ -31,9 +32,10 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js';
|
|||||||
* by 512px images (for retina/hidpi devices) then `tilePixelRatio`
|
* by 512px images (for retina/hidpi devices) then `tilePixelRatio`
|
||||||
* should be set to `2`.
|
* should be set to `2`.
|
||||||
* @property {number|import("../size.js").Size} [tileSize=[256, 256]] The tile size used by the tile service.
|
* @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
|
* @property {import("../Tile.js").UrlFunction} [tileUrlFunction] Optional function to get
|
||||||
* tile URL given a tile coordinate and the projection.
|
* 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}`,
|
* @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`,
|
||||||
* and `{z}` placeholders. A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`,
|
* 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.
|
* 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 :
|
const tileGrid = options.tileGrid !== undefined ? options.tileGrid :
|
||||||
createXYZ({
|
createXYZ({
|
||||||
extent: extentFromProjection(projection),
|
extent: extentFromProjection(projection),
|
||||||
|
maxResolution: options.maxResolution,
|
||||||
maxZoom: options.maxZoom,
|
maxZoom: options.maxZoom,
|
||||||
minZoom: options.minZoom,
|
minZoom: options.minZoom,
|
||||||
tileSize: options.tileSize
|
tileSize: options.tileSize
|
||||||
|
|||||||
+9
-6
@@ -72,8 +72,9 @@ export function createForExtent(extent, opt_maxZoom, opt_tileSize, opt_corner) {
|
|||||||
/**
|
/**
|
||||||
* @typedef {Object} XYZOptions
|
* @typedef {Object} XYZOptions
|
||||||
* @property {import("./extent.js").Extent} [extent] Extent for the tile grid. The origin for an XYZ tile grid is the
|
* @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
|
* top-left corner of the extent. If `maxResolution` is not provided the zero level of the grid is defined by the resolution
|
||||||
* provided extent. If not provided, the extent of the EPSG:3857 projection is used.
|
* 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
|
* @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.
|
* 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.
|
* @property {number} [minZoom=0] Minimum zoom.
|
||||||
@@ -99,7 +100,8 @@ export function createXYZ(opt_options) {
|
|||||||
resolutions: resolutionsFromExtent(
|
resolutions: resolutionsFromExtent(
|
||||||
extent,
|
extent,
|
||||||
xyzOptions.maxZoom,
|
xyzOptions.maxZoom,
|
||||||
xyzOptions.tileSize
|
xyzOptions.tileSize,
|
||||||
|
xyzOptions.maxResolution
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
return new TileGrid(gridOptions);
|
return new TileGrid(gridOptions);
|
||||||
@@ -113,9 +115,10 @@ export function createXYZ(opt_options) {
|
|||||||
* DEFAULT_MAX_ZOOM).
|
* DEFAULT_MAX_ZOOM).
|
||||||
* @param {number|import("./size.js").Size=} opt_tileSize Tile size (default uses
|
* @param {number|import("./size.js").Size=} opt_tileSize Tile size (default uses
|
||||||
* DEFAULT_TILE_SIZE).
|
* DEFAULT_TILE_SIZE).
|
||||||
|
* @param {number=} opt_maxResolution Resolution at level zero.
|
||||||
* @return {!Array<number>} Resolutions array.
|
* @return {!Array<number>} Resolutions array.
|
||||||
*/
|
*/
|
||||||
function resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize) {
|
function resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize, opt_maxResolution) {
|
||||||
const maxZoom = opt_maxZoom !== undefined ?
|
const maxZoom = opt_maxZoom !== undefined ?
|
||||||
opt_maxZoom : DEFAULT_MAX_ZOOM;
|
opt_maxZoom : DEFAULT_MAX_ZOOM;
|
||||||
|
|
||||||
@@ -124,8 +127,8 @@ function resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize) {
|
|||||||
|
|
||||||
const tileSize = toSize(opt_tileSize !== undefined ?
|
const tileSize = toSize(opt_tileSize !== undefined ?
|
||||||
opt_tileSize : DEFAULT_TILE_SIZE);
|
opt_tileSize : DEFAULT_TILE_SIZE);
|
||||||
const maxResolution = Math.max(
|
const maxResolution = opt_maxResolution > 0 ? opt_maxResolution :
|
||||||
width / tileSize[0], height / tileSize[1]);
|
Math.max(width / tileSize[0], height / tileSize[1]);
|
||||||
|
|
||||||
const length = maxZoom + 1;
|
const length = maxZoom + 1;
|
||||||
const resolutions = new Array(length);
|
const resolutions = new Array(length);
|
||||||
|
|||||||
@@ -404,16 +404,17 @@ describe('ol.tilegrid.TileGrid', function() {
|
|||||||
it('respects configuration options', function() {
|
it('respects configuration options', function() {
|
||||||
const tileGrid = createXYZ({
|
const tileGrid = createXYZ({
|
||||||
extent: [10, 20, 30, 40],
|
extent: [10, 20, 30, 40],
|
||||||
|
maxResolution: 10 / 128,
|
||||||
minZoom: 1,
|
minZoom: 1,
|
||||||
maxZoom: 2,
|
maxZoom: 2,
|
||||||
tileSize: 128
|
tileSize: 128
|
||||||
});
|
});
|
||||||
expect(tileGrid.getExtent()).to.eql([10, 20, 30, 40]);
|
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.getMinZoom()).to.equal(1);
|
||||||
expect(tileGrid.getMaxZoom()).to.equal(2);
|
expect(tileGrid.getMaxZoom()).to.equal(2);
|
||||||
expect(tileGrid.getTileSize()).to.equal(128);
|
expect(tileGrid.getTileSize()).to.equal(128);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getForProjection', function() {
|
describe('getForProjection', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user