| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  | import FeatureSource from "./FeatureSource"; | 
					
						
							|  |  |  | import {UIEventSource} from "../UIEventSource"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-15 00:26:25 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Merges features from different featureSources | 
					
						
							|  |  |  |  * Uses the freshest feature available in the case multiple sources offer data with the same identifier | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  | export default class FeatureSourceMerger implements FeatureSource { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 12:55:38 +02:00
										 |  |  |     public features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); | 
					
						
							|  |  |  |     public readonly name; | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |     private readonly _sources: FeatureSource[]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor(sources: FeatureSource[]) { | 
					
						
							|  |  |  |         this._sources = sources; | 
					
						
							| 
									
										
										
										
											2021-04-23 12:55:38 +02:00
										 |  |  |         this.name = "SourceMerger of (" + sources.map(s => s.name).join(", ") + ")" | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |         const self = this; | 
					
						
							| 
									
										
										
										
											2021-04-23 12:55:38 +02:00
										 |  |  |         for (let i = 0; i < sources.length; i++) { | 
					
						
							| 
									
										
										
										
											2021-01-15 00:29:07 +01:00
										 |  |  |             let source = sources[i]; | 
					
						
							|  |  |  |             source.features.addCallback(() => { | 
					
						
							|  |  |  |                 self.Update(); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-01-15 00:29:07 +01:00
										 |  |  |         this.Update(); | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private Update() { | 
					
						
							| 
									
										
										
										
											2021-05-07 01:43:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let somethingChanged = false; | 
					
						
							|  |  |  |         const all: Map<string, { feature: any, freshness: Date }> = new Map<string, { feature: any; freshness: Date }>(); | 
					
						
							|  |  |  |         // We seed the dictionary with the previously loaded features
 | 
					
						
							|  |  |  |         const oldValues = this.features.data ?? []; | 
					
						
							|  |  |  |         for (const oldValue of oldValues) { | 
					
						
							| 
									
										
										
										
											2021-06-10 16:55:08 +02:00
										 |  |  |             all.set(oldValue.feature.id + oldValue.feature._matching_layer_id, oldValue) | 
					
						
							| 
									
										
										
										
											2021-05-07 01:43:32 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |         for (const source of this._sources) { | 
					
						
							| 
									
										
										
										
											2021-04-23 12:55:38 +02:00
										 |  |  |             if (source?.features?.data === undefined) { | 
					
						
							| 
									
										
										
										
											2021-01-04 22:59:11 +01:00
										 |  |  |                 continue; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |             for (const f of source.features.data) { | 
					
						
							| 
									
										
										
										
											2021-06-10 16:55:08 +02:00
										 |  |  |                 const id = f.feature.properties.id + f.feature._matching_layer_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); | 
					
						
							|  |  |  |                 if (oldV.freshness < f.freshness) { | 
					
						
							|  |  |  |                     // Jup, this feature is fresher
 | 
					
						
							|  |  |  |                     all.set(id, f); | 
					
						
							|  |  |  |                     somethingChanged = true; | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-05-07 01:43:32 +02:00
										 |  |  |          | 
					
						
							|  |  |  |         if(!somethingChanged){ | 
					
						
							|  |  |  |             // We don't bother triggering an update
 | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-05-07 01:43:32 +02:00
										 |  |  |          | 
					
						
							|  |  |  |         const newList = []; | 
					
						
							|  |  |  |         all.forEach((value, key) => { | 
					
						
							|  |  |  |             newList.push(value) | 
					
						
							|  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2021-01-03 03:09:52 +01:00
										 |  |  |         this.features.setData(newList); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |