forked from MapComplete/MapComplete
		
	Use IndexedDb to store cached geodata, fix #494. This should prevent crashes
This commit is contained in:
		
							parent
							
								
									8fa7de661e
								
							
						
					
					
						commit
						9c848cfaee
					
				
					 7 changed files with 94 additions and 147 deletions
				
			
		|  | @ -1,116 +0,0 @@ | |||
| import FilteredLayer from "../../../Models/FilteredLayer"; | ||||
| import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; | ||||
| import {UIEventSource} from "../../UIEventSource"; | ||||
| import TileHierarchy from "./TileHierarchy"; | ||||
| import SaveTileToLocalStorageActor from "../Actors/SaveTileToLocalStorageActor"; | ||||
| import {BBox} from "../../BBox"; | ||||
| import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"; | ||||
| 
 | ||||
| export default class TiledFromLocalStorageSource implements TileHierarchy<FeatureSourceForLayer & Tiled> { | ||||
|     public readonly loadedTiles: Map<number, FeatureSourceForLayer & Tiled> = new Map<number, FeatureSourceForLayer & Tiled>(); | ||||
|     private readonly layer: FilteredLayer; | ||||
|     private readonly handleFeatureSource: (src: FeatureSourceForLayer & Tiled, index: number) => void; | ||||
|     private readonly undefinedTiles: Set<number>; | ||||
| 
 | ||||
|     constructor(layer: FilteredLayer, | ||||
|                 handleFeatureSource: (src: FeatureSourceForLayer & Tiled, index: number) => void, | ||||
|                 state: { | ||||
|                     currentBounds: UIEventSource<BBox> | ||||
|                 }) { | ||||
|         this.layer = layer; | ||||
|         this.handleFeatureSource = handleFeatureSource; | ||||
| 
 | ||||
| 
 | ||||
|         this.undefinedTiles = new Set<number>() | ||||
|         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)) | ||||
| 
 | ||||
|         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) | ||||
|             } | ||||
|         }) | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public static GetFreshnesses(layerId: string): Map<number, Date> { | ||||
|         const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layerId + "-" | ||||
|         const freshnesses = new Map<number, Date>() | ||||
|         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 + "-" | ||||
|         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") | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     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) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue