forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			84 lines
		
	
	
		
			No EOL
		
	
	
		
			3.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			No EOL
		
	
	
		
			3.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /**
 | |
|  * Applies geometry changes from 'Changes' onto every feature of a featureSource
 | |
|  */
 | |
| import {Changes} from "../../Osm/Changes";
 | |
| import {UIEventSource} from "../../UIEventSource";
 | |
| import {FeatureSourceForLayer, IndexedFeatureSource} from "../FeatureSource";
 | |
| import FilteredLayer from "../../../Models/FilteredLayer";
 | |
| import {ChangeDescription, ChangeDescriptionTools} from "../../Osm/Actions/ChangeDescription";
 | |
| 
 | |
| 
 | |
| export default class ChangeGeometryApplicator implements FeatureSourceForLayer {
 | |
|     public readonly features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]);
 | |
|     public readonly name: string;
 | |
|     public readonly layer: FilteredLayer
 | |
|     private readonly source: IndexedFeatureSource;
 | |
|     private readonly changes: Changes;
 | |
| 
 | |
|     constructor(source: (IndexedFeatureSource & FeatureSourceForLayer), changes: Changes) {
 | |
|         this.source = source;
 | |
|         this.changes = changes;
 | |
|         this.layer = source.layer
 | |
| 
 | |
|         this.name = "ChangesApplied(" + source.name + ")"
 | |
|         this.features = new UIEventSource<{ feature: any; freshness: Date }[]>(undefined)
 | |
| 
 | |
|         const self = this;
 | |
|         source.features.addCallbackAndRunD(_ => self.update())
 | |
| 
 | |
|         changes.allChanges.addCallbackAndRunD(_ => self.update())
 | |
| 
 | |
|     }
 | |
| 
 | |
|     private update() {
 | |
|         const upstreamFeatures = this.source.features.data
 | |
|         const upstreamIds = this.source.containedIds.data
 | |
|         const changesToApply = this.changes.allChanges.data
 | |
|             ?.filter(ch =>
 | |
|                 // Does upsteram have this element? If not, we skip
 | |
|                 upstreamIds.has(ch.type + "/" + ch.id) &&
 | |
|                 // Are any (geometry) changes defined?
 | |
|                 ch.changes !== undefined &&
 | |
|                 // Ignore new elements, they are handled by the NewGeometryFromChangesFeatureSource
 | |
|                 ch.id > 0)
 | |
| 
 | |
|         if (changesToApply === undefined || changesToApply.length === 0) {
 | |
|             // No changes to apply!
 | |
|             // Pass the original feature and lets continue our day
 | |
|             this.features.setData(upstreamFeatures);
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         const changesPerId = new Map<string, ChangeDescription[]>()
 | |
|         for (const ch of changesToApply) {
 | |
|             const key = ch.type + "/" + ch.id
 | |
|             if (changesPerId.has(key)) {
 | |
|                 changesPerId.get(key).push(ch)
 | |
|             } else {
 | |
|                 changesPerId.set(key, [ch])
 | |
|             }
 | |
|         }
 | |
|         const newFeatures: { feature: any, freshness: Date }[] = []
 | |
|         for (const feature of upstreamFeatures) {
 | |
|             const changesForFeature = changesPerId.get(feature.feature.properties.id)
 | |
|             if (changesForFeature === undefined) {
 | |
|                 // No changes for this element
 | |
|                 newFeatures.push(feature)
 | |
|                 continue;
 | |
|             }
 | |
| 
 | |
|             // Allright! We have a feature to rewrite!
 | |
|             const copy = {
 | |
|                 ...feature
 | |
|             }
 | |
|             // We only apply the last change as that one'll have the latest geometry
 | |
|             const change = changesForFeature[changesForFeature.length - 1]
 | |
|             copy.feature.geometry = ChangeDescriptionTools.getGeojsonGeometry(change)
 | |
|             console.log("Applying a geometry change onto ", feature, change, copy)
 | |
|             newFeatures.push(copy)
 | |
|         }
 | |
|         this.features.setData(newFeatures)
 | |
| 
 | |
|     }
 | |
| 
 | |
| } |