forked from MapComplete/MapComplete
		
	The overpassfeaturesource now only fetches layers that must be updated, fix #599
This commit is contained in:
		
							parent
							
								
									9b88478804
								
							
						
					
					
						commit
						00e5ce0b02
					
				
					 7 changed files with 56 additions and 10 deletions
				
			
		|  | @ -11,6 +11,8 @@ import {BBox} from "../BBox"; | ||||||
| import Loc from "../../Models/Loc"; | import Loc from "../../Models/Loc"; | ||||||
| import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; | import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; | ||||||
| import Constants from "../../Models/Constants"; | import Constants from "../../Models/Constants"; | ||||||
|  | import TileFreshnessCalculator from "../FeatureSource/TileFreshnessCalculator"; | ||||||
|  | import {Tiles} from "../../Models/TileRange"; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| export default class OverpassFeatureSource implements FeatureSource { | export default class OverpassFeatureSource implements FeatureSource { | ||||||
|  | @ -38,9 +40,18 @@ export default class OverpassFeatureSource implements FeatureSource { | ||||||
|         readonly overpassTimeout: UIEventSource<number>; |         readonly overpassTimeout: UIEventSource<number>; | ||||||
|         readonly currentBounds: UIEventSource<BBox> |         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; |     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( |     constructor( | ||||||
|         state: { |         state: { | ||||||
|             readonly locationControl: UIEventSource<Loc>, |             readonly locationControl: UIEventSource<Loc>, | ||||||
|  | @ -54,13 +65,15 @@ export default class OverpassFeatureSource implements FeatureSource { | ||||||
|             padToTiles: UIEventSource<number>, |             padToTiles: UIEventSource<number>, | ||||||
|             isActive?: UIEventSource<boolean>, |             isActive?: UIEventSource<boolean>, | ||||||
|             relationTracker: RelationsTracker, |             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.state = state | ||||||
|         this._isActive = options.isActive; |         this._isActive = options.isActive; | ||||||
|         this.onBboxLoaded = options.onBboxLoaded |         this.onBboxLoaded = options.onBboxLoaded | ||||||
|         this.relationsTracker = options.relationTracker |         this.relationsTracker = options.relationTracker | ||||||
|  |         this.freshnesses = options.freshnesses | ||||||
|         const self = this; |         const self = this; | ||||||
|         state.currentBounds.addCallback(_ => { |         state.currentBounds.addCallback(_ => { | ||||||
|             self.update(options.padToTiles.data) |             self.update(options.padToTiles.data) | ||||||
|  | @ -117,12 +130,13 @@ export default class OverpassFeatureSource implements FeatureSource { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         const layersToDownload = [] |         const layersToDownload = [] | ||||||
|  |         const neededTiles = this.state.currentBounds.data.expandToTileBounds(padToZoomLevel).containingTileRange(padToZoomLevel) | ||||||
|         for (const layer of this.state.layoutToUse.layers) { |         for (const layer of this.state.layoutToUse.layers) { | ||||||
| 
 | 
 | ||||||
|             if (typeof (layer) === "string") { |             if (typeof (layer) === "string") { | ||||||
|                 throw "A layer was not expanded!" |                 throw "A layer was not expanded!" | ||||||
|             } |             } | ||||||
|             if(Constants.priviliged_layers.indexOf(layer.id) >= 0){ |             if (Constants.priviliged_layers.indexOf(layer.id) >= 0) { | ||||||
|                 continue |                 continue | ||||||
|             } |             } | ||||||
|             if (this.state.locationControl.data.zoom < layer.minzoom) { |             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!
 |                 // Not our responsibility to download this layer!
 | ||||||
|                 continue; |                 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) |             layersToDownload.push(layer) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         if (layersToDownload.length == 0) { | ||||||
|  |             console.debug("Not updating - no layers needed") | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         const self = this; |         const self = this; | ||||||
|         const overpassUrls = self.state.overpassUrl.data |         const overpassUrls = self.state.overpassUrl.data | ||||||
|         let bounds: BBox |         let bounds: BBox | ||||||
|  |  | ||||||
|  | @ -1,9 +1,10 @@ | ||||||
| import FeatureSource from "../FeatureSource"; | import FeatureSource from "../FeatureSource"; | ||||||
| import {UIEventSource} from "../../UIEventSource"; | import {UIEventSource} from "../../UIEventSource"; | ||||||
| import State from "../../../State"; |  | ||||||
| import ElementsState from "../../State/ElementsState"; |  | ||||||
| import {ElementStorage} from "../../ElementStorage"; | 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 { | export default class RegisteringAllFromFeatureSourceActor { | ||||||
|     public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>; |     public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>; | ||||||
|     public readonly name; |     public readonly name; | ||||||
|  |  | ||||||
|  | @ -40,18 +40,23 @@ import {ElementStorage} from "../ElementStorage"; | ||||||
| export default class FeaturePipeline { | export default class FeaturePipeline { | ||||||
| 
 | 
 | ||||||
|     public readonly sufficientlyZoomed: UIEventSource<boolean>; |     public readonly sufficientlyZoomed: UIEventSource<boolean>; | ||||||
| 
 |  | ||||||
|     public readonly runningQuery: UIEventSource<boolean>; |     public readonly runningQuery: UIEventSource<boolean>; | ||||||
|     public readonly timeout: UIEventSource<number>; |     public readonly timeout: UIEventSource<number>; | ||||||
| 
 |  | ||||||
|     public readonly somethingLoaded: UIEventSource<boolean> = new UIEventSource<boolean>(false) |     public readonly somethingLoaded: UIEventSource<boolean> = new UIEventSource<boolean>(false) | ||||||
|     public readonly newDataLoadedSignal: UIEventSource<FeatureSource> = new UIEventSource<FeatureSource>(undefined) |     public readonly newDataLoadedSignal: UIEventSource<FeatureSource> = new UIEventSource<FeatureSource>(undefined) | ||||||
| 
 | 
 | ||||||
|  |      | ||||||
|  |      | ||||||
|     private readonly overpassUpdater: OverpassFeatureSource |     private readonly overpassUpdater: OverpassFeatureSource | ||||||
|     private state: MapState; |     private state: MapState; | ||||||
|     private readonly relationTracker: RelationsTracker |     private readonly relationTracker: RelationsTracker | ||||||
|     private readonly perLayerHierarchy: Map<string, TileHierarchyMerger>; |     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 freshnesses = new Map<string, TileFreshnessCalculator>(); | ||||||
| 
 | 
 | ||||||
|     private readonly oldestAllowedDate: Date; |     private readonly oldestAllowedDate: Date; | ||||||
|  | @ -468,6 +473,7 @@ export default class FeaturePipeline { | ||||||
|                 padToTiles: state.locationControl.map(l => Math.min(15, l.zoom + 1)), |                 padToTiles: state.locationControl.map(l => Math.min(15, l.zoom + 1)), | ||||||
|                 relationTracker: this.relationTracker, |                 relationTracker: this.relationTracker, | ||||||
|                 isActive: useOsmApi.map(b => !b && overpassIsActive.data, [overpassIsActive]), |                 isActive: useOsmApi.map(b => !b && overpassIsActive.data, [overpassIsActive]), | ||||||
|  |                 freshnesses: this.freshnesses, | ||||||
|                 onBboxLoaded: (bbox, date, downloadedLayers, paddedToZoomLevel) => { |                 onBboxLoaded: (bbox, date, downloadedLayers, paddedToZoomLevel) => { | ||||||
|                     Tiles.MapRange(bbox.containingTileRange(paddedToZoomLevel), (x, y) => { |                     Tiles.MapRange(bbox.containingTileRange(paddedToZoomLevel), (x, y) => { | ||||||
|                         const tileIndex = Tiles.tile_index(paddedToZoomLevel, x, y) |                         const tileIndex = Tiles.tile_index(paddedToZoomLevel, x, y) | ||||||
|  |  | ||||||
|  | @ -12,6 +12,9 @@ import LayoutConfig from "../../../Models/ThemeConfig/LayoutConfig"; | ||||||
| import {Or} from "../../Tags/Or"; | import {Or} from "../../Tags/Or"; | ||||||
| import {TagsFilter} from "../../Tags/TagsFilter"; | 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 { | export default class OsmFeatureSource { | ||||||
|     public readonly isRunning: UIEventSource<boolean> = new UIEventSource<boolean>(false) |     public readonly isRunning: UIEventSource<boolean> = new UIEventSource<boolean>(false) | ||||||
|     public readonly downloadedTiles = new Set<number>() |     public readonly downloadedTiles = new Set<number>() | ||||||
|  |  | ||||||
|  | @ -52,7 +52,6 @@ export class Overpass { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         self._relationTracker.RegisterRelations(json) |         self._relationTracker.RegisterRelations(json) | ||||||
|         console.warn("OSMTOGEOJSON:", osmtogeojson) |  | ||||||
|         const geojson = osmtogeojson.default(json); |         const geojson = osmtogeojson.default(json); | ||||||
|         const osmTime = new Date(json.osm3s.timestamp_osm_base); |         const osmTime = new Date(json.osm3s.timestamp_osm_base); | ||||||
|         return [geojson, osmTime]; |         return [geojson, osmTime]; | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ import {Utils} from "../Utils"; | ||||||
| 
 | 
 | ||||||
| export default class Constants { | 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 ImgurApiKey = '7070e7167f0a25a' | ||||||
|     public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" |     public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -153,7 +153,7 @@ export default class LayoutConfig { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         this.overpassTimeout = json.overpassTimeout ?? 30 |         this.overpassTimeout = json.overpassTimeout ?? 30 | ||||||
|         this.overpassMaxZoom = json.overpassMaxZoom ?? 17 |         this.overpassMaxZoom = json.overpassMaxZoom ?? 16 | ||||||
|         this.osmApiTileSize = json.osmApiTileSize ?? this.overpassMaxZoom + 1 |         this.osmApiTileSize = json.osmApiTileSize ?? this.overpassMaxZoom + 1 | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue