forked from MapComplete/MapComplete
		
	Refactoring of the climbing theme
This commit is contained in:
		
							parent
							
								
									c36bce8100
								
							
						
					
					
						commit
						bc953abe48
					
				
					 15 changed files with 1099 additions and 1001 deletions
				
			
		|  | @ -330,12 +330,19 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { | |||
|     private readonly _state: DesugaringContext; | ||||
| 
 | ||||
|     constructor(state: DesugaringContext,) { | ||||
|         super("If a layer has a dependency on another layer, these layers are added automatically on the theme. (For example: defibrillator depends on 'walls_and_buildings' to snap onto. This layer is added automatically)", ["layers"], "AddDependencyLayersToTheme"); | ||||
|         super( | ||||
|             `If a layer has a dependency on another layer, these layers are added automatically on the theme. (For example: defibrillator depends on 'walls_and_buildings' to snap onto. This layer is added automatically)
 | ||||
|              | ||||
|             Note that these layers are added _at the start_ of the layer list, meaning that they will see _every_ feature. | ||||
|             Furthermore, \`passAllFeatures\` will be set, so that they won't steal away features from further layers.
 | ||||
|             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");
 | ||||
|         this._state = state; | ||||
|     } | ||||
| 
 | ||||
|     private static CalculateDependencies(alreadyLoaded: LayerConfigJson[], allKnownLayers: Map<string, LayerConfigJson>, themeId: string): LayerConfigJson[] { | ||||
|         const dependenciesToAdd: LayerConfigJson[] = [] | ||||
|     private static CalculateDependencies(alreadyLoaded: LayerConfigJson[], allKnownLayers: Map<string, LayerConfigJson>, themeId: string): | ||||
|         {config: LayerConfigJson, reason: string}[] { | ||||
|         const dependenciesToAdd:  {config: LayerConfigJson, reason: string}[]  = [] | ||||
|         const loadedLayerIds: Set<string> = new Set<string>(alreadyLoaded.map(l => l.id)); | ||||
| 
 | ||||
|         // Verify cross-dependencies
 | ||||
|  | @ -361,35 +368,39 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { | |||
|             } | ||||
| 
 | ||||
|             // During the generate script, builtin layers are verified but not loaded - so we have to add them manually here
 | ||||
|             // Their existance is checked elsewhere, so this is fine
 | ||||
|             // Their existence is checked elsewhere, so this is fine
 | ||||
|             unmetDependencies = dependencies.filter(dep => !loadedLayerIds.has(dep.neededLayer)) | ||||
|             for (const unmetDependency of unmetDependencies) { | ||||
|                 if (loadedLayerIds.has(unmetDependency.neededLayer)) { | ||||
|                     continue | ||||
|                 } | ||||
|                 const dep = allKnownLayers.get(unmetDependency.neededLayer) | ||||
|                 const dep = Utils.Clone(allKnownLayers.get(unmetDependency.neededLayer)) | ||||
|                 const reason =  "This layer is needed by " + unmetDependency.neededBy +" because " + | ||||
|                     unmetDependency.reason + " (at " + unmetDependency.context + ")"; | ||||
|                 if (dep === undefined) { | ||||
|                     const message = | ||||
|                         ["Loading a dependency failed: layer " + unmetDependency.neededLayer + " is not found, neither as layer of " + themeId + " nor as builtin layer.", | ||||
|                             "This layer is needed by " + unmetDependency.neededBy, | ||||
|                             unmetDependency.reason + " (at " + unmetDependency.context + ")", | ||||
|                             reason, | ||||
|                             "Loaded layers are: " + alreadyLoaded.map(l => l.id).join(",") | ||||
| 
 | ||||
|                         ] | ||||
|                     throw message.join("\n\t"); | ||||
|                 } | ||||
|                 dependenciesToAdd.unshift(dep) | ||||
|                  | ||||
|                 dep.forceLoad = true; | ||||
|                 dep.passAllFeatures = true; | ||||
|                 dep.description = reason; | ||||
|                 dependenciesToAdd.unshift({ | ||||
|                     config: dep, | ||||
|                     reason | ||||
|                 }) | ||||
|                 loadedLayerIds.add(dep.id); | ||||
|                 unmetDependencies = unmetDependencies.filter(d => d.neededLayer !== unmetDependency.neededLayer) | ||||
|             } | ||||
| 
 | ||||
|         } while (unmetDependencies.length > 0) | ||||
| 
 | ||||
|         return dependenciesToAdd.map(dep => { | ||||
|             dep = Utils.Clone(dep); | ||||
|             dep.forceLoad = true | ||||
|             return dep | ||||
|         }); | ||||
|         return dependenciesToAdd | ||||
|     } | ||||
| 
 | ||||
|     convert(theme: LayoutConfigJson, context: string): { result: LayoutConfigJson; information: string[] } { | ||||
|  | @ -404,11 +415,16 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { | |||
|         }) | ||||
| 
 | ||||
|         const dependencies = AddDependencyLayersToTheme.CalculateDependencies(layers, allKnownLayers, theme.id); | ||||
|         if (dependencies.length > 0) { | ||||
|         for (const dependency of dependencies) { | ||||
|              | ||||
|             information.push(context + ": added " + dependencies.map(d => d.id).join(", ") + " to the theme as they are needed") | ||||
|         } | ||||
|         layers.unshift(...dependencies); | ||||
|         if (dependencies.length > 0) { | ||||
|             for (const dependency of dependencies) { | ||||
|             information.push(context + ": added " + dependency.config.id + " to the theme. "+dependency.reason) | ||||
|                  | ||||
|             } | ||||
|         } | ||||
|         layers.unshift(...dependencies.map(l => l.config)); | ||||
| 
 | ||||
|         return { | ||||
|             result: { | ||||
|  |  | |||
|  | @ -81,7 +81,7 @@ export default class DependencyCalculator { | |||
| 
 | ||||
|                     // The important line: steal the dependencies!
 | ||||
|                     deps.push({ | ||||
|                         neededLayer: layerId, reason: "A calculated tag loads features from this layer", | ||||
|                         neededLayer: layerId, reason: "a calculated tag loads features from this layer", | ||||
|                         context: "calculatedTag[" + currentLine + "] which calculates the value for " + currentKey, | ||||
|                         neededBy: layer.id | ||||
|                     }) | ||||
|  |  | |||
|  | @ -161,7 +161,11 @@ export default class LayerConfig extends WithContextLoader { | |||
|             this.calculatedTags = []; | ||||
|             for (const kv of json.calculatedTags) { | ||||
|                 const index = kv.indexOf("="); | ||||
|                 let key = kv.substring(0, index); | ||||
|                 let key = kv.substring(0, index).trim(); | ||||
|                 const r = "[a-z_][a-z0-9:]*" | ||||
|                 if(key.match(r) === null){ | ||||
|                     throw "At "+context+" invalid key for calculated tag: "+key+"; it should match "+r | ||||
|                 } | ||||
|                 const isStrict = key.endsWith(':') | ||||
|                 if (isStrict) { | ||||
|                     key = key.substr(0, key.length - 1) | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ import {QueryParameters} from "../../Logic/Web/QueryParameters"; | |||
| import {TagUtils} from "../../Logic/Tags/TagUtils"; | ||||
| import {InputElement} from "../Input/InputElement"; | ||||
| import {DropDown} from "../Input/DropDown"; | ||||
| import {UIElement} from "../UIElement"; | ||||
| 
 | ||||
| export default class FilterView extends VariableUiElement { | ||||
|     constructor(filteredLayer: UIEventSource<FilteredLayer[]>,  | ||||
|  | @ -33,7 +34,7 @@ export default class FilterView extends VariableUiElement { | |||
|             filteredLayer.map((filteredLayers) => { | ||||
|                     // Create the views which toggle layers (and filters them) ...
 | ||||
|                     let elements = filteredLayers | ||||
|                         ?.map(l => FilterView.createOneFilteredLayerElement(l)?.SetClass("filter-panel")) | ||||
|                         ?.map(l => FilterView.createOneFilteredLayerElement(l, State.state)?.SetClass("filter-panel")) | ||||
|                         ?.filter(l => l !== undefined) | ||||
|                     elements[0].SetClass("first-filter-panel") | ||||
|                  | ||||
|  | @ -87,10 +88,14 @@ export default class FilterView extends VariableUiElement { | |||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     private static createOneFilteredLayerElement(filteredLayer: FilteredLayer) { | ||||
|     private static createOneFilteredLayerElement(filteredLayer: FilteredLayer, state: {featureSwitchIsDebugging: UIEventSource<boolean>}) { | ||||
|         if (filteredLayer.layerDef.name === undefined) { | ||||
|             // Name is not defined: we hide this one
 | ||||
|             return undefined; | ||||
|             return new Toggle( | ||||
|                 filteredLayer.layerDef.description.Clone().SetClass("subtle")                , | ||||
|                 undefined, | ||||
|                 state.featureSwitchIsDebugging | ||||
|             ); | ||||
|         } | ||||
|         const iconStyle = "width:1.5rem;height:1.5rem;margin-left:1.25rem;flex-shrink: 0;"; | ||||
| 
 | ||||
|  |  | |||
|  | @ -85,6 +85,10 @@ export class AllTagsPanel extends VariableUiElement { | |||
|                 if (value === undefined) { | ||||
|                     continue | ||||
|                 } | ||||
|                 let type = ""; | ||||
|                 if(typeof value !== "string"){ | ||||
|                     type = " <i>"+(typeof value)+"</i>" | ||||
|                 } | ||||
|                 parts.push(["<i>" + key + "</i>", value]) | ||||
|             } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,300 +1,375 @@ | |||
| { | ||||
|   "id": "climbing", | ||||
|   "name": { | ||||
|     "nl": "Klimgelegenheden", | ||||
|     "de": "Klettermöglichkeiten", | ||||
|     "en": "Climbing opportunities", | ||||
|     "ja": "登坂教室", | ||||
|     "fr": "Opportunité d’escalade", | ||||
|     "it": "Opportunità di arrampicata" | ||||
|   }, | ||||
|   "minzoom": 10, | ||||
|   "source": { | ||||
|     "osmTags": { | ||||
|       "and": [ | ||||
|         "sport=climbing", | ||||
|         "climbing!~route", | ||||
|         "leisure!~sports_centre", | ||||
|         "climbing!=route_top", | ||||
|         "climbing!=route_bottom" | ||||
|       ] | ||||
|     } | ||||
|   }, | ||||
|   "title": { | ||||
|     "render": { | ||||
|       "en": "Climbing opportunity", | ||||
|       "nl": "Klimgelegenheid", | ||||
|       "de": "Klettermöglichkeit", | ||||
|       "ja": "登坂教室", | ||||
|       "nb_NO": "Klatremulighet", | ||||
|       "fr": "Opportunité d’escalade", | ||||
|       "it": "Opportunità di arrampicata" | ||||
|     }, | ||||
|     "mappings": [ | ||||
|       { | ||||
|         "if": "climbing=crag", | ||||
|         "then": { | ||||
|           "en": "Climbing crag <b>{name}</b>", | ||||
|           "fr": "Mur d’escalade <b>{name}</b>", | ||||
|           "it": "Muro da arrampicata <b>{name}</b>", | ||||
|           "de": "Klettergarten <b>{name}</b>" | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "if": { | ||||
|           "and": [ | ||||
|             { | ||||
|               "or": [ | ||||
|                 "climbing=area", | ||||
|                 "climbing=site" | ||||
|               ] | ||||
|             }, | ||||
|             "name~*" | ||||
|           ] | ||||
|         }, | ||||
|         "then": { | ||||
|           "en": "Climbing area <b>{name}</b>", | ||||
|           "nl": "Klimsite <b>{name}</b>", | ||||
|           "fr": "Zone d’escalade <b>{name}</b>", | ||||
|           "de": "Klettergebiet <b>{name}</b>", | ||||
|           "it": "Area di arrampicata <b>{name}</b>" | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "if": { | ||||
|           "or": [ | ||||
|             "climbing=site", | ||||
|             "climbing=area" | ||||
|           ] | ||||
|         }, | ||||
|         "then": { | ||||
|           "en": "Climbing site", | ||||
|           "nl": "Klimsite", | ||||
|           "fr": "Site d’escalade", | ||||
|           "de": "Klettergebiet", | ||||
|           "it": "Sito di arrampicata", | ||||
|           "ca": "Llocs d'escalada" | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "if": "name~*", | ||||
|         "then": { | ||||
|           "nl": "Klimgelegenheid <b>{name}</b>", | ||||
|           "en": "Climbing opportunity <b>{name}</b>", | ||||
|           "fr": "Opportunité d’escalade <b>{name}</b>", | ||||
|           "de": "Klettermöglichkeit <b>{name}</b>", | ||||
|           "it": "Opportunità di arrampicata <b>{name}</b>" | ||||
|         } | ||||
|       } | ||||
|     ] | ||||
|   }, | ||||
|   "title": null, | ||||
|   "description": { | ||||
|     "nl": "Een klimgelegenheid", | ||||
|     "de": "Eine Klettergelegenheit", | ||||
|     "en": "A climbing opportunity", | ||||
|     "ja": "登坂教室", | ||||
|     "nb_NO": "En klatremulighet", | ||||
|     "fr": "Opportunité d’escalade", | ||||
|     "it": "Un’opportunità di arrampicata" | ||||
|     "en": "A dummy layer which contains tagrenderings, shared among the climbing layers" | ||||
|   }, | ||||
|   "minzoom": 25, | ||||
|   "source": { | ||||
|     "osmTags": "sport=climbing" | ||||
|   }, | ||||
|   "tagRenderings": [ | ||||
|     "images", | ||||
|     { | ||||
|       "id": "minimap", | ||||
|       "render": "{minimap(18, id, _contained_climbing_route_ids): height: 9rem; overflow: hidden; border-radius:3rem; }" | ||||
|     }, | ||||
|     { | ||||
|       "render": { | ||||
|         "en": "<h3>Length overview</h3>{histogram(_length_hist)}", | ||||
|         "fr": "<h3>Résumé de longueur</h3>{histogram(_length_hist)}", | ||||
|         "de": "<h3>Längenübersicht</h3>{histogram(_length_hist)}", | ||||
|         "it": "<h3>Riassunto della lunghezza</h3>{histogram(_length_hist)}" | ||||
|       "id": "website", | ||||
|       "question": { | ||||
|         "en": "Is there a (unofficial) website with more informations (e.g. topos)?", | ||||
|         "de": "Gibt es eine (inoffizielle) Website mit mehr Informationen (z.B. Topos)?", | ||||
|         "ja": "もっと情報のある(非公式の)ウェブサイトはありますか(例えば、topos)?", | ||||
|         "nl": "Is er een (onofficiële) website met meer informatie (b.v. met topos)?", | ||||
|         "ru": "Есть ли (неофициальный) веб-сайт с более подробной информацией (напр., topos)?", | ||||
|         "fr": "Existe-t’il un site avec plus d’informations (ex : topographie) ?", | ||||
|         "it": "C’è un sito web (anche non ufficiale) con qualche informazione in più (ad es. topografie)?" | ||||
|       }, | ||||
|       "condition": "_length_hist!~\\[\\]", | ||||
|       "id": "Contained routes length hist" | ||||
|     }, | ||||
|     { | ||||
|       "render": { | ||||
|         "en": "<h3>Grades overview</h3>{histogram(_difficulty_hist)}", | ||||
|         "fr": "<h3>Résumé des difficultés</h3>{histogram(_difficulty_hist)}", | ||||
|         "de": "<h3>Schwierigkeitsübersicht</h3>{histogram(_difficulty_hist)}", | ||||
|         "it": "<h3>Riassunto delle difficoltà</h3>{histogram(_difficulty_hist)}" | ||||
|       "condition": { | ||||
|         "and": [ | ||||
|           "leisure!~sports_centre", | ||||
|           "sport=climbing", | ||||
|           "office=", | ||||
|           "club=" | ||||
|         ] | ||||
|       }, | ||||
|       "condition": "_difficulty_hist!~\\[\\]", | ||||
|       "id": "Contained routes hist" | ||||
|       "render": "<a href='{url}' target='_blank'>{url}</a>", | ||||
|       "freeform": { | ||||
|         "key": "url", | ||||
|         "type": "url" | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "id": "average_length", | ||||
|       "render": { | ||||
|         "en": "<h3>Contains {_contained_climbing_routes_count} routes</h3> <ul>{_contained_climbing_routes}</ul>", | ||||
|         "fr": "<h3>Contient {_contained_climbing_routes_count} voies</h3> <ul>{_contained_climbing_routes}</ul>", | ||||
|         "it": "<h3>Contiene {_contained_climbing_routes_count} vie</h3> <ul>{_contained_climbing_routes}</ul>", | ||||
|         "de": "<h3> Enthält {_contained_climbing_routes_count} Routen</h3> <ul>{_contained_climbing_routes}</ul>" | ||||
|       }, | ||||
|       "condition": "_contained_climbing_routes~*", | ||||
|       "id": "Contained_climbing_routes" | ||||
|     }, | ||||
|     { | ||||
|       "render": { | ||||
|         "en": "<strong>{name}</strong>", | ||||
|         "nl": "<strong>{name}</strong>", | ||||
|         "de": "<strong>{name}</strong>", | ||||
|         "ca": "<strong>{name}</strong>", | ||||
|         "fr": "<strong>{name}</strong>", | ||||
|         "id": "<strong>{name}</strong>", | ||||
|         "ru": "<strong>{name}</strong>", | ||||
|         "ja": "<strong>{name}</strong>", | ||||
|         "it": "<strong>{name}</strong>" | ||||
|         "de": "Die Routen sind durchschnittlich <b>{canonical(climbing:length)}</b> lang", | ||||
|         "en": "The routes are <b>{canonical(climbing:length)}</b> long on average", | ||||
|         "nl": "De klimroutes zijn gemiddeld <b>{canonical(climbing:length)}</b> lang", | ||||
|         "ja": "ルートの長さは平均で<b>{canonical(climbing:length)}</b>です", | ||||
|         "fr": "Les voies font <b>{canonical(climbing:length)}</b> de long en moyenne", | ||||
|         "it": "Le vie sono lunghe mediamente <b>{canonical(climbing:length)}</b>" | ||||
|       }, | ||||
|       "question": { | ||||
|         "en": "What is the name of this climbing opportunity?", | ||||
|         "nl": "Wat is de naam van dit Klimgelegenheid?", | ||||
|         "de": "Wie heißt diese Klettergelegenheit?", | ||||
|         "ja": "この登坂教室の名前は何ですか?", | ||||
|         "fr": "Quel est le nom de ce site ?", | ||||
|         "it": "Qual è il nome di questa opportunità di arrampicata?" | ||||
|         "de": "Wie lang sind die Routen (durchschnittlich) in Metern?", | ||||
|         "en": "What is the (average) length of the routes in meters?", | ||||
|         "nl": "Wat is de (gemiddelde) lengte van de klimroutes, in meter?", | ||||
|         "ja": "ルートの(平均)長さはメートル単位でいくつですか?", | ||||
|         "fr": "Quelle est la longueur moyenne des voies en mètres ?", | ||||
|         "it": "Quale è la lunghezza (media) delle vie in metri?" | ||||
|       }, | ||||
|       "freeform": { | ||||
|         "key": "name" | ||||
|         "key": "climbing:length", | ||||
|         "type": "pfloat" | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "id": "min_difficulty", | ||||
|       "question": { | ||||
|         "de": "Welche Schwierigkeit hat hier die leichteste Route (französisch/belgisches System)?", | ||||
|         "en": "What is the grade of the easiest route here, according to the french classification system?", | ||||
|         "nl": "Wat is het niveau van de makkelijkste route, volgens het Franse classificatiesysteem?", | ||||
|         "ja": "ここで一番簡単なルートのレベルは、フランスのランク評価システムで何ですか?", | ||||
|         "fr": "Quel est le niveau de la voie la plus simple selon la classification franco-belge ?", | ||||
|         "it": "Qual è il livello della via più facile qua, secondo il sistema di classificazione francese?" | ||||
|       }, | ||||
|       "render": { | ||||
|         "de": "Die leichteste Route hat hier die Schwierigkeit {climbing:grade:french:min} (französisch/belgisches System)", | ||||
|         "en": "The lowest grade is {climbing:grade:french:min} according to the french/belgian system", | ||||
|         "nl": "De minimale klimmoeilijkheid is {climbing:grade:french:min} volgens het Franse/Belgische systeem", | ||||
|         "ja": "フランス/ベルギーのランク評価システムでは、最小の難易度は{climbing:grade:french:min}です", | ||||
|         "fr": "La difficulté minimale est {climbing:grade:french:min} selon la classification franco-belge", | ||||
|         "it": "Il minimo livello di difficoltà è {climbing:grade:french:min} secondo il sistema francese/belga" | ||||
|       }, | ||||
|       "freeform": { | ||||
|         "key": "climbing:grade:french:min" | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "id": "max_difficulty", | ||||
|       "question": { | ||||
|         "de": "Welche Schwierigkeit hat hier die schwerste Route (französisch/belgisches System)?", | ||||
|         "en": "What is the highest grade route here, according to the french classification system?", | ||||
|         "nl": "Wat is het niveau van de moeilijkste route, volgens het Franse classificatiesysteem?", | ||||
|         "ja": "フランスのランク評価によると、ここで一番難しいルートのレベルはどれくらいですか?", | ||||
|         "fr": "Quel est le niveau de la voie la plus difficile selon la classification franco-belge ?", | ||||
|         "it": "Qual è il livello della via più difficile qua, secondo il sistema di classificazione francese?" | ||||
|       }, | ||||
|       "render": { | ||||
|         "de": "Die schwierigste Route hat hier die Schwierigkeitsstufe {climbing:grade:french:max} (französisch/belgisches System)", | ||||
|         "en": "The highest grade is {climbing:grade:french:max} according to the french/belgian system", | ||||
|         "nl": "De maximale klimmoeilijkheid is {climbing:grade:french:max} volgens het Franse/Belgische systeem", | ||||
|         "ja": "フランス/ベルギーのランク評価システムでは、最大の難易度は{climbing:grade:french:max}です", | ||||
|         "fr": "La difficulté maximale est {climbing:grade:french:max} selon la classification franco-belge", | ||||
|         "it": "Il massimo livello di difficoltà è {climbing:grade:french:max} secondo il sistema francese/belga" | ||||
|       }, | ||||
|       "freeform": { | ||||
|         "key": "climbing:grade:french:max" | ||||
|       }, | ||||
|       "condition": { | ||||
|         "and": [ | ||||
|           "climbing!~route", | ||||
|           "office=", | ||||
|           "club=", | ||||
|           { | ||||
|             "or": [ | ||||
|               "climbing:sport=yes", | ||||
|               "sport=climbing" | ||||
|             ] | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "id": "bouldering", | ||||
|       "question": { | ||||
|         "de": "Kann hier gebouldert werden?", | ||||
|         "en": "Is bouldering possible here?", | ||||
|         "nl": "Is het mogelijk om hier te bolderen?", | ||||
|         "ja": "ここでボルダリングはできますか?", | ||||
|         "nb_NO": "Er buldring mulig her?", | ||||
|         "fr": "L’escalade de bloc est-elle possible ici ?", | ||||
|         "it": "È possibile praticare ‘bouldering’ qua?" | ||||
|       }, | ||||
|       "mappings": [ | ||||
|         { | ||||
|           "if": "climbing:boulder=yes", | ||||
|           "then": { | ||||
|             "de": "Hier kann gebouldert werden", | ||||
|             "en": "Bouldering is possible here", | ||||
|             "nl": "Bolderen kan hier", | ||||
|             "ja": "ボルダリングはここで可能です", | ||||
|             "nb_NO": "Buldring er mulig her", | ||||
|             "fr": "L’escalade de bloc est possible", | ||||
|             "it": "L’arrampicata su massi è possibile qua" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing:boulder=no", | ||||
|           "then": { | ||||
|             "de": "Hier kann nicht gebouldert werden", | ||||
|             "en": "Bouldering is not possible here", | ||||
|             "nl": "Bolderen kan hier niet", | ||||
|             "ja": "ここではボルダリングはできません", | ||||
|             "nb_NO": "Buldring er ikke mulig her", | ||||
|             "fr": "L’escalade de bloc n’est pas possible", | ||||
|             "it": "L’arrampicata su massi non è possibile qua" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing:boulder=limited", | ||||
|           "then": { | ||||
|             "de": "Bouldern ist hier nur an wenigen Routen möglich", | ||||
|             "en": "Bouldering is possible, allthough there are only a few routes", | ||||
|             "nl": "Bolderen kan hier, maar er zijn niet zoveel routes", | ||||
|             "ja": "ボルダリングは可能ですが、少しのルートしかありません", | ||||
|             "fr": "L’escalade de bloc est possible sur des voies précises", | ||||
|             "it": "L’arrampicata su massi è possibile anche se su poche vie" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing:boulder~*", | ||||
|           "then": { | ||||
|             "de": "Hier gibt es {climbing:boulder} Boulder-Routen", | ||||
|             "en": "There are {climbing:boulder} boulder routes", | ||||
|             "nl": "Er zijn hier {climbing:boulder} bolderroutes", | ||||
|             "ja": "{climbing:boulder} ボルダールートがある", | ||||
|             "fr": "Il y a {climbing:boulder} voies d’escalade de bloc", | ||||
|             "it": "Sono presenti {climbing:boulder} vie di arrampicata su massi" | ||||
|           }, | ||||
|           "hideInAnswer": true | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "id": "toprope", | ||||
|       "question": { | ||||
|         "de": "Ist Toprope-Klettern hier möglich?", | ||||
|         "en": "Is toprope climbing possible here?", | ||||
|         "nl": "Is het mogelijk om hier te toprope-klimmen?", | ||||
|         "ja": "ここでtoprope登坂はできますか?", | ||||
|         "fr": "Est-il possible d’escalader à la moulinette ?", | ||||
|         "it": "È possibile arrampicarsi con la corda dall’alto qua?" | ||||
|       }, | ||||
|       "mappings": [ | ||||
|         { | ||||
|           "if": "climbing:toprope=yes", | ||||
|           "then": { | ||||
|             "de": "Toprope-Klettern ist hier möglich", | ||||
|             "en": "Toprope climbing is possible here", | ||||
|             "nl": "Toprope-klimmen kan hier", | ||||
|             "ja": "ここでToprope登坂ができます", | ||||
|             "fr": "L’escalade à la moulinette est possible", | ||||
|             "it": "È possibile arrampicarsi con moulinette qua" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing:toprope=no", | ||||
|           "then": { | ||||
|             "de": "Toprope-Climbing ist hier nicht möglich", | ||||
|             "en": "Toprope climbing is not possible here", | ||||
|             "nl": "Toprope-klimmen kan hier niet", | ||||
|             "ja": "ここではToprope登坂はできません", | ||||
|             "fr": "L’escalade à la moulinette n’est pas possible", | ||||
|             "it": "Non è possibile arrampicarsi con moulinette qua" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing:toprope~*", | ||||
|           "then": { | ||||
|             "de": "Hier gibt es {climbing:toprope} Toprope-Routen", | ||||
|             "en": "There are {climbing:toprope} toprope routes", | ||||
|             "nl": "Er zijn hier {climbing:toprope} toprope routes", | ||||
|             "ja": "{climbing:toprope} 登坂ルートがある", | ||||
|             "fr": "{climbing:toprope} voies sont équipées de moulinettes", | ||||
|             "it": "Sono presenti {climbing:toprope} vie con moulinette" | ||||
|           }, | ||||
|           "hideInAnswer": true | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "id": "sportclimbing", | ||||
|       "question": { | ||||
|         "de": "Ist hier Sportklettern möglich (feste Ankerpunkte)?", | ||||
|         "en": "Is sport climbing possible here on fixed anchors?", | ||||
|         "nl": "Is het mogelijk om hier te sportklimmen/voorklimmen op reeds aangebrachte haken?", | ||||
|         "ja": "ここでは固定アンカー式のスポーツクライミングはできますか?", | ||||
|         "it": "È possibile arrampicarsi qua con ancoraggi fissi?" | ||||
|       }, | ||||
|       "mappings": [ | ||||
|         { | ||||
|           "if": "climbing:sport=yes", | ||||
|           "then": { | ||||
|             "de": "Sportklettern ist hier möglich", | ||||
|             "en": "Sport climbing is possible here", | ||||
|             "nl": "Sportklimmen/voorklimmen kan hier", | ||||
|             "ru": "Здесь можно заняться спортивным скалолазанием", | ||||
|             "ja": "ここでスポーツクライミングができます", | ||||
|             "it": "L’arrampicata sportiva è possibile qua", | ||||
|             "hu": "Itt lehetőség van sportmászásra", | ||||
|             "fr": "De l’escalade est possible ici" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing:sport=no", | ||||
|           "then": { | ||||
|             "de": "Sportklettern ist hier nicht möglich", | ||||
|             "en": "Sport climbing is not possible here", | ||||
|             "nl": "Sportklimmen/voorklimmen kan hier niet", | ||||
|             "ru": "Спортивное скалолазание здесь невозможно", | ||||
|             "ja": "ここではスポーツクライミングはできません", | ||||
|             "it": "L’arrampicata sportiva non è possibile qua", | ||||
|             "hu": "Itt nincs lehetőség sportmászásra", | ||||
|             "fr": "L’escalade est impossible ici" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing:sport~*", | ||||
|           "then": { | ||||
|             "de": "Hier gibt es {climbing:sport} Sportkletter-Routen", | ||||
|             "en": "There are {climbing:sport} sport climbing routes", | ||||
|             "nl": "Er zijn hier {climbing:sport} sportklimroutes/voorklimroutes", | ||||
|             "ja": "スポーツクライミングの {climbing:sport} ルートがある", | ||||
|             "it": "Sono presenti {climbing:sport} vie di arrampicata sportiva" | ||||
|           }, | ||||
|           "hideInAnswer": true | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "id": "trad_climbing", | ||||
|       "question": { | ||||
|         "de": "Ist hier traditionelles Klettern möglich (eigene Sicherung z.B. mit Klemmkleilen)?", | ||||
|         "en": "Is traditional climbing possible here (using own gear e.g. chocks)?", | ||||
|         "nl": "Is het mogelijk om hier traditioneel te klimmen? <br/><span class='subtle'>(Dit is klimmen met klemblokjes en friends)</span>", | ||||
|         "ja": "伝統的な登山はここで可能ですか(例えば、チョックのような独自のギアを使用して)?", | ||||
|         "it": "È possibile arrampicarsi in maniera tradizionale qua (usando attrezzi propri, ad es. dadi)?" | ||||
|       }, | ||||
|       "mappings": [ | ||||
|         { | ||||
|           "if": "climbing:traditional=yes", | ||||
|           "then": { | ||||
|             "de": "Traditionelles Klettern ist hier möglich", | ||||
|             "en": "Traditional climbing is possible here", | ||||
|             "nl": "Traditioneel klimmen kan hier", | ||||
|             "ja": "ここでは伝統的な登山が可能です", | ||||
|             "it": "L’arrampicata tradizionale è possibile qua" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing:traditional=no", | ||||
|           "then": { | ||||
|             "de": "Traditionelles Klettern ist hier nicht möglich", | ||||
|             "en": "Traditional climbing is not possible here", | ||||
|             "nl": "Traditioneel klimmen kan hier niet", | ||||
|             "ja": "伝統的な登山はここではできない", | ||||
|             "it": "L’arrampicata tradizionale non è possibile qua" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing:traditional~*", | ||||
|           "then": { | ||||
|             "de": "Hier gibt es {climbing:traditional} Routen für traditionelles Klettern", | ||||
|             "en": "There are {climbing:traditional} traditional climbing routes", | ||||
|             "nl": "Er zijn hier {climbing:traditional} traditionele klimroutes", | ||||
|             "ja": "{climbing:traditional} の伝統的な登山ルートがある", | ||||
|             "it": "Sono presenti {climbing:traditional} vie di arrampicata tradizionale" | ||||
|           }, | ||||
|           "hideInAnswer": true | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "id": "max_bolts", | ||||
|       "question": { | ||||
|         "en": "How many bolts do routes in {title()} have at most?" | ||||
|       }, | ||||
|       "render": { | ||||
|         "en": "The sport climbing routes here have at most {climbing:bolts:max} bolts.<div class='subtle'>This is without relays and indicates how much quickdraws a climber needs</div>" | ||||
|       }, | ||||
|       "freeform": { | ||||
|         "key": "climbing:bolts:max", | ||||
|         "type": "pnat", | ||||
|         "addExtraTag": [ | ||||
|           "climbing:sport=yes" | ||||
|         ], | ||||
|         "inline": true | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "id": "fee", | ||||
|       "question": { | ||||
|         "en": "Is a fee required to climb here?" | ||||
|       }, | ||||
|       "render": { | ||||
|         "en": "A fee of {charge} should be paid for climbing here" | ||||
|       }, | ||||
|       "freeform": { | ||||
|         "key": "charge", | ||||
|         "addExtraTags": [ | ||||
|           "fee=yes" | ||||
|         ], | ||||
|         "inline": true | ||||
|       }, | ||||
|       "mappings": [ | ||||
|         { | ||||
|           "if": "fee=no", | ||||
|           "addExtraTags": [ | ||||
|             "charge=" | ||||
|           ], | ||||
|           "then": { | ||||
|             "en": "Climbing here is free of charge" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": { | ||||
|             "and": [ | ||||
|               "noname=yes", | ||||
|               "name=" | ||||
|               "fee=yes", | ||||
|               "charge=" | ||||
|             ] | ||||
|           }, | ||||
|           "then": { | ||||
|             "en": "This climbing opportunity doesn't have a name", | ||||
|             "nl": "Dit Klimgelegenheid heeft geen naam", | ||||
|             "de": "Diese Klettergelegenheit hat keinen Namen", | ||||
|             "ja": "この登坂教室には名前がついていない", | ||||
|             "fr": "Ce site n’a pas de nom", | ||||
|             "it": "Questa opportunità di arrampicata non ha un nome" | ||||
|           } | ||||
|             "en": "Paying a fee is required to climb here" | ||||
|           }, | ||||
|           "hideInAnswer": "charge~*" | ||||
|         } | ||||
|       ], | ||||
|       "id": "name" | ||||
|     }, | ||||
|     { | ||||
|       "question": "What kind of climbing opportunity is this?", | ||||
|       "mappings": [ | ||||
|         { | ||||
|           "if": "climbing=boulder", | ||||
|           "then": { | ||||
|             "en": "A climbing boulder - a single rock or cliff with one or a few climbing routes which can be climbed safely without rope", | ||||
|             "fr": "Rocher d’escalade, rocher avec une ou peu de voie permettant d’escalader sans corde", | ||||
|             "de": "Ein Kletterfelsen - ein einzelner Felsen oder eine Klippe mit einer oder wenigen Kletterrouten, die ohne Seil sicher bestiegen werden können", | ||||
|             "it": "Un masso per arrampicata (una singola roccia o falesia con una o poche vie di arrampicata che possono essere scalate in sicurezza senza una corda)" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing=crag", | ||||
|           "then": { | ||||
|             "en": "A climbing crag - a single rock or cliff with at least a few climbing routes", | ||||
|             "fr": "Mur d’escalade, rocher avec plusieurs voies d’escalades", | ||||
|             "it": "Un muro da arrampicata (un singolo masso o falesia con almeno qualche via per arrampicata)", | ||||
|             "de": "Ein Kletterfelsen - ein einzelner Fels oder eine Klippe mit mindestens einigen Kletterrouten" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing=area", | ||||
|           "then": "A climbing area with one or more climbing crags and/or boulders" | ||||
|         } | ||||
|       ], | ||||
|       "id": "Type" | ||||
|     }, | ||||
|     { | ||||
|       "question": { | ||||
|         "en": "What is the rock type here?", | ||||
|         "fr": "Quel est le type de roche ?", | ||||
|         "de": "Welchen Gesteinstyp gibt es hier?", | ||||
|         "it": "Qual è il tipo di roccia qua?" | ||||
|       }, | ||||
|       "render": { | ||||
|         "en": "The rock type is {rock}", | ||||
|         "fr": "La roche est du {rock}", | ||||
|         "de": "Der Gesteinstyp ist {rock}", | ||||
|         "it": "Il tipo di roccia è {rock}" | ||||
|       }, | ||||
|       "freeform": { | ||||
|         "key": "rock" | ||||
|       }, | ||||
|       "mappings": [ | ||||
|         { | ||||
|           "if": "rock=limestone", | ||||
|           "then": { | ||||
|             "en": "Limestone", | ||||
|             "nl": "Kalksteen", | ||||
|             "fr": "Calcaire", | ||||
|             "de": "Kalkstein", | ||||
|             "it": "Calcare" | ||||
|           } | ||||
|         } | ||||
|       ], | ||||
|       "condition": { | ||||
|         "or": [ | ||||
|           "climbing=crag", | ||||
|           "natural=cliff", | ||||
|           "natural=bare_rock" | ||||
|         ] | ||||
|       }, | ||||
|       "id": "Rock type (crag/rock/cliff only)" | ||||
|     } | ||||
|   ], | ||||
|   "presets": [ | ||||
|     { | ||||
|       "tags": [ | ||||
|         "sport=climbing" | ||||
|       ], | ||||
|       "title": { | ||||
|         "en": "a climbing opportunity", | ||||
|         "nl": "een klimgelegenheid", | ||||
|         "de": "eine klettermöglichkeit", | ||||
|         "ja": "登坂教室", | ||||
|         "nb_NO": "en klatremulighet", | ||||
|         "fr": "une opportunité d’escalade", | ||||
|         "it": "una opportunità di arrampicata" | ||||
|       }, | ||||
|       "description": { | ||||
|         "nl": "Een klimgelegenheid", | ||||
|         "de": "Eine Klettergelegenheit", | ||||
|         "en": "A climbing opportunity", | ||||
|         "ja": "登坂教室", | ||||
|         "nb_NO": "En klatremulighet", | ||||
|         "fr": "Opportunité d’escalade", | ||||
|         "it": "Un’opportunità di arrampicata" | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
|   "calculatedTags": [ | ||||
|     "_contained_climbing_routes_properties=feat.overlapWith('climbing_route').map(f => f.feat.properties).map(p => {return {id: p.id, name: p.name, 'climbing:grade:french': p['climbing:grade:french'], 'climbing:length': p['climbing:length']} })", | ||||
|     "_contained_climbing_routes=JSON.parse(feat.properties._contained_climbing_routes_properties ?? '[]').map(p => `<li><a href='#${p.id}'>${p.name ?? 'climbing route'}</a> (<b>${p['climbing:grade:french'] ?? 'unknown difficulty'}</b>, ${p['climbing:length'] ?? 'unkown length'} meter)</li>`).join('')", | ||||
|     "_contained_climbing_route_ids=JSON.parse(feat.properties._contained_climbing_routes_properties ?? '[]').map(p => p.id)", | ||||
|     "_difficulty_hist=JSON.parse(feat.properties._contained_climbing_routes_properties ?? '[]').map(p => p['climbing:grade:french'])", | ||||
|     "_length_hist=JSON.parse(feat.properties._contained_climbing_routes_properties ?? '[]').map(p => p['climbing:length'])", | ||||
|     "_contained_climbing_routes_count=JSON.parse(feat.properties._contained_climbing_routes_properties ?? '[]').length" | ||||
|   ], | ||||
|   "mapRendering": [ | ||||
|     { | ||||
|       "icon": { | ||||
|         "render": "./assets/themes/climbing/climbing_no_rope.svg" | ||||
|       }, | ||||
|       "iconSize": { | ||||
|         "render": "40,40,center" | ||||
|       }, | ||||
|       "location": [ | ||||
|         "point", | ||||
|         "centroid" | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "color": { | ||||
|         "render": "#d38d5fAA" | ||||
|       }, | ||||
|       "width": { | ||||
|         "render": "8" | ||||
|       } | ||||
|     } | ||||
|   ] | ||||
|   ], | ||||
|   "mapRendering": null | ||||
| } | ||||
							
								
								
									
										308
									
								
								assets/layers/climbing_area/climbing_area.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								assets/layers/climbing_area/climbing_area.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,308 @@ | |||
| { | ||||
|   "id": "climbing_area", | ||||
|   "name": { | ||||
|     "nl": "Klimgelegenheden", | ||||
|     "de": "Klettermöglichkeiten", | ||||
|     "en": "Climbing opportunities", | ||||
|     "ja": "登坂教室", | ||||
|     "fr": "Opportunité d’escalade", | ||||
|     "it": "Opportunità di arrampicata" | ||||
|   }, | ||||
|   "description": { | ||||
|     "en": "An area where climbing is possible, e.g. a crag, site, boulder, ... Contains aggregation of routes" | ||||
|   }, | ||||
|   "minzoom": 10, | ||||
|   "source": { | ||||
|     "osmTags": { | ||||
|       "and": [ | ||||
|         "sport=climbing", | ||||
|         "climbing!~route", | ||||
|         "leisure!~sports_centre", | ||||
|         "climbing!=route_top", | ||||
|         "climbing!=route_bottom" | ||||
|       ] | ||||
|     } | ||||
|   }, | ||||
|   "title": { | ||||
|     "render": { | ||||
|       "en": "Climbing opportunity", | ||||
|       "nl": "Klimgelegenheid", | ||||
|       "de": "Klettermöglichkeit", | ||||
|       "ja": "登坂教室", | ||||
|       "nb_NO": "Klatremulighet", | ||||
|       "fr": "Opportunité d’escalade", | ||||
|       "it": "Opportunità di arrampicata" | ||||
|     }, | ||||
|     "mappings": [ | ||||
|       { | ||||
|         "if": "climbing=crag", | ||||
|         "then": { | ||||
|           "en": "Climbing crag <b>{name}</b>", | ||||
|           "fr": "Mur d’escalade <b>{name}</b>", | ||||
|           "it": "Muro da arrampicata <b>{name}</b>", | ||||
|           "de": "Klettergarten <b>{name}</b>" | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "if": { | ||||
|           "and": [ | ||||
|             { | ||||
|               "or": [ | ||||
|                 "climbing=area", | ||||
|                 "climbing=site" | ||||
|               ] | ||||
|             }, | ||||
|             "name~*" | ||||
|           ] | ||||
|         }, | ||||
|         "then": { | ||||
|           "en": "Climbing area <b>{name}</b>", | ||||
|           "nl": "Klimsite <b>{name}</b>", | ||||
|           "fr": "Zone d’escalade <b>{name}</b>", | ||||
|           "de": "Klettergebiet <b>{name}</b>", | ||||
|           "it": "Area di arrampicata <b>{name}</b>" | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "if": { | ||||
|           "or": [ | ||||
|             "climbing=site", | ||||
|             "climbing=area" | ||||
|           ] | ||||
|         }, | ||||
|         "then": { | ||||
|           "en": "Climbing site", | ||||
|           "nl": "Klimsite", | ||||
|           "fr": "Site d’escalade", | ||||
|           "de": "Klettergebiet", | ||||
|           "it": "Sito di arrampicata", | ||||
|           "ca": "Llocs d'escalada" | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "if": "name~*", | ||||
|         "then": { | ||||
|           "nl": "Klimgelegenheid <b>{name}</b>", | ||||
|           "en": "Climbing opportunity <b>{name}</b>", | ||||
|           "fr": "Opportunité d’escalade <b>{name}</b>", | ||||
|           "de": "Klettermöglichkeit <b>{name}</b>", | ||||
|           "it": "Opportunità di arrampicata <b>{name}</b>" | ||||
|         } | ||||
|       } | ||||
|     ] | ||||
|   }, | ||||
|   "calculatedTags": [ | ||||
|     "_contained_climbing_routes_properties=feat.overlapWith('climbing_route').map(f => f.feat.properties).map(p => {return {id: p.id, name: p.name, 'climbing:grade:french': p['climbing:grade:french'], 'climbing:length': p['climbing:length']} })", | ||||
|     "_contained_climbing_routes=feat.get('_contained_climbing_routes_properties')?.map(p => `<li><a href='#${p.id}'>${p.name ?? 'climbing route'}</a> (<b>${p['climbing:grade:french'] ?? 'unknown difficulty'}</b>, ${p['climbing:length'] ?? 'unkown length'} meter)</li>`).join('')", | ||||
|     "_contained_climbing_route_ids=feat.get('_contained_climbing_routes_properties')?.map(p => p.id)", | ||||
|     "_difficulty_hist=feat.get('_contained_climbing_routes_properties')?.map(p => p['climbing:grade:french'])?.filter(p => (p ?? null) !== null)?.sort()", | ||||
|     "_difficulty_max=feat.get('_difficulty_hist')?.at(-1)", | ||||
|     "_difficulty_min=feat.get('_difficulty_hist')?.at(0)", | ||||
|     "_length_hist=feat.get('_contained_climbing_routes_properties')?.map(p => p['climbing:length'])?.filter(p => (p ?? null)  !== null)?.sort()", | ||||
|     "_length_max=feat.get('_length_hist')?.at(-1)", | ||||
|     "_length_min=feat.get('_length_hist')?.at(0)", | ||||
|     "_bolts_hist=feat.get('_contained_climbing_routes_properties')?.map(p => p['climbing:bolts'])?.filter(p => (p ?? null)  !== null)?.sort()", | ||||
|     "_bolts_max=feat.get('_bolts_hist')?.at(-1)", | ||||
|     "_bolts_min=feat.get('_bolts_hist')?.at(0)", | ||||
|     "_contained_climbing_routes_count=feat.get('_contained_climbing_routes_properties')?.length" | ||||
|   ], | ||||
|   "tagRenderings": [ | ||||
|     "images", | ||||
|     { | ||||
|       "id": "minimap", | ||||
|       "render": "{minimap(18, id, _contained_climbing_route_ids): height: 9rem; overflow: hidden; border-radius:3rem; }" | ||||
|     }, | ||||
|     { | ||||
|       "render": { | ||||
|         "en": "<h3>Length overview</h3>{histogram(_length_hist)}", | ||||
|         "fr": "<h3>Résumé de longueur</h3>{histogram(_length_hist)}", | ||||
|         "de": "<h3>Längenübersicht</h3>{histogram(_length_hist)}", | ||||
|         "it": "<h3>Riassunto della lunghezza</h3>{histogram(_length_hist)}" | ||||
|       }, | ||||
|       "condition": "_length_hist!~\\[\\]", | ||||
|       "id": "Contained routes length hist" | ||||
|     }, | ||||
|     { | ||||
|       "render": { | ||||
|         "en": "<h3>Grades overview</h3>{histogram(_difficulty_hist)}", | ||||
|         "fr": "<h3>Résumé des difficultés</h3>{histogram(_difficulty_hist)}", | ||||
|         "de": "<h3>Schwierigkeitsübersicht</h3>{histogram(_difficulty_hist)}", | ||||
|         "it": "<h3>Riassunto delle difficoltà</h3>{histogram(_difficulty_hist)}" | ||||
|       }, | ||||
|       "condition": "_difficulty_hist!~\\[\\]", | ||||
|       "id": "Contained routes hist" | ||||
|     }, | ||||
|     { | ||||
|       "render": { | ||||
|         "en": "<h3>Contains {_contained_climbing_routes_count} routes</h3> <ul>{_contained_climbing_routes}</ul>", | ||||
|         "fr": "<h3>Contient {_contained_climbing_routes_count} voies</h3> <ul>{_contained_climbing_routes}</ul>", | ||||
|         "it": "<h3>Contiene {_contained_climbing_routes_count} vie</h3> <ul>{_contained_climbing_routes}</ul>", | ||||
|         "de": "<h3> Enthält {_contained_climbing_routes_count} Routen</h3> <ul>{_contained_climbing_routes}</ul>" | ||||
|       }, | ||||
|       "condition": "_contained_climbing_routes~*", | ||||
|       "id": "Contained_climbing_routes" | ||||
|     }, | ||||
|     { | ||||
|       "render": { | ||||
|         "en": "<strong>{name}</strong>", | ||||
|         "nl": "<strong>{name}</strong>", | ||||
|         "de": "<strong>{name}</strong>", | ||||
|         "ca": "<strong>{name}</strong>", | ||||
|         "fr": "<strong>{name}</strong>", | ||||
|         "id": "<strong>{name}</strong>", | ||||
|         "ru": "<strong>{name}</strong>", | ||||
|         "ja": "<strong>{name}</strong>", | ||||
|         "it": "<strong>{name}</strong>" | ||||
|       }, | ||||
|       "question": { | ||||
|         "en": "What is the name of this climbing opportunity?", | ||||
|         "nl": "Wat is de naam van dit Klimgelegenheid?", | ||||
|         "de": "Wie heißt diese Klettergelegenheit?", | ||||
|         "ja": "この登坂教室の名前は何ですか?", | ||||
|         "fr": "Quel est le nom de ce site ?", | ||||
|         "it": "Qual è il nome di questa opportunità di arrampicata?" | ||||
|       }, | ||||
|       "freeform": { | ||||
|         "key": "name" | ||||
|       }, | ||||
|       "mappings": [ | ||||
|         { | ||||
|           "if": { | ||||
|             "and": [ | ||||
|               "noname=yes", | ||||
|               "name=" | ||||
|             ] | ||||
|           }, | ||||
|           "then": { | ||||
|             "en": "This climbing opportunity doesn't have a name", | ||||
|             "nl": "Dit Klimgelegenheid heeft geen naam", | ||||
|             "de": "Diese Klettergelegenheit hat keinen Namen", | ||||
|             "ja": "この登坂教室には名前がついていない", | ||||
|             "fr": "Ce site n’a pas de nom", | ||||
|             "it": "Questa opportunità di arrampicata non ha un nome" | ||||
|           } | ||||
|         } | ||||
|       ], | ||||
|       "id": "name" | ||||
|     }, | ||||
|     { | ||||
|       "question": "What kind of climbing opportunity is this?", | ||||
|       "mappings": [ | ||||
|         { | ||||
|           "if": "climbing=boulder", | ||||
|           "then": { | ||||
|             "en": "A climbing boulder - a single rock or cliff with one or a few climbing routes which can be climbed safely without rope", | ||||
|             "fr": "Rocher d’escalade, rocher avec une ou peu de voie permettant d’escalader sans corde", | ||||
|             "de": "Ein Kletterfelsen - ein einzelner Felsen oder eine Klippe mit einer oder wenigen Kletterrouten, die ohne Seil sicher bestiegen werden können", | ||||
|             "it": "Un masso per arrampicata (una singola roccia o falesia con una o poche vie di arrampicata che possono essere scalate in sicurezza senza una corda)" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing=crag", | ||||
|           "then": { | ||||
|             "en": "A climbing crag - a single rock or cliff with at least a few climbing routes", | ||||
|             "fr": "Mur d’escalade, rocher avec plusieurs voies d’escalades", | ||||
|             "it": "Un muro da arrampicata (un singolo masso o falesia con almeno qualche via per arrampicata)", | ||||
|             "de": "Ein Kletterfelsen - ein einzelner Fels oder eine Klippe mit mindestens einigen Kletterrouten" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing=area", | ||||
|           "then": "A climbing area with one or more climbing crags and/or boulders" | ||||
|         } | ||||
|       ], | ||||
|       "id": "Type" | ||||
|     }, | ||||
|     { | ||||
|       "question": { | ||||
|         "en": "What is the rock type here?", | ||||
|         "fr": "Quel est le type de roche ?", | ||||
|         "de": "Welchen Gesteinstyp gibt es hier?", | ||||
|         "it": "Qual è il tipo di roccia qua?" | ||||
|       }, | ||||
|       "render": { | ||||
|         "en": "The rock type is {rock}", | ||||
|         "fr": "La roche est du {rock}", | ||||
|         "de": "Der Gesteinstyp ist {rock}", | ||||
|         "it": "Il tipo di roccia è {rock}" | ||||
|       }, | ||||
|       "freeform": { | ||||
|         "key": "rock" | ||||
|       }, | ||||
|       "mappings": [ | ||||
|         { | ||||
|           "if": "rock=limestone", | ||||
|           "then": { | ||||
|             "en": "Limestone", | ||||
|             "nl": "Kalksteen", | ||||
|             "fr": "Calcaire", | ||||
|             "de": "Kalkstein", | ||||
|             "it": "Calcare" | ||||
|           } | ||||
|         } | ||||
|       ], | ||||
|       "condition": { | ||||
|         "or": [ | ||||
|           "climbing=crag", | ||||
|           "natural=cliff", | ||||
|           "natural=bare_rock" | ||||
|         ] | ||||
|       }, | ||||
|       "id": "Rock type (crag/rock/cliff only)" | ||||
|     }, | ||||
|     { | ||||
|       "builtin": [ | ||||
|         "climbing.website", | ||||
|         "climbing.fee", | ||||
|         "climbing.bouldering" | ||||
|       ] | ||||
|     } | ||||
|   ], | ||||
|   "presets": [ | ||||
|     { | ||||
|       "tags": [ | ||||
|         "sport=climbing" | ||||
|       ], | ||||
|       "title": { | ||||
|         "en": "a climbing opportunity", | ||||
|         "nl": "een klimgelegenheid", | ||||
|         "de": "eine klettermöglichkeit", | ||||
|         "ja": "登坂教室", | ||||
|         "nb_NO": "en klatremulighet", | ||||
|         "fr": "une opportunité d’escalade", | ||||
|         "it": "una opportunità di arrampicata" | ||||
|       }, | ||||
|       "description": { | ||||
|         "nl": "Een klimgelegenheid", | ||||
|         "de": "Eine Klettergelegenheit", | ||||
|         "en": "A climbing opportunity", | ||||
|         "ja": "登坂教室", | ||||
|         "nb_NO": "En klatremulighet", | ||||
|         "fr": "Opportunité d’escalade", | ||||
|         "it": "Un’opportunità di arrampicata" | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
|   "mapRendering": [ | ||||
|     { | ||||
|       "icon": { | ||||
|         "render": "./assets/themes/climbing/climbing_no_rope.svg" | ||||
|       }, | ||||
|       "iconSize": { | ||||
|         "render": "40,40,center" | ||||
|       }, | ||||
|       "location": [ | ||||
|         "point", | ||||
|         "centroid" | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "color": { | ||||
|         "render": "#d38d5fAA" | ||||
|       }, | ||||
|       "width": { | ||||
|         "render": "8" | ||||
|       } | ||||
|     } | ||||
|   ] | ||||
| } | ||||
|  | @ -55,15 +55,7 @@ | |||
|     "images", | ||||
|     { | ||||
|       "render": { | ||||
|         "en": "<strong>{name}</strong>", | ||||
|         "nl": "<strong>{name}</strong>", | ||||
|         "de": "<strong>{name}</strong>", | ||||
|         "ca": "<strong>{name}</strong>", | ||||
|         "fr": "<strong>{name}</strong>", | ||||
|         "id": "<strong>{name}</strong>", | ||||
|         "ru": "<strong>{name}</strong>", | ||||
|         "ja": "<strong>{name}</strong>", | ||||
|         "it": "<strong>{name}</strong>" | ||||
|         "*": "<strong>{name}</strong>" | ||||
|       }, | ||||
|       "question": { | ||||
|         "en": "What is the name of this climbing gym?", | ||||
|  | @ -81,7 +73,65 @@ | |||
|     "website", | ||||
|     "phone", | ||||
|     "email", | ||||
|     "opening_hours" | ||||
|     { | ||||
|       "builtin": ["climbing.fee"] | ||||
|     }, | ||||
|     "opening_hours", | ||||
|     { | ||||
|       "builtin":      | ||||
|       ["climbing.average_length","climbing.min_difficulty","climbing.max_difficulty", | ||||
|         "climbing.bouldering", | ||||
|       "climbing.sportclimbing"] | ||||
|     }, | ||||
|     { | ||||
|       "builtin": "climbing.max_bolts", | ||||
|       "override": { | ||||
|         "condition": "climbing:sport=yes" | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "id": "Speed climbing?", | ||||
|       "question": { | ||||
|         "de": "Gibt es hier eine Speedkletter-Wand?", | ||||
|         "en": "Is there a speed climbing wall?", | ||||
|         "nl": "Is er een snelklimmuur (speed climbing)?", | ||||
|         "ja": "スピードクライミングウォールはありますか?", | ||||
|         "it": "È presente una prete per l’arrampicata di velocità?" | ||||
|       }, | ||||
|       "mappings": [ | ||||
|         { | ||||
|           "if": "climbing:speed=yes", | ||||
|           "then": { | ||||
|             "de": "Hier gibt es eine Speedkletter-Wand", | ||||
|             "en": "There is a speed climbing wall", | ||||
|             "nl": "Er is een snelklimmuur voor speed climbing", | ||||
|             "ja": "スピードクライミングウォールがある", | ||||
|             "it": "È presente una parete per l’arrampicata di velocità" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing:speed=no", | ||||
|           "then": { | ||||
|             "de": "Hier gibt es keine Speedkletter-Wand", | ||||
|             "en": "There is no speed climbing wall", | ||||
|             "nl": "Er is geen snelklimmuur voor speed climbing", | ||||
|             "ja": "スピードクライミングウォールがない", | ||||
|             "it": "Non è presente una parete per l’arrampicata di velocità" | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing:speed~*", | ||||
|           "then": { | ||||
|             "de": "Hier gibt es {climbing:speed} Speedkletter-Routen", | ||||
|             "en": "There are {climbing:speed} speed climbing walls", | ||||
|             "nl": "Er zijn hier {climbing:speed} snelklimmuren", | ||||
|             "ja": "{climbing:speed} のスピードクライミングウォールがある", | ||||
|             "it": "Sono presenti {climbing:speed} pareti per l’arrampicata di velocità" | ||||
|           }, | ||||
|           "hideInAnswer": true | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|   ], | ||||
|   "mapRendering": [ | ||||
|     { | ||||
|  |  | |||
|  | @ -9,6 +9,9 @@ | |||
|     "fr": "Opportunités d’escalade ?", | ||||
|     "it": "Opportunità di arrampicata?" | ||||
|   }, | ||||
|   "description": { | ||||
|     "en": "Fallback layer with items on which climbing _might_ be possible. It is loaded when zoomed in a lot, to prevent duplicate items to be added" | ||||
|   }, | ||||
|   "minzoom": 19, | ||||
|   "source": { | ||||
|     "osmTags": { | ||||
|  | @ -38,15 +41,6 @@ | |||
|       "it": "Opportunità di arrampicata?" | ||||
|     } | ||||
|   }, | ||||
|   "description": { | ||||
|     "nl": "Een klimgelegenheid?", | ||||
|     "de": "Eine Klettergelegenheit?", | ||||
|     "en": "A climbing opportunity?", | ||||
|     "ja": "登坂教室?", | ||||
|     "nb_NO": "En klatremulighet?", | ||||
|     "fr": "Opportunité d’escalade ?", | ||||
|     "it": "Un’opportunità di arrampicata?" | ||||
|   }, | ||||
|   "tagRenderings": [ | ||||
|     { | ||||
|       "id": "climbing-opportunity-name", | ||||
|  |  | |||
|  | @ -9,6 +9,9 @@ | |||
|     "fr": "Voies d’escalade", | ||||
|     "it": "Vie di arrampicata" | ||||
|   }, | ||||
|   "description": { | ||||
|     "en": "A single climbing route and its properties. Some properties are derived from the containing features" | ||||
|   }, | ||||
|   "minzoom": 18, | ||||
|   "source": { | ||||
|     "osmTags": { | ||||
|  | @ -135,6 +138,7 @@ | |||
|       "id": "Difficulty" | ||||
|     }, | ||||
|     { | ||||
|       "id": "bolts", | ||||
|       "question": { | ||||
|         "en": "How many bolts does this route have before reaching the anchor?", | ||||
|         "fr": "Combien de prises cette voie possède avant d’atteindre la moulinette ?", | ||||
|  | @ -142,7 +146,7 @@ | |||
|         "it": "Quanti bulloni sono presenti in questo percorso prima di arrivare alla moulinette?" | ||||
|       }, | ||||
|       "render": { | ||||
|         "en": "This route has {climbing:bolts} bolts", | ||||
|         "en": "This route has {climbing:bolts} bolts <div class='subtle'>This is without relays and indicates how much quickdraws a climber needs</div>", | ||||
|         "fr": "Cette voie a {climbing:bolts} prises", | ||||
|         "de": "Diese Kletterroute hat {climbing:bolts} Haken", | ||||
|         "it": "Questo percorso ha {climbing:bolts} bulloni" | ||||
|  | @ -152,7 +156,8 @@ | |||
|         "type": "pnat", | ||||
|         "addExtraTag": [ | ||||
|           "climbing:bolted=yes" | ||||
|         ] | ||||
|         ], | ||||
|         "inline": true | ||||
|       }, | ||||
|       "mappings": [ | ||||
|         { | ||||
|  | @ -163,29 +168,15 @@ | |||
|             "de": "Auf dieser Kletterroute sind keine Haken vorhanden", | ||||
|             "it": "In questo percorso non sono presenti bulloni" | ||||
|           }, | ||||
|           "hideInAnswer": true | ||||
|         }, | ||||
|         { | ||||
|           "if": "climbing:bolted=no&climbing:bolts=", | ||||
|           "then": { | ||||
|             "en": "This route is not bolted", | ||||
|             "fr": "Cette voie n’a pas de prises", | ||||
|             "de": "Auf dieser Kletterroute sind keine Haken vorhanden", | ||||
|             "it": "In questo percorso non sono presenti bulloni" | ||||
|           } | ||||
|           "addExtraTags": [ | ||||
|             "climbing:bolts=" | ||||
|           ] | ||||
|         } | ||||
|       ], | ||||
|       "id": "Bolts" | ||||
|     }, | ||||
|     { | ||||
|       "question": "Is there other relevant info?", | ||||
|       "render": "<h3>Description</h3><br/>{description}", | ||||
|       "freeform": { | ||||
|         "key": "description" | ||||
|       }, | ||||
|       "id": "Description" | ||||
|       ] | ||||
|     }, | ||||
|     "description", | ||||
|     { | ||||
|       "id": "Rock type via embedded feature", | ||||
|       "render": { | ||||
|         "en": "The rock type is {_embedding_features_with_rock:rock} as stated <a href='#{_embedding_features_with_rock:id}'>on the surrounding crag</a>", | ||||
|         "fr": "Le type de roche est {_embedding_features_with_rock:rock} selon <a href='#{_embedding_features_with_rock:id}'>le mur</a>", | ||||
|  | @ -194,8 +185,7 @@ | |||
|       }, | ||||
|       "freeform": { | ||||
|         "key": "_embedding_features_with_rock:rock" | ||||
|       }, | ||||
|       "id": "Rock type" | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
|   "presets": [ | ||||
|  |  | |||
|  | @ -43,688 +43,307 @@ | |||
|   "startZoom": 1, | ||||
|   "widenFactor": 1.5, | ||||
|   "layers": [ | ||||
|     { | ||||
|       "builtin": [ | ||||
|     "climbing_club", | ||||
|     "climbing_gym", | ||||
|     "climbing_route", | ||||
|     "climbing", | ||||
|     "climbing_area", | ||||
|     "climbing_opportunity" | ||||
|   ], | ||||
|   "overrideAll": { | ||||
|     "allowMove": { | ||||
|       "enableRelocation": false, | ||||
|       "enableImproveAccuracy": true | ||||
|     }, | ||||
|     "+titleIcons": [ | ||||
|       { | ||||
|         "render": "<div class='flex' style='word-wrap: normal; padding-right: 0.25rem;'><img src='./assets/themes/climbing/height.svg' style='height: 1.75rem;'/>{climbing:length}m</div>", | ||||
|         "condition": "climbing:length~*" | ||||
|       }, | ||||
|       { | ||||
|         "mappings": [ | ||||
|       ], | ||||
|       "override":  { | ||||
|         "allowMove": { | ||||
|           "enableRelocation": false, | ||||
|           "enableImproveAccuracy": true | ||||
|         }, | ||||
|         "+titleIcons": [ | ||||
|           { | ||||
|             "if": "climbing:bolts~*", | ||||
|             "then": "<div class='flex' style='padding-right: 0.25rem;'><img src='./assets/themes/climbing/carabiner.svg' style='width: 1rem;'/>{climbing:bolts}</div>" | ||||
|             "render": "<div class='flex' style='word-wrap: normal; padding-right: 0.25rem;'><img src='./assets/themes/climbing/height.svg' style='height: 1.75rem;'/>{climbing:length}m</div>", | ||||
|             "condition": "climbing:length~*" | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:bolted=yes", | ||||
|             "then": "<img src='./assets/themes/climbing/carabiner.svg' style='width:2rem; height:2rem'/>" | ||||
|             "mappings": [ | ||||
|               { | ||||
|                 "if": "__bolts_max~*", | ||||
|                 "then": "<div class='flex' style='padding-right: 0.25rem;'><img src='./assets/themes/climbing/carabiner.svg' style='width: 1rem;'/>{__bolts_max}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "climbing:bolted=yes", | ||||
|                 "then": "<img src='./assets/themes/climbing/carabiner.svg' style='width:2rem; height:2rem'/>" | ||||
|               } | ||||
|             ] | ||||
|           }, | ||||
|           { | ||||
|             "id": "Min difficulty", | ||||
|             "condition": "__difficulty_min~*", | ||||
|             "then": "<div class='w-8 flex justify-center rounded-left-full border border-black' style='margin-right: -5px; background-color:#ebf224'> {__difficulty_min}</div>", | ||||
| 
 | ||||
|             "mappings": [ | ||||
|               { | ||||
|                 "if": "__difficulty_min~(2|3).*", | ||||
|                 "then": "<div class='w-8 flex justify-center rounded-left-full' style='margin-right: -5px; background-color:#ebf224'> {__difficulty_min}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "__difficulty_min~4.*", | ||||
|                 "then": "<div class='w-8 flex justify-center rounded-left-full' style='margin-right: -5px; background-color:#7af224'> {__difficulty_min}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "__difficulty_min~5.*", | ||||
|                 "then": "<div class='w-8 flex justify-center rounded-left-full' style='margin-right: -5px; background-color:#f24a24'> {__difficulty_min}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "__difficulty_min~6.*", | ||||
|                 "then": "<div class='w-8 flex justify-center rounded-left-full' style='margin-right: -5px; background-color:#244af2'> {__difficulty_min}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "__difficulty_min~(7|8).*", | ||||
|                 "then": "<div class='w-8 flex justify-center rounded-left-full' style='margin-right: -5px; background-color:#e904ed'> {__difficulty_min}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "__difficulty_min~*", | ||||
|                 "then": "<div class='w-8 flex justify-center rounded-left-full' style='margin-right: -5px; background-colour:black'> {__difficulty_min}</div>" | ||||
|               } | ||||
|             ] | ||||
|           }, | ||||
|           { | ||||
|             "id": "max difficulty", | ||||
|             "condition": "__difficulty_max~*", | ||||
|             "then": "<div class='w-8 flex justify-center rounded-right-full border border-black' style='background-color:#ebf224'> {__difficulty_max}</div>", | ||||
|             "mappings": [ | ||||
|               { | ||||
|                 "if": "__difficulty_max~(2|3).*", | ||||
|                 "then": "<div class='w-8 flex justify-center rounded-right-full' style='background-color:#ebf224'> {__difficulty_max}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "__difficulty_max~4.*", | ||||
|                 "then": "<div class='w-8 flex justify-center rounded-right-full' style='background-color:#7af224'> {__difficulty_max}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "__difficulty_max~5.*", | ||||
|                 "then": "<div class='w-8 flex justify-center rounded-right-full' style='background-color:#f24a24'> {__difficulty_max}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "__difficulty_max~6.*", | ||||
|                 "then": "<div class='w-8 flex justify-center rounded-right-full' style='background-color:#244af2'> {__difficulty_max}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "__difficulty_max~(7|8).*", | ||||
|                 "then": "<div class='w-8 flex justify-center rounded-right-full' style='background-color:#e904ed'> {__difficulty_max}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "__difficulty_max~*", | ||||
|                 "then": "<div class='w-8 flex justify-center rounded-right-full' style='background-colour:black'> {__difficulty_max}</div>" | ||||
|               } | ||||
|             ] | ||||
|           }, | ||||
|           { | ||||
|             "mappings": [ | ||||
|               { | ||||
|                 "if": "climbing:grade:french~3.*", | ||||
|                 "then": "<div class='rounded-full px-1' style='background-color:#ebf224'> {climbing:grade:french}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "climbing:grade:french~4.*", | ||||
|                 "then": "<div class='rounded-full pl-2 pr-2' style='background-color:#7af224'> {climbing:grade:french}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "climbing:grade:french~5.*", | ||||
|                 "then": "<div class='rounded-full pl-2 pr-2' style='background-color:#f24a24'> {climbing:grade:french}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "climbing:grade:french~6.*", | ||||
|                 "then": "<div class='text-white rounded-full pl-2 pr-2' style='background-color:#244af2'> {climbing:grade:french}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "climbing:grade:french~7.*", | ||||
|                 "then": "<div class='text-white rounded-full pl-2 pr-2' style='background-color:#e904ed'> {climbing:grade:french}</div>" | ||||
|               }, | ||||
|               { | ||||
|                 "if": "climbing:grade:french~*", | ||||
|                 "then": "<div class='text-white rounded-full px-2' style='background-colour:black'> {climbing:grade:french}</div>" | ||||
|               } | ||||
|             ] | ||||
|           } | ||||
|         ] | ||||
|       }, | ||||
|       { | ||||
|         "mappings": [ | ||||
|           { | ||||
|             "if": "climbing:grade:french~3.*", | ||||
|             "then": "<div class='rounded-full px-1' style='background-color:#ebf224'> {climbing:grade:french}</div>" | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:grade:french~4.*", | ||||
|             "then": "<div class='rounded-full pl-2 pr-2' style='background-color:#7af224'> {climbing:grade:french}</div>" | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:grade:french~5.*", | ||||
|             "then": "<div class='rounded-full pl-2 pr-2' style='background-color:#f24a24'> {climbing:grade:french}</div>" | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:grade:french~6.*", | ||||
|             "then": "<div class='text-white rounded-full pl-2 pr-2' style='background-color:#244af2'> {climbing:grade:french}</div>" | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:grade:french~7.*", | ||||
|             "then": "<div class='text-white rounded-full pl-2 pr-2' style='background-color:#e904ed'> {climbing:grade:french}</div>" | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:grade:french~*", | ||||
|             "then": "<div class='text-white rounded-full px-2' style='background-colour:black'> {climbing:grade:french}</div>" | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     ], | ||||
|     "+calculatedTags": [ | ||||
|       "_embedding_feature_properties=feat.overlapWith('climbing').map(f => f.feat.properties).filter(p => p !== undefined).map(p => {return{access: p.access, id: p.id, name: p.name, climbing: p.climbing, 'access:description': p['access:description']}})", | ||||
|       "_embedding_features_with_access=JSON.parse(feat.properties._embedding_feature_properties ?? '[]').filter(p => p.access !== undefined)[0]", | ||||
|       "_embedding_feature_with_rock=JSON.parse(feat.properties._embedding_feature_properties ?? '[]').filter(p => p.rock !== undefined)[0] ?? '{}'", | ||||
|       "_embedding_features_with_rock:rock=JSON.parse(feat.properties._embedding_feature_with_rock ?? '{}')?.rock", | ||||
|       "_embedding_features_with_rock:id=JSON.parse(feat.properties._embedding_feature_with_rock ?? '{}')?.id", | ||||
|       "_embedding_feature:access=JSON.parse(feat.properties._embedding_features_with_access ?? '{}').access", | ||||
|       "_embedding_feature:access:description=JSON.parse(feat.properties._embedding_features_with_access ?? '{}')['access:description']", | ||||
|       "_embedding_feature:id=JSON.parse(feat.properties._embedding_features_with_access ?? '{}').id" | ||||
|     ], | ||||
|     "units+": [ | ||||
|       { | ||||
|         "appliesToKey": [ | ||||
|           "climbing:length", | ||||
|           "climbing:length:min", | ||||
|           "climbing:length:max" | ||||
|         ], | ||||
|         "applicableUnits": [ | ||||
|         "+calculatedTags": [ | ||||
|           "_embedding_feature_properties=feat.overlapWith('climbing_area').map(f => f.feat.properties).filter(p => p !== undefined).map(p => {return{access: p.access, id: p.id, name: p.name, climbing: p.climbing, 'access:description': p['access:description']}})", | ||||
|           "_embedding_features_with_access=feat.get('_embedding_feature_properties')?.filter(p => p.access !== undefined)?.at(0)", | ||||
|           "_embedding_feature_with_rock=feat.get('_embedding_feature_properties')?.filter(p => p.rock !== undefined)?.at(0)", | ||||
|           "_embedding_features_with_rock:rock=feat.get('_embedding_feature_with_rock')?.rock", | ||||
|           "_embedding_features_with_rock:id=feat.get('_embedding_feature_with_rock')?.id", | ||||
|           "_embedding_feature:access=feat.get('_embedding_features_with_access')?.access", | ||||
|           "_embedding_feature:access:description=(feat.get('_embedding_features_with_access')??{})['access:description']", | ||||
|           "_embedding_feature:id=feat.get('_embedding_features_with_access')?.id", | ||||
|           "__difficulty_max= feat.properties['climbing:grade:french:max'] ?? feat.properties['_difficulty_max']", | ||||
|           "__difficulty_min= feat.properties['climbing:grade:french:min'] ?? feat.properties['_difficulty_min']", | ||||
|           "__bolts_max= feat.get('climbing:bolts:max') ?? feat.get('climbing:bolts') ?? feat.get('_bolts_max')" | ||||
|         ], | ||||
|         "units+": [ | ||||
|           { | ||||
|             "canonicalDenomination": "", | ||||
|             "alternativeDenomination": [ | ||||
|               "m", | ||||
|               "meter", | ||||
|               "meters" | ||||
|             "appliesToKey": [ | ||||
|               "climbing:length", | ||||
|               "climbing:length:min", | ||||
|               "climbing:length:max" | ||||
|             ], | ||||
|             "human": { | ||||
|               "en": " meter", | ||||
|               "nl": " meter", | ||||
|               "fr": " mètres", | ||||
|               "de": " Meter", | ||||
|               "eo": " metro", | ||||
|               "it": " metri", | ||||
|               "ru": " метр", | ||||
|               "ca": " metre" | ||||
|             }, | ||||
|             "default": true | ||||
|           }, | ||||
|             "applicableUnits": [ | ||||
|               { | ||||
|                 "canonicalDenomination": "", | ||||
|                 "alternativeDenomination": [ | ||||
|                   "m", | ||||
|                   "meter", | ||||
|                   "meters" | ||||
|                 ], | ||||
|                 "human": { | ||||
|                   "en": " meter", | ||||
|                   "nl": " meter", | ||||
|                   "fr": " mètres", | ||||
|                   "de": " Meter", | ||||
|                   "eo": " metro", | ||||
|                   "it": " metri", | ||||
|                   "ru": " метр", | ||||
|                   "ca": " metre" | ||||
|                 }, | ||||
|                 "default": true | ||||
|               }, | ||||
|               { | ||||
|                 "canonicalDenomination": "ft", | ||||
|                 "alternativeDenomination": [ | ||||
|                   "feet", | ||||
|                   "voet" | ||||
|                 ], | ||||
|                 "human": { | ||||
|                   "en": " feet", | ||||
|                   "nl": " voet", | ||||
|                   "fr": " pieds", | ||||
|                   "de": " Fuß", | ||||
|                   "eo": " futo", | ||||
|                   "it": " piedi", | ||||
|                   "ca": " peus" | ||||
|                 } | ||||
|               } | ||||
|             ] | ||||
|           } | ||||
|         ], | ||||
|         "tagRenderings+": [ | ||||
|           { | ||||
|             "canonicalDenomination": "ft", | ||||
|             "alternativeDenomination": [ | ||||
|               "feet", | ||||
|               "voet" | ||||
|             "id": "Access from containing feature", | ||||
|             "mappings": [ | ||||
|               { | ||||
|                 "if": "_embedding_feature:access=yes", | ||||
|                 "then": { | ||||
|                   "en": "<span class='subtle'>The <a href='#{_embedding_feature:id}'>containing feature</a> states that this is</span> publicly accessible<br/>{_embedding_feature:access:description}", | ||||
|                   "nl": "<span class='subtle'>Een <a href='#{_embedding_feature:id}'>omvattend element</a> geeft aan dat dit <span>publiek toegangkelijk is</span><br/>{_embedding_feature:access:description}", | ||||
|                   "fr": "<span class='subtle'>L’<a href='#{_embedding_feature:id}'>élément englobant</a> indique un </span> accès libre<br/>{_embedding_feature:access:description}", | ||||
|                   "it": "<span class='subtle'>L’ <a href='#{_embedding_feature:id}'>elemento in cui è contenuto</a> indica che è</span> pubblicamente accessibile<br/>{_embedding_feature:access:description}", | ||||
|                   "de": "<span class='subtle'>Das <a href='#{_embedding_feature:id}'>enthaltende Objekt</a> gibt an, dass es </span>öffentlich zugänglich ist<br/>{_embedding_feature:access:description}" | ||||
|                 } | ||||
|               }, | ||||
|               { | ||||
|                 "if": "_embedding_feature:access=permit", | ||||
|                 "then": { | ||||
|                   "en": "<span class='subtle'>The <a href='#{_embedding_feature:id}'>containing feature</a> states that </span> a permit is needed to access<br/>{_embedding_feature:access:description}", | ||||
|                   "nl": "<span class='subtle'>Een <a href='#{_embedding_feature:id}'>omvattend element</a> geeft aan dat</span> een toelating nodig is om hier te klimmen<br/>{_embedding_feature:access:description}", | ||||
|                   "fr": "<span class='subtle'>L’<a href='#{_embedding_feature:id}'>élément englobant</a> indique qu’</span> une autorisation d’accès est nécessaire<br/>{_embedding_feature:access:description}", | ||||
|                   "it": "<span class='subtle'>L’<a href='#{_embedding_feature:id}'>elemento che lo contiene</a> indica che </span> è richiesto un’autorizzazione per accedervi<br/>{_embedding_feature:access:description}", | ||||
|                   "de": "<span class='subtle'>Das <a href='#{_embedding_feature:id}'>enthaltende Objekt</a> besagt, dass </span> eine Genehmigung erforderlich ist für den Zugang zu<br/>{_embedding_feature:access:description}" | ||||
|                 } | ||||
|               }, | ||||
|               { | ||||
|                 "if": "_embedding_feature:access=customers", | ||||
|                 "then": { | ||||
|                   "en": "<span class='subtle'>The <a href='#{_embedding_feature:id}'>containing feature</a> states that this is</span> only accessible to customers<br/>{_embedding_feature:access:description}", | ||||
|                   "fr": "<span class='subtle'>L’<a href='#{_embedding_feature:id}'>élément englobant</a> indique que </span> l’accès est réservés aux clients<br/>{_embedding_feature:access:description}", | ||||
|                   "it": "<span class='subtle'>L’ <a href='#{_embedding_feature:id}'>elemento che lo contiene</a> indica che è</span> accessibile solo ai clienti<br/>{_embedding_feature:access:description}", | ||||
|                   "de": "<span class='subtle'>Das <a href='#{_embedding_feature:id}'>enthaltende Objekt</a> besagt, dass es nur für Kunden</span> zugänglich ist<br/>{_embedding_feature:access:description}" | ||||
|                 } | ||||
|               }, | ||||
|               { | ||||
|                 "if": "_embedding_feature:access=members", | ||||
|                 "then": { | ||||
|                   "en": "<span class='subtle'>The <a href='#{_embedding_feature:id}'>containing feature</a> states that this is</span> only accessible to club members<br/>{_embedding_feature:access:description}", | ||||
|                   "fr": "<span class='subtle'>L’<a href='#{_embedding_feature:id}'>élément englobant</a> indique que </span> l’accès est réservé aux membres<br/>{_embedding_feature:access:description}", | ||||
|                   "it": "<span class='subtle'>L’ <a href='#{_embedding_feature:id}'>elemento che lo contiene</a> indica che è </span> accessibile solamente ai membri del club<br/>{_embedding_feature:access:description}", | ||||
|                   "de": "<span class='subtle'>Das <a href='#{_embedding_feature:id}'>enthaltende Objekt</a> besagt, dass es </span>nur für Mitglieder zugänglich ist<br/>{_embedding_feature:access:description}" | ||||
|                 } | ||||
|               }, | ||||
|               { | ||||
|                 "if": "_embedding_feature:access=no", | ||||
|                 "then": "Not accessible as stated by <a href='#{_embedding_feature:id}'>the containing feature</a>" | ||||
|               } | ||||
|             ], | ||||
|             "human": { | ||||
|               "en": " feet", | ||||
|               "nl": " voet", | ||||
|               "fr": " pieds", | ||||
|               "de": " Fuß", | ||||
|               "eo": " futo", | ||||
|               "it": " piedi", | ||||
|               "ca": " peus" | ||||
|             } | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     ], | ||||
|     "tagRenderings+": [ | ||||
|       { | ||||
|         "id": "Website", | ||||
|         "question": { | ||||
|           "en": "Is there a (unofficial) website with more informations (e.g. topos)?", | ||||
|           "de": "Gibt es eine (inoffizielle) Website mit mehr Informationen (z.B. Topos)?", | ||||
|           "ja": "もっと情報のある(非公式の)ウェブサイトはありますか(例えば、topos)?", | ||||
|           "nl": "Is er een (onofficiële) website met meer informatie (b.v. met topos)?", | ||||
|           "ru": "Есть ли (неофициальный) веб-сайт с более подробной информацией (напр., topos)?", | ||||
|           "fr": "Existe-t’il un site avec plus d’informations (ex : topographie) ?", | ||||
|           "it": "C’è un sito web (anche non ufficiale) con qualche informazione in più (ad es. topografie)?" | ||||
|         }, | ||||
|         "condition": { | ||||
|           "and": [ | ||||
|             "leisure!~sports_centre", | ||||
|             "sport=climbing", | ||||
|             "office=", | ||||
|             "club=" | ||||
|           ] | ||||
|         }, | ||||
|         "render": "<a href='{url}' target='_blank'>{url}</a>", | ||||
|         "freeform": { | ||||
|           "key": "url", | ||||
|           "type": "url" | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "id": "Access from containing feature", | ||||
|         "mappings": [ | ||||
|           { | ||||
|             "if": "_embedding_feature:access=yes", | ||||
|             "then": { | ||||
|               "en": "<span class='subtle'>The <a href='#{_embedding_feature:id}'>containing feature</a> states that this is</span> publicly accessible<br/>{_embedding_feature:access:description}", | ||||
|               "nl": "<span class='subtle'>Een <a href='#{_embedding_feature:id}'>omvattend element</a> geeft aan dat dit <span>publiek toegangkelijk is</span><br/>{_embedding_feature:access:description}", | ||||
|               "fr": "<span class='subtle'>L’<a href='#{_embedding_feature:id}'>élément englobant</a> indique un </span> accès libre<br/>{_embedding_feature:access:description}", | ||||
|               "it": "<span class='subtle'>L’ <a href='#{_embedding_feature:id}'>elemento in cui è contenuto</a> indica che è</span> pubblicamente accessibile<br/>{_embedding_feature:access:description}", | ||||
|               "de": "<span class='subtle'>Das <a href='#{_embedding_feature:id}'>enthaltende Objekt</a> gibt an, dass es </span>öffentlich zugänglich ist<br/>{_embedding_feature:access:description}" | ||||
|             } | ||||
|             "condition": "_embedding_feature:access~*" | ||||
|           }, | ||||
|           { | ||||
|             "if": "_embedding_feature:access=permit", | ||||
|             "then": { | ||||
|               "en": "<span class='subtle'>The <a href='#{_embedding_feature:id}'>containing feature</a> states that </span> a permit is needed to access<br/>{_embedding_feature:access:description}", | ||||
|               "nl": "<span class='subtle'>Een <a href='#{_embedding_feature:id}'>omvattend element</a> geeft aan dat</span> een toelating nodig is om hier te klimmen<br/>{_embedding_feature:access:description}", | ||||
|               "fr": "<span class='subtle'>L’<a href='#{_embedding_feature:id}'>élément englobant</a> indique qu’</span> une autorisation d’accès est nécessaire<br/>{_embedding_feature:access:description}", | ||||
|               "it": "<span class='subtle'>L’<a href='#{_embedding_feature:id}'>elemento che lo contiene</a> indica che </span> è richiesto un’autorizzazione per accedervi<br/>{_embedding_feature:access:description}", | ||||
|               "de": "<span class='subtle'>Das <a href='#{_embedding_feature:id}'>enthaltende Objekt</a> besagt, dass </span> eine Genehmigung erforderlich ist für den Zugang zu<br/>{_embedding_feature:access:description}" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "_embedding_feature:access=customers", | ||||
|             "then": { | ||||
|               "en": "<span class='subtle'>The <a href='#{_embedding_feature:id}'>containing feature</a> states that this is</span> only accessible to customers<br/>{_embedding_feature:access:description}", | ||||
|               "fr": "<span class='subtle'>L’<a href='#{_embedding_feature:id}'>élément englobant</a> indique que </span> l’accès est réservés aux clients<br/>{_embedding_feature:access:description}", | ||||
|               "it": "<span class='subtle'>L’ <a href='#{_embedding_feature:id}'>elemento che lo contiene</a> indica che è</span> accessibile solo ai clienti<br/>{_embedding_feature:access:description}", | ||||
|               "de": "<span class='subtle'>Das <a href='#{_embedding_feature:id}'>enthaltende Objekt</a> besagt, dass es nur für Kunden</span> zugänglich ist<br/>{_embedding_feature:access:description}" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "_embedding_feature:access=members", | ||||
|             "then": { | ||||
|               "en": "<span class='subtle'>The <a href='#{_embedding_feature:id}'>containing feature</a> states that this is</span> only accessible to club members<br/>{_embedding_feature:access:description}", | ||||
|               "fr": "<span class='subtle'>L’<a href='#{_embedding_feature:id}'>élément englobant</a> indique que </span> l’accès est réservé aux membres<br/>{_embedding_feature:access:description}", | ||||
|               "it": "<span class='subtle'>L’ <a href='#{_embedding_feature:id}'>elemento che lo contiene</a> indica che è </span> accessibile solamente ai membri del club<br/>{_embedding_feature:access:description}", | ||||
|               "de": "<span class='subtle'>Das <a href='#{_embedding_feature:id}'>enthaltende Objekt</a> besagt, dass es </span>nur für Mitglieder zugänglich ist<br/>{_embedding_feature:access:description}" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "_embedding_feature:access=no", | ||||
|             "then": "Not accessible as stated by <a href='#{_embedding_feature:id}'>the containing feature</a>" | ||||
|           } | ||||
|         ], | ||||
|         "condition": "_embedding_feature:access~*" | ||||
|       }, | ||||
|       { | ||||
|         "id": "Access", | ||||
|         "question": { | ||||
|           "en": "Who can access here?", | ||||
|           "fr": "Qui peut y accéder ?", | ||||
|           "de": "Wer hat hier Zugang?", | ||||
|           "it": "Chi può accedervi?" | ||||
|         }, | ||||
|         "mappings": [ | ||||
|           { | ||||
|             "if": "access=yes", | ||||
|             "then": { | ||||
|               "en": "Publicly accessible to anyone", | ||||
|               "fr": "Libre d’accès", | ||||
|               "de": "Öffentlich zugänglich für jedermann", | ||||
|               "it": "Pubblicamente accessibile a chiunque" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "access=permit", | ||||
|             "then": { | ||||
|               "en": "You need a permit to access here", | ||||
|               "fr": "Une autorisation est nécessaire", | ||||
|               "de": "Zugang nur mit Genehmigung", | ||||
|               "it": "È necessario avere un’autorizzazione per entrare" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "access=customers", | ||||
|             "then": { | ||||
|               "en": "Only customers", | ||||
|               "fr": "Réservé aux clients", | ||||
|               "de": "Nur für Kunden", | ||||
|               "it": "Riservato ai clienti", | ||||
|               "ca": "Només clients" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "access=members", | ||||
|             "then": { | ||||
|               "en": "Only club members", | ||||
|               "ru": "Только членам клуба", | ||||
|               "fr": "Réservé aux membres", | ||||
|               "de": "Nur für Vereinsmitglieder", | ||||
|               "it": "Riservato ai membri del club", | ||||
|               "ca": "Només membres del club" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "access=no", | ||||
|             "then": "Not accessible" | ||||
|           } | ||||
|         ], | ||||
|         "condition": { | ||||
|           "and": [ | ||||
|             "climbing!=no", | ||||
|             "office=", | ||||
|             "club=", | ||||
|             { | ||||
|               "or": [ | ||||
|                 "sport=climbing", | ||||
|                 "climbing:sport=yes" | ||||
|               ] | ||||
|             "id": "access", | ||||
|             "question": { | ||||
|               "en": "Who can access here?", | ||||
|               "fr": "Qui peut y accéder ?", | ||||
|               "de": "Wer hat hier Zugang?", | ||||
|               "it": "Chi può accedervi?" | ||||
|             }, | ||||
|             { | ||||
|             "mappings": [ | ||||
|               { | ||||
|                 "if": "access=yes", | ||||
|                 "then": { | ||||
|                   "en": "Publicly accessible to anyone", | ||||
|                   "fr": "Libre d’accès", | ||||
|                   "de": "Öffentlich zugänglich für jedermann", | ||||
|                   "it": "Pubblicamente accessibile a chiunque" | ||||
|                 } | ||||
|               }, | ||||
|               { | ||||
|                 "if": "access=permit", | ||||
|                 "then": { | ||||
|                   "en": "You need a permit to access here", | ||||
|                   "fr": "Une autorisation est nécessaire", | ||||
|                   "de": "Zugang nur mit Genehmigung", | ||||
|                   "it": "È necessario avere un’autorizzazione per entrare" | ||||
|                 } | ||||
|               }, | ||||
|               { | ||||
|                 "if": "access=customers", | ||||
|                 "then": { | ||||
|                   "en": "Only customers", | ||||
|                   "fr": "Réservé aux clients", | ||||
|                   "de": "Nur für Kunden", | ||||
|                   "it": "Riservato ai clienti", | ||||
|                   "ca": "Només clients" | ||||
|                 } | ||||
|               }, | ||||
|               { | ||||
|                 "if": "access=members", | ||||
|                 "then": { | ||||
|                   "en": "Only club members", | ||||
|                   "ru": "Только членам клуба", | ||||
|                   "fr": "Réservé aux membres", | ||||
|                   "de": "Nur für Vereinsmitglieder", | ||||
|                   "it": "Riservato ai membri del club", | ||||
|                   "ca": "Només membres del club" | ||||
|                 } | ||||
|               }, | ||||
|               { | ||||
|                 "if": "access=no", | ||||
|                 "then": "Not accessible" | ||||
|               } | ||||
|             ], | ||||
|             "condition": { | ||||
|               "or": [ | ||||
|                 "access~*", | ||||
|                 "_embedding_feature:access=" | ||||
|               ] | ||||
|             } | ||||
|           ] | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "id": "Access description (without _embedding_feature:access:description)", | ||||
|         "render": "{access:description}", | ||||
|         "freeform": { | ||||
|           "key": "access:description" | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "id": "Avg length?", | ||||
|         "render": { | ||||
|           "de": "Die Routen sind durchschnittlich <b>{canonical(climbing:length)}</b> lang", | ||||
|           "en": "The routes are <b>{canonical(climbing:length)}</b> long on average", | ||||
|           "nl": "De klimroutes zijn gemiddeld <b>{canonical(climbing:length)}</b> lang", | ||||
|           "ja": "ルートの長さは平均で<b>{canonical(climbing:length)}</b>です", | ||||
|           "fr": "Les voies font <b>{canonical(climbing:length)}</b> de long en moyenne", | ||||
|           "it": "Le vie sono lunghe mediamente <b>{canonical(climbing:length)}</b>" | ||||
|         }, | ||||
|         "condition": { | ||||
|           "and": [ | ||||
|             "climbing!~route", | ||||
|             "office=", | ||||
|             "club=", | ||||
|             "climbing:toprope!=no", | ||||
|             { | ||||
|               "or": [ | ||||
|                 "sport=climbing", | ||||
|                 "climbing:sport=yes", | ||||
|                 "climbing=traditional", | ||||
|                 "climbing=gym" | ||||
|               ] | ||||
|             } | ||||
|           ] | ||||
|         }, | ||||
|         "question": { | ||||
|           "de": "Wie lang sind die Routen (durchschnittlich) in Metern?", | ||||
|           "en": "What is the (average) length of the routes in meters?", | ||||
|           "nl": "Wat is de (gemiddelde) lengte van de klimroutes, in meter?", | ||||
|           "ja": "ルートの(平均)長さはメートル単位でいくつですか?", | ||||
|           "fr": "Quelle est la longueur moyenne des voies en mètres ?", | ||||
|           "it": "Quale è la lunghezza (media) delle vie in metri?" | ||||
|         }, | ||||
|         "freeform": { | ||||
|           "key": "climbing:length", | ||||
|           "type": "pnat" | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "id": "Difficulty-min", | ||||
|         "question": { | ||||
|           "de": "Welche Schwierigkeit hat hier die leichteste Route (französisch/belgisches System)?", | ||||
|           "en": "What is the grade of the easiest route here, according to the french classification system?", | ||||
|           "nl": "Wat is het niveau van de makkelijkste route, volgens het Franse classificatiesysteem?", | ||||
|           "ja": "ここで一番簡単なルートのレベルは、フランスのランク評価システムで何ですか?", | ||||
|           "fr": "Quel est le niveau de la voie la plus simple selon la classification franco-belge ?", | ||||
|           "it": "Qual è il livello della via più facile qua, secondo il sistema di classificazione francese?" | ||||
|         }, | ||||
|         "render": { | ||||
|           "de": "Die leichteste Route hat hier die Schwierigkeit {climbing:grade:french:min} (französisch/belgisches System)", | ||||
|           "en": "The lowest grade is {climbing:grade:french:min} according to the french/belgian system", | ||||
|           "nl": "De minimale klimmoeilijkheid is {climbing:grade:french:min} volgens het Franse/Belgische systeem", | ||||
|           "ja": "フランス/ベルギーのランク評価システムでは、最小の難易度は{climbing:grade:french:min}です", | ||||
|           "fr": "La difficulté minimale est {climbing:grade:french:min} selon la classification franco-belge", | ||||
|           "it": "Il minimo livello di difficoltà è {climbing:grade:french:min} secondo il sistema francese/belga" | ||||
|         }, | ||||
|         "freeform": { | ||||
|           "key": "climbing:grade:french:min" | ||||
|         }, | ||||
|         "condition": { | ||||
|           "and": [ | ||||
|             "climbing!~route", | ||||
|             "office=", | ||||
|             "club=", | ||||
|             { | ||||
|               "or": [ | ||||
|                 "climbing:sport=yes", | ||||
|                 "sport=climbing" | ||||
|               ] | ||||
|             } | ||||
|           ] | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "id": "Difficulty-max", | ||||
|         "question": { | ||||
|           "de": "Welche Schwierigkeit hat hier die schwerste Route (französisch/belgisches System)?", | ||||
|           "en": "What is the highest grade route here, according to the french classification system?", | ||||
|           "nl": "Wat is het niveau van de moeilijkste route, volgens het Franse classificatiesysteem?", | ||||
|           "ja": "フランスのランク評価によると、ここで一番難しいルートのレベルはどれくらいですか?", | ||||
|           "fr": "Quel est le niveau de la voie la plus difficile selon la classification franco-belge ?", | ||||
|           "it": "Qual è il livello della via più difficile qua, secondo il sistema di classificazione francese?" | ||||
|         }, | ||||
|         "render": { | ||||
|           "de": "Die schwierigste Route hat hier die Schwierigkeitsstufe {climbing:grade:french:max} (französisch/belgisches System)", | ||||
|           "en": "The highest grade is {climbing:grade:french:max} according to the french/belgian system", | ||||
|           "nl": "De maximale klimmoeilijkheid is {climbing:grade:french:max} volgens het Franse/Belgische systeem", | ||||
|           "ja": "フランス/ベルギーのランク評価システムでは、最大の難易度は{climbing:grade:french:max}です", | ||||
|           "fr": "La difficulté maximale est {climbing:grade:french:max} selon la classification franco-belge", | ||||
|           "it": "Il massimo livello di difficoltà è {climbing:grade:french:max} secondo il sistema francese/belga" | ||||
|         }, | ||||
|         "freeform": { | ||||
|           "key": "climbing:grade:french:max" | ||||
|         }, | ||||
|         "condition": { | ||||
|           "and": [ | ||||
|             "climbing!~route", | ||||
|             "office=", | ||||
|             "club=", | ||||
|             { | ||||
|               "or": [ | ||||
|                 "climbing:sport=yes", | ||||
|                 "sport=climbing" | ||||
|               ] | ||||
|             } | ||||
|           ] | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "id": "Boldering?", | ||||
|         "question": { | ||||
|           "de": "Kann hier gebouldert werden?", | ||||
|           "en": "Is bouldering possible here?", | ||||
|           "nl": "Is het mogelijk om hier te bolderen?", | ||||
|           "ja": "ここでボルダリングはできますか?", | ||||
|           "nb_NO": "Er buldring mulig her?", | ||||
|           "fr": "L’escalade de bloc est-elle possible ici ?", | ||||
|           "it": "È possibile praticare ‘bouldering’ qua?" | ||||
|         }, | ||||
|         "mappings": [ | ||||
|           { | ||||
|             "if": "climbing:boulder=yes", | ||||
|             "then": { | ||||
|               "de": "Hier kann gebouldert werden", | ||||
|               "en": "Bouldering is possible here", | ||||
|               "nl": "Bolderen kan hier", | ||||
|               "ja": "ボルダリングはここで可能です", | ||||
|               "nb_NO": "Buldring er mulig her", | ||||
|               "fr": "L’escalade de bloc est possible", | ||||
|               "it": "L’arrampicata su massi è possibile qua" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:boulder=no", | ||||
|             "then": { | ||||
|               "de": "Hier kann nicht gebouldert werden", | ||||
|               "en": "Bouldering is not possible here", | ||||
|               "nl": "Bolderen kan hier niet", | ||||
|               "ja": "ここではボルダリングはできません", | ||||
|               "nb_NO": "Buldring er ikke mulig her", | ||||
|               "fr": "L’escalade de bloc n’est pas possible", | ||||
|               "it": "L’arrampicata su massi non è possibile qua" | ||||
|             "id": "Access description (without _embedding_feature:access:description)", | ||||
|             "render": "{access:description}", | ||||
|             "freeform": { | ||||
|               "key": "access:description" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:boulder=limited", | ||||
|             "then": { | ||||
|               "de": "Bouldern ist hier nur an wenigen Routen möglich", | ||||
|               "en": "Bouldering is possible, allthough there are only a few routes", | ||||
|               "nl": "Bolderen kan hier, maar er zijn niet zoveel routes", | ||||
|               "ja": "ボルダリングは可能ですが、少しのルートしかありません", | ||||
|               "fr": "L’escalade de bloc est possible sur des voies précises", | ||||
|               "it": "L’arrampicata su massi è possibile anche se su poche vie" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:boulder~*", | ||||
|             "then": { | ||||
|               "de": "Hier gibt es {climbing:boulder} Boulder-Routen", | ||||
|               "en": "There are {climbing:boulder} boulder routes", | ||||
|               "nl": "Er zijn hier {climbing:boulder} bolderroutes", | ||||
|               "ja": "{climbing:boulder} ボルダールートがある", | ||||
|               "fr": "Il y a {climbing:boulder} voies d’escalade de bloc", | ||||
|               "it": "Sono presenti {climbing:boulder} vie di arrampicata su massi" | ||||
|             }, | ||||
|             "hideInAnswer": true | ||||
|           } | ||||
|         ], | ||||
|         "condition": { | ||||
|           "and": [ | ||||
|             { | ||||
|               "or": [ | ||||
|                 "climbing:sport=yes", | ||||
|                 "sport=climbing" | ||||
|               ] | ||||
|             }, | ||||
|             "office=", | ||||
|             "club=" | ||||
|           ] | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "id": "Toproping?", | ||||
|         "question": { | ||||
|           "de": "Ist Toprope-Klettern hier möglich?", | ||||
|           "en": "Is toprope climbing possible here?", | ||||
|           "nl": "Is het mogelijk om hier te toprope-klimmen?", | ||||
|           "ja": "ここでtoprope登坂はできますか?", | ||||
|           "fr": "Est-il possible d’escalader à la moulinette ?", | ||||
|           "it": "È possibile arrampicarsi con la corda dall’alto qua?" | ||||
|         }, | ||||
|         "mappings": [ | ||||
|           { | ||||
|             "if": "climbing:toprope=yes", | ||||
|             "then": { | ||||
|               "de": "Toprope-Klettern ist hier möglich", | ||||
|               "en": "Toprope climbing is possible here", | ||||
|               "nl": "Toprope-klimmen kan hier", | ||||
|               "ja": "ここでToprope登坂ができます", | ||||
|               "fr": "L’escalade à la moulinette est possible", | ||||
|               "it": "È possibile arrampicarsi con moulinette qua" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:toprope=no", | ||||
|             "then": { | ||||
|               "de": "Toprope-Climbing ist hier nicht möglich", | ||||
|               "en": "Toprope climbing is not possible here", | ||||
|               "nl": "Toprope-klimmen kan hier niet", | ||||
|               "ja": "ここではToprope登坂はできません", | ||||
|               "fr": "L’escalade à la moulinette n’est pas possible", | ||||
|               "it": "Non è possibile arrampicarsi con moulinette qua" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:toprope~*", | ||||
|             "then": { | ||||
|               "de": "Hier gibt es {climbing:toprope} Toprope-Routen", | ||||
|               "en": "There are {climbing:toprope} toprope routes", | ||||
|               "nl": "Er zijn hier {climbing:toprope} toprope routes", | ||||
|               "ja": "{climbing:toprope} 登坂ルートがある", | ||||
|               "fr": "{climbing:toprope} voies sont équipées de moulinettes", | ||||
|               "it": "Sono presenti {climbing:toprope} vie con moulinette" | ||||
|             }, | ||||
|             "hideInAnswer": true | ||||
|           } | ||||
|         ], | ||||
|         "condition": { | ||||
|           "and": [ | ||||
|             { | ||||
|               "or": [ | ||||
|                 "climbing:sport=yes", | ||||
|                 "sport=climbing" | ||||
|               ] | ||||
|             }, | ||||
|             "office=", | ||||
|             "club=" | ||||
|           ] | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "id": "Sportclimbing?", | ||||
|         "question": { | ||||
|           "de": "Ist hier Sportklettern möglich (feste Ankerpunkte)?", | ||||
|           "en": "Is sport climbing possible here on fixed anchors?", | ||||
|           "nl": "Is het mogelijk om hier te sportklimmen/voorklimmen op reeds aangebrachte haken?", | ||||
|           "ja": "ここでは固定アンカー式のスポーツクライミングはできますか?", | ||||
|           "it": "È possibile arrampicarsi qua con ancoraggi fissi?" | ||||
|         }, | ||||
|         "mappings": [ | ||||
|           { | ||||
|             "if": "climbing:sport=yes", | ||||
|             "then": { | ||||
|               "de": "Sportklettern ist hier möglich", | ||||
|               "en": "Sport climbing is possible here", | ||||
|               "nl": "Sportklimmen/voorklimmen kan hier", | ||||
|               "ru": "Здесь можно заняться спортивным скалолазанием", | ||||
|               "ja": "ここでスポーツクライミングができます", | ||||
|               "it": "L’arrampicata sportiva è possibile qua", | ||||
|               "hu": "Itt lehetőség van sportmászásra", | ||||
|               "fr": "De l’escalade est possible ici" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:sport=no", | ||||
|             "then": { | ||||
|               "de": "Sportklettern ist hier nicht möglich", | ||||
|               "en": "Sport climbing is not possible here", | ||||
|               "nl": "Sportklimmen/voorklimmen kan hier niet", | ||||
|               "ru": "Спортивное скалолазание здесь невозможно", | ||||
|               "ja": "ここではスポーツクライミングはできません", | ||||
|               "it": "L’arrampicata sportiva non è possibile qua", | ||||
|               "hu": "Itt nincs lehetőség sportmászásra", | ||||
|               "fr": "L’escalade est impossible ici" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:sport~*", | ||||
|             "then": { | ||||
|               "de": "Hier gibt es {climbing:sport} Sportkletter-Routen", | ||||
|               "en": "There are {climbing:sport} sport climbing routes", | ||||
|               "nl": "Er zijn hier {climbing:sport} sportklimroutes/voorklimroutes", | ||||
|               "ja": "スポーツクライミングの {climbing:sport} ルートがある", | ||||
|               "it": "Sono presenti {climbing:sport} vie di arrampicata sportiva" | ||||
|             }, | ||||
|             "hideInAnswer": true | ||||
|           } | ||||
|         ], | ||||
|         "condition": { | ||||
|           "and": [ | ||||
|             { | ||||
|               "or": [ | ||||
|                 "climbing:sport=yes", | ||||
|                 "sport=climbing" | ||||
|               ] | ||||
|             }, | ||||
|             "office=", | ||||
|             "club=" | ||||
|           ] | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "id": "Traditional climbing?", | ||||
|         "question": { | ||||
|           "de": "Ist hier traditionelles Klettern möglich (eigene Sicherung z.B. mit Klemmkleilen)?", | ||||
|           "en": "Is traditional climbing possible here (using own gear e.g. chocks)?", | ||||
|           "nl": "Is het mogelijk om hier traditioneel te klimmen? <br/><span class='subtle'>(Dit is klimmen met klemblokjes en friends)</span>", | ||||
|           "ja": "伝統的な登山はここで可能ですか(例えば、チョックのような独自のギアを使用して)?", | ||||
|           "it": "È possibile arrampicarsi in maniera tradizionale qua (usando attrezzi propri, ad es. dadi)?" | ||||
|         }, | ||||
|         "mappings": [ | ||||
|           { | ||||
|             "if": "climbing:traditional=yes", | ||||
|             "then": { | ||||
|               "de": "Traditionelles Klettern ist hier möglich", | ||||
|               "en": "Traditional climbing is possible here", | ||||
|               "nl": "Traditioneel klimmen kan hier", | ||||
|               "ja": "ここでは伝統的な登山が可能です", | ||||
|               "it": "L’arrampicata tradizionale è possibile qua" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:traditional=no", | ||||
|             "then": { | ||||
|               "de": "Traditionelles Klettern ist hier nicht möglich", | ||||
|               "en": "Traditional climbing is not possible here", | ||||
|               "nl": "Traditioneel klimmen kan hier niet", | ||||
|               "ja": "伝統的な登山はここではできない", | ||||
|               "it": "L’arrampicata tradizionale non è possibile qua" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:traditional~*", | ||||
|             "then": { | ||||
|               "de": "Hier gibt es {climbing:traditional} Routen für traditionelles Klettern", | ||||
|               "en": "There are {climbing:traditional} traditional climbing routes", | ||||
|               "nl": "Er zijn hier {climbing:traditional} traditionele klimroutes", | ||||
|               "ja": "{climbing:traditional} の伝統的な登山ルートがある", | ||||
|               "it": "Sono presenti {climbing:traditional} vie di arrampicata tradizionale" | ||||
|             }, | ||||
|             "hideInAnswer": true | ||||
|           } | ||||
|         ], | ||||
|         "condition": { | ||||
|           "and": [ | ||||
|             { | ||||
|               "or": [ | ||||
|                 "climbing:sport=yes", | ||||
|                 "sport=climbing" | ||||
|               ] | ||||
|             }, | ||||
|             "office=", | ||||
|             "club=" | ||||
|           ] | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         "id": "Speed climbing?", | ||||
|         "question": { | ||||
|           "de": "Gibt es hier eine Speedkletter-Wand?", | ||||
|           "en": "Is there a speed climbing wall?", | ||||
|           "nl": "Is er een snelklimmuur (speed climbing)?", | ||||
|           "ja": "スピードクライミングウォールはありますか?", | ||||
|           "it": "È presente una prete per l’arrampicata di velocità?" | ||||
|         }, | ||||
|         "condition": { | ||||
|           "and": [ | ||||
|             "leisure=sports_centre", | ||||
|             { | ||||
|               "or": [ | ||||
|                 "climbing:sport=yes", | ||||
|                 "sport=climbing" | ||||
|               ] | ||||
|             }, | ||||
|             "office=", | ||||
|             "club=" | ||||
|           ] | ||||
|         }, | ||||
|         "mappings": [ | ||||
|           { | ||||
|             "if": "climbing:speed=yes", | ||||
|             "then": { | ||||
|               "de": "Hier gibt es eine Speedkletter-Wand", | ||||
|               "en": "There is a speed climbing wall", | ||||
|               "nl": "Er is een snelklimmuur voor speed climbing", | ||||
|               "ja": "スピードクライミングウォールがある", | ||||
|               "it": "È presente una parete per l’arrampicata di velocità" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:speed=no", | ||||
|             "then": { | ||||
|               "de": "Hier gibt es keine Speedkletter-Wand", | ||||
|               "en": "There is no speed climbing wall", | ||||
|               "nl": "Er is geen snelklimmuur voor speed climbing", | ||||
|               "ja": "スピードクライミングウォールがない", | ||||
|               "it": "Non è presente una parete per l’arrampicata di velocità" | ||||
|             } | ||||
|           }, | ||||
|           { | ||||
|             "if": "climbing:speed~*", | ||||
|             "then": { | ||||
|               "de": "Hier gibt es {climbing:speed} Speedkletter-Routen", | ||||
|               "en": "There are {climbing:speed} speed climbing walls", | ||||
|               "nl": "Er zijn hier {climbing:speed} snelklimmuren", | ||||
|               "ja": "{climbing:speed} のスピードクライミングウォールがある", | ||||
|               "it": "Sono presenti {climbing:speed} pareti per l’arrampicata di velocità" | ||||
|             }, | ||||
|             "hideInAnswer": true | ||||
|           } | ||||
|           "questions", | ||||
|           "reviews" | ||||
|         ] | ||||
|       }, | ||||
|       "questions", | ||||
|       "reviews" | ||||
|     ] | ||||
|   } | ||||
|       } | ||||
|     } | ||||
|   ] | ||||
| } | ||||
|  | @ -17,8 +17,8 @@ | |||
|     "es": "Árboles" | ||||
|   }, | ||||
|   "shortDescription": { | ||||
|     "nl": "Breng bomen in kaart", | ||||
|     "en": "Map all the trees", | ||||
|     "nl": "Breng bomen in kaart", | ||||
|     "fr": "Carte des arbres", | ||||
|     "it": "Mappa tutti gli alberi", | ||||
|     "ja": "すべての樹木をマッピングする", | ||||
|  |  | |||
|  | @ -1144,16 +1144,16 @@ video { | |||
|   width: 2.75rem; | ||||
| } | ||||
| 
 | ||||
| .w-16 { | ||||
|   width: 4rem; | ||||
| } | ||||
| 
 | ||||
| .w-min { | ||||
|   width: -webkit-min-content; | ||||
|   width: -moz-min-content; | ||||
|   width: min-content; | ||||
| } | ||||
| 
 | ||||
| .w-16 { | ||||
|   width: 4rem; | ||||
| } | ||||
| 
 | ||||
| .w-auto { | ||||
|   width: auto; | ||||
| } | ||||
|  | @ -1987,6 +1987,16 @@ a { | |||
|   width: min-content; | ||||
| } | ||||
| 
 | ||||
| .rounded-left-full { | ||||
|   border-bottom-left-radius: 999rem; | ||||
|   border-top-left-radius: 999rem; | ||||
| } | ||||
| 
 | ||||
| .rounded-right-full { | ||||
|   border-bottom-right-radius: 999rem; | ||||
|   border-top-right-radius: 999rem; | ||||
| } | ||||
| 
 | ||||
| .w-16-imp { | ||||
|   width: 4rem !important; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										20
									
								
								index.css
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								index.css
									
										
									
									
									
								
							|  | @ -39,6 +39,16 @@ | |||
|             background-color: var(--catch-detail-color); | ||||
|             color: var(--catch-detail-color-contrast); | ||||
|         } | ||||
|          | ||||
|         .rounded-left-full { | ||||
|             border-bottom-left-radius: 999rem; | ||||
|             border-top-left-radius: 999rem; | ||||
|         } | ||||
| 
 | ||||
|         .rounded-right-full { | ||||
|             border-bottom-right-radius: 999rem; | ||||
|             border-top-right-radius: 999rem; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -223,6 +233,16 @@ a { | |||
|     width: min-content; | ||||
| } | ||||
| 
 | ||||
| .rounded-left-full { | ||||
|     border-bottom-left-radius: 999rem; | ||||
|     border-top-left-radius: 999rem; | ||||
| } | ||||
| 
 | ||||
| .rounded-right-full { | ||||
|     border-bottom-right-radius: 999rem; | ||||
|     border-top-right-radius: 999rem; | ||||
| } | ||||
| 
 | ||||
| .w-16-imp { | ||||
|     width: 4rem !important; | ||||
| } | ||||
|  |  | |||
|  | @ -156,6 +156,9 @@ class LayerOverviewUtils { | |||
|         } | ||||
| 
 | ||||
|         this.checkAllSvgs() | ||||
| 
 | ||||
|         const green = s => '\x1b[92m' + s + '\x1b[0m' | ||||
|         console.log(green("All done!")) | ||||
|     } | ||||
| 
 | ||||
|     private buildLayerIndex(knownImagePaths: Set<string>): Map<string, LayerConfigJson> { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue