diff --git a/examples/zoomify.html b/examples/zoomify.html index 919b7ceea3..d5b18997ca 100644 --- a/examples/zoomify.html +++ b/examples/zoomify.html @@ -11,5 +11,6 @@ tags: "zoomify, deep zoom, IIP, pixel, projection" diff --git a/examples/zoomify.js b/examples/zoomify.js index 35466ff78c..19c469dfdf 100644 --- a/examples/zoomify.js +++ b/examples/zoomify.js @@ -12,6 +12,8 @@ const iipUrl = 'http://vips.vtech.fr/cgi-bin/iipsrv.fcgi?FIF=' + '/mnt/MD1/AD00/ const layer = new TileLayer({ source: new Zoomify({ + tileSize: 256, + tilePixelRatio: 1, url: zoomifyUrl, size: [imgWidth, imgHeight], crossOrigin: 'anonymous' @@ -20,12 +22,15 @@ const layer = new TileLayer({ const extent = [0, -imgHeight, imgWidth, 0]; +const resolutions = layer.getSource().getTileGrid().getResolutions(); + const map = new Map({ layers: [layer], target: 'map', view: new View({ // adjust zoom levels to those provided by the source - resolutions: layer.getSource().getTileGrid().getResolutions(), + minResolution: resolutions[resolutions.length - 1], + maxResolution: resolutions[0], // constrain the center: center cannot be set outside this extent extent: extent }) @@ -36,17 +41,73 @@ const control = document.getElementById('zoomifyProtocol'); control.addEventListener('change', function(event) { const value = event.currentTarget.value; if (value === 'iip') { - layer.setSource(new Zoomify({ - url: iipUrl, - size: [imgWidth, imgHeight], - crossOrigin: 'anonymous' - })); + const extent = [0, -imgHeight, imgWidth, 0]; + layer.setSource( + new Zoomify({ + tileSize: 256, + tilePixelRatio: 1, + url: iipUrl, + size: [imgWidth, imgHeight], + crossOrigin: 'anonymous' + }) + ); + const resolutions = layer.getSource().getTileGrid().getResolutions(); + map.setView( + new View({ + // adjust zoom levels to those provided by the source + minResolution: resolutions[resolutions.length - 1], + maxResolution: resolutions[0], + // constrain the center: center cannot be set outside this extent + extent: extent + }) + ); + map.getView().fit(extent); } else if (value === 'zoomify') { - layer.setSource(new Zoomify({ - url: zoomifyUrl, - size: [imgWidth, imgHeight], - crossOrigin: 'anonymous' - })); + const extent = [0, -imgHeight, imgWidth, 0]; + layer.setSource( + new Zoomify({ + tileSize: 256, + tilePixelRatio: 1, + url: zoomifyUrl, + size: [imgWidth, imgHeight], + crossOrigin: 'anonymous' + }) + ); + const resolutions = layer.getSource().getTileGrid().getResolutions(); + map.setView( + new View({ + // adjust zoom levels to those provided by the source + minResolution: resolutions[resolutions.length - 1], + maxResolution: resolutions[0], + // constrain the center: center cannot be set outside this extent + extent: extent + }) + ); + map.getView().fit(extent); + } else if (value === 'zoomifyretina') { + const pixelRatio = 4; + // Be careful! Image extent will be modified by pixel ratio + const extent = [0, -imgHeight / pixelRatio, imgWidth / pixelRatio, 0]; + layer.setSource( + new Zoomify({ + tileSize: 256 / pixelRatio, + tilePixelRatio: pixelRatio, + url: zoomifyUrl, + size: [imgWidth / pixelRatio, imgHeight / pixelRatio], + crossOrigin: 'anonymous' + }) + ); + const resolutions = layer.getSource().getTileGrid().getResolutions(); + map.setView( + new View({ + // adjust zoom levels to those provided by the source + minResolution: resolutions[resolutions.length - 1] / pixelRatio, + maxResolution: resolutions[0], + // constrain the center: center cannot be set outside this extent + extent: extent + }) + ); + map.getView().fit(extent); } }); diff --git a/src/ol/source/Zoomify.js b/src/ol/source/Zoomify.js index 4baefa3bba..1085b12724 100644 --- a/src/ol/source/Zoomify.js +++ b/src/ol/source/Zoomify.js @@ -26,6 +26,7 @@ const TierSizeCalculation = { export class CustomTile extends ImageTile { /** + * @param {number} tilePixelRatio Tile pixel ratio to disaply the tile * @param {import("../tilegrid/TileGrid.js").default} tileGrid TileGrid that the tile belongs to. * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate. * @param {TileState} state State. @@ -34,8 +35,7 @@ export class CustomTile extends ImageTile { * @param {import("../Tile.js").LoadFunction} tileLoadFunction Tile load function. * @param {import("../Tile.js").Options=} opt_options Tile options. */ - constructor(tileGrid, tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) { - + constructor(tilePixelRatio, tileGrid, tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) { super(tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options); /** @@ -48,8 +48,11 @@ export class CustomTile extends ImageTile { * @private * @type {import("../size.js").Size} */ - this.tileSize_ = toSize(tileGrid.getTileSize(tileCoord[0])); - + this.tileSize_ = toSize(tileGrid.getTileSize(tileCoord[0])).map( + function(x) { + return x * tilePixelRatio; + } + ); } /** @@ -143,6 +146,7 @@ class Zoomify extends TileImage { const extent = options.extent || [0, -size[1], size[0], 0]; const tierSizeInTiles = []; const tileSize = options.tileSize || DEFAULT_TILE_SIZE; + const tilePixelRatio = options.tilePixelRatio || 1; let tileSizeForTierSizeCalculation = tileSize; switch (tierSizeCalculation) { @@ -242,14 +246,14 @@ class Zoomify extends TileImage { const tileUrlFunction = createFromTileUrlFunctions(urls.map(createFromTemplate)); - const ZoomifyTileClass = CustomTile.bind(null, tileGrid); + const ZoomifyTileClass = CustomTile.bind(null, tilePixelRatio, tileGrid); super({ attributions: options.attributions, cacheSize: options.cacheSize, crossOrigin: options.crossOrigin, projection: options.projection, - tilePixelRatio: options.tilePixelRatio, + tilePixelRatio: tilePixelRatio, reprojectionErrorThreshold: options.reprojectionErrorThreshold, tileClass: ZoomifyTileClass, tileGrid: tileGrid,