Make zDirection configurable on tile source

This commit is contained in:
ahocevar
2019-07-30 16:50:01 +02:00
parent 230205c3fd
commit e07ff9c04e
17 changed files with 65 additions and 26 deletions

View File

@@ -63,12 +63,6 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
* @type {import("../../TileRange.js").default} * @type {import("../../TileRange.js").default}
*/ */
this.tmpTileRange_ = new TileRange(0, 0, 0, 0); this.tmpTileRange_ = new TileRange(0, 0, 0, 0);
/**
* @protected
* @type {number}
*/
this.zDirection = 0;
} }
/** /**
@@ -151,8 +145,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
const tileSource = tileLayer.getSource(); const tileSource = tileLayer.getSource();
const sourceRevision = tileSource.getRevision(); const sourceRevision = tileSource.getRevision();
const tileGrid = tileSource.getTileGridForProjection(projection); const tileGrid = tileSource.getTileGridForProjection(projection);
const zDirection = tileSource.zDirection === undefined ? this.zDirection : tileSource.zDirection; const z = tileGrid.getZForResolution(viewResolution, tileSource.zDirection);
const z = tileGrid.getZForResolution(viewResolution, zDirection);
const tileResolution = tileGrid.getResolution(z); const tileResolution = tileGrid.getResolution(z);
let extent = frameState.extent; let extent = frameState.extent;

View File

@@ -113,8 +113,6 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
*/ */
this.tmpTransform_ = createTransform(); this.tmpTransform_ = createTransform();
// Use nearest lower resolution.
this.zDirection = 1;
} }
/** /**

View File

@@ -269,7 +269,8 @@ class BingMaps extends TileImage {
const attributions = []; const attributions = [];
const viewState = frameState.viewState; const viewState = frameState.viewState;
const tileGrid = this.getTileGrid(); const tileGrid = this.getTileGrid();
const tileCoord = tileGrid.getTileCoordForCoordAndResolution(viewState.center, viewState.resolution); const z = tileGrid.getZForResolution(viewState.resolution, this.zDirection);
const tileCoord = tileGrid.getTileCoordForCoordAndZ(viewState.center, z);
const zoom = tileCoord[0]; const zoom = tileCoord[0];
resource.imageryProviders.map(function(imageryProvider) { resource.imageryProviders.map(function(imageryProvider) {
let intersecting = false; let intersecting = false;

View File

@@ -40,8 +40,8 @@ import TileImage from './TileImage.js';
* @property {string} [url] Base URL of the IIIF Image service. * @property {string} [url] Base URL of the IIIF Image service.
* This should be the same as the IIIF Image ID. * This should be the same as the IIIF Image ID.
* @property {Versions} [version=Versions.VERSION2] Service's IIIF Image API version. * @property {Versions} [version=Versions.VERSION2] Service's IIIF Image API version.
* @property {number} [zDirection] Indicate which resolution should be used * @property {number} [zDirection=0] Indicate which resolution should be used
* by a renderer if the views resolution does not match any resolution of the tile source. * by a renderer if the view resolution does not match any resolution of the tile source.
* If 0, the nearest resolution will be used. If 1, the nearest lower resolution * If 0, the nearest resolution will be used. If 1, the nearest lower resolution
* will be used. If -1, the nearest higher resolution will be used. * will be used. If -1, the nearest higher resolution will be used.
*/ */

View File

@@ -24,6 +24,7 @@ import {wrapX, getForProjection as getTileGridForProjection} from '../tilegrid.j
* @property {boolean} [wrapX=true] * @property {boolean} [wrapX=true]
* @property {number} [transition] * @property {number} [transition]
* @property {string} [key] * @property {string} [key]
* @property {number} [zDirection=0]
*/ */
@@ -110,9 +111,9 @@ class TileSource extends Source {
* by a renderer if the views resolution does not match any resolution of the tile source. * by a renderer if the views resolution does not match any resolution of the tile source.
* If 0, the nearest resolution will be used. If 1, the nearest lower resolution * If 0, the nearest resolution will be used. If 1, the nearest lower resolution
* will be used. If -1, the nearest higher resolution will be used. * will be used. If -1, the nearest higher resolution will be used.
* @type {number=} * @type {number}
*/ */
this.zDirection; this.zDirection = options.zDirection ? options.zDirection : 0;
} }
/** /**

View File

@@ -80,6 +80,11 @@ class LabeledTile extends Tile {
* @property {import("../proj.js").ProjectionLike} [projection='EPSG:3857'] Optional projection. * @property {import("../proj.js").ProjectionLike} [projection='EPSG:3857'] Optional projection.
* @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid. * @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.
* @property {boolean} [wrapX=true] Whether to wrap the world horizontally. * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.
* @property {number} [zDirection=0] Set to `1` when debugging `VectorTile` sources with
* a default configuration. Indicates which resolution should be used by a renderer if
* the view resolution does not match any resolution of the tile source. If 0, the nearest
* resolution will be used. If 1, the nearest lower resolution will be used. If -1, the
* nearest higher resolution will be used.
*/ */
@@ -106,7 +111,8 @@ class TileDebug extends XYZ {
opaque: false, opaque: false,
projection: options.projection, projection: options.projection,
tileGrid: options.tileGrid, tileGrid: options.tileGrid,
wrapX: options.wrapX !== undefined ? options.wrapX : true wrapX: options.wrapX !== undefined ? options.wrapX : true,
zDirection: options.zDirection
}); });
} }

View File

@@ -52,6 +52,10 @@ import {getForProjection as getTileGridForProjection} from '../tilegrid.js';
* @property {number} [transition] Duration of the opacity transition for rendering. * @property {number} [transition] Duration of the opacity transition for rendering.
* To disable the opacity transition, pass `transition: 0`. * To disable the opacity transition, pass `transition: 0`.
* @property {string} [key] Optional tile key for proper cache fetching * @property {string} [key] Optional tile key for proper cache fetching
* @property {number} [zDirection=0] Indicate which resolution should be used
* by a renderer if the view resolution does not match any resolution of the tile source.
* If 0, the nearest resolution will be used. If 1, the nearest lower resolution
* will be used. If -1, the nearest higher resolution will be used.
*/ */
@@ -84,7 +88,8 @@ class TileImage extends UrlTile {
wrapX: options.wrapX, wrapX: options.wrapX,
transition: options.transition, transition: options.transition,
key: options.key, key: options.key,
attributionsCollapsible: options.attributionsCollapsible attributionsCollapsible: options.attributionsCollapsible,
zDirection: options.zDirection
}); });
/** /**

View File

@@ -168,7 +168,8 @@ class TileWMS extends TileImage {
tileGrid = this.getTileGridForProjection(projectionObj); tileGrid = this.getTileGridForProjection(projectionObj);
} }
const tileCoord = tileGrid.getTileCoordForCoordAndResolution(coordinate, resolution); const z = tileGrid.getZForResolution(resolution, this.zDirection);
const tileCoord = tileGrid.getTileCoordForCoordAndZ(coordinate, z);
if (tileGrid.getResolutions().length <= tileCoord[0]) { if (tileGrid.getResolutions().length <= tileCoord[0]) {
return undefined; return undefined;

View File

@@ -385,8 +385,8 @@ class UTFGrid extends TileSource {
forDataAtCoordinateAndResolution( forDataAtCoordinateAndResolution(
coordinate, resolution, callback, opt_request) { coordinate, resolution, callback, opt_request) {
if (this.tileGrid) { if (this.tileGrid) {
const tileCoord = this.tileGrid.getTileCoordForCoordAndResolution( const z = this.tileGrid.getZForResolution(resolution, this.zDirection);
coordinate, resolution); const tileCoord = this.tileGrid.getTileCoordForCoordAndZ(coordinate, z);
const tile = /** @type {!CustomTile} */(this.getTile( const tile = /** @type {!CustomTile} */(this.getTile(
tileCoord[0], tileCoord[1], tileCoord[2], 1, this.getProjection())); tileCoord[0], tileCoord[1], tileCoord[2], 1, this.getProjection()));
tile.forDataAtCoordinate(coordinate, callback, opt_request); tile.forDataAtCoordinate(coordinate, callback, opt_request);

View File

@@ -25,6 +25,7 @@ import {getKeyZXY} from '../tilecoord.js';
* @property {boolean} [wrapX=true] * @property {boolean} [wrapX=true]
* @property {number} [transition] * @property {number} [transition]
* @property {string} [key] * @property {string} [key]
* @property {number} [zDirection=0]
*/ */
@@ -51,7 +52,8 @@ class UrlTile extends TileSource {
wrapX: options.wrapX, wrapX: options.wrapX,
transition: options.transition, transition: options.transition,
key: options.key, key: options.key,
attributionsCollapsible: options.attributionsCollapsible attributionsCollapsible: options.attributionsCollapsible,
zDirection: options.zDirection
}); });
/** /**

View File

@@ -64,6 +64,10 @@ import {equals} from '../array.js';
* When set to `false`, only one world * When set to `false`, only one world
* will be rendered. When set to `true`, tiles will be wrapped horizontally to * will be rendered. When set to `true`, tiles will be wrapped horizontally to
* render multiple worlds. * render multiple worlds.
* @property {number} [zDirection=1] Indicate which resolution should be used
* by a renderer if the view resolution does not match any resolution of the tile source.
* If 0, the nearest resolution will be used. If 1, the nearest lower resolution
* will be used. If -1, the nearest higher resolution will be used.
*/ */
@@ -109,7 +113,8 @@ class VectorTile extends UrlTile {
url: options.url, url: options.url,
urls: options.urls, urls: options.urls,
wrapX: options.wrapX === undefined ? true : options.wrapX, wrapX: options.wrapX === undefined ? true : options.wrapX,
transition: options.transition transition: options.transition,
zDirection: options.zDirection === undefined ? 1 : options.zDirection
}); });
/** /**

View File

@@ -41,6 +41,10 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js';
* @property {boolean} [wrapX=true] Whether to wrap the world horizontally. * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.
* @property {number} [transition] Duration of the opacity transition for rendering. * @property {number} [transition] Duration of the opacity transition for rendering.
* To disable the opacity transition, pass `transition: 0`. * To disable the opacity transition, pass `transition: 0`.
* @property {number} [zDirection=0] Indicate which resolution should be used
* by a renderer if the view resolution does not match any resolution of the tile source.
* If 0, the nearest resolution will be used. If 1, the nearest lower resolution
* will be used. If -1, the nearest higher resolution will be used.
*/ */
@@ -94,7 +98,8 @@ class XYZ extends TileImage {
urls: options.urls, urls: options.urls,
wrapX: options.wrapX !== undefined ? options.wrapX : true, wrapX: options.wrapX !== undefined ? options.wrapX : true,
transition: options.transition, transition: options.transition,
attributionsCollapsible: options.attributionsCollapsible attributionsCollapsible: options.attributionsCollapsible,
zDirection: options.zDirection
}); });
} }

View File

@@ -114,8 +114,8 @@ export class CustomTile extends ImageTile {
* @property {number} [transition] Duration of the opacity transition for rendering. * @property {number} [transition] Duration of the opacity transition for rendering.
* To disable the opacity transition, pass `transition: 0`. * To disable the opacity transition, pass `transition: 0`.
* @property {number} [tileSize=256] Tile size. Same tile size is used for all zoom levels. * @property {number} [tileSize=256] Tile size. Same tile size is used for all zoom levels.
* @property {number} [zDirection] Indicate which resolution should be used * @property {number} [zDirection=0] Indicate which resolution should be used
* by a renderer if the views resolution does not match any resolution of the tile source. * by a renderer if the view resolution does not match any resolution of the tile source.
* If 0, the nearest resolution will be used. If 1, the nearest lower resolution * If 0, the nearest resolution will be used. If 1, the nearest lower resolution
* will be used. If -1, the nearest higher resolution will be used. * will be used. If -1, the nearest higher resolution will be used.
*/ */

View File

@@ -86,6 +86,17 @@ describe('ol.renderer.canvas.TileLayer', function() {
done(); done();
}); });
}); });
it('respects the source\'s zDirection setting', function(done) {
layer.getSource().zDirection = 1;
map.getView().setZoom(5.8); // would lead to z6 tile request with the default zDirection
map.once('rendercomplete', function() {
const tileCache = layer.getSource().tileCache;
const keys = tileCache.getKeys();
expect(keys.some(key => key.startsWith('6/'))).to.be(false);
done();
});
});
}); });
}); });

View File

@@ -101,7 +101,7 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
it('creates a new instance', function() { it('creates a new instance', function() {
const renderer = new CanvasVectorTileLayerRenderer(layer); const renderer = new CanvasVectorTileLayerRenderer(layer);
expect(renderer).to.be.a(CanvasVectorTileLayerRenderer); expect(renderer).to.be.a(CanvasVectorTileLayerRenderer);
expect(renderer.zDirection).to.be(1); expect(renderer.getLayer()).to.equal(layer);
}); });
it('does not render replays for pure image rendering', function() { it('does not render replays for pure image rendering', function() {

View File

@@ -26,6 +26,10 @@ describe('ol.source.VectorTile', function() {
expect(source.format_).to.equal(format); expect(source.format_).to.equal(format);
}); });
it('sets the default zDirection on the instance', function() {
expect(source.zDirection).to.be(1);
});
it('uses ol.VectorTile as default tileClass', function() { it('uses ol.VectorTile as default tileClass', function() {
expect(source.tileClass).to.equal(VectorTile); expect(source.tileClass).to.equal(VectorTile);
}); });

View File

@@ -20,6 +20,13 @@ describe('ol.source.XYZ', function() {
expect(source).to.be.an(TileSource); expect(source).to.be.an(TileSource);
}); });
it('can be constructed with a custom zDirection', function() {
const source = new XYZ({
zDirection: -1
});
expect(source.zDirection).to.be(-1);
});
it('can be constructed with a custom tile grid', function() { it('can be constructed with a custom tile grid', function() {
const tileGrid = createXYZ(); const tileGrid = createXYZ();
const tileSource = new XYZ({ const tileSource = new XYZ({