Performance: don't do an overpass request on every map pan if zoomed out too much

This commit is contained in:
Pieter Vander Vennet 2024-12-11 02:31:21 +01:00
parent 91a7957b85
commit 417bee2ee8
2 changed files with 21 additions and 28 deletions

View file

@ -1,4 +1,4 @@
import { Feature } from "geojson"
import { Feature, Geometry } from "geojson"
import { UpdatableFeatureSource } from "../FeatureSource"
import { ImmutableStore, Store, UIEventSource } from "../../UIEventSource"
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
@ -7,6 +7,9 @@ import { Overpass } from "../../Osm/Overpass"
import { Utils } from "../../../Utils"
import { TagsFilter } from "../../Tags/TagsFilter"
import { BBox } from "../../BBox"
import { FeatureCollection } from "@turf/turf"
import { OsmTags } from "../../../Models/OsmFeature"
"use strict";
/**
* A wrapper around the 'Overpass'-object.
@ -56,14 +59,13 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
this.state = state
this._isActive = options?.isActive ?? new ImmutableStore(true)
this.padToZoomLevel = options?.padToTiles
const self = this
this._layersToDownload = options?.ignoreZoom
? new ImmutableStore(state.layers)
: state.zoom.map((zoom) => this.layersToDownload(zoom))
state.bounds.mapD(
(_) => {
self.updateAsyncIfNeeded()
() => {
this.updateAsyncIfNeeded()
},
[this._layersToDownload]
)
@ -104,10 +106,11 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
/**
* Download the relevant data from overpass. Attempt to use a different server if one fails; only downloads the relevant layers
* Will always attempt to download, even is 'options.isActive.data' is 'false', the zoom level is incorrect, ...
* @private
*/
public async updateAsync(overrideBounds?: BBox): Promise<void> {
let data: any = undefined
let data: FeatureCollection<Geometry, OsmTags> = undefined
let lastUsed = 0
const start = new Date()
const layersToDownload = this._layersToDownload.data
@ -116,8 +119,7 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
return
}
const self = this
const overpassUrls = self.state.overpassUrl.data
const overpassUrls = this.state.overpassUrl.data
if (overpassUrls === undefined || overpassUrls.length === 0) {
throw "Panic: overpassFeatureSource didn't receive any overpassUrls"
}
@ -140,10 +142,11 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
return undefined
}
this.runningQuery.setData(true)
console.trace("Overpass feature source: querying geojson")
data = (await overpass.queryGeoJson(bounds))[0]
} catch (e) {
self.retries.data++
self.retries.ping()
this.retries.data++
this.retries.ping()
console.error(`QUERY FAILED due to`, e)
await Utils.waitFor(1000)
@ -153,12 +156,12 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
console.log("Trying next time with", overpassUrls[lastUsed])
} else {
lastUsed = 0
self.timeout.setData(self.retries.data * 5)
this.timeout.setData(this.retries.data * 5)
while (self.timeout.data > 0) {
while (this.timeout.data > 0) {
await Utils.waitFor(1000)
self.timeout.data--
self.timeout.ping()
this.timeout.data--
this.timeout.ping()
}
}
}
@ -180,14 +183,14 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
timeNeeded,
"seconds"
)
self.features.setData(data.features)
this.features.setData(data.features)
this._lastQueryBBox = bounds
this._lastRequestedLayers = layersToDownload
} catch (e) {
console.error("Got the overpass response, but could not process it: ", e, e.stack)
} finally {
self.retries.setData(0)
self.runningQuery.setData(false)
this.retries.setData(0)
this.runningQuery.setData(false)
}
}

View file

@ -24,8 +24,6 @@ export default class ThemeSource extends FeatureSourceMerger {
*/
public readonly isLoading: Store<boolean>
private readonly supportsForceDownload: UpdatableFeatureSource[]
public static readonly fromCacheZoomLevel = 15
/**
@ -44,8 +42,6 @@ export default class ThemeSource extends FeatureSourceMerger {
mvtAvailableLayers: Set<string>,
fullNodeDatabaseSource?: FullNodeDatabaseSource
) {
const supportsForceDownload: UpdatableFeatureSource[] = []
const { bounds, zoom } = mapProperties
// remove all 'special' layers
layers = layers.filter((layer) => layer.source !== null && layer.source !== undefined)
@ -95,7 +91,6 @@ export default class ThemeSource extends FeatureSourceMerger {
)
overpassSource = ThemeSource.setupOverpass(osmLayers, bounds, zoom, featureSwitches)
nonMvtSources.push(overpassSource)
supportsForceDownload.push(overpassSource)
}
function setIsLoading() {
@ -110,7 +105,6 @@ export default class ThemeSource extends FeatureSourceMerger {
ThemeSource.setupGeojsonSource(l, mapProperties, isDisplayed(l.id))
)
const downloadAllBounds: UIEventSource<BBox> = new UIEventSource<BBox>(undefined)
const downloadAll = new OverpassFeatureSource(
{
layers: layers.filter((l) => l.isNormal()),
@ -123,6 +117,7 @@ export default class ThemeSource extends FeatureSourceMerger {
},
{
ignoreZoom: true,
isActive: new ImmutableStore(false)
}
)
@ -135,13 +130,8 @@ export default class ThemeSource extends FeatureSourceMerger {
)
this.isLoading = isLoading
supportsForceDownload.push(...geojsonSources)
supportsForceDownload.push(...mvtSources) // Non-mvt sources are handled by overpass
this._mapBounds = mapProperties.bounds
this._downloadAll = downloadAll
this.supportsForceDownload = supportsForceDownload
this._mapBounds = mapProperties.bounds
}
private static setupMvtSource(