Add caching into local storage for a faster map experience

This commit is contained in:
Pieter Vander Vennet 2021-01-15 00:29:07 +01:00
parent 3a2d654ac3
commit f33fe081d0
12 changed files with 128 additions and 41 deletions

View file

@ -130,7 +130,7 @@ export default class UpdateFromOverpass implements FeatureSource{
const w = Math.max(-180, bounds.getWest() - diff);
const queryBounds = {north: n, east: e, south: s, west: w};
const z = Math.floor(this._location.data.zoom);
const z = Math.floor(this._location.data.zoom ?? 0);
this.runningQuery.setData(true);
const self = this;

View file

@ -0,0 +1,48 @@
import FilteringFeatureSource from "../FeatureSource/FilteringFeatureSource";
import State from "../../State";
import FeatureSourceMerger from "../FeatureSource/FeatureSourceMerger";
import RememberingSource from "../FeatureSource/RememberingSource";
import WayHandlingApplyingFeatureSource from "../FeatureSource/WayHandlingApplyingFeatureSource";
import NoOverlapSource from "../FeatureSource/NoOverlapSource";
import FeatureDuplicatorPerLayer from "../FeatureSource/FeatureDuplicatorPerLayer";
import FeatureSource from "../FeatureSource/FeatureSource";
import {UIEventSource} from "../UIEventSource";
import LocalStorageSaver from "./LocalStorageSaver";
import LayerConfig from "../../Customizations/JSON/LayerConfig";
import LocalStorageSource from "./LocalStorageSource";
export default class FeaturePipeline implements FeatureSource {
public features: UIEventSource<{ feature: any; freshness: Date }[]>;
constructor(flayers: { isDisplayed: UIEventSource<boolean>, layerDef: LayerConfig }[], updater: FeatureSource) {
const overpassSource = new WayHandlingApplyingFeatureSource(flayers,
new NoOverlapSource(flayers, new FeatureDuplicatorPerLayer(flayers, updater))
);
const amendedOverpassSource =
new RememberingSource(new LocalStorageSaver(
overpassSource
));
const merged = new FeatureSourceMerger([
amendedOverpassSource,
new FeatureDuplicatorPerLayer(flayers, State.state.changes),
new LocalStorageSource()
]);
merged.features.addCallbackAndRun(feats => console.log("Merged has",feats?.length))
const source =
new FilteringFeatureSource(
flayers,
State.state.locationControl,
merged
);
source.features.addCallbackAndRun(feats => console.log("Filtered has",feats?.length))
this.features = source.features;
}
}

View file

@ -9,15 +9,20 @@ export default class FeatureSourceMerger implements FeatureSource {
constructor(sources: FeatureSource[]) {
this._sources = sources;
const self = this;
for (const source of sources) {
source.features.addCallback(() => self.Update());
for (let i = 0; i < sources.length; i++){
let source = sources[i];
source.features.addCallback(() => {
self.Update();
});
}
this.Update();
}
private Update() {
let all = {}; // Mapping 'id' -> {feature, freshness}
for (const source of this._sources) {
if(source?.features?.data === undefined){
console.log("Not defined");
continue;
}
for (const f of source.features.data) {

View file

@ -74,6 +74,7 @@ export default class FilteringFeatureSource implements FeatureSource {
update();
});
update();
}

View file

@ -0,0 +1,35 @@
/***
* Saves all the features that are passed in to localstorage, so they can be retrieved on the next run
*
* Technically, more an Actor then a featuresource, but it fits more neatly this ay
*/
import FeatureSource from "./FeatureSource";
import {UIEventSource} from "../UIEventSource";
export default class LocalStorageSaver implements FeatureSource {
public static readonly storageKey: string = "cached-features";
public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>;
constructor(source: FeatureSource) {
this.features = source.features;
this.features.addCallbackAndRun(features => {
if (features === undefined) {
return;
}
if(features.length == 0){
return;
}
try {
localStorage.setItem(LocalStorageSaver.storageKey, JSON.stringify(features));
} catch (e) {
console.warn("Could not save the features to local storage:", e)
}
})
}
}

View file

@ -0,0 +1,22 @@
import FeatureSource from "./FeatureSource";
import {UIEventSource} from "../UIEventSource";
import LocalStorageSaver from "./LocalStorageSaver";
export default class LocalStorageSource implements FeatureSource {
public features: UIEventSource<{ feature: any; freshness: Date }[]>;
constructor() {
this.features = new UIEventSource<{ feature: any; freshness: Date }[]>([])
try {
const fromStorage = localStorage.getItem(LocalStorageSaver.storageKey);
if (fromStorage == null) {
return;
}
const loaded = JSON.parse(fromStorage);
this.features.setData(loaded);
} catch (e) {
console.log("Could not load features from localStorage:", e)
}
}
}