| 
									
										
										
										
											2021-05-06 01:33:09 +02:00
										 |  |  | import FeatureSource from "./FeatureSource"; | 
					
						
							|  |  |  | import {UIEventSource} from "../UIEventSource"; | 
					
						
							|  |  |  | import {OsmObject} from "../Osm/OsmObject"; | 
					
						
							| 
									
										
										
										
											2021-05-06 03:03:54 +02:00
										 |  |  | import State from "../../State"; | 
					
						
							|  |  |  | import {Utils} from "../../Utils"; | 
					
						
							| 
									
										
										
										
											2021-05-06 01:33:09 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default class OsmApiFeatureSource implements FeatureSource { | 
					
						
							|  |  |  |     public readonly features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); | 
					
						
							|  |  |  |     public readonly name: string = "OsmApiFeatureSource"; | 
					
						
							| 
									
										
										
										
											2021-05-06 03:03:54 +02:00
										 |  |  |     private readonly loadedTiles: Set<string> = new Set<string>(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-13 13:04:17 +02:00
										 |  |  |     constructor() { | 
					
						
							| 
									
										
										
										
											2021-05-06 03:03:54 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public load(id: string) { | 
					
						
							| 
									
										
										
										
											2021-07-18 14:52:09 +02:00
										 |  |  |         if (id.indexOf("-") >= 0) { | 
					
						
							| 
									
										
										
										
											2021-05-09 18:56:51 +02:00
										 |  |  |             // Newly added point - not yet in OSM
 | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-05-13 13:04:17 +02:00
										 |  |  |         console.debug("Downloading", id, "from the OSM-API") | 
					
						
							| 
									
										
										
										
											2021-06-30 16:02:46 +02:00
										 |  |  |         OsmObject.DownloadObject(id).addCallbackAndRunD(element => { | 
					
						
							| 
									
										
										
										
											2021-07-18 14:52:09 +02:00
										 |  |  |             try { | 
					
						
							|  |  |  |                 const geojson = element.asGeoJson(); | 
					
						
							|  |  |  |                 geojson.id = geojson.properties.id; | 
					
						
							|  |  |  |                 this.features.setData([{feature: geojson, freshness: element.timestamp}]) | 
					
						
							|  |  |  |             } catch (e) { | 
					
						
							|  |  |  |                 console.error(e) | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-05-06 01:33:09 +02:00
										 |  |  |         }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 03:03:54 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Loads the current inview-area | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public loadArea(z: number = 16): boolean { | 
					
						
							|  |  |  |         const layers = State.state.filteredLayers.data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const disabledLayers = layers.filter(layer => layer.layerDef.source.overpassScript !== undefined || layer.layerDef.source.geojsonSource !== undefined) | 
					
						
							|  |  |  |         if (disabledLayers.length > 0) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         const loc = State.state.locationControl.data; | 
					
						
							|  |  |  |         if (loc.zoom < 16) { | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (State.state.leafletMap.data === undefined) { | 
					
						
							|  |  |  |             return false; // Not yet inited
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         const bounds = State.state.leafletMap.data.getBounds() | 
					
						
							|  |  |  |         const tileRange = Utils.TileRangeBetween(z, bounds.getNorth(), bounds.getEast(), bounds.getSouth(), bounds.getWest()) | 
					
						
							|  |  |  |         const self = this; | 
					
						
							|  |  |  |         Utils.MapRange(tileRange, (x, y) => { | 
					
						
							|  |  |  |             const key = x + "/" + y; | 
					
						
							|  |  |  |             if (self.loadedTiles.has(key)) { | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             self.loadedTiles.add(key); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const bounds = Utils.tile_bounds(z, x, y); | 
					
						
							|  |  |  |             console.log("Loading OSM data tile", z, x, y, " with bounds", bounds) | 
					
						
							|  |  |  |             OsmObject.LoadArea(bounds, objects => { | 
					
						
							| 
									
										
										
										
											2021-07-18 14:52:09 +02:00
										 |  |  |                 const keptGeoJson: { feature: any, freshness: Date }[] = [] | 
					
						
							| 
									
										
										
										
											2021-05-06 03:03:54 +02:00
										 |  |  |                 // Which layer does the object match?
 | 
					
						
							|  |  |  |                 for (const object of objects) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     for (const flayer of layers) { | 
					
						
							|  |  |  |                         const layer = flayer.layerDef; | 
					
						
							|  |  |  |                         const tags = object.tags | 
					
						
							|  |  |  |                         const doesMatch = layer.source.osmTags.matchesProperties(tags); | 
					
						
							|  |  |  |                         if (doesMatch) { | 
					
						
							|  |  |  |                             const geoJson = object.asGeoJson(); | 
					
						
							|  |  |  |                             geoJson._matching_layer_id = layer.id | 
					
						
							| 
									
										
										
										
											2021-07-18 14:52:09 +02:00
										 |  |  |                             keptGeoJson.push({feature: geoJson, freshness: object.timestamp}) | 
					
						
							| 
									
										
										
										
											2021-05-06 03:03:54 +02:00
										 |  |  |                             break; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 self.features.setData(keptGeoJson) | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 01:33:09 +02:00
										 |  |  | } |