diff --git a/Models/ThemeConfig/Conversion/PrepareTheme.ts b/Models/ThemeConfig/Conversion/PrepareTheme.ts index 8a9877e10..1d61f2a3b 100644 --- a/Models/ThemeConfig/Conversion/PrepareTheme.ts +++ b/Models/ThemeConfig/Conversion/PrepareTheme.ts @@ -330,12 +330,19 @@ class AddDependencyLayersToTheme extends DesugaringStep { 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, themeId: string): LayerConfigJson[] { - const dependenciesToAdd: LayerConfigJson[] = [] + private static CalculateDependencies(alreadyLoaded: LayerConfigJson[], allKnownLayers: Map, themeId: string): + {config: LayerConfigJson, reason: string}[] { + const dependenciesToAdd: {config: LayerConfigJson, reason: string}[] = [] const loadedLayerIds: Set = new Set(alreadyLoaded.map(l => l.id)); // Verify cross-dependencies @@ -361,35 +368,39 @@ class AddDependencyLayersToTheme extends DesugaringStep { } // 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 { }) const dependencies = AddDependencyLayersToTheme.CalculateDependencies(layers, allKnownLayers, theme.id); - if (dependencies.length > 0) { - - information.push(context + ": added " + dependencies.map(d => d.id).join(", ") + " to the theme as they are needed") + for (const dependency of dependencies) { + } - 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: { diff --git a/Models/ThemeConfig/DependencyCalculator.ts b/Models/ThemeConfig/DependencyCalculator.ts index c4d3663d3..895f26779 100644 --- a/Models/ThemeConfig/DependencyCalculator.ts +++ b/Models/ThemeConfig/DependencyCalculator.ts @@ -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 }) diff --git a/Models/ThemeConfig/LayerConfig.ts b/Models/ThemeConfig/LayerConfig.ts index ade6d6b6d..5d95d3cb2 100644 --- a/Models/ThemeConfig/LayerConfig.ts +++ b/Models/ThemeConfig/LayerConfig.ts @@ -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) diff --git a/UI/BigComponents/FilterView.ts b/UI/BigComponents/FilterView.ts index e707211a0..092cd31ec 100644 --- a/UI/BigComponents/FilterView.ts +++ b/UI/BigComponents/FilterView.ts @@ -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, @@ -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}) { 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;"; diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 320355393..d9a802870 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -85,6 +85,10 @@ export class AllTagsPanel extends VariableUiElement { if (value === undefined) { continue } + let type = ""; + if(typeof value !== "string"){ + type = " "+(typeof value)+"" + } parts.push(["" + key + "", value]) } diff --git a/assets/layers/climbing/climbing.json b/assets/layers/climbing/climbing.json index 9c53a74a0..36cd68b9d 100644 --- a/assets/layers/climbing/climbing.json +++ b/assets/layers/climbing/climbing.json @@ -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 {name}", - "fr": "Mur d’escalade {name}", - "it": "Muro da arrampicata {name}", - "de": "Klettergarten {name}" - } - }, - { - "if": { - "and": [ - { - "or": [ - "climbing=area", - "climbing=site" - ] - }, - "name~*" - ] - }, - "then": { - "en": "Climbing area {name}", - "nl": "Klimsite {name}", - "fr": "Zone d’escalade {name}", - "de": "Klettergebiet {name}", - "it": "Area di arrampicata {name}" - } - }, - { - "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 {name}", - "en": "Climbing opportunity {name}", - "fr": "Opportunité d’escalade {name}", - "de": "Klettermöglichkeit {name}", - "it": "Opportunità di arrampicata {name}" - } - } - ] - }, + "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": "

Length overview

{histogram(_length_hist)}", - "fr": "

Résumé de longueur

{histogram(_length_hist)}", - "de": "

Längenübersicht

{histogram(_length_hist)}", - "it": "

Riassunto della lunghezza

{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": "

Grades overview

{histogram(_difficulty_hist)}", - "fr": "

Résumé des difficultés

{histogram(_difficulty_hist)}", - "de": "

Schwierigkeitsübersicht

{histogram(_difficulty_hist)}", - "it": "

Riassunto delle difficoltà

{histogram(_difficulty_hist)}" + "condition": { + "and": [ + "leisure!~sports_centre", + "sport=climbing", + "office=", + "club=" + ] }, - "condition": "_difficulty_hist!~\\[\\]", - "id": "Contained routes hist" + "render": "{url}", + "freeform": { + "key": "url", + "type": "url" + } }, { + "id": "average_length", "render": { - "en": "

Contains {_contained_climbing_routes_count} routes

    {_contained_climbing_routes}
", - "fr": "

Contient {_contained_climbing_routes_count} voies

    {_contained_climbing_routes}
", - "it": "

Contiene {_contained_climbing_routes_count} vie

    {_contained_climbing_routes}
", - "de": "

Enthält {_contained_climbing_routes_count} Routen

    {_contained_climbing_routes}
" - }, - "condition": "_contained_climbing_routes~*", - "id": "Contained_climbing_routes" - }, - { - "render": { - "en": "{name}", - "nl": "{name}", - "de": "{name}", - "ca": "{name}", - "fr": "{name}", - "id": "{name}", - "ru": "{name}", - "ja": "{name}", - "it": "{name}" + "de": "Die Routen sind durchschnittlich {canonical(climbing:length)} lang", + "en": "The routes are {canonical(climbing:length)} long on average", + "nl": "De klimroutes zijn gemiddeld {canonical(climbing:length)} lang", + "ja": "ルートの長さは平均で{canonical(climbing:length)}です", + "fr": "Les voies font {canonical(climbing:length)} de long en moyenne", + "it": "Le vie sono lunghe mediamente {canonical(climbing:length)}" }, "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?
(Dit is klimmen met klemblokjes en friends)", + "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.
This is without relays and indicates how much quickdraws a climber needs
" + }, + "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 => `
  • ${p.name ?? 'climbing route'} (${p['climbing:grade:french'] ?? 'unknown difficulty'}, ${p['climbing:length'] ?? 'unkown length'} meter)
  • `).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 } \ No newline at end of file diff --git a/assets/layers/climbing_area/climbing_area.json b/assets/layers/climbing_area/climbing_area.json new file mode 100644 index 000000000..22c0d2884 --- /dev/null +++ b/assets/layers/climbing_area/climbing_area.json @@ -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 {name}", + "fr": "Mur d’escalade {name}", + "it": "Muro da arrampicata {name}", + "de": "Klettergarten {name}" + } + }, + { + "if": { + "and": [ + { + "or": [ + "climbing=area", + "climbing=site" + ] + }, + "name~*" + ] + }, + "then": { + "en": "Climbing area {name}", + "nl": "Klimsite {name}", + "fr": "Zone d’escalade {name}", + "de": "Klettergebiet {name}", + "it": "Area di arrampicata {name}" + } + }, + { + "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 {name}", + "en": "Climbing opportunity {name}", + "fr": "Opportunité d’escalade {name}", + "de": "Klettermöglichkeit {name}", + "it": "Opportunità di arrampicata {name}" + } + } + ] + }, + "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 => `
  • ${p.name ?? 'climbing route'} (${p['climbing:grade:french'] ?? 'unknown difficulty'}, ${p['climbing:length'] ?? 'unkown length'} meter)
  • `).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": "

    Length overview

    {histogram(_length_hist)}", + "fr": "

    Résumé de longueur

    {histogram(_length_hist)}", + "de": "

    Längenübersicht

    {histogram(_length_hist)}", + "it": "

    Riassunto della lunghezza

    {histogram(_length_hist)}" + }, + "condition": "_length_hist!~\\[\\]", + "id": "Contained routes length hist" + }, + { + "render": { + "en": "

    Grades overview

    {histogram(_difficulty_hist)}", + "fr": "

    Résumé des difficultés

    {histogram(_difficulty_hist)}", + "de": "

    Schwierigkeitsübersicht

    {histogram(_difficulty_hist)}", + "it": "

    Riassunto delle difficoltà

    {histogram(_difficulty_hist)}" + }, + "condition": "_difficulty_hist!~\\[\\]", + "id": "Contained routes hist" + }, + { + "render": { + "en": "

    Contains {_contained_climbing_routes_count} routes

      {_contained_climbing_routes}
    ", + "fr": "

    Contient {_contained_climbing_routes_count} voies

      {_contained_climbing_routes}
    ", + "it": "

    Contiene {_contained_climbing_routes_count} vie

      {_contained_climbing_routes}
    ", + "de": "

    Enthält {_contained_climbing_routes_count} Routen

      {_contained_climbing_routes}
    " + }, + "condition": "_contained_climbing_routes~*", + "id": "Contained_climbing_routes" + }, + { + "render": { + "en": "{name}", + "nl": "{name}", + "de": "{name}", + "ca": "{name}", + "fr": "{name}", + "id": "{name}", + "ru": "{name}", + "ja": "{name}", + "it": "{name}" + }, + "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" + } + } + ] +} \ No newline at end of file diff --git a/assets/layers/climbing_gym/climbing_gym.json b/assets/layers/climbing_gym/climbing_gym.json index d93037ae6..afa06676b 100644 --- a/assets/layers/climbing_gym/climbing_gym.json +++ b/assets/layers/climbing_gym/climbing_gym.json @@ -55,15 +55,7 @@ "images", { "render": { - "en": "{name}", - "nl": "{name}", - "de": "{name}", - "ca": "{name}", - "fr": "{name}", - "id": "{name}", - "ru": "{name}", - "ja": "{name}", - "it": "{name}" + "*": "{name}" }, "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": [ { diff --git a/assets/layers/climbing_opportunity/climbing_opportunity.json b/assets/layers/climbing_opportunity/climbing_opportunity.json index c9afa69f0..3a5e85106 100644 --- a/assets/layers/climbing_opportunity/climbing_opportunity.json +++ b/assets/layers/climbing_opportunity/climbing_opportunity.json @@ -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", diff --git a/assets/layers/climbing_route/climbing_route.json b/assets/layers/climbing_route/climbing_route.json index faba96032..a562c753c 100644 --- a/assets/layers/climbing_route/climbing_route.json +++ b/assets/layers/climbing_route/climbing_route.json @@ -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
    This is without relays and indicates how much quickdraws a climber needs
    ", "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": "

    Description


    {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 on the surrounding crag", "fr": "Le type de roche est {_embedding_features_with_rock:rock} selon le mur", @@ -194,8 +185,7 @@ }, "freeform": { "key": "_embedding_features_with_rock:rock" - }, - "id": "Rock type" + } } ], "presets": [ diff --git a/assets/themes/climbing/climbing.json b/assets/themes/climbing/climbing.json index 3723d6b51..043485b54 100644 --- a/assets/themes/climbing/climbing.json +++ b/assets/themes/climbing/climbing.json @@ -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": "
    {climbing:length}m
    ", - "condition": "climbing:length~*" - }, - { - "mappings": [ + ], + "override": { + "allowMove": { + "enableRelocation": false, + "enableImproveAccuracy": true + }, + "+titleIcons": [ { - "if": "climbing:bolts~*", - "then": "
    {climbing:bolts}
    " + "render": "
    {climbing:length}m
    ", + "condition": "climbing:length~*" }, { - "if": "climbing:bolted=yes", - "then": "" + "mappings": [ + { + "if": "__bolts_max~*", + "then": "
    {__bolts_max}
    " + }, + { + "if": "climbing:bolted=yes", + "then": "" + } + ] + }, + { + "id": "Min difficulty", + "condition": "__difficulty_min~*", + "then": "
    {__difficulty_min}
    ", + + "mappings": [ + { + "if": "__difficulty_min~(2|3).*", + "then": "
    {__difficulty_min}
    " + }, + { + "if": "__difficulty_min~4.*", + "then": "
    {__difficulty_min}
    " + }, + { + "if": "__difficulty_min~5.*", + "then": "
    {__difficulty_min}
    " + }, + { + "if": "__difficulty_min~6.*", + "then": "
    {__difficulty_min}
    " + }, + { + "if": "__difficulty_min~(7|8).*", + "then": "
    {__difficulty_min}
    " + }, + { + "if": "__difficulty_min~*", + "then": "
    {__difficulty_min}
    " + } + ] + }, + { + "id": "max difficulty", + "condition": "__difficulty_max~*", + "then": "
    {__difficulty_max}
    ", + "mappings": [ + { + "if": "__difficulty_max~(2|3).*", + "then": "
    {__difficulty_max}
    " + }, + { + "if": "__difficulty_max~4.*", + "then": "
    {__difficulty_max}
    " + }, + { + "if": "__difficulty_max~5.*", + "then": "
    {__difficulty_max}
    " + }, + { + "if": "__difficulty_max~6.*", + "then": "
    {__difficulty_max}
    " + }, + { + "if": "__difficulty_max~(7|8).*", + "then": "
    {__difficulty_max}
    " + }, + { + "if": "__difficulty_max~*", + "then": "
    {__difficulty_max}
    " + } + ] + }, + { + "mappings": [ + { + "if": "climbing:grade:french~3.*", + "then": "
    {climbing:grade:french}
    " + }, + { + "if": "climbing:grade:french~4.*", + "then": "
    {climbing:grade:french}
    " + }, + { + "if": "climbing:grade:french~5.*", + "then": "
    {climbing:grade:french}
    " + }, + { + "if": "climbing:grade:french~6.*", + "then": "
    {climbing:grade:french}
    " + }, + { + "if": "climbing:grade:french~7.*", + "then": "
    {climbing:grade:french}
    " + }, + { + "if": "climbing:grade:french~*", + "then": "
    {climbing:grade:french}
    " + } + ] } - ] - }, - { - "mappings": [ - { - "if": "climbing:grade:french~3.*", - "then": "
    {climbing:grade:french}
    " - }, - { - "if": "climbing:grade:french~4.*", - "then": "
    {climbing:grade:french}
    " - }, - { - "if": "climbing:grade:french~5.*", - "then": "
    {climbing:grade:french}
    " - }, - { - "if": "climbing:grade:french~6.*", - "then": "
    {climbing:grade:french}
    " - }, - { - "if": "climbing:grade:french~7.*", - "then": "
    {climbing:grade:french}
    " - }, - { - "if": "climbing:grade:french~*", - "then": "
    {climbing:grade:french}
    " - } - ] - } - ], - "+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": "The containing feature states that this is publicly accessible
    {_embedding_feature:access:description}", + "nl": "Een omvattend element geeft aan dat dit publiek toegangkelijk is
    {_embedding_feature:access:description}", + "fr": "L’élément englobant indique un accès libre
    {_embedding_feature:access:description}", + "it": "L’ elemento in cui è contenuto indica che è pubblicamente accessibile
    {_embedding_feature:access:description}", + "de": "Das enthaltende Objekt gibt an, dass es öffentlich zugänglich ist
    {_embedding_feature:access:description}" + } + }, + { + "if": "_embedding_feature:access=permit", + "then": { + "en": "The containing feature states that a permit is needed to access
    {_embedding_feature:access:description}", + "nl": "Een omvattend element geeft aan dat een toelating nodig is om hier te klimmen
    {_embedding_feature:access:description}", + "fr": "L’élément englobant indique qu’ une autorisation d’accès est nécessaire
    {_embedding_feature:access:description}", + "it": "L’elemento che lo contiene indica che è richiesto un’autorizzazione per accedervi
    {_embedding_feature:access:description}", + "de": "Das enthaltende Objekt besagt, dass eine Genehmigung erforderlich ist für den Zugang zu
    {_embedding_feature:access:description}" + } + }, + { + "if": "_embedding_feature:access=customers", + "then": { + "en": "The containing feature states that this is only accessible to customers
    {_embedding_feature:access:description}", + "fr": "L’élément englobant indique que l’accès est réservés aux clients
    {_embedding_feature:access:description}", + "it": "L’ elemento che lo contiene indica che è accessibile solo ai clienti
    {_embedding_feature:access:description}", + "de": "Das enthaltende Objekt besagt, dass es nur für Kunden zugänglich ist
    {_embedding_feature:access:description}" + } + }, + { + "if": "_embedding_feature:access=members", + "then": { + "en": "The containing feature states that this is only accessible to club members
    {_embedding_feature:access:description}", + "fr": "L’élément englobant indique que l’accès est réservé aux membres
    {_embedding_feature:access:description}", + "it": "L’ elemento che lo contiene indica che è accessibile solamente ai membri del club
    {_embedding_feature:access:description}", + "de": "Das enthaltende Objekt besagt, dass es nur für Mitglieder zugänglich ist
    {_embedding_feature:access:description}" + } + }, + { + "if": "_embedding_feature:access=no", + "then": "Not accessible as stated by the containing feature" + } ], - "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": "{url}", - "freeform": { - "key": "url", - "type": "url" - } - }, - { - "id": "Access from containing feature", - "mappings": [ - { - "if": "_embedding_feature:access=yes", - "then": { - "en": "The containing feature states that this is publicly accessible
    {_embedding_feature:access:description}", - "nl": "Een omvattend element geeft aan dat dit publiek toegangkelijk is
    {_embedding_feature:access:description}", - "fr": "L’élément englobant indique un accès libre
    {_embedding_feature:access:description}", - "it": "L’ elemento in cui è contenuto indica che è pubblicamente accessibile
    {_embedding_feature:access:description}", - "de": "Das enthaltende Objekt gibt an, dass es öffentlich zugänglich ist
    {_embedding_feature:access:description}" - } + "condition": "_embedding_feature:access~*" }, { - "if": "_embedding_feature:access=permit", - "then": { - "en": "The containing feature states that a permit is needed to access
    {_embedding_feature:access:description}", - "nl": "Een omvattend element geeft aan dat een toelating nodig is om hier te klimmen
    {_embedding_feature:access:description}", - "fr": "L’élément englobant indique qu’ une autorisation d’accès est nécessaire
    {_embedding_feature:access:description}", - "it": "L’elemento che lo contiene indica che è richiesto un’autorizzazione per accedervi
    {_embedding_feature:access:description}", - "de": "Das enthaltende Objekt besagt, dass eine Genehmigung erforderlich ist für den Zugang zu
    {_embedding_feature:access:description}" - } - }, - { - "if": "_embedding_feature:access=customers", - "then": { - "en": "The containing feature states that this is only accessible to customers
    {_embedding_feature:access:description}", - "fr": "L’élément englobant indique que l’accès est réservés aux clients
    {_embedding_feature:access:description}", - "it": "L’ elemento che lo contiene indica che è accessibile solo ai clienti
    {_embedding_feature:access:description}", - "de": "Das enthaltende Objekt besagt, dass es nur für Kunden zugänglich ist
    {_embedding_feature:access:description}" - } - }, - { - "if": "_embedding_feature:access=members", - "then": { - "en": "The containing feature states that this is only accessible to club members
    {_embedding_feature:access:description}", - "fr": "L’élément englobant indique que l’accès est réservé aux membres
    {_embedding_feature:access:description}", - "it": "L’ elemento che lo contiene indica che è accessibile solamente ai membri del club
    {_embedding_feature:access:description}", - "de": "Das enthaltende Objekt besagt, dass es nur für Mitglieder zugänglich ist
    {_embedding_feature:access:description}" - } - }, - { - "if": "_embedding_feature:access=no", - "then": "Not accessible as stated by the containing feature" - } - ], - "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 {canonical(climbing:length)} lang", - "en": "The routes are {canonical(climbing:length)} long on average", - "nl": "De klimroutes zijn gemiddeld {canonical(climbing:length)} lang", - "ja": "ルートの長さは平均で{canonical(climbing:length)}です", - "fr": "Les voies font {canonical(climbing:length)} de long en moyenne", - "it": "Le vie sono lunghe mediamente {canonical(climbing:length)}" - }, - "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?
    (Dit is klimmen met klemblokjes en friends)", - "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" - ] - } + } + } + ] } \ No newline at end of file diff --git a/assets/themes/trees/trees.json b/assets/themes/trees/trees.json index 910160fa5..393e0cadb 100644 --- a/assets/themes/trees/trees.json +++ b/assets/themes/trees/trees.json @@ -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": "すべての樹木をマッピングする", diff --git a/css/index-tailwind-output.css b/css/index-tailwind-output.css index a41659488..c517a8104 100644 --- a/css/index-tailwind-output.css +++ b/css/index-tailwind-output.css @@ -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; } diff --git a/index.css b/index.css index 77c7b0160..e70d93b25 100644 --- a/index.css +++ b/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; } diff --git a/scripts/generateLayerOverview.ts b/scripts/generateLayerOverview.ts index 02cc13859..66fb28e88 100644 --- a/scripts/generateLayerOverview.ts +++ b/scripts/generateLayerOverview.ts @@ -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): Map {