| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  | import { FeatureSource, FeatureSourceForLayer } from "./FeatureSource" | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import FilteredLayer from "../../Models/FilteredLayer" | 
					
						
							|  |  |  | import SimpleFeatureSource from "./Sources/SimpleFeatureSource" | 
					
						
							| 
									
										
										
										
											2023-03-23 01:42:47 +01:00
										 |  |  | import { Feature } from "geojson" | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | import { Utils } from "../../Utils" | 
					
						
							|  |  |  | import { UIEventSource } from "../UIEventSource" | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * In some rare cases, some elements are shown on multiple layers (when 'passthrough' is enabled) | 
					
						
							|  |  |  |  * If this is the case, multiple objects with a different _matching_layer_id are generated. | 
					
						
							|  |  |  |  * In any case, this featureSource marks the objects with _matching_layer_id | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  | export default class PerLayerFeatureSourceSplitter< | 
					
						
							|  |  |  |     T extends FeatureSourceForLayer = SimpleFeatureSource | 
					
						
							|  |  |  | > { | 
					
						
							|  |  |  |     public readonly perLayer: ReadonlyMap<string, T> | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     constructor( | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         layers: FilteredLayer[], | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         upstream: FeatureSource, | 
					
						
							|  |  |  |         options?: { | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |             constructStore?: (features: UIEventSource<Feature[]>, layer: FilteredLayer) => T | 
					
						
							| 
									
										
										
										
											2023-03-30 04:51:56 +02:00
										 |  |  |             handleLeftovers?: (featuresWithoutLayer: Feature[]) => void | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         const knownLayers = new Map<string, T>() | 
					
						
							|  |  |  |         this.perLayer = knownLayers | 
					
						
							|  |  |  |         const layerSources = new Map<string, UIEventSource<Feature[]>>() | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  |         console.log("PerLayerFeatureSourceSplitter got layers", layers) | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         const constructStore = | 
					
						
							|  |  |  |             options?.constructStore ?? ((store, layer) => new SimpleFeatureSource(layer, store)) | 
					
						
							|  |  |  |         for (const layer of layers) { | 
					
						
							|  |  |  |             const src = new UIEventSource<Feature[]>([]) | 
					
						
							|  |  |  |             layerSources.set(layer.layerDef.id, src) | 
					
						
							|  |  |  |             knownLayers.set(layer.layerDef.id, <T>constructStore(src, layer)) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         upstream.features.addCallbackAndRunD((features) => { | 
					
						
							|  |  |  |             if (layers === undefined) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // We try to figure out (for each feature) in which feature store it should be saved.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-23 01:42:47 +01:00
										 |  |  |             const featuresPerLayer = new Map<string, Feature[]>() | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |             const noLayerFound: Feature[] = [] | 
					
						
							| 
									
										
										
										
											2021-11-07 16:34:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |             for (const layer of layers) { | 
					
						
							| 
									
										
										
										
											2021-12-13 02:05:34 +01:00
										 |  |  |                 featuresPerLayer.set(layer.layerDef.id, []) | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for (const f of features) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 let foundALayer = false | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |                 for (const layer of layers) { | 
					
						
							| 
									
										
										
										
											2023-03-23 01:42:47 +01:00
										 |  |  |                     if (layer.layerDef.source.osmTags.matchesProperties(f.properties)) { | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |                         // We have found our matching layer!
 | 
					
						
							| 
									
										
										
										
											2021-12-13 20:51:44 +01:00
										 |  |  |                         featuresPerLayer.get(layer.layerDef.id).push(f) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                         foundALayer = true | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |                         if (!layer.layerDef.passAllFeatures) { | 
					
						
							|  |  |  |                             // If not 'passAllFeatures', we are done for this feature
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                             break | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 if (!foundALayer) { | 
					
						
							| 
									
										
										
										
											2022-04-28 11:47:54 +02:00
										 |  |  |                     noLayerFound.push(f) | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // At this point, we have our features per layer as a list
 | 
					
						
							|  |  |  |             // We assign them to the correct featureSources
 | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |             for (const layer of layers) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 const id = layer.layerDef.id | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |                 const features = featuresPerLayer.get(id) | 
					
						
							|  |  |  |                 if (features === undefined) { | 
					
						
							|  |  |  |                     // No such features for this layer
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |                 const src = layerSources.get(id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (Utils.sameList(src.data, features)) { | 
					
						
							| 
									
										
										
										
											2023-03-30 04:51:56 +02:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |                 src.setData(features) | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-11-07 16:34:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-22 05:02:09 +02:00
										 |  |  |             // AT last, the leftovers are handled
 | 
					
						
							| 
									
										
										
										
											2021-11-07 16:34:51 +01:00
										 |  |  |             if (options?.handleLeftovers !== undefined && noLayerFound.length > 0) { | 
					
						
							| 
									
										
										
										
											2021-09-22 05:02:09 +02:00
										 |  |  |                 options.handleLeftovers(noLayerFound) | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |         }) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-28 05:13:48 +02:00
										 |  |  |     public forEach(f: (featureSource: FeatureSourceForLayer) => void) { | 
					
						
							|  |  |  |         for (const fs of this.perLayer.values()) { | 
					
						
							|  |  |  |             f(fs) | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | } |