The overpassfeaturesource now only fetches layers that must be updated, fix #599

This commit is contained in:
pietervdvn 2022-01-15 02:44:11 +01:00
parent 9b88478804
commit 00e5ce0b02
7 changed files with 56 additions and 10 deletions

View file

@ -11,6 +11,8 @@ import {BBox} from "../BBox";
import Loc from "../../Models/Loc";
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
import Constants from "../../Models/Constants";
import TileFreshnessCalculator from "../FeatureSource/TileFreshnessCalculator";
import {Tiles} from "../../Models/TileRange";
export default class OverpassFeatureSource implements FeatureSource {
@ -38,9 +40,18 @@ export default class OverpassFeatureSource implements FeatureSource {
readonly overpassTimeout: UIEventSource<number>;
readonly currentBounds: UIEventSource<BBox>
}
private readonly _isActive: UIEventSource<boolean>;
private readonly _isActive: UIEventSource<boolean>
/**
* Callback to handle all the data
*/
private readonly onBboxLoaded: (bbox: BBox, date: Date, layers: LayerConfig[], zoomlevel: number) => void;
/**
* Keeps track of how fresh the data is
* @private
*/
private readonly freshnesses: Map<string, TileFreshnessCalculator>;
constructor(
state: {
readonly locationControl: UIEventSource<Loc>,
@ -54,13 +65,15 @@ export default class OverpassFeatureSource implements FeatureSource {
padToTiles: UIEventSource<number>,
isActive?: UIEventSource<boolean>,
relationTracker: RelationsTracker,
onBboxLoaded?: (bbox: BBox, date: Date, layers: LayerConfig[], zoomlevel: number) => void
onBboxLoaded?: (bbox: BBox, date: Date, layers: LayerConfig[], zoomlevel: number) => void,
freshnesses?: Map<string, TileFreshnessCalculator>
}) {
this.state = state
this._isActive = options.isActive;
this.onBboxLoaded = options.onBboxLoaded
this.relationsTracker = options.relationTracker
this.freshnesses = options.freshnesses
const self = this;
state.currentBounds.addCallback(_ => {
self.update(options.padToTiles.data)
@ -117,12 +130,13 @@ export default class OverpassFeatureSource implements FeatureSource {
const layersToDownload = []
const neededTiles = this.state.currentBounds.data.expandToTileBounds(padToZoomLevel).containingTileRange(padToZoomLevel)
for (const layer of this.state.layoutToUse.layers) {
if (typeof (layer) === "string") {
throw "A layer was not expanded!"
}
if(Constants.priviliged_layers.indexOf(layer.id) >= 0){
if (Constants.priviliged_layers.indexOf(layer.id) >= 0) {
continue
}
if (this.state.locationControl.data.zoom < layer.minzoom) {
@ -135,9 +149,32 @@ export default class OverpassFeatureSource implements FeatureSource {
// Not our responsibility to download this layer!
continue;
}
const freshness = this.freshnesses?.get(layer.id)
if (freshness !== undefined) {
const oldestDataDate = Math.min(...Tiles.MapRange(neededTiles, (x, y) => {
const date = freshness.freshnessFor(padToZoomLevel, x, y);
if (date === undefined) {
return 0
}
return date.getTime()
})) / 1000;
const now = new Date().getTime()
const minRequiredAge = (now / 1000) - layer.maxAgeOfCache
if (oldestDataDate >= minRequiredAge) {
// still fresh enough - not updating
continue
}
}
layersToDownload.push(layer)
}
if (layersToDownload.length == 0) {
console.debug("Not updating - no layers needed")
return;
}
const self = this;
const overpassUrls = self.state.overpassUrl.data
let bounds: BBox

View file

@ -1,9 +1,10 @@
import FeatureSource from "../FeatureSource";
import {UIEventSource} from "../../UIEventSource";
import State from "../../../State";
import ElementsState from "../../State/ElementsState";
import {ElementStorage} from "../../ElementStorage";
/**
* Makes sure that every feature is added to the ElementsStorage, so that the tags-eventsource can be retrieved
*/
export default class RegisteringAllFromFeatureSourceActor {
public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>;
public readonly name;

View file

@ -40,18 +40,23 @@ import {ElementStorage} from "../ElementStorage";
export default class FeaturePipeline {
public readonly sufficientlyZoomed: UIEventSource<boolean>;
public readonly runningQuery: UIEventSource<boolean>;
public readonly timeout: UIEventSource<number>;
public readonly somethingLoaded: UIEventSource<boolean> = new UIEventSource<boolean>(false)
public readonly newDataLoadedSignal: UIEventSource<FeatureSource> = new UIEventSource<FeatureSource>(undefined)
private readonly overpassUpdater: OverpassFeatureSource
private state: MapState;
private readonly relationTracker: RelationsTracker
private readonly perLayerHierarchy: Map<string, TileHierarchyMerger>;
/**
* Keeps track of the age of the loaded data.
* Has one freshness-Calculator for every layer
* @private
*/
private readonly freshnesses = new Map<string, TileFreshnessCalculator>();
private readonly oldestAllowedDate: Date;
@ -468,6 +473,7 @@ export default class FeaturePipeline {
padToTiles: state.locationControl.map(l => Math.min(15, l.zoom + 1)),
relationTracker: this.relationTracker,
isActive: useOsmApi.map(b => !b && overpassIsActive.data, [overpassIsActive]),
freshnesses: this.freshnesses,
onBboxLoaded: (bbox, date, downloadedLayers, paddedToZoomLevel) => {
Tiles.MapRange(bbox.containingTileRange(paddedToZoomLevel), (x, y) => {
const tileIndex = Tiles.tile_index(paddedToZoomLevel, x, y)

View file

@ -12,6 +12,9 @@ import LayoutConfig from "../../../Models/ThemeConfig/LayoutConfig";
import {Or} from "../../Tags/Or";
import {TagsFilter} from "../../Tags/TagsFilter";
/**
* If a tile is needed (requested via the UIEventSource in the constructor), will download the appropriate tile and pass it via 'handleTile'
*/
export default class OsmFeatureSource {
public readonly isRunning: UIEventSource<boolean> = new UIEventSource<boolean>(false)
public readonly downloadedTiles = new Set<number>()

View file

@ -52,7 +52,6 @@ export class Overpass {
}
self._relationTracker.RegisterRelations(json)
console.warn("OSMTOGEOJSON:", osmtogeojson)
const geojson = osmtogeojson.default(json);
const osmTime = new Date(json.osm3s.timestamp_osm_base);
return [geojson, osmTime];

View file

@ -2,7 +2,7 @@ import {Utils} from "../Utils";
export default class Constants {
public static vNumber = "0.14.0-alpha-4";
public static vNumber = "0.14.0-alpha-5";
public static ImgurApiKey = '7070e7167f0a25a'
public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85"

View file

@ -153,7 +153,7 @@ export default class LayoutConfig {
}
}
this.overpassTimeout = json.overpassTimeout ?? 30
this.overpassMaxZoom = json.overpassMaxZoom ?? 17
this.overpassMaxZoom = json.overpassMaxZoom ?? 16
this.osmApiTileSize = json.osmApiTileSize ?? this.overpassMaxZoom + 1
}