| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import { UIEventSource } from "../UIEventSource" | 
					
						
							| 
									
										
										
										
											2021-04-18 14:24:30 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | export interface Relation { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     id: number | 
					
						
							| 
									
										
										
										
											2021-04-18 14:24:30 +02:00
										 |  |  |     type: "relation" | 
					
						
							|  |  |  |     members: { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         type: "way" | "node" | "relation" | 
					
						
							|  |  |  |         ref: number | 
					
						
							| 
									
										
										
										
											2021-04-18 14:24:30 +02:00
										 |  |  |         role: string | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     }[] | 
					
						
							|  |  |  |     tags: any | 
					
						
							| 
									
										
										
										
											2021-04-18 14:24:30 +02:00
										 |  |  |     // Alias for tags; tags == properties
 | 
					
						
							|  |  |  |     properties: any | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  | export default class RelationsTracker { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     public knownRelations = new UIEventSource<Map<string, { role: string; relation: Relation }[]>>( | 
					
						
							|  |  |  |         new Map(), | 
					
						
							|  |  |  |         "Relation memberships" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-04-18 14:24:30 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     constructor() {} | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-22 03:30:46 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Gets an overview of the relations - except for multipolygons. We don't care about those | 
					
						
							|  |  |  |      * @param overpassJson | 
					
						
							|  |  |  |      * @constructor | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  |     private static GetRelationElements(overpassJson: any): Relation[] { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const relations = overpassJson.elements.filter( | 
					
						
							|  |  |  |             (element) => element.type === "relation" && element.tags.type !== "multipolygon" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-04-18 14:24:30 +02:00
										 |  |  |         for (const relation of relations) { | 
					
						
							|  |  |  |             relation.properties = relation.tags | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return relations | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-07 16:34:51 +01:00
										 |  |  |     public RegisterRelations(overpassJson: any): void { | 
					
						
							|  |  |  |         this.UpdateMembershipTable(RelationsTracker.GetRelationElements(overpassJson)) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-18 14:24:30 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Build a mapping of {memberId --> {role in relation, id of relation} } | 
					
						
							|  |  |  |      * @param relations | 
					
						
							|  |  |  |      * @constructor | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  |     private UpdateMembershipTable(relations: Relation[]): void { | 
					
						
							|  |  |  |         const memberships = this.knownRelations.data | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         let changed = false | 
					
						
							| 
									
										
										
										
											2021-04-18 14:24:30 +02:00
										 |  |  |         for (const relation of relations) { | 
					
						
							|  |  |  |             for (const member of relation.members) { | 
					
						
							|  |  |  |                 const role = { | 
					
						
							|  |  |  |                     role: member.role, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     relation: relation, | 
					
						
							| 
									
										
										
										
											2021-04-18 14:24:30 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |                 const key = member.type + "/" + member.ref | 
					
						
							|  |  |  |                 if (!memberships.has(key)) { | 
					
						
							|  |  |  |                     memberships.set(key, []) | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  |                 const knownRelations = memberships.get(key) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 const alreadyExists = knownRelations.some((knownRole) => { | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  |                     return knownRole.role === role.role && knownRole.relation === role.relation | 
					
						
							|  |  |  |                 }) | 
					
						
							|  |  |  |                 if (!alreadyExists) { | 
					
						
							|  |  |  |                     knownRelations.push(role) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     changed = true | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-04-18 14:24:30 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-09-21 02:10:42 +02:00
										 |  |  |         if (changed) { | 
					
						
							|  |  |  |             this.knownRelations.ping() | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-04-18 14:24:30 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | } |