forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			64 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { Tiles } from "../../Models/TileRange"
 | 
						|
 | 
						|
export default class TileFreshnessCalculator {
 | 
						|
    /**
 | 
						|
     * All the freshnesses per tile index
 | 
						|
     * @private
 | 
						|
     */
 | 
						|
    private readonly freshnesses = new Map<number, Date>()
 | 
						|
 | 
						|
    /**
 | 
						|
     * 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))
 | 
						|
    }
 | 
						|
}
 |