| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import { SubstitutedTranslation } from "../../UI/SubstitutedTranslation" | 
					
						
							|  |  |  | import TagRenderingConfig from "./TagRenderingConfig" | 
					
						
							|  |  |  | import { ExtraFuncParams, ExtraFunctions } from "../../Logic/ExtraFunctions" | 
					
						
							|  |  |  | import LayerConfig from "./LayerConfig" | 
					
						
							| 
									
										
										
										
											2022-11-02 14:44:06 +01:00
										 |  |  | import { SpecialVisualization } from "../../UI/SpecialVisualization" | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | export default class DependencyCalculator { | 
					
						
							|  |  |  |     public static GetTagRenderingDependencies(tr: TagRenderingConfig): string[] { | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  |         if (tr === undefined) { | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |             throw "Got undefined tag rendering in getTagRenderingDependencies" | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         const deps: string[] = [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // All translated snippets
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const parts: string[] = [].concat(...tr.EnumerateTranslations().map((tr) => tr.AllValues())) | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (const part of parts) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const specialVizs: { func: SpecialVisualization; args: string[] }[] = | 
					
						
							|  |  |  |                 SubstitutedTranslation.ExtractSpecialComponents(part) | 
					
						
							|  |  |  |                     .map((o) => o.special) | 
					
						
							|  |  |  |                     .filter((o) => o?.func?.getLayerDependencies !== undefined) | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |             for (const specialViz of specialVizs) { | 
					
						
							|  |  |  |                 deps.push(...specialViz.func.getLayerDependencies(specialViz.args)) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return deps | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Returns a set of all other layer-ids that this layer needs to function. | 
					
						
							|  |  |  |      * E.g. if this layers does snap to another layer in the preset, this other layer id will be mentioned | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     public static getLayerDependencies( | 
					
						
							|  |  |  |         layer: LayerConfig | 
					
						
							|  |  |  |     ): { neededLayer: string; reason: string; context?: string; neededBy: string }[] { | 
					
						
							|  |  |  |         const deps: { neededLayer: string; reason: string; context?: string; neededBy: string }[] = | 
					
						
							|  |  |  |             [] | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (let i = 0; layer.presets !== undefined && i < layer.presets.length; i++) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const preset = layer.presets[i] | 
					
						
							|  |  |  |             preset.preciseInput?.snapToLayers?.forEach((id) => { | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |                 deps.push({ | 
					
						
							|  |  |  |                     neededLayer: id, | 
					
						
							|  |  |  |                     reason: "a preset snaps to this layer", | 
					
						
							|  |  |  |                     context: "presets[" + i + "]", | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     neededBy: layer.id, | 
					
						
							|  |  |  |                 }) | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |             }) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const tr of layer.AllTagRenderings()) { | 
					
						
							|  |  |  |             for (const dep of DependencyCalculator.GetTagRenderingDependencies(tr)) { | 
					
						
							|  |  |  |                 deps.push({ | 
					
						
							|  |  |  |                     neededLayer: dep, | 
					
						
							|  |  |  |                     reason: "a tagrendering needs this layer", | 
					
						
							|  |  |  |                     context: tr.id, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     neededBy: layer.id, | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |                 }) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (layer.calculatedTags?.length > 0) { | 
					
						
							|  |  |  |             const obj = { | 
					
						
							|  |  |  |                 type: "Feature", | 
					
						
							|  |  |  |                 geometry: { | 
					
						
							|  |  |  |                     type: "Point", | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     coordinates: [0, 0], | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |                 }, | 
					
						
							|  |  |  |                 properties: { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     id: "node/1", | 
					
						
							|  |  |  |                 }, | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             let currentKey = undefined | 
					
						
							|  |  |  |             let currentLine = undefined | 
					
						
							|  |  |  |             const params: ExtraFuncParams = { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 getFeatureById: (_) => undefined, | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |                 getFeaturesWithin: (layerId, _) => { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     if (layerId === "*") { | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |                         // This is a wildcard
 | 
					
						
							|  |  |  |                         return [] | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2022-01-26 21:40:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |                     // The important line: steal the dependencies!
 | 
					
						
							|  |  |  |                     deps.push({ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                         neededLayer: layerId, | 
					
						
							|  |  |  |                         reason: "a calculated tag loads features from this layer", | 
					
						
							|  |  |  |                         context: | 
					
						
							|  |  |  |                             "calculatedTag[" + | 
					
						
							|  |  |  |                             currentLine + | 
					
						
							|  |  |  |                             "] which calculates the value for " + | 
					
						
							|  |  |  |                             currentKey, | 
					
						
							|  |  |  |                         neededBy: layer.id, | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |                     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     return [] | 
					
						
							|  |  |  |                 }, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 memberships: undefined, | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             // Init the extra patched functions...
 | 
					
						
							|  |  |  |             ExtraFunctions.FullPatchFeature(params, obj) | 
					
						
							|  |  |  |             // ... Run the calculated tag code, which will trigger the getFeaturesWithin above...
 | 
					
						
							|  |  |  |             for (let i = 0; i < layer.calculatedTags.length; i++) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 const [key, code] = layer.calculatedTags[i] | 
					
						
							|  |  |  |                 currentLine = i // Leak the state...
 | 
					
						
							|  |  |  |                 currentKey = key | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |                 try { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     const func = new Function("feat", "return " + code + ";") | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |                     const result = func(obj) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     obj.properties[key] = JSON.stringify(result) | 
					
						
							|  |  |  |                 } catch (e) {} | 
					
						
							| 
									
										
										
										
											2021-12-05 02:06:14 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return deps | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | } |