diff --git a/assets/layers/sauna/sauna.json b/assets/layers/sauna/sauna.json index bf1c3b555..23fedd023 100644 --- a/assets/layers/sauna/sauna.json +++ b/assets/layers/sauna/sauna.json @@ -1,7 +1,24 @@ { - "credits": "Osmwithspace", + "id": "sauna", + "name": { + "en": "Sauna" + }, + "description": { + "en": "A sauna is a small room or house designed as a place to experience dry or wet heat sessions, or an establishment with one or more of these and auxiliary facilities." + }, + "source": { + "osmTags": { + "and": [ + "leisure=sauna" + ] + } + }, "minzoom": 8, - "allowMove": true, + "title": { + "render": { + "en": "{name}" + } + }, "pointRendering": [ { "location": [ @@ -15,111 +32,21 @@ ] } ], - "tagRenderings": [ - "images", - "reviews", - "opening_hours", - { - "id": "charge_cost_rewritten", - "rewrite": { - "sourceString": [ - "{key}", - "{time}" - ], - "into": [ - [ - "2 hours", - { - "en": "2 hours", - "de": "2 Stunden" - } - ], - [ - "4 hours", - { - "en": "4 hours", - "de": "4 Stunden" - } - ], - [ - "day", - { - "en": "one day", - "de": "einen Tag" - } - ] - ] - }, - "renderings": [ - { - "id": "charge_{key}", - "question": { - "en": "What is the entrance fee for {time}?", - "de": "Was ist der Eintrittspreis für {time}?" - }, - "render": { - "en": "entrance fee for {time}: {charge}", - "de": "Eintrittspreis für {time}: {charge}" - }, - "freeform": { - "key": "charge", - "type": "currency", - "inline": true, - "postfixDistinguished": "{key}", - "addExtraTags": [ - "fee=yes" - ] - }, - "mappings": [ - { - "if": "fee=no", - "addExtraTags": [ - "charge=" - ], - "then": { - "en": "The sauna is free of charge", - "de": "Die Sauna ist kostenlos" - }, - "hideInAnswer": "fee!=no" - } - ] - } - ] - }, - "contact", - "fixme" - ], "lineRendering": [ { "width": 1, "color": "blue" } ], - "credits:uid": 8770388, - "source": { - "osmTags": { - "and": [ - "leisure=sauna", - { - "or": [ - "opening_hours!=", - "website!=", - "phone!=" - ] - } - ] - } - }, - "description": { - "en": "A sauna is a small room or house designed as a place to experience dry or wet heat sessions, or an establishment with one or more of these and auxiliary facilities." - }, - "id": "sauna", - "name": { - "en": "Sauna" - }, - "title": { - "render": { - "en": "{name}" - } - } -} \ No newline at end of file + "tagRenderings": [ + "images", + "reviews", + "opening_hours", + "contact", + "sauna_at_leisure.sauna_expanded", + "fixme" + ], + "allowMove": true, + "credits": "Osmwithspace", + "credits:uid": 8770388 +} diff --git a/assets/layers/sauna_at_leisure/sauna_at_leisure.json b/assets/layers/sauna_at_leisure/sauna_at_leisure.json index 1bb01a292..e2f965c66 100644 --- a/assets/layers/sauna_at_leisure/sauna_at_leisure.json +++ b/assets/layers/sauna_at_leisure/sauna_at_leisure.json @@ -1,7 +1,26 @@ { - "credits": "Osmwithspace", + "id": "sauna_at_leisure", + "name": { + "en": "Saunas at other amenities", + "de": "Saunen in anderen Einrichtungen" + }, + "description": { + "en": "A sauna is a small room or house designed as a place to experience dry or wet heat sessions, or an establishment with one or more of these and auxiliary facilities." + }, + "#": "Use 'sauna_at_leisure.sauna_grouped' in a layer.tagRenderings to add the 'sauna information' expandle block (incl 'has sauna'); use 'sauna_at_leisure.expanded' to get all sauna questions directly (which does _not_ include the 'has sauna' question)", + "source": { + "osmTags": { + "or": [ + "sauna=yes" + ] + } + }, "minzoom": 8, - "allowMove": true, + "title": { + "render": { + "en": "{name}" + } + }, "pointRendering": [ { "location": [ @@ -15,34 +34,132 @@ ] } ], + "lineRendering": [ + { + "width": 1, + "color": "blue" + } + ], "tagRenderings": [ { - "builtin": "sauna.*", - "override": { - "condition": { - "and+": [ - "sauna=yes" - ] + "id": "sauna-group", + "labels": [ + "sauna_grouped" + ], + "render": { + "special": { + "type": "group", + "header": "sauna-header", + "labels": "has_sauna;sauna_expanded;sauna-questions" } - }, - "prefix": "sauna" + } + }, + { + "id": "sauna-header", + "labels": [ + "sauna_grouped", + "hidden" + ], + "render": { + "en": "Sauna information" + }, + "icon": "./assets/layers/sauna/sauna.svg", + "mappings": [ + { + "if": "sauna=no", + "then": { + "en": "No sauna" + } + } + ] + }, + { + "id": "sauna-picture-carousel", + "labels": [ + "sauna_expanded", + "sauna_grouped", + "hidden" + ], + "render": { + "special": { + "type": "image_carousel", + "image_key": "sayna:panoramax;sauna:image;sauna:mapillary" + } + } + }, + { + "id": "sauna-picture", + "condition": { + "and": [ + { + "or": [ + "sauna=yes", + "leisure=sauna", + "beauty=sauna" + ] + } + ] + }, + "labels": [ + "sauna_expanded", + "sauna_grouped", + "hidden" + ], + "render": { + "special": { + "type": "image_upload", + "image_key": "sauna:panoramax", + "label": { + "en": "Add a picture of the sauna" + } + } + } + }, + { + "question": { + "en": "Does {title()} have a sauna?" + }, + "id": "has_sauna", + "labels": [ + "sauna_grouped", + "at_leisure_only", + "hidden" + ], + "mappings": [ + { + "if": "sauna=yes", + "then": { + "en": "Has a sauna" + } + }, + { + "if": "sauna=no", + "then": { + "en": "No sauna" + } + } + ] }, - "images", - "reviews", { "id": "sauna_access", - "condition": "leisure!=water_park", + "labels": [ + "sauna_expanded", + "sauna_grouped", + "hidden" + ], + "condition": { + "and": [ + { + "or": [ + "sauna=yes" + ] + } + ] + }, "question": { "en": "Is this sauna publicly accessible?", "de": "Ist die Sauna öffentlich zugänglich?" }, - "render": { - "en": "Access is {sauna:access}", - "de": "Zugang ist {sauna:access}" - }, - "freeform": { - "key": "sauna:access" - }, "mappings": [ { "if": "sauna:access=yes", @@ -104,48 +221,104 @@ } ] }, - "contact", - "fixme" - ], - "lineRendering": [ { - "width": 1, - "color": "blue" - } - ], - "credits:uid": 8770388, - "source": { - "osmTags": { - "or": [ - { - "and": [ - "sauna=yes", - "leisure=water_park" + "id": "charge_cost_rewritten", + "rewrite": { + "sourceString": [ + "{key}", + "{time}" + ], + "into": [ + [ + "2 hours", + { + "en": "2 hours", + "de": "2 Stunden" + } + ], + [ + "4 hours", + { + "en": "4 hours", + "de": "4 Stunden" + } + ], + [ + "day", + { + "en": "one day", + "de": "einen Tag" + } ] - }, + ] + }, + "renderings": [ { - "and": [ - "sauna=yes", - "leisure!=water_park", - "sauna:access!=no", - "sauna:access!=private", - "sauna:access!=customers" - ] + "id": "charge_{key}", + "labels": [ + "sauna_expanded", + "sauna_grouped", + "hidden" + ], + "question": { + "en": "What is the entrance fee for {time}?", + "de": "Was ist der Eintrittspreis für {time}?" + }, + "render": { + "en": "entrance fee for {time}: {charge}", + "de": "Eintrittspreis für {time}: {charge}" + }, + "freeform": { + "key": "charge", + "type": "currency", + "inline": true, + "postfixDistinguished": "{key}", + "addExtraTags": [ + "fee=yes" + ] + }, + "mappings": [ + { + "if": "fee=no", + "addExtraTags": [ + "charge=" + ], + "then": { + "en": "The sauna is free of charge", + "de": "Die Sauna ist kostenlos" + } + } + ], + "condition": { + "and": [ + "access!=customers", + "access!=no", + "access!=private", + { + "or": [ + "sauna=yes" + ] + } + ] + } } ] + }, + { + "id": "sauna-questions", + "labels": [ + "sauna_grouped", + "hidden" + ], + "render": { + "special": { + "type": "questions", + "labels": "at_leisure_only;sauna_expanded" + } + } } - }, - "description": { - "en": "A sauna is a small room or house designed as a place to experience dry or wet heat sessions, or an establishment with one or more of these and auxiliary facilities." - }, - "id": "sauna_at_leisure", - "name": { - "en": "Saunas at other amenities", - "de": "Saunen in anderen Einrichtungen" - }, - "title": { - "render": { - "en": "{name}" - } - } + ], + "allowMove": true, + "credits": "Osmwithspace", + "credits:uid": 8770388 } diff --git a/assets/layers/shops/shops.json b/assets/layers/shops/shops.json index cceec48e1..e66da0144 100644 --- a/assets/layers/shops/shops.json +++ b/assets/layers/shops/shops.json @@ -365,6 +365,69 @@ "filter": true } }, + { + "id": "beauty_shop_type", + "question": { + "en": "What type of beauty shop is this?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "beauty=nails", + "then": { + "en": "Offers nail care services such as manicures, pedicures, and nail enhancements" + } + }, + { + "if": "beauty=skin_care", + "then": { + "en": "Offers skin care services" + } + }, + { + "if": "beauty=tanning", + "then": { + "en": "Offers tanning services such as sunbeds" + } + }, + { + "if": "beauty=cosmetics", + "then": { + "en": "Offers cosmetic services, such as makeup" + } + }, + { + "if": "beauty=massage", + "then": { + "en": "Offers massages" + } + }, + { + "if": "beauty=waxing", + "then": { + "en": "Offers hair removal through waxing" + } + }, + { + "if": "beauty=hair_removal", + "then": { + "en": "Offers hair removal services, e.g. with a laser" + } + }, + { + "if": "beauty=eyebrow", + "then": { + "en": "Offers eyebrow enhancement services" + } + }, + { + "if": "beauty=pedicure", + "then": { + "en": "Offers pedicure services" + } + } + ] + }, { "id": "brand", "question": { @@ -1357,9 +1420,7 @@ { "builtin": "bike_cleaning.bike_cleaning-service_bicycle_cleaning_charge" }, - "internet", - "internet-fee", - "internet-ssid", + "internet-all", { "id": "organic", "question": { @@ -1471,6 +1532,21 @@ } } }, + { + "builtin": "sauna_at_leisure.sauna_grouped", + "override": { + "condition": { + "and+": [ + { + "or": [ + "shop=beauty", + "shop=massage" + ] + } + ] + } + } + }, "description", "toilet_at_amenity_lib.all" ], diff --git a/assets/layers/tourism_accomodation/tourism_accomodation.json b/assets/layers/tourism_accomodation/tourism_accomodation.json index 75885933f..7e32981e3 100644 --- a/assets/layers/tourism_accomodation/tourism_accomodation.json +++ b/assets/layers/tourism_accomodation/tourism_accomodation.json @@ -408,6 +408,7 @@ "contact", "wheelchair-access", "toilet_at_amenity_lib.all", + "sauna_at_leisure.sauna_grouped", "internet-all", "dog-access" ], diff --git a/assets/themes/sauna/sauna.json b/assets/themes/sauna/sauna.json index b0056e88c..eb66bb7b5 100644 --- a/assets/themes/sauna/sauna.json +++ b/assets/themes/sauna/sauna.json @@ -1,16 +1,109 @@ { - "credits": "Osmwithspace", - "credits:uid": 8770388, "id": "sauna", "title": { "en": "Sauna" }, - "layers": [ - "sauna", - "sauna_at_leisure" - ], "description": { "en": "Sauna" }, - "icon": "./assets/layers/sauna/sauna.svg" + "icon": "./assets/layers/sauna/sauna.svg", + "credits": [ + "Osmwithspace" + ], + "#layers": "sauna_at_leisure acts as fallback-layer and will show all objects with `sauna=yes`", + "layers": [ + "sauna", + { + "builtin": "tourism_accomodation", + "override": { + "id": "tourism_accomodation_with_sauna", + "presets=": [], + "filter=": [], + "minzoom": 8, + "source": { + "osmTags": { + "and+": "sauna=yes" + } + } + } + }, + { + "builtin": "tourism_accomodation", + "override": { + "minzoom": 18, + "name=": null, + "filter": { + "sameAs": "tourism_accomodation_with_sauna" + } + } + }, + { + "builtin": "shops", + "override": { + "id": "shops_with_sauna", + "source": { + "osmTags": + { + "and+": [ + "sauna=yes" + ] + } + + }, + "presets=":[], + "minzoom": 8, + "filter=": [] + } + }, + { + "builtin": "shops", + "hideTagRenderingsWithLabels": [ + "shop_types" + ], + "override": { + "id": "beauty_shops", + "minzoom": 18, + "name=": null, + "source": { + "osmTags": { + "and+": [ + { + "or": [ + "shop=beauty", + "shop=massage" + ] + } + ] + } + }, + "presets=": [ + { + "tags": [ + "shop=beauty" + ], + "title": { + "en": "a beauty shop" + } + }, + { + "tags": [ + "shop=massage" + ], + "title": { + "en": "a massage shop" + } + } + ] + } + }, + { + "builtin": "toilet", + "override": { + "minzoom":18, + "name=": null + } + }, + "sauna_at_leisure" + ], + "credits:uid": 8770388 } diff --git a/src/Models/ThemeConfig/Conversion/PrepareLayer.ts b/src/Models/ThemeConfig/Conversion/PrepareLayer.ts index 3f9c37b09..62256c392 100644 --- a/src/Models/ThemeConfig/Conversion/PrepareLayer.ts +++ b/src/Models/ThemeConfig/Conversion/PrepareLayer.ts @@ -1072,7 +1072,7 @@ class DeriveSource extends DesugaringStep { return json } - json.source = { osmTags } + json.source = { osmTags: {and: [osmTags]} } return json } } diff --git a/src/Models/ThemeConfig/LayerConfig.ts b/src/Models/ThemeConfig/LayerConfig.ts index d27004458..db66b509e 100644 --- a/src/Models/ThemeConfig/LayerConfig.ts +++ b/src/Models/ThemeConfig/LayerConfig.ts @@ -71,7 +71,7 @@ export default class LayerConfig extends WithContextLoader { * If this layer is based on another layer, this might be indicated here * @private */ - private readonly _basedOn: string | undefined + public readonly _basedOn: string | undefined constructor( json: LayerConfigJson, diff --git a/src/UI/Popup/DataVisualisations.ts b/src/UI/Popup/DataVisualisations.ts index d1b5a885f..05b15f471 100644 --- a/src/UI/Popup/DataVisualisations.ts +++ b/src/UI/Popup/DataVisualisations.ts @@ -248,6 +248,10 @@ class PresetTypeSelect extends SpecialVisualizationSvelte { layer: LayerConfig, ): SvelteUIElement { const t = Translations.t.preset_type + if(layer._basedOn !== layer.id){ + console.warn("Trying to use the _original_ layer") + layer = state.theme.layers.find(l => l.id === layer._basedOn) ?? layer + } const question: QuestionableTagRenderingConfigJson = { id: layer.id + "-type", question: t.question.translations, @@ -260,6 +264,10 @@ class PresetTypeSelect extends SpecialVisualizationSvelte { }).translations, })), } + if(question.mappings.length === 0){ + console.error("No mappings for preset_type_select, something went wrong") + return undefined + } const config = new TagRenderingConfig(question) return new SvelteUIElement(TagRenderingEditable, { config,