forked from MapComplete/MapComplete
		
	Performance: don't do an overpass request on every map pan if zoomed out too much
This commit is contained in:
		
							parent
							
								
									91a7957b85
								
							
						
					
					
						commit
						417bee2ee8
					
				
					 2 changed files with 21 additions and 28 deletions
				
			
		|  | @ -1,4 +1,4 @@ | ||||||
| import { Feature } from "geojson" | import { Feature, Geometry } from "geojson" | ||||||
| import { UpdatableFeatureSource } from "../FeatureSource" | import { UpdatableFeatureSource } from "../FeatureSource" | ||||||
| import { ImmutableStore, Store, UIEventSource } from "../../UIEventSource" | import { ImmutableStore, Store, UIEventSource } from "../../UIEventSource" | ||||||
| import LayerConfig from "../../../Models/ThemeConfig/LayerConfig" | import LayerConfig from "../../../Models/ThemeConfig/LayerConfig" | ||||||
|  | @ -7,6 +7,9 @@ import { Overpass } from "../../Osm/Overpass" | ||||||
| import { Utils } from "../../../Utils" | import { Utils } from "../../../Utils" | ||||||
| import { TagsFilter } from "../../Tags/TagsFilter" | import { TagsFilter } from "../../Tags/TagsFilter" | ||||||
| import { BBox } from "../../BBox" | import { BBox } from "../../BBox" | ||||||
|  | import { FeatureCollection } from "@turf/turf" | ||||||
|  | import { OsmTags } from "../../../Models/OsmFeature" | ||||||
|  | "use strict"; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * A wrapper around the 'Overpass'-object. |  * A wrapper around the 'Overpass'-object. | ||||||
|  | @ -56,14 +59,13 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource { | ||||||
|         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 |  | ||||||
|         this._layersToDownload = options?.ignoreZoom |         this._layersToDownload = options?.ignoreZoom | ||||||
|             ? new ImmutableStore(state.layers) |             ? new ImmutableStore(state.layers) | ||||||
|             : state.zoom.map((zoom) => this.layersToDownload(zoom)) |             : state.zoom.map((zoom) => this.layersToDownload(zoom)) | ||||||
| 
 | 
 | ||||||
|         state.bounds.mapD( |         state.bounds.mapD( | ||||||
|             (_) => { |             () => { | ||||||
|                 self.updateAsyncIfNeeded() |                 this.updateAsyncIfNeeded() | ||||||
|             }, |             }, | ||||||
|             [this._layersToDownload] |             [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 |      * 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 |      * @private | ||||||
|      */ |      */ | ||||||
|     public async updateAsync(overrideBounds?: BBox): Promise<void> { |     public async updateAsync(overrideBounds?: BBox): Promise<void> { | ||||||
|         let data: any = undefined |         let data: FeatureCollection<Geometry, OsmTags> = undefined | ||||||
|         let lastUsed = 0 |         let lastUsed = 0 | ||||||
|         const start = new Date() |         const start = new Date() | ||||||
|         const layersToDownload = this._layersToDownload.data |         const layersToDownload = this._layersToDownload.data | ||||||
|  | @ -116,8 +119,7 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource { | ||||||
|             return |             return | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const self = this |         const overpassUrls = this.state.overpassUrl.data | ||||||
|         const overpassUrls = self.state.overpassUrl.data |  | ||||||
|         if (overpassUrls === undefined || overpassUrls.length === 0) { |         if (overpassUrls === undefined || overpassUrls.length === 0) { | ||||||
|             throw "Panic: overpassFeatureSource didn't receive any overpassUrls" |             throw "Panic: overpassFeatureSource didn't receive any overpassUrls" | ||||||
|         } |         } | ||||||
|  | @ -140,10 +142,11 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource { | ||||||
|                     return undefined |                     return undefined | ||||||
|                 } |                 } | ||||||
|                 this.runningQuery.setData(true) |                 this.runningQuery.setData(true) | ||||||
|  |                 console.trace("Overpass feature source: querying geojson") | ||||||
|                 data = (await overpass.queryGeoJson(bounds))[0] |                 data = (await overpass.queryGeoJson(bounds))[0] | ||||||
|             } catch (e) { |             } catch (e) { | ||||||
|                 self.retries.data++ |                 this.retries.data++ | ||||||
|                 self.retries.ping() |                 this.retries.ping() | ||||||
|                 console.error(`QUERY FAILED due to`, e) |                 console.error(`QUERY FAILED due to`, e) | ||||||
| 
 | 
 | ||||||
|                 await Utils.waitFor(1000) |                 await Utils.waitFor(1000) | ||||||
|  | @ -153,12 +156,12 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource { | ||||||
|                     console.log("Trying next time with", overpassUrls[lastUsed]) |                     console.log("Trying next time with", overpassUrls[lastUsed]) | ||||||
|                 } else { |                 } else { | ||||||
|                     lastUsed = 0 |                     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) |                         await Utils.waitFor(1000) | ||||||
|                         self.timeout.data-- |                         this.timeout.data-- | ||||||
|                         self.timeout.ping() |                         this.timeout.ping() | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | @ -180,14 +183,14 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource { | ||||||
|                 timeNeeded, |                 timeNeeded, | ||||||
|                 "seconds" |                 "seconds" | ||||||
|             ) |             ) | ||||||
|             self.features.setData(data.features) |             this.features.setData(data.features) | ||||||
|             this._lastQueryBBox = bounds |             this._lastQueryBBox = bounds | ||||||
|             this._lastRequestedLayers = layersToDownload |             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 { | ||||||
|             self.retries.setData(0) |             this.retries.setData(0) | ||||||
|             self.runningQuery.setData(false) |             this.runningQuery.setData(false) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -24,8 +24,6 @@ export default class ThemeSource extends FeatureSourceMerger { | ||||||
|      */ |      */ | ||||||
|     public readonly isLoading: Store<boolean> |     public readonly isLoading: Store<boolean> | ||||||
| 
 | 
 | ||||||
|     private readonly supportsForceDownload: UpdatableFeatureSource[] |  | ||||||
| 
 |  | ||||||
|     public static readonly fromCacheZoomLevel = 15 |     public static readonly fromCacheZoomLevel = 15 | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | @ -44,8 +42,6 @@ export default class ThemeSource extends FeatureSourceMerger { | ||||||
|         mvtAvailableLayers: Set<string>, |         mvtAvailableLayers: Set<string>, | ||||||
|         fullNodeDatabaseSource?: FullNodeDatabaseSource |         fullNodeDatabaseSource?: FullNodeDatabaseSource | ||||||
|     ) { |     ) { | ||||||
|         const supportsForceDownload: UpdatableFeatureSource[] = [] |  | ||||||
| 
 |  | ||||||
|         const { bounds, zoom } = mapProperties |         const { bounds, zoom } = mapProperties | ||||||
|         // remove all 'special' layers
 |         // remove all 'special' layers
 | ||||||
|         layers = layers.filter((layer) => layer.source !== null && layer.source !== undefined) |         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) |             overpassSource = ThemeSource.setupOverpass(osmLayers, bounds, zoom, featureSwitches) | ||||||
|             nonMvtSources.push(overpassSource) |             nonMvtSources.push(overpassSource) | ||||||
|             supportsForceDownload.push(overpassSource) |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         function setIsLoading() { |         function setIsLoading() { | ||||||
|  | @ -110,7 +105,6 @@ export default class ThemeSource extends FeatureSourceMerger { | ||||||
|             ThemeSource.setupGeojsonSource(l, mapProperties, isDisplayed(l.id)) |             ThemeSource.setupGeojsonSource(l, mapProperties, isDisplayed(l.id)) | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         const downloadAllBounds: UIEventSource<BBox> = new UIEventSource<BBox>(undefined) |  | ||||||
|         const downloadAll = new OverpassFeatureSource( |         const downloadAll = new OverpassFeatureSource( | ||||||
|             { |             { | ||||||
|                 layers: layers.filter((l) => l.isNormal()), |                 layers: layers.filter((l) => l.isNormal()), | ||||||
|  | @ -123,6 +117,7 @@ export default class ThemeSource extends FeatureSourceMerger { | ||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
|                 ignoreZoom: true, |                 ignoreZoom: true, | ||||||
|  |                 isActive: new ImmutableStore(false) | ||||||
|             } |             } | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|  | @ -135,13 +130,8 @@ export default class ThemeSource extends FeatureSourceMerger { | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         this.isLoading = isLoading |         this.isLoading = isLoading | ||||||
|         supportsForceDownload.push(...geojsonSources) |  | ||||||
|         supportsForceDownload.push(...mvtSources) // Non-mvt sources are handled by overpass
 |  | ||||||
| 
 |  | ||||||
|         this._mapBounds = mapProperties.bounds |  | ||||||
|         this._downloadAll = downloadAll |         this._downloadAll = downloadAll | ||||||
| 
 |         this._mapBounds = mapProperties.bounds | ||||||
|         this.supportsForceDownload = supportsForceDownload |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private static setupMvtSource( |     private static setupMvtSource( | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue