import FilteredLayer from "../../../Models/FilteredLayer"; import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; import {UIEventSource} from "../../UIEventSource"; import TileHierarchy from "./TileHierarchy"; import SaveTileToLocalStorageActor from "../Actors/SaveTileToLocalStorageActor"; import {Tiles} from "../../../Models/TileRange"; import {BBox} from "../../BBox"; import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"; export default class TiledFromLocalStorageSource implements TileHierarchy { public readonly loadedTiles: Map = new Map(); private readonly layer: FilteredLayer; private readonly handleFeatureSource: (src: FeatureSourceForLayer & Tiled, index: number) => void; private readonly undefinedTiles: Set; public static GetFreshnesses(layerId: string): Map { const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layerId + "-" const freshnesses = new Map() for (const key of Object.keys(localStorage)) { if (!(key.startsWith(prefix) && key.endsWith("-time"))) { continue } const index = Number(key.substring(prefix.length, key.length - "-time".length)) const time = Number(localStorage.getItem(key)) const freshness = new Date() freshness.setTime(time) freshnesses.set(index, freshness) } return freshnesses } static cleanCacheForLayer(layer: LayerConfig) { const now = new Date() const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layer.id + "-" console.log("Cleaning tiles of ", prefix, "with max age",layer.maxAgeOfCache) for (const key of Object.keys(localStorage)) { if (!(key.startsWith(prefix) && key.endsWith("-time"))) { continue } const index = Number(key.substring(prefix.length, key.length - "-time".length)) const time = Number(localStorage.getItem(key)) const timeDiff = (now.getTime() - time) / 1000 if(timeDiff >= layer.maxAgeOfCache){ const k = prefix+index; localStorage.removeItem(k) localStorage.removeItem(k+"-format") localStorage.removeItem(k+"-time") } } } constructor(layer: FilteredLayer, handleFeatureSource: (src: FeatureSourceForLayer & Tiled, index: number) => void, state: { currentBounds: UIEventSource }) { this.layer = layer; this.handleFeatureSource = handleFeatureSource; this.undefinedTiles = new Set() const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layer.layerDef.id + "-" const knownTiles: number[] = Object.keys(localStorage) .filter(key => { return key.startsWith(prefix) && !key.endsWith("-time") && !key.endsWith("-format"); }) .map(key => { return Number(key.substring(prefix.length)); }) .filter(i => !isNaN(i)) console.debug("Layer", layer.layerDef.id, "has following tiles in available in localstorage", knownTiles.map(i => Tiles.tile_from_index(i).join("/")).join(", ")) for (const index of knownTiles) { const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layer.layerDef.id + "-" + index; const version = localStorage.getItem(prefix + "-format") if (version === undefined || version !== SaveTileToLocalStorageActor.formatVersion) { // Invalid version! Remove this tile from local storage localStorage.removeItem(prefix) localStorage.removeItem(prefix + "-time") localStorage.removeItem(prefix + "-format") this.undefinedTiles.add(index) console.log("Dropped old format tile", prefix) } } const self = this state.currentBounds.map(bounds => { if (bounds === undefined) { return; } for (const knownTile of knownTiles) { if (this.loadedTiles.has(knownTile)) { continue; } if (this.undefinedTiles.has(knownTile)) { continue; } if (!bounds.overlapsWith(BBox.fromTileIndex(knownTile))) { continue; } self.loadTile(knownTile) } }) } private loadTile(neededIndex: number) { try { const key = SaveTileToLocalStorageActor.storageKey + "-" + this.layer.layerDef.id + "-" + neededIndex const data = localStorage.getItem(key) const features = JSON.parse(data) const src = { layer: this.layer, features: new UIEventSource<{ feature: any; freshness: Date }[]>(features), name: "FromLocalStorage(" + key + ")", tileIndex: neededIndex, bbox: BBox.fromTileIndex(neededIndex) } this.handleFeatureSource(src, neededIndex) this.loadedTiles.set(neededIndex, src) } catch (e) { console.error("Could not load data tile from local storage due to", e) this.undefinedTiles.add(neededIndex) } } }