import { Tiles } from "../../Models/TileRange" export default class TileFreshnessCalculator { /** * All the freshnesses per tile index * @private */ private readonly freshnesses = new Map() /** * Marks that some data got loaded for this layer * @param tileId * @param freshness */ public addTileLoad(tileId: number, freshness: Date) { const existingFreshness = this.freshnessFor(...Tiles.tile_from_index(tileId)) if (existingFreshness >= freshness) { return } this.freshnesses.set(tileId, freshness) // Do we have freshness for the neighbouring tiles? If so, we can mark the tile above as loaded too! let [z, x, y] = Tiles.tile_from_index(tileId) if (z === 0) { return } x = x - (x % 2) // Make the tiles always even y = y - (y % 2) const ul = this.freshnessFor(z, x, y)?.getTime() if (ul === undefined) { return } const ur = this.freshnessFor(z, x + 1, y)?.getTime() if (ur === undefined) { return } const ll = this.freshnessFor(z, x, y + 1)?.getTime() if (ll === undefined) { return } const lr = this.freshnessFor(z, x + 1, y + 1)?.getTime() if (lr === undefined) { return } const leastFresh = Math.min(ul, ur, ll, lr) const date = new Date() date.setTime(leastFresh) this.addTileLoad(Tiles.tile_index(z - 1, Math.floor(x / 2), Math.floor(y / 2)), date) } public freshnessFor(z: number, x: number, y: number): Date { if (z < 0) { return undefined } const tileId = Tiles.tile_index(z, x, y) if (this.freshnesses.has(tileId)) { return this.freshnesses.get(tileId) } // recurse up return this.freshnessFor(z - 1, Math.floor(x / 2), Math.floor(y / 2)) } }