diff --git a/examples/zoomify.html b/examples/zoomify.html index d5b18997ca..fb7503d075 100644 --- a/examples/zoomify.html +++ b/examples/zoomify.html @@ -10,7 +10,6 @@ tags: "zoomify, deep zoom, IIP, pixel, projection"
diff --git a/examples/zoomify.js b/examples/zoomify.js index 19c469dfdf..0da330b013 100644 --- a/examples/zoomify.js +++ b/examples/zoomify.js @@ -3,17 +3,13 @@ import View from '../src/ol/View.js'; import TileLayer from '../src/ol/layer/Tile.js'; import Zoomify from '../src/ol/source/Zoomify.js'; -const imgWidth = 9911; -const imgHeight = 6100; +const imgWidth = 4000; +const imgHeight = 3000; -const zoomifyUrl = 'http://vips.vtech.fr/cgi-bin/iipsrv.fcgi?zoomify=' + - '/mnt/MD1/AD00/plan_CHU-4HD-01/FOND.TIF/'; -const iipUrl = 'http://vips.vtech.fr/cgi-bin/iipsrv.fcgi?FIF=' + '/mnt/MD1/AD00/plan_CHU-4HD-01/FOND.TIF' + '&JTL={z},{tileIndex}'; +const zoomifyUrl = 'https://ol-zoomify.surge.sh/zoomify/'; const layer = new TileLayer({ source: new Zoomify({ - tileSize: 256, - tilePixelRatio: 1, url: zoomifyUrl, size: [imgWidth, imgHeight], crossOrigin: 'anonymous' @@ -22,17 +18,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 - minResolution: resolutions[resolutions.length - 1], - maxResolution: resolutions[0], + resolutions: layer.getSource().getTileGrid().getResolutions(), // constrain the center: center cannot be set outside this extent - extent: extent + extent: extent, + constrainOnlyCenter: true }) }); map.getView().fit(extent); @@ -40,74 +34,23 @@ map.getView().fit(extent); const control = document.getElementById('zoomifyProtocol'); control.addEventListener('change', function(event) { const value = event.currentTarget.value; - if (value === 'iip') { - 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') { - 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); + if (value === 'zoomify') { + layer.setSource(new Zoomify({ + url: zoomifyUrl, + size: [imgWidth, imgHeight], + crossOrigin: 'anonymous' + })); } 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); + layer.setSource(new Zoomify({ + tileSize: 256, // The tile size is 256px on the server, this is the default value + tilePixelRatio: 2, // We want to display this on a retina screen + tilePixelRatioOriginal: 1, // But the server serves 256px tiles, not 512px tiles that would be needed nominally. + zDirection: -1, //Ensure we get the most precise tile in any case + url: zoomifyUrl, + size: [imgWidth, imgHeight], + crossOrigin: 'anonymous' + })); } - }); + + diff --git a/src/ol/source/Zoomify.js b/src/ol/source/Zoomify.js index 5a5bd2efa1..cc2ec00c34 100644 --- a/src/ol/source/Zoomify.js +++ b/src/ol/source/Zoomify.js @@ -90,7 +90,8 @@ export class CustomTile extends ImageTile { * you must provide a `crossOrigin` value you want to access pixel data with the Canvas renderer. * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail. * @property {import("../proj.js").ProjectionLike} [projection] Projection. - * @property {number} [tilePixelRatio] The pixel ratio used by the tile service. For example, if the tile service advertizes 256px by 256px tiles but actually sends 512px by 512px images (for retina/hidpi devices) then `tilePixelRatio` should be set to `2` + * @property {number} [tilePixelRatio] The pixel ratio to display on screen. If on a retina screen then `tilePixelRatio` should be 2, else it should be 1. + * @property {number} [tilePixelRatioOriginal] The pixel ratio used by the tile service. For example, if the tile service advertizes 256px by 256px tiles but actually sends 512px by 512px images (for retina/hidpi devices) then `tilePixelRatioOriginal` should be set to `2` * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels). * Higher values can increase reprojection performance, but decrease precision. * @property {string} [url] URL template or base URL of the Zoomify service. @@ -147,6 +148,7 @@ class Zoomify extends TileImage { const tierSizeInTiles = []; const tileSize = options.tileSize || DEFAULT_TILE_SIZE; const tilePixelRatio = options.tilePixelRatio || 1; + const tilePixelRatioOriginal = options.tilePixelRatioOriginal || tilePixelRatio; let tileSizeForTierSizeCalculation = tileSize; switch (tierSizeCalculation) { @@ -246,7 +248,7 @@ class Zoomify extends TileImage { const tileUrlFunction = createFromTileUrlFunctions(urls.map(createFromTemplate)); - const ZoomifyTileClass = CustomTile.bind(null, tilePixelRatio, tileGrid); + const ZoomifyTileClass = CustomTile.bind(null, tilePixelRatioOriginal, tileGrid); super({ attributions: options.attributions,