forked from MapComplete/MapComplete
		
	Themes: move tagRenderings+ above leftover-questions
This commit is contained in:
		
							parent
							
								
									f2d470ff2e
								
							
						
					
					
						commit
						f2f041f9d0
					
				
					 1 changed files with 83 additions and 61 deletions
				
			
		|  | @ -1,14 +1,4 @@ | |||
| import { | ||||
|     Concat, | ||||
|     Conversion, | ||||
|     DesugaringContext, | ||||
|     DesugaringStep, | ||||
|     Each, | ||||
|     Fuse, | ||||
|     On, | ||||
|     Pass, | ||||
|     SetDefault, | ||||
| } from "./Conversion" | ||||
| import { Concat, Conversion, DesugaringContext, DesugaringStep, Each, Fuse, On, Pass, SetDefault } from "./Conversion" | ||||
| import { LayoutConfigJson } from "../Json/LayoutConfigJson" | ||||
| import { PrepareLayer } from "./PrepareLayer" | ||||
| import { LayerConfigJson } from "../Json/LayerConfigJson" | ||||
|  | @ -27,9 +17,9 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs | |||
| 
 | ||||
|     constructor(state: DesugaringContext) { | ||||
|         super( | ||||
|             "Converts the identifier of a builtin layer into the actual layer, or converts a 'builtin' syntax with override in the fully expanded form", | ||||
|             "Converts the identifier of a builtin layer into the actual layer, or converts a 'builtin' syntax with override in the fully expanded form. Note that 'tagRenderings+' will be inserted before 'leftover-questions'", | ||||
|             [], | ||||
|             "SubstituteLayer" | ||||
|             "SubstituteLayer", | ||||
|         ) | ||||
|         this._state = state | ||||
|     } | ||||
|  | @ -80,23 +70,34 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs | |||
|                 (found["tagRenderings"] ?? []).length > 0 | ||||
|             ) { | ||||
|                 context.err( | ||||
|                     `When overriding a layer, an override is not allowed to override into tagRenderings. Use "+tagRenderings" or "tagRenderings+" instead to prepend or append some questions.` | ||||
|                     `When overriding a layer, an override is not allowed to override into tagRenderings. Use "+tagRenderings" or "tagRenderings+" instead to prepend or append some questions.`, | ||||
|                 ) | ||||
|             } | ||||
|             try { | ||||
| 
 | ||||
|                 const trPlus = json["override"]["tagRenderings+"] | ||||
|                 if(trPlus){ | ||||
|                     let index = found.tagRenderings.findIndex(tr => tr["id"] === "leftover-questions") | ||||
|                     if(index < 0){ | ||||
|                         index = found.tagRenderings.length | ||||
|                     } | ||||
|                     found.tagRenderings.splice(index, 0, ...trPlus) | ||||
|                     delete json["override"]["tagRenderings+"] | ||||
|                 } | ||||
| 
 | ||||
|                 Utils.Merge(json["override"], found) | ||||
|                 layers.push(found) | ||||
|             } catch (e) { | ||||
|                 context.err( | ||||
|                     `Could not apply an override due to: ${e}.\nThe override is: ${JSON.stringify( | ||||
|                         json["override"] | ||||
|                     )}` | ||||
|                         json["override"], | ||||
|                     )}`,
 | ||||
|                 ) | ||||
|             } | ||||
| 
 | ||||
|             if (json["hideTagRenderingsWithLabels"]) { | ||||
|                 if(typeof json["hideTagRenderingsWithLabels"] === "string"){ | ||||
|                     throw "At "+context+".hideTagRenderingsWithLabels should be a list containing strings, you specified a string" | ||||
|                 if (typeof json["hideTagRenderingsWithLabels"] === "string") { | ||||
|                     throw "At " + context + ".hideTagRenderingsWithLabels should be a list containing strings, you specified a string" | ||||
|                 } | ||||
|                 const hideLabels: Set<string> = new Set(json["hideTagRenderingsWithLabels"]) | ||||
|                 // These labels caused at least one deletion
 | ||||
|  | @ -110,9 +111,9 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs | |||
|                             usedLabels.add(labels[forbiddenLabel]) | ||||
|                             context.info( | ||||
|                                 "Dropping tagRendering " + | ||||
|                                     tr["id"] + | ||||
|                                     " as it has a forbidden label: " + | ||||
|                                     labels[forbiddenLabel] | ||||
|                                 tr["id"] + | ||||
|                                 " as it has a forbidden label: " + | ||||
|                                 labels[forbiddenLabel], | ||||
|                             ) | ||||
|                             continue | ||||
|                         } | ||||
|  | @ -121,7 +122,7 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs | |||
|                     if (hideLabels.has(tr["id"])) { | ||||
|                         usedLabels.add(tr["id"]) | ||||
|                         context.info( | ||||
|                             "Dropping tagRendering " + tr["id"] + " as its id is a forbidden label" | ||||
|                             "Dropping tagRendering " + tr["id"] + " as its id is a forbidden label", | ||||
|                         ) | ||||
|                         continue | ||||
|                     } | ||||
|  | @ -130,10 +131,10 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs | |||
|                         usedLabels.add(tr["group"]) | ||||
|                         context.info( | ||||
|                             "Dropping tagRendering " + | ||||
|                                 tr["id"] + | ||||
|                                 " as its group `" + | ||||
|                                 tr["group"] + | ||||
|                                 "` is a forbidden label" | ||||
|                             tr["id"] + | ||||
|                             " as its group `" + | ||||
|                             tr["group"] + | ||||
|                             "` is a forbidden label", | ||||
|                         ) | ||||
|                         continue | ||||
|                     } | ||||
|  | @ -144,8 +145,8 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs | |||
|                 if (unused.length > 0) { | ||||
|                     context.err( | ||||
|                         "This theme specifies that certain tagrenderings have to be removed based on forbidden layers. One or more of these layers did not match any tagRenderings and caused no deletions: " + | ||||
|                             unused.join(", ") + | ||||
|                             "\n   This means that this label can be removed or that the original tagRendering that should be deleted does not have this label anymore" | ||||
|                         unused.join(", ") + | ||||
|                         "\n   This means that this label can be removed or that the original tagRendering that should be deleted does not have this label anymore", | ||||
|                     ) | ||||
|                 } | ||||
|                 found.tagRenderings = filtered | ||||
|  | @ -162,7 +163,7 @@ class AddDefaultLayers extends DesugaringStep<LayoutConfigJson> { | |||
|         super( | ||||
|             "Adds the default layers, namely: " + Constants.added_by_default.join(", "), | ||||
|             ["layers"], | ||||
|             "AddDefaultLayers" | ||||
|             "AddDefaultLayers", | ||||
|         ) | ||||
|         this._state = state | ||||
|     } | ||||
|  | @ -186,10 +187,10 @@ class AddDefaultLayers extends DesugaringStep<LayoutConfigJson> { | |||
|             if (alreadyLoaded.has(v.id)) { | ||||
|                 context.warn( | ||||
|                     "Layout " + | ||||
|                         context + | ||||
|                         " already has a layer with name " + | ||||
|                         v.id + | ||||
|                         "; skipping inclusion of this builtin layer" | ||||
|                     context + | ||||
|                     " already has a layer with name " + | ||||
|                     v.id + | ||||
|                     "; skipping inclusion of this builtin layer", | ||||
|                 ) | ||||
|                 continue | ||||
|             } | ||||
|  | @ -205,14 +206,14 @@ class AddImportLayers extends DesugaringStep<LayoutConfigJson> { | |||
|         super( | ||||
|             "For every layer in the 'layers'-list, create a new layer which'll import notes. (Note that priviliged layers and layers which have a geojson-source set are ignored)", | ||||
|             ["layers"], | ||||
|             "AddImportLayers" | ||||
|             "AddImportLayers", | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     convert(json: LayoutConfigJson, context: ConversionContext): LayoutConfigJson { | ||||
|         if (!(json.enableNoteImports ?? true)) { | ||||
|             context.info( | ||||
|                 "Not creating a note import layers for theme " + json.id + " as they are disabled" | ||||
|                 "Not creating a note import layers for theme " + json.id + " as they are disabled", | ||||
|             ) | ||||
|             return json | ||||
|         } | ||||
|  | @ -247,7 +248,7 @@ class AddImportLayers extends DesugaringStep<LayoutConfigJson> { | |||
|             try { | ||||
|                 const importLayerResult = creator.convert( | ||||
|                     layer, | ||||
|                     context.inOperation(this.name).enter(i1) | ||||
|                     context.inOperation(this.name).enter(i1), | ||||
|                 ) | ||||
|                 if (importLayerResult !== undefined) { | ||||
|                     json.layers.push(importLayerResult) | ||||
|  | @ -266,7 +267,7 @@ class AddContextToTranslationsInLayout extends DesugaringStep<LayoutConfigJson> | |||
|         super( | ||||
|             "Adds context to translations, including the prefix 'themes:json.id'; this is to make sure terms in an 'overrides' or inline layer are linkable too", | ||||
|             ["_context"], | ||||
|             "AddContextToTranlationsInLayout" | ||||
|             "AddContextToTranlationsInLayout", | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|  | @ -281,7 +282,7 @@ class ApplyOverrideAll extends DesugaringStep<LayoutConfigJson> { | |||
|         super( | ||||
|             "Applies 'overrideAll' onto every 'layer'. The 'overrideAll'-field is removed afterwards", | ||||
|             ["overrideAll", "layers"], | ||||
|             "ApplyOverrideAll" | ||||
|             "ApplyOverrideAll", | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|  | @ -295,9 +296,29 @@ class ApplyOverrideAll extends DesugaringStep<LayoutConfigJson> { | |||
| 
 | ||||
|         delete json.overrideAll | ||||
|         const newLayers = [] | ||||
| 
 | ||||
|         let tagRenderingsPlus = undefined | ||||
|         if (overrideAll["tagRenderings+"] !== undefined) { | ||||
|             tagRenderingsPlus = overrideAll["tagRenderings+"] | ||||
|             delete overrideAll["tagRenderings+"] | ||||
|         } | ||||
| 
 | ||||
|         for (let layer of json.layers) { | ||||
|             layer = Utils.Clone(<LayerConfigJson>layer) | ||||
|             Utils.Merge(overrideAll, layer) | ||||
|             if (tagRenderingsPlus) { | ||||
|                 if (!layer.tagRenderings) { | ||||
|                     layer.tagRenderings = tagRenderingsPlus | ||||
|                 } else { | ||||
| 
 | ||||
|                     let index = layer.tagRenderings.findIndex(tr => tr["id"] === "leftover-questions") | ||||
|                     if (index < 0) { | ||||
|                         index = layer.tagRenderings.length - 1 | ||||
|                     } | ||||
|                     layer.tagRenderings.splice(index, 0, ...tagRenderingsPlus) | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             newLayers.push(layer) | ||||
|         } | ||||
|         json.layers = newLayers | ||||
|  | @ -317,7 +338,7 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { | |||
|             Some layers (e.g. \`all_buildings_and_walls\' or \'streets_with_a_name\') are invisible, so by default, \'force_load\' is set too.
 | ||||
|             `,
 | ||||
|             ["layers"], | ||||
|             "AddDependencyLayersToTheme" | ||||
|             "AddDependencyLayersToTheme", | ||||
|         ) | ||||
|         this._state = state | ||||
|     } | ||||
|  | @ -325,7 +346,7 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { | |||
|     private static CalculateDependencies( | ||||
|         alreadyLoaded: LayerConfigJson[], | ||||
|         allKnownLayers: Map<string, LayerConfigJson>, | ||||
|         themeId: string | ||||
|         themeId: string, | ||||
|     ): { config: LayerConfigJson; reason: string }[] { | ||||
|         const dependenciesToAdd: { config: LayerConfigJson; reason: string }[] = [] | ||||
|         const loadedLayerIds: Set<string> = new Set<string>(alreadyLoaded.map((l) => l.id)) | ||||
|  | @ -348,7 +369,7 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { | |||
|             for (const layerConfig of alreadyLoaded) { | ||||
|                 try { | ||||
|                     const layerDeps = DependencyCalculator.getLayerDependencies( | ||||
|                         new LayerConfig(layerConfig, themeId + "(dependencies)") | ||||
|                         new LayerConfig(layerConfig, themeId + "(dependencies)"), | ||||
|                     ) | ||||
|                     dependencies.push(...layerDeps) | ||||
|                 } catch (e) { | ||||
|  | @ -385,10 +406,10 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { | |||
|                 if (dep === undefined) { | ||||
|                     const message = [ | ||||
|                         "Loading a dependency failed: layer " + | ||||
|                             unmetDependency.neededLayer + | ||||
|                             " is not found, neither as layer of " + | ||||
|                             themeId + | ||||
|                             " nor as builtin layer.", | ||||
|                         unmetDependency.neededLayer + | ||||
|                         " is not found, neither as layer of " + | ||||
|                         themeId + | ||||
|                         " nor as builtin layer.", | ||||
|                         reason, | ||||
|                         "Loaded layers are: " + alreadyLoaded.map((l) => l.id).join(","), | ||||
|                     ] | ||||
|  | @ -404,7 +425,7 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { | |||
|                 }) | ||||
|                 loadedLayerIds.add(dep.id) | ||||
|                 unmetDependencies = unmetDependencies.filter( | ||||
|                     (d) => d.neededLayer !== unmetDependency.neededLayer | ||||
|                     (d) => d.neededLayer !== unmetDependency.neededLayer, | ||||
|                 ) | ||||
|             } | ||||
|         } while (unmetDependencies.length > 0) | ||||
|  | @ -425,14 +446,14 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { | |||
|         const dependencies = AddDependencyLayersToTheme.CalculateDependencies( | ||||
|             layers, | ||||
|             allKnownLayers, | ||||
|             theme.id | ||||
|             theme.id, | ||||
|         ) | ||||
|         for (const dependency of dependencies) { | ||||
|         } | ||||
|         if (dependencies.length > 0) { | ||||
|             for (const dependency of dependencies) { | ||||
|                 context.info( | ||||
|                     "Added " + dependency.config.id + " to the theme. " + dependency.reason | ||||
|                     "Added " + dependency.config.id + " to the theme. " + dependency.reason, | ||||
|                 ) | ||||
|             } | ||||
|         } | ||||
|  | @ -474,7 +495,7 @@ class WarnForUnsubstitutedLayersInTheme extends DesugaringStep<LayoutConfigJson> | |||
|         super( | ||||
|             "Generates a warning if a theme uses an unsubstituted layer", | ||||
|             ["layers"], | ||||
|             "WarnForUnsubstitutedLayersInTheme" | ||||
|             "WarnForUnsubstitutedLayersInTheme", | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|  | @ -486,7 +507,7 @@ class WarnForUnsubstitutedLayersInTheme extends DesugaringStep<LayoutConfigJson> | |||
|             context | ||||
|                 .enter("layers") | ||||
|                 .err( | ||||
|                     "No layers are defined. You must define at least one layer to have a valid theme" | ||||
|                     "No layers are defined. You must define at least one layer to have a valid theme", | ||||
|                 ) | ||||
|             return json | ||||
|         } | ||||
|  | @ -510,10 +531,10 @@ class WarnForUnsubstitutedLayersInTheme extends DesugaringStep<LayoutConfigJson> | |||
| 
 | ||||
|             context.warn( | ||||
|                 "The theme " + | ||||
|                     json.id + | ||||
|                     " has an inline layer: " + | ||||
|                     layer["id"] + | ||||
|                     ". This is discouraged." | ||||
|                 json.id + | ||||
|                 " has an inline layer: " + | ||||
|                 layer["id"] + | ||||
|                 ". This is discouraged.", | ||||
|             ) | ||||
|         } | ||||
|         return json | ||||
|  | @ -522,11 +543,12 @@ class WarnForUnsubstitutedLayersInTheme extends DesugaringStep<LayoutConfigJson> | |||
| 
 | ||||
| export class PrepareTheme extends Fuse<LayoutConfigJson> { | ||||
|     private state: DesugaringContext | ||||
| 
 | ||||
|     constructor( | ||||
|         state: DesugaringContext, | ||||
|         options?: { | ||||
|             skipDefaultLayers: false | boolean | ||||
|         } | ||||
|         }, | ||||
|     ) { | ||||
|         super( | ||||
|             "Fully prepares and expands a theme", | ||||
|  | @ -538,7 +560,7 @@ export class PrepareTheme extends Fuse<LayoutConfigJson> { | |||
|             new SetDefault("socialImage", "assets/SocialImage.png", true), | ||||
|             // We expand all tagrenderings first...
 | ||||
|             new On("layers", new Each(new PrepareLayer(state))), | ||||
|             // Then we apply the override all
 | ||||
|             // Then we apply the override all. Note that it'll cheat with tagRenderings+
 | ||||
|             new ApplyOverrideAll(), | ||||
|             // And then we prepare all the layers _again_ in case that an override all contained unexpanded tagrenderings!
 | ||||
|             new On("layers", new Each(new PrepareLayer(state))), | ||||
|  | @ -546,7 +568,7 @@ export class PrepareTheme extends Fuse<LayoutConfigJson> { | |||
|                 ? new Pass("AddDefaultLayers is disabled due to the set flag") | ||||
|                 : new AddDefaultLayers(state), | ||||
|             new AddDependencyLayersToTheme(state), | ||||
|             new AddImportLayers() | ||||
|             new AddImportLayers(), | ||||
|         ) | ||||
|         this.state = state | ||||
|     } | ||||
|  | @ -561,13 +583,13 @@ export class PrepareTheme extends Fuse<LayoutConfigJson> { | |||
|         const needsNodeDatabase = result.layers?.some((l: LayerConfigJson) => | ||||
|             l.tagRenderings?.some((tr) => | ||||
|                 ValidationUtils.getSpecialVisualisations(<any>tr)?.some( | ||||
|                     (special) => special.needsNodeDatabase | ||||
|                 ) | ||||
|             ) | ||||
|                     (special) => special.needsNodeDatabase, | ||||
|                 ), | ||||
|             ), | ||||
|         ) | ||||
|         if (needsNodeDatabase) { | ||||
|             context.info( | ||||
|                 "Setting 'enableNodeDatabase' as this theme uses a special visualisation which needs to keep track of _all_ nodes" | ||||
|                 "Setting 'enableNodeDatabase' as this theme uses a special visualisation which needs to keep track of _all_ nodes", | ||||
|             ) | ||||
|             result.enableNodeDatabase = true | ||||
|         } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue