| 
									
										
										
										
											2023-03-26 05:58:28 +02:00
										 |  |  | import { Store, UIEventSource } from "../../UIEventSource" | 
					
						
							| 
									
										
										
										
											2023-04-06 01:33:08 +02:00
										 |  |  | import { FeatureSource ,  IndexedFeatureSource } from "../FeatureSource" | 
					
						
							| 
									
										
										
										
											2023-03-23 01:42:47 +01:00
										 |  |  | import { Feature } from "geojson" | 
					
						
							| 
									
										
										
										
											2023-03-30 04:51:56 +02:00
										 |  |  | import { Utils } from "../../../Utils" | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-26 05:58:28 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export default class FeatureSourceMerger implements IndexedFeatureSource { | 
					
						
							| 
									
										
										
										
											2023-03-23 01:42:47 +01:00
										 |  |  |     public features: UIEventSource<Feature[]> = new UIEventSource([]) | 
					
						
							| 
									
										
										
										
											2023-03-26 05:58:28 +02:00
										 |  |  |     public readonly featuresById: Store<Map<string, Feature>> | 
					
						
							|  |  |  |     private readonly _featuresById: UIEventSource<Map<string, Feature>> | 
					
						
							|  |  |  |     private readonly _sources: FeatureSource[] = [] | 
					
						
							| 
									
										
										
										
											2022-06-21 22:55:48 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-03-26 05:58:28 +02:00
										 |  |  |      * Merges features from different featureSources. | 
					
						
							|  |  |  |      * In case that multiple features have the same id, the latest `_version_number` will be used. Otherwise, we will take the last one | 
					
						
							| 
									
										
										
										
											2022-06-21 22:55:48 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-03-26 05:58:28 +02:00
										 |  |  |     constructor(...sources: FeatureSource[]) { | 
					
						
							|  |  |  |         this._featuresById = new UIEventSource<Map<string, Feature>>(undefined) | 
					
						
							|  |  |  |         this.featuresById = this._featuresById | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |         const self = this | 
					
						
							| 
									
										
										
										
											2023-03-26 05:58:28 +02:00
										 |  |  |         for (let source of sources) { | 
					
						
							|  |  |  |             source.features.addCallback(() => { | 
					
						
							|  |  |  |                 self.addData(sources.map((s) => s.features.data)) | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         this.addData(sources.map((s) => s.features.data)) | 
					
						
							|  |  |  |         this._sources = sources | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-26 05:58:28 +02:00
										 |  |  |     protected addSource(source: FeatureSource) { | 
					
						
							|  |  |  |         this._sources.push(source) | 
					
						
							|  |  |  |         source.features.addCallbackAndRun(() => { | 
					
						
							|  |  |  |             this.addData(this._sources.map((s) => s.features.data)) | 
					
						
							| 
									
										
										
										
											2021-09-20 17:14:55 +02:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-26 05:58:28 +02:00
										 |  |  |     protected addData(featuress: Feature[][]) { | 
					
						
							| 
									
										
										
										
											2023-03-30 04:51:56 +02:00
										 |  |  |         featuress = Utils.NoNull(featuress) | 
					
						
							| 
									
										
										
										
											2021-05-07 01:43:32 +02:00
										 |  |  |         let somethingChanged = false | 
					
						
							| 
									
										
										
										
											2023-03-23 01:42:47 +01:00
										 |  |  |         const all: Map<string, Feature> = new Map() | 
					
						
							| 
									
										
										
										
											2023-03-30 04:51:56 +02:00
										 |  |  |         const unseen = new Set<string>() | 
					
						
							| 
									
										
										
										
											2021-05-07 01:43:32 +02:00
										 |  |  |         // We seed the dictionary with the previously loaded features
 | 
					
						
							|  |  |  |         const oldValues = this.features.data ?? [] | 
					
						
							|  |  |  |         for (const oldValue of oldValues) { | 
					
						
							| 
									
										
										
										
											2023-03-23 01:42:47 +01:00
										 |  |  |             all.set(oldValue.properties.id, oldValue) | 
					
						
							| 
									
										
										
										
											2023-03-30 04:51:56 +02:00
										 |  |  |             unseen.add(oldValue.properties.id) | 
					
						
							| 
									
										
										
										
											2021-05-07 01:43:32 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-26 05:58:28 +02:00
										 |  |  |         for (const features of featuress) { | 
					
						
							|  |  |  |             for (const f of features) { | 
					
						
							| 
									
										
										
										
											2023-03-23 01:42:47 +01:00
										 |  |  |                 const id = f.properties.id | 
					
						
							| 
									
										
										
										
											2023-03-30 04:51:56 +02:00
										 |  |  |                 unseen.delete(id) | 
					
						
							| 
									
										
										
										
											2021-05-07 01:43:32 +02:00
										 |  |  |                 if (!all.has(id)) { | 
					
						
							|  |  |  |                     // This is a new feature
 | 
					
						
							|  |  |  |                     somethingChanged = true | 
					
						
							|  |  |  |                     all.set(id, f) | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // This value has been seen already, either in a previous run or by a previous datasource
 | 
					
						
							|  |  |  |                 // Let's figure out if something changed
 | 
					
						
							|  |  |  |                 const oldV = all.get(id) | 
					
						
							| 
									
										
										
										
											2023-03-26 05:58:28 +02:00
										 |  |  |                 if (oldV == f) { | 
					
						
							| 
									
										
										
										
											2023-03-23 01:42:47 +01:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2023-03-23 01:42:47 +01:00
										 |  |  |                 all.set(id, f) | 
					
						
							|  |  |  |                 somethingChanged = true | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-09-09 00:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-30 04:51:56 +02:00
										 |  |  |         somethingChanged ||= unseen.size > 0 | 
					
						
							|  |  |  |         unseen.forEach((id) => all.delete(id)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-09 00:05:51 +02:00
										 |  |  |         if (!somethingChanged) { | 
					
						
							| 
									
										
										
										
											2021-05-07 01:43:32 +02:00
										 |  |  |             // We don't bother triggering an update
 | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-09-09 00:05:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-07 01:43:32 +02:00
										 |  |  |         const newList = [] | 
					
						
							| 
									
										
										
										
											2023-03-26 05:58:28 +02:00
										 |  |  |         all.forEach((value, key) => { | 
					
						
							| 
									
										
										
										
											2021-05-07 01:43:32 +02:00
										 |  |  |             newList.push(value) | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |         this.features.setData(newList) | 
					
						
							| 
									
										
										
										
											2023-03-26 05:58:28 +02:00
										 |  |  |         this._featuresById.setData(all) | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } |