@allmaps/iiif-parser
Version:
Allmaps IIIF parser
100 lines (99 loc) • 3.9 kB
JavaScript
export function getTileImageRequest({ width: imageWidth, height: imageHeight }, zoomLevel, column, row) {
// See https://iiif.io/api/image/3.0/implementation/#3-tile-region-parameter-calculation
const regionX = column * zoomLevel.originalWidth;
const regionY = row * zoomLevel.originalHeight;
const regionWidth = column * zoomLevel.originalWidth + zoomLevel.width * zoomLevel.scaleFactor >
imageWidth
? imageWidth - column * zoomLevel.originalWidth
: zoomLevel.width * zoomLevel.scaleFactor;
const regionHeight = row * zoomLevel.originalHeight + zoomLevel.height * zoomLevel.scaleFactor >
imageHeight
? imageHeight - row * zoomLevel.originalHeight
: zoomLevel.height * zoomLevel.scaleFactor;
let tileWidth = zoomLevel.width;
let tileHeight = zoomLevel.height;
if (regionX + zoomLevel.width * zoomLevel.scaleFactor > imageWidth) {
tileWidth = Math.floor((imageWidth - regionX + zoomLevel.scaleFactor - 1) / zoomLevel.scaleFactor);
}
if (regionY + zoomLevel.height * zoomLevel.scaleFactor > imageHeight) {
tileHeight = Math.floor((imageHeight - regionY + zoomLevel.scaleFactor - 1) /
zoomLevel.scaleFactor);
}
return {
region: {
x: regionX,
y: regionY,
width: regionWidth,
height: regionHeight
},
size: {
width: tileWidth,
height: tileHeight
}
};
}
function getDefaultTileset({ width: imageWidth, height: imageHeight }, tileWidth = 768) {
const maxTilesPerSide = Math.max(imageWidth, imageHeight) / tileWidth;
const maxExponent = Math.ceil(Math.log(maxTilesPerSide) / Math.log(2));
// let maxTileSide
// if (parsedImage.maxWidth) {
// maxTileSide = parsedImage.maxWidth
// }
// if (parsedImage.maxHeight) {
// maxTileSide = maxTileSide
// ? Math.min(maxTileSide, parsedImage.maxHeight)
// : parsedImage.maxHeight
// }
// if (parsedImage.maxArea) {
// maxTileSide = maxTileSide
// ? Math.min(maxTileSide, Math.sqrt(parsedImage.maxArea))
// : Math.sqrt(parsedImage.maxArea)
// }
return {
scaleFactors: Array.from({ length: maxExponent }, (_, exponent) => 2 ** exponent),
// .filter((scaleFactor) => {
// if (maxTileSide) {
// return tileWidth * scaleFactor <= maxTileSide
// } else {
// return true
// }
// }),
width: tileWidth
};
}
function getTileZoomLevelFromScaleFactor({ width: imageWidth, height: imageHeight }, tileset, scaleFactor) {
const height = tileset.height || tileset.width;
const originalWidth = tileset.width * scaleFactor;
const originalHeight = height * scaleFactor;
return {
scaleFactor,
width: tileset.width,
height,
originalWidth,
originalHeight,
columns: Math.ceil(imageWidth / originalWidth),
rows: Math.ceil(imageHeight / originalHeight)
};
}
function getTileZoomLevelsFromTilesets(imageSize, tilesets) {
return tilesets
.map((tileset) => tileset.scaleFactors.map((scaleFactor) => getTileZoomLevelFromScaleFactor(imageSize, tileset, scaleFactor)))
.flat();
}
function hasValidTileset(tilesets) {
if (tilesets.some((tileset) => tileset.width && tileset.scaleFactors && tileset.scaleFactors.length)) {
return true;
}
return false;
}
export function getTileZoomLevels(imageSize, tilesets, supportsAnyRegionAndSize) {
if (!tilesets || !hasValidTileset(tilesets)) {
if (supportsAnyRegionAndSize) {
tilesets = [getDefaultTileset(imageSize)];
}
else {
throw new Error('Image does not support tiles or custom regions and sizes.');
}
}
return getTileZoomLevelsFromTilesets(imageSize, tilesets);
}