| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  | import State from "../../../State"; | 
					
						
							|  |  |  | import FilteredLayer from "../../../Models/FilteredLayer"; | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  | import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  | import {Utils} from "../../../Utils"; | 
					
						
							|  |  |  | import {UIEventSource} from "../../UIEventSource"; | 
					
						
							|  |  |  | import Loc from "../../../Models/Loc"; | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  | import TileHierarchy from "./TileHierarchy"; | 
					
						
							| 
									
										
										
										
											2021-09-26 17:36:39 +02:00
										 |  |  | import {Tiles} from "../../../Models/TileRange"; | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  | /*** | 
					
						
							|  |  |  |  * A tiled source which dynamically loads the required tiles at a fixed zoom level | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export default class DynamicTileSource implements TileHierarchy<FeatureSourceForLayer & Tiled> { | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |     private readonly _loadedTiles = new Set<number>(); | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     public readonly loadedTiles: Map<number, FeatureSourceForLayer & Tiled>; | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     constructor( | 
					
						
							|  |  |  |         layer: FilteredLayer, | 
					
						
							|  |  |  |         zoomlevel: number, | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  |         constructTile: (zxy: [number, number, number]) => (FeatureSourceForLayer & Tiled), | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |         state: { | 
					
						
							|  |  |  |             locationControl: UIEventSource<Loc> | 
					
						
							|  |  |  |             leafletMap: any | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ) { | 
					
						
							|  |  |  |         state = State.state | 
					
						
							|  |  |  |         const self = this; | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.loadedTiles = new Map<number,FeatureSourceForLayer & Tiled>() | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |         const neededTiles = state.locationControl.map( | 
					
						
							|  |  |  |             location => { | 
					
						
							|  |  |  |                 if (!layer.isDisplayed.data) { | 
					
						
							|  |  |  |                     // No need to download! - the layer is disabled
 | 
					
						
							|  |  |  |                     return undefined; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (location.zoom < layer.layerDef.minzoom) { | 
					
						
							|  |  |  |                     // No need to download! - the layer is disabled
 | 
					
						
							|  |  |  |                     return undefined; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // Yup, this is cheating to just get the bounds here
 | 
					
						
							|  |  |  |                 const bounds = state.leafletMap.data?.getBounds() | 
					
						
							|  |  |  |                 if (bounds === undefined) { | 
					
						
							|  |  |  |                     // We'll retry later
 | 
					
						
							|  |  |  |                     return undefined | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-09-26 17:36:39 +02:00
										 |  |  |                 const tileRange = Tiles.TileRangeBetween(zoomlevel, bounds.getNorth(), bounds.getEast(), bounds.getSouth(), bounds.getWest()) | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-26 17:36:39 +02:00
										 |  |  |                 const needed = Tiles.MapRange(tileRange, (x, y) => Tiles.tile_index(zoomlevel, x, y)).filter(i => !self._loadedTiles.has(i)) | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  |                 if (needed.length === 0) { | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |                     return undefined | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return needed | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             , [layer.isDisplayed, state.leafletMap]).stabilized(250); | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |         neededTiles.addCallbackAndRunD(neededIndexes => { | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  |             console.log("Tiled geojson source ",layer.layerDef.id," needs", neededIndexes) | 
					
						
							|  |  |  |             if (neededIndexes === undefined) { | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |             for (const neededIndex of neededIndexes) { | 
					
						
							|  |  |  |                 self._loadedTiles.add(neededIndex) | 
					
						
							| 
									
										
										
										
											2021-09-26 17:36:39 +02:00
										 |  |  |                 const src = constructTile(Tiles.tile_from_index(neededIndex)) | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  |                 if(src !== undefined){ | 
					
						
							|  |  |  |                     self.loadedTiles.set(neededIndex, src) | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |