| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig" | 
					
						
							|  |  |  | import FeaturePipeline from "../FeatureSource/FeaturePipeline" | 
					
						
							|  |  |  | import { Tiles } from "../../Models/TileRange" | 
					
						
							|  |  |  | import ShowDataLayer from "../../UI/ShowDataLayer/ShowDataLayer" | 
					
						
							|  |  |  | import { TileHierarchyAggregator } from "../../UI/ShowDataLayer/TileHierarchyAggregator" | 
					
						
							|  |  |  | import ShowTileInfo from "../../UI/ShowDataLayer/ShowTileInfo" | 
					
						
							|  |  |  | import { UIEventSource } from "../UIEventSource" | 
					
						
							|  |  |  | import MapState from "./MapState" | 
					
						
							|  |  |  | import SelectedFeatureHandler from "../Actors/SelectedFeatureHandler" | 
					
						
							|  |  |  | import Hash from "../Web/Hash" | 
					
						
							| 
									
										
										
										
											2021-12-07 17:46:57 +01:00
										 |  |  | import { BBox } from "../BBox" | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  | import FeatureInfoBox from "../../UI/Popup/FeatureInfoBox" | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  | import { FeatureSourceForLayer, Tiled } from "../FeatureSource/FeatureSource" | 
					
						
							|  |  |  | import MetaTagRecalculator from "../FeatureSource/Actors/MetaTagRecalculator" | 
					
						
							| 
									
										
										
										
											2022-03-02 16:00:02 +01:00
										 |  |  | import ScrollableFullScreen from "../../UI/Base/ScrollableFullScreen" | 
					
						
							|  |  |  | import LayerConfig from "../../Models/ThemeConfig/LayerConfig" | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | export default class FeaturePipelineState extends MapState { | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * The piece of code which fetches data from various sources and shows it on the background map | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public readonly featurePipeline: FeaturePipeline | 
					
						
							|  |  |  |     private readonly featureAggregator: TileHierarchyAggregator | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |     private readonly metatagRecalculator: MetaTagRecalculator | 
					
						
							| 
									
										
										
										
											2022-03-02 16:00:02 +01:00
										 |  |  |     private readonly popups: Map<string, ScrollableFullScreen> = new Map< | 
					
						
							|  |  |  |         string, | 
					
						
							|  |  |  |         ScrollableFullScreen | 
					
						
							|  |  |  |     >() | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |     constructor(layoutToUse: LayoutConfig) { | 
					
						
							|  |  |  |         super(layoutToUse) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-22 14:13:41 +01:00
										 |  |  |         const clustering = layoutToUse?.clustering | 
					
						
							| 
									
										
										
										
											2021-10-15 18:48:33 +02:00
										 |  |  |         this.featureAggregator = TileHierarchyAggregator.createHierarchy(this) | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |         const clusterCounter = this.featureAggregator | 
					
						
							|  |  |  |         const self = this | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |         /** | 
					
						
							|  |  |  |          * We are a bit in a bind: | 
					
						
							|  |  |  |          * There is the featurePipeline, which creates some sources during construction | 
					
						
							|  |  |  |          * THere is the metatagger, which needs to have these sources registered AND which takes a FeaturePipeline as argument | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |          * | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |          * This is a bit of a catch-22 (except that it isn't) | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |          * The sources that are registered in the constructor are saved into 'registeredSources' temporary | 
					
						
							|  |  |  |          * | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |          */ | 
					
						
							|  |  |  |         const sourcesToRegister = [] | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         function registerRaw(source: FeatureSourceForLayer & Tiled) { | 
					
						
							|  |  |  |             if (self.metatagRecalculator === undefined) { | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |                 sourcesToRegister.push(source) | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |                 self.metatagRecalculator.registerSource(source) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         function registerSource(source: FeatureSourceForLayer & Tiled) { | 
					
						
							|  |  |  |             clusterCounter.addTile(source) | 
					
						
							|  |  |  |             const sourceBBox = source.features.map((allFeatures) => | 
					
						
							|  |  |  |                 BBox.bboxAroundAll(allFeatures.map((f) => BBox.get(f.feature))) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // Do show features indicates if the respective 'showDataLayer' should be shown. It can be hidden by e.g. clustering
 | 
					
						
							|  |  |  |             const doShowFeatures = source.features.map( | 
					
						
							|  |  |  |                 (f) => { | 
					
						
							|  |  |  |                     const z = self.locationControl.data.zoom | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if (!source.layer.isDisplayed.data) { | 
					
						
							|  |  |  |                         return false | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |                     const bounds = self.currentBounds.data | 
					
						
							|  |  |  |                     if (bounds === undefined) { | 
					
						
							|  |  |  |                         // Map is not yet displayed
 | 
					
						
							|  |  |  |                         return false | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |                     if (!sourceBBox.data.overlapsWith(bounds)) { | 
					
						
							|  |  |  |                         // Not within range -> features are hidden
 | 
					
						
							|  |  |  |                         return false | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |                     if (z < source.layer.layerDef.minzoom) { | 
					
						
							|  |  |  |                         // Layer is always hidden for this zoom level
 | 
					
						
							|  |  |  |                         return false | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |                     if (z > clustering.maxZoom) { | 
					
						
							|  |  |  |                         return true | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |                     if (f.length > clustering.minNeededElements) { | 
					
						
							|  |  |  |                         // This tile alone already has too much features
 | 
					
						
							|  |  |  |                         return false | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |                     let [tileZ, tileX, tileY] = Tiles.tile_from_index(source.tileIndex) | 
					
						
							|  |  |  |                     if (tileZ >= z) { | 
					
						
							|  |  |  |                         while (tileZ > z) { | 
					
						
							|  |  |  |                             tileZ-- | 
					
						
							|  |  |  |                             tileX = Math.floor(tileX / 2) | 
					
						
							|  |  |  |                             tileY = Math.floor(tileY / 2) | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |                         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |                         if ( | 
					
						
							|  |  |  |                             clusterCounter.getTile(Tiles.tile_index(tileZ, tileX, tileY)) | 
					
						
							|  |  |  |                                 ?.totalValue > clustering.minNeededElements | 
					
						
							|  |  |  |                         ) { | 
					
						
							|  |  |  |                             // To much elements
 | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |                             return false | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |                     return true | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 [self.currentBounds, source.layer.isDisplayed, sourceBBox] | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |             new ShowDataLayer({ | 
					
						
							|  |  |  |                 features: source, | 
					
						
							|  |  |  |                 leafletMap: self.leafletMap, | 
					
						
							|  |  |  |                 layerToShow: source.layer.layerDef, | 
					
						
							|  |  |  |                 doShowLayer: doShowFeatures, | 
					
						
							|  |  |  |                 selectedElement: self.selectedElement, | 
					
						
							|  |  |  |                 state: self, | 
					
						
							| 
									
										
										
										
											2022-03-02 16:00:02 +01:00
										 |  |  |                 popup: (tags, layer) => self.CreatePopup(tags, layer), | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |             }) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-26 20:47:08 +01:00
										 |  |  |         this.featurePipeline = new FeaturePipeline(registerSource, this, { | 
					
						
							|  |  |  |             handleRawFeatureSource: registerRaw, | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         this.metatagRecalculator = new MetaTagRecalculator(this, this.featurePipeline) | 
					
						
							|  |  |  |         this.metatagRecalculator.registerSource(this.currentView, true) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         sourcesToRegister.forEach((source) => self.metatagRecalculator.registerSource(source)) | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |         new SelectedFeatureHandler(Hash.hash, this) | 
					
						
							| 
									
										
										
										
											2021-11-07 16:34:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |         this.AddClusteringToMap(this.leafletMap) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-02 17:13:21 +01:00
										 |  |  |     public CreatePopup(tags: UIEventSource<any>, layer: LayerConfig): ScrollableFullScreen { | 
					
						
							|  |  |  |         if (this.popups.has(tags.data.id)) { | 
					
						
							|  |  |  |             return this.popups.get(tags.data.id) | 
					
						
							| 
									
										
										
										
											2022-03-02 16:00:02 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         const popup = new FeatureInfoBox(tags, layer, this) | 
					
						
							| 
									
										
										
										
											2022-03-02 17:13:21 +01:00
										 |  |  |         this.popups.set(tags.data.id, popup) | 
					
						
							| 
									
										
										
										
											2022-03-02 16:00:02 +01:00
										 |  |  |         return popup | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Adds the cluster-tiles to the given map | 
					
						
							|  |  |  |      * @param leafletMap: a UIEventSource possible having a leaflet map | 
					
						
							|  |  |  |      * @constructor | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public AddClusteringToMap(leafletMap: UIEventSource<any>) { | 
					
						
							|  |  |  |         const clustering = this.layoutToUse.clustering | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |         const self = this | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |         new ShowDataLayer({ | 
					
						
							|  |  |  |             features: this.featureAggregator.getCountsForZoom( | 
					
						
							|  |  |  |                 clustering, | 
					
						
							|  |  |  |                 this.locationControl, | 
					
						
							|  |  |  |                 clustering.minNeededElements | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             leafletMap: leafletMap, | 
					
						
							|  |  |  |             layerToShow: ShowTileInfo.styling, | 
					
						
							| 
									
										
										
										
											2022-01-19 20:34:04 +01:00
										 |  |  |             popup: this.featureSwitchIsDebugging.data | 
					
						
							|  |  |  |                 ? (tags, layer) => new FeatureInfoBox(tags, layer, self) | 
					
						
							|  |  |  |                 : undefined, | 
					
						
							|  |  |  |             state: this, | 
					
						
							| 
									
										
										
										
											2021-10-15 05:20:02 +02:00
										 |  |  |         }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |