diff --git a/examples/zoomify.js b/examples/zoomify.js index 047dbd1146..47a32ae0db 100644 --- a/examples/zoomify.js +++ b/examples/zoomify.js @@ -8,15 +8,27 @@ const imgHeight = 3000; const zoomifyUrl = 'https://ol-zoomify.surge.sh/zoomify/'; -const layer = new TileLayer({ - source: new Zoomify({ - url: zoomifyUrl, - size: [imgWidth, imgHeight], - crossOrigin: 'anonymous' - }) +const source = new Zoomify({ + url: zoomifyUrl, + size: [imgWidth, imgHeight], + crossOrigin: 'anonymous', + zDirection: -1 // Ensure we get a tile with the screen resolution or higher +}); +const extent = source.getTileGrid().getExtent(); + +const retinaPixelRatio = 2; +const retinaSource = new Zoomify({ + url: zoomifyUrl, + size: [imgWidth, imgHeight], + crossOrigin: 'anonymous', + zDirection: -1, // Ensure we get a tile with the screen resolution or higher + tilePixelRatio: retinaPixelRatio, // Display retina tiles + tileSize: 256 / retinaPixelRatio // from a higher zoom level }); -const extent = [0, -imgHeight, imgWidth, 0]; +const layer = new TileLayer({ + source: source +}); const map = new Map({ layers: [layer], @@ -35,20 +47,9 @@ const control = document.getElementById('zoomifyProtocol'); control.addEventListener('change', function(event) { const value = event.currentTarget.value; if (value === 'zoomify') { - layer.setSource(new Zoomify({ - url: zoomifyUrl, - size: [imgWidth, imgHeight], - crossOrigin: 'anonymous', - zDirection: -1 // Ensure we get the most precise tile in any case - })); + layer.setSource(source); } else if (value === 'zoomifyretina') { - layer.setSource(new Zoomify({ - url: zoomifyUrl, - size: [imgWidth, imgHeight], - crossOrigin: 'anonymous', - zDirection: -1, // Ensure we get the most precise tile in any case - tilePixelRatio: 2 // Display retina tiles - })); + layer.setSource(retinaSource); } }); diff --git a/src/ol/source/IIIF.js b/src/ol/source/IIIF.js index 2fb4014673..8370a936f3 100644 --- a/src/ol/source/IIIF.js +++ b/src/ol/source/IIIF.js @@ -9,6 +9,7 @@ import {Versions} from '../format/IIIFInfo.js'; import {assert} from '../asserts.js'; import TileGrid from '../tilegrid/TileGrid.js'; import TileImage from './TileImage.js'; +import {toSize} from '../size.js'; /** * @typedef {Object} Options @@ -87,7 +88,7 @@ class IIIF extends TileImage { const extent = options.extent || [0, -height, width, 0]; const supportsListedSizes = sizes != undefined && Array.isArray(sizes) && sizes.length > 0; - const supportsListedTiles = tileSize != undefined && (typeof tileSize === 'number' && Number.isInteger(tileSize) && tileSize > 0 || Array.isArray(tileSize) && tileSize.length > 0); + const supportsListedTiles = tileSize !== undefined && (typeof tileSize === 'number' && Number.isInteger(tileSize) && tileSize > 0 || Array.isArray(tileSize) && tileSize.length > 0); const supportsArbitraryTiling = supports != undefined && Array.isArray(supports) && (supports.includes('regionByPx') || supports.includes('regionByPct')) && (supports.includes('sizeByWh') || supports.includes('sizeByH') || @@ -265,7 +266,9 @@ class IIIF extends TileImage { return baseUrl + regionParam + '/' + sizeParam + '/0/' + quality + '.' + format; }; - const IiifTileClass = CustomTile.bind(null, tilePixelRatio, tileGrid); + const IiifTileClass = CustomTile.bind(null, toSize(tileSize || 256).map(function(size) { + return size * tilePixelRatio; + })); super({ attributions: options.attributions, diff --git a/src/ol/source/Zoomify.js b/src/ol/source/Zoomify.js index e42ebaddeb..509a7e0ae2 100644 --- a/src/ol/source/Zoomify.js +++ b/src/ol/source/Zoomify.js @@ -8,7 +8,6 @@ import TileState from '../TileState.js'; import {expandUrl, createFromTileUrlFunctions} from '../tileurlfunction.js'; import {assert} from '../asserts.js'; import {createCanvasContext2D} from '../dom.js'; -import {getTopLeft} from '../extent.js'; import {toSize} from '../size.js'; import TileImage from './TileImage.js'; import TileGrid from '../tilegrid/TileGrid.js'; @@ -26,7 +25,7 @@ const TierSizeCalculation = { export class CustomTile extends ImageTile { /** - * @param {import("../tilegrid/TileGrid.js").default} tileGrid TileGrid that the tile belongs to. + * @param {import("../size.js").Size} tileSize Full tile size. * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate. * @param {TileState} state State. * @param {string} src Image source URI. @@ -34,7 +33,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(tileSize, tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) { super(tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options); @@ -45,10 +44,9 @@ export class CustomTile extends ImageTile { this.zoomifyImage_ = null; /** - * @private * @type {import("../size.js").Size} */ - this.tileSize_ = toSize(tileGrid.getTileSize(tileCoord[0])); + this.tileSize_ = tileSize; } @@ -138,12 +136,12 @@ class Zoomify extends TileImage { options.tierSizeCalculation : TierSizeCalculation.DEFAULT; + const tilePixelRatio = options.tilePixelRatio || 1; const imageWidth = size[0]; const imageHeight = size[1]; - const extent = options.extent || [0, -size[1], size[0], 0]; const tierSizeInTiles = []; const tileSize = options.tileSize || DEFAULT_TILE_SIZE; - let tileSizeForTierSizeCalculation = tileSize; + let tileSizeForTierSizeCalculation = tileSize * tilePixelRatio; switch (tierSizeCalculation) { case TierSizeCalculation.DEFAULT: @@ -175,10 +173,10 @@ class Zoomify extends TileImage { tierSizeInTiles.push([1, 1]); tierSizeInTiles.reverse(); - const resolutions = [1]; + const resolutions = [tilePixelRatio]; const tileCountUpToTier = [0]; for (let i = 1, ii = tierSizeInTiles.length; i < ii; i++) { - resolutions.push(1 << i); + resolutions.push(tilePixelRatio << i); tileCountUpToTier.push( tierSizeInTiles[i - 1][0] * tierSizeInTiles[i - 1][1] + tileCountUpToTier[i - 1] @@ -188,8 +186,7 @@ class Zoomify extends TileImage { const tileGrid = new TileGrid({ tileSize: tileSize, - extent: extent, - origin: getTopLeft(extent), + extent: options.extent || [0, -imageHeight, imageWidth, 0], resolutions: resolutions }); @@ -199,6 +196,8 @@ class Zoomify extends TileImage { } const urls = expandUrl(url); + const tileWidth = tileSize * tilePixelRatio; + /** * @param {string} template Template. * @return {import("../Tile.js").UrlFunction} Tile URL function. @@ -222,8 +221,6 @@ class Zoomify extends TileImage { const tileIndex = tileCoordX + tileCoordY * tierSizeInTiles[tileCoordZ][0]; - const tileSize = tileGrid.getTileSize(tileCoordZ); - const tileWidth = Array.isArray(tileSize) ? tileSize[0] : tileSize; const tileGroup = ((tileIndex + tileCountUpToTier[tileCoordZ]) / tileWidth) | 0; const localContext = { 'z': tileCoordZ, @@ -242,14 +239,14 @@ class Zoomify extends TileImage { const tileUrlFunction = createFromTileUrlFunctions(urls.map(createFromTemplate)); - const ZoomifyTileClass = CustomTile.bind(null, tileGrid); + const ZoomifyTileClass = CustomTile.bind(null, toSize(tileSize * tilePixelRatio)); 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, @@ -266,4 +263,4 @@ class Zoomify extends TileImage { } -export default Zoomify; \ No newline at end of file +export default Zoomify;