function getTileMetric(layout, tileset, padding = 0.595) {
const zoom = tileset[0][2];
const nTiles = 2 ** zoom;
const tileLength = tileset.scale;
const mapResolution = layout.tileSize() / tileLength;
function wrap(x, xmax) {
while (x < 0) x += xmax;
while (x >= xmax) x -= xmax;
return x;
}
const [vpWidth, vpHeight] = layout.size();
const pad = padding * mapResolution;
const x0 = wrap(-tileset.translate[0] - pad, nTiles);
const x1 = x0 + vpWidth / tileLength + 2 * pad;
const y0 = -tileset.translate[1] - pad;
const y1 = y0 + vpHeight / tileLength + 2 * pad;
return function(tile) {
let zoomFac = 2 ** (zoom - tile.z);
let tileResolution = Math.min(1, mapResolution / zoomFac);
let tb = {
x0: tile.x * zoomFac,
x1: (tile.x + 1) * zoomFac,
y0: tile.y * zoomFac,
y1: (tile.y + 1) * zoomFac
};
let xOverlap = Math.max(
Math.min(x1, tb.x1) - Math.max(x0, tb.x0),
Math.min(x1, tb.x1 + nTiles) - Math.max(x0, tb.x0 + nTiles)
);
let yOverlap = Math.min(y1, tb.y1) - Math.max(y0, tb.y0);
let overlapArea = Math.max(0, xOverlap) * Math.max(0, yOverlap);
let visibleArea = overlapArea / mapResolution ** 2;
return 1.0 - visibleArea * tileResolution;
};
}