Fix: overpass feature source will redownload if the layers to download have changed

This commit is contained in:
Pieter Vander Vennet 2024-09-02 01:59:58 +02:00
parent fae8ee7aa3
commit 7ed53076fe

View file

@ -34,6 +34,8 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
private readonly _isActive: Store<boolean> private readonly _isActive: Store<boolean>
private readonly padToZoomLevel?: Store<number> private readonly padToZoomLevel?: Store<number>
private _lastQueryBBox: BBox private _lastQueryBBox: BBox
private _lastRequestedLayers: LayerConfig[]
private readonly _layersToDownload: Store<LayerConfig[]>
constructor( constructor(
state: { state: {
@ -48,26 +50,21 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
options?: { options?: {
padToTiles?: Store<number> padToTiles?: Store<number>
isActive?: Store<boolean> isActive?: Store<boolean>
} },
) { ) {
this.state = state this.state = state
this._isActive = options?.isActive ?? new ImmutableStore(true) this._isActive = options?.isActive ?? new ImmutableStore(true)
this.padToZoomLevel = options?.padToTiles this.padToZoomLevel = options?.padToTiles
const self = this const self = this
state.bounds.addCallbackD((_) => { this._layersToDownload = state.zoom.map(zoom => this.layersToDownload(zoom))
state.bounds.mapD((_) => {
self.updateAsyncIfNeeded() self.updateAsyncIfNeeded()
}) }, [this._layersToDownload])
} }
/** private layersToDownload(zoom: number): LayerConfig[] {
* Download the relevant data from overpass. Attempt to use a different server; only downloads the relevant layers const layersToDownload: LayerConfig[] = []
* @private
*/
public async updateAsync(): Promise<void> {
let data: any = undefined
let lastUsed = 0
const layersToDownload = []
for (const layer of this.state.layers) { for (const layer of this.state.layers) {
if (typeof layer === "string") { if (typeof layer === "string") {
throw "A layer was not expanded!" throw "A layer was not expanded!"
@ -75,7 +72,7 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
if (layer.source === undefined) { if (layer.source === undefined) {
continue continue
} }
if (this.state.zoom.data < layer.minzoom) { if (zoom < layer.minzoom) {
continue continue
} }
if (layer.doNotDownload) { if (layer.doNotDownload) {
@ -85,7 +82,7 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
// This is a special layer. Should not have been here // This is a special layer. Should not have been here
console.warn( console.warn(
"OverpassFeatureSource received a layer for which the source is null:", "OverpassFeatureSource received a layer for which the source is null:",
layer.id layer.id,
) )
continue continue
} }
@ -96,6 +93,19 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
layersToDownload.push(layer) layersToDownload.push(layer)
} }
return layersToDownload
}
/**
* Download the relevant data from overpass. Attempt to use a different server if one fails; only downloads the relevant layers
* @private
*/
public async updateAsync(): Promise<void> {
let data: any = undefined
let lastUsed = 0
const start = new Date()
const layersToDownload = this._layersToDownload.data
if (layersToDownload.length == 0) { if (layersToDownload.length == 0) {
return return
} }
@ -106,15 +116,14 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
throw "Panic: overpassFeatureSource didn't receive any overpassUrls" throw "Panic: overpassFeatureSource didn't receive any overpassUrls"
} }
// Note: the bounds are updated between attempts, in case that the user zoomed around // Note: the bounds are updated between attempts, in case that the user zoomed around
let bounds: BBox let bounds : BBox
do { do {
try { try {
bounds = this.state.bounds.data bounds = this.state.bounds.data
?.pad(this.state.widenFactor) ?.pad(this.state.widenFactor)
?.expandToTileBounds(this.padToZoomLevel?.data) ?.expandToTileBounds(this.padToZoomLevel?.data)
if (!bounds) {
if (bounds === undefined) { return
return undefined
} }
const overpass = this.GetFilter(overpassUrls[lastUsed], layersToDownload) const overpass = this.GetFilter(overpassUrls[lastUsed], layersToDownload)
@ -154,9 +163,12 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
// Some metatags are delivered by overpass _without_ underscore-prefix; we fix them below // Some metatags are delivered by overpass _without_ underscore-prefix; we fix them below
// TODO FIXME re-enable this data.features.forEach((f) => SimpleMetaTaggers.objectMetaInfo.applyMetaTagsOnFeature(f)) // TODO FIXME re-enable this data.features.forEach((f) => SimpleMetaTaggers.objectMetaInfo.applyMetaTagsOnFeature(f))
console.log("Overpass returned", data.features.length, "features") const end = new Date()
const timeNeeded = (end.getTime() - start.getTime()) / 1000
console.log("Overpass returned", data.features.length, "features in", timeNeeded, "seconds")
self.features.setData(data.features) self.features.setData(data.features)
this._lastQueryBBox = bounds this._lastQueryBBox = bounds
this._lastRequestedLayers= layersToDownload
} catch (e) { } catch (e) {
console.error("Got the overpass response, but could not process it: ", e, e.stack) console.error("Got the overpass response, but could not process it: ", e, e.stack)
} finally { } finally {
@ -201,6 +213,7 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
const requestedBounds = this.state.bounds.data const requestedBounds = this.state.bounds.data
if ( if (
this._lastQueryBBox !== undefined && this._lastQueryBBox !== undefined &&
Utils.sameList(this._layersToDownload.data, this._lastRequestedLayers) &&
requestedBounds.isContainedIn(this._lastQueryBBox) requestedBounds.isContainedIn(this._lastQueryBBox)
) { ) {
return undefined return undefined