From 18a1221dd4ebbce0034aaa5047299583f0e5cd4c Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 22 Sep 2021 16:46:25 +0200 Subject: [PATCH 01/65] Add parking fee to charging stations theme --- .../charging_station.protojson | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/assets/layers/charging_station/charging_station.protojson b/assets/layers/charging_station/charging_station.protojson index ddc91b36a..7689ae905 100644 --- a/assets/layers/charging_station/charging_station.protojson +++ b/assets/layers/charging_station/charging_station.protojson @@ -523,6 +523,26 @@ } } ] + }, + { + "#": "Parking:fee", + "question": { + "en": "Does one have to pay a parking fee while charging?" + }, + "mappings": [ + { + "if": "parking:fee=no", + "then": { + "en": "No additional parking cost while charging" + } + }, + { + "if": "parking:fee=yes", + "then": { + "en": "An additional parking fee should be paid while charging" + } + } + ] } ], "icon": { From 73f76881c43b3d1c7bd70c41460ae03b27d18467 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 22 Sep 2021 16:58:25 +0200 Subject: [PATCH 02/65] Use same formatting as weblate for translation files --- assets/layers/barrier/barrier.json | 574 +-- assets/layers/bench/bench.json | 1218 ++--- assets/layers/bench_at_pt/bench_at_pt.json | 276 +- .../bicycle_library/bicycle_library.json | 528 +- .../bicycle_tube_vending_machine.json | 448 +- assets/layers/bike_cafe/bike_cafe.json | 670 +-- .../layers/bike_cleaning/bike_cleaning.json | 270 +- .../bike_monitoring_station.json | 160 +- assets/layers/bike_parking/bike_parking.json | 974 ++-- .../bike_repair_station.json | 1398 +++--- assets/layers/bike_shop/bike_shop.json | 1346 +++--- .../bike_themed_object.json | 138 +- assets/layers/binocular/binocular.json | 196 +- assets/layers/birdhide/birdhide.json | 570 +-- assets/layers/cafe_pub/cafe_pub.json | 356 +- .../charging_station/charging_station.json | 4294 ++++++++--------- assets/layers/crossings/crossings.json | 620 +-- .../cycleways_and_roads.json | 2330 ++++----- .../layers/defibrillator/defibrillator.json | 1050 ++-- assets/layers/direction/direction.json | 90 +- .../layers/drinking_water/drinking_water.json | 306 +- assets/layers/food/food.json | 1182 ++--- assets/layers/ghost_bike/ghost_bike.json | 358 +- .../layers/grass_in_parks/grass_in_parks.json | 92 +- .../information_board/information_board.json | 110 +- assets/layers/map/map.json | 446 +- .../layers/nature_reserve/nature_reserve.json | 906 ++-- .../observation_tower/observation_tower.json | 350 +- assets/layers/parking/parking.json | 370 +- assets/layers/picnic_table/picnic_table.json | 202 +- assets/layers/play_forest/play_forest.json | 204 +- assets/layers/playground/playground.json | 1024 ++-- .../public_bookcase/public_bookcase.json | 914 ++-- assets/layers/slow_roads/slow_roads.json | 484 +- assets/layers/sport_pitch/sport_pitch.json | 966 ++-- .../surveillance_camera.json | 936 ++-- assets/layers/toilet/toilet.json | 770 +-- assets/layers/trail/trail.json | 388 +- assets/layers/tree_node/tree_node.json | 1106 ++--- assets/layers/viewpoint/viewpoint.json | 130 +- .../layers/village_green/village_green.json | 64 +- .../visitor_information_centre.json | 120 +- assets/layers/waste_basket/waste_basket.json | 228 +- assets/layers/watermill/watermill.json | 322 +- scripts/generateTranslations.ts | 2 +- 45 files changed, 14743 insertions(+), 14743 deletions(-) diff --git a/assets/layers/barrier/barrier.json b/assets/layers/barrier/barrier.json index e7cc75562..7c215f8f5 100644 --- a/assets/layers/barrier/barrier.json +++ b/assets/layers/barrier/barrier.json @@ -1,293 +1,293 @@ { - "id": "barrier", - "name": { - "en": "Barriers", - "nl": "Barrières" - }, - "description": { - "en": "Obstacles while cycling, such as bollards and cycle barriers", - "nl": "Hindernissen tijdens het fietsen, zoals paaltjes en fietshekjes" - }, - "source": { - "osmTags": { - "or": [ - "barrier=bollard", - "barrier=cycle_barrier" - ] - } - }, - "minzoom": 17, - "title": { - "render": { - "en": "Barrier", - "nl": "Barrière" + "id": "barrier", + "name": { + "en": "Barriers", + "nl": "Barrières" }, - "mappings": [ - { - "if": "barrier=bollard", - "then": { - "en": "Bollard", - "nl": "Paaltje" + "description": { + "en": "Obstacles while cycling, such as bollards and cycle barriers", + "nl": "Hindernissen tijdens het fietsen, zoals paaltjes en fietshekjes" + }, + "source": { + "osmTags": { + "or": [ + "barrier=bollard", + "barrier=cycle_barrier" + ] } - }, - { - "if": "barrier=cycle_barrier", - "then": { - "en": "Cycling Barrier", - "nl": "Fietshekjes" + }, + "minzoom": 17, + "title": { + "render": { + "en": "Barrier", + "nl": "Barrière" + }, + "mappings": [ + { + "if": "barrier=bollard", + "then": { + "en": "Bollard", + "nl": "Paaltje" + } + }, + { + "if": "barrier=cycle_barrier", + "then": { + "en": "Cycling Barrier", + "nl": "Fietshekjes" + } + } + ] + }, + "icon": "./assets/layers/barrier/barrier.svg", + "width": "5", + "presets": [ + { + "title": { + "en": "Bollard", + "nl": "Paaltje" + }, + "tags": [ + "barrier=bollard" + ], + "description": { + "en": "A bollard in the road", + "nl": "Een paaltje in de weg" + }, + "preciseInput": { + "preferredBackground": [ + "photo" + ], + "snapToLayer": "cycleways_and_roads", + "maxSnapDistance": 25 + } + }, + { + "title": { + "en": "Cycle barrier", + "nl": "Fietshekjes" + }, + "tags": [ + "barrier=bollard" + ], + "description": { + "en": "Cycle barrier, slowing down cyclists", + "nl": "Fietshekjes, voor het afremmen van fietsers" + }, + "preciseInput": { + "preferredBackground": [ + "photo" + ], + "snapToLayer": "cycleways_and_roads", + "maxSnapDistance": 25 + } + } + ], + "tagRenderings": [ + { + "#": "bicycle=yes/no", + "question": { + "en": "Can a bicycle go past this barrier?", + "nl": "Kan een fietser langs deze barrière?" + }, + "mappings": [ + { + "if": "bicycle=yes", + "then": { + "en": "A cyclist can go past this.", + "nl": "Een fietser kan hier langs." + } + }, + { + "if": "bicycle=no", + "then": { + "en": "A cyclist can not go past this.", + "nl": "Een fietser kan hier niet langs." + } + } + ] + }, + { + "#": "Bollard type", + "question": { + "en": "What kind of bollard is this?", + "nl": "Wat voor soort paal is dit?" + }, + "condition": "barrier=bollard", + "mappings": [ + { + "if": "bollard=removable", + "then": { + "en": "Removable bollard", + "nl": "Verwijderbare paal" + } + }, + { + "if": "bollard=fixed", + "then": { + "en": "Fixed bollard", + "nl": "Vaste paal" + } + }, + { + "if": "bollard=foldable", + "then": { + "en": "Bollard that can be folded down", + "nl": "Paal die platgevouwen kan worden" + } + }, + { + "if": "bollard=flexible", + "then": { + "en": "Flexible bollard, usually plastic", + "nl": "Flexibele paal, meestal plastic" + } + }, + { + "if": "bollard=rising", + "then": { + "en": "Rising bollard", + "nl": "Verzonken poller" + } + } + ] + }, + { + "#": "Cycle barrier type", + "question": { + "en": "What kind of cycling barrier is this?", + "nl": "Wat voor fietshekjes zijn dit?" + }, + "condition": "barrier=cycle_barrier", + "mappings": [ + { + "if": "cycle_barrier:type=single", + "then": { + "en": "Single, just two barriers with a space inbetween ", + "nl": "Enkelvoudig, slechts twee hekjes met ruimte ertussen " + } + }, + { + "if": "cycle_barrier:type=double", + "then": { + "en": "Double, two barriers behind each other ", + "nl": "Dubbel, twee hekjes achter elkaar " + } + }, + { + "if": "cycle_barrier:type=triple", + "then": { + "en": "Triple, three barriers behind each other ", + "nl": "Drievoudig, drie hekjes achter elkaar " + } + }, + { + "if": "cycle_barrier:type=squeeze", + "then": { + "en": "Squeeze gate, gap is smaller at top, than at the bottom ", + "nl": "Knijppoort, ruimte is smaller aan de top, dan aan de bodem " + } + } + ] + }, + { + "#": "MaxWidth", + "render": { + "en": "Maximum width: {maxwidth:physical} m", + "nl": "Maximumbreedte: {maxwidth:physical} m" + }, + "question": { + "en": "How wide is the gap left over besides the barrier?", + "nl": "Hoe breed is de ruimte naast de barrière?" + }, + "condition": { + "and": [ + "cycle_barrier:type!=double", + "cycle_barrier:type!=triple" + ] + }, + "freeform": { + "key": "maxwidth:physical", + "type": "length", + "helperArgs": [ + "20", + "map" + ] + } + }, + { + "#": "Space between barrier (cyclebarrier)", + "render": { + "en": "Space between barriers (along the length of the road): {width:separation} m", + "nl": "Ruimte tussen barrières (langs de lengte van de weg): {width:separation} m" + }, + "question": { + "en": "How much space is there between the barriers (along the length of the road)?", + "nl": "Hoeveel ruimte is er tussen de barrières (langs de lengte van de weg)?" + }, + "condition": { + "or": [ + "cycle_barrier:type=double", + "cycle_barrier:type=triple" + ] + }, + "freeform": { + "key": "width:separation", + "type": "length", + "helperArgs": [ + "21", + "map" + ] + } + }, + { + "#": "Width of opening (cyclebarrier)", + "render": { + "en": "Width of opening: {width:opening} m", + "nl": "Breedte van de opening: {width:opening} m" + }, + "question": { + "en": "How wide is the smallest opening next to the barriers?", + "nl": "Hoe breed is de smalste opening naast de barrières?" + }, + "condition": { + "or": [ + "cycle_barrier:type=double", + "cycle_barrier:type=triple" + ] + }, + "freeform": { + "key": "width:opening", + "type": "length", + "helperArgs": [ + "21", + "map" + ] + } + }, + { + "#": "Overlap (cyclebarrier)", + "render": { + "en": "Overlap: {overlap} m" + }, + "question": { + "en": "How much overlap do the barriers have?", + "nl": "Hoeveel overlappen de barrières?" + }, + "condition": { + "or": [ + "cycle_barrier:type=double", + "cycle_barrier:type=triple" + ] + }, + "freeform": { + "key": "overlap", + "type": "length", + "helperArgs": [ + "21", + "map" + ] + } } - } ] - }, - "icon": "./assets/layers/barrier/barrier.svg", - "width": "5", - "presets": [ - { - "title": { - "en": "Bollard", - "nl": "Paaltje" - }, - "tags": [ - "barrier=bollard" - ], - "description": { - "en": "A bollard in the road", - "nl": "Een paaltje in de weg" - }, - "preciseInput": { - "preferredBackground": [ - "photo" - ], - "snapToLayer": "cycleways_and_roads", - "maxSnapDistance": 25 - } - }, - { - "title": { - "en": "Cycle barrier", - "nl": "Fietshekjes" - }, - "tags": [ - "barrier=bollard" - ], - "description": { - "en": "Cycle barrier, slowing down cyclists", - "nl": "Fietshekjes, voor het afremmen van fietsers" - }, - "preciseInput": { - "preferredBackground": [ - "photo" - ], - "snapToLayer": "cycleways_and_roads", - "maxSnapDistance": 25 - } - } - ], - "tagRenderings": [ - { - "#": "bicycle=yes/no", - "question": { - "en": "Can a bicycle go past this barrier?", - "nl": "Kan een fietser langs deze barrière?" - }, - "mappings": [ - { - "if": "bicycle=yes", - "then": { - "en": "A cyclist can go past this.", - "nl": "Een fietser kan hier langs." - } - }, - { - "if": "bicycle=no", - "then": { - "en": "A cyclist can not go past this.", - "nl": "Een fietser kan hier niet langs." - } - } - ] - }, - { - "#": "Bollard type", - "question": { - "en": "What kind of bollard is this?", - "nl": "Wat voor soort paal is dit?" - }, - "condition": "barrier=bollard", - "mappings": [ - { - "if": "bollard=removable", - "then": { - "en": "Removable bollard", - "nl": "Verwijderbare paal" - } - }, - { - "if": "bollard=fixed", - "then": { - "en": "Fixed bollard", - "nl": "Vaste paal" - } - }, - { - "if": "bollard=foldable", - "then": { - "en": "Bollard that can be folded down", - "nl": "Paal die platgevouwen kan worden" - } - }, - { - "if": "bollard=flexible", - "then": { - "en": "Flexible bollard, usually plastic", - "nl": "Flexibele paal, meestal plastic" - } - }, - { - "if": "bollard=rising", - "then": { - "en": "Rising bollard", - "nl": "Verzonken poller" - } - } - ] - }, - { - "#": "Cycle barrier type", - "question": { - "en": "What kind of cycling barrier is this?", - "nl": "Wat voor fietshekjes zijn dit?" - }, - "condition": "barrier=cycle_barrier", - "mappings": [ - { - "if": "cycle_barrier:type=single", - "then": { - "en": "Single, just two barriers with a space inbetween ", - "nl": "Enkelvoudig, slechts twee hekjes met ruimte ertussen " - } - }, - { - "if": "cycle_barrier:type=double", - "then": { - "en": "Double, two barriers behind each other ", - "nl": "Dubbel, twee hekjes achter elkaar " - } - }, - { - "if": "cycle_barrier:type=triple", - "then": { - "en": "Triple, three barriers behind each other ", - "nl": "Drievoudig, drie hekjes achter elkaar " - } - }, - { - "if": "cycle_barrier:type=squeeze", - "then": { - "en": "Squeeze gate, gap is smaller at top, than at the bottom ", - "nl": "Knijppoort, ruimte is smaller aan de top, dan aan de bodem " - } - } - ] - }, - { - "#": "MaxWidth", - "render": { - "en": "Maximum width: {maxwidth:physical} m", - "nl": "Maximumbreedte: {maxwidth:physical} m" - }, - "question": { - "en": "How wide is the gap left over besides the barrier?", - "nl": "Hoe breed is de ruimte naast de barrière?" - }, - "condition": { - "and": [ - "cycle_barrier:type!=double", - "cycle_barrier:type!=triple" - ] - }, - "freeform": { - "key": "maxwidth:physical", - "type": "length", - "helperArgs": [ - "20", - "map" - ] - } - }, - { - "#": "Space between barrier (cyclebarrier)", - "render": { - "en": "Space between barriers (along the length of the road): {width:separation} m", - "nl": "Ruimte tussen barrières (langs de lengte van de weg): {width:separation} m" - }, - "question": { - "en": "How much space is there between the barriers (along the length of the road)?", - "nl": "Hoeveel ruimte is er tussen de barrières (langs de lengte van de weg)?" - }, - "condition": { - "or": [ - "cycle_barrier:type=double", - "cycle_barrier:type=triple" - ] - }, - "freeform": { - "key": "width:separation", - "type": "length", - "helperArgs": [ - "21", - "map" - ] - } - }, - { - "#": "Width of opening (cyclebarrier)", - "render": { - "en": "Width of opening: {width:opening} m", - "nl": "Breedte van de opening: {width:opening} m" - }, - "question": { - "en": "How wide is the smallest opening next to the barriers?", - "nl": "Hoe breed is de smalste opening naast de barrières?" - }, - "condition": { - "or": [ - "cycle_barrier:type=double", - "cycle_barrier:type=triple" - ] - }, - "freeform": { - "key": "width:opening", - "type": "length", - "helperArgs": [ - "21", - "map" - ] - } - }, - { - "#": "Overlap (cyclebarrier)", - "render": { - "en": "Overlap: {overlap} m" - }, - "question": { - "en": "How much overlap do the barriers have?", - "nl": "Hoeveel overlappen de barrières?" - }, - "condition": { - "or": [ - "cycle_barrier:type=double", - "cycle_barrier:type=triple" - ] - }, - "freeform": { - "key": "overlap", - "type": "length", - "helperArgs": [ - "21", - "map" - ] - } - } - ] } \ No newline at end of file diff --git a/assets/layers/bench/bench.json b/assets/layers/bench/bench.json index a2cf274dd..a18a31723 100644 --- a/assets/layers/bench/bench.json +++ b/assets/layers/bench/bench.json @@ -1,614 +1,614 @@ { - "id": "bench", - "name": { - "en": "Benches", - "de": "Sitzbänke", - "fr": "Bancs", - "nl": "Zitbanken", - "es": "Bancos", - "hu": "Padok", - "id": "Bangku", - "it": "Panchine", - "ru": "Скамейки", - "zh_Hans": "长椅", - "zh_Hant": "長椅", - "nb_NO": "Benker", - "fi": "Penkit", - "pl": "Ławki", - "pt_BR": "Bancos" - }, - "minzoom": 17, - "source": { - "osmTags": "amenity=bench" - }, - "wayHandling": 1, - "title": { - "render": { - "en": "Bench", - "de": "Sitzbank", - "fr": "Banc", - "nl": "Zitbank", - "es": "Banco", - "hu": "Pad", - "id": "Bangku", - "it": "Panchina", - "ru": "Скамейка", - "zh_Hans": "长椅", - "zh_Hant": "長椅", - "nb_NO": "Benk", - "fi": "Penkki", - "pl": "Ławka", - "pt_BR": "Banco" - } - }, - "tagRenderings": [ - "images", - { - "render": { - "en": "Backrest", - "de": "Rückenlehne", - "fr": "Dossier", - "nl": "Rugleuning", - "es": "Respaldo", - "hu": "Háttámla", - "id": "Sandaran", - "it": "Schienale", - "ru": "Спинка", - "zh_Hans": "靠背", - "zh_Hant": "靠背", - "nb_NO": "Rygglene", - "fi": "Selkänoja", - "pl": "Oparcie", - "pt_BR": "Encosto" - }, - "freeform": { - "key": "backrest" - }, - "mappings": [ - { - "if": "backrest=yes", - "then": { - "en": "Backrest: Yes", - "de": "Rückenlehne: Ja", - "fr": "Dossier : Oui", - "nl": "Heeft een rugleuning", - "es": "Respaldo: Si", - "hu": "Háttámla: Igen", - "id": "Sandaran: Ya", - "it": "Schienale: Sì", - "ru": "Со спинкой", - "zh_Hans": "靠背:有", - "zh_Hant": "靠背:有", - "nb_NO": "Rygglene: Ja", - "fi": "Selkänoja: kyllä", - "pl": "Oparcie: Tak", - "pt_BR": "Encosto: Sim" - } - }, - { - "if": "backrest=no", - "then": { - "en": "Backrest: No", - "de": "Rückenlehne: Nein", - "fr": "Dossier : Non", - "nl": "Rugleuning ontbreekt", - "es": "Respaldo: No", - "hu": "Háttámla: Nem", - "id": "Sandaran: Tidak", - "it": "Schienale: No", - "ru": "Без спинки", - "zh_Hans": "靠背:无", - "zh_Hant": "靠背:無", - "nb_NO": "Rygglene: Nei", - "fi": "Selkänoja: ei", - "pl": "Oparcie: Nie", - "pt_BR": "Encosto: Não" - } - } - ], - "question": { - "en": "Does this bench have a backrest?", - "de": "Hat diese Bank eine Rückenlehne?", - "fr": "Ce banc dispose-t-il d'un dossier ?", - "nl": "Heeft deze zitbank een rugleuning?", - "es": "¿Este banco tiene un respaldo?", - "hu": "Van háttámlája ennek a padnak?", - "id": "Apakah bangku ini memiliki sandaran?", - "it": "Questa panchina ha lo schienale?", - "ru": "Есть ли у этой скамейки спинка?", - "zh_Hans": "这个长椅有靠背吗?", - "zh_Hant": "這個長椅是否有靠背?", - "nb_NO": "Har denne beken et rygglene?", - "pl": "Czy ta ławka ma oparcie?", - "pt_BR": "Este assento tem um escosto?" - } - }, - { - "render": { - "en": "{seats} seats", - "de": "{seats} Sitzplätze", - "fr": "{seats} places", - "nl": "{seats} zitplaatsen", - "es": "{seats} asientos", - "hu": "{seats} ülőhely", - "id": "{seats} kursi", - "it": "{seats} posti", - "ru": "{seats} мест", - "zh_Hant": "{seats} 座位數", - "nb_NO": "{seats} seter", - "pl": "{seats} siedzeń", - "pt_BR": "{seats} assentos" - }, - "freeform": { - "key": "seats", - "type": "nat" - }, - "question": { - "en": "How many seats does this bench have?", - "de": "Wie viele Sitzplätze hat diese Bank?", - "fr": "De combien de places dispose ce banc ?", - "nl": "Hoeveel zitplaatsen heeft deze bank?", - "es": "¿Cuántos asientos tiene este banco?", - "hu": "Hány ülőhely van ezen a padon?", - "it": "Quanti posti ha questa panchina?", - "ru": "Сколько мест на этой скамейке?", - "zh_Hans": "这个长椅有几个座位?", - "zh_Hant": "這個長椅有幾個位子?", - "nb_NO": "Hvor mange sitteplasser har denne benken?", - "pl": "Ile siedzeń ma ta ławka?", - "pt_BR": "Quantos assentos este banco tem?" - } - }, - { - "render": { - "en": "Material: {material}", - "de": "Material: {material}", - "fr": "Matériau : {material}", - "nl": "Gemaakt van {material}", - "es": "Material: {material}", - "hu": "Anyag: {material}", - "it": "Materiale: {material}", - "ru": "Материал: {material}", - "zh_Hanå¨s": "材质: {material}", - "zh_Hant": "材質:{material}", - "nb_NO": "Materiale: {material}", - "fi": "Materiaali: {material}", - "zh_Hans": "材质: {material}", - "pl": "Materiał: {material}", - "pt_BR": "Material: {material}" - }, - "freeform": { - "key": "material", - "addExtraTags": [] - }, - "mappings": [ - { - "if": "material=wood", - "then": { - "en": "Material: wood", - "de": "Material: Holz", - "fr": "Matériau : bois", - "nl": "Gemaakt uit hout", - "es": "Material: madera", - "hu": "Anyag: fa", - "it": "Materiale: legno", - "ru": "Материал: дерево", - "zh_Hans": "材质:木", - "nb_NO": "Materiale: tre", - "zh_Hant": "材質:木頭", - "pt_BR": "Material: madeira", - "fi": "Materiaali: puu", - "pl": "Materiał: drewno" - } - }, - { - "if": "material=metal", - "then": { - "en": "Material: metal", - "de": "Material: Metall", - "fr": "Matériau : métal", - "nl": "Gemaakt uit metaal", - "es": "Material: metal", - "hu": "Anyag: fém", - "it": "Materiale: metallo", - "ru": "Материал: металл", - "zh_Hans": "材质:金属", - "nb_NO": "Materiale: metall", - "zh_Hant": "材質:金屬", - "pl": "Materiał: metal", - "pt_BR": "Material: metal" - } - }, - { - "if": "material=stone", - "then": { - "en": "Material: stone", - "de": "Material: Stein", - "fr": "Matériau : pierre", - "nl": "Gemaakt uit steen", - "es": "Material: piedra", - "hu": "Anyag: kő", - "it": "Materiale: pietra", - "ru": "Материал: камень", - "zh_Hans": "材质:石头", - "nb_NO": "Materiale: stein", - "zh_Hant": "材質:石頭", - "pt_BR": "Material: pedra", - "fi": "Materiaali: kivi", - "pl": "Materiał: kamień" - } - }, - { - "if": "material=concrete", - "then": { - "en": "Material: concrete", - "de": "Material: Beton", - "fr": "Matériau : béton", - "nl": "Gemaakt uit beton", - "es": "Material: concreto", - "hu": "Anyag: beton", - "it": "Materiale: cemento", - "ru": "Материал: бетон", - "zh_Hans": "材质:混凝土", - "nb_NO": "Materiale: betong", - "zh_Hant": "材質:水泥", - "pt_BR": "Material: concreto", - "fi": "Materiaali: betoni", - "pl": "Materiał: beton" - } - }, - { - "if": "material=plastic", - "then": { - "en": "Material: plastic", - "de": "Material: Kunststoff", - "fr": "Matériau : plastique", - "nl": "Gemaakt uit plastiek", - "es": "Material: plastico", - "hu": "Anyag: műanyag", - "it": "Materiale: plastica", - "ru": "Материал: пластик", - "zh_Hans": "材质:塑料", - "nb_NO": "Materiale: plastikk", - "zh_Hant": "材質:塑膠", - "pt_BR": "Material: plástico", - "fi": "Materiaali: muovi", - "pl": "Materiał: plastik" - } - }, - { - "if": "material=steel", - "then": { - "en": "Material: steel", - "de": "Material: Stahl", - "fr": "Matériau : acier", - "nl": "Gemaakt uit staal", - "es": "Material: acero", - "hu": "Anyag: acél", - "it": "Materiale: acciaio", - "ru": "Материал: сталь", - "zh_Hans": "材质:不锈钢", - "nb_NO": "Materiale: stål", - "zh_Hant": "材質:鋼鐵", - "pt_BR": "Material: aço", - "fi": "Materiaali: teräs", - "pl": "Materiał: stal" - } - } - ], - "question": { - "en": "What is the bench (seating) made from?", - "de": "Aus welchem Material besteht die Sitzbank (Sitzfläche)?", - "fr": "De quel matériau ce banc est-il fait ?", - "nl": "Uit welk materiaal is het zitgedeelte van deze zitbank gemaakt?", - "hu": "Miből van a pad (ülő része)?", - "it": "Di che materiale è fatta questa panchina?", - "zh_Hans": "这个长椅(或座椅)是用什么材料做的?", - "ru": "Из какого материала сделана скамейка?", - "zh_Hant": "這個長椅 (座位) 是什麼做的?", - "pt_BR": "De que é feito o banco (assento)?", - "pl": "Z czego wykonana jest ławka (siedzisko)?" - } - }, - { - "question": { - "en": "In which direction are you looking when sitting on the bench?", - "de": "In welche Richtung schaut man, wenn man auf der Bank sitzt?", - "nl": "In welke richting kijk je wanneer je op deze zitbank zit?", - "fr": "Dans quelle direction regardez-vous quand vous êtes assis sur le banc ?", - "hu": "Milyen irányba néz a pad?", - "it": "In che direzione si guarda quando si è seduti su questa panchina?", - "ru": "В каком направлении вы смотрите, когда сидите на скамейке?", - "zh_Hans": "坐在长椅上的时候你目视的方向是哪边?", - "zh_Hant": "坐在長椅時是面對那個方向?", - "pt_BR": "Em que direção você olha quando está sentado no banco?", - "pl": "W jakim kierunku patrzysz siedząc na ławce?" - }, - "render": { - "en": "When sitting on the bench, one looks towards {direction}°.", - "de": "Wenn man auf der Bank sitzt, schaut man in Richtung {direction}°.", - "nl": "Wanneer je op deze bank zit, dan kijk je in {direction}°.", - "fr": "Assis sur le banc, on regarde vers {direction}°.", - "hu": "A pad {direction}° felé néz.", - "it": "Quando si è seduti su questa panchina, si guarda verso {direction}°.", - "zh_Hans": "坐在长椅上的时候目视方向为 {direction}°方位。", - "ru": "Сидя на скамейке, вы смотрите в сторону {direction}°.", - "zh_Hant": "當坐在長椅時,那個人朝向 {direction}°。", - "pl": "Siedząc na ławce, patrzy się w kierunku {direction}°.", - "pt_BR": "Ao sentar-se no banco, olha-se para {direction} °." - }, - "freeform": { - "key": "direction", - "type": "direction" - } - }, - { - "render": { - "en": "Colour: {colour}", - "de": "Farbe: {colour}", - "fr": "Couleur : {colour}", - "nl": "Kleur: {colour}", - "hu": "Szín: {colour}", - "it": "Colore: {colour}", - "ru": "Цвет: {colour}", - "id": "Warna: {colour}", - "zh_Hans": "颜色: {colour}", - "zh_Hant": "顏色:{colour}", - "nb_NO": "Farge: {colour}", - "pt_BR": "Cor: {colour}", - "fi": "Väri: {colour}", - "pl": "Kolor: {colour}" - }, - "question": { - "en": "Which colour does this bench have?", - "de": "Welche Farbe hat diese Sitzbank?", - "fr": "Quelle est la couleur de ce banc ?", - "nl": "Welke kleur heeft deze zitbank?", - "hu": "Milyen színű a pad?", - "it": "Di che colore è questa panchina?", - "ru": "Какого цвета скамейка?", - "zh_Hans": "这个长椅是什么颜色的?", - "zh_Hant": "這個長椅是什麼顏色的?", - "pt_BR": "Qual a cor dessa bancada?", - "pl": "Jaki kolor ma ta ławka?" - }, - "freeform": { - "key": "colour", - "type": "color" - }, - "mappings": [ - { - "if": "colour=brown", - "then": { - "en": "Colour: brown", - "de": "Farbe: braun", - "fr": "Couleur : marron", - "nl": "De kleur is bruin", - "hu": "Szín: barna", - "it": "Colore: marrone", - "ru": "Цвет: коричневый", - "zh_Hans": "颜色:棕", - "zh_Hant": "顏色:棕色", - "nb_NO": "Farge: brun", - "pt_BR": "Cor: marrom", - "fi": "Väri: ruskea", - "pl": "Kolor: brązowy" - } - }, - { - "if": "colour=green", - "then": { - "en": "Colour: green", - "de": "Farbe: grün", - "fr": "Couleur : verte", - "nl": "De kleur is groen", - "hu": "Szín: zöld", - "it": "Colore: verde", - "ru": "Цвет: зеленый", - "zh_Hans": "颜色:绿", - "zh_Hant": "顏色:綠色", - "nb_NO": "Farge: grønn", - "pt_BR": "Cor: verde", - "fi": "Väri: vihreä", - "pl": "Kolor: zielony" - } - }, - { - "if": "colour=gray", - "then": { - "en": "Colour: gray", - "de": "Farbe: grau", - "fr": "Couleur : gris", - "nl": "De kleur is grijs", - "hu": "Szín: szürke", - "it": "Colore: grigio", - "ru": "Цвет: серый", - "zh_Hans": "颜色:灰", - "zh_Hant": "顏色:灰色", - "nb_NO": "Farge: grå", - "pt_BR": "Cor: cinza", - "fi": "Väri: harmaa", - "pl": "Kolor: szary" - } - }, - { - "if": "colour=white", - "then": { - "en": "Colour: white", - "de": "Farbe: weiß", - "fr": "Couleur : blanc", - "nl": "De kleur is wit", - "hu": "Szín: fehér", - "it": "Colore: bianco", - "ru": "Цвет: белый", - "zh_Hans": "颜色:白", - "zh_Hant": "顏色:白色", - "nb_NO": "Farge: hvit", - "pt_BR": "Cor: branco", - "fi": "Väri: valkoinen", - "pl": "Kolor: biały" - } - }, - { - "if": "colour=red", - "then": { - "en": "Colour: red", - "de": "Farbe: rot", - "fr": "Couleur : rouge", - "nl": "De kleur is rood", - "hu": "Szín: piros", - "it": "Colore: rosso", - "ru": "Цвет: красный", - "zh_Hans": "颜色:红", - "zh_Hant": "顏色:紅色", - "nb_NO": "Farge: rød", - "pt_BR": "Cor: vermelho", - "fi": "Väri: punainen", - "pl": "Kolor: czerwony" - } - }, - { - "if": "colour=black", - "then": { - "en": "Colour: black", - "de": "Farbe: schwarz", - "fr": "Couleur : noire", - "nl": "De kleur is zwart", - "hu": "Szín: fekete", - "it": "Colore: nero", - "ru": "Цвет: чёрный", - "zh_Hans": "颜色:黑", - "zh_Hant": "顏色:黑色", - "nb_NO": "Farge: svart", - "pt_BR": "Cor: preto", - "fi": "Väri: musta", - "pl": "Kolor: czarny" - } - }, - { - "if": "colour=blue", - "then": { - "en": "Colour: blue", - "de": "Farbe: blau", - "fr": "Couleur : bleu", - "nl": "De kleur is blauw", - "hu": "Szín: kék", - "it": "Colore: blu", - "ru": "Цвет: синий", - "zh_Hans": "颜色:蓝", - "zh_Hant": "顏色:藍色", - "nb_NO": "Farge: blå", - "pt_BR": "Cor: azul", - "fi": "Väri: sininen", - "pl": "Kolor: niebieski" - } - }, - { - "if": "colour=yellow", - "then": { - "en": "Colour: yellow", - "de": "Farbe: gelb", - "fr": "Couleur : jaune", - "nl": "De kleur is geel", - "hu": "Szín: sárga", - "it": "Colore: giallo", - "ru": "Цвет: желтый", - "zh_Hans": "颜色:黄", - "zh_Hant": "顏色:黃色", - "nb_NO": "Farge: gul", - "pt_BR": "Cor: amarelo", - "fi": "Väri: keltainen", - "pl": "Kolor: żółty" - } - } - ] - }, - { - "question": { - "en": "When was this bench last surveyed?", - "nl": "Wanneer is deze laatste bank laatst gesurveyed?", - "fr": "Quand ce banc a-t-il été contrôlé pour la dernière fois ?", - "it": "Quando è stata verificata l’ultima volta questa panchina?", - "zh_Hans": "上次对这个长椅实地调查是什么时候?", - "de": "Wann wurde diese Bank zuletzt überprüft?", - "ru": "Когда последний раз обследовали эту скамейку?", - "zh_Hant": "上一次探察長椅是什麼時候?", - "pt_BR": "Quando esta bancada foi pesquisada pela última vez?", - "pl": "Kiedy ostatnio badano tę ławkę?" - }, - "render": { - "en": "This bench was last surveyed on {survey:date}", - "nl": "Deze bank is laatst gesurveyd op {survey:date}", - "fr": "Ce banc a été contrôlé pour la dernière fois le {survey:date}", - "it": "Questa panchina è stata controllata l’ultima volta in data {survey:date}", - "zh_Hans": "这个长椅于 {survey:date}最后一次实地调查", - "de": "Diese Bank wurde zuletzt überprüft am {survey:date}", - "ru": "Последний раз обследование этой скамейки проводилось {survey:date}", - "zh_Hant": "這個長椅最後是在 {survey:date} 探查的", - "pt_BR": "Esta bancada foi pesquisada pela última vez em {survey:date}", - "pl": "Ławka ta była ostatnio badana w dniu {survey:date}" - }, - "freeform": { - "key": "survey:date", - "type": "date" - }, - "mappings": [ - { - "if": "survey:date:={_now:date}", - "then": "Surveyed today!" - } - ] - } - ], - "icon": { - "render": "circle:#FE6F32;./assets/layers/bench/bench.svg" - }, - "iconSize": { - "render": "35,35,center" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "amenity=bench" - ], - "title": { - "en": "Bench", - "de": "Sitzbank", - "fr": "Banc", - "nl": "Zitbank", - "es": "Banco", - "it": "Panchina", - "ru": "Скамейка", + "id": "bench", + "name": { + "en": "Benches", + "de": "Sitzbänke", + "fr": "Bancs", + "nl": "Zitbanken", + "es": "Bancos", + "hu": "Padok", "id": "Bangku", + "it": "Panchine", + "ru": "Скамейки", "zh_Hans": "长椅", - "nb_NO": "Benk", "zh_Hant": "長椅", - "pt_BR": "Banco", - "fi": "Penkki", - "pl": "Ławka" - }, - "description": { - "en": "Add a new bench", - "de": "Neue Sitzbank eintragen", - "fr": "Ajouter un nouveau banc", - "nl": "Voeg een nieuwe zitbank toe", - "es": "Añadir un nuevo banco", - "hu": "Pad hozzáadása", - "it": "Aggiungi una nuova panchina", - "ru": "Добавить новую скамейку", - "zh_Hans": "增加一个新的长椅", - "nb_NO": "Legg til en ny benk", - "zh_Hant": "新增長椅", - "pt_BR": "Adicionar um novo banco", - "fi": "Lisää uusi penkki", - "pl": "Dodaj nową ławkę" - }, - "presiceInput": { - "preferredBackground": "photo" - } - } - ] + "nb_NO": "Benker", + "fi": "Penkit", + "pl": "Ławki", + "pt_BR": "Bancos" + }, + "minzoom": 17, + "source": { + "osmTags": "amenity=bench" + }, + "wayHandling": 1, + "title": { + "render": { + "en": "Bench", + "de": "Sitzbank", + "fr": "Banc", + "nl": "Zitbank", + "es": "Banco", + "hu": "Pad", + "id": "Bangku", + "it": "Panchina", + "ru": "Скамейка", + "zh_Hans": "长椅", + "zh_Hant": "長椅", + "nb_NO": "Benk", + "fi": "Penkki", + "pl": "Ławka", + "pt_BR": "Banco" + } + }, + "tagRenderings": [ + "images", + { + "render": { + "en": "Backrest", + "de": "Rückenlehne", + "fr": "Dossier", + "nl": "Rugleuning", + "es": "Respaldo", + "hu": "Háttámla", + "id": "Sandaran", + "it": "Schienale", + "ru": "Спинка", + "zh_Hans": "靠背", + "zh_Hant": "靠背", + "nb_NO": "Rygglene", + "fi": "Selkänoja", + "pl": "Oparcie", + "pt_BR": "Encosto" + }, + "freeform": { + "key": "backrest" + }, + "mappings": [ + { + "if": "backrest=yes", + "then": { + "en": "Backrest: Yes", + "de": "Rückenlehne: Ja", + "fr": "Dossier : Oui", + "nl": "Heeft een rugleuning", + "es": "Respaldo: Si", + "hu": "Háttámla: Igen", + "id": "Sandaran: Ya", + "it": "Schienale: Sì", + "ru": "Со спинкой", + "zh_Hans": "靠背:有", + "zh_Hant": "靠背:有", + "nb_NO": "Rygglene: Ja", + "fi": "Selkänoja: kyllä", + "pl": "Oparcie: Tak", + "pt_BR": "Encosto: Sim" + } + }, + { + "if": "backrest=no", + "then": { + "en": "Backrest: No", + "de": "Rückenlehne: Nein", + "fr": "Dossier : Non", + "nl": "Rugleuning ontbreekt", + "es": "Respaldo: No", + "hu": "Háttámla: Nem", + "id": "Sandaran: Tidak", + "it": "Schienale: No", + "ru": "Без спинки", + "zh_Hans": "靠背:无", + "zh_Hant": "靠背:無", + "nb_NO": "Rygglene: Nei", + "fi": "Selkänoja: ei", + "pl": "Oparcie: Nie", + "pt_BR": "Encosto: Não" + } + } + ], + "question": { + "en": "Does this bench have a backrest?", + "de": "Hat diese Bank eine Rückenlehne?", + "fr": "Ce banc dispose-t-il d'un dossier ?", + "nl": "Heeft deze zitbank een rugleuning?", + "es": "¿Este banco tiene un respaldo?", + "hu": "Van háttámlája ennek a padnak?", + "id": "Apakah bangku ini memiliki sandaran?", + "it": "Questa panchina ha lo schienale?", + "ru": "Есть ли у этой скамейки спинка?", + "zh_Hans": "这个长椅有靠背吗?", + "zh_Hant": "這個長椅是否有靠背?", + "nb_NO": "Har denne beken et rygglene?", + "pl": "Czy ta ławka ma oparcie?", + "pt_BR": "Este assento tem um escosto?" + } + }, + { + "render": { + "en": "{seats} seats", + "de": "{seats} Sitzplätze", + "fr": "{seats} places", + "nl": "{seats} zitplaatsen", + "es": "{seats} asientos", + "hu": "{seats} ülőhely", + "id": "{seats} kursi", + "it": "{seats} posti", + "ru": "{seats} мест", + "zh_Hant": "{seats} 座位數", + "nb_NO": "{seats} seter", + "pl": "{seats} siedzeń", + "pt_BR": "{seats} assentos" + }, + "freeform": { + "key": "seats", + "type": "nat" + }, + "question": { + "en": "How many seats does this bench have?", + "de": "Wie viele Sitzplätze hat diese Bank?", + "fr": "De combien de places dispose ce banc ?", + "nl": "Hoeveel zitplaatsen heeft deze bank?", + "es": "¿Cuántos asientos tiene este banco?", + "hu": "Hány ülőhely van ezen a padon?", + "it": "Quanti posti ha questa panchina?", + "ru": "Сколько мест на этой скамейке?", + "zh_Hans": "这个长椅有几个座位?", + "zh_Hant": "這個長椅有幾個位子?", + "nb_NO": "Hvor mange sitteplasser har denne benken?", + "pl": "Ile siedzeń ma ta ławka?", + "pt_BR": "Quantos assentos este banco tem?" + } + }, + { + "render": { + "en": "Material: {material}", + "de": "Material: {material}", + "fr": "Matériau : {material}", + "nl": "Gemaakt van {material}", + "es": "Material: {material}", + "hu": "Anyag: {material}", + "it": "Materiale: {material}", + "ru": "Материал: {material}", + "zh_Hanå¨s": "材质: {material}", + "zh_Hant": "材質:{material}", + "nb_NO": "Materiale: {material}", + "fi": "Materiaali: {material}", + "zh_Hans": "材质: {material}", + "pl": "Materiał: {material}", + "pt_BR": "Material: {material}" + }, + "freeform": { + "key": "material", + "addExtraTags": [] + }, + "mappings": [ + { + "if": "material=wood", + "then": { + "en": "Material: wood", + "de": "Material: Holz", + "fr": "Matériau : bois", + "nl": "Gemaakt uit hout", + "es": "Material: madera", + "hu": "Anyag: fa", + "it": "Materiale: legno", + "ru": "Материал: дерево", + "zh_Hans": "材质:木", + "nb_NO": "Materiale: tre", + "zh_Hant": "材質:木頭", + "pt_BR": "Material: madeira", + "fi": "Materiaali: puu", + "pl": "Materiał: drewno" + } + }, + { + "if": "material=metal", + "then": { + "en": "Material: metal", + "de": "Material: Metall", + "fr": "Matériau : métal", + "nl": "Gemaakt uit metaal", + "es": "Material: metal", + "hu": "Anyag: fém", + "it": "Materiale: metallo", + "ru": "Материал: металл", + "zh_Hans": "材质:金属", + "nb_NO": "Materiale: metall", + "zh_Hant": "材質:金屬", + "pl": "Materiał: metal", + "pt_BR": "Material: metal" + } + }, + { + "if": "material=stone", + "then": { + "en": "Material: stone", + "de": "Material: Stein", + "fr": "Matériau : pierre", + "nl": "Gemaakt uit steen", + "es": "Material: piedra", + "hu": "Anyag: kő", + "it": "Materiale: pietra", + "ru": "Материал: камень", + "zh_Hans": "材质:石头", + "nb_NO": "Materiale: stein", + "zh_Hant": "材質:石頭", + "pt_BR": "Material: pedra", + "fi": "Materiaali: kivi", + "pl": "Materiał: kamień" + } + }, + { + "if": "material=concrete", + "then": { + "en": "Material: concrete", + "de": "Material: Beton", + "fr": "Matériau : béton", + "nl": "Gemaakt uit beton", + "es": "Material: concreto", + "hu": "Anyag: beton", + "it": "Materiale: cemento", + "ru": "Материал: бетон", + "zh_Hans": "材质:混凝土", + "nb_NO": "Materiale: betong", + "zh_Hant": "材質:水泥", + "pt_BR": "Material: concreto", + "fi": "Materiaali: betoni", + "pl": "Materiał: beton" + } + }, + { + "if": "material=plastic", + "then": { + "en": "Material: plastic", + "de": "Material: Kunststoff", + "fr": "Matériau : plastique", + "nl": "Gemaakt uit plastiek", + "es": "Material: plastico", + "hu": "Anyag: műanyag", + "it": "Materiale: plastica", + "ru": "Материал: пластик", + "zh_Hans": "材质:塑料", + "nb_NO": "Materiale: plastikk", + "zh_Hant": "材質:塑膠", + "pt_BR": "Material: plástico", + "fi": "Materiaali: muovi", + "pl": "Materiał: plastik" + } + }, + { + "if": "material=steel", + "then": { + "en": "Material: steel", + "de": "Material: Stahl", + "fr": "Matériau : acier", + "nl": "Gemaakt uit staal", + "es": "Material: acero", + "hu": "Anyag: acél", + "it": "Materiale: acciaio", + "ru": "Материал: сталь", + "zh_Hans": "材质:不锈钢", + "nb_NO": "Materiale: stål", + "zh_Hant": "材質:鋼鐵", + "pt_BR": "Material: aço", + "fi": "Materiaali: teräs", + "pl": "Materiał: stal" + } + } + ], + "question": { + "en": "What is the bench (seating) made from?", + "de": "Aus welchem Material besteht die Sitzbank (Sitzfläche)?", + "fr": "De quel matériau ce banc est-il fait ?", + "nl": "Uit welk materiaal is het zitgedeelte van deze zitbank gemaakt?", + "hu": "Miből van a pad (ülő része)?", + "it": "Di che materiale è fatta questa panchina?", + "zh_Hans": "这个长椅(或座椅)是用什么材料做的?", + "ru": "Из какого материала сделана скамейка?", + "zh_Hant": "這個長椅 (座位) 是什麼做的?", + "pt_BR": "De que é feito o banco (assento)?", + "pl": "Z czego wykonana jest ławka (siedzisko)?" + } + }, + { + "question": { + "en": "In which direction are you looking when sitting on the bench?", + "de": "In welche Richtung schaut man, wenn man auf der Bank sitzt?", + "nl": "In welke richting kijk je wanneer je op deze zitbank zit?", + "fr": "Dans quelle direction regardez-vous quand vous êtes assis sur le banc ?", + "hu": "Milyen irányba néz a pad?", + "it": "In che direzione si guarda quando si è seduti su questa panchina?", + "ru": "В каком направлении вы смотрите, когда сидите на скамейке?", + "zh_Hans": "坐在长椅上的时候你目视的方向是哪边?", + "zh_Hant": "坐在長椅時是面對那個方向?", + "pt_BR": "Em que direção você olha quando está sentado no banco?", + "pl": "W jakim kierunku patrzysz siedząc na ławce?" + }, + "render": { + "en": "When sitting on the bench, one looks towards {direction}°.", + "de": "Wenn man auf der Bank sitzt, schaut man in Richtung {direction}°.", + "nl": "Wanneer je op deze bank zit, dan kijk je in {direction}°.", + "fr": "Assis sur le banc, on regarde vers {direction}°.", + "hu": "A pad {direction}° felé néz.", + "it": "Quando si è seduti su questa panchina, si guarda verso {direction}°.", + "zh_Hans": "坐在长椅上的时候目视方向为 {direction}°方位。", + "ru": "Сидя на скамейке, вы смотрите в сторону {direction}°.", + "zh_Hant": "當坐在長椅時,那個人朝向 {direction}°。", + "pl": "Siedząc na ławce, patrzy się w kierunku {direction}°.", + "pt_BR": "Ao sentar-se no banco, olha-se para {direction} °." + }, + "freeform": { + "key": "direction", + "type": "direction" + } + }, + { + "render": { + "en": "Colour: {colour}", + "de": "Farbe: {colour}", + "fr": "Couleur : {colour}", + "nl": "Kleur: {colour}", + "hu": "Szín: {colour}", + "it": "Colore: {colour}", + "ru": "Цвет: {colour}", + "id": "Warna: {colour}", + "zh_Hans": "颜色: {colour}", + "zh_Hant": "顏色:{colour}", + "nb_NO": "Farge: {colour}", + "pt_BR": "Cor: {colour}", + "fi": "Väri: {colour}", + "pl": "Kolor: {colour}" + }, + "question": { + "en": "Which colour does this bench have?", + "de": "Welche Farbe hat diese Sitzbank?", + "fr": "Quelle est la couleur de ce banc ?", + "nl": "Welke kleur heeft deze zitbank?", + "hu": "Milyen színű a pad?", + "it": "Di che colore è questa panchina?", + "ru": "Какого цвета скамейка?", + "zh_Hans": "这个长椅是什么颜色的?", + "zh_Hant": "這個長椅是什麼顏色的?", + "pt_BR": "Qual a cor dessa bancada?", + "pl": "Jaki kolor ma ta ławka?" + }, + "freeform": { + "key": "colour", + "type": "color" + }, + "mappings": [ + { + "if": "colour=brown", + "then": { + "en": "Colour: brown", + "de": "Farbe: braun", + "fr": "Couleur : marron", + "nl": "De kleur is bruin", + "hu": "Szín: barna", + "it": "Colore: marrone", + "ru": "Цвет: коричневый", + "zh_Hans": "颜色:棕", + "zh_Hant": "顏色:棕色", + "nb_NO": "Farge: brun", + "pt_BR": "Cor: marrom", + "fi": "Väri: ruskea", + "pl": "Kolor: brązowy" + } + }, + { + "if": "colour=green", + "then": { + "en": "Colour: green", + "de": "Farbe: grün", + "fr": "Couleur : verte", + "nl": "De kleur is groen", + "hu": "Szín: zöld", + "it": "Colore: verde", + "ru": "Цвет: зеленый", + "zh_Hans": "颜色:绿", + "zh_Hant": "顏色:綠色", + "nb_NO": "Farge: grønn", + "pt_BR": "Cor: verde", + "fi": "Väri: vihreä", + "pl": "Kolor: zielony" + } + }, + { + "if": "colour=gray", + "then": { + "en": "Colour: gray", + "de": "Farbe: grau", + "fr": "Couleur : gris", + "nl": "De kleur is grijs", + "hu": "Szín: szürke", + "it": "Colore: grigio", + "ru": "Цвет: серый", + "zh_Hans": "颜色:灰", + "zh_Hant": "顏色:灰色", + "nb_NO": "Farge: grå", + "pt_BR": "Cor: cinza", + "fi": "Väri: harmaa", + "pl": "Kolor: szary" + } + }, + { + "if": "colour=white", + "then": { + "en": "Colour: white", + "de": "Farbe: weiß", + "fr": "Couleur : blanc", + "nl": "De kleur is wit", + "hu": "Szín: fehér", + "it": "Colore: bianco", + "ru": "Цвет: белый", + "zh_Hans": "颜色:白", + "zh_Hant": "顏色:白色", + "nb_NO": "Farge: hvit", + "pt_BR": "Cor: branco", + "fi": "Väri: valkoinen", + "pl": "Kolor: biały" + } + }, + { + "if": "colour=red", + "then": { + "en": "Colour: red", + "de": "Farbe: rot", + "fr": "Couleur : rouge", + "nl": "De kleur is rood", + "hu": "Szín: piros", + "it": "Colore: rosso", + "ru": "Цвет: красный", + "zh_Hans": "颜色:红", + "zh_Hant": "顏色:紅色", + "nb_NO": "Farge: rød", + "pt_BR": "Cor: vermelho", + "fi": "Väri: punainen", + "pl": "Kolor: czerwony" + } + }, + { + "if": "colour=black", + "then": { + "en": "Colour: black", + "de": "Farbe: schwarz", + "fr": "Couleur : noire", + "nl": "De kleur is zwart", + "hu": "Szín: fekete", + "it": "Colore: nero", + "ru": "Цвет: чёрный", + "zh_Hans": "颜色:黑", + "zh_Hant": "顏色:黑色", + "nb_NO": "Farge: svart", + "pt_BR": "Cor: preto", + "fi": "Väri: musta", + "pl": "Kolor: czarny" + } + }, + { + "if": "colour=blue", + "then": { + "en": "Colour: blue", + "de": "Farbe: blau", + "fr": "Couleur : bleu", + "nl": "De kleur is blauw", + "hu": "Szín: kék", + "it": "Colore: blu", + "ru": "Цвет: синий", + "zh_Hans": "颜色:蓝", + "zh_Hant": "顏色:藍色", + "nb_NO": "Farge: blå", + "pt_BR": "Cor: azul", + "fi": "Väri: sininen", + "pl": "Kolor: niebieski" + } + }, + { + "if": "colour=yellow", + "then": { + "en": "Colour: yellow", + "de": "Farbe: gelb", + "fr": "Couleur : jaune", + "nl": "De kleur is geel", + "hu": "Szín: sárga", + "it": "Colore: giallo", + "ru": "Цвет: желтый", + "zh_Hans": "颜色:黄", + "zh_Hant": "顏色:黃色", + "nb_NO": "Farge: gul", + "pt_BR": "Cor: amarelo", + "fi": "Väri: keltainen", + "pl": "Kolor: żółty" + } + } + ] + }, + { + "question": { + "en": "When was this bench last surveyed?", + "nl": "Wanneer is deze laatste bank laatst gesurveyed?", + "fr": "Quand ce banc a-t-il été contrôlé pour la dernière fois ?", + "it": "Quando è stata verificata l’ultima volta questa panchina?", + "zh_Hans": "上次对这个长椅实地调查是什么时候?", + "de": "Wann wurde diese Bank zuletzt überprüft?", + "ru": "Когда последний раз обследовали эту скамейку?", + "zh_Hant": "上一次探察長椅是什麼時候?", + "pt_BR": "Quando esta bancada foi pesquisada pela última vez?", + "pl": "Kiedy ostatnio badano tę ławkę?" + }, + "render": { + "en": "This bench was last surveyed on {survey:date}", + "nl": "Deze bank is laatst gesurveyd op {survey:date}", + "fr": "Ce banc a été contrôlé pour la dernière fois le {survey:date}", + "it": "Questa panchina è stata controllata l’ultima volta in data {survey:date}", + "zh_Hans": "这个长椅于 {survey:date}最后一次实地调查", + "de": "Diese Bank wurde zuletzt überprüft am {survey:date}", + "ru": "Последний раз обследование этой скамейки проводилось {survey:date}", + "zh_Hant": "這個長椅最後是在 {survey:date} 探查的", + "pt_BR": "Esta bancada foi pesquisada pela última vez em {survey:date}", + "pl": "Ławka ta była ostatnio badana w dniu {survey:date}" + }, + "freeform": { + "key": "survey:date", + "type": "date" + }, + "mappings": [ + { + "if": "survey:date:={_now:date}", + "then": "Surveyed today!" + } + ] + } + ], + "icon": { + "render": "circle:#FE6F32;./assets/layers/bench/bench.svg" + }, + "iconSize": { + "render": "35,35,center" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "amenity=bench" + ], + "title": { + "en": "Bench", + "de": "Sitzbank", + "fr": "Banc", + "nl": "Zitbank", + "es": "Banco", + "it": "Panchina", + "ru": "Скамейка", + "id": "Bangku", + "zh_Hans": "长椅", + "nb_NO": "Benk", + "zh_Hant": "長椅", + "pt_BR": "Banco", + "fi": "Penkki", + "pl": "Ławka" + }, + "description": { + "en": "Add a new bench", + "de": "Neue Sitzbank eintragen", + "fr": "Ajouter un nouveau banc", + "nl": "Voeg een nieuwe zitbank toe", + "es": "Añadir un nuevo banco", + "hu": "Pad hozzáadása", + "it": "Aggiungi una nuova panchina", + "ru": "Добавить новую скамейку", + "zh_Hans": "增加一个新的长椅", + "nb_NO": "Legg til en ny benk", + "zh_Hant": "新增長椅", + "pt_BR": "Adicionar um novo banco", + "fi": "Lisää uusi penkki", + "pl": "Dodaj nową ławkę" + }, + "presiceInput": { + "preferredBackground": "photo" + } + } + ] } \ No newline at end of file diff --git a/assets/layers/bench_at_pt/bench_at_pt.json b/assets/layers/bench_at_pt/bench_at_pt.json index ff184b187..e585bae45 100644 --- a/assets/layers/bench_at_pt/bench_at_pt.json +++ b/assets/layers/bench_at_pt/bench_at_pt.json @@ -1,145 +1,145 @@ { - "id": "bench_at_pt", - "name": { - "en": "Benches at public transport stops", - "de": "Sitzbänke bei Haltestellen", - "fr": "Bancs des arrêts de transport en commun", - "nl": "Zitbanken aan bushaltes", - "es": "Bancos en una parada de transporte público", - "hu": "Padok megállókban", - "it": "Panchine alle fermate del trasporto pubblico", - "ru": "Скамейки на остановках общественного транспорта", - "zh_Hans": "在公交站点的长椅", - "nb_NO": "Benker", - "zh_Hant": "大眾運輸站點的長椅", - "pt_BR": "Bancos em pontos de transporte público", - "pl": "Ławki na przystankach komunikacji miejskiej" - }, - "minzoom": 14, - "source": { - "osmTags": { - "or": [ - "bench=yes", - "bench=stand_up_bench" - ] - } - }, - "title": { - "render": { - "en": "Bench", - "de": "Sitzbank", - "fr": "Banc", - "nl": "Zitbank", - "es": "Banco", - "hu": "Pad", - "it": "Panchina", - "ru": "Скамейка", - "id": "Bangku", - "zh_Hans": "长椅", - "nb_NO": "Benk", - "zh_Hant": "長椅", - "pt_BR": "Banco", - "fi": "Penkki", - "pl": "Ławka" + "id": "bench_at_pt", + "name": { + "en": "Benches at public transport stops", + "de": "Sitzbänke bei Haltestellen", + "fr": "Bancs des arrêts de transport en commun", + "nl": "Zitbanken aan bushaltes", + "es": "Bancos en una parada de transporte público", + "hu": "Padok megállókban", + "it": "Panchine alle fermate del trasporto pubblico", + "ru": "Скамейки на остановках общественного транспорта", + "zh_Hans": "在公交站点的长椅", + "nb_NO": "Benker", + "zh_Hant": "大眾運輸站點的長椅", + "pt_BR": "Bancos em pontos de transporte público", + "pl": "Ławki na przystankach komunikacji miejskiej" }, - "mappings": [ - { - "if": { - "or": [ - "public_transport=platform", - "railway=platform", - "highway=bus_stop" - ] - }, - "then": { - "en": "Bench at public transport stop", - "de": "Sitzbank bei Haltestelle", - "fr": "Banc d'un arrêt de transport en commun", - "nl": "Zitbank aan een bushalte", - "hu": "Pad megállóban", - "it": "Panchina alla fermata del trasporto pubblico", - "ru": "Скамейка на остановке общественного транспорта", - "zh_Hans": "在公交站点的长椅", - "zh_Hant": "大眾運輸站點的長椅", - "pt_BR": "Banco em ponto de transporte público", - "pl": "Ławka na przystanku komunikacji miejskiej" + "minzoom": 14, + "source": { + "osmTags": { + "or": [ + "bench=yes", + "bench=stand_up_bench" + ] } - }, - { - "if": { - "and": [ - "amenity=shelter" - ] - }, - "then": { - "en": "Bench in shelter", - "de": "Sitzbank in Unterstand", - "fr": "Banc dans un abri", - "nl": "Zitbank in een schuilhokje", - "hu": "Pad fedett helyen", - "it": "Panchina in un riparo", - "zh_Hans": "在庇护所的长椅", - "ru": "Скамейка в укрытии", - "zh_Hant": "涼亭內的長椅", - "pt_BR": "Banco em abrigo" - } - } - ] - }, - "tagRenderings": [ - "images", - { - "render": { - "en": "{name}", - "de": "{name}", - "fr": "{name}", - "nl": "{name}", - "hu": "{name}", - "it": "{name}", - "ru": "{name}", - "id": "{name}", - "zh_Hans": "{name}", - "zh_Hant": "{name}", - "pt_BR": "{name}", - "fi": "{name}", - "pl": "{name}" - }, - "freeform": { - "key": "name" - } }, - { - "render": { - "en": "Stand up bench", - "de": "Stehbank", - "fr": "Banc assis debout", - "nl": "Leunbank", - "it": "Panca in piedi", - "zh_Hans": "站立长凳", - "ru": "Встаньте на скамейке", - "zh_Hant": "站立長椅" - }, - "freeform": { - "key": "bench", - "addExtraTags": [] - }, - "condition": { - "and": [ - "bench=stand_up_bench" + "title": { + "render": { + "en": "Bench", + "de": "Sitzbank", + "fr": "Banc", + "nl": "Zitbank", + "es": "Banco", + "hu": "Pad", + "it": "Panchina", + "ru": "Скамейка", + "id": "Bangku", + "zh_Hans": "长椅", + "nb_NO": "Benk", + "zh_Hant": "長椅", + "pt_BR": "Banco", + "fi": "Penkki", + "pl": "Ławka" + }, + "mappings": [ + { + "if": { + "or": [ + "public_transport=platform", + "railway=platform", + "highway=bus_stop" + ] + }, + "then": { + "en": "Bench at public transport stop", + "de": "Sitzbank bei Haltestelle", + "fr": "Banc d'un arrêt de transport en commun", + "nl": "Zitbank aan een bushalte", + "hu": "Pad megállóban", + "it": "Panchina alla fermata del trasporto pubblico", + "ru": "Скамейка на остановке общественного транспорта", + "zh_Hans": "在公交站点的长椅", + "zh_Hant": "大眾運輸站點的長椅", + "pt_BR": "Banco em ponto de transporte público", + "pl": "Ławka na przystanku komunikacji miejskiej" + } + }, + { + "if": { + "and": [ + "amenity=shelter" + ] + }, + "then": { + "en": "Bench in shelter", + "de": "Sitzbank in Unterstand", + "fr": "Banc dans un abri", + "nl": "Zitbank in een schuilhokje", + "hu": "Pad fedett helyen", + "it": "Panchina in un riparo", + "zh_Hans": "在庇护所的长椅", + "ru": "Скамейка в укрытии", + "zh_Hant": "涼亭內的長椅", + "pt_BR": "Banco em abrigo" + } + } ] - } + }, + "tagRenderings": [ + "images", + { + "render": { + "en": "{name}", + "de": "{name}", + "fr": "{name}", + "nl": "{name}", + "hu": "{name}", + "it": "{name}", + "ru": "{name}", + "id": "{name}", + "zh_Hans": "{name}", + "zh_Hant": "{name}", + "pt_BR": "{name}", + "fi": "{name}", + "pl": "{name}" + }, + "freeform": { + "key": "name" + } + }, + { + "render": { + "en": "Stand up bench", + "de": "Stehbank", + "fr": "Banc assis debout", + "nl": "Leunbank", + "it": "Panca in piedi", + "zh_Hans": "站立长凳", + "ru": "Встаньте на скамейке", + "zh_Hant": "站立長椅" + }, + "freeform": { + "key": "bench", + "addExtraTags": [] + }, + "condition": { + "and": [ + "bench=stand_up_bench" + ] + } + } + ], + "icon": { + "render": "./assets/themes/benches/bench_public_transport.svg" + }, + "width": { + "render": "8" + }, + "iconSize": { + "render": "35,35,center" + }, + "color": { + "render": "#00f" } - ], - "icon": { - "render": "./assets/themes/benches/bench_public_transport.svg" - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "35,35,center" - }, - "color": { - "render": "#00f" - } } \ No newline at end of file diff --git a/assets/layers/bicycle_library/bicycle_library.json b/assets/layers/bicycle_library/bicycle_library.json index 589cf99ec..f2751c175 100644 --- a/assets/layers/bicycle_library/bicycle_library.json +++ b/assets/layers/bicycle_library/bicycle_library.json @@ -1,268 +1,268 @@ { - "id": "bicycle_library", - "name": { - "en": "Bicycle library", - "nl": "Fietsbibliotheek", - "fr": "Vélothèque", - "it": "Bici in prestito", - "ru": "Велосипедная библиотека", - "zh_Hant": "單車圖書館", - "pt_BR": "Biblioteca de bicicleta" - }, - "minzoom": 8, - "source": { - "osmTags": "amenity=bicycle_library" - }, - "title": { - "render": { - "en": "Bicycle library", - "nl": "Fietsbibliotheek", - "fr": "Vélothèque", - "it": "Bici in prestito", - "ru": "Велосипедная библиотека", - "zh_Hant": "單車圖書館", - "pt_BR": "Biblioteca de bicicleta" - }, - "mappings": [ - { - "if": "name~*", - "then": "{name}" - } - ] - }, - "titleIcons": [ - { - "condition": { - "or": [ - "service:bicycle:pump=yes", - "service:bicycle:pump=separate" - ] - }, - "render": "" - }, - "defaults" - ], - "description": { - "en": "A facility where bicycles can be lent for longer period of times", - "nl": "Een plaats waar men voor langere tijd een fiets kan lenen", - "fr": "Un lieu où des vélos peuvent être empruntés pour un temps plus long", - "hu": "Létesítmény, ahonnan kerékpár kölcsönözhető hosszabb időre", - "it": "Una struttura dove le biciclette possono essere prestate per periodi di tempo più lunghi", - "de": "Eine Einrichtung, in der Fahrräder für längere Zeit geliehen werden können", - "ru": "Учреждение, где велосипед может быть арендован на более длительный срок", - "zh_Hant": "能夠長期租用單車的設施", - "pt_BR": "Uma instalação onde as bicicletas podem ser emprestadas por períodos mais longos", - "pl": "Obiekt, w którym rowery można wypożyczyć na dłuższy okres" - }, - "tagRenderings": [ - "images", - { - "question": { - "en": "What is the name of this bicycle library?", - "nl": "Wat is de naam van deze fietsbieb?", - "fr": "Quel est le nom de cette vélothèque ?", - "it": "Qual è il nome di questo “bici in prestito”?", - "ru": "Как называется эта велосипедная библиотека?", - "nb_NO": "Hva heter dette sykkelbiblioteket?", - "zh_Hant": "這個單車圖書館的名稱是?", - "pt_BR": "Qual o nome desta biblioteca de bicicleta?" - }, - "render": { - "en": "This bicycle library is called {name}", - "nl": "Deze fietsbieb heet {name}", - "fr": "Cette vélothèque s'appelle {name}", - "it": "Il “bici in prestito” è chiamato {name}", - "ru": "Эта велосипедная библиотека называется {name}", - "nb_NO": "Dette sykkelbiblioteket heter {name}", - "zh_Hant": "這個單車圖書館叫做 {name}", - "pt_BR": "Esta biblioteca de bicicleta é chamada de {name}" - }, - "freeform": { - "key": "name" - } - }, - "website", - "phone", - "email", - "opening_hours", - { - "question": { - "en": "How much does lending a bicycle cost?", - "nl": "Hoeveel kost het huren van een fiets?", - "fr": "Combien coûte l'emprunt d'un vélo ?", - "hu": "Mennyibe kerül egy kerékpár kölcsönzése?", - "it": "Quanto costa il prestito di una bicicletta?", - "ru": "Сколько стоит прокат велосипеда?", - "de": "Wie viel kostet das Ausleihen eines Fahrrads?", - "nb_NO": "Hvor mye koster det å leie en sykkel?", - "zh_Hant": "租用單車的費用多少?", - "pt_BR": "Quanto custa um empréstimo de bicicleta?" - }, - "render": { - "en": "Lending a bicycle costs {charge}", - "nl": "Een fiets huren kost {charge}", - "fr": "Emprunter un vélo coûte {charge}", - "hu": "Egy kerékpár kölcsönzése {charge}", - "it": "Il prestito di una bicicletta costa {charge}", - "ru": "Стоимость аренды велосипеда {charge}", - "de": "Das Ausleihen eines Fahrrads kostet {charge}", - "nb_NO": "Sykkelleie koster {charge}", - "zh_Hant": "租借單車需要 {charge}", - "pt_BR": "Custos de empréstimo de bicicleta {charge}" - }, - "freeform": { - "key": "charge", - "addExtraTags": [ - "fee=yes" - ] - }, - "mappings": [ - { - "if": { - "and": [ - "fee=no", - "charge=" - ] - }, - "then": { - "en": "Lending a bicycle is free", - "nl": "Een fiets huren is gratis", - "fr": "L'emprunt de vélo est gratuit", - "hu": "A kerékpárkölcsönzés ingyenes", - "it": "Il prestito di una bicicletta è gratuito", - "de": "Das Ausleihen eines Fahrrads ist kostenlos", - "ru": "Прокат велосипедов бесплатен", - "nb_NO": "Det er gratis å leie en sykkel", - "zh_Hant": "租借單車免費", - "pt_BR": "Emprestar uma bicicleta é grátis" - } - }, - { - "if": { - "and": [ - "fee=yes", - "charge=€20warranty + €20/year" - ] - }, - "then": { - "en": "Lending a bicycle costs €20/year and €20 warranty", - "nl": "Een fiets huren kost €20/jaar en €20 waarborg", - "fr": "Emprunter un vélo coûte 20 €/an et 20 € de garantie", - "it": "Il prestito di una bicicletta costa 20 €/anno più 20 € di garanzia", - "de": "Das Ausleihen eines Fahrrads kostet 20€ pro Jahr und 20€ Gebühr", - "zh_Hant": "租借單車價錢 €20/year 與 €20 保證金", - "ru": "Прокат велосипеда стоит €20/год и €20 залог", - "pt_BR": "Emprestar uma bicicleta custa €20/ano e €20 de garantia" - } - } - ] - }, - { - "question": { - "en": "Who can lend bicycles here?", - "nl": "Voor wie worden hier fietsen aangeboden?", - "fr": "Qui peut emprunter des vélos ici ?", - "hu": "Ki kölcsönözhet itt kerékpárt?", - "it": "Chi può prendere in prestito le biciclette qua?", - "zh_Hans": "谁可以从这里借自行车?", - "de": "Wer kann hier Fahrräder ausleihen?", - "ru": "Кто здесь может арендовать велосипед?", - "zh_Hant": "誰可以在這裡租單車?", - "pt_BR": "Quem pode emprestar bicicletas aqui?" - }, - "multiAnswer": true, - "mappings": [ - { - "if": "bicycle_library:for=child", - "then": { - "nl": "Aanbod voor kinderen", - "en": "Bikes for children available", - "fr": "Vélos pour enfants disponibles", - "hu": "", - "it": "Sono disponibili biciclette per bambini", - "de": "Fahrräder für Kinder verfügbar", - "ru": "Доступны детские велосипеды", - "zh_Hant": "提供兒童單車", - "pt_BR": "Bicicletas para crianças disponíveis" - } - }, - { - "if": "bicycle_library:for=adult", - "then": { - "nl": "Aanbod voor volwassenen", - "en": "Bikes for adult available", - "fr": "Vélos pour adultes disponibles", - "it": "Sono disponibili biciclette per adulti", - "de": "Fahrräder für Erwachsene verfügbar", - "ru": "Доступны велосипеды для взрослых", - "zh_Hant": "有提供成人單車", - "pt_BR": "Bicicletas para adulto disponíveis" - } - }, - { - "if": "bicycle_library:for=disabled", - "then": { - "nl": "Aanbod voor personen met een handicap", - "en": "Bikes for disabled persons available", - "fr": "Vélos pour personnes handicapées disponibles", - "it": "Sono disponibili biciclette per disabili", - "de": "Fahrräder für Behinderte verfügbar", - "ru": "Доступны велосипеды для людей с ограниченными возможностями", - "zh_Hant": "有提供行動不便人士的單車", - "pt_BR": "Bicicletas para deficientes físicos disponíveis" - } - } - ] - }, - "description" - ], - "presets": [ - { - "title": { - "en": "Fietsbibliotheek", - "nl": "Bicycle library", - "ru": "Велосипедная библиотека", - "zh_Hant": "自行車圖書館 ( Fietsbibliotheek)", - "it": "Bici in prestito", + "id": "bicycle_library", + "name": { + "en": "Bicycle library", + "nl": "Fietsbibliotheek", "fr": "Vélothèque", - "pt_BR": "Biblioteca de bicicletas" - }, - "tags": [ - "amenity=bicycle_library" - ], - "description": { - "nl": "Een fietsbieb heeft een collectie fietsen die leden mogen lenen", - "en": "A bicycle library has a collection of bikes which can be lent", - "fr": "Une vélothèque a une flotte de vélos qui peuvent être empruntés", - "it": "Una ciclo-teca o «bici in prestito» ha una collezione di bici che possno essere prestate", - "ru": "В велосипедной библиотеке есть велосипеды для аренды", - "zh_Hant": "單車圖書館有一大批單車供人租借" - } - } - ], - "icon": { - "render": "pin:#22ff55;./assets/layers/bicycle_library/bicycle_library.svg" - }, - "iconOverlays": [ - { - "if": "opening_hours~*", - "then": "isOpen", - "badge": true + "it": "Bici in prestito", + "ru": "Велосипедная библиотека", + "zh_Hant": "單車圖書館", + "pt_BR": "Biblioteca de bicicleta" }, - { - "if": "service:bicycle:pump=yes", - "then": "circle:#e2783d;./assets/layers/bike_repair_station/pump.svg", - "badge": true - } - ], - "width": { - "render": "1" - }, - "iconSize": { - "render": "50,50,bottom" - }, - "color": { - "render": "#c00" - }, - "wayHandling": 2 + "minzoom": 8, + "source": { + "osmTags": "amenity=bicycle_library" + }, + "title": { + "render": { + "en": "Bicycle library", + "nl": "Fietsbibliotheek", + "fr": "Vélothèque", + "it": "Bici in prestito", + "ru": "Велосипедная библиотека", + "zh_Hant": "單車圖書館", + "pt_BR": "Biblioteca de bicicleta" + }, + "mappings": [ + { + "if": "name~*", + "then": "{name}" + } + ] + }, + "titleIcons": [ + { + "condition": { + "or": [ + "service:bicycle:pump=yes", + "service:bicycle:pump=separate" + ] + }, + "render": "" + }, + "defaults" + ], + "description": { + "en": "A facility where bicycles can be lent for longer period of times", + "nl": "Een plaats waar men voor langere tijd een fiets kan lenen", + "fr": "Un lieu où des vélos peuvent être empruntés pour un temps plus long", + "hu": "Létesítmény, ahonnan kerékpár kölcsönözhető hosszabb időre", + "it": "Una struttura dove le biciclette possono essere prestate per periodi di tempo più lunghi", + "de": "Eine Einrichtung, in der Fahrräder für längere Zeit geliehen werden können", + "ru": "Учреждение, где велосипед может быть арендован на более длительный срок", + "zh_Hant": "能夠長期租用單車的設施", + "pt_BR": "Uma instalação onde as bicicletas podem ser emprestadas por períodos mais longos", + "pl": "Obiekt, w którym rowery można wypożyczyć na dłuższy okres" + }, + "tagRenderings": [ + "images", + { + "question": { + "en": "What is the name of this bicycle library?", + "nl": "Wat is de naam van deze fietsbieb?", + "fr": "Quel est le nom de cette vélothèque ?", + "it": "Qual è il nome di questo “bici in prestito”?", + "ru": "Как называется эта велосипедная библиотека?", + "nb_NO": "Hva heter dette sykkelbiblioteket?", + "zh_Hant": "這個單車圖書館的名稱是?", + "pt_BR": "Qual o nome desta biblioteca de bicicleta?" + }, + "render": { + "en": "This bicycle library is called {name}", + "nl": "Deze fietsbieb heet {name}", + "fr": "Cette vélothèque s'appelle {name}", + "it": "Il “bici in prestito” è chiamato {name}", + "ru": "Эта велосипедная библиотека называется {name}", + "nb_NO": "Dette sykkelbiblioteket heter {name}", + "zh_Hant": "這個單車圖書館叫做 {name}", + "pt_BR": "Esta biblioteca de bicicleta é chamada de {name}" + }, + "freeform": { + "key": "name" + } + }, + "website", + "phone", + "email", + "opening_hours", + { + "question": { + "en": "How much does lending a bicycle cost?", + "nl": "Hoeveel kost het huren van een fiets?", + "fr": "Combien coûte l'emprunt d'un vélo ?", + "hu": "Mennyibe kerül egy kerékpár kölcsönzése?", + "it": "Quanto costa il prestito di una bicicletta?", + "ru": "Сколько стоит прокат велосипеда?", + "de": "Wie viel kostet das Ausleihen eines Fahrrads?", + "nb_NO": "Hvor mye koster det å leie en sykkel?", + "zh_Hant": "租用單車的費用多少?", + "pt_BR": "Quanto custa um empréstimo de bicicleta?" + }, + "render": { + "en": "Lending a bicycle costs {charge}", + "nl": "Een fiets huren kost {charge}", + "fr": "Emprunter un vélo coûte {charge}", + "hu": "Egy kerékpár kölcsönzése {charge}", + "it": "Il prestito di una bicicletta costa {charge}", + "ru": "Стоимость аренды велосипеда {charge}", + "de": "Das Ausleihen eines Fahrrads kostet {charge}", + "nb_NO": "Sykkelleie koster {charge}", + "zh_Hant": "租借單車需要 {charge}", + "pt_BR": "Custos de empréstimo de bicicleta {charge}" + }, + "freeform": { + "key": "charge", + "addExtraTags": [ + "fee=yes" + ] + }, + "mappings": [ + { + "if": { + "and": [ + "fee=no", + "charge=" + ] + }, + "then": { + "en": "Lending a bicycle is free", + "nl": "Een fiets huren is gratis", + "fr": "L'emprunt de vélo est gratuit", + "hu": "A kerékpárkölcsönzés ingyenes", + "it": "Il prestito di una bicicletta è gratuito", + "de": "Das Ausleihen eines Fahrrads ist kostenlos", + "ru": "Прокат велосипедов бесплатен", + "nb_NO": "Det er gratis å leie en sykkel", + "zh_Hant": "租借單車免費", + "pt_BR": "Emprestar uma bicicleta é grátis" + } + }, + { + "if": { + "and": [ + "fee=yes", + "charge=€20warranty + €20/year" + ] + }, + "then": { + "en": "Lending a bicycle costs €20/year and €20 warranty", + "nl": "Een fiets huren kost €20/jaar en €20 waarborg", + "fr": "Emprunter un vélo coûte 20 €/an et 20 € de garantie", + "it": "Il prestito di una bicicletta costa 20 €/anno più 20 € di garanzia", + "de": "Das Ausleihen eines Fahrrads kostet 20€ pro Jahr und 20€ Gebühr", + "zh_Hant": "租借單車價錢 €20/year 與 €20 保證金", + "ru": "Прокат велосипеда стоит €20/год и €20 залог", + "pt_BR": "Emprestar uma bicicleta custa €20/ano e €20 de garantia" + } + } + ] + }, + { + "question": { + "en": "Who can lend bicycles here?", + "nl": "Voor wie worden hier fietsen aangeboden?", + "fr": "Qui peut emprunter des vélos ici ?", + "hu": "Ki kölcsönözhet itt kerékpárt?", + "it": "Chi può prendere in prestito le biciclette qua?", + "zh_Hans": "谁可以从这里借自行车?", + "de": "Wer kann hier Fahrräder ausleihen?", + "ru": "Кто здесь может арендовать велосипед?", + "zh_Hant": "誰可以在這裡租單車?", + "pt_BR": "Quem pode emprestar bicicletas aqui?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "bicycle_library:for=child", + "then": { + "nl": "Aanbod voor kinderen", + "en": "Bikes for children available", + "fr": "Vélos pour enfants disponibles", + "hu": "", + "it": "Sono disponibili biciclette per bambini", + "de": "Fahrräder für Kinder verfügbar", + "ru": "Доступны детские велосипеды", + "zh_Hant": "提供兒童單車", + "pt_BR": "Bicicletas para crianças disponíveis" + } + }, + { + "if": "bicycle_library:for=adult", + "then": { + "nl": "Aanbod voor volwassenen", + "en": "Bikes for adult available", + "fr": "Vélos pour adultes disponibles", + "it": "Sono disponibili biciclette per adulti", + "de": "Fahrräder für Erwachsene verfügbar", + "ru": "Доступны велосипеды для взрослых", + "zh_Hant": "有提供成人單車", + "pt_BR": "Bicicletas para adulto disponíveis" + } + }, + { + "if": "bicycle_library:for=disabled", + "then": { + "nl": "Aanbod voor personen met een handicap", + "en": "Bikes for disabled persons available", + "fr": "Vélos pour personnes handicapées disponibles", + "it": "Sono disponibili biciclette per disabili", + "de": "Fahrräder für Behinderte verfügbar", + "ru": "Доступны велосипеды для людей с ограниченными возможностями", + "zh_Hant": "有提供行動不便人士的單車", + "pt_BR": "Bicicletas para deficientes físicos disponíveis" + } + } + ] + }, + "description" + ], + "presets": [ + { + "title": { + "en": "Fietsbibliotheek", + "nl": "Bicycle library", + "ru": "Велосипедная библиотека", + "zh_Hant": "自行車圖書館 ( Fietsbibliotheek)", + "it": "Bici in prestito", + "fr": "Vélothèque", + "pt_BR": "Biblioteca de bicicletas" + }, + "tags": [ + "amenity=bicycle_library" + ], + "description": { + "nl": "Een fietsbieb heeft een collectie fietsen die leden mogen lenen", + "en": "A bicycle library has a collection of bikes which can be lent", + "fr": "Une vélothèque a une flotte de vélos qui peuvent être empruntés", + "it": "Una ciclo-teca o «bici in prestito» ha una collezione di bici che possno essere prestate", + "ru": "В велосипедной библиотеке есть велосипеды для аренды", + "zh_Hant": "單車圖書館有一大批單車供人租借" + } + } + ], + "icon": { + "render": "pin:#22ff55;./assets/layers/bicycle_library/bicycle_library.svg" + }, + "iconOverlays": [ + { + "if": "opening_hours~*", + "then": "isOpen", + "badge": true + }, + { + "if": "service:bicycle:pump=yes", + "then": "circle:#e2783d;./assets/layers/bike_repair_station/pump.svg", + "badge": true + } + ], + "width": { + "render": "1" + }, + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#c00" + }, + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json b/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json index d7aede718..44c088518 100644 --- a/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json +++ b/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json @@ -1,69 +1,6 @@ { - "id": "bicycle_tube_vending_machine", - "name": { - "en": "Bicycle tube vending machine", - "nl": "Fietsbanden-verkoopsautomaat", - "fr": "Distributeur automatique de chambre à air de vélo", - "it": "Distributore automatico di camere d’aria per bici", - "de": "Fahrradschlauch-Automat", - "ru": "Торговый автомат для велосипедистов", - "zh_Hant": "自行車內胎自動售貨機", - "pt_BR": "Máquina de venda automática de tubos de bicicleta" - }, - "title": { - "render": { - "en": "Bicycle tube vending machine", - "nl": "Fietsbanden-verkoopsautomaat", - "fr": "Distributeur automatique de chambre à air de vélo", - "it": "Distributore automatico di camere d’aria per bici", - "de": "Fahrradschlauch-Automat", - "ru": "Торговый автомат для велосипедистов", - "zh_Hant": "自行車內胎自動售貨機", - "pt_BR": "Máquina de venda automática de tubos de bicicleta" - }, - "mappings": [ - { - "if": "name~*", - "then": "Bicycle tube vending machine {name}" - } - ] - }, - "titleIcons": [ - { - "render": "", - "condition": "operator=De Fietsambassade Gent" - }, - "defaults" - ], - "icon": { - "render": "pin:#ffffff;./assets/layers/bicycle_tube_vending_machine/pinIcon.svg" - }, - "iconOverlays": [ - { - "if": { - "or": [ - "operational_status=broken", - "operational_status=closed" - ] - }, - "then": "close:#c33", - "badge": true - } - ], - "iconSize": "50,50,bottom", - "source": { - "osmTags": { - "and": [ - "amenity=vending_machine", - "vending~.*bicycle_tube.*" - ] - } - }, - "minzoom": 13, - "wayHandling": 2, - "presets": [ - { - "title": { + "id": "bicycle_tube_vending_machine", + "name": { "en": "Bicycle tube vending machine", "nl": "Fietsbanden-verkoopsautomaat", "fr": "Distributeur automatique de chambre à air de vélo", @@ -72,183 +9,246 @@ "ru": "Торговый автомат для велосипедистов", "zh_Hant": "自行車內胎自動售貨機", "pt_BR": "Máquina de venda automática de tubos de bicicleta" - }, - "tags": [ - "amenity=vending_machine", - "vending=bicycle_tube", - "vending:bicycle_tube=yes" - ] - } - ], - "color": "#6bc4f7", - "tagRenderings": [ - "images", - { - "#": "Still in use?", - "question": { - "en": "Is this vending machine still operational?", - "nl": "Is deze verkoopsautomaat nog steeds werkende?", - "fr": "Cette machine est-elle encore opérationelle ?", - "it": "Questo distributore automatico funziona ancora?", - "ru": "Этот торговый автомат все еще работает?", - "de": "Ist dieser Automat noch in Betrieb?", - "zh_Hant": "這個自動販賣機仍有運作嗎?", - "pt_BR": "Esta máquina de venda automática ainda está operacional?" - }, - "render": { - "en": "The operational status is {operational_status", - "nl": "Deze verkoopsautomaat is {operational_status}", - "fr": "L'état opérationnel est {operational_status}", - "it": "Lo stato operativo è {operational_status}", - "de": "Der Betriebszustand ist {operational_status", - "ru": "Рабочий статус: {operational_status", - "zh_Hant": "運作狀態是 {operational_status", - "pt_BR": "O estado operacional é: {operational_status" - }, - "freeform": { - "key": "operational_status" - }, - "mappings": [ - { - "if": "operational_status=", - "then": { - "en": "This vending machine works", - "nl": "Deze verkoopsautomaat werkt", - "fr": "Le distributeur automatique fonctionne", - "hu": "Az automata működik", - "it": "Il distributore automatico funziona", - "ru": "Этот торговый автомат работает", - "zh_Hans": "这个借还机正常工作", - "de": "Dieser Automat funktioniert", - "zh_Hant": "這個自動販賣機仍運作", - "pt_BR": "Esta máquina de venda automática funciona" - } - }, - { - "if": "operational_status=broken", - "then": { - "en": "This vending machine is broken", - "nl": "Deze verkoopsautomaat is kapot", - "fr": "Le distributeur automatique est en panne", - "hu": "Az automata elromlott", - "it": "Il distributore automatico è guasto", - "ru": "Этот торговый автомат сломан", - "zh_Hans": "这个借还机已经损坏", - "de": "Dieser Automat ist kaputt", - "zh_Hant": "這個自動販賣機沒有運作了", - "pt_BR": "Esta máquina de venda automática está quebrada" - } - }, - { - "if": "operational_status=closed", - "then": { - "en": "This vending machine is closed", - "nl": "Deze verkoopsautomaat is uitgeschakeld", - "fr": "Le distributeur automatique est fermé", - "hu": "Az automata zárva van", - "it": "Il distributore automatico è spento", - "ru": "Этот торговый автомат закрыт", - "zh_Hans": "这个借还机被关闭了", - "de": "Dieser Automat ist geschlossen", - "zh_Hant": "這個自動販賣機已經關閉了", - "pt_BR": "Esta máquina de venda automática está fechada" - } - } - ] }, - { - "question": "How much does a bicycle tube cost?", - "render": "A bicycle tube costs {charge}", - "freeform": { - "key": "charge" - } + "title": { + "render": { + "en": "Bicycle tube vending machine", + "nl": "Fietsbanden-verkoopsautomaat", + "fr": "Distributeur automatique de chambre à air de vélo", + "it": "Distributore automatico di camere d’aria per bici", + "de": "Fahrradschlauch-Automat", + "ru": "Торговый автомат для велосипедистов", + "zh_Hant": "自行車內胎自動售貨機", + "pt_BR": "Máquina de venda automática de tubos de bicicleta" + }, + "mappings": [ + { + "if": "name~*", + "then": "Bicycle tube vending machine {name}" + } + ] }, - { - "question": "How can one pay at this tube vending machine?", - "mappings": [ + "titleIcons": [ { - "if": "payment:coins=yes", - "ifnot": "payment:coins=no", - "then": "Payment with coins is possible" + "render": "", + "condition": "operator=De Fietsambassade Gent" }, - { - "if": "payment:notes=yes", - "ifnot": "payment:notes=no", - "then": "Payment with notes is possible" - }, - { - "if": "payment:cards=yes", - "ifnot": "payment:cards=no", - "then": "Payment with cards is possible" - } - ], - "multiAnswer": true + "defaults" + ], + "icon": { + "render": "pin:#ffffff;./assets/layers/bicycle_tube_vending_machine/pinIcon.svg" }, - { - "question": "Which brand of tubes are sold here?", - "freeform": { - "key": "brand" - }, - "render": "{brand} tubes are sold here", - "mappings": [ + "iconOverlays": [ { - "if": "brand=Continental", - "then": "Continental tubes are sold here" - }, - { - "if": "brand=Schwalbe", - "then": "Schwalbe tubes are sold here" + "if": { + "or": [ + "operational_status=broken", + "operational_status=closed" + ] + }, + "then": "close:#c33", + "badge": true + } + ], + "iconSize": "50,50,bottom", + "source": { + "osmTags": { + "and": [ + "amenity=vending_machine", + "vending~.*bicycle_tube.*" + ] } - ], - "multiAnswer": true }, - { - "question": "Who maintains this vending machine?", - "render": "This vending machine is maintained by {operator}", - "mappings": [ + "minzoom": 13, + "wayHandling": 2, + "presets": [ { - "if": "operator=Schwalbe", - "then": "Maintained by Schwalbe" - }, - { - "if": "operator=Continental", - "then": "Maintained by Continental" + "title": { + "en": "Bicycle tube vending machine", + "nl": "Fietsbanden-verkoopsautomaat", + "fr": "Distributeur automatique de chambre à air de vélo", + "it": "Distributore automatico di camere d’aria per bici", + "de": "Fahrradschlauch-Automat", + "ru": "Торговый автомат для велосипедистов", + "zh_Hant": "自行車內胎自動售貨機", + "pt_BR": "Máquina de venda automática de tubos de bicicleta" + }, + "tags": [ + "amenity=vending_machine", + "vending=bicycle_tube", + "vending:bicycle_tube=yes" + ] } - ], - "freeform": { - "key": "operator" - } - }, - { - "question": "Are other bicycle bicycle accessories sold here?", - "mappings": [ + ], + "color": "#6bc4f7", + "tagRenderings": [ + "images", { - "if": "vending:bicycle_light=yes", - "ifnot": "vending:bicycle_light=no", - "then": "Bicycle lights are sold here" + "#": "Still in use?", + "question": { + "en": "Is this vending machine still operational?", + "nl": "Is deze verkoopsautomaat nog steeds werkende?", + "fr": "Cette machine est-elle encore opérationelle ?", + "it": "Questo distributore automatico funziona ancora?", + "ru": "Этот торговый автомат все еще работает?", + "de": "Ist dieser Automat noch in Betrieb?", + "zh_Hant": "這個自動販賣機仍有運作嗎?", + "pt_BR": "Esta máquina de venda automática ainda está operacional?" + }, + "render": { + "en": "The operational status is {operational_status", + "nl": "Deze verkoopsautomaat is {operational_status}", + "fr": "L'état opérationnel est {operational_status}", + "it": "Lo stato operativo è {operational_status}", + "de": "Der Betriebszustand ist {operational_status", + "ru": "Рабочий статус: {operational_status", + "zh_Hant": "運作狀態是 {operational_status", + "pt_BR": "O estado operacional é: {operational_status" + }, + "freeform": { + "key": "operational_status" + }, + "mappings": [ + { + "if": "operational_status=", + "then": { + "en": "This vending machine works", + "nl": "Deze verkoopsautomaat werkt", + "fr": "Le distributeur automatique fonctionne", + "hu": "Az automata működik", + "it": "Il distributore automatico funziona", + "ru": "Этот торговый автомат работает", + "zh_Hans": "这个借还机正常工作", + "de": "Dieser Automat funktioniert", + "zh_Hant": "這個自動販賣機仍運作", + "pt_BR": "Esta máquina de venda automática funciona" + } + }, + { + "if": "operational_status=broken", + "then": { + "en": "This vending machine is broken", + "nl": "Deze verkoopsautomaat is kapot", + "fr": "Le distributeur automatique est en panne", + "hu": "Az automata elromlott", + "it": "Il distributore automatico è guasto", + "ru": "Этот торговый автомат сломан", + "zh_Hans": "这个借还机已经损坏", + "de": "Dieser Automat ist kaputt", + "zh_Hant": "這個自動販賣機沒有運作了", + "pt_BR": "Esta máquina de venda automática está quebrada" + } + }, + { + "if": "operational_status=closed", + "then": { + "en": "This vending machine is closed", + "nl": "Deze verkoopsautomaat is uitgeschakeld", + "fr": "Le distributeur automatique est fermé", + "hu": "Az automata zárva van", + "it": "Il distributore automatico è spento", + "ru": "Этот торговый автомат закрыт", + "zh_Hans": "这个借还机被关闭了", + "de": "Dieser Automat ist geschlossen", + "zh_Hant": "這個自動販賣機已經關閉了", + "pt_BR": "Esta máquina de venda automática está fechada" + } + } + ] }, { - "if": "vending:gloves=yes", - "ifnot": "vending:gloves=no", - "then": "Gloves are sold here" + "question": "How much does a bicycle tube cost?", + "render": "A bicycle tube costs {charge}", + "freeform": { + "key": "charge" + } }, { - "if": "vending:bicycle_repair_kit=yes", - "ifnot": "vending:bicycle_repair_kit=no", - "then": "Bicycle repair kits are sold here" + "question": "How can one pay at this tube vending machine?", + "mappings": [ + { + "if": "payment:coins=yes", + "ifnot": "payment:coins=no", + "then": "Payment with coins is possible" + }, + { + "if": "payment:notes=yes", + "ifnot": "payment:notes=no", + "then": "Payment with notes is possible" + }, + { + "if": "payment:cards=yes", + "ifnot": "payment:cards=no", + "then": "Payment with cards is possible" + } + ], + "multiAnswer": true }, { - "if": "vending:bicycle_pump=yes", - "ifnot": "vending:bicycle_pump=no", - "then": "Bicycle pumps are sold here" + "question": "Which brand of tubes are sold here?", + "freeform": { + "key": "brand" + }, + "render": "{brand} tubes are sold here", + "mappings": [ + { + "if": "brand=Continental", + "then": "Continental tubes are sold here" + }, + { + "if": "brand=Schwalbe", + "then": "Schwalbe tubes are sold here" + } + ], + "multiAnswer": true }, { - "if": "vending:bicycle_lock=yes", - "ifnot": "vending:bicycle_lock=no", - "then": "Bicycle locks are sold here" + "question": "Who maintains this vending machine?", + "render": "This vending machine is maintained by {operator}", + "mappings": [ + { + "if": "operator=Schwalbe", + "then": "Maintained by Schwalbe" + }, + { + "if": "operator=Continental", + "then": "Maintained by Continental" + } + ], + "freeform": { + "key": "operator" + } + }, + { + "question": "Are other bicycle bicycle accessories sold here?", + "mappings": [ + { + "if": "vending:bicycle_light=yes", + "ifnot": "vending:bicycle_light=no", + "then": "Bicycle lights are sold here" + }, + { + "if": "vending:gloves=yes", + "ifnot": "vending:gloves=no", + "then": "Gloves are sold here" + }, + { + "if": "vending:bicycle_repair_kit=yes", + "ifnot": "vending:bicycle_repair_kit=no", + "then": "Bicycle repair kits are sold here" + }, + { + "if": "vending:bicycle_pump=yes", + "ifnot": "vending:bicycle_pump=no", + "then": "Bicycle pumps are sold here" + }, + { + "if": "vending:bicycle_lock=yes", + "ifnot": "vending:bicycle_lock=no", + "then": "Bicycle locks are sold here" + } + ], + "multiAnswer": true } - ], - "multiAnswer": true - } - ] + ] } \ No newline at end of file diff --git a/assets/layers/bike_cafe/bike_cafe.json b/assets/layers/bike_cafe/bike_cafe.json index 111a4bc28..93b07cd19 100644 --- a/assets/layers/bike_cafe/bike_cafe.json +++ b/assets/layers/bike_cafe/bike_cafe.json @@ -1,344 +1,344 @@ { - "id": "bike_cafe", - "name": { - "en": "Bike cafe", - "nl": "Fietscafé", - "fr": "Café vélo", - "gl": "Café de ciclistas", - "de": "Fahrrad-Café", - "it": "Caffè in bici", - "zh_Hans": "自行车咖啡", - "ru": "Велосипедное кафе", - "zh_Hant": "單車咖啡廳", - "pt_BR": "Café de bicicletas" - }, - "minzoom": 13, - "source": { - "osmTags": { - "and": [ - { - "or": [ - "amenity=pub", - "amenity=bar", - "amenity=cafe", - "amenity=restaurant" - ] - }, - { - "#": "Note the double tilde in 'service:bicycle' which interprets the key as regex too", - "or": [ - "pub=cycling", - "pub=bicycle", - "theme=cycling", - "theme=bicycle", - "service:bicycle:.*~~*" - ] - } - ] - } - }, - "title": { - "render": { - "en": "Bike cafe", - "nl": "Fietscafé", - "fr": "Café Vélo", - "gl": "Café de ciclistas", - "de": "Fahrrad-Café", - "it": "Caffè in bici", - "zh_Hans": "自行车咖啡", - "ru": "Велосипедное кафе", - "zh_Hant": "單車咖啡廳", - "pt_BR": "Café de bicicleta" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "en": "Bike cafe {name}", - "nl": "Fietscafé {name}", - "fr": "Café Vélo {name}", - "gl": "Café de ciclistas {name}", - "de": "Fahrrad-Café {name}", - "it": "Caffè in bici {name}", - "zh_Hans": "自行车咖啡 {name}", - "ru": "Велосипедное кафе {name}", - "zh_Hant": "單車咖啡廳{name}", - "pt_BR": "Café de bicicleta {name}" - } - } - ] - }, - "tagRenderings": [ - "images", - { - "question": { - "en": "What is the name of this bike cafe?", - "nl": "Wat is de naam van dit fietscafé?", - "fr": "Quel est le nom de ce Café vélo ?", - "gl": "Cal é o nome deste café de ciclistas?", - "de": "Wie heißt dieses Fahrrad-Café?", - "it": "Qual è il nome di questo caffè in bici?", - "zh_Hans": "这个自行车咖啡的名字是什么?", - "ru": "Как называется это байк-кафе?", - "zh_Hant": "這個單車咖啡廳的名稱是?", - "pt_BR": "Qual o nome deste café de bicicleta?" - }, - "render": { - "en": "This bike cafe is called {name}", - "nl": "Dit fietscafé heet {name}", - "fr": "Ce Café vélo s'appelle {name}", - "gl": "Este café de ciclistas chámase {name}", - "de": "Dieses Fahrrad-Café heißt {name}", - "it": "Questo caffè in bici è chiamato {name}", - "zh_Hans": "这家自行车咖啡叫做 {name}", - "ru": "Это велосипедное кафе называется {name}", - "zh_Hant": "這個單車咖啡廳叫做 {name}", - "pt_BR": "Este café de bicicleta se chama {name}" - }, - "freeform": { - "key": "name" - } - }, - { - "question": { - "en": "Does this bike cafe offer a bike pump for use by anyone?", - "nl": "Biedt dit fietscafé een fietspomp aan voor iedereen?", - "fr": "Est-ce que ce Café vélo propose une pompe en libre accès ?", - "gl": "Este café de ciclistas ofrece unha bomba de ar para que calquera persoa poida usala?", - "de": "Bietet dieses Fahrrad-Café eine Fahrradpumpe an, die von jedem benutzt werden kann?", - "it": "Questo caffè in bici offre una pompa per bici che chiunque può utilizzare?", - "zh_Hans": "这家自行车咖啡为每个使用者提供打气筒吗?", - "ru": "Есть ли в этом велосипедном кафе велосипедный насос для всеобщего использования?", - "zh_Hant": "這個單車咖啡廳有提供給任何人都能使用的單車打氣甬嗎?" - }, - "mappings": [ - { - "if": "service:bicycle:pump=yes", - "then": { - "en": "This bike cafe offers a bike pump for anyone", - "nl": "Dit fietscafé biedt een fietspomp aan voor eender wie", - "fr": "Ce Café vélo offre une pompe en libre accès", - "gl": "Este café de ciclistas ofrece unha bomba de ar", - "de": "Dieses Fahrrad-Café bietet eine Fahrradpumpe an, die von jedem benutzt werden kann", - "it": "Questo caffè in bici offre una pompa per bici liberamente utilizzabile", - "zh_Hans": "这家自行车咖啡为每个人提供打气筒", - "zh_Hant": "這個單車咖啡廳有提供給任何人都能使用的單車打氣甬", - "ru": "В этом велосипедном кафе есть велосипедный насос для всеобщего использования" - } - }, - { - "if": "service:bicycle:pump=no", - "then": { - "en": "This bike cafe doesn't offer a bike pump for anyone", - "nl": "Dit fietscafé biedt geen fietspomp aan voor iedereen", - "fr": "Ce Café vélo n'offre pas de pompe en libre accès", - "gl": "Este café de ciclistas non ofrece unha bomba de ar", - "de": "Dieses Fahrrad-Café bietet keine Fahrradpumpe an, die von jedem benutzt werden kann", - "it": "Questo caffè in bici non offre una pompa per bici liberamente utilizzabile", - "zh_Hans": "这家自行车咖啡不为每个人提供打气筒", - "zh_Hant": "這個單車咖啡廳並沒有為所有人提供單車打氣甬", - "ru": "В этом велосипедном кафе нет велосипедного насоса для всеобщего использования" - } - } - ] - }, - { - "question": { - "en": "Are there tools here to repair your own bike?", - "nl": "Biedt dit fietscafé gereedschap aan om je fiets zelf te herstellen?", - "fr": "Est-ce qu'il y a des outils pour réparer soi-même son vélo ?", - "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta?", - "de": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?", - "it": "Ci sono degli strumenti per riparare la propria bicicletta?", - "zh_Hans": "这里有供你修车用的工具吗?", - "zh_Hant": "這裡是否有工具修理你的單車嗎?", - "ru": "Есть ли здесь инструменты для починки вашего велосипеда?", - "pt_BR": "Há ferramentas aqui para consertar sua bicicleta?" - }, - "mappings": [ - { - "if": "service:bicycle:diy=yes", - "then": { - "en": "This bike cafe offers tools for DIY repair", - "nl": "Dit fietscafé biedt gereedschap aan om je fiets zelf te herstellen", - "fr": "Ce Café vélo propose des outils pour réparer son vélo soi-même", - "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta", - "de": "Dieses Fahrrad-Café bietet Werkzeuge für die selbständige Reparatur an", - "it": "Questo caffè in bici fornisce degli attrezzi per la riparazione fai-da-te", - "zh_Hans": "这家自行车咖啡为DIY修理者提供工具", - "zh_Hant": "這個單車咖啡廳提供工具讓你修理", - "ru": "В этом велосипедном кафе есть инструменты для починки своего велосипеда", - "pt_BR": "Este café de bicicleta oferece ferramentas de reparo faça você mesmo" - } - }, - { - "if": "service:bicycle:diy=no", - "then": { - "en": "This bike cafe doesn't offer tools for DIY repair", - "nl": "Dit fietscafé biedt geen gereedschap aan om je fiets zelf te herstellen", - "fr": "Ce Café vélo ne propose pas d'outils pour réparer son vélo soi-même", - "gl": "Non hai ferramentas aquí para arranxar a túa propia bicicleta", - "de": "Dieses Fahrrad-Café bietet keine Werkzeuge für die selbständige Reparatur an", - "it": "Questo caffè in bici non fornisce degli attrezzi per la riparazione fai-da-te", - "zh_Hans": "这家自行车咖啡不为DIY修理者提供工具", - "zh_Hant": "這個單車咖啡廳並沒有提供工具讓你修理", - "ru": "В этом велосипедном кафе нет инструментов для починки своего велосипеда", - "pt_BR": "Este café de bicicleta não oferece ferramentas de reparo faça você mesmo" - } - } - ] - }, - { - "question": { - "en": "Does this bike cafe repair bikes?", - "nl": "Herstelt dit fietscafé fietsen?", - "fr": "Est-ce que ce Café vélo répare les vélos ?", - "gl": "Este café de ciclistas arranxa bicicletas?", - "de": "Repariert dieses Fahrrad-Café Fahrräder?", - "it": "Questo caffè in bici ripara le bici?", - "zh_Hans": "这家自行车咖啡t提供修车服务吗?", - "zh_Hant": "這個單車咖啡廳是否能修理單車?", - "ru": "Есть ли услуги ремонта велосипедов в этом велосипедном кафе?", - "pt_BR": "Este café de bicicleta conserta bicicletas?" - }, - "mappings": [ - { - "if": "service:bicycle:repair=yes", - "then": { - "en": "This bike cafe repairs bikes", - "nl": "Dit fietscafé herstelt fietsen", - "fr": "Ce Café vélo répare les vélos", - "gl": "Este café de ciclistas arranxa bicicletas", - "de": "Dieses Fahrrad-Café repariert Fahrräder", - "it": "Questo caffè in bici ripara le bici", - "zh_Hans": "这家自行车咖啡可以修车", - "zh_Hant": "這個單車咖啡廳修理單車", - "ru": "В этом велосипедном кафе есть услуги ремонта велосипедов", - "pt_BR": "Este café de bicicleta conserta bicicletas" - } - }, - { - "if": "service:bicycle:repair=no", - "then": { - "en": "This bike cafe doesn't repair bikes", - "nl": "Dit fietscafé herstelt geen fietsen", - "fr": "Ce Café vélo ne répare pas les vélos", - "gl": "Este café de ciclistas non arranxa bicicletas", - "de": "Dieses Fahrrad-Café repariert keine Fahrräder", - "it": "Questo caffè in bici non ripara le bici", - "zh_Hans": "这家自行车咖啡不能修车", - "zh_Hant": "這個單車咖啡廳並不修理單車", - "ru": "В этом велосипедном кафе нет услуг ремонта велосипедов", - "pt_BR": "Este café de bicicleta não conserta bicicletas" - } - } - ] - }, - { - "question": { - "en": "What is the website of {name}?", - "nl": "Wat is de website van {name}?", - "fr": "Quel est le site web de {name} ?", - "gl": "Cal é a páxina web de {name}?", - "de": "Was ist die Webseite von {name}?", - "it": "Qual è il sito web di {name}?", - "ru": "Какой сайт у {name}?", - "zh_Hans": "{name}的网站是什么?", - "zh_Hant": "{name} 的網站是?", - "pt_BR": "Qual o website de {name}?" - }, - "render": "{website}", - "freeform": { - "key": "website" - } - }, - { - "question": { - "en": "What is the phone number of {name}?", - "nl": "Wat is het telefoonnummer van {name}?", - "fr": "Quel est le numéro de téléphone de {name} ?", - "gl": "Cal é o número de teléfono de {name}?", - "de": "Wie lautet die Telefonnummer von {name}?", - "it": "Qual è il numero di telefono di {name}?", - "ru": "Какой номер телефона у {name}?", - "zh_Hans": "{name}的电话号码是什么?", - "zh_Hant": "{name} 的電話號碼是?", - "pt_BR": "Qual o número de telefone de {name}?" - }, - "render": "{phone}", - "freeform": { - "key": "phone", - "type": "phone" - } - }, - { - "question": { - "en": "What is the email address of {name}?", - "nl": "Wat is het email-adres van {name}?", - "fr": "Quelle est l'adresse électronique de {name} ?", - "gl": "Cal é o enderezo de correo electrónico de {name}?", - "de": "Wie lautet die E-Mail-Adresse von {name}?", - "it": "Qual è l’indirizzo email di {name}?", - "ru": "Какой адрес электронной почты у {name}?", - "zh_Hans": "{name}的电子邮箱是什么?", - "zh_Hant": "{name} 的電子郵件地址是?", - "pt_BR": "Qual o endereço de email de {name}?" - }, - "render": "{email}", - "freeform": { - "key": "email", - "type": "email" - } - }, - { - "question": { - "en": "When it this bike café opened?", - "nl": "Wanneer is dit fietscafé geopend?", - "fr": "Quand ce Café vélo est-t-il ouvert ?", - "it": "Quando è aperto questo caffè in bici?", - "zh_Hans": "这家自行车咖啡什么时候开门营业?", - "zh_Hant": "何時這個單車咖啡廳營運?", - "ru": "Каков режим работы этого велосипедного кафе?", - "pt_BR": "Quando este café de bicicleta abre?" - }, - "render": "{opening_hours_table(opening_hours)}", - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - } - } - ], - "icon": { - "render": "./assets/layers/bike_cafe/bike_cafe.svg" - }, - "width": { - "render": "2" - }, - "iconSize": { - "render": "50,50,bottom" - }, - "color": { - "render": "#694E2D" - }, - "presets": [ - { - "title": { + "id": "bike_cafe", + "name": { "en": "Bike cafe", "nl": "Fietscafé", - "fr": "Café Vélo", + "fr": "Café vélo", "gl": "Café de ciclistas", "de": "Fahrrad-Café", "it": "Caffè in bici", "zh_Hans": "自行车咖啡", - "zh_Hant": "單車咖啡廳", "ru": "Велосипедное кафе", - "pt_BR": "Café de bicicleta" - }, - "tags": [ - "amenity=pub", - "pub=cycling" - ] - } - ], - "wayHandling": 2 + "zh_Hant": "單車咖啡廳", + "pt_BR": "Café de bicicletas" + }, + "minzoom": 13, + "source": { + "osmTags": { + "and": [ + { + "or": [ + "amenity=pub", + "amenity=bar", + "amenity=cafe", + "amenity=restaurant" + ] + }, + { + "#": "Note the double tilde in 'service:bicycle' which interprets the key as regex too", + "or": [ + "pub=cycling", + "pub=bicycle", + "theme=cycling", + "theme=bicycle", + "service:bicycle:.*~~*" + ] + } + ] + } + }, + "title": { + "render": { + "en": "Bike cafe", + "nl": "Fietscafé", + "fr": "Café Vélo", + "gl": "Café de ciclistas", + "de": "Fahrrad-Café", + "it": "Caffè in bici", + "zh_Hans": "自行车咖啡", + "ru": "Велосипедное кафе", + "zh_Hant": "單車咖啡廳", + "pt_BR": "Café de bicicleta" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "en": "Bike cafe {name}", + "nl": "Fietscafé {name}", + "fr": "Café Vélo {name}", + "gl": "Café de ciclistas {name}", + "de": "Fahrrad-Café {name}", + "it": "Caffè in bici {name}", + "zh_Hans": "自行车咖啡 {name}", + "ru": "Велосипедное кафе {name}", + "zh_Hant": "單車咖啡廳{name}", + "pt_BR": "Café de bicicleta {name}" + } + } + ] + }, + "tagRenderings": [ + "images", + { + "question": { + "en": "What is the name of this bike cafe?", + "nl": "Wat is de naam van dit fietscafé?", + "fr": "Quel est le nom de ce Café vélo ?", + "gl": "Cal é o nome deste café de ciclistas?", + "de": "Wie heißt dieses Fahrrad-Café?", + "it": "Qual è il nome di questo caffè in bici?", + "zh_Hans": "这个自行车咖啡的名字是什么?", + "ru": "Как называется это байк-кафе?", + "zh_Hant": "這個單車咖啡廳的名稱是?", + "pt_BR": "Qual o nome deste café de bicicleta?" + }, + "render": { + "en": "This bike cafe is called {name}", + "nl": "Dit fietscafé heet {name}", + "fr": "Ce Café vélo s'appelle {name}", + "gl": "Este café de ciclistas chámase {name}", + "de": "Dieses Fahrrad-Café heißt {name}", + "it": "Questo caffè in bici è chiamato {name}", + "zh_Hans": "这家自行车咖啡叫做 {name}", + "ru": "Это велосипедное кафе называется {name}", + "zh_Hant": "這個單車咖啡廳叫做 {name}", + "pt_BR": "Este café de bicicleta se chama {name}" + }, + "freeform": { + "key": "name" + } + }, + { + "question": { + "en": "Does this bike cafe offer a bike pump for use by anyone?", + "nl": "Biedt dit fietscafé een fietspomp aan voor iedereen?", + "fr": "Est-ce que ce Café vélo propose une pompe en libre accès ?", + "gl": "Este café de ciclistas ofrece unha bomba de ar para que calquera persoa poida usala?", + "de": "Bietet dieses Fahrrad-Café eine Fahrradpumpe an, die von jedem benutzt werden kann?", + "it": "Questo caffè in bici offre una pompa per bici che chiunque può utilizzare?", + "zh_Hans": "这家自行车咖啡为每个使用者提供打气筒吗?", + "ru": "Есть ли в этом велосипедном кафе велосипедный насос для всеобщего использования?", + "zh_Hant": "這個單車咖啡廳有提供給任何人都能使用的單車打氣甬嗎?" + }, + "mappings": [ + { + "if": "service:bicycle:pump=yes", + "then": { + "en": "This bike cafe offers a bike pump for anyone", + "nl": "Dit fietscafé biedt een fietspomp aan voor eender wie", + "fr": "Ce Café vélo offre une pompe en libre accès", + "gl": "Este café de ciclistas ofrece unha bomba de ar", + "de": "Dieses Fahrrad-Café bietet eine Fahrradpumpe an, die von jedem benutzt werden kann", + "it": "Questo caffè in bici offre una pompa per bici liberamente utilizzabile", + "zh_Hans": "这家自行车咖啡为每个人提供打气筒", + "zh_Hant": "這個單車咖啡廳有提供給任何人都能使用的單車打氣甬", + "ru": "В этом велосипедном кафе есть велосипедный насос для всеобщего использования" + } + }, + { + "if": "service:bicycle:pump=no", + "then": { + "en": "This bike cafe doesn't offer a bike pump for anyone", + "nl": "Dit fietscafé biedt geen fietspomp aan voor iedereen", + "fr": "Ce Café vélo n'offre pas de pompe en libre accès", + "gl": "Este café de ciclistas non ofrece unha bomba de ar", + "de": "Dieses Fahrrad-Café bietet keine Fahrradpumpe an, die von jedem benutzt werden kann", + "it": "Questo caffè in bici non offre una pompa per bici liberamente utilizzabile", + "zh_Hans": "这家自行车咖啡不为每个人提供打气筒", + "zh_Hant": "這個單車咖啡廳並沒有為所有人提供單車打氣甬", + "ru": "В этом велосипедном кафе нет велосипедного насоса для всеобщего использования" + } + } + ] + }, + { + "question": { + "en": "Are there tools here to repair your own bike?", + "nl": "Biedt dit fietscafé gereedschap aan om je fiets zelf te herstellen?", + "fr": "Est-ce qu'il y a des outils pour réparer soi-même son vélo ?", + "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta?", + "de": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?", + "it": "Ci sono degli strumenti per riparare la propria bicicletta?", + "zh_Hans": "这里有供你修车用的工具吗?", + "zh_Hant": "這裡是否有工具修理你的單車嗎?", + "ru": "Есть ли здесь инструменты для починки вашего велосипеда?", + "pt_BR": "Há ferramentas aqui para consertar sua bicicleta?" + }, + "mappings": [ + { + "if": "service:bicycle:diy=yes", + "then": { + "en": "This bike cafe offers tools for DIY repair", + "nl": "Dit fietscafé biedt gereedschap aan om je fiets zelf te herstellen", + "fr": "Ce Café vélo propose des outils pour réparer son vélo soi-même", + "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta", + "de": "Dieses Fahrrad-Café bietet Werkzeuge für die selbständige Reparatur an", + "it": "Questo caffè in bici fornisce degli attrezzi per la riparazione fai-da-te", + "zh_Hans": "这家自行车咖啡为DIY修理者提供工具", + "zh_Hant": "這個單車咖啡廳提供工具讓你修理", + "ru": "В этом велосипедном кафе есть инструменты для починки своего велосипеда", + "pt_BR": "Este café de bicicleta oferece ferramentas de reparo faça você mesmo" + } + }, + { + "if": "service:bicycle:diy=no", + "then": { + "en": "This bike cafe doesn't offer tools for DIY repair", + "nl": "Dit fietscafé biedt geen gereedschap aan om je fiets zelf te herstellen", + "fr": "Ce Café vélo ne propose pas d'outils pour réparer son vélo soi-même", + "gl": "Non hai ferramentas aquí para arranxar a túa propia bicicleta", + "de": "Dieses Fahrrad-Café bietet keine Werkzeuge für die selbständige Reparatur an", + "it": "Questo caffè in bici non fornisce degli attrezzi per la riparazione fai-da-te", + "zh_Hans": "这家自行车咖啡不为DIY修理者提供工具", + "zh_Hant": "這個單車咖啡廳並沒有提供工具讓你修理", + "ru": "В этом велосипедном кафе нет инструментов для починки своего велосипеда", + "pt_BR": "Este café de bicicleta não oferece ferramentas de reparo faça você mesmo" + } + } + ] + }, + { + "question": { + "en": "Does this bike cafe repair bikes?", + "nl": "Herstelt dit fietscafé fietsen?", + "fr": "Est-ce que ce Café vélo répare les vélos ?", + "gl": "Este café de ciclistas arranxa bicicletas?", + "de": "Repariert dieses Fahrrad-Café Fahrräder?", + "it": "Questo caffè in bici ripara le bici?", + "zh_Hans": "这家自行车咖啡t提供修车服务吗?", + "zh_Hant": "這個單車咖啡廳是否能修理單車?", + "ru": "Есть ли услуги ремонта велосипедов в этом велосипедном кафе?", + "pt_BR": "Este café de bicicleta conserta bicicletas?" + }, + "mappings": [ + { + "if": "service:bicycle:repair=yes", + "then": { + "en": "This bike cafe repairs bikes", + "nl": "Dit fietscafé herstelt fietsen", + "fr": "Ce Café vélo répare les vélos", + "gl": "Este café de ciclistas arranxa bicicletas", + "de": "Dieses Fahrrad-Café repariert Fahrräder", + "it": "Questo caffè in bici ripara le bici", + "zh_Hans": "这家自行车咖啡可以修车", + "zh_Hant": "這個單車咖啡廳修理單車", + "ru": "В этом велосипедном кафе есть услуги ремонта велосипедов", + "pt_BR": "Este café de bicicleta conserta bicicletas" + } + }, + { + "if": "service:bicycle:repair=no", + "then": { + "en": "This bike cafe doesn't repair bikes", + "nl": "Dit fietscafé herstelt geen fietsen", + "fr": "Ce Café vélo ne répare pas les vélos", + "gl": "Este café de ciclistas non arranxa bicicletas", + "de": "Dieses Fahrrad-Café repariert keine Fahrräder", + "it": "Questo caffè in bici non ripara le bici", + "zh_Hans": "这家自行车咖啡不能修车", + "zh_Hant": "這個單車咖啡廳並不修理單車", + "ru": "В этом велосипедном кафе нет услуг ремонта велосипедов", + "pt_BR": "Este café de bicicleta não conserta bicicletas" + } + } + ] + }, + { + "question": { + "en": "What is the website of {name}?", + "nl": "Wat is de website van {name}?", + "fr": "Quel est le site web de {name} ?", + "gl": "Cal é a páxina web de {name}?", + "de": "Was ist die Webseite von {name}?", + "it": "Qual è il sito web di {name}?", + "ru": "Какой сайт у {name}?", + "zh_Hans": "{name}的网站是什么?", + "zh_Hant": "{name} 的網站是?", + "pt_BR": "Qual o website de {name}?" + }, + "render": "{website}", + "freeform": { + "key": "website" + } + }, + { + "question": { + "en": "What is the phone number of {name}?", + "nl": "Wat is het telefoonnummer van {name}?", + "fr": "Quel est le numéro de téléphone de {name} ?", + "gl": "Cal é o número de teléfono de {name}?", + "de": "Wie lautet die Telefonnummer von {name}?", + "it": "Qual è il numero di telefono di {name}?", + "ru": "Какой номер телефона у {name}?", + "zh_Hans": "{name}的电话号码是什么?", + "zh_Hant": "{name} 的電話號碼是?", + "pt_BR": "Qual o número de telefone de {name}?" + }, + "render": "{phone}", + "freeform": { + "key": "phone", + "type": "phone" + } + }, + { + "question": { + "en": "What is the email address of {name}?", + "nl": "Wat is het email-adres van {name}?", + "fr": "Quelle est l'adresse électronique de {name} ?", + "gl": "Cal é o enderezo de correo electrónico de {name}?", + "de": "Wie lautet die E-Mail-Adresse von {name}?", + "it": "Qual è l’indirizzo email di {name}?", + "ru": "Какой адрес электронной почты у {name}?", + "zh_Hans": "{name}的电子邮箱是什么?", + "zh_Hant": "{name} 的電子郵件地址是?", + "pt_BR": "Qual o endereço de email de {name}?" + }, + "render": "{email}", + "freeform": { + "key": "email", + "type": "email" + } + }, + { + "question": { + "en": "When it this bike café opened?", + "nl": "Wanneer is dit fietscafé geopend?", + "fr": "Quand ce Café vélo est-t-il ouvert ?", + "it": "Quando è aperto questo caffè in bici?", + "zh_Hans": "这家自行车咖啡什么时候开门营业?", + "zh_Hant": "何時這個單車咖啡廳營運?", + "ru": "Каков режим работы этого велосипедного кафе?", + "pt_BR": "Quando este café de bicicleta abre?" + }, + "render": "{opening_hours_table(opening_hours)}", + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + } + } + ], + "icon": { + "render": "./assets/layers/bike_cafe/bike_cafe.svg" + }, + "width": { + "render": "2" + }, + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#694E2D" + }, + "presets": [ + { + "title": { + "en": "Bike cafe", + "nl": "Fietscafé", + "fr": "Café Vélo", + "gl": "Café de ciclistas", + "de": "Fahrrad-Café", + "it": "Caffè in bici", + "zh_Hans": "自行车咖啡", + "zh_Hant": "單車咖啡廳", + "ru": "Велосипедное кафе", + "pt_BR": "Café de bicicleta" + }, + "tags": [ + "amenity=pub", + "pub=cycling" + ] + } + ], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/bike_cleaning/bike_cleaning.json b/assets/layers/bike_cleaning/bike_cleaning.json index d4c45d6a7..bf92b1987 100644 --- a/assets/layers/bike_cleaning/bike_cleaning.json +++ b/assets/layers/bike_cleaning/bike_cleaning.json @@ -1,57 +1,6 @@ { - "id": "bike_cleaning", - "name": { - "en": "Bike cleaning service", - "nl": "Fietsschoonmaakpunt", - "fr": "Service de nettoyage de vélo", - "it": "Servizio lavaggio bici", - "de": "Fahrrad-Reinigungsdienst", - "zh_Hant": "單車清理服務", - "pt_BR": "Serviço de limpeza de bicicletas" - }, - "title": { - "render": { - "en": "Bike cleaning service", - "nl": "Fietsschoonmaakpunt", - "fr": "Service de nettoyage de vélo", - "it": "Servizio lavaggio bici", - "de": "Fahrrad-Reinigungsdienst", - "zh_Hant": "單車清理服務", - "pt_BR": "Serviço de limpeza de bicicletas" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "en": "Bike cleaning service {name}", - "nl": "Fietsschoonmaakpunt {name}", - "fr": "Service de nettoyage de vélo {name}", - "it": "Servizio lavaggio bici {name}", - "de": "Fahrrad-Reinigungsdienst{name}", - "zh_Hant": "單車清理服務 {name}", - "pt_BR": "Serviço de limpeza de bicicletas {name}" - } - } - ] - }, - "icon": { - "render": "./assets/layers/bike_cleaning/bike_cleaning.svg" - }, - "iconSize": "50,50,bottom", - "source": { - "osmTags": { - "or": [ - "service:bicycle:cleaning=yes", - "service:bicycle:cleaning=diy", - "amenity=bicycle_wash" - ] - } - }, - "minzoom": 13, - "wayHandling": 1, - "presets": [ - { - "title": { + "id": "bike_cleaning", + "name": { "en": "Bike cleaning service", "nl": "Fietsschoonmaakpunt", "fr": "Service de nettoyage de vélo", @@ -59,89 +8,140 @@ "de": "Fahrrad-Reinigungsdienst", "zh_Hant": "單車清理服務", "pt_BR": "Serviço de limpeza de bicicletas" - }, - "tags": [ - "amenity=bicycle_wash" - ] - } - ], - "color": "#6bc4f7", - "iconOverlays": [ - { - "if": { - "and": [ - "service:bicycle:cleaning~*", - "amenity!=bike_wash" - ] - }, - "then": { - "render": "./assets/layers/bike_cleaning/bike_cleaning_icon.svg", - "roaming": true - }, - "badge": true - } - ], - "titleIcons": [ - { - "render": "", - "roaming": true - } - ], - "tagRenderings": [ - "images", - { - "question": "How much does it cost to use the cleaning service?", - "render": "Using the cleaning service costs {charge}", - "condition": "amenity!=bike_wash", - "freeform": { - "key": "service:bicycle:cleaning:charge", - "addExtraTags": [ - "service:bicycle:cleaning:fee=yes" - ] - }, - "mappings": [ - { - "if": "service:bicycle:cleaning:fee=no&service:bicycle:cleaning:charge=", - "then": "The cleaning service is free to use" - }, - { - "if": "service:bicycle:cleaning:fee=no&", - "then": "Free to use", - "hideInAnswer": true - }, - { - "if": "service:bicycle:cleaning:fee=yes", - "then": "The cleaning service has a fee" - } - ], - "roaming": true }, - { - "question": "How much does it cost to use the cleaning service?", - "render": "Using the cleaning service costs {charge}", - "condition": "amenity=bike_wash", - "freeform": { - "key": "charge", - "addExtraTags": [ - "fee=yes" + "title": { + "render": { + "en": "Bike cleaning service", + "nl": "Fietsschoonmaakpunt", + "fr": "Service de nettoyage de vélo", + "it": "Servizio lavaggio bici", + "de": "Fahrrad-Reinigungsdienst", + "zh_Hant": "單車清理服務", + "pt_BR": "Serviço de limpeza de bicicletas" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "en": "Bike cleaning service {name}", + "nl": "Fietsschoonmaakpunt {name}", + "fr": "Service de nettoyage de vélo {name}", + "it": "Servizio lavaggio bici {name}", + "de": "Fahrrad-Reinigungsdienst{name}", + "zh_Hant": "單車清理服務 {name}", + "pt_BR": "Serviço de limpeza de bicicletas {name}" + } + } ] - }, - "mappings": [ - { - "if": "fee=no&charge=", - "then": "Free to use cleaning service" - }, - { - "if": "fee=no&", - "then": "Free to use", - "hideInAnswer": true - }, - { - "if": "fee=yes", - "then": "The cleaning service has a fee" + }, + "icon": { + "render": "./assets/layers/bike_cleaning/bike_cleaning.svg" + }, + "iconSize": "50,50,bottom", + "source": { + "osmTags": { + "or": [ + "service:bicycle:cleaning=yes", + "service:bicycle:cleaning=diy", + "amenity=bicycle_wash" + ] } - ], - "roaming": false - } - ] + }, + "minzoom": 13, + "wayHandling": 1, + "presets": [ + { + "title": { + "en": "Bike cleaning service", + "nl": "Fietsschoonmaakpunt", + "fr": "Service de nettoyage de vélo", + "it": "Servizio lavaggio bici", + "de": "Fahrrad-Reinigungsdienst", + "zh_Hant": "單車清理服務", + "pt_BR": "Serviço de limpeza de bicicletas" + }, + "tags": [ + "amenity=bicycle_wash" + ] + } + ], + "color": "#6bc4f7", + "iconOverlays": [ + { + "if": { + "and": [ + "service:bicycle:cleaning~*", + "amenity!=bike_wash" + ] + }, + "then": { + "render": "./assets/layers/bike_cleaning/bike_cleaning_icon.svg", + "roaming": true + }, + "badge": true + } + ], + "titleIcons": [ + { + "render": "", + "roaming": true + } + ], + "tagRenderings": [ + "images", + { + "question": "How much does it cost to use the cleaning service?", + "render": "Using the cleaning service costs {charge}", + "condition": "amenity!=bike_wash", + "freeform": { + "key": "service:bicycle:cleaning:charge", + "addExtraTags": [ + "service:bicycle:cleaning:fee=yes" + ] + }, + "mappings": [ + { + "if": "service:bicycle:cleaning:fee=no&service:bicycle:cleaning:charge=", + "then": "The cleaning service is free to use" + }, + { + "if": "service:bicycle:cleaning:fee=no&", + "then": "Free to use", + "hideInAnswer": true + }, + { + "if": "service:bicycle:cleaning:fee=yes", + "then": "The cleaning service has a fee" + } + ], + "roaming": true + }, + { + "question": "How much does it cost to use the cleaning service?", + "render": "Using the cleaning service costs {charge}", + "condition": "amenity=bike_wash", + "freeform": { + "key": "charge", + "addExtraTags": [ + "fee=yes" + ] + }, + "mappings": [ + { + "if": "fee=no&charge=", + "then": "Free to use cleaning service" + }, + { + "if": "fee=no&", + "then": "Free to use", + "hideInAnswer": true + }, + { + "if": "fee=yes", + "then": "The cleaning service has a fee" + } + ], + "roaming": false + } + ] } \ No newline at end of file diff --git a/assets/layers/bike_monitoring_station/bike_monitoring_station.json b/assets/layers/bike_monitoring_station/bike_monitoring_station.json index 702e1690e..a20942f96 100644 --- a/assets/layers/bike_monitoring_station/bike_monitoring_station.json +++ b/assets/layers/bike_monitoring_station/bike_monitoring_station.json @@ -1,85 +1,85 @@ { - "id": "bike_monitoring_station", - "name": { - "en": "Monitoring stations", - "nl": "Telstation", - "fr": "Stations de contrôle", - "it": "Stazioni di monitoraggio", - "zh_Hant": "監視站", - "ru": "Станции мониторинга", - "pt_BR": "Estações de monitoramento" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - "man_made=monitoring_station", - "monitoring:bicycle=yes" - ] - } - }, - "title": { - "render": { - "nl": "Fietstelstation", - "en": "Bicycle counting station", - "fr": "Station de comptage de vélo", - "it": "Contabiciclette", - "de": "Fahrradzählstation", - "zh_Hant": "單車計數站", - "pt_BR": "Estação de contagem de bicicletas" + "id": "bike_monitoring_station", + "name": { + "en": "Monitoring stations", + "nl": "Telstation", + "fr": "Stations de contrôle", + "it": "Stazioni di monitoraggio", + "zh_Hant": "監視站", + "ru": "Станции мониторинга", + "pt_BR": "Estações de monitoramento" }, - "mappings": [ - { - "if": "name~*", - "then": { - "en": "Bicycle counting station {name}", - "nl": "Fietstelstation {name}", - "fr": "Station de comptage de vélo {name}", - "it": "Contabiciclette {name}", - "de": "Fahrradzählstation {name}", - "zh_Hant": "單車計數站 {name}", - "pl": "Stacja liczenia rowerów {name}", - "pt_BR": "Estação de contagem de bicicletas {name}" + "minzoom": 12, + "source": { + "osmTags": { + "and": [ + "man_made=monitoring_station", + "monitoring:bicycle=yes" + ] } - }, - { - "if": "ref~*", - "then": { - "en": "Bicycle counting station {ref}", - "nl": "Fietstelstation {ref}", - "fr": "Station de comptage de vélo {ref}", - "it": "Contabiciclette {ref}", - "de": "Fahrradzählstation {ref}", - "zh_Hant": "單車計數站 {ref}", - "pl": "Stacja liczenia rowerów {ref}", - "pt_BR": "Estação de contagem de bicicletas {ref}" - } - } - ] - }, - "tagRenderings": [ - "images", - { - "render": "{live({url},{url:format},hour)} cyclists last hour
{live({url},{url:format},day)} cyclists today
{live({url},{url:format},year)} cyclists this year
", - "condition": { - "and": [ - "url~*", - "url:format~*" + }, + "title": { + "render": { + "nl": "Fietstelstation", + "en": "Bicycle counting station", + "fr": "Station de comptage de vélo", + "it": "Contabiciclette", + "de": "Fahrradzählstation", + "zh_Hant": "單車計數站", + "pt_BR": "Estação de contagem de bicicletas" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "en": "Bicycle counting station {name}", + "nl": "Fietstelstation {name}", + "fr": "Station de comptage de vélo {name}", + "it": "Contabiciclette {name}", + "de": "Fahrradzählstation {name}", + "zh_Hant": "單車計數站 {name}", + "pl": "Stacja liczenia rowerów {name}", + "pt_BR": "Estação de contagem de bicicletas {name}" + } + }, + { + "if": "ref~*", + "then": { + "en": "Bicycle counting station {ref}", + "nl": "Fietstelstation {ref}", + "fr": "Station de comptage de vélo {ref}", + "it": "Contabiciclette {ref}", + "de": "Fahrradzählstation {ref}", + "zh_Hant": "單車計數站 {ref}", + "pl": "Stacja liczenia rowerów {ref}", + "pt_BR": "Estação de contagem de bicicletas {ref}" + } + } ] - } - } - ], - "icon": { - "render": "./assets/layers/bike_monitoring_station/monitoring_station.svg" - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#00f" - }, - "presets": [] + }, + "tagRenderings": [ + "images", + { + "render": "{live({url},{url:format},hour)} cyclists last hour
{live({url},{url:format},day)} cyclists today
{live({url},{url:format},year)} cyclists this year
", + "condition": { + "and": [ + "url~*", + "url:format~*" + ] + } + } + ], + "icon": { + "render": "./assets/layers/bike_monitoring_station/monitoring_station.svg" + }, + "width": { + "render": "8" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#00f" + }, + "presets": [] } \ No newline at end of file diff --git a/assets/layers/bike_parking/bike_parking.json b/assets/layers/bike_parking/bike_parking.json index e1983de68..7153b1532 100644 --- a/assets/layers/bike_parking/bike_parking.json +++ b/assets/layers/bike_parking/bike_parking.json @@ -1,36 +1,6 @@ { - "id": "bike_parking", - "name": { - "en": "Bike parking", - "nl": "Fietsparking", - "fr": "Parking à vélo", - "gl": "Aparcadoiro de bicicletas", - "de": "Fahrrad-Parkplätze", - "hu": "Kerékpáros parkoló", - "it": "Parcheggio bici", - "zh_Hant": "單車停車場", - "ru": "Велопарковка", - "pl": "Parking dla rowerów", - "pt_BR": "Estacionamento de bicicletas" - }, - "minzoom": 17, - "source": { - "osmTags": { - "and": [ - "amenity=bicycle_parking" - ] - } - }, - "icon": { - "render": "./assets/layers/bike_parking/parking.svg" - }, - "iconSize": "40,40,bottom", - "color": "#00f", - "width": "1", - "wayHandling": 2, - "presets": [ - { - "title": { + "id": "bike_parking", + "name": { "en": "Bike parking", "nl": "Fietsparking", "fr": "Parking à vélo", @@ -42,471 +12,501 @@ "ru": "Велопарковка", "pl": "Parking dla rowerów", "pt_BR": "Estacionamento de bicicletas" - }, - "tags": [ - "amenity=bicycle_parking" - ] - } - ], - "title": { - "render": { - "en": "Bike parking", - "nl": "Fietsparking", - "fr": "Parking à vélo", - "gl": "Aparcadoiro de bicicletas", - "de": "Fahrrad-Parkplätze", - "hu": "Kerékpáros parkoló", - "it": "Parcheggio bici", - "zh_Hant": "單車停車場", - "ru": "Велопарковка", - "pl": "Parking dla rowerów", - "pt_BR": "Estacionamento de bicicletas" - } - }, - "tagRenderings": [ - "images", - { - "#": "Bicycle parking type", - "question": { - "en": "What is the type of this bicycle parking?", - "nl": "Van welk type is deze fietsparking?", - "fr": "Quel type de parking à vélos est-ce ?", - "gl": "Que tipo de aparcadoiro de bicicletas é?", - "de": "Was ist die Art dieses Fahrrad-Parkplatzes?", - "hu": "Milyen típusú ez a kerékpáros parkoló?", - "it": "Di che tipo di parcheggio bici si tratta?", - "ru": "К какому типу относится эта велопарковка?", - "zh_Hant": "這是那種類型的單車停車場?", - "pl": "Jaki jest typ tego parkingu dla rowerów?", - "pt_BR": "Qual o tipo deste estacionamento de bicicletas?" - }, - "render": { - "en": "This is a bicycle parking of the type: {bicycle_parking}", - "nl": "Dit is een fietsparking van het type: {bicycle_parking}", - "fr": "Ceci est un parking à vélo de type {bicycle_parking}", - "gl": "Este é un aparcadoiro de bicicletas do tipo: {bicycle_parking}", - "de": "Dies ist ein Fahrrad-Parkplatz der Art: {bicycle_parking}", - "hu": "Ez egy {bicycle_parking} típusú kerékpáros parkoló", - "it": "È un parcheggio bici del tipo: {bicycle_parking}", - "zh_Hant": "這個單車停車場的類型是:{bicycle_parking}", - "ru": "Это велопарковка типа {bicycle_parking}", - "pl": "Jest to parking rowerowy typu: {bicycle_parking}", - "pt_BR": "Este é um estacionamento de bicicletas do tipo: {bicycle_parking}" - }, - "freeform": { - "key": "bicycle_parking", - "addExtraTags": [ - "fixme=Freeform used on 'bicycle_parking'-tag: possibly a wrong value" - ] - }, - "mappings": [ - { - "if": "bicycle_parking=stands", - "then": { - "en": "Staple racks ", - "nl": "Nietjes ", - "fr": "Arceaux ", - "gl": "De roda (Stands) ", - "de": "Fahrradbügel ", - "hu": "\"U\" ", - "it": "Archetti ", - "zh_Hant": "單車架 " - } - }, - { - "if": "bicycle_parking=wall_loops", - "then": { - "en": "Wheel rack/loops ", - "nl": "Wielrek/lussen ", - "fr": "Pinces-roues ", - "gl": "Aros ", - "de": "Metallgestänge ", - "hu": "Kengyeles ", - "it": "Scolapiatti ", - "zh_Hant": "車輪架/圓圈 " - } - }, - { - "if": "bicycle_parking=handlebar_holder", - "then": { - "en": "Handlebar holder ", - "nl": "Stuurhouder ", - "fr": "Support guidon ", - "gl": "Cadeado para guiador ", - "de": "Halter für Fahrradlenker ", - "it": "Blocca manubrio ", - "zh_Hant": "車把架 " - } - }, - { - "if": "bicycle_parking=rack", - "then": { - "en": "Rack ", - "nl": "Rek ", - "fr": "Râtelier ", - "gl": "Cremalleira ", - "de": "Gestell ", - "zh_Hant": "車架", - "it": "Rastrelliera ", - "ru": "Стойка " - } - }, - { - "if": "bicycle_parking=two_tier", - "then": { - "en": "Two-tiered ", - "nl": "Dubbel (twee verdiepingen) ", - "fr": "Superposé ", - "gl": "Dobre cremalleira ", - "de": "Zweistufig ", - "hu": "Kétszintű ", - "zh_Hant": "兩層", - "it": "A due piani ", - "ru": "Двухуровневая " - } - }, - { - "if": "bicycle_parking=shed", - "then": { - "en": "Shed ", - "nl": "Schuur ", - "fr": "Abri ", - "gl": "Abeiro ", - "de": "Schuppen ", - "hu": "Fészer ", - "zh_Hant": "車棚 ", - "it": "Rimessa ", - "ru": "Навес " - } - }, - { - "if": "bicycle_parking=bollard", - "then": { - "en": "Bollard ", - "nl": "Paal met ring ", - "fr": "Potelet ", - "it": "Colonnina ", - "de": "Poller ", - "zh_Hant": "柱子 " - } - }, - { - "if": "bicycle_parking=floor", - "then": { - "en": "An area on the floor which is marked for bicycle parking", - "nl": "Een oppervlakte die gemarkeerd is om fietsen te parkeren", - "fr": "Zone au sol qui est marquée pour le stationnement des vélos", - "it": "Una zona del pavimento che è marcata per il parcheggio delle bici", - "de": "Ein Bereich auf dem Boden, der für das Abstellen von Fahrrädern gekennzeichnet ist", - "zh_Hant": "樓層當中標示為單車停車場的區域" - } + }, + "minzoom": 17, + "source": { + "osmTags": { + "and": [ + "amenity=bicycle_parking" + ] } - ] }, - { - "#": "Underground?", - "question": { - "en": "What is the relative location of this bicycle parking?", - "nl": "Wat is de relatieve locatie van deze parking??", - "fr": "Quelle est la position relative de ce parking à vélo ?", - "it": "Qual è la posizione relativa di questo parcheggio bici?", - "zh_Hant": "這個單車停車場的相對位置是?", - "pl": "Jaka jest względna lokalizacja tego parkingu rowerowego?", - "pt_BR": "Qual a localização relativa deste estacionamento de bicicletas?" - }, - "mappings": [ + "icon": { + "render": "./assets/layers/bike_parking/parking.svg" + }, + "iconSize": "40,40,bottom", + "color": "#00f", + "width": "1", + "wayHandling": 2, + "presets": [ { - "if": "location=underground", - "then": { - "en": "Underground parking", - "nl": "Ondergrondse parking", - "fr": "Parking souterrain", - "it": "Parcheggio sotterraneo", - "ru": "Подземная парковка", - "de": "Tiefgarage", - "zh_Hant": "地下停車場", - "pt_BR": "Estacionamento subterrâneo" - } - }, - { - "if": "location=underground", - "then": { - "en": "Underground parking", - "nl": "Ondergrondse parking", - "fr": "Parking souterrain", - "it": "Parcheggio sotterraneo", - "ru": "Подземная парковка", - "de": "Tiefgarage", - "zh_Hant": "地下停車場", - "pt_BR": "Estacionamento subterrâneo" - } - }, - { - "if": "location=surface", - "then": { - "en": "Surface level parking", - "nl": "Parking op de begane grond", - "fr": "Parking en surface", - "hu": "Felszíni parkoló", - "it": "Parcheggio in superficie", - "de": "Ebenerdiges Parken", - "zh_Hant": "地面停車場", - "pt_BR": "Estacionamento de superfície" - } - }, - { - "if": "location=", - "then": { - "en": "Surface level parking", - "nl": "Parking op de begane grond", - "fr": "Parking en surface", - "hu": "Felszíni parkoló", - "it": "Parcheggio in superficie", - "de": "Ebenerdiges Parken", - "zh_Hant": "地面層停車場", - "pt_BR": "Estacionamento ao nível da superfície" - }, - "hideInAnwser": true - }, - { - "if": "location=rooftop", - "then": { - "en": "Rooftop parking", - "nl": "Dakparking", - "fr": "Parking sur un toit", - "hu": "Tetőparkoló", - "it": "Parcheggio sul tetto", - "ru": "Парковка на крыше", - "zh_Hant": "屋頂停車場", - "pt_BR": "Estacionamento no telhado" - } + "title": { + "en": "Bike parking", + "nl": "Fietsparking", + "fr": "Parking à vélo", + "gl": "Aparcadoiro de bicicletas", + "de": "Fahrrad-Parkplätze", + "hu": "Kerékpáros parkoló", + "it": "Parcheggio bici", + "zh_Hant": "單車停車場", + "ru": "Велопарковка", + "pl": "Parking dla rowerów", + "pt_BR": "Estacionamento de bicicletas" + }, + "tags": [ + "amenity=bicycle_parking" + ] } - ] - }, - { - "#": "Is covered?", - "question": { - "en": "Is this parking covered? Also select \"covered\" for indoor parkings.", - "nl": "Is deze parking overdekt? Selecteer ook \"overdekt\" voor fietsparkings binnen een gebouw.", - "gl": "Este aparcadoiro está cuberto? Tamén escolle \"cuberto\" para aparcadoiros interiores.", - "de": "Ist dieser Parkplatz überdacht? Wählen Sie auch \"überdacht\" für Innenparkplätze.", - "fr": "Ce parking est-il couvert ? Sélectionnez aussi \"couvert\" pour les parkings en intérieur.", - "hu": "Fedett ez a parkoló? (Beltéri parkoló esetén is válaszd a \"fedett\" opciót.)", - "it": "È un parcheggio coperto? Indicare “coperto” per parcheggi all’interno.", - "zh_Hant": "這個停車場是否有車棚?如果是室內停車場也請選擇\"遮蔽\"。", - "pt_BR": "Este estacionamento é coberto? Também selecione \"coberto\" para estacionamentos internos." - }, - "condition": { - "and": [ - "bicycle_parking!=shed", - "location!=underground" - ] - }, - "mappings": [ - { - "if": "covered=yes", - "then": { - "en": "This parking is covered (it has a roof)", - "nl": "Deze parking is overdekt (er is een afdak)", - "gl": "Este aparcadoiro está cuberto (ten un teito)", - "de": "Dieser Parkplatz ist überdacht (er hat ein Dach)", - "fr": "Ce parking est couvert (il a un toit)", - "hu": "A parkoló fedett", - "it": "È un parcheggio coperto (ha un tetto)", - "zh_Hant": "這個停車場有遮蔽 (有屋頂)", - "ru": "Это крытая парковка (есть крыша/навес)", - "pt_BR": "Este estacionamento é coberto (tem um telhado)" - } - }, - { - "if": "covered=no", - "then": { - "en": "This parking is not covered", - "nl": "Deze parking is niet overdekt", - "gl": "Este aparcadoiro non está cuberto", - "de": "Dieser Parkplatz ist nicht überdacht", - "fr": "Ce parking n'est pas couvert", - "hu": "A parkoló nem fedett", - "it": "Non è un parcheggio coperto", - "zh_Hant": "這個停車場沒有遮蔽", - "ru": "Это открытая парковка", - "pt_BR": "Este estacionamento não é coberto" - } + ], + "title": { + "render": { + "en": "Bike parking", + "nl": "Fietsparking", + "fr": "Parking à vélo", + "gl": "Aparcadoiro de bicicletas", + "de": "Fahrrad-Parkplätze", + "hu": "Kerékpáros parkoló", + "it": "Parcheggio bici", + "zh_Hant": "單車停車場", + "ru": "Велопарковка", + "pl": "Parking dla rowerów", + "pt_BR": "Estacionamento de bicicletas" } - ] }, - { - "#": "Capacity", - "question": { - "en": "How many bicycles fit in this bicycle parking (including possible cargo bicycles)?", - "fr": "Combien de vélos entrent dans ce parking à vélos (y compris les éventuels vélos de transport) ?", - "nl": "Hoeveel fietsen kunnen in deze fietsparking (inclusief potentiëel bakfietsen)?", - "gl": "Cantas bicicletas caben neste aparcadoiro de bicicletas (incluídas as posíbeis bicicletas de carga)?", - "de": "Wie viele Fahrräder passen auf diesen Fahrrad-Parkplatz (einschließlich möglicher Lastenfahrräder)?", - "it": "Quante biciclette entrano in questo parcheggio per bici (incluse le eventuali bici da trasporto)?", - "zh_Hant": "這個單車停車場能放幾台單車 (包括裝箱單車)?" - }, - "render": { - "en": "Place for {capacity} bikes", - "fr": "Place pour {capacity} vélos", - "nl": "Plaats voor {capacity} fietsen", - "gl": "Lugar para {capacity} bicicletas", - "de": "Platz für {capacity} Fahrräder", - "it": "Posti per {capacity} bici", - "zh_Hant": "{capacity} 單車的地方", - "ru": "Место для {capacity} велосипеда(ов)", - "pt_BR": "Lugar para {capacity} bicicletas" - }, - "freeform": { - "key": "capacity", - "type": "nat" - } - }, - { - "#": "Access", - "question": { - "en": "Who can use this bicycle parking?", - "nl": "Wie mag er deze fietsenstalling gebruiken?", - "fr": "Qui peut utiliser ce parking à vélo ?", - "it": "Chi può usare questo parcheggio bici?", - "de": "Wer kann diesen Fahrradparplatz nutzen?", - "zh_Hant": "誰可以使用這個單車停車場?", - "ru": "Кто может пользоваться этой велопарковкой?", - "pt_BR": "Quem pode usar este estacionamento de bicicletas?" - }, - "render": { - "en": "{access}", - "de": "{access}", - "fr": "{access}", - "nl": "{access}", - "it": "{access}", - "ru": "{access}", - "id": "{access}", - "zh_Hant": "{access}", - "fi": "{access}", - "pt_BR": "{access}" - }, - "freeform": { - "key": "access", - "addExtraTags": [ - "fixme=Freeform used on 'access'-tag: possibly a wrong value" - ] - }, - "mappings": [ + "tagRenderings": [ + "images", { - "if": "access=yes", - "then": { - "en": "Publicly accessible", - "nl": "Publiek toegankelijke fietsenstalling", - "fr": "Accessible publiquement", - "it": "Accessibile pubblicamente", - "de": "Öffentlich zugänglich", - "zh_Hant": "公開可用", - "pt_BR": "Acessível ao público" - } + "#": "Bicycle parking type", + "question": { + "en": "What is the type of this bicycle parking?", + "nl": "Van welk type is deze fietsparking?", + "fr": "Quel type de parking à vélos est-ce ?", + "gl": "Que tipo de aparcadoiro de bicicletas é?", + "de": "Was ist die Art dieses Fahrrad-Parkplatzes?", + "hu": "Milyen típusú ez a kerékpáros parkoló?", + "it": "Di che tipo di parcheggio bici si tratta?", + "ru": "К какому типу относится эта велопарковка?", + "zh_Hant": "這是那種類型的單車停車場?", + "pl": "Jaki jest typ tego parkingu dla rowerów?", + "pt_BR": "Qual o tipo deste estacionamento de bicicletas?" + }, + "render": { + "en": "This is a bicycle parking of the type: {bicycle_parking}", + "nl": "Dit is een fietsparking van het type: {bicycle_parking}", + "fr": "Ceci est un parking à vélo de type {bicycle_parking}", + "gl": "Este é un aparcadoiro de bicicletas do tipo: {bicycle_parking}", + "de": "Dies ist ein Fahrrad-Parkplatz der Art: {bicycle_parking}", + "hu": "Ez egy {bicycle_parking} típusú kerékpáros parkoló", + "it": "È un parcheggio bici del tipo: {bicycle_parking}", + "zh_Hant": "這個單車停車場的類型是:{bicycle_parking}", + "ru": "Это велопарковка типа {bicycle_parking}", + "pl": "Jest to parking rowerowy typu: {bicycle_parking}", + "pt_BR": "Este é um estacionamento de bicicletas do tipo: {bicycle_parking}" + }, + "freeform": { + "key": "bicycle_parking", + "addExtraTags": [ + "fixme=Freeform used on 'bicycle_parking'-tag: possibly a wrong value" + ] + }, + "mappings": [ + { + "if": "bicycle_parking=stands", + "then": { + "en": "Staple racks ", + "nl": "Nietjes ", + "fr": "Arceaux ", + "gl": "De roda (Stands) ", + "de": "Fahrradbügel ", + "hu": "\"U\" ", + "it": "Archetti ", + "zh_Hant": "單車架 " + } + }, + { + "if": "bicycle_parking=wall_loops", + "then": { + "en": "Wheel rack/loops ", + "nl": "Wielrek/lussen ", + "fr": "Pinces-roues ", + "gl": "Aros ", + "de": "Metallgestänge ", + "hu": "Kengyeles ", + "it": "Scolapiatti ", + "zh_Hant": "車輪架/圓圈 " + } + }, + { + "if": "bicycle_parking=handlebar_holder", + "then": { + "en": "Handlebar holder ", + "nl": "Stuurhouder ", + "fr": "Support guidon ", + "gl": "Cadeado para guiador ", + "de": "Halter für Fahrradlenker ", + "it": "Blocca manubrio ", + "zh_Hant": "車把架 " + } + }, + { + "if": "bicycle_parking=rack", + "then": { + "en": "Rack ", + "nl": "Rek ", + "fr": "Râtelier ", + "gl": "Cremalleira ", + "de": "Gestell ", + "zh_Hant": "車架", + "it": "Rastrelliera ", + "ru": "Стойка " + } + }, + { + "if": "bicycle_parking=two_tier", + "then": { + "en": "Two-tiered ", + "nl": "Dubbel (twee verdiepingen) ", + "fr": "Superposé ", + "gl": "Dobre cremalleira ", + "de": "Zweistufig ", + "hu": "Kétszintű ", + "zh_Hant": "兩層", + "it": "A due piani ", + "ru": "Двухуровневая " + } + }, + { + "if": "bicycle_parking=shed", + "then": { + "en": "Shed ", + "nl": "Schuur ", + "fr": "Abri ", + "gl": "Abeiro ", + "de": "Schuppen ", + "hu": "Fészer ", + "zh_Hant": "車棚 ", + "it": "Rimessa ", + "ru": "Навес " + } + }, + { + "if": "bicycle_parking=bollard", + "then": { + "en": "Bollard ", + "nl": "Paal met ring ", + "fr": "Potelet ", + "it": "Colonnina ", + "de": "Poller ", + "zh_Hant": "柱子 " + } + }, + { + "if": "bicycle_parking=floor", + "then": { + "en": "An area on the floor which is marked for bicycle parking", + "nl": "Een oppervlakte die gemarkeerd is om fietsen te parkeren", + "fr": "Zone au sol qui est marquée pour le stationnement des vélos", + "it": "Una zona del pavimento che è marcata per il parcheggio delle bici", + "de": "Ein Bereich auf dem Boden, der für das Abstellen von Fahrrädern gekennzeichnet ist", + "zh_Hant": "樓層當中標示為單車停車場的區域" + } + } + ] }, { - "if": "access=customers", - "then": { - "en": "Access is primarily for visitors to a business", - "nl": "Klanten van de zaak of winkel", - "fr": "Accès destiné principalement aux visiteurs d'un lieu", - "it": "Accesso destinato principalmente ai visitatori di un’attività", - "zh_Hant": "通行性主要是為了企業的顧客", - "pt_BR": "Acesso é principalmente para visitantes de uma empresa" - } + "#": "Underground?", + "question": { + "en": "What is the relative location of this bicycle parking?", + "nl": "Wat is de relatieve locatie van deze parking??", + "fr": "Quelle est la position relative de ce parking à vélo ?", + "it": "Qual è la posizione relativa di questo parcheggio bici?", + "zh_Hant": "這個單車停車場的相對位置是?", + "pl": "Jaka jest względna lokalizacja tego parkingu rowerowego?", + "pt_BR": "Qual a localização relativa deste estacionamento de bicicletas?" + }, + "mappings": [ + { + "if": "location=underground", + "then": { + "en": "Underground parking", + "nl": "Ondergrondse parking", + "fr": "Parking souterrain", + "it": "Parcheggio sotterraneo", + "ru": "Подземная парковка", + "de": "Tiefgarage", + "zh_Hant": "地下停車場", + "pt_BR": "Estacionamento subterrâneo" + } + }, + { + "if": "location=underground", + "then": { + "en": "Underground parking", + "nl": "Ondergrondse parking", + "fr": "Parking souterrain", + "it": "Parcheggio sotterraneo", + "ru": "Подземная парковка", + "de": "Tiefgarage", + "zh_Hant": "地下停車場", + "pt_BR": "Estacionamento subterrâneo" + } + }, + { + "if": "location=surface", + "then": { + "en": "Surface level parking", + "nl": "Parking op de begane grond", + "fr": "Parking en surface", + "hu": "Felszíni parkoló", + "it": "Parcheggio in superficie", + "de": "Ebenerdiges Parken", + "zh_Hant": "地面停車場", + "pt_BR": "Estacionamento de superfície" + } + }, + { + "if": "location=", + "then": { + "en": "Surface level parking", + "nl": "Parking op de begane grond", + "fr": "Parking en surface", + "hu": "Felszíni parkoló", + "it": "Parcheggio in superficie", + "de": "Ebenerdiges Parken", + "zh_Hant": "地面層停車場", + "pt_BR": "Estacionamento ao nível da superfície" + }, + "hideInAnwser": true + }, + { + "if": "location=rooftop", + "then": { + "en": "Rooftop parking", + "nl": "Dakparking", + "fr": "Parking sur un toit", + "hu": "Tetőparkoló", + "it": "Parcheggio sul tetto", + "ru": "Парковка на крыше", + "zh_Hant": "屋頂停車場", + "pt_BR": "Estacionamento no telhado" + } + } + ] }, { - "if": "access=private", - "then": { - "en": "Access is limited to members of a school, company or organisation", - "nl": "Private fietsenstalling van een school, een bedrijf, ...", - "fr": "Accès limité aux membres d'une école, entreprise ou organisation", - "it": "Accesso limitato ai membri di una scuola, una compagnia o un’organizzazione", - "zh_Hant": "通行性僅限學校、公司或組織的成員", - "pt_BR": "Acesso é limitado aos membros de uma escola, companhia ou organização" - } + "#": "Is covered?", + "question": { + "en": "Is this parking covered? Also select \"covered\" for indoor parkings.", + "nl": "Is deze parking overdekt? Selecteer ook \"overdekt\" voor fietsparkings binnen een gebouw.", + "gl": "Este aparcadoiro está cuberto? Tamén escolle \"cuberto\" para aparcadoiros interiores.", + "de": "Ist dieser Parkplatz überdacht? Wählen Sie auch \"überdacht\" für Innenparkplätze.", + "fr": "Ce parking est-il couvert ? Sélectionnez aussi \"couvert\" pour les parkings en intérieur.", + "hu": "Fedett ez a parkoló? (Beltéri parkoló esetén is válaszd a \"fedett\" opciót.)", + "it": "È un parcheggio coperto? Indicare “coperto” per parcheggi all’interno.", + "zh_Hant": "這個停車場是否有車棚?如果是室內停車場也請選擇\"遮蔽\"。", + "pt_BR": "Este estacionamento é coberto? Também selecione \"coberto\" para estacionamentos internos." + }, + "condition": { + "and": [ + "bicycle_parking!=shed", + "location!=underground" + ] + }, + "mappings": [ + { + "if": "covered=yes", + "then": { + "en": "This parking is covered (it has a roof)", + "nl": "Deze parking is overdekt (er is een afdak)", + "gl": "Este aparcadoiro está cuberto (ten un teito)", + "de": "Dieser Parkplatz ist überdacht (er hat ein Dach)", + "fr": "Ce parking est couvert (il a un toit)", + "hu": "A parkoló fedett", + "it": "È un parcheggio coperto (ha un tetto)", + "zh_Hant": "這個停車場有遮蔽 (有屋頂)", + "ru": "Это крытая парковка (есть крыша/навес)", + "pt_BR": "Este estacionamento é coberto (tem um telhado)" + } + }, + { + "if": "covered=no", + "then": { + "en": "This parking is not covered", + "nl": "Deze parking is niet overdekt", + "gl": "Este aparcadoiro non está cuberto", + "de": "Dieser Parkplatz ist nicht überdacht", + "fr": "Ce parking n'est pas couvert", + "hu": "A parkoló nem fedett", + "it": "Non è un parcheggio coperto", + "zh_Hant": "這個停車場沒有遮蔽", + "ru": "Это открытая парковка", + "pt_BR": "Este estacionamento não é coberto" + } + } + ] + }, + { + "#": "Capacity", + "question": { + "en": "How many bicycles fit in this bicycle parking (including possible cargo bicycles)?", + "fr": "Combien de vélos entrent dans ce parking à vélos (y compris les éventuels vélos de transport) ?", + "nl": "Hoeveel fietsen kunnen in deze fietsparking (inclusief potentiëel bakfietsen)?", + "gl": "Cantas bicicletas caben neste aparcadoiro de bicicletas (incluídas as posíbeis bicicletas de carga)?", + "de": "Wie viele Fahrräder passen auf diesen Fahrrad-Parkplatz (einschließlich möglicher Lastenfahrräder)?", + "it": "Quante biciclette entrano in questo parcheggio per bici (incluse le eventuali bici da trasporto)?", + "zh_Hant": "這個單車停車場能放幾台單車 (包括裝箱單車)?" + }, + "render": { + "en": "Place for {capacity} bikes", + "fr": "Place pour {capacity} vélos", + "nl": "Plaats voor {capacity} fietsen", + "gl": "Lugar para {capacity} bicicletas", + "de": "Platz für {capacity} Fahrräder", + "it": "Posti per {capacity} bici", + "zh_Hant": "{capacity} 單車的地方", + "ru": "Место для {capacity} велосипеда(ов)", + "pt_BR": "Lugar para {capacity} bicicletas" + }, + "freeform": { + "key": "capacity", + "type": "nat" + } + }, + { + "#": "Access", + "question": { + "en": "Who can use this bicycle parking?", + "nl": "Wie mag er deze fietsenstalling gebruiken?", + "fr": "Qui peut utiliser ce parking à vélo ?", + "it": "Chi può usare questo parcheggio bici?", + "de": "Wer kann diesen Fahrradparplatz nutzen?", + "zh_Hant": "誰可以使用這個單車停車場?", + "ru": "Кто может пользоваться этой велопарковкой?", + "pt_BR": "Quem pode usar este estacionamento de bicicletas?" + }, + "render": { + "en": "{access}", + "de": "{access}", + "fr": "{access}", + "nl": "{access}", + "it": "{access}", + "ru": "{access}", + "id": "{access}", + "zh_Hant": "{access}", + "fi": "{access}", + "pt_BR": "{access}" + }, + "freeform": { + "key": "access", + "addExtraTags": [ + "fixme=Freeform used on 'access'-tag: possibly a wrong value" + ] + }, + "mappings": [ + { + "if": "access=yes", + "then": { + "en": "Publicly accessible", + "nl": "Publiek toegankelijke fietsenstalling", + "fr": "Accessible publiquement", + "it": "Accessibile pubblicamente", + "de": "Öffentlich zugänglich", + "zh_Hant": "公開可用", + "pt_BR": "Acessível ao público" + } + }, + { + "if": "access=customers", + "then": { + "en": "Access is primarily for visitors to a business", + "nl": "Klanten van de zaak of winkel", + "fr": "Accès destiné principalement aux visiteurs d'un lieu", + "it": "Accesso destinato principalmente ai visitatori di un’attività", + "zh_Hant": "通行性主要是為了企業的顧客", + "pt_BR": "Acesso é principalmente para visitantes de uma empresa" + } + }, + { + "if": "access=private", + "then": { + "en": "Access is limited to members of a school, company or organisation", + "nl": "Private fietsenstalling van een school, een bedrijf, ...", + "fr": "Accès limité aux membres d'une école, entreprise ou organisation", + "it": "Accesso limitato ai membri di una scuola, una compagnia o un’organizzazione", + "zh_Hant": "通行性僅限學校、公司或組織的成員", + "pt_BR": "Acesso é limitado aos membros de uma escola, companhia ou organização" + } + } + ] + }, + { + "#": "Cargo bike spaces?", + "question": { + "en": "Does this bicycle parking have spots for cargo bikes?", + "nl": "Heeft deze fietsparking plaats voor bakfietsen?", + "gl": "Este aparcadoiro de bicicletas ten espazo para bicicletas de carga?", + "de": "Gibt es auf diesem Fahrrad-Parkplatz Plätze für Lastenfahrräder?", + "fr": "Est-ce que ce parking à vélo a des emplacements pour des vélos cargo ?", + "it": "Questo parcheggio dispone di posti specifici per le bici da trasporto?", + "zh_Hant": "這個單車停車場有地方放裝箱的單車嗎?", + "pt_BR": "O estacionamento de bicicletas tem vagas para bicicletas de carga?" + }, + "mappings": [ + { + "if": "cargo_bike=yes", + "then": { + "en": "This parking has room for cargo bikes", + "nl": "Deze parking heeft plaats voor bakfietsen", + "gl": "Este aparcadoiro ten espazo para bicicletas de carga.", + "de": "Dieser Parkplatz bietet Platz für Lastenfahrräder", + "fr": "Ce parking a de la place pour les vélos cargo", + "it": "Questo parcheggio ha posto per bici da trasporto", + "zh_Hant": "這個停車場有地方可以放裝箱單車", + "pt_BR": "Este estacionamento tem vagas para bicicletas de carga" + } + }, + { + "if": "cargo_bike=designated", + "then": { + "en": "This parking has designated (official) spots for cargo bikes.", + "nl": "Er zijn speciale plaatsen voorzien voor bakfietsen", + "gl": "Este aparcadoiro ten espazos designados (oficiais) para bicicletas de carga.", + "de": "Dieser Parkplatz verfügt über ausgewiesene (offizielle) Plätze für Lastenfahrräder.", + "fr": "Ce parking a des emplacements (officiellement) destinés aux vélos cargo.", + "it": "Questo parcheggio ha posti destinati (ufficialmente) alle bici da trasporto.", + "zh_Hant": "這停車場有設計 (官方) 空間給裝箱的單車。", + "pt_BR": "Este estacionamento tem vagas (oficiais) projetadas para bicicletas de carga." + } + }, + { + "if": "cargo_bike=no", + "then": { + "en": "You're not allowed to park cargo bikes", + "nl": "Je mag hier geen bakfietsen parkeren", + "gl": "Non está permitido aparcar bicicletas de carga", + "de": "Es ist nicht erlaubt, Lastenfahrräder zu parken", + "fr": "Il est interdit de garer des vélos cargo", + "it": "Il parcheggio delle bici da trasporto è proibito", + "pt_BR": "Você não tem permissão para estacionar bicicletas de carga" + } + } + ] + }, + { + "#": "Cargo bike capacity?", + "question": { + "en": "How many cargo bicycles fit in this bicycle parking?", + "nl": "Voor hoeveel bakfietsen heeft deze fietsparking plaats?", + "fr": "Combien de vélos de transport entrent dans ce parking à vélos ?", + "gl": "Cantas bicicletas de carga caben neste aparcadoiro de bicicletas?", + "de": "Wie viele Lastenfahrräder passen auf diesen Fahrrad-Parkplatz?", + "it": "Quante bici da trasporto entrano in questo parcheggio per bici?", + "pt_BR": "Quantas bicicletas de carga cabem neste estacionamento de bicicletas?" + }, + "render": { + "en": "This parking fits {capacity:cargo_bike} cargo bikes", + "nl": "Deze parking heeft plaats voor {capacity:cargo_bike} fietsen", + "fr": "Ce parking a de la place pour {capacity:cargo_bike} vélos de transport", + "gl": "Neste aparcadoiro caben {capacity:cargo_bike} bicicletas de carga", + "de": "Auf diesen Parkplatz passen {capacity:cargo_bike} Lastenfahrräder", + "it": "Questo parcheggio può contenere {capacity:cargo_bike} bici da trasporto", + "pt_BR": "Neste estacionamento cabem {capacity:cargo_bike} bicicletas de carga" + }, + "condition": "cargo_bike~designated|yes", + "freeform": { + "key": "capacity:cargo_bike", + "type": "nat" + } } - ] - }, - { - "#": "Cargo bike spaces?", - "question": { - "en": "Does this bicycle parking have spots for cargo bikes?", - "nl": "Heeft deze fietsparking plaats voor bakfietsen?", - "gl": "Este aparcadoiro de bicicletas ten espazo para bicicletas de carga?", - "de": "Gibt es auf diesem Fahrrad-Parkplatz Plätze für Lastenfahrräder?", - "fr": "Est-ce que ce parking à vélo a des emplacements pour des vélos cargo ?", - "it": "Questo parcheggio dispone di posti specifici per le bici da trasporto?", - "zh_Hant": "這個單車停車場有地方放裝箱的單車嗎?", - "pt_BR": "O estacionamento de bicicletas tem vagas para bicicletas de carga?" - }, - "mappings": [ - { - "if": "cargo_bike=yes", - "then": { - "en": "This parking has room for cargo bikes", - "nl": "Deze parking heeft plaats voor bakfietsen", - "gl": "Este aparcadoiro ten espazo para bicicletas de carga.", - "de": "Dieser Parkplatz bietet Platz für Lastenfahrräder", - "fr": "Ce parking a de la place pour les vélos cargo", - "it": "Questo parcheggio ha posto per bici da trasporto", - "zh_Hant": "這個停車場有地方可以放裝箱單車", - "pt_BR": "Este estacionamento tem vagas para bicicletas de carga" - } - }, - { - "if": "cargo_bike=designated", - "then": { - "en": "This parking has designated (official) spots for cargo bikes.", - "nl": "Er zijn speciale plaatsen voorzien voor bakfietsen", - "gl": "Este aparcadoiro ten espazos designados (oficiais) para bicicletas de carga.", - "de": "Dieser Parkplatz verfügt über ausgewiesene (offizielle) Plätze für Lastenfahrräder.", - "fr": "Ce parking a des emplacements (officiellement) destinés aux vélos cargo.", - "it": "Questo parcheggio ha posti destinati (ufficialmente) alle bici da trasporto.", - "zh_Hant": "這停車場有設計 (官方) 空間給裝箱的單車。", - "pt_BR": "Este estacionamento tem vagas (oficiais) projetadas para bicicletas de carga." - } - }, - { - "if": "cargo_bike=no", - "then": { - "en": "You're not allowed to park cargo bikes", - "nl": "Je mag hier geen bakfietsen parkeren", - "gl": "Non está permitido aparcar bicicletas de carga", - "de": "Es ist nicht erlaubt, Lastenfahrräder zu parken", - "fr": "Il est interdit de garer des vélos cargo", - "it": "Il parcheggio delle bici da trasporto è proibito", - "pt_BR": "Você não tem permissão para estacionar bicicletas de carga" - } - } - ] - }, - { - "#": "Cargo bike capacity?", - "question": { - "en": "How many cargo bicycles fit in this bicycle parking?", - "nl": "Voor hoeveel bakfietsen heeft deze fietsparking plaats?", - "fr": "Combien de vélos de transport entrent dans ce parking à vélos ?", - "gl": "Cantas bicicletas de carga caben neste aparcadoiro de bicicletas?", - "de": "Wie viele Lastenfahrräder passen auf diesen Fahrrad-Parkplatz?", - "it": "Quante bici da trasporto entrano in questo parcheggio per bici?", - "pt_BR": "Quantas bicicletas de carga cabem neste estacionamento de bicicletas?" - }, - "render": { - "en": "This parking fits {capacity:cargo_bike} cargo bikes", - "nl": "Deze parking heeft plaats voor {capacity:cargo_bike} fietsen", - "fr": "Ce parking a de la place pour {capacity:cargo_bike} vélos de transport", - "gl": "Neste aparcadoiro caben {capacity:cargo_bike} bicicletas de carga", - "de": "Auf diesen Parkplatz passen {capacity:cargo_bike} Lastenfahrräder", - "it": "Questo parcheggio può contenere {capacity:cargo_bike} bici da trasporto", - "pt_BR": "Neste estacionamento cabem {capacity:cargo_bike} bicicletas de carga" - }, - "condition": "cargo_bike~designated|yes", - "freeform": { - "key": "capacity:cargo_bike", - "type": "nat" - } - } - ] + ] } \ No newline at end of file diff --git a/assets/layers/bike_repair_station/bike_repair_station.json b/assets/layers/bike_repair_station/bike_repair_station.json index df372236f..226d8436c 100644 --- a/assets/layers/bike_repair_station/bike_repair_station.json +++ b/assets/layers/bike_repair_station/bike_repair_station.json @@ -1,725 +1,725 @@ { - "id": "bike_repair_station", - "name": { - "en": "Bike stations (repair, pump or both)", - "nl": "Fietspunten (herstel, pomp of allebei)", - "fr": "Station velo (réparation, pompe à vélo)", - "gl": "Estación de bicicletas (arranxo, bomba de ar ou ambos)", - "de": "Fahrradstationen (Reparatur, Pumpe oder beides)", - "it": "Stazioni bici (riparazione, gonfiaggio o entrambi)", - "pt_BR": "Estações de bicicletas (reparo, bomba ou ambos)" - }, - "minzoom": 13, - "source": { - "osmTags": { - "and": [ - "amenity=bicycle_repair_station" - ] - } - }, - "title": { - "render": { - "en": "Bike station (pump & repair)", - "nl": "Herstelpunt met pomp", - "fr": "Point station velo avec pompe", - "gl": "Estación de bicicletas (arranxo e bomba de ar)", - "de": "Fahrradstation (Pumpe & Reparatur)", - "it": "Stazione bici (gonfiaggio & riparazione)", - "pt_BR": "Estação de bicicletas (bomba e reparo)" + "id": "bike_repair_station", + "name": { + "en": "Bike stations (repair, pump or both)", + "nl": "Fietspunten (herstel, pomp of allebei)", + "fr": "Station velo (réparation, pompe à vélo)", + "gl": "Estación de bicicletas (arranxo, bomba de ar ou ambos)", + "de": "Fahrradstationen (Reparatur, Pumpe oder beides)", + "it": "Stazioni bici (riparazione, gonfiaggio o entrambi)", + "pt_BR": "Estações de bicicletas (reparo, bomba ou ambos)" }, - "mappings": [ - { - "if": { - "or": [ - "service:bicycle:pump=no", - "service:bicycle:pump:operational_status=broken" - ] - }, - "then": { - "en": "Bike repair station", - "nl": "Herstelpunt", - "fr": "Point de réparation velo", - "gl": "Estación de arranxo de bicicletas", - "de": "Fahrrad-Reparaturstation", - "it": "Stazione riparazione bici", - "pt_BR": "Estação de reparo de bicicletas" + "minzoom": 13, + "source": { + "osmTags": { + "and": [ + "amenity=bicycle_repair_station" + ] } - }, - { - "if": { - "and": [ - "service:bicycle:pump=yes", - "service:bicycle:tools=yes" - ] + }, + "title": { + "render": { + "en": "Bike station (pump & repair)", + "nl": "Herstelpunt met pomp", + "fr": "Point station velo avec pompe", + "gl": "Estación de bicicletas (arranxo e bomba de ar)", + "de": "Fahrradstation (Pumpe & Reparatur)", + "it": "Stazione bici (gonfiaggio & riparazione)", + "pt_BR": "Estação de bicicletas (bomba e reparo)" }, - "then": { - "en": "Bike repair station", - "nl": "Herstelpunt", - "fr": "Point de réparation", - "gl": "Estación de arranxo de bicicletas", - "de": "Fahrrad-Reparaturstation", - "it": "Stazione riparazione bici", - "pt_BR": "Estação de reparo de bicicletas" - } - }, - { - "if": { - "and": [ - "service:bicycle:pump:operational_status=broken", + "mappings": [ { - "or": [ - "service:bicycle:tools=no", - "service:bicycle:tools=" - ] + "if": { + "or": [ + "service:bicycle:pump=no", + "service:bicycle:pump:operational_status=broken" + ] + }, + "then": { + "en": "Bike repair station", + "nl": "Herstelpunt", + "fr": "Point de réparation velo", + "gl": "Estación de arranxo de bicicletas", + "de": "Fahrrad-Reparaturstation", + "it": "Stazione riparazione bici", + "pt_BR": "Estação de reparo de bicicletas" + } + }, + { + "if": { + "and": [ + "service:bicycle:pump=yes", + "service:bicycle:tools=yes" + ] + }, + "then": { + "en": "Bike repair station", + "nl": "Herstelpunt", + "fr": "Point de réparation", + "gl": "Estación de arranxo de bicicletas", + "de": "Fahrrad-Reparaturstation", + "it": "Stazione riparazione bici", + "pt_BR": "Estação de reparo de bicicletas" + } + }, + { + "if": { + "and": [ + "service:bicycle:pump:operational_status=broken", + { + "or": [ + "service:bicycle:tools=no", + "service:bicycle:tools=" + ] + } + ] + }, + "then": { + "en": "Broken pump", + "nl": "Kapotte fietspomp", + "fr": "Pompe cassée", + "gl": "Bomba de ar estragada", + "de": "Kaputte Pumpe", + "it": "Pompa rotta", + "ru": "Сломанный насос", + "pt_BR": "Bomba quebrada" + } + }, + { + "if": { + "and": [ + "service:bicycle:pump=yes", + "service:bicycle:tools=no", + "name~*" + ] + }, + "then": { + "en": "Bicycle pump {name}", + "nl": "Fietspomp {name}", + "fr": "Pompe de vélo {name}", + "gl": "Bomba de ar {name}", + "de": "Fahrradpumpe {name}", + "it": "Pompa per bici {name}", + "ru": "Велосипедный насос {name}", + "pt_BR": "Bomba de bicicleta {name}" + } + }, + { + "if": { + "and": [ + "service:bicycle:pump=yes", + "service:bicycle:tools=no" + ] + }, + "then": { + "en": "Bicycle pump", + "nl": "Fietspomp", + "fr": "Pompe de vélo", + "gl": "Bomba de ar", + "de": "Fahrradpumpe", + "it": "Pompa per bici", + "ru": "Велосипедный насос", + "pt_BR": "Bomba de bicicleta" + } } - ] - }, - "then": { - "en": "Broken pump", - "nl": "Kapotte fietspomp", - "fr": "Pompe cassée", - "gl": "Bomba de ar estragada", - "de": "Kaputte Pumpe", - "it": "Pompa rotta", - "ru": "Сломанный насос", - "pt_BR": "Bomba quebrada" - } - }, - { - "if": { - "and": [ - "service:bicycle:pump=yes", - "service:bicycle:tools=no", - "name~*" - ] - }, - "then": { - "en": "Bicycle pump {name}", - "nl": "Fietspomp {name}", - "fr": "Pompe de vélo {name}", - "gl": "Bomba de ar {name}", - "de": "Fahrradpumpe {name}", - "it": "Pompa per bici {name}", - "ru": "Велосипедный насос {name}", - "pt_BR": "Bomba de bicicleta {name}" - } - }, - { - "if": { - "and": [ - "service:bicycle:pump=yes", - "service:bicycle:tools=no" - ] - }, - "then": { - "en": "Bicycle pump", - "nl": "Fietspomp", - "fr": "Pompe de vélo", - "gl": "Bomba de ar", - "de": "Fahrradpumpe", - "it": "Pompa per bici", - "ru": "Велосипедный насос", - "pt_BR": "Bomba de bicicleta" - } - } - ] - }, - "titleIcons": [ - { - "render": "", - "condition": "operator=De Fietsambassade Gent", - "roaming": true - }, - "defaults" - ], - "tagRenderings": [ - "images", - { - "question": { - "en": "Which services are available at this bike station?", - "nl": "Welke functies biedt dit fietspunt?", - "fr": "Quels services sont valables à cette station vélo ?", - "gl": "Que servizos están dispoñíbeis nesta estación de bicicletas?", - "de": "Welche Einrichtungen stehen an dieser Fahrradstation zur Verfügung?", - "it": "Quali servizi sono disponibili in questa stazione per bici?", - "pt_BR": "Quais serviços estão disponíveis nesta estação de bicicletas?" - }, - "mappings": [ - { - "if": { - "and": [ - "service:bicycle:tools=no", - "service:bicycle:pump=yes" - ] - }, - "then": { - "en": "There is only a pump present", - "nl": "Er is enkel een pomp aanwezig", - "fr": "Il y a seulement une pompe", - "gl": "Só hai unha bomba de ar presente", - "de": "Es ist nur eine Pumpe vorhanden", - "it": "C’è solamente una pompa presente", - "pt_BR": "Há somente uma bomba presente" - } - }, - { - "if": { - "and": [ - "service:bicycle:tools=yes", - "service:bicycle:pump=no" - ] - }, - "then": { - "en": "There are only tools (screwdrivers, pliers...) present", - "nl": "Er is enkel gereedschap aanwezig (schroevendraaier, tang...)", - "fr": "Il y a seulement des outils (tournevis, pinces...)", - "gl": "Só hai ferramentas (desaparafusadores, alicates...) presentes", - "de": "Es sind nur Werkzeuge (Schraubenzieher, Zangen...) vorhanden", - "it": "Ci sono solo degli attrezzi (cacciaviti, pinze…) presenti", - "pt_BR": "Há somente ferramentas (chaves de fenda, alicates...) presentes" - } - }, - { - "if": { - "and": [ - "service:bicycle:tools=yes", - "service:bicycle:pump=yes" - ] - }, - "then": { - "en": "There are both tools and a pump present", - "nl": "Er is zowel een pomp als gereedschap aanwezig", - "fr": "Il y a des outils et une pompe", - "gl": "Hai ferramentas e unha bomba de ar presentes", - "de": "Es sind sowohl Werkzeuge als auch eine Pumpe vorhanden", - "it": "Ci sono sia attrezzi che pompa presenti", - "pt_BR": "Há tanto ferramentas e uma bomba presente" - } - } - ] - }, - { - "question": { - "en": "Who maintains this cycle pump?", - "nl": "Wie beheert deze fietspomp?", - "fr": "Qui maintient cette pompe à vélo ?", - "it": "Chi gestisce questa pompa per bici?", - "de": "Wer wartet diese Fahrradpumpe?", - "pt_BR": "Quem faz a manutenção desta bomba de ciclo?" - }, - "render": { - "nl": "Beheer door {operator}", - "en": "Maintained by {operator}", - "fr": "Mantenue par {operator}", - "it": "Manutenuta da {operator}", - "de": "Gewartet von {operator}", - "pt_BR": "Mantida por {operator}" - }, - "freeform": { - "key": "operator" - }, - "mappings": [ - { - "if": "operator=De Fietsambassade Gent", - "then": "De Fietsambassade Gent", - "hideInAnswer": "_country!=be" - } - ] - }, - { - "question": { - "en": "What is the email address of the maintainer?", - "nl": "Wat is het email-adres van de beheerder?" - }, - "freeform": { - "key": "email", - "type": "email" - }, - "render": "{email}" - }, - { - "question": { - "en": "What is the phone number of the maintainer?", - "nl": "Wat is het telefoonnummer van de beheerder?" - }, - "freeform": { - "key": "phone", - "type": "phone" - }, - "render": "{phone}" - }, - { - "question": { - "nl": "Wanneer is dit fietsherstelpunt open?", - "en": "When is this bicycle repair point open?", - "fr": "Quand ce point de réparation de vélo est-il ouvert ?", - "it": "Quando è aperto questo punto riparazione bici?", - "de": "Wann ist diese Fahrradreparaturstelle geöffnet?", - "ru": "Когда работает эта точка обслуживания велосипедов?" - }, - "render": "{opening_hours_table()}", - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - }, - "mappings": [ - { - "if": "opening_hours=24/7", - "then": { - "nl": "Dag en nacht open", - "en": "Always open", - "fr": "Ouvert en permanence", - "it": "Sempre aperto", - "de": "Immer geöffnet", - "ru": "Всегда открыто", - "pt_BR": "Sempre aberto" - } - }, - { - "if": "opening_hours=", - "then": { - "nl": "Dag en nacht open", - "en": "Always open", - "fr": "Ouvert en permanence", - "it": "Sempre aperto", - "de": "Immer geöffnet", - "pt_BR": "Sempre aberto" - }, - "hideInAnswer": true - } - ] - }, - { - "question": { - "en": "Does this bike repair station have a special tool to repair your bike chain?", - "nl": "Heeft dit herstelpunt een speciale reparatieset voor je ketting?", - "fr": "Est-ce que cette station vélo a un outil specifique pour réparer la chaîne du vélo ?", - "gl": "Esta estación de arranxo de bicicletas ten unha ferramenta especial para arranxar a cadea da túa bicicleta?", - "de": "Verfügt diese Fahrrad-Reparaturstation über Spezialwerkzeug zur Reparatur von Fahrradketten?", - "it": "Questa stazione di riparazione bici ha un attrezzo speciale per riparare la catena della bici?" - }, - "condition": "service:bicycle:tools=yes", - "mappings": [ - { - "if": "service:bicycle:chain_tool=yes", - "then": { - "en": "There is a chain tool", - "nl": "Er is een reparatieset voor je ketting", - "fr": "Il y a un outil pour réparer la chaine", - "gl": "Hai unha ferramenta para a cadea", - "de": "Es gibt ein Kettenwerkzeug", - "it": "È presente un utensile per riparare la catena", - "pt_BR": "Há uma ferramenta de corrente" - } - }, - { - "if": "service:bicycle:chain_tool=no", - "then": { - "en": "There is no chain tool", - "nl": "Er is geen reparatieset voor je ketting", - "fr": "Il n'y a pas d'outil pour réparer la chaine", - "gl": "Non hai unha ferramenta para a cadea", - "de": "Es gibt kein Kettenwerkzeug", - "it": "Non è presente un utensile per riparare la catena", - "pt_BR": "Não há uma ferramenta de corrente" - } - } - ] - }, - { - "question": { - "en": "Does this bike station have a hook to hang your bike on or a stand to raise it?", - "nl": "Heeft dit herstelpunt een haak of standaard om je fiets op te hangen/zetten?", - "fr": "Est-ce que cette station vélo à un crochet pour suspendre son vélo ou une accroche pour l'élevé ?", - "gl": "Esta estación de bicicletas ten un guindastre para pendurar a túa bicicleta ou un soporte para elevala?", - "de": "Hat diese Fahrradstation einen Haken, an dem Sie Ihr Fahrrad aufhängen können, oder einen Ständer, um es anzuheben?", - "it": "Questa stazione bici ha un gancio per tenere sospesa la bici o un supporto per alzarla?" - }, - "condition": "service:bicycle:tools=yes", - "mappings": [ - { - "if": "service:bicycle:stand=yes", - "then": { - "en": "There is a hook or stand", - "nl": "Er is een haak of standaard", - "fr": "Il y a un crochet ou une accroche", - "gl": "Hai un guindastre ou soporte", - "de": "Es gibt einen Haken oder Ständer", - "it": "C’è un gancio o un supporto", - "pt_BR": "Há um gancho ou um suporte" - } - }, - { - "if": "service:bicycle:stand=no", - "then": { - "en": "There is no hook or stand", - "nl": "Er is geen haak of standaard", - "fr": "Il n'y pas de crochet ou d'accroche", - "gl": "Non hai un guindastre ou soporte", - "de": "Es gibt keinen Haken oder Ständer", - "it": "Non c’è né un gancio né un supporto", - "pt_BR": "Não há um gancho ou um suporte" - } - } - ] - }, - { - "#": "Operational status", - "question": { - "en": "Is the bike pump still operational?", - "nl": "Werkt de fietspomp nog?", - "fr": "La pompe à vélo fonctionne-t-elle toujours ?", - "gl": "Segue a funcionar a bomba de ar?", - "de": "Ist die Fahrradpumpe noch funktionstüchtig?", - "it": "La pompa per bici è sempre funzionante?", - "ru": "Велосипедный насос все еще работает?", - "pl": "Czy pompka rowerowa jest nadal sprawna?" - }, - "condition": "service:bicycle:pump=yes", - "mappings": [ - { - "if": "service:bicycle:pump:operational_status=broken", - "then": { - "en": "The bike pump is broken", - "nl": "De fietspomp is kapot", - "fr": "La pompe à vélo est cassée", - "gl": "A bomba de ar está estragada", - "de": "Die Fahrradpumpe ist kaputt", - "it": "La pompa per bici è guasta", - "ru": "Велосипедный насос сломан", - "pl": "Pompka rowerowa jest zepsuta" - } - }, - { - "if": "service:bicycle:pump:operational_status=", - "then": { - "en": "The bike pump is operational", - "nl": "De fietspomp werkt nog", - "fr": "La pompe est opérationnelle", - "gl": "A bomba de ar está operativa", - "de": "Die Fahrradpumpe ist betriebsbereit", - "it": "La pompa per bici funziona", - "ru": "Велосипедный насос работает", - "pl": "Pompka rowerowa jest sprawna" - } - } - ] - }, - { - "#": "Email maintainer", - "condition": { - "and": [ - "email~*", - "service:bicycle:pump:operational_status=broken" ] - }, - "render": { - "en": "Report this bicycle pump as broken", - "nl": "Rapporteer deze fietspomp als kapot" - } }, - { - "question": { - "en": "What valves are supported?", - "nl": "Welke ventielen werken er met de pomp?", - "fr": "Quelles valves sont compatibles ?", - "gl": "Que válvulas son compatíbeis?", - "de": "Welche Ventile werden unterstützt?", - "it": "Quali valvole sono supportate?", - "pl": "Jakie zawory są obsługiwane?" - }, - "render": { - "en": "This pump supports the following valves: {valves}", - "nl": "Deze pomp werkt met de volgende ventielen: {valves}", - "fr": "Cette pompe est compatible avec les valves suivantes : {valves}", - "gl": "Esta bomba de ar admite as seguintes válvulas: {valves}", - "de": "Diese Pumpe unterstützt die folgenden Ventile: {valves}", - "it": "Questa pompa è compatibile con le seguenti valvole: {valves}", - "ru": "Этот насос поддерживает следующие клапаны: {valves}", - "pl": "Ta pompka obsługuje następujące zawory: {valves}" - }, - "freeform": { - "#addExtraTags": [ - "fixme=Freeform 'valves'-tag used: possibly a wrong value" - ], - "key": "valves" - }, - "multiAnswer": true, - "mappings": [ + "titleIcons": [ { - "if": "valves=sclaverand", - "then": { - "en": "Sclaverand (also known as Presta)", - "nl": "Sclaverand (ook gekend als Presta)", - "fr": "Sclaverand (aussi appelé Presta)", - "gl": "Sclaverand (tamén coñecido como Presta)", - "de": "Sklaverand (auch bekannt als Presta)", - "it": "Sclaverand (detta anche Presta)", - "ru": "Клапан Presta (также известный как французский клапан)" - } + "render": "", + "condition": "operator=De Fietsambassade Gent", + "roaming": true + }, + "defaults" + ], + "tagRenderings": [ + "images", + { + "question": { + "en": "Which services are available at this bike station?", + "nl": "Welke functies biedt dit fietspunt?", + "fr": "Quels services sont valables à cette station vélo ?", + "gl": "Que servizos están dispoñíbeis nesta estación de bicicletas?", + "de": "Welche Einrichtungen stehen an dieser Fahrradstation zur Verfügung?", + "it": "Quali servizi sono disponibili in questa stazione per bici?", + "pt_BR": "Quais serviços estão disponíveis nesta estação de bicicletas?" + }, + "mappings": [ + { + "if": { + "and": [ + "service:bicycle:tools=no", + "service:bicycle:pump=yes" + ] + }, + "then": { + "en": "There is only a pump present", + "nl": "Er is enkel een pomp aanwezig", + "fr": "Il y a seulement une pompe", + "gl": "Só hai unha bomba de ar presente", + "de": "Es ist nur eine Pumpe vorhanden", + "it": "C’è solamente una pompa presente", + "pt_BR": "Há somente uma bomba presente" + } + }, + { + "if": { + "and": [ + "service:bicycle:tools=yes", + "service:bicycle:pump=no" + ] + }, + "then": { + "en": "There are only tools (screwdrivers, pliers...) present", + "nl": "Er is enkel gereedschap aanwezig (schroevendraaier, tang...)", + "fr": "Il y a seulement des outils (tournevis, pinces...)", + "gl": "Só hai ferramentas (desaparafusadores, alicates...) presentes", + "de": "Es sind nur Werkzeuge (Schraubenzieher, Zangen...) vorhanden", + "it": "Ci sono solo degli attrezzi (cacciaviti, pinze…) presenti", + "pt_BR": "Há somente ferramentas (chaves de fenda, alicates...) presentes" + } + }, + { + "if": { + "and": [ + "service:bicycle:tools=yes", + "service:bicycle:pump=yes" + ] + }, + "then": { + "en": "There are both tools and a pump present", + "nl": "Er is zowel een pomp als gereedschap aanwezig", + "fr": "Il y a des outils et une pompe", + "gl": "Hai ferramentas e unha bomba de ar presentes", + "de": "Es sind sowohl Werkzeuge als auch eine Pumpe vorhanden", + "it": "Ci sono sia attrezzi che pompa presenti", + "pt_BR": "Há tanto ferramentas e uma bomba presente" + } + } + ] }, { - "if": "valves=dunlop", - "then": { - "en": "Dunlop", - "nl": "Dunlop", - "fr": "Dunlop", - "gl": "Dunlop", - "de": "Dunlop", - "it": "Dunlop", - "ru": "Клапан Dunlop" - } + "question": { + "en": "Who maintains this cycle pump?", + "nl": "Wie beheert deze fietspomp?", + "fr": "Qui maintient cette pompe à vélo ?", + "it": "Chi gestisce questa pompa per bici?", + "de": "Wer wartet diese Fahrradpumpe?", + "pt_BR": "Quem faz a manutenção desta bomba de ciclo?" + }, + "render": { + "nl": "Beheer door {operator}", + "en": "Maintained by {operator}", + "fr": "Mantenue par {operator}", + "it": "Manutenuta da {operator}", + "de": "Gewartet von {operator}", + "pt_BR": "Mantida por {operator}" + }, + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": "operator=De Fietsambassade Gent", + "then": "De Fietsambassade Gent", + "hideInAnswer": "_country!=be" + } + ] }, { - "if": "valves=schrader", - "then": { - "en": "Schrader (cars)", - "nl": "Schrader (auto's)", - "fr": "Schrader (les valves de voitures)", - "gl": "Schrader (para automóbiles)", - "de": "Schrader (Autos)", - "it": "Schrader (valvola delle auto)" - } - } - ] - }, - { - "question": { - "en": "Is this an electric bike pump?", - "nl": "Is dit een electrische fietspomp?", - "fr": "Est-ce que cette pompe est électrique ?", - "gl": "Esta é unha bomba de ar eléctrica?", - "de": "Ist dies eine elektrische Fahrradpumpe?", - "it": "Questa pompa per bici è elettrica?", - "ru": "Это электрический велосипедный насос?", - "pl": "Czy jest to elektryczna pompka do roweru?" - }, - "condition": "service:bicycle:pump=yes", - "mappings": [ - { - "if": "manual=yes", - "then": { - "en": "Manual pump", - "nl": "Manuele pomp", - "fr": "Pompe manuelle", - "gl": "Bomba de ar manual", - "de": "Manuelle Pumpe", - "it": "Pompa manuale", - "ru": "Ручной насос", - "pl": "Pompa ręczna", - "pt_BR": "Bomba manual" - } + "question": { + "en": "What is the email address of the maintainer?", + "nl": "Wat is het email-adres van de beheerder?" + }, + "freeform": { + "key": "email", + "type": "email" + }, + "render": "{email}" }, { - "if": "manual=no", - "then": { - "en": "Electrical pump", - "nl": "Electrische pomp", - "fr": "Pompe électrique", - "gl": "Bomba de ar eléctrica", - "de": "Elektrische Pumpe", - "it": "Pompa elettrica", - "ru": "Электрический насос", - "pl": "Pompka elektryczna", - "pt_BR": "Bomba elétrica" - } - } - ] - }, - { - "question": { - "en": "Does the pump have a pressure indicator or manometer?", - "nl": "Heeft deze pomp een luchtdrukmeter?", - "fr": "Est-ce que la pompe à un manomètre integré ?", - "gl": "Ten a bomba de ar un indicador de presión ou un manómetro?", - "de": "Verfügt die Pumpe über einen Druckanzeiger oder ein Manometer?", - "it": "Questa pompa ha l’indicatore della pressione o il manometro?", - "pl": "Czy pompka posiada wskaźnik ciśnienia lub manometr?" - }, - "condition": "service:bicycle:pump=yes", - "mappings": [ - { - "if": "manometer=yes", - "then": { - "en": "There is a manometer", - "nl": "Er is een luchtdrukmeter", - "fr": "Il y a un manomètre", - "gl": "Hai manómetro", - "de": "Es gibt ein Manometer", - "it": "C’è un manometro", - "ru": "Есть манометр", - "pl": "Jest manometr", - "pt_BR": "Há um manômetro" - } + "question": { + "en": "What is the phone number of the maintainer?", + "nl": "Wat is het telefoonnummer van de beheerder?" + }, + "freeform": { + "key": "phone", + "type": "phone" + }, + "render": "{phone}" }, { - "if": "manometer=no", - "then": { - "en": "There is no manometer", - "nl": "Er is geen luchtdrukmeter", - "fr": "Il n'y a pas de manomètre", - "gl": "Non hai manómetro", - "de": "Es gibt kein Manometer", - "it": "Non c’è un manometro", - "ru": "Нет манометра", - "pl": "Nie ma manometru", - "pt_BR": "Não há um manômetro" - } + "question": { + "nl": "Wanneer is dit fietsherstelpunt open?", + "en": "When is this bicycle repair point open?", + "fr": "Quand ce point de réparation de vélo est-il ouvert ?", + "it": "Quando è aperto questo punto riparazione bici?", + "de": "Wann ist diese Fahrradreparaturstelle geöffnet?", + "ru": "Когда работает эта точка обслуживания велосипедов?" + }, + "render": "{opening_hours_table()}", + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + }, + "mappings": [ + { + "if": "opening_hours=24/7", + "then": { + "nl": "Dag en nacht open", + "en": "Always open", + "fr": "Ouvert en permanence", + "it": "Sempre aperto", + "de": "Immer geöffnet", + "ru": "Всегда открыто", + "pt_BR": "Sempre aberto" + } + }, + { + "if": "opening_hours=", + "then": { + "nl": "Dag en nacht open", + "en": "Always open", + "fr": "Ouvert en permanence", + "it": "Sempre aperto", + "de": "Immer geöffnet", + "pt_BR": "Sempre aberto" + }, + "hideInAnswer": true + } + ] }, { - "if": "manometer=broken", - "then": { - "en": "There is manometer but it is broken", - "nl": "Er is een luchtdrukmeter maar die is momenteel defect", - "fr": "Il y a un manomètre mais il est cassé", - "gl": "Hai manómetro pero está estragado", - "de": "Es gibt ein Manometer, aber es ist kaputt", - "it": "C’è un manometro ma è rotto", - "ru": "Есть манометр, но он сломан", - "pl": "Jest manometr, ale jest uszkodzony", - "pt_BR": "Há um manômetro mas está quebrado" - } - } - ] - }, - "level" - ], - "icon": { - "render": { - "en": "./assets/layers/bike_repair_station/repair_station.svg", - "ru": "./assets/layers/bike_repair_station/repair_station.svg", - "it": "./assets/layers/bike_repair_station/repair_station.svg", - "fi": "./assets/layers/bike_repair_station/repair_station.svg", - "fr": "./assets/layers/bike_repair_station/repair_station.svg", - "pt_BR": "./assets/layers/bike_repair_station/repair_station.svg" - }, - "mappings": [ - { - "if": { - "and": [ - "service:bicycle:pump=no", - "service:bicycle:pump:operational_status=broken" - ] + "question": { + "en": "Does this bike repair station have a special tool to repair your bike chain?", + "nl": "Heeft dit herstelpunt een speciale reparatieset voor je ketting?", + "fr": "Est-ce que cette station vélo a un outil specifique pour réparer la chaîne du vélo ?", + "gl": "Esta estación de arranxo de bicicletas ten unha ferramenta especial para arranxar a cadea da túa bicicleta?", + "de": "Verfügt diese Fahrrad-Reparaturstation über Spezialwerkzeug zur Reparatur von Fahrradketten?", + "it": "Questa stazione di riparazione bici ha un attrezzo speciale per riparare la catena della bici?" + }, + "condition": "service:bicycle:tools=yes", + "mappings": [ + { + "if": "service:bicycle:chain_tool=yes", + "then": { + "en": "There is a chain tool", + "nl": "Er is een reparatieset voor je ketting", + "fr": "Il y a un outil pour réparer la chaine", + "gl": "Hai unha ferramenta para a cadea", + "de": "Es gibt ein Kettenwerkzeug", + "it": "È presente un utensile per riparare la catena", + "pt_BR": "Há uma ferramenta de corrente" + } + }, + { + "if": "service:bicycle:chain_tool=no", + "then": { + "en": "There is no chain tool", + "nl": "Er is geen reparatieset voor je ketting", + "fr": "Il n'y a pas d'outil pour réparer la chaine", + "gl": "Non hai unha ferramenta para a cadea", + "de": "Es gibt kein Kettenwerkzeug", + "it": "Non è presente un utensile per riparare la catena", + "pt_BR": "Não há uma ferramenta de corrente" + } + } + ] }, - "then": "./assets/layers/bike_repair_station/repair_station.svg" - }, - { - "if": { - "and": [ - "service:bicycle:pump=yes", - "service:bicycle:tools=yes" - ] + { + "question": { + "en": "Does this bike station have a hook to hang your bike on or a stand to raise it?", + "nl": "Heeft dit herstelpunt een haak of standaard om je fiets op te hangen/zetten?", + "fr": "Est-ce que cette station vélo à un crochet pour suspendre son vélo ou une accroche pour l'élevé ?", + "gl": "Esta estación de bicicletas ten un guindastre para pendurar a túa bicicleta ou un soporte para elevala?", + "de": "Hat diese Fahrradstation einen Haken, an dem Sie Ihr Fahrrad aufhängen können, oder einen Ständer, um es anzuheben?", + "it": "Questa stazione bici ha un gancio per tenere sospesa la bici o un supporto per alzarla?" + }, + "condition": "service:bicycle:tools=yes", + "mappings": [ + { + "if": "service:bicycle:stand=yes", + "then": { + "en": "There is a hook or stand", + "nl": "Er is een haak of standaard", + "fr": "Il y a un crochet ou une accroche", + "gl": "Hai un guindastre ou soporte", + "de": "Es gibt einen Haken oder Ständer", + "it": "C’è un gancio o un supporto", + "pt_BR": "Há um gancho ou um suporte" + } + }, + { + "if": "service:bicycle:stand=no", + "then": { + "en": "There is no hook or stand", + "nl": "Er is geen haak of standaard", + "fr": "Il n'y pas de crochet ou d'accroche", + "gl": "Non hai un guindastre ou soporte", + "de": "Es gibt keinen Haken oder Ständer", + "it": "Non c’è né un gancio né un supporto", + "pt_BR": "Não há um gancho ou um suporte" + } + } + ] }, - "then": "./assets/layers/bike_repair_station/repair_station_pump.svg" - }, - { - "if": { - "and": [ - "service:bicycle:pump:operational_status=broken", - "service:bicycle:tools=no" - ] + { + "#": "Operational status", + "question": { + "en": "Is the bike pump still operational?", + "nl": "Werkt de fietspomp nog?", + "fr": "La pompe à vélo fonctionne-t-elle toujours ?", + "gl": "Segue a funcionar a bomba de ar?", + "de": "Ist die Fahrradpumpe noch funktionstüchtig?", + "it": "La pompa per bici è sempre funzionante?", + "ru": "Велосипедный насос все еще работает?", + "pl": "Czy pompka rowerowa jest nadal sprawna?" + }, + "condition": "service:bicycle:pump=yes", + "mappings": [ + { + "if": "service:bicycle:pump:operational_status=broken", + "then": { + "en": "The bike pump is broken", + "nl": "De fietspomp is kapot", + "fr": "La pompe à vélo est cassée", + "gl": "A bomba de ar está estragada", + "de": "Die Fahrradpumpe ist kaputt", + "it": "La pompa per bici è guasta", + "ru": "Велосипедный насос сломан", + "pl": "Pompka rowerowa jest zepsuta" + } + }, + { + "if": "service:bicycle:pump:operational_status=", + "then": { + "en": "The bike pump is operational", + "nl": "De fietspomp werkt nog", + "fr": "La pompe est opérationnelle", + "gl": "A bomba de ar está operativa", + "de": "Die Fahrradpumpe ist betriebsbereit", + "it": "La pompa per bici funziona", + "ru": "Велосипедный насос работает", + "pl": "Pompka rowerowa jest sprawna" + } + } + ] }, - "then": "./assets/layers/bike_repair_station/broken_pump_2.svg" - }, - { - "if": { - "and": [ - "service:bicycle:pump=yes", - { - "or": [ - "service:bicycle:tools=no", - "service:bicycle:tools=" - ] + { + "#": "Email maintainer", + "condition": { + "and": [ + "email~*", + "service:bicycle:pump:operational_status=broken" + ] + }, + "render": { + "en": "Report this bicycle pump as broken", + "nl": "Rapporteer deze fietspomp als kapot" } - ] }, - "then": "./assets/layers/bike_repair_station/pump.svg" - } + { + "question": { + "en": "What valves are supported?", + "nl": "Welke ventielen werken er met de pomp?", + "fr": "Quelles valves sont compatibles ?", + "gl": "Que válvulas son compatíbeis?", + "de": "Welche Ventile werden unterstützt?", + "it": "Quali valvole sono supportate?", + "pl": "Jakie zawory są obsługiwane?" + }, + "render": { + "en": "This pump supports the following valves: {valves}", + "nl": "Deze pomp werkt met de volgende ventielen: {valves}", + "fr": "Cette pompe est compatible avec les valves suivantes : {valves}", + "gl": "Esta bomba de ar admite as seguintes válvulas: {valves}", + "de": "Diese Pumpe unterstützt die folgenden Ventile: {valves}", + "it": "Questa pompa è compatibile con le seguenti valvole: {valves}", + "ru": "Этот насос поддерживает следующие клапаны: {valves}", + "pl": "Ta pompka obsługuje następujące zawory: {valves}" + }, + "freeform": { + "#addExtraTags": [ + "fixme=Freeform 'valves'-tag used: possibly a wrong value" + ], + "key": "valves" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "valves=sclaverand", + "then": { + "en": "Sclaverand (also known as Presta)", + "nl": "Sclaverand (ook gekend als Presta)", + "fr": "Sclaverand (aussi appelé Presta)", + "gl": "Sclaverand (tamén coñecido como Presta)", + "de": "Sklaverand (auch bekannt als Presta)", + "it": "Sclaverand (detta anche Presta)", + "ru": "Клапан Presta (также известный как французский клапан)" + } + }, + { + "if": "valves=dunlop", + "then": { + "en": "Dunlop", + "nl": "Dunlop", + "fr": "Dunlop", + "gl": "Dunlop", + "de": "Dunlop", + "it": "Dunlop", + "ru": "Клапан Dunlop" + } + }, + { + "if": "valves=schrader", + "then": { + "en": "Schrader (cars)", + "nl": "Schrader (auto's)", + "fr": "Schrader (les valves de voitures)", + "gl": "Schrader (para automóbiles)", + "de": "Schrader (Autos)", + "it": "Schrader (valvola delle auto)" + } + } + ] + }, + { + "question": { + "en": "Is this an electric bike pump?", + "nl": "Is dit een electrische fietspomp?", + "fr": "Est-ce que cette pompe est électrique ?", + "gl": "Esta é unha bomba de ar eléctrica?", + "de": "Ist dies eine elektrische Fahrradpumpe?", + "it": "Questa pompa per bici è elettrica?", + "ru": "Это электрический велосипедный насос?", + "pl": "Czy jest to elektryczna pompka do roweru?" + }, + "condition": "service:bicycle:pump=yes", + "mappings": [ + { + "if": "manual=yes", + "then": { + "en": "Manual pump", + "nl": "Manuele pomp", + "fr": "Pompe manuelle", + "gl": "Bomba de ar manual", + "de": "Manuelle Pumpe", + "it": "Pompa manuale", + "ru": "Ручной насос", + "pl": "Pompa ręczna", + "pt_BR": "Bomba manual" + } + }, + { + "if": "manual=no", + "then": { + "en": "Electrical pump", + "nl": "Electrische pomp", + "fr": "Pompe électrique", + "gl": "Bomba de ar eléctrica", + "de": "Elektrische Pumpe", + "it": "Pompa elettrica", + "ru": "Электрический насос", + "pl": "Pompka elektryczna", + "pt_BR": "Bomba elétrica" + } + } + ] + }, + { + "question": { + "en": "Does the pump have a pressure indicator or manometer?", + "nl": "Heeft deze pomp een luchtdrukmeter?", + "fr": "Est-ce que la pompe à un manomètre integré ?", + "gl": "Ten a bomba de ar un indicador de presión ou un manómetro?", + "de": "Verfügt die Pumpe über einen Druckanzeiger oder ein Manometer?", + "it": "Questa pompa ha l’indicatore della pressione o il manometro?", + "pl": "Czy pompka posiada wskaźnik ciśnienia lub manometr?" + }, + "condition": "service:bicycle:pump=yes", + "mappings": [ + { + "if": "manometer=yes", + "then": { + "en": "There is a manometer", + "nl": "Er is een luchtdrukmeter", + "fr": "Il y a un manomètre", + "gl": "Hai manómetro", + "de": "Es gibt ein Manometer", + "it": "C’è un manometro", + "ru": "Есть манометр", + "pl": "Jest manometr", + "pt_BR": "Há um manômetro" + } + }, + { + "if": "manometer=no", + "then": { + "en": "There is no manometer", + "nl": "Er is geen luchtdrukmeter", + "fr": "Il n'y a pas de manomètre", + "gl": "Non hai manómetro", + "de": "Es gibt kein Manometer", + "it": "Non c’è un manometro", + "ru": "Нет манометра", + "pl": "Nie ma manometru", + "pt_BR": "Não há um manômetro" + } + }, + { + "if": "manometer=broken", + "then": { + "en": "There is manometer but it is broken", + "nl": "Er is een luchtdrukmeter maar die is momenteel defect", + "fr": "Il y a un manomètre mais il est cassé", + "gl": "Hai manómetro pero está estragado", + "de": "Es gibt ein Manometer, aber es ist kaputt", + "it": "C’è un manometro ma è rotto", + "ru": "Есть манометр, но он сломан", + "pl": "Jest manometr, ale jest uszkodzony", + "pt_BR": "Há um manômetro mas está quebrado" + } + } + ] + }, + "level" + ], + "icon": { + "render": { + "en": "./assets/layers/bike_repair_station/repair_station.svg", + "ru": "./assets/layers/bike_repair_station/repair_station.svg", + "it": "./assets/layers/bike_repair_station/repair_station.svg", + "fi": "./assets/layers/bike_repair_station/repair_station.svg", + "fr": "./assets/layers/bike_repair_station/repair_station.svg", + "pt_BR": "./assets/layers/bike_repair_station/repair_station.svg" + }, + "mappings": [ + { + "if": { + "and": [ + "service:bicycle:pump=no", + "service:bicycle:pump:operational_status=broken" + ] + }, + "then": "./assets/layers/bike_repair_station/repair_station.svg" + }, + { + "if": { + "and": [ + "service:bicycle:pump=yes", + "service:bicycle:tools=yes" + ] + }, + "then": "./assets/layers/bike_repair_station/repair_station_pump.svg" + }, + { + "if": { + "and": [ + "service:bicycle:pump:operational_status=broken", + "service:bicycle:tools=no" + ] + }, + "then": "./assets/layers/bike_repair_station/broken_pump_2.svg" + }, + { + "if": { + "and": [ + "service:bicycle:pump=yes", + { + "or": [ + "service:bicycle:tools=no", + "service:bicycle:tools=" + ] + } + ] + }, + "then": "./assets/layers/bike_repair_station/pump.svg" + } + ] + }, + "iconOverlays": [ + { + "if": "operator=De Fietsambassade Gent", + "then": "./assets/themes/cyclofix/fietsambassade_gent_logo_small.svg", + "badge": true + } + ], + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#00f" + }, + "width": { + "render": "1" + }, + "wayHandling": 2, + "presets": [ + { + "title": { + "en": "Bike pump", + "nl": "Fietspomp", + "fr": "Pompe à vélo", + "gl": "Bomba de ar", + "de": "Fahrradpumpe", + "it": "Pompa per bici", + "ru": "Велосипедный насос", + "fi": "Pyöräpumppu", + "pl": "Pompka do roweru", + "pt_BR": "Bomba de bicicleta" + }, + "tags": [ + "amenity=bicycle_repair_station", + "service:bicycle:tools=no", + "service:bicycle:pump=yes" + ], + "description": { + "en": "A device to inflate your tires on a fixed location in the public space.

Examples of bicycle pumps

", + "nl": "Een apparaat waar je je fietsbanden kan oppompen, beschikbaar in de publieke ruimte. De fietspomp in je kelder telt dus niet.

Voorbeelden

Examples of bicycle pumps

", + "it": "Un dispositivo per gonfiare le proprie gomme in un luogo fisso pubblicamente accessibile.

Esempi di pompe per biciclette

", + "fr": "Un dispositif pour gonfler vos pneus sur un emplacement fixe dans l'espace public.

Exemples de pompes à vélo

", + "de": "Ein Gerät zum Aufpumpen von Reifen an einem festen Standort im öffentlichen Raum.

Beispiele für Fahrradpumpen

", + "pl": "Urządzenie do pompowania opon w stałym miejscu w przestrzeni publicznej.

Przykłady pompek rowerowych

", + "pt_BR": "Um dispositivo para encher seus pneus em um local fixa no espaço público

Exemplos de bombas de bicicletas

" + } + }, + { + "title": { + "en": "Bike repair station and pump", + "nl": "Herstelpunt en pomp", + "fr": "Point de réparation vélo avec pompe", + "gl": "Estación de arranxo de bicicletas con bomba de ar", + "de": "Fahrrad-Reparaturstation und Pumpe", + "it": "Stazione di riparazione bici e pompa", + "pl": "Stacja naprawy rowerów i pompka" + }, + "tags": [ + "amenity=bicycle_repair_station", + "service:bicycle:tools=yes", + "service:bicycle:pump=yes" + ], + "description": { + "en": "A device with tools to repair your bike combined with a pump at a fixed location. The tools are often secured with chains against theft.

Example

", + "nl": "Een apparaat met zowel gereedschap om je fiets te herstellen, met een pomp. Deze zijn op een vastgemaakt op een plaats in de publieke ruimte, bv. aan een paal.

Voorbeeld

", + "fr": "Un dispositif avec des outils pour réparer votre vélo combiné à une pompe a un emplacement fixe. Les outils sont souvent attachés par une chaîne pour empêcher le vol.

Exemple

", + "it": "Un dispositivo con attrezzi per riparare la tua bici e una pompa in un luogo fisso. Gli attrezzi sono spesso attaccati ad una catena per prevenire il furto.

Esempio

", + "de": "Ein Gerät mit Werkzeugen zur Reparatur von Fahrrädern kombiniert mit einer Pumpe an einem festen Standort. Die Werkzeuge sind oft mit Ketten gegen Diebstahl gesichert.

Beispiel

" + } + }, + { + "title": { + "en": "Bike repair station without pump", + "nl": "Herstelpunt zonder pomp", + "fr": "Point de réparation vélo sans pompe", + "gl": "Estación de arranxo de bicicletas sin bomba de ar", + "de": "Fahrrad-Reparaturstation ohne Pumpe", + "it": "Stazione di riparazione bici senza pompa" + }, + "tags": [ + "amenity=bicycle_repair_station", + "service:bicycle:tools=yes", + "service:bicycle:pump=no" + ] + } ] - }, - "iconOverlays": [ - { - "if": "operator=De Fietsambassade Gent", - "then": "./assets/themes/cyclofix/fietsambassade_gent_logo_small.svg", - "badge": true - } - ], - "iconSize": { - "render": "50,50,bottom" - }, - "color": { - "render": "#00f" - }, - "width": { - "render": "1" - }, - "wayHandling": 2, - "presets": [ - { - "title": { - "en": "Bike pump", - "nl": "Fietspomp", - "fr": "Pompe à vélo", - "gl": "Bomba de ar", - "de": "Fahrradpumpe", - "it": "Pompa per bici", - "ru": "Велосипедный насос", - "fi": "Pyöräpumppu", - "pl": "Pompka do roweru", - "pt_BR": "Bomba de bicicleta" - }, - "tags": [ - "amenity=bicycle_repair_station", - "service:bicycle:tools=no", - "service:bicycle:pump=yes" - ], - "description": { - "en": "A device to inflate your tires on a fixed location in the public space.

Examples of bicycle pumps

", - "nl": "Een apparaat waar je je fietsbanden kan oppompen, beschikbaar in de publieke ruimte. De fietspomp in je kelder telt dus niet.

Voorbeelden

Examples of bicycle pumps

", - "it": "Un dispositivo per gonfiare le proprie gomme in un luogo fisso pubblicamente accessibile.

Esempi di pompe per biciclette

", - "fr": "Un dispositif pour gonfler vos pneus sur un emplacement fixe dans l'espace public.

Exemples de pompes à vélo

", - "de": "Ein Gerät zum Aufpumpen von Reifen an einem festen Standort im öffentlichen Raum.

Beispiele für Fahrradpumpen

", - "pl": "Urządzenie do pompowania opon w stałym miejscu w przestrzeni publicznej.

Przykłady pompek rowerowych

", - "pt_BR": "Um dispositivo para encher seus pneus em um local fixa no espaço público

Exemplos de bombas de bicicletas

" - } - }, - { - "title": { - "en": "Bike repair station and pump", - "nl": "Herstelpunt en pomp", - "fr": "Point de réparation vélo avec pompe", - "gl": "Estación de arranxo de bicicletas con bomba de ar", - "de": "Fahrrad-Reparaturstation und Pumpe", - "it": "Stazione di riparazione bici e pompa", - "pl": "Stacja naprawy rowerów i pompka" - }, - "tags": [ - "amenity=bicycle_repair_station", - "service:bicycle:tools=yes", - "service:bicycle:pump=yes" - ], - "description": { - "en": "A device with tools to repair your bike combined with a pump at a fixed location. The tools are often secured with chains against theft.

Example

", - "nl": "Een apparaat met zowel gereedschap om je fiets te herstellen, met een pomp. Deze zijn op een vastgemaakt op een plaats in de publieke ruimte, bv. aan een paal.

Voorbeeld

", - "fr": "Un dispositif avec des outils pour réparer votre vélo combiné à une pompe a un emplacement fixe. Les outils sont souvent attachés par une chaîne pour empêcher le vol.

Exemple

", - "it": "Un dispositivo con attrezzi per riparare la tua bici e una pompa in un luogo fisso. Gli attrezzi sono spesso attaccati ad una catena per prevenire il furto.

Esempio

", - "de": "Ein Gerät mit Werkzeugen zur Reparatur von Fahrrädern kombiniert mit einer Pumpe an einem festen Standort. Die Werkzeuge sind oft mit Ketten gegen Diebstahl gesichert.

Beispiel

" - } - }, - { - "title": { - "en": "Bike repair station without pump", - "nl": "Herstelpunt zonder pomp", - "fr": "Point de réparation vélo sans pompe", - "gl": "Estación de arranxo de bicicletas sin bomba de ar", - "de": "Fahrrad-Reparaturstation ohne Pumpe", - "it": "Stazione di riparazione bici senza pompa" - }, - "tags": [ - "amenity=bicycle_repair_station", - "service:bicycle:tools=yes", - "service:bicycle:pump=no" - ] - } - ] } \ No newline at end of file diff --git a/assets/layers/bike_shop/bike_shop.json b/assets/layers/bike_shop/bike_shop.json index 5d230e2ec..77d3833b1 100644 --- a/assets/layers/bike_shop/bike_shop.json +++ b/assets/layers/bike_shop/bike_shop.json @@ -1,680 +1,680 @@ { - "id": "bike_shop", - "name": { - "en": "Bike repair/shop", - "nl": "Fietszaak", - "fr": "Magasin ou réparateur de vélo", - "gl": "Tenda/arranxo de bicicletas", - "de": "Fahrradwerkstatt/geschäft", - "it": "Venditore/riparatore bici", - "ru": "Обслуживание велосипедов/магазин", - "pt_BR": "Reparo/loja de bicicletas" - }, - "minzoom": 13, - "source": { - "osmTags": { - "#": "We select all bicycle shops, sport shops (but we try to weed out non-bicycle related shops), and any shop with a bicycle related tag", - "or": [ - "shop=bicycle", - { - "#": "A bicycle rental with a network is something such as villo, bluebike, ... We don't want them", - "and": [ - "amenity=bicycle_rental", - "network=" - ] - }, - { - "#": "if sport is defined and is not bicycle, it is retrackted; if bicycle retail/repair is marked as 'no', it is retracted too.", - "##": "There will be a few false-positives with this. They will get filtered out by people marking both 'not selling bikes' and 'not repairing bikes'. Furthermore, the OSMers will add a sports-subcategory on it", - "and": [ - "shop=sports", - "service:bicycle:retail!=no", - "service:bicycle:repair!=no", - { - "or": [ - "sport=bicycle", - "sport=cycling", - "sport=" - ] - } - ] - }, - { - "#": "Any shop with any bicycle service", - "and": [ - "shop~*", - "service:bicycle:.*~~.*" - ] - } - ] - } - }, - "title": { - "render": { - "en": "Bike repair/shop", - "nl": "Fietszaak", - "fr": "Magasin ou réparateur de vélo", - "gl": "Tenda/arranxo de bicicletas", - "de": "Fahrradwerkstatt/geschäft", - "it": "Venditore/riparatore bici", - "ru": "Обслуживание велосипедов/магазин", - "pt_BR": "Reparo/loja de bicicletas" - }, - "mappings": [ - { - "if": { - "and": [ - "shop=sports" - ] - }, - "then": { - "en": "Sport gear shop {name}", - "nl": "Sportwinkel {name}", - "fr": "Magasin de sport {name}", - "it": "Negozio di articoli sportivi {name}", - "ru": "Магазин спортивного инвентаря {name}", - "de": "Sportartikelgeschäft {name}", - "pt_BR": "Loja de equipamentos esportivos {name}" - } - }, - { - "if": { - "and": [ - "shop!~.*bicycle.*", - "shop~*" - ] - }, - "then": "Other shop" - }, - { - "if": { - "and": [ - { - "or": [ - "service:bicycle:rental=yes", - "amenity=bicycle_rental" - ] - } - ] - }, - "then": { - "nl": "Fietsverhuur {name}", - "en": "Bicycle rental {name}", - "fr": "Location de vélo {name}", - "it": "Noleggio di biciclette {name}", - "ru": "Прокат велосипедов {name}", - "de": "Fahrradverleih{name}", - "pt_BR": "Aluguel de bicicletas {name}" - } - }, - { - "if": { - "and": [ - "service:bicycle:retail!~yes", - "service:bicycle:repair=yes" - ] - }, - "then": { - "en": "Bike repair {name}", - "nl": "Fietsenmaker {name}", - "fr": "Réparateur de vélo {name}", - "gl": "Arranxo de bicicletas {name}", - "de": "Fahrradwerkstatt {name}", - "it": "Riparazione biciclette {name", - "ru": "Ремонт велосипедов {name}", - "pt_BR": "Reparo de bicicletas {name}" - } - }, - { - "if": { - "and": [ - "service:bicycle:repair!~yes" - ] - }, - "then": { - "en": "Bike shop {name}", - "nl": "Fietswinkel {name}", - "fr": "Magasin de vélo {name}", - "gl": "Tenda de bicicletas {name}", - "de": "Fahrradgeschäft {name}", - "it": "Negozio di biciclette {name}", - "ru": "Магазин велосипедов {name}", - "pt_BR": "Loja de bicicletas {name}" - } - }, - { - "if": "name~*", - "then": { - "en": "Bike repair/shop {name}", - "nl": "Fietszaak {name}", - "fr": "Magasin ou réparateur de vélo {name}", - "gl": "Tenda/arranxo de bicicletas {name}", - "de": "Fahrradwerkstatt/geschäft {name}", - "it": "Venditore/riparatore bici {name}", - "pt_BR": "Loja/reparo de bicicletas {name}" - } - } - ] - }, - "titleIcons": [ - { - "render": "", - "condition": "operator=De Fietsambassade Gent" - }, - { - "condition": { - "or": [ - "service:bicycle:pump=yes", - "service:bicycle:pump=separate" - ] - }, - "render": "" - }, - { - "condition": "service:bicycle:diy=yes", - "render": "" - }, - "defaults" - ], - "description": { - "en": "A shop specifically selling bicycles or related items", - "nl": "Een winkel die hoofdzakelijk fietsen en fietstoebehoren verkoopt", - "fr": "Un magasin vendant spécifiquement des vélos ou des objets en lien", - "it": "Un negozio che vende specificatamente biciclette o articoli similari", - "ru": "Магазин, специализирующийся на продаже велосипедов или сопутствующих товаров", - "pt_BR": "Uma loja que vende especificamente bicicletas ou itens relacionados" - }, - "tagRenderings": [ - "images", - { - "condition": { - "and": [ - "shop~*", - "shop!~bicycle", - "shop!~sports" - ] - }, - "render": { - "en": "This shop is specialized in selling {shop} and does bicycle related activities", - "nl": "Deze winkel verkoopt {shop} en heeft fiets-gerelateerde activiteiten.", - "fr": "Ce magasin est spécialisé dans la vente de {shop} et a des activités liées au vélo", - "it": "Questo negozio è specializzato nella vendita di {shop} ed effettua attività relative alle biciclette", - "pt_BR": "Esta loja é especializada em vender {shop} e faz atividades relacionadas à bicicletas" - } - }, - { - "question": { - "en": "What is the name of this bicycle shop?", - "nl": "Wat is de naam van deze fietszaak?", - "fr": "Quel est le nom du magasin de vélos ?", - "gl": "Cal é o nome desta tenda de bicicletas?", - "de": "Wie heißt dieser Fahrradladen?", - "it": "Qual è il nome di questo negozio di biciclette?", - "ru": "Как называется магазин велосипедов?", - "pt_BR": "Qual o nome desta loja de bicicletas?" - }, - "render": { - "en": "This bicycle shop is called {name}", - "nl": "Deze fietszaak heet {name}", - "fr": "Ce magasin s'appelle {name}", - "gl": "Esta tenda de bicicletas chámase {name}", - "de": "Dieses Fahrradgeschäft heißt {name}", - "it": "Questo negozio di biciclette è chiamato {name}", - "ru": "Этот магазин велосипедов называется {name}", - "pt_BR": "Esta loja de bicicletas se chama {nome}" - }, - "freeform": { - "key": "name" - } - }, - { - "question": { - "en": "What is the website of {name}?", - "nl": "Wat is de website van {name}?", - "fr": "Quel est le site web de {name} ?", - "gl": "Cal é a páxina web de {name}?", - "it": "Qual è il sito web di {name}?", - "ru": "Какой сайт у {name}?", - "id": "URL {name} apa?", - "de": "Was ist die Webseite von {name}?", - "pt_BR": "Qual o website de {name}?" - }, - "render": "{website}", - "freeform": { - "key": "website", - "type": "url" - } - }, - { - "question": { - "en": "What is the phone number of {name}?", - "nl": "Wat is het telefoonnummer van {name}?", - "fr": "Quel est le numéro de téléphone de {name} ?", - "gl": "Cal é o número de teléfono de {name}?", - "it": "Qual è il numero di telefono di {name}?", - "ru": "Какой номер телефона у {name}?", - "de": "Wie lautet die Telefonnummer von {name}?", - "pt_BR": "Qual o número de telefone de {name}?" - }, - "render": "{phone}", - "freeform": { - "key": "phone", - "type": "phone" - } - }, - { - "question": { - "en": "What is the email address of {name}?", - "nl": "Wat is het email-adres van {name}?", - "fr": "Quelle est l'adresse électronique de {name} ?", - "gl": "Cal é o enderezo de correo electrónico de {name}?", - "it": "Qual è l’indirizzo email di {name}?", - "ru": "Какой адрес электронной почты у {name}?", - "de": "Wie lautet die E-Mail-Adresse von {name}?", - "pt_BR": "Qual o endereço de email de {name}?" - }, - "render": "{email}", - "freeform": { - "key": "email", - "type": "email" - } - }, - { - "render": "{opening_hours_table(opening_hours)}", - "question": "When is this shop opened?", - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - } - }, - "description", - { - "render": "Enkel voor {access}", - "freeform": { - "key": "access" - } - }, - { - "question": { - "en": "Does this shop sell bikes?", - "nl": "Verkoopt deze fietszaak fietsen?", - "fr": "Est-ce que ce magasin vend des vélos ?", - "gl": "Esta tenda vende bicicletas?", - "de": "Verkauft dieser Laden Fahrräder?", - "it": "Questo negozio vende bici?", - "ru": "Продаются ли велосипеды в этом магазине?", - "pt_BR": "Esta loja vende bicicletas?" - }, - "mappings": [ - { - "if": "service:bicycle:retail=yes", - "then": { - "en": "This shop sells bikes", - "nl": "Deze winkel verkoopt fietsen", - "fr": "Ce magasin vend des vélos", - "gl": "Esta tenda vende bicicletas", - "de": "Dieses Geschäft verkauft Fahrräder", - "it": "Questo negozio vende bici", - "ru": "В этом магазине продаются велосипеды", - "pt_BR": "Esta loja vende bicicletas" - } - }, - { - "if": "service:bicycle:retail=no", - "then": { - "en": "This shop doesn't sell bikes", - "nl": "Deze winkel verkoopt geen fietsen", - "fr": "Ce magasin ne vend pas de vélo", - "gl": "Esta tenda non vende bicicletas", - "de": "Dieses Geschäft verkauft keine Fahrräder", - "it": "Questo negozio non vende bici", - "ru": "В этом магазине не продают велосипеды", - "pt_BR": "Esta loja não vende bicicletas" - } - } - ] - }, - { - "question": { - "en": "Does this shop repair bikes?", - "nl": "Herstelt deze winkel fietsen?", - "fr": "Est-ce que ce magasin répare des vélos ?", - "gl": "Esta tenda arranxa bicicletas?", - "de": "Repariert dieses Geschäft Fahrräder?", - "it": "Questo negozio ripara bici?", - "ru": "В этом магазине ремонтируют велосипеды?", - "pt_BR": "Esta loja conserta bicicletas?" - }, - "mappings": [ - { - "if": "service:bicycle:repair=yes", - "then": { - "en": "This shop repairs bikes", - "nl": "Deze winkel herstelt fietsen", - "fr": "Ce magasin répare des vélos", - "gl": "Esta tenda arranxa bicicletas", - "de": "Dieses Geschäft repariert Fahrräder", - "it": "Questo negozio ripara bici", - "ru": "Этот магазин ремонтирует велосипеды", - "pt_BR": "Esta loja conserta bicicletas" - } - }, - { - "if": "service:bicycle:repair=no", - "then": { - "en": "This shop doesn't repair bikes", - "nl": "Deze winkel herstelt geen fietsen", - "fr": "Ce magasin ne répare pas les vélos", - "gl": "Esta tenda non arranxa bicicletas", - "de": "Dieses Geschäft repariert keine Fahrräder", - "it": "Questo negozio non ripara bici", - "ru": "Этот магазин не ремонтирует велосипеды", - "pt_BR": "Esta loja não conserta bicicletas" - } - }, - { - "if": "service:bicycle:repair=only_sold", - "then": { - "en": "This shop only repairs bikes bought here", - "nl": "Deze winkel herstelt enkel fietsen die hier werden gekocht", - "fr": "Ce magasin ne répare seulement les vélos achetés là-bas", - "gl": "Esta tenda só arranxa bicicletas mercadas aquí", - "de": "Dieses Geschäft repariert nur hier gekaufte Fahrräder", - "it": "Questo negozio ripara solo le bici che sono state acquistate qua", - "ru": "Этот магазин ремонтирует только велосипеды, купленные здесь", - "pt_BR": "Esta loja conserta bicicletas compradas aqui" - } - }, - { - "if": "service:bicycle:repair=brand", - "then": { - "en": "This shop only repairs bikes of a certain brand", - "nl": "Deze winkel herstelt enkel fietsen van een bepaald merk", - "fr": "Ce magasin ne répare seulement des marques spécifiques", - "gl": "Esta tenda só arranxa bicicletas dunha certa marca", - "de": "Dieses Geschäft repariert nur Fahrräder einer bestimmten Marke", - "it": "Questo negozio ripara solo le biciclette di una certa marca", - "ru": "В этом магазине обслуживают велосипеды определённого бренда", - "pt_BR": "Esta loja conserta bicicletas de uma certa marca" - } - } - ] - }, - { - "question": { - "en": "Does this shop rent out bikes?", - "nl": "Verhuurt deze winkel fietsen?", - "fr": "Est-ce ce magasin loue des vélos ?", - "gl": "Esta tenda aluga bicicletas?", - "de": "Vermietet dieser Laden Fahrräder?", - "it": "Questo negozio noleggia le bici?", - "ru": "Этот магазин сдает велосипеды в аренду?", - "pt_BR": "Esta loja aluga bicicletas?" - }, - "mappings": [ - { - "if": "service:bicycle:rental=yes", - "then": { - "en": "This shop rents out bikes", - "nl": "Deze winkel verhuurt fietsen", - "fr": "Ce magasin loue des vélos", - "gl": "Esta tenda aluga bicicletas", - "de": "Dieses Geschäft vermietet Fahrräder", - "it": "Questo negozio noleggia le bici", - "ru": "Этот магазин сдает велосипеды в аренду", - "pt_BR": "Esta loja aluga bicicletas" - } - }, - { - "if": "service:bicycle:rental=no", - "then": { - "en": "This shop doesn't rent out bikes", - "nl": "Deze winkel verhuurt geen fietsen", - "fr": "Ce magasin ne loue pas de vélos", - "gl": "Esta tenda non aluga bicicletas", - "de": "Dieses Geschäft vermietet keine Fahrräder", - "it": "Questo negozio non noleggia le bici", - "ru": "Этот магазин не сдает велосипеды напрокат", - "pt_BR": "Esta loja não aluga bicicletas" - } - } - ] - }, - { - "question": { - "en": "Does this shop sell second-hand bikes?", - "nl": "Verkoopt deze winkel tweedehands fietsen?", - "fr": "Est-ce ce magasin vend des vélos d'occasion ?", - "gl": "Esta tenda vende bicicletas de segunda man?", - "de": "Verkauft dieses Geschäft gebrauchte Fahrräder?", - "it": "Questo negozio vende bici usate?", - "ru": "В этом магазине продаются подержанные велосипеды?" - }, - "mappings": [ - { - "if": "service:bicycle:second_hand=yes", - "then": { - "en": "This shop sells second-hand bikes", - "nl": "Deze winkel verkoopt tweedehands fietsen", - "fr": "Ce magasin vend des vélos d'occasion", - "gl": "Esta tenda vende bicicletas de segunda man", - "de": "Dieses Geschäft verkauft gebrauchte Fahrräder", - "it": "Questo negozio vende bici usate", - "ru": "В этом магазине продаются подержанные велосипеды" - } - }, - { - "if": "service:bicycle:second_hand=no", - "then": { - "en": "This shop doesn't sell second-hand bikes", - "nl": "Deze winkel verkoopt geen tweedehands fietsen", - "fr": "Ce magasin ne vend pas de vélos d'occasion", - "gl": "Esta tenda non vende bicicletas de segunda man", - "de": "Dieses Geschäft verkauft keine gebrauchten Fahrräder", - "it": "Questo negozio non vende bici usate", - "ru": "В этом магазине не продаются подержанные велосипеды" - } - }, - { - "if": "service:bicycle:second_hand=only", - "then": { - "en": "This shop only sells second-hand bikes", - "nl": "Deze winkel verkoopt enkel tweedehands fietsen", - "fr": "Ce magasin vend seulement des vélos d'occasion", - "gl": "Esta tenda só vende bicicletas de segunda man", - "de": "Dieses Geschäft verkauft nur gebrauchte Fahrräder", - "it": "Questo negozio vende solamente bici usate", - "ru": "В этом магазине продаются только подержанные велосипеды" - } - } - ] - }, - { - "question": { - "en": "Does this shop offer a bike pump for use by anyone?", - "nl": "Biedt deze winkel een fietspomp aan voor iedereen?", - "fr": "Est-ce que ce magasin offre une pompe en accès libre ?", - "gl": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa?", - "de": "Bietet dieses Geschäft eine Fahrradpumpe zur Benutzung für alle an?", - "it": "Questo negozio offre l’uso a chiunque di una pompa per bici?", - "ru": "Предлагается ли в этом магазине велосипедный насос для всеобщего пользования?" - }, - "mappings": [ - { - "if": "service:bicycle:pump=yes", - "then": { - "en": "This shop offers a bike pump for anyone", - "nl": "Deze winkel biedt een fietspomp aan voor iedereen", - "fr": "Ce magasin offre une pompe en acces libre", - "gl": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa", - "de": "Dieses Geschäft bietet eine Fahrradpumpe für alle an", - "it": "Questo negozio offre l’uso pubblico di una pompa per bici", - "ru": "В этом магазине есть велосипедный насос для всеобщего пользования" - } - }, - { - "if": "service:bicycle:pump=no", - "then": { - "en": "This shop doesn't offer a bike pump for anyone", - "nl": "Deze winkel biedt geen fietspomp aan voor eender wie", - "fr": "Ce magasin n'offre pas de pompe en libre accès", - "gl": "Esta tenda non ofrece unha bomba de ar para uso de calquera persoa", - "de": "Dieses Geschäft bietet für niemanden eine Fahrradpumpe an", - "it": "Questo negozio non offre l’uso pubblico di una pompa per bici", - "ru": "В этом магазине нет велосипедного насоса для всеобщего пользования" - } - }, - { - "if": "service:bicycle:pump=separate", - "then": { - "en": "There is bicycle pump, it is shown as a separate point ", - "nl": "Er is een fietspomp, deze is apart aangeduid", - "fr": "Il y a une pompe à vélo, c'est indiqué comme un point séparé ", - "it": "C’è una pompa per bici, è mostrata come punto separato " - } - } - ] - }, - { - "question": { - "en": "Are there tools here to repair your own bike?", - "nl": "Biedt deze winkel gereedschap aan om je fiets zelf te herstellen?", - "fr": "Est-ce qu'il y a des outils pour réparer son vélo dans ce magasin ?", - "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta?", - "de": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?", - "it": "Sono presenti degli attrezzi per riparare la propria bici?", - "ru": "Есть ли здесь инструменты для починки собственного велосипеда?" - }, - "mappings": [ - { - "if": "service:bicycle:diy=yes", - "then": { - "en": "This shop offers tools for DIY repair", - "nl": "Deze winkel biedt gereedschap aan om je fiets zelf te herstellen", - "fr": "Ce magasin offre des outils pour réparer son vélo soi-même", - "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta", - "de": "Dieses Geschäft bietet Werkzeuge für die Heimwerkerreparatur an", - "it": "Questo negozio offre degli attrezzi per la riparazione fai-da-te" - } - }, - { - "if": "service:bicycle:diy=no", - "then": { - "en": "This shop doesn't offer tools for DIY repair", - "nl": "Deze winkel biedt geen gereedschap aan om je fiets zelf te herstellen", - "fr": "Ce magasin n'offre pas des outils pour réparer son vélo soi-même", - "gl": "Non hai ferramentas aquí para arranxar a túa propia bicicleta", - "de": "Dieses Geschäft bietet keine Werkzeuge für Heimwerkerreparaturen an", - "it": "Questo negozio non offre degli attrezzi per la riparazione fai-da-te" - } - }, - { - "if": "service:bicycle:diy=only_sold", - "then": { - "en": "Tools for DIY repair are only available if you bought/hire the bike in the shop", - "nl": "Het gereedschap aan om je fiets zelf te herstellen is enkel voor als je de fiets er kocht of huurt", - "fr": "Des outils d'auto-réparation sont disponibles uniquement si vous avez acheté ou loué le vélo dans ce magasin", - "it": "Gli attrezzi per la riparazione fai-da-te sono disponibili solamente se hai acquistato/noleggiato la bici nel negozio", - "de": "Werkzeuge für die Selbstreparatur sind nur verfügbar, wenn Sie das Fahrrad im Laden gekauft/gemietet haben", - "ru": "Инструменты для починки доступны только при покупке/аренде велосипеда в магазине" - } - } - ] - }, - { - "question": { - "en": "Are bicycles washed here?", - "nl": "Biedt deze winkel een fietsschoonmaak aan?", - "fr": "Lave-t-on les vélos ici ?", - "it": "Vengono lavate le bici qua?", - "ru": "Здесь моют велосипеды?", - "de": "Werden hier Fahrräder gewaschen?" - }, - "mappings": [ - { - "if": "service:bicycle:cleaning=yes", - "then": { - "en": "This shop cleans bicycles", - "nl": "Deze winkel biedt fietsschoonmaak aan", - "fr": "Ce magasin lave les vélos", - "it": "Questo negozio lava le biciclette", - "de": "Dieses Geschäft reinigt Fahrräder", - "ru": "В этом магазине оказываются услуги мойки/чистки велосипедов" - } - }, - { - "if": "service:bicycle:cleaning=diy", - "then": { - "en": "This shop has an installation where one can clean bicycles themselves", - "nl": "Deze winkel biedt een installatie aan om zelf je fiets schoon te maken", - "fr": "Ce magasin a une installation pour laver soi même des vélos", - "it": "Questo negozio ha una struttura dove è possibile pulire la propria bici", - "de": "Dieser Laden hat eine Anlage, in der man Fahrräder selbst reinigen kann" - } - }, - { - "if": "service:bicycle:cleaning=no", - "then": { - "en": "This shop doesn't offer bicycle cleaning", - "nl": "Deze winkel biedt geen fietsschoonmaak aan", - "fr": "Ce magasin ne fait pas le nettoyage de vélo", - "it": "Questo negozio non offre la pulizia della bicicletta", - "de": "Dieser Laden bietet keine Fahrradreinigung an", - "ru": "В этом магазине нет услуг мойки/чистки велосипедов" - } - } - ] - } - ], - "presets": [ - { - "title": { + "id": "bike_shop", + "name": { "en": "Bike repair/shop", "nl": "Fietszaak", - "fr": "Magasin et réparateur de vélo", + "fr": "Magasin ou réparateur de vélo", "gl": "Tenda/arranxo de bicicletas", "de": "Fahrradwerkstatt/geschäft", - "it": "Negozio/riparatore di bici", - "ru": "Обслуживание велосипедов/магазин" - }, - "tags": [ - "shop=bicycle" - ] - } - ], - "icon": { - "render": "./assets/layers/bike_shop/repair_shop.svg", - "mappings": [ - { - "if": "operator=De Fietsambassade Gent", - "then": "./assets/themes/cyclofix/fietsambassade_gent_logo_small.svg" - }, - { - "if": "service:bicycle:retail=yes", - "then": "./assets/layers/bike_shop/shop.svg" - } - ] - }, - "iconOverlays": [ - { - "if": "opening_hours~*", - "then": "isOpen", - "badge": true + "it": "Venditore/riparatore bici", + "ru": "Обслуживание велосипедов/магазин", + "pt_BR": "Reparo/loja de bicicletas" }, - { - "if": "service:bicycle:pump=yes", - "then": "circle:#e2783d;./assets/layers/bike_repair_station/pump.svg", - "badge": true - } - ], - "width": { - "render": "1" - }, - "iconSize": { - "render": "50,50,bottom" - }, - "color": { - "render": "#c00" - }, - "wayHandling": 2 + "minzoom": 13, + "source": { + "osmTags": { + "#": "We select all bicycle shops, sport shops (but we try to weed out non-bicycle related shops), and any shop with a bicycle related tag", + "or": [ + "shop=bicycle", + { + "#": "A bicycle rental with a network is something such as villo, bluebike, ... We don't want them", + "and": [ + "amenity=bicycle_rental", + "network=" + ] + }, + { + "#": "if sport is defined and is not bicycle, it is retrackted; if bicycle retail/repair is marked as 'no', it is retracted too.", + "##": "There will be a few false-positives with this. They will get filtered out by people marking both 'not selling bikes' and 'not repairing bikes'. Furthermore, the OSMers will add a sports-subcategory on it", + "and": [ + "shop=sports", + "service:bicycle:retail!=no", + "service:bicycle:repair!=no", + { + "or": [ + "sport=bicycle", + "sport=cycling", + "sport=" + ] + } + ] + }, + { + "#": "Any shop with any bicycle service", + "and": [ + "shop~*", + "service:bicycle:.*~~.*" + ] + } + ] + } + }, + "title": { + "render": { + "en": "Bike repair/shop", + "nl": "Fietszaak", + "fr": "Magasin ou réparateur de vélo", + "gl": "Tenda/arranxo de bicicletas", + "de": "Fahrradwerkstatt/geschäft", + "it": "Venditore/riparatore bici", + "ru": "Обслуживание велосипедов/магазин", + "pt_BR": "Reparo/loja de bicicletas" + }, + "mappings": [ + { + "if": { + "and": [ + "shop=sports" + ] + }, + "then": { + "en": "Sport gear shop {name}", + "nl": "Sportwinkel {name}", + "fr": "Magasin de sport {name}", + "it": "Negozio di articoli sportivi {name}", + "ru": "Магазин спортивного инвентаря {name}", + "de": "Sportartikelgeschäft {name}", + "pt_BR": "Loja de equipamentos esportivos {name}" + } + }, + { + "if": { + "and": [ + "shop!~.*bicycle.*", + "shop~*" + ] + }, + "then": "Other shop" + }, + { + "if": { + "and": [ + { + "or": [ + "service:bicycle:rental=yes", + "amenity=bicycle_rental" + ] + } + ] + }, + "then": { + "nl": "Fietsverhuur {name}", + "en": "Bicycle rental {name}", + "fr": "Location de vélo {name}", + "it": "Noleggio di biciclette {name}", + "ru": "Прокат велосипедов {name}", + "de": "Fahrradverleih{name}", + "pt_BR": "Aluguel de bicicletas {name}" + } + }, + { + "if": { + "and": [ + "service:bicycle:retail!~yes", + "service:bicycle:repair=yes" + ] + }, + "then": { + "en": "Bike repair {name}", + "nl": "Fietsenmaker {name}", + "fr": "Réparateur de vélo {name}", + "gl": "Arranxo de bicicletas {name}", + "de": "Fahrradwerkstatt {name}", + "it": "Riparazione biciclette {name", + "ru": "Ремонт велосипедов {name}", + "pt_BR": "Reparo de bicicletas {name}" + } + }, + { + "if": { + "and": [ + "service:bicycle:repair!~yes" + ] + }, + "then": { + "en": "Bike shop {name}", + "nl": "Fietswinkel {name}", + "fr": "Magasin de vélo {name}", + "gl": "Tenda de bicicletas {name}", + "de": "Fahrradgeschäft {name}", + "it": "Negozio di biciclette {name}", + "ru": "Магазин велосипедов {name}", + "pt_BR": "Loja de bicicletas {name}" + } + }, + { + "if": "name~*", + "then": { + "en": "Bike repair/shop {name}", + "nl": "Fietszaak {name}", + "fr": "Magasin ou réparateur de vélo {name}", + "gl": "Tenda/arranxo de bicicletas {name}", + "de": "Fahrradwerkstatt/geschäft {name}", + "it": "Venditore/riparatore bici {name}", + "pt_BR": "Loja/reparo de bicicletas {name}" + } + } + ] + }, + "titleIcons": [ + { + "render": "", + "condition": "operator=De Fietsambassade Gent" + }, + { + "condition": { + "or": [ + "service:bicycle:pump=yes", + "service:bicycle:pump=separate" + ] + }, + "render": "" + }, + { + "condition": "service:bicycle:diy=yes", + "render": "" + }, + "defaults" + ], + "description": { + "en": "A shop specifically selling bicycles or related items", + "nl": "Een winkel die hoofdzakelijk fietsen en fietstoebehoren verkoopt", + "fr": "Un magasin vendant spécifiquement des vélos ou des objets en lien", + "it": "Un negozio che vende specificatamente biciclette o articoli similari", + "ru": "Магазин, специализирующийся на продаже велосипедов или сопутствующих товаров", + "pt_BR": "Uma loja que vende especificamente bicicletas ou itens relacionados" + }, + "tagRenderings": [ + "images", + { + "condition": { + "and": [ + "shop~*", + "shop!~bicycle", + "shop!~sports" + ] + }, + "render": { + "en": "This shop is specialized in selling {shop} and does bicycle related activities", + "nl": "Deze winkel verkoopt {shop} en heeft fiets-gerelateerde activiteiten.", + "fr": "Ce magasin est spécialisé dans la vente de {shop} et a des activités liées au vélo", + "it": "Questo negozio è specializzato nella vendita di {shop} ed effettua attività relative alle biciclette", + "pt_BR": "Esta loja é especializada em vender {shop} e faz atividades relacionadas à bicicletas" + } + }, + { + "question": { + "en": "What is the name of this bicycle shop?", + "nl": "Wat is de naam van deze fietszaak?", + "fr": "Quel est le nom du magasin de vélos ?", + "gl": "Cal é o nome desta tenda de bicicletas?", + "de": "Wie heißt dieser Fahrradladen?", + "it": "Qual è il nome di questo negozio di biciclette?", + "ru": "Как называется магазин велосипедов?", + "pt_BR": "Qual o nome desta loja de bicicletas?" + }, + "render": { + "en": "This bicycle shop is called {name}", + "nl": "Deze fietszaak heet {name}", + "fr": "Ce magasin s'appelle {name}", + "gl": "Esta tenda de bicicletas chámase {name}", + "de": "Dieses Fahrradgeschäft heißt {name}", + "it": "Questo negozio di biciclette è chiamato {name}", + "ru": "Этот магазин велосипедов называется {name}", + "pt_BR": "Esta loja de bicicletas se chama {nome}" + }, + "freeform": { + "key": "name" + } + }, + { + "question": { + "en": "What is the website of {name}?", + "nl": "Wat is de website van {name}?", + "fr": "Quel est le site web de {name} ?", + "gl": "Cal é a páxina web de {name}?", + "it": "Qual è il sito web di {name}?", + "ru": "Какой сайт у {name}?", + "id": "URL {name} apa?", + "de": "Was ist die Webseite von {name}?", + "pt_BR": "Qual o website de {name}?" + }, + "render": "{website}", + "freeform": { + "key": "website", + "type": "url" + } + }, + { + "question": { + "en": "What is the phone number of {name}?", + "nl": "Wat is het telefoonnummer van {name}?", + "fr": "Quel est le numéro de téléphone de {name} ?", + "gl": "Cal é o número de teléfono de {name}?", + "it": "Qual è il numero di telefono di {name}?", + "ru": "Какой номер телефона у {name}?", + "de": "Wie lautet die Telefonnummer von {name}?", + "pt_BR": "Qual o número de telefone de {name}?" + }, + "render": "{phone}", + "freeform": { + "key": "phone", + "type": "phone" + } + }, + { + "question": { + "en": "What is the email address of {name}?", + "nl": "Wat is het email-adres van {name}?", + "fr": "Quelle est l'adresse électronique de {name} ?", + "gl": "Cal é o enderezo de correo electrónico de {name}?", + "it": "Qual è l’indirizzo email di {name}?", + "ru": "Какой адрес электронной почты у {name}?", + "de": "Wie lautet die E-Mail-Adresse von {name}?", + "pt_BR": "Qual o endereço de email de {name}?" + }, + "render": "{email}", + "freeform": { + "key": "email", + "type": "email" + } + }, + { + "render": "{opening_hours_table(opening_hours)}", + "question": "When is this shop opened?", + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + } + }, + "description", + { + "render": "Enkel voor {access}", + "freeform": { + "key": "access" + } + }, + { + "question": { + "en": "Does this shop sell bikes?", + "nl": "Verkoopt deze fietszaak fietsen?", + "fr": "Est-ce que ce magasin vend des vélos ?", + "gl": "Esta tenda vende bicicletas?", + "de": "Verkauft dieser Laden Fahrräder?", + "it": "Questo negozio vende bici?", + "ru": "Продаются ли велосипеды в этом магазине?", + "pt_BR": "Esta loja vende bicicletas?" + }, + "mappings": [ + { + "if": "service:bicycle:retail=yes", + "then": { + "en": "This shop sells bikes", + "nl": "Deze winkel verkoopt fietsen", + "fr": "Ce magasin vend des vélos", + "gl": "Esta tenda vende bicicletas", + "de": "Dieses Geschäft verkauft Fahrräder", + "it": "Questo negozio vende bici", + "ru": "В этом магазине продаются велосипеды", + "pt_BR": "Esta loja vende bicicletas" + } + }, + { + "if": "service:bicycle:retail=no", + "then": { + "en": "This shop doesn't sell bikes", + "nl": "Deze winkel verkoopt geen fietsen", + "fr": "Ce magasin ne vend pas de vélo", + "gl": "Esta tenda non vende bicicletas", + "de": "Dieses Geschäft verkauft keine Fahrräder", + "it": "Questo negozio non vende bici", + "ru": "В этом магазине не продают велосипеды", + "pt_BR": "Esta loja não vende bicicletas" + } + } + ] + }, + { + "question": { + "en": "Does this shop repair bikes?", + "nl": "Herstelt deze winkel fietsen?", + "fr": "Est-ce que ce magasin répare des vélos ?", + "gl": "Esta tenda arranxa bicicletas?", + "de": "Repariert dieses Geschäft Fahrräder?", + "it": "Questo negozio ripara bici?", + "ru": "В этом магазине ремонтируют велосипеды?", + "pt_BR": "Esta loja conserta bicicletas?" + }, + "mappings": [ + { + "if": "service:bicycle:repair=yes", + "then": { + "en": "This shop repairs bikes", + "nl": "Deze winkel herstelt fietsen", + "fr": "Ce magasin répare des vélos", + "gl": "Esta tenda arranxa bicicletas", + "de": "Dieses Geschäft repariert Fahrräder", + "it": "Questo negozio ripara bici", + "ru": "Этот магазин ремонтирует велосипеды", + "pt_BR": "Esta loja conserta bicicletas" + } + }, + { + "if": "service:bicycle:repair=no", + "then": { + "en": "This shop doesn't repair bikes", + "nl": "Deze winkel herstelt geen fietsen", + "fr": "Ce magasin ne répare pas les vélos", + "gl": "Esta tenda non arranxa bicicletas", + "de": "Dieses Geschäft repariert keine Fahrräder", + "it": "Questo negozio non ripara bici", + "ru": "Этот магазин не ремонтирует велосипеды", + "pt_BR": "Esta loja não conserta bicicletas" + } + }, + { + "if": "service:bicycle:repair=only_sold", + "then": { + "en": "This shop only repairs bikes bought here", + "nl": "Deze winkel herstelt enkel fietsen die hier werden gekocht", + "fr": "Ce magasin ne répare seulement les vélos achetés là-bas", + "gl": "Esta tenda só arranxa bicicletas mercadas aquí", + "de": "Dieses Geschäft repariert nur hier gekaufte Fahrräder", + "it": "Questo negozio ripara solo le bici che sono state acquistate qua", + "ru": "Этот магазин ремонтирует только велосипеды, купленные здесь", + "pt_BR": "Esta loja conserta bicicletas compradas aqui" + } + }, + { + "if": "service:bicycle:repair=brand", + "then": { + "en": "This shop only repairs bikes of a certain brand", + "nl": "Deze winkel herstelt enkel fietsen van een bepaald merk", + "fr": "Ce magasin ne répare seulement des marques spécifiques", + "gl": "Esta tenda só arranxa bicicletas dunha certa marca", + "de": "Dieses Geschäft repariert nur Fahrräder einer bestimmten Marke", + "it": "Questo negozio ripara solo le biciclette di una certa marca", + "ru": "В этом магазине обслуживают велосипеды определённого бренда", + "pt_BR": "Esta loja conserta bicicletas de uma certa marca" + } + } + ] + }, + { + "question": { + "en": "Does this shop rent out bikes?", + "nl": "Verhuurt deze winkel fietsen?", + "fr": "Est-ce ce magasin loue des vélos ?", + "gl": "Esta tenda aluga bicicletas?", + "de": "Vermietet dieser Laden Fahrräder?", + "it": "Questo negozio noleggia le bici?", + "ru": "Этот магазин сдает велосипеды в аренду?", + "pt_BR": "Esta loja aluga bicicletas?" + }, + "mappings": [ + { + "if": "service:bicycle:rental=yes", + "then": { + "en": "This shop rents out bikes", + "nl": "Deze winkel verhuurt fietsen", + "fr": "Ce magasin loue des vélos", + "gl": "Esta tenda aluga bicicletas", + "de": "Dieses Geschäft vermietet Fahrräder", + "it": "Questo negozio noleggia le bici", + "ru": "Этот магазин сдает велосипеды в аренду", + "pt_BR": "Esta loja aluga bicicletas" + } + }, + { + "if": "service:bicycle:rental=no", + "then": { + "en": "This shop doesn't rent out bikes", + "nl": "Deze winkel verhuurt geen fietsen", + "fr": "Ce magasin ne loue pas de vélos", + "gl": "Esta tenda non aluga bicicletas", + "de": "Dieses Geschäft vermietet keine Fahrräder", + "it": "Questo negozio non noleggia le bici", + "ru": "Этот магазин не сдает велосипеды напрокат", + "pt_BR": "Esta loja não aluga bicicletas" + } + } + ] + }, + { + "question": { + "en": "Does this shop sell second-hand bikes?", + "nl": "Verkoopt deze winkel tweedehands fietsen?", + "fr": "Est-ce ce magasin vend des vélos d'occasion ?", + "gl": "Esta tenda vende bicicletas de segunda man?", + "de": "Verkauft dieses Geschäft gebrauchte Fahrräder?", + "it": "Questo negozio vende bici usate?", + "ru": "В этом магазине продаются подержанные велосипеды?" + }, + "mappings": [ + { + "if": "service:bicycle:second_hand=yes", + "then": { + "en": "This shop sells second-hand bikes", + "nl": "Deze winkel verkoopt tweedehands fietsen", + "fr": "Ce magasin vend des vélos d'occasion", + "gl": "Esta tenda vende bicicletas de segunda man", + "de": "Dieses Geschäft verkauft gebrauchte Fahrräder", + "it": "Questo negozio vende bici usate", + "ru": "В этом магазине продаются подержанные велосипеды" + } + }, + { + "if": "service:bicycle:second_hand=no", + "then": { + "en": "This shop doesn't sell second-hand bikes", + "nl": "Deze winkel verkoopt geen tweedehands fietsen", + "fr": "Ce magasin ne vend pas de vélos d'occasion", + "gl": "Esta tenda non vende bicicletas de segunda man", + "de": "Dieses Geschäft verkauft keine gebrauchten Fahrräder", + "it": "Questo negozio non vende bici usate", + "ru": "В этом магазине не продаются подержанные велосипеды" + } + }, + { + "if": "service:bicycle:second_hand=only", + "then": { + "en": "This shop only sells second-hand bikes", + "nl": "Deze winkel verkoopt enkel tweedehands fietsen", + "fr": "Ce magasin vend seulement des vélos d'occasion", + "gl": "Esta tenda só vende bicicletas de segunda man", + "de": "Dieses Geschäft verkauft nur gebrauchte Fahrräder", + "it": "Questo negozio vende solamente bici usate", + "ru": "В этом магазине продаются только подержанные велосипеды" + } + } + ] + }, + { + "question": { + "en": "Does this shop offer a bike pump for use by anyone?", + "nl": "Biedt deze winkel een fietspomp aan voor iedereen?", + "fr": "Est-ce que ce magasin offre une pompe en accès libre ?", + "gl": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa?", + "de": "Bietet dieses Geschäft eine Fahrradpumpe zur Benutzung für alle an?", + "it": "Questo negozio offre l’uso a chiunque di una pompa per bici?", + "ru": "Предлагается ли в этом магазине велосипедный насос для всеобщего пользования?" + }, + "mappings": [ + { + "if": "service:bicycle:pump=yes", + "then": { + "en": "This shop offers a bike pump for anyone", + "nl": "Deze winkel biedt een fietspomp aan voor iedereen", + "fr": "Ce magasin offre une pompe en acces libre", + "gl": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa", + "de": "Dieses Geschäft bietet eine Fahrradpumpe für alle an", + "it": "Questo negozio offre l’uso pubblico di una pompa per bici", + "ru": "В этом магазине есть велосипедный насос для всеобщего пользования" + } + }, + { + "if": "service:bicycle:pump=no", + "then": { + "en": "This shop doesn't offer a bike pump for anyone", + "nl": "Deze winkel biedt geen fietspomp aan voor eender wie", + "fr": "Ce magasin n'offre pas de pompe en libre accès", + "gl": "Esta tenda non ofrece unha bomba de ar para uso de calquera persoa", + "de": "Dieses Geschäft bietet für niemanden eine Fahrradpumpe an", + "it": "Questo negozio non offre l’uso pubblico di una pompa per bici", + "ru": "В этом магазине нет велосипедного насоса для всеобщего пользования" + } + }, + { + "if": "service:bicycle:pump=separate", + "then": { + "en": "There is bicycle pump, it is shown as a separate point ", + "nl": "Er is een fietspomp, deze is apart aangeduid", + "fr": "Il y a une pompe à vélo, c'est indiqué comme un point séparé ", + "it": "C’è una pompa per bici, è mostrata come punto separato " + } + } + ] + }, + { + "question": { + "en": "Are there tools here to repair your own bike?", + "nl": "Biedt deze winkel gereedschap aan om je fiets zelf te herstellen?", + "fr": "Est-ce qu'il y a des outils pour réparer son vélo dans ce magasin ?", + "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta?", + "de": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?", + "it": "Sono presenti degli attrezzi per riparare la propria bici?", + "ru": "Есть ли здесь инструменты для починки собственного велосипеда?" + }, + "mappings": [ + { + "if": "service:bicycle:diy=yes", + "then": { + "en": "This shop offers tools for DIY repair", + "nl": "Deze winkel biedt gereedschap aan om je fiets zelf te herstellen", + "fr": "Ce magasin offre des outils pour réparer son vélo soi-même", + "gl": "Hai ferramentas aquí para arranxar a túa propia bicicleta", + "de": "Dieses Geschäft bietet Werkzeuge für die Heimwerkerreparatur an", + "it": "Questo negozio offre degli attrezzi per la riparazione fai-da-te" + } + }, + { + "if": "service:bicycle:diy=no", + "then": { + "en": "This shop doesn't offer tools for DIY repair", + "nl": "Deze winkel biedt geen gereedschap aan om je fiets zelf te herstellen", + "fr": "Ce magasin n'offre pas des outils pour réparer son vélo soi-même", + "gl": "Non hai ferramentas aquí para arranxar a túa propia bicicleta", + "de": "Dieses Geschäft bietet keine Werkzeuge für Heimwerkerreparaturen an", + "it": "Questo negozio non offre degli attrezzi per la riparazione fai-da-te" + } + }, + { + "if": "service:bicycle:diy=only_sold", + "then": { + "en": "Tools for DIY repair are only available if you bought/hire the bike in the shop", + "nl": "Het gereedschap aan om je fiets zelf te herstellen is enkel voor als je de fiets er kocht of huurt", + "fr": "Des outils d'auto-réparation sont disponibles uniquement si vous avez acheté ou loué le vélo dans ce magasin", + "it": "Gli attrezzi per la riparazione fai-da-te sono disponibili solamente se hai acquistato/noleggiato la bici nel negozio", + "de": "Werkzeuge für die Selbstreparatur sind nur verfügbar, wenn Sie das Fahrrad im Laden gekauft/gemietet haben", + "ru": "Инструменты для починки доступны только при покупке/аренде велосипеда в магазине" + } + } + ] + }, + { + "question": { + "en": "Are bicycles washed here?", + "nl": "Biedt deze winkel een fietsschoonmaak aan?", + "fr": "Lave-t-on les vélos ici ?", + "it": "Vengono lavate le bici qua?", + "ru": "Здесь моют велосипеды?", + "de": "Werden hier Fahrräder gewaschen?" + }, + "mappings": [ + { + "if": "service:bicycle:cleaning=yes", + "then": { + "en": "This shop cleans bicycles", + "nl": "Deze winkel biedt fietsschoonmaak aan", + "fr": "Ce magasin lave les vélos", + "it": "Questo negozio lava le biciclette", + "de": "Dieses Geschäft reinigt Fahrräder", + "ru": "В этом магазине оказываются услуги мойки/чистки велосипедов" + } + }, + { + "if": "service:bicycle:cleaning=diy", + "then": { + "en": "This shop has an installation where one can clean bicycles themselves", + "nl": "Deze winkel biedt een installatie aan om zelf je fiets schoon te maken", + "fr": "Ce magasin a une installation pour laver soi même des vélos", + "it": "Questo negozio ha una struttura dove è possibile pulire la propria bici", + "de": "Dieser Laden hat eine Anlage, in der man Fahrräder selbst reinigen kann" + } + }, + { + "if": "service:bicycle:cleaning=no", + "then": { + "en": "This shop doesn't offer bicycle cleaning", + "nl": "Deze winkel biedt geen fietsschoonmaak aan", + "fr": "Ce magasin ne fait pas le nettoyage de vélo", + "it": "Questo negozio non offre la pulizia della bicicletta", + "de": "Dieser Laden bietet keine Fahrradreinigung an", + "ru": "В этом магазине нет услуг мойки/чистки велосипедов" + } + } + ] + } + ], + "presets": [ + { + "title": { + "en": "Bike repair/shop", + "nl": "Fietszaak", + "fr": "Magasin et réparateur de vélo", + "gl": "Tenda/arranxo de bicicletas", + "de": "Fahrradwerkstatt/geschäft", + "it": "Negozio/riparatore di bici", + "ru": "Обслуживание велосипедов/магазин" + }, + "tags": [ + "shop=bicycle" + ] + } + ], + "icon": { + "render": "./assets/layers/bike_shop/repair_shop.svg", + "mappings": [ + { + "if": "operator=De Fietsambassade Gent", + "then": "./assets/themes/cyclofix/fietsambassade_gent_logo_small.svg" + }, + { + "if": "service:bicycle:retail=yes", + "then": "./assets/layers/bike_shop/shop.svg" + } + ] + }, + "iconOverlays": [ + { + "if": "opening_hours~*", + "then": "isOpen", + "badge": true + }, + { + "if": "service:bicycle:pump=yes", + "then": "circle:#e2783d;./assets/layers/bike_repair_station/pump.svg", + "badge": true + } + ], + "width": { + "render": "1" + }, + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#c00" + }, + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/bike_themed_object/bike_themed_object.json b/assets/layers/bike_themed_object/bike_themed_object.json index bae9e790e..527376742 100644 --- a/assets/layers/bike_themed_object/bike_themed_object.json +++ b/assets/layers/bike_themed_object/bike_themed_object.json @@ -1,73 +1,73 @@ { - "id": "bike_themed_object", - "name": { - "en": "Bike related object", - "nl": "Fietsgerelateerd object", - "fr": "Objet cycliste", - "de": "Mit Fahrrad zusammenhängendes Objekt", - "it": "Oggetto relativo alle bici" - }, - "minzoom": 13, - "source": { - "osmTags": { - "or": [ - "theme=bicycle", - "theme=cycling", - "sport=cycling", - "association=cycling", - "association=bicycle", - "ngo=cycling", - "ngo=bicycle", - "club=bicycle", - "club=cycling" - ] - } - }, - "title": { - "render": { - "en": "Bike related object", - "nl": "Fietsgerelateerd object", - "fr": "Objet cycliste", - "de": "Mit Fahrrad zusammenhängendes Objekt", - "it": "Oggetto relativo alle bici" + "id": "bike_themed_object", + "name": { + "en": "Bike related object", + "nl": "Fietsgerelateerd object", + "fr": "Objet cycliste", + "de": "Mit Fahrrad zusammenhängendes Objekt", + "it": "Oggetto relativo alle bici" }, - "mappings": [ - { - "if": "name~*", - "then": "{name}" - }, - { - "if": "leisure=track", - "then": { - "nl": "Wielerpiste", - "en": "Cycle track", - "fr": "Piste cyclable", - "it": "Pista ciclabile", - "de": "Radweg" + "minzoom": 13, + "source": { + "osmTags": { + "or": [ + "theme=bicycle", + "theme=cycling", + "sport=cycling", + "association=cycling", + "association=bicycle", + "ngo=cycling", + "ngo=bicycle", + "club=bicycle", + "club=cycling" + ] } - } - ] - }, - "tagRenderings": [ - "images", - "description", - "website", - "email", - "phone", - "opening_hours" - ], - "icon": { - "render": "./assets/layers/bike_themed_object/other_services.svg" - }, - "width": { - "render": "2" - }, - "iconSize": { - "render": "50,50,bottom" - }, - "color": { - "render": "#AB76D5" - }, - "presets": [], - "wayHandling": 2 + }, + "title": { + "render": { + "en": "Bike related object", + "nl": "Fietsgerelateerd object", + "fr": "Objet cycliste", + "de": "Mit Fahrrad zusammenhängendes Objekt", + "it": "Oggetto relativo alle bici" + }, + "mappings": [ + { + "if": "name~*", + "then": "{name}" + }, + { + "if": "leisure=track", + "then": { + "nl": "Wielerpiste", + "en": "Cycle track", + "fr": "Piste cyclable", + "it": "Pista ciclabile", + "de": "Radweg" + } + } + ] + }, + "tagRenderings": [ + "images", + "description", + "website", + "email", + "phone", + "opening_hours" + ], + "icon": { + "render": "./assets/layers/bike_themed_object/other_services.svg" + }, + "width": { + "render": "2" + }, + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#AB76D5" + }, + "presets": [], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/binocular/binocular.json b/assets/layers/binocular/binocular.json index 3c31bcfac..1b2573e29 100644 --- a/assets/layers/binocular/binocular.json +++ b/assets/layers/binocular/binocular.json @@ -1,102 +1,102 @@ { - "id": "binocular", - "name": { - "en": "Binoculars", - "nl": "Verrekijkers" - }, - "minzoom": 0, - "title": { - "render": { - "en": "Binoculars", - "nl": "Verrekijker" - } - }, - "description": { - "en": "Binoculas", - "nl": "Verrekijkers" - }, - "tagRenderings": [ - "images", - { - "mappings": [ - { - "if": { - "and": [ - "fee=no", - "charge=" - ] - }, - "then": { - "en": "Free to use", - "nl": "Gratis te gebruiken" - } - } - ], - "freeform": { - "key": "charge", - "addExtraTags": [ - "fee=yes" - ] - }, - "render": { - "en": "Using these binoculars costs {charge}", - "nl": "Deze verrekijker gebruiken kost {charge}" - }, - "question": { - "en": "How much does one have to pay to use these binoculars?", - "nl": "Hoeveel moet men betalen om deze verrekijker te gebruiken?" - } + "id": "binocular", + "name": { + "en": "Binoculars", + "nl": "Verrekijkers" }, - { - "question": { - "en": "When looking through this binocular, in what direction does one look?", - "nl": "Welke richting kijkt men uit als men door deze verrekijker kijkt?" - }, - "render": { - "en": "Looks towards {direction}°", - "nl": "Kijkt richting {direction}°" - }, - "freeform": { - "key": "direction", - "type": "direction" - } + "minzoom": 0, + "title": { + "render": { + "en": "Binoculars", + "nl": "Verrekijker" + } + }, + "description": { + "en": "Binoculas", + "nl": "Verrekijkers" + }, + "tagRenderings": [ + "images", + { + "mappings": [ + { + "if": { + "and": [ + "fee=no", + "charge=" + ] + }, + "then": { + "en": "Free to use", + "nl": "Gratis te gebruiken" + } + } + ], + "freeform": { + "key": "charge", + "addExtraTags": [ + "fee=yes" + ] + }, + "render": { + "en": "Using these binoculars costs {charge}", + "nl": "Deze verrekijker gebruiken kost {charge}" + }, + "question": { + "en": "How much does one have to pay to use these binoculars?", + "nl": "Hoeveel moet men betalen om deze verrekijker te gebruiken?" + } + }, + { + "question": { + "en": "When looking through this binocular, in what direction does one look?", + "nl": "Welke richting kijkt men uit als men door deze verrekijker kijkt?" + }, + "render": { + "en": "Looks towards {direction}°", + "nl": "Kijkt richting {direction}°" + }, + "freeform": { + "key": "direction", + "type": "direction" + } + } + ], + "icon": { + "render": "circle:white;./assets/layers/binocular/telescope.svg" + }, + "width": { + "render": "8" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "amenity=binoculars" + ], + "title": { + "en": "binoculars", + "nl": "verrekijker" + }, + "description": { + "en": "A telescope or pair of binoculars mounted on a pole, available to the public to look around. ", + "nl": "Een telescoop of verrekijker die op een vaste plaats gemonteerd staat waar iedereen door mag kijken. " + }, + "preciseInput": { + "preferredBackground": "photo" + } + } + ], + "source": { + "osmTags": { + "and": [ + "amenity=binoculars" + ] + } } - ], - "icon": { - "render": "circle:white;./assets/layers/binocular/telescope.svg" - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "amenity=binoculars" - ], - "title": { - "en": "binoculars", - "nl": "verrekijker" - }, - "description": { - "en": "A telescope or pair of binoculars mounted on a pole, available to the public to look around. ", - "nl": "Een telescoop of verrekijker die op een vaste plaats gemonteerd staat waar iedereen door mag kijken. " - }, - "preciseInput": { - "preferredBackground": "photo" - } - } - ], - "source": { - "osmTags": { - "and": [ - "amenity=binoculars" - ] - } - } } \ No newline at end of file diff --git a/assets/layers/birdhide/birdhide.json b/assets/layers/birdhide/birdhide.json index 50fce43cb..4e1504864 100644 --- a/assets/layers/birdhide/birdhide.json +++ b/assets/layers/birdhide/birdhide.json @@ -1,295 +1,295 @@ { - "id": "birdhide", - "name": { - "nl": "Vogelkijkhutten" - }, - "minzoom": 14, - "source": { - "osmTags": { - "and": [ - "leisure=bird_hide" - ] - } - }, - "title": { - "render": { - "nl": "Vogelkijkplaats" + "id": "birdhide", + "name": { + "nl": "Vogelkijkhutten" }, - "mappings": [ - { - "if": { - "and": [ - "name~((V|v)ogel.*).*" - ] - }, - "then": { - "nl": "{name}" + "minzoom": 14, + "source": { + "osmTags": { + "and": [ + "leisure=bird_hide" + ] } - }, - { - "if": { - "and": [ - "name~*", + }, + "title": { + "render": { + "nl": "Vogelkijkplaats" + }, + "mappings": [ { - "or": [ - "building!~no", - "shelter=yes" - ] + "if": { + "and": [ + "name~((V|v)ogel.*).*" + ] + }, + "then": { + "nl": "{name}" + } + }, + { + "if": { + "and": [ + "name~*", + { + "or": [ + "building!~no", + "shelter=yes" + ] + } + ] + }, + "then": { + "nl": "Vogelkijkhut {name}" + } + }, + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "Vogelkijkwand {name}" + } } - ] + ] + }, + "description": { + "nl": "Een vogelkijkhut" + }, + "tagRenderings": [ + "images", + { + "question": { + "nl": "Is dit een kijkwand of kijkhut?" + }, + "mappings": [ + { + "if": { + "and": [ + "shelter=no", + "building=", + "amenity=" + ] + }, + "then": { + "nl": "Vogelkijkwand" + } + }, + { + "if": { + "and": [ + "amenity=shelter", + "building=yes", + "shelter=yes" + ] + }, + "then": { + "nl": "Vogelkijkhut" + } + }, + { + "if": { + "and": [ + "building=tower", + "bird_hide=tower" + ] + }, + "then": { + "nl": "Vogelkijktoren" + } + }, + { + "if": { + "or": [ + "amenity=shelter", + "building=yes", + "shelter=yes" + ] + }, + "then": { + "nl": "Vogelkijkhut" + }, + "hideInAnswer": true + } + ] }, - "then": { - "nl": "Vogelkijkhut {name}" - } - }, - { - "if": { - "and": [ - "name~*" - ] + { + "question": { + "nl": "Is deze vogelkijkplaats rolstoeltoegankelijk?" + }, + "mappings": [ + { + "if": { + "and": [ + "wheelchair=designated" + ] + }, + "then": { + "nl": "Er zijn speciale voorzieningen voor rolstoelen" + } + }, + { + "if": { + "and": [ + "wheelchair=yes" + ] + }, + "then": { + "nl": "Een rolstoel raakt er vlot" + } + }, + { + "if": { + "and": [ + "wheelchair=limited" + ] + }, + "then": { + "nl": "Je kan er raken met een rolstoel, maar het is niet makkelijk" + } + }, + { + "if": { + "and": [ + "wheelchair=no" + ] + }, + "then": { + "nl": "Niet rolstoeltoegankelijk" + } + } + ] }, - "then": { - "nl": "Vogelkijkwand {name}" + { + "render": { + "nl": "Beheer door {operator}" + }, + "freeform": { + "key": "operator" + }, + "question": { + "nl": "Wie beheert deze vogelkijkplaats?" + }, + "mappings": [ + { + "if": "operator=Natuurpunt", + "then": { + "nl": "Beheer door Natuurpunt" + } + }, + { + "if": "operator=Agentschap Natuur en Bos", + "then": { + "nl": "Beheer door het Agentschap Natuur en Bos " + } + } + ] + } + ], + "icon": { + "render": { + "nl": "./assets/layers/birdhide/birdhide.svg" + }, + "mappings": [ + { + "if": { + "or": [ + "building=yes", + "shelter=yes", + "amenity=shelter" + ] + }, + "then": "./assets/layers/birdhide/birdshelter.svg" + } + ] + }, + "size": { + "freeform": { + "addExtraTags": [] + }, + "render": { + "nl": "40,40,center" + }, + "mappings": [] + }, + "color": { + "render": { + "nl": "#94bb28" + } + }, + "stroke": { + "render": { + "nl": "3" + } + }, + "presets": [ + { + "tags": [ + "leisure=bird_hide", + "building=yes", + "shelter=yes", + "amenity=shelter" + ], + "title": { + "nl": "Vogelkijkhut" + }, + "description": { + "nl": "Een overdekte hut waarbinnen er warm en droog naar vogels gekeken kan worden" + } + }, + { + "tags": [ + "leisure=bird_hide", + "building=no", + "shelter=no" + ], + "title": { + "nl": "Vogelkijkwand" + }, + "description": { + "nl": "Een vogelkijkwand waarachter men kan staan om vogels te kijken" + } + } + ], + "wayHandling": 1, + "filter": [ + { + "options": [ + { + "question": { + "nl": "Rolstoeltoegankelijk", + "en": "Wheelchair accessible" + }, + "osmTags": { + "or": [ + "wheelchair=yes", + "wheelchair=designated", + "wheelchair=permissive" + ] + } + } + ] + }, + { + "options": [ + { + "question": { + "nl": "Enkel overdekte kijkhutten" + }, + "osmTags": { + "and": [ + { + "or": [ + "shelter=yes", + "building~*" + ] + }, + "covered!=no" + ] + } + } + ] } - } ] - }, - "description": { - "nl": "Een vogelkijkhut" - }, - "tagRenderings": [ - "images", - { - "question": { - "nl": "Is dit een kijkwand of kijkhut?" - }, - "mappings": [ - { - "if": { - "and": [ - "shelter=no", - "building=", - "amenity=" - ] - }, - "then": { - "nl": "Vogelkijkwand" - } - }, - { - "if": { - "and": [ - "amenity=shelter", - "building=yes", - "shelter=yes" - ] - }, - "then": { - "nl": "Vogelkijkhut" - } - }, - { - "if": { - "and": [ - "building=tower", - "bird_hide=tower" - ] - }, - "then": { - "nl": "Vogelkijktoren" - } - }, - { - "if": { - "or": [ - "amenity=shelter", - "building=yes", - "shelter=yes" - ] - }, - "then": { - "nl": "Vogelkijkhut" - }, - "hideInAnswer": true - } - ] - }, - { - "question": { - "nl": "Is deze vogelkijkplaats rolstoeltoegankelijk?" - }, - "mappings": [ - { - "if": { - "and": [ - "wheelchair=designated" - ] - }, - "then": { - "nl": "Er zijn speciale voorzieningen voor rolstoelen" - } - }, - { - "if": { - "and": [ - "wheelchair=yes" - ] - }, - "then": { - "nl": "Een rolstoel raakt er vlot" - } - }, - { - "if": { - "and": [ - "wheelchair=limited" - ] - }, - "then": { - "nl": "Je kan er raken met een rolstoel, maar het is niet makkelijk" - } - }, - { - "if": { - "and": [ - "wheelchair=no" - ] - }, - "then": { - "nl": "Niet rolstoeltoegankelijk" - } - } - ] - }, - { - "render": { - "nl": "Beheer door {operator}" - }, - "freeform": { - "key": "operator" - }, - "question": { - "nl": "Wie beheert deze vogelkijkplaats?" - }, - "mappings": [ - { - "if": "operator=Natuurpunt", - "then": { - "nl": "Beheer door Natuurpunt" - } - }, - { - "if": "operator=Agentschap Natuur en Bos", - "then": { - "nl": "Beheer door het Agentschap Natuur en Bos " - } - } - ] - } - ], - "icon": { - "render": { - "nl": "./assets/layers/birdhide/birdhide.svg" - }, - "mappings": [ - { - "if": { - "or": [ - "building=yes", - "shelter=yes", - "amenity=shelter" - ] - }, - "then": "./assets/layers/birdhide/birdshelter.svg" - } - ] - }, - "size": { - "freeform": { - "addExtraTags": [] - }, - "render": { - "nl": "40,40,center" - }, - "mappings": [] - }, - "color": { - "render": { - "nl": "#94bb28" - } - }, - "stroke": { - "render": { - "nl": "3" - } - }, - "presets": [ - { - "tags": [ - "leisure=bird_hide", - "building=yes", - "shelter=yes", - "amenity=shelter" - ], - "title": { - "nl": "Vogelkijkhut" - }, - "description": { - "nl": "Een overdekte hut waarbinnen er warm en droog naar vogels gekeken kan worden" - } - }, - { - "tags": [ - "leisure=bird_hide", - "building=no", - "shelter=no" - ], - "title": { - "nl": "Vogelkijkwand" - }, - "description": { - "nl": "Een vogelkijkwand waarachter men kan staan om vogels te kijken" - } - } - ], - "wayHandling": 1, - "filter": [ - { - "options": [ - { - "question": { - "nl": "Rolstoeltoegankelijk", - "en": "Wheelchair accessible" - }, - "osmTags": { - "or": [ - "wheelchair=yes", - "wheelchair=designated", - "wheelchair=permissive" - ] - } - } - ] - }, - { - "options": [ - { - "question": { - "nl": "Enkel overdekte kijkhutten" - }, - "osmTags": { - "and": [ - { - "or": [ - "shelter=yes", - "building~*" - ] - }, - "covered!=no" - ] - } - } - ] - } - ] } \ No newline at end of file diff --git a/assets/layers/cafe_pub/cafe_pub.json b/assets/layers/cafe_pub/cafe_pub.json index be3f1d6e5..59d661966 100644 --- a/assets/layers/cafe_pub/cafe_pub.json +++ b/assets/layers/cafe_pub/cafe_pub.json @@ -1,183 +1,183 @@ { - "id": "cafe_pub", - "name": { - "nl": "Cafés", - "en": "Cafés and pubs" - }, - "source": { - "osmTags": { - "or": [ - "amenity=bar", - "amenity=pub", - "amenity=cafe", - "amenity=biergarten" - ] - } - }, - "wayHandling": 1, - "icon": { - "render": "circle:white;./assets/layers/cafe_pub/pub.svg", - "mappings": [ - { - "if": "amenity=cafe", - "then": "circle:white;./assets/layers/cafe_pub/cafe.svg" - } - ] - }, - "iconOverlays": [ - { - "if": "opening_hours~*", - "then": "isOpen", - "badge": true - } - ], - "label": { - "mappings": [ - { - "if": "name~*", - "then": "
{name}
" - } - ] - }, - "presets": [ - { - "tags": [ - "amenity=pub" - ], - "title": { - "en": "pub", - "nl": "bruin cafe of kroeg" - }, - "description": { - "nl": "Dit is een bruin café of een kroeg waar voornamelijk bier wordt gedronken. De inrichting is typisch gezellig met veel houtwerk " - }, - "preciseInput": { - "preferredBackground": "map" - } + "id": "cafe_pub", + "name": { + "nl": "Cafés", + "en": "Cafés and pubs" }, - { - "tags": [ - "amenity=bar" - ], - "title": { - "en": "bar", - "nl": "bar" - }, - "description": { - "nl": "Dit is een bar waar men ter plaatse alcoholische drank nuttigt. De inrichting is typisch modern en commercieel, soms met lichtinstallatie en feestmuziek" - }, - "preciseInput": { - "preferredBackground": "map" - } - }, - { - "tags": [ - "amenity=cafe" - ], - "title": { - "en": "cafe", - "nl": "cafe" - }, - "description": { - "nl": "Dit is een cafe - een plaats waar men rustig kan zitten om een thee, koffie of alcoholische drank te nuttigen." - }, - "preciseInput": { - "preferredBackground": "map" - } - } - ], - "title": { - "render": { - "nl": "Café" - }, - "mappings": [ - { - "if": { - "and": [ - "name~*" - ] - }, - "then": { - "nl": "{name}", - "en": "{name}" + "source": { + "osmTags": { + "or": [ + "amenity=bar", + "amenity=pub", + "amenity=cafe", + "amenity=biergarten" + ] + } + }, + "wayHandling": 1, + "icon": { + "render": "circle:white;./assets/layers/cafe_pub/pub.svg", + "mappings": [ + { + "if": "amenity=cafe", + "then": "circle:white;./assets/layers/cafe_pub/cafe.svg" + } + ] + }, + "iconOverlays": [ + { + "if": "opening_hours~*", + "then": "isOpen", + "badge": true + } + ], + "label": { + "mappings": [ + { + "if": "name~*", + "then": "
{name}
" + } + ] + }, + "presets": [ + { + "tags": [ + "amenity=pub" + ], + "title": { + "en": "pub", + "nl": "bruin cafe of kroeg" + }, + "description": { + "nl": "Dit is een bruin café of een kroeg waar voornamelijk bier wordt gedronken. De inrichting is typisch gezellig met veel houtwerk " + }, + "preciseInput": { + "preferredBackground": "map" + } + }, + { + "tags": [ + "amenity=bar" + ], + "title": { + "en": "bar", + "nl": "bar" + }, + "description": { + "nl": "Dit is een bar waar men ter plaatse alcoholische drank nuttigt. De inrichting is typisch modern en commercieel, soms met lichtinstallatie en feestmuziek" + }, + "preciseInput": { + "preferredBackground": "map" + } + }, + { + "tags": [ + "amenity=cafe" + ], + "title": { + "en": "cafe", + "nl": "cafe" + }, + "description": { + "nl": "Dit is een cafe - een plaats waar men rustig kan zitten om een thee, koffie of alcoholische drank te nuttigen." + }, + "preciseInput": { + "preferredBackground": "map" + } + } + ], + "title": { + "render": { + "nl": "Café" + }, + "mappings": [ + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "{name}", + "en": "{name}" + } + } + ] + }, + "tagRenderings": [ + "images", + { + "#": "Name", + "question": { + "nl": "Wat is de naam van dit café?", + "en": "What is the name of this pub?" + }, + "render": { + "nl": "De naam van dit café is {name}", + "en": "This pub is named {name}" + }, + "freeform": { + "key": "name" + } + }, + { + "#": "Classification", + "question": { + "en": "What kind of cafe is this", + "nl": "Welk soort café is dit?" + }, + "mappings": [ + { + "if": "amenity=pub", + "then": { + "nl": "Dit is een bruin café of een kroeg waar voornamelijk bier wordt gedronken. De inrichting is typisch gezellig met veel houtwerk " + } + }, + { + "if": "amenity=bar", + "then": { + "nl": "Dit is een bar waar men ter plaatse alcoholische drank nuttigt. De inrichting is typisch modern en commercieel, soms met lichtinstallatie en feestmuziek" + } + }, + { + "if": "amenity=cafe", + "then": { + "nl": "Dit is een cafe - een plaats waar men rustig kan zitten om een thee, koffie of alcoholische drank te nuttigen." + } + }, + { + "if": "amenity=restaurant", + "then": { + "nl": "Dit is een restaurant waar men een maaltijd geserveerd krijgt" + } + }, + { + "if": "amenity=biergarten", + "then": { + "nl": "Een open ruimte waar bier geserveerd wordt. Typisch in Duitsland" + }, + "hideInAnswer": "_country!=de" + } + ] + }, + "opening_hours", + "website", + "email", + "phone", + "payment-options", + "wheelchair-access" + ], + "filter": [ + { + "options": [ + { + "question": { + "en": "Opened now", + "nl": "Nu geopened" + }, + "osmTags": "_isOpen=yes" + } + ] } - } ] - }, - "tagRenderings": [ - "images", - { - "#": "Name", - "question": { - "nl": "Wat is de naam van dit café?", - "en": "What is the name of this pub?" - }, - "render": { - "nl": "De naam van dit café is {name}", - "en": "This pub is named {name}" - }, - "freeform": { - "key": "name" - } - }, - { - "#": "Classification", - "question": { - "en": "What kind of cafe is this", - "nl": "Welk soort café is dit?" - }, - "mappings": [ - { - "if": "amenity=pub", - "then": { - "nl": "Dit is een bruin café of een kroeg waar voornamelijk bier wordt gedronken. De inrichting is typisch gezellig met veel houtwerk " - } - }, - { - "if": "amenity=bar", - "then": { - "nl": "Dit is een bar waar men ter plaatse alcoholische drank nuttigt. De inrichting is typisch modern en commercieel, soms met lichtinstallatie en feestmuziek" - } - }, - { - "if": "amenity=cafe", - "then": { - "nl": "Dit is een cafe - een plaats waar men rustig kan zitten om een thee, koffie of alcoholische drank te nuttigen." - } - }, - { - "if": "amenity=restaurant", - "then": { - "nl": "Dit is een restaurant waar men een maaltijd geserveerd krijgt" - } - }, - { - "if": "amenity=biergarten", - "then": { - "nl": "Een open ruimte waar bier geserveerd wordt. Typisch in Duitsland" - }, - "hideInAnswer": "_country!=de" - } - ] - }, - "opening_hours", - "website", - "email", - "phone", - "payment-options", - "wheelchair-access" - ], - "filter": [ - { - "options": [ - { - "question": { - "en": "Opened now", - "nl": "Nu geopened" - }, - "osmTags": "_isOpen=yes" - } - ] - } - ] } \ No newline at end of file diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json index 3935c515f..4446049ab 100644 --- a/assets/layers/charging_station/charging_station.json +++ b/assets/layers/charging_station/charging_station.json @@ -1,2183 +1,2183 @@ { - "id": "charging_station", - "name": { - "en": "Charging stations", - "it": "Stazioni di ricarica", - "ja": "充電ステーション", - "nb_NO": "Ladestasjoner", - "ru": "Зарядные станции", - "zh_Hant": "充電站" - }, - "minzoom": 10, - "source": { - "osmTags": { - "or": [ - "amenity=charging_station", - "disused:amenity=charging_station", - "planned:amenity=charging_station", - "construction:amenity=charging_station" - ] - } - }, - "title": { - "render": { - "en": "Charging station", - "it": "Stazione di ricarica", - "ja": "充電ステーション", - "nb_NO": "Ladestasjon", - "ru": "Зарядная станция", - "zh_Hant": "充電站" - } - }, - "description": { - "en": "A charging station", - "it": "Una stazione di ricarica", - "ja": "充電ステーション", - "nb_NO": "En ladestasjon", - "ru": "Зарядная станция", - "zh_Hant": "充電站" - }, - "calculatedTags": [ - "motorcar=feat.properties.motorcar ?? feat.properties.car" - ], - "tagRenderings": [ - "images", - { - "#": "Type", - "question": { - "en": "Which vehicles are allowed to charge here?" - }, - "multiAnswer": true, - "mappings": [ - { - "if": "bicycle=yes", - "ifnot": "bicycle=no", - "then": { - "en": "bicycles can be charged here" - } - }, - { - "if": "motorcar=yes", - "extraTags": "car=", - "ifnot": { - "and": [ - "car=", - "motorcar=no" - ] - }, - "then": { - "en": "Cars can be charged here" - } - }, - { - "if": "scooter=yes", - "ifnot": "scooter=no", - "then": { - "en": "Scooters can be charged here" - } - }, - { - "if": "hgv=yes", - "ifnot": "hgv=no", - "then": { - "en": "Heavy good vehicles (such as trucks) can be charged here" - } - }, - { - "if": "bus=yes", - "ifnot": "bus=no", - "then": { - "en": "Buses can be charged here" - } - } - ] + "id": "charging_station", + "name": { + "en": "Charging stations", + "it": "Stazioni di ricarica", + "ja": "充電ステーション", + "nb_NO": "Ladestasjoner", + "ru": "Зарядные станции", + "zh_Hant": "充電站" }, - { - "question": "Who is allowed to use this charging station?", - "render": "Access is {access}", - "freeform": { - "key": "access", - "addExtraTags": [ - "fixme=Freeform field used for access - doublecheck the value" - ] - }, - "mappings": [ - { - "if": "access=yes", - "then": "Anyone can use this charging station (payment might be needed)" - }, - { - "if": { + "minzoom": 10, + "source": { + "osmTags": { "or": [ - "access=permissive", - "access=public" + "amenity=charging_station", + "disused:amenity=charging_station", + "planned:amenity=charging_station", + "construction:amenity=charging_station" ] - }, - "then": "Anyone can use this charging station (payment might be needed)", - "hideInAnswer": true - }, - { - "if": "access=customers", - "then": "Only customers of the place this station belongs to can use this charging station
E.g. a charging station operated by hotel which is only usable by their guests " - }, - { - "if": "access=private", - "then": "Not accessible to the general public (e.g. only accessible to the owners, employees, ...)" } - ] }, - { - "#": "capacity", - "render": { - "en": "{capacity} vehicles can be charged here at the same time", - "nl": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" - }, - "question": { - "en": "How much vehicles can be charged here at the same time?", - "nl": "Hoeveel voertuigen kunnen hier opgeladen worden?" - }, - "freeform": { - "key": "capacity", - "type": "pnat" - } + "title": { + "render": { + "en": "Charging station", + "it": "Stazione di ricarica", + "ja": "充電ステーション", + "nb_NO": "Ladestasjon", + "ru": "Зарядная станция", + "zh_Hant": "充電站" + } }, - { - "question": { - "en": "Which charging stations are available here?" - }, - "multiAnswer": true, - "mappings": [ + "description": { + "en": "A charging station", + "it": "Una stazione di ricarica", + "ja": "充電ステーション", + "nb_NO": "En ladestasjon", + "ru": "Зарядная станция", + "zh_Hant": "充電站" + }, + "calculatedTags": [ + "motorcar=feat.properties.motorcar ?? feat.properties.car" + ], + "tagRenderings": [ + "images", { - "if": "socket:schuko=1", - "ifnot": "socket:schuko=", - "then": { - "en": " Schuko wall plug without ground pin (CEE7/4 type F)", - "nl": " Schuko stekker zonder aardingspin (CEE7/4 type F)" - } - }, - { - "if": { - "and": [ - "socket:schuko~*", - "socket:schuko!=1" + "#": "Type", + "question": { + "en": "Which vehicles are allowed to charge here?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "bicycle=yes", + "ifnot": "bicycle=no", + "then": { + "en": "bicycles can be charged here" + } + }, + { + "if": "motorcar=yes", + "extraTags": "car=", + "ifnot": { + "and": [ + "car=", + "motorcar=no" + ] + }, + "then": { + "en": "Cars can be charged here" + } + }, + { + "if": "scooter=yes", + "ifnot": "scooter=no", + "then": { + "en": "Scooters can be charged here" + } + }, + { + "if": "hgv=yes", + "ifnot": "hgv=no", + "then": { + "en": "Heavy good vehicles (such as trucks) can be charged here" + } + }, + { + "if": "bus=yes", + "ifnot": "bus=no", + "then": { + "en": "Buses can be charged here" + } + } ] - }, - "then": { - "en": " Schuko wall plug without ground pin (CEE7/4 type F)", - "nl": " Schuko stekker zonder aardingspin (CEE7/4 type F)" - }, - "hideInAnswer": true }, { - "if": "socket:typee=1", - "ifnot": "socket:typee=", - "then": { - "en": " European wall plug with ground pin (CEE7/4 type E)", - "nl": " Europese stekker met aardingspin (CEE7/4 type E)" - } - }, - { - "if": { - "and": [ - "socket:typee~*", - "socket:typee!=1" + "question": "Who is allowed to use this charging station?", + "render": "Access is {access}", + "freeform": { + "key": "access", + "addExtraTags": [ + "fixme=Freeform field used for access - doublecheck the value" + ] + }, + "mappings": [ + { + "if": "access=yes", + "then": "Anyone can use this charging station (payment might be needed)" + }, + { + "if": { + "or": [ + "access=permissive", + "access=public" + ] + }, + "then": "Anyone can use this charging station (payment might be needed)", + "hideInAnswer": true + }, + { + "if": "access=customers", + "then": "Only customers of the place this station belongs to can use this charging station
E.g. a charging station operated by hotel which is only usable by their guests " + }, + { + "if": "access=private", + "then": "Not accessible to the general public (e.g. only accessible to the owners, employees, ...)" + } ] - }, - "then": { - "en": " European wall plug with ground pin (CEE7/4 type E)", - "nl": " Europese stekker met aardingspin (CEE7/4 type E)" - }, - "hideInAnswer": true }, { - "if": "socket:chademo=1", - "ifnot": "socket:chademo=", - "then": { - "en": " Chademo", - "nl": " " - } - }, - { - "if": { - "and": [ - "socket:chademo~*", - "socket:chademo!=1" - ] - }, - "then": { - "en": " Chademo", - "nl": " " - }, - "hideInAnswer": true - }, - { - "if": "socket:type1_cable=1", - "ifnot": "socket:type1_cable=", - "then": { - "en": " Type 1 with cable (J1772)", - "nl": " Type 1 met kabel (J1772)" - } - }, - { - "if": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=1" - ] - }, - "then": { - "en": " Type 1 with cable (J1772)", - "nl": " Type 1 met kabel (J1772)" - }, - "hideInAnswer": true - }, - { - "if": "socket:type1=1", - "ifnot": "socket:type1=", - "then": { - "en": " Type 1 without cable (J1772)", - "nl": " Type 1 zonder kabel (J1772)" - } - }, - { - "if": { - "and": [ - "socket:type1~*", - "socket:type1!=1" - ] - }, - "then": { - "en": " Type 1 without cable (J1772)", - "nl": " Type 1 zonder kabel (J1772)" - }, - "hideInAnswer": true - }, - { - "if": "socket:type1_combo=1", - "ifnot": "socket:type1_combo=", - "then": { - "en": " Type 1 CCS (aka Type 1 Combo)", - "nl": " " - } - }, - { - "if": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=1" - ] - }, - "then": { - "en": " Type 1 CCS (aka Type 1 Combo)", - "nl": " " - }, - "hideInAnswer": true - }, - { - "if": "socket:tesla_supercharger=1", - "ifnot": "socket:tesla_supercharger=", - "then": { - "en": " Tesla Supercharger", - "nl": " " - } - }, - { - "if": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=1" - ] - }, - "then": { - "en": " Tesla Supercharger", - "nl": " " - }, - "hideInAnswer": true - }, - { - "if": "socket:type2=1", - "ifnot": "socket:type2=", - "then": { - "en": " Type 2 (mennekes)", - "nl": " " - } - }, - { - "if": { - "and": [ - "socket:type2~*", - "socket:type2!=1" - ] - }, - "then": { - "en": " Type 2 (mennekes)", - "nl": " " - }, - "hideInAnswer": true - }, - { - "if": "socket:type2_combo=1", - "ifnot": "socket:type2_combo=", - "then": { - "en": " Type 2 CCS (mennekes)", - "nl": " " - } - }, - { - "if": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=1" - ] - }, - "then": { - "en": " Type 2 CCS (mennekes)", - "nl": " " - }, - "hideInAnswer": true - } - ] - }, - { - "question": { - "en": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", - "nl": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here", - "nl": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" - }, - "freeform": { - "key": "socket:schuko", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "nl": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) " - }, - "render": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" - }, - "freeform": { - "key": "socket:schuko:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:schuko:voltage=230 V", - "then": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" - } - } - ], - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "nl": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" - }, - "render": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:current}A", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" - }, - "freeform": { - "key": "socket:schuko:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:schuko:current=16 A", - "then": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" - } - } - ], - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" - }, - "render": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" - }, - "freeform": { - "key": "socket:schuko:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:schuko:output=3.6 kw", - "then": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" - } - } - ], - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", - "nl": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?" - }, - "render": { - "en": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here", - "nl": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" - }, - "freeform": { - "key": "socket:typee", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "nl": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) " - }, - "render": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" - }, - "freeform": { - "key": "socket:typee:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:typee:voltage=230 V", - "then": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" - } - } - ], - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "nl": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" - }, - "render": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" - }, - "freeform": { - "key": "socket:typee:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:typee:current=16 A", - "then": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" - } - } - ], - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" - }, - "render": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" - }, - "freeform": { - "key": "socket:typee:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:typee:output=3 kw", - "then": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" - } - }, - { - "if": "socket:socket:typee:output=22 kw", - "then": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" - } - } - ], - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Chademo are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Chademo plugs of type Chademo available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:chademo", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Chademo offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Chademo outputs {socket:chademo:voltage} volt", - "nl": " heeft een spanning van {socket:chademo:voltage} volt" - }, - "freeform": { - "key": "socket:chademo:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:chademo:voltage=500 V", - "then": { - "en": "Chademo outputs 500 volt", - "nl": " heeft een spanning van 500 volt" - } - } - ], - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Chademo offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Chademo outputs at most {socket:chademo:current}A", - "nl": " levert een stroom van maximaal {socket:chademo:current}A" - }, - "freeform": { - "key": "socket:chademo:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:chademo:current=120 A", - "then": { - "en": "Chademo outputs at most 120 A", - "nl": " levert een stroom van maximaal 120 A" - } - } - ], - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Chademo offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Chademo outputs at most {socket:chademo:output}", - "nl": " levert een vermogen van maximaal {socket:chademo:output}" - }, - "freeform": { - "key": "socket:chademo:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:chademo:output=50 kw", - "then": { - "en": "Chademo outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" - } - } - ], - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Type 1 with cable (J1772) are available here?", - "nl": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here", - "nl": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" - }, - "freeform": { - "key": "socket:type1_cable", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Type 1 with cable (J1772) offer?", - "nl": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) " - }, - "render": { - "en": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt", - "nl": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" - }, - "freeform": { - "key": "socket:type1_cable:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_cable:voltage=200 V", - "then": { - "en": "Type 1 with cable (J1772) outputs 200 volt", - "nl": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" - } - }, - { - "if": "socket:socket:type1_cable:voltage=240 V", - "then": { - "en": "Type 1 with cable (J1772) outputs 240 volt", - "nl": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" - } - } - ], - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Type 1 with cable (J1772) offer?", - "nl": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?" - }, - "render": { - "en": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A", - "nl": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" - }, - "freeform": { - "key": "socket:type1_cable:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_cable:current=32 A", - "then": { - "en": "Type 1 with cable (J1772) outputs at most 32 A", - "nl": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Type 1 with cable (J1772) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?" - }, - "render": { - "en": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}", - "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" - }, - "freeform": { - "key": "socket:type1_cable:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_cable:output=3.7 kw", - "then": { - "en": "Type 1 with cable (J1772) outputs at most 3.7 kw", - "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" - } - }, - { - "if": "socket:socket:type1_cable:output=7 kw", - "then": { - "en": "Type 1 with cable (J1772) outputs at most 7 kw", - "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" - } - } - ], - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Type 1 without cable (J1772) are available here?", - "nl": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here", - "nl": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" - }, - "freeform": { - "key": "socket:type1", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Type 1 without cable (J1772) offer?", - "nl": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) " - }, - "render": { - "en": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt", - "nl": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" - }, - "freeform": { - "key": "socket:type1:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1:voltage=200 V", - "then": { - "en": "Type 1 without cable (J1772) outputs 200 volt", - "nl": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" - } - }, - { - "if": "socket:socket:type1:voltage=240 V", - "then": { - "en": "Type 1 without cable (J1772) outputs 240 volt", - "nl": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" - } - } - ], - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Type 1 without cable (J1772) offer?", - "nl": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?" - }, - "render": { - "en": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A", - "nl": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" - }, - "freeform": { - "key": "socket:type1:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1:current=32 A", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 32 A", - "nl": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Type 1 without cable (J1772) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?" - }, - "render": { - "en": "Type 1 without cable (J1772) outputs at most {socket:type1:output}", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" - }, - "freeform": { - "key": "socket:type1:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1:output=3.7 kw", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 3.7 kw", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" - } - }, - { - "if": "socket:socket:type1:output=6.6 kw", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 6.6 kw", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" - } - }, - { - "if": "socket:socket:type1:output=7 kw", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 7 kw", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" - } - }, - { - "if": "socket:socket:type1:output=7.2 kw", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 7.2 kw", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" - } - } - ], - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:type1_combo", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt", - "nl": " heeft een spanning van {socket:type1_combo:voltage} volt" - }, - "freeform": { - "key": "socket:type1_combo:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_combo:voltage=400 V", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt", - "nl": " heeft een spanning van 400 volt" - } - }, - { - "if": "socket:socket:type1_combo:voltage=1000 V", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt", - "nl": " heeft een spanning van 1000 volt" - } - } - ], - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A", - "nl": " levert een stroom van maximaal {socket:type1_combo:current}A" - }, - "freeform": { - "key": "socket:type1_combo:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_combo:current=50 A", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A", - "nl": " levert een stroom van maximaal 50 A" - } - }, - { - "if": "socket:socket:type1_combo:current=125 A", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" - } - } - ], - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}", - "nl": " levert een vermogen van maximaal {socket:type1_combo:output}" - }, - "freeform": { - "key": "socket:type1_combo:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_combo:output=50 kw", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" - } - }, - { - "if": "socket:socket:type1_combo:output=62.5 kw", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw", - "nl": " levert een vermogen van maximaal 62.5 kw" - } - }, - { - "if": "socket:socket:type1_combo:output=150 kw", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw", - "nl": " levert een vermogen van maximaal 150 kw" - } - }, - { - "if": "socket:socket:type1_combo:output=350 kw", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw", - "nl": " levert een vermogen van maximaal 350 kw" - } - } - ], - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Tesla Supercharger are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Tesla Supercharger plugs of type Tesla Supercharger available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:tesla_supercharger", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Tesla Supercharger offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt", - "nl": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" - }, - "freeform": { - "key": "socket:tesla_supercharger:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger:voltage=480 V", - "then": { - "en": "Tesla Supercharger outputs 480 volt", - "nl": " heeft een spanning van 480 volt" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Tesla Supercharger offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A", - "nl": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" - }, - "freeform": { - "key": "socket:tesla_supercharger:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger:current=125 A", - "then": { - "en": "Tesla Supercharger outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" - } - }, - { - "if": "socket:socket:tesla_supercharger:current=350 A", - "then": { - "en": "Tesla Supercharger outputs at most 350 A", - "nl": " levert een stroom van maximaal 350 A" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Tesla Supercharger offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}", - "nl": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" - }, - "freeform": { - "key": "socket:tesla_supercharger:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger:output=120 kw", - "then": { - "en": "Tesla Supercharger outputs at most 120 kw", - "nl": " levert een vermogen van maximaal 120 kw" - } - }, - { - "if": "socket:socket:tesla_supercharger:output=150 kw", - "then": { - "en": "Tesla Supercharger outputs at most 150 kw", - "nl": " levert een vermogen van maximaal 150 kw" - } - }, - { - "if": "socket:socket:tesla_supercharger:output=250 kw", - "then": { - "en": "Tesla Supercharger outputs at most 250 kw", - "nl": " levert een vermogen van maximaal 250 kw" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Type 2 (mennekes) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:type2", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Type 2 (mennekes) offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Type 2 (mennekes) outputs {socket:type2:voltage} volt", - "nl": " heeft een spanning van {socket:type2:voltage} volt" - }, - "freeform": { - "key": "socket:type2:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2:voltage=230 V", - "then": { - "en": "Type 2 (mennekes) outputs 230 volt", - "nl": " heeft een spanning van 230 volt" - } - }, - { - "if": "socket:socket:type2:voltage=400 V", - "then": { - "en": "Type 2 (mennekes) outputs 400 volt", - "nl": " heeft een spanning van 400 volt" - } - } - ], - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Type 2 (mennekes) offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Type 2 (mennekes) outputs at most {socket:type2:current}A", - "nl": " levert een stroom van maximaal {socket:type2:current}A" - }, - "freeform": { - "key": "socket:type2:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2:current=16 A", - "then": { - "en": "Type 2 (mennekes) outputs at most 16 A", - "nl": " levert een stroom van maximaal 16 A" - } - }, - { - "if": "socket:socket:type2:current=32 A", - "then": { - "en": "Type 2 (mennekes) outputs at most 32 A", - "nl": " levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Type 2 (mennekes) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Type 2 (mennekes) outputs at most {socket:type2:output}", - "nl": " levert een vermogen van maximaal {socket:type2:output}" - }, - "freeform": { - "key": "socket:type2:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2:output=11 kw", - "then": { - "en": "Type 2 (mennekes) outputs at most 11 kw", - "nl": " levert een vermogen van maximaal 11 kw" - } - }, - { - "if": "socket:socket:type2:output=22 kw", - "then": { - "en": "Type 2 (mennekes) outputs at most 22 kw", - "nl": " levert een vermogen van maximaal 22 kw" - } - } - ], - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "question": { - "en": "How much plugs of type Type 2 CCS (mennekes) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:type2_combo", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "question": { - "en": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt", - "nl": " heeft een spanning van {socket:type2_combo:voltage} volt" - }, - "freeform": { - "key": "socket:type2_combo:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_combo:voltage=500 V", - "then": { - "en": "Type 2 CCS (mennekes) outputs 500 volt", - "nl": " heeft een spanning van 500 volt" - } - }, - { - "if": "socket:socket:type2_combo:voltage=920 V", - "then": { - "en": "Type 2 CCS (mennekes) outputs 920 volt", - "nl": " heeft een spanning van 920 volt" - } - } - ], - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "question": { - "en": "What current do the plugs with Type 2 CCS (mennekes) offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A", - "nl": " levert een stroom van maximaal {socket:type2_combo:current}A" - }, - "freeform": { - "key": "socket:type2_combo:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_combo:current=125 A", - "then": { - "en": "Type 2 CCS (mennekes) outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" - } - }, - { - "if": "socket:socket:type2_combo:current=350 A", - "then": { - "en": "Type 2 CCS (mennekes) outputs at most 350 A", - "nl": " levert een stroom van maximaal 350 A" - } - } - ], - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "question": { - "en": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}", - "nl": " levert een vermogen van maximaal {socket:type2_combo:output}" - }, - "freeform": { - "key": "socket:type2_combo:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_combo:output=50 kw", - "then": { - "en": "Type 2 CCS (mennekes) outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" - } - } - ], - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "#": "Authentication", - "question": { - "en": "What kind of authentication is available at the charging station?", - "it": "Quali sono gli orari di apertura di questa stazione di ricarica?", - "ja": "この充電ステーションはいつオープンしますか?", - "nb_NO": "Når åpnet denne ladestasjonen?", - "ru": "В какое время работает эта зарядная станция?", - "zh_Hant": "何時是充電站開放使用的時間?" - }, - "multiAnswer": true, - "mappings": [ - { - "if": "authentication:membership_card=yes", - "ifnot": "authentication:membership_card=no", - "then": { - "en": "Authentication by a membership card" - } - }, - { - "if": "authentication:app=yes", - "ifnot": "authentication:app=no", - "then": { - "en": "Authentication by an app" - } - }, - { - "if": "authentication:phone_call=yes", - "ifnot": "authentication:phone_call=no", - "then": { - "en": "Authentication via phone call is available" - } - }, - { - "if": "authentication:short_message=yes", - "ifnot": "authentication:short_message=no", - "then": { - "en": "Authentication via phone call is available" - } - }, - { - "if": "authentication:nfc=yes", - "ifnot": "authentication:nfc=no", - "then": { - "en": "Authentication via NFC is available" - } - }, - { - "if": "authentication:money_card=yes", - "ifnot": "authentication:money_card=no", - "then": { - "en": "Authentication via Money Card is available" - } - }, - { - "if": "authentication:debit_card=yes", - "ifnot": "authentication:debit_card=no", - "then": { - "en": "Authentication via debit card is available" - } - }, - { - "if": "authentication:none=yes", - "ifnot": "authentication:none=no", - "then": { - "en": "No authentication is needed" - } - } - ] - }, - { - "#": "Auth phone", - "render": { - "en": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}", - "it": "{network}", - "ja": "{network}", - "nb_NO": "{network}", - "ru": "{network}", - "zh_Hant": "{network}" - }, - "question": { - "en": "What's the phone number for authentication call or SMS?", - "it": "A quale rete appartiene questa stazione di ricarica?", - "ja": "この充電ステーションの運営チェーンはどこですか?", - "ru": "К какой сети относится эта станция?", - "zh_Hant": "充電站所屬的網路是?" - }, - "freeform": { - "key": "authentication:phone_call:number", - "type": "phone" - }, - "condition": { - "or": [ - "authentication:phone_call=yes", - "authentication:short_message=yes" - ] - }, - "it": { - "0": { - "then": "Non appartiene a una rete" - } - }, - "ja": { - "0": { - "then": "大規模な運営チェーンの一部ではない" - } - }, - "ru": { - "0": { - "then": "Не является частью более крупной сети" - } - }, - "zh_Hant": { - "0": { - "then": "不屬於大型網路" - } - } - }, - { - "#": "OH", - "render": "{opening_hours_table(opening_hours)}", - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - }, - "question": { - "en": "When is this charging station opened?" - }, - "mappings": [ - { - "if": "opening_hours=24/7", - "then": { - "en": "24/7 opened (including holidays)" - } - } - ] - }, - { - "#": "fee/charge", - "question": { - "en": "How much does one have to pay to use this charging station?", - "nl": "Hoeveel kost het gebruik van dit oplaadpunt?" - }, - "freeform": { - "key": "charge", - "addExtraTags": [ - "fee=yes" - ] - }, - "render": { - "en": "Using this charging station costs {charge}", - "nl": "Dit oplaadpunt gebruiken kost {charge}" - }, - "mappings": [ - { - "if": { - "and": [ - "fee=no", - "charge=" - ] - }, - "then": { - "nl": "Gratis te gebruiken", - "en": "Free to use" - } - } - ] - }, - { - "builtin": "payment-options", - "override": { - "condition": { - "or": [ - "fee=yes", - "charge~*" - ] - }, - "mappings+": [ - { - "if": "payment:app=yes", - "ifnot": "payment:app=no", - "then": { - "en": "Payment is done using a dedicated app", - "nl": "Betalen via een app van het netwerk" + "#": "capacity", + "render": { + "en": "{capacity} vehicles can be charged here at the same time", + "nl": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" + }, + "question": { + "en": "How much vehicles can be charged here at the same time?", + "nl": "Hoeveel voertuigen kunnen hier opgeladen worden?" + }, + "freeform": { + "key": "capacity", + "type": "pnat" + } + }, + { + "question": { + "en": "Which charging stations are available here?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "socket:schuko=1", + "ifnot": "socket:schuko=", + "then": { + "en": " Schuko wall plug without ground pin (CEE7/4 type F)", + "nl": " Schuko stekker zonder aardingspin (CEE7/4 type F)" + } + }, + { + "if": { + "and": [ + "socket:schuko~*", + "socket:schuko!=1" + ] + }, + "then": { + "en": " Schuko wall plug without ground pin (CEE7/4 type F)", + "nl": " Schuko stekker zonder aardingspin (CEE7/4 type F)" + }, + "hideInAnswer": true + }, + { + "if": "socket:typee=1", + "ifnot": "socket:typee=", + "then": { + "en": " European wall plug with ground pin (CEE7/4 type E)", + "nl": " Europese stekker met aardingspin (CEE7/4 type E)" + } + }, + { + "if": { + "and": [ + "socket:typee~*", + "socket:typee!=1" + ] + }, + "then": { + "en": " European wall plug with ground pin (CEE7/4 type E)", + "nl": " Europese stekker met aardingspin (CEE7/4 type E)" + }, + "hideInAnswer": true + }, + { + "if": "socket:chademo=1", + "ifnot": "socket:chademo=", + "then": { + "en": " Chademo", + "nl": " " + } + }, + { + "if": { + "and": [ + "socket:chademo~*", + "socket:chademo!=1" + ] + }, + "then": { + "en": " Chademo", + "nl": " " + }, + "hideInAnswer": true + }, + { + "if": "socket:type1_cable=1", + "ifnot": "socket:type1_cable=", + "then": { + "en": " Type 1 with cable (J1772)", + "nl": " Type 1 met kabel (J1772)" + } + }, + { + "if": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=1" + ] + }, + "then": { + "en": " Type 1 with cable (J1772)", + "nl": " Type 1 met kabel (J1772)" + }, + "hideInAnswer": true + }, + { + "if": "socket:type1=1", + "ifnot": "socket:type1=", + "then": { + "en": " Type 1 without cable (J1772)", + "nl": " Type 1 zonder kabel (J1772)" + } + }, + { + "if": { + "and": [ + "socket:type1~*", + "socket:type1!=1" + ] + }, + "then": { + "en": " Type 1 without cable (J1772)", + "nl": " Type 1 zonder kabel (J1772)" + }, + "hideInAnswer": true + }, + { + "if": "socket:type1_combo=1", + "ifnot": "socket:type1_combo=", + "then": { + "en": " Type 1 CCS (aka Type 1 Combo)", + "nl": " " + } + }, + { + "if": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=1" + ] + }, + "then": { + "en": " Type 1 CCS (aka Type 1 Combo)", + "nl": " " + }, + "hideInAnswer": true + }, + { + "if": "socket:tesla_supercharger=1", + "ifnot": "socket:tesla_supercharger=", + "then": { + "en": " Tesla Supercharger", + "nl": " " + } + }, + { + "if": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=1" + ] + }, + "then": { + "en": " Tesla Supercharger", + "nl": " " + }, + "hideInAnswer": true + }, + { + "if": "socket:type2=1", + "ifnot": "socket:type2=", + "then": { + "en": " Type 2 (mennekes)", + "nl": " " + } + }, + { + "if": { + "and": [ + "socket:type2~*", + "socket:type2!=1" + ] + }, + "then": { + "en": " Type 2 (mennekes)", + "nl": " " + }, + "hideInAnswer": true + }, + { + "if": "socket:type2_combo=1", + "ifnot": "socket:type2_combo=", + "then": { + "en": " Type 2 CCS (mennekes)", + "nl": " " + } + }, + { + "if": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=1" + ] + }, + "then": { + "en": " Type 2 CCS (mennekes)", + "nl": " " + }, + "hideInAnswer": true + } + ] + }, + { + "question": { + "en": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", + "nl": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here", + "nl": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" + }, + "freeform": { + "key": "socket:schuko", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "question": { + "en": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "nl": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) " + }, + "render": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" + }, + "freeform": { + "key": "socket:schuko:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:schuko:voltage=230 V", + "then": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" + } + } + ], + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "question": { + "en": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "nl": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" + }, + "render": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:current}A", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" + }, + "freeform": { + "key": "socket:schuko:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:schuko:current=16 A", + "then": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" + } + } + ], + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "question": { + "en": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" + }, + "render": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" + }, + "freeform": { + "key": "socket:schuko:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:schuko:output=3.6 kw", + "then": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" + } + } + ], + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "question": { + "en": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", + "nl": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here", + "nl": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" + }, + "freeform": { + "key": "socket:typee", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "question": { + "en": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "nl": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) " + }, + "render": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" + }, + "freeform": { + "key": "socket:typee:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:typee:voltage=230 V", + "then": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" + } + } + ], + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "question": { + "en": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "nl": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" + }, + "render": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" + }, + "freeform": { + "key": "socket:typee:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:typee:current=16 A", + "then": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" + } + } + ], + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "question": { + "en": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" + }, + "render": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" + }, + "freeform": { + "key": "socket:typee:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:typee:output=3 kw", + "then": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" + } + }, + { + "if": "socket:socket:typee:output=22 kw", + "then": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "question": { + "en": "How much plugs of type Chademo are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Chademo plugs of type Chademo available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:chademo", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "question": { + "en": "What voltage do the plugs with Chademo offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Chademo outputs {socket:chademo:voltage} volt", + "nl": " heeft een spanning van {socket:chademo:voltage} volt" + }, + "freeform": { + "key": "socket:chademo:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:chademo:voltage=500 V", + "then": { + "en": "Chademo outputs 500 volt", + "nl": " heeft een spanning van 500 volt" + } + } + ], + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "question": { + "en": "What current do the plugs with Chademo offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Chademo outputs at most {socket:chademo:current}A", + "nl": " levert een stroom van maximaal {socket:chademo:current}A" + }, + "freeform": { + "key": "socket:chademo:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:chademo:current=120 A", + "then": { + "en": "Chademo outputs at most 120 A", + "nl": " levert een stroom van maximaal 120 A" + } + } + ], + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "question": { + "en": "What power output does a single plug of type Chademo offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Chademo outputs at most {socket:chademo:output}", + "nl": " levert een vermogen van maximaal {socket:chademo:output}" + }, + "freeform": { + "key": "socket:chademo:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:chademo:output=50 kw", + "then": { + "en": "Chademo outputs at most 50 kw", + "nl": " levert een vermogen van maximaal 50 kw" + } + } + ], + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "question": { + "en": "How much plugs of type Type 1 with cable (J1772) are available here?", + "nl": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here", + "nl": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" + }, + "freeform": { + "key": "socket:type1_cable", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "question": { + "en": "What voltage do the plugs with Type 1 with cable (J1772) offer?", + "nl": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) " + }, + "render": { + "en": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt", + "nl": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" + }, + "freeform": { + "key": "socket:type1_cable:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_cable:voltage=200 V", + "then": { + "en": "Type 1 with cable (J1772) outputs 200 volt", + "nl": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" + } + }, + { + "if": "socket:socket:type1_cable:voltage=240 V", + "then": { + "en": "Type 1 with cable (J1772) outputs 240 volt", + "nl": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" + } + } + ], + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "question": { + "en": "What current do the plugs with Type 1 with cable (J1772) offer?", + "nl": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?" + }, + "render": { + "en": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A", + "nl": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" + }, + "freeform": { + "key": "socket:type1_cable:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_cable:current=32 A", + "then": { + "en": "Type 1 with cable (J1772) outputs at most 32 A", + "nl": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "question": { + "en": "What power output does a single plug of type Type 1 with cable (J1772) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?" + }, + "render": { + "en": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}", + "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" + }, + "freeform": { + "key": "socket:type1_cable:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_cable:output=3.7 kw", + "then": { + "en": "Type 1 with cable (J1772) outputs at most 3.7 kw", + "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" + } + }, + { + "if": "socket:socket:type1_cable:output=7 kw", + "then": { + "en": "Type 1 with cable (J1772) outputs at most 7 kw", + "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" + } + } + ], + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "question": { + "en": "How much plugs of type Type 1 without cable (J1772) are available here?", + "nl": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here", + "nl": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" + }, + "freeform": { + "key": "socket:type1", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "question": { + "en": "What voltage do the plugs with Type 1 without cable (J1772) offer?", + "nl": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) " + }, + "render": { + "en": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt", + "nl": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" + }, + "freeform": { + "key": "socket:type1:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1:voltage=200 V", + "then": { + "en": "Type 1 without cable (J1772) outputs 200 volt", + "nl": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" + } + }, + { + "if": "socket:socket:type1:voltage=240 V", + "then": { + "en": "Type 1 without cable (J1772) outputs 240 volt", + "nl": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" + } + } + ], + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "question": { + "en": "What current do the plugs with Type 1 without cable (J1772) offer?", + "nl": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?" + }, + "render": { + "en": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A", + "nl": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" + }, + "freeform": { + "key": "socket:type1:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1:current=32 A", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 32 A", + "nl": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "question": { + "en": "What power output does a single plug of type Type 1 without cable (J1772) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?" + }, + "render": { + "en": "Type 1 without cable (J1772) outputs at most {socket:type1:output}", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" + }, + "freeform": { + "key": "socket:type1:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1:output=3.7 kw", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 3.7 kw", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" + } + }, + { + "if": "socket:socket:type1:output=6.6 kw", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 6.6 kw", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" + } + }, + { + "if": "socket:socket:type1:output=7 kw", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 7 kw", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" + } + }, + { + "if": "socket:socket:type1:output=7.2 kw", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 7.2 kw", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" + } + } + ], + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "question": { + "en": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:type1_combo", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "question": { + "en": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt", + "nl": " heeft een spanning van {socket:type1_combo:voltage} volt" + }, + "freeform": { + "key": "socket:type1_combo:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_combo:voltage=400 V", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt", + "nl": " heeft een spanning van 400 volt" + } + }, + { + "if": "socket:socket:type1_combo:voltage=1000 V", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt", + "nl": " heeft een spanning van 1000 volt" + } + } + ], + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "question": { + "en": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A", + "nl": " levert een stroom van maximaal {socket:type1_combo:current}A" + }, + "freeform": { + "key": "socket:type1_combo:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_combo:current=50 A", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A", + "nl": " levert een stroom van maximaal 50 A" + } + }, + { + "if": "socket:socket:type1_combo:current=125 A", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A", + "nl": " levert een stroom van maximaal 125 A" + } + } + ], + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "question": { + "en": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}", + "nl": " levert een vermogen van maximaal {socket:type1_combo:output}" + }, + "freeform": { + "key": "socket:type1_combo:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_combo:output=50 kw", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw", + "nl": " levert een vermogen van maximaal 50 kw" + } + }, + { + "if": "socket:socket:type1_combo:output=62.5 kw", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw", + "nl": " levert een vermogen van maximaal 62.5 kw" + } + }, + { + "if": "socket:socket:type1_combo:output=150 kw", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw", + "nl": " levert een vermogen van maximaal 150 kw" + } + }, + { + "if": "socket:socket:type1_combo:output=350 kw", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw", + "nl": " levert een vermogen van maximaal 350 kw" + } + } + ], + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "question": { + "en": "How much plugs of type Tesla Supercharger are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Tesla Supercharger plugs of type Tesla Supercharger available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:tesla_supercharger", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "question": { + "en": "What voltage do the plugs with Tesla Supercharger offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt", + "nl": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_supercharger:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger:voltage=480 V", + "then": { + "en": "Tesla Supercharger outputs 480 volt", + "nl": " heeft een spanning van 480 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "question": { + "en": "What current do the plugs with Tesla Supercharger offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A", + "nl": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" + }, + "freeform": { + "key": "socket:tesla_supercharger:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger:current=125 A", + "then": { + "en": "Tesla Supercharger outputs at most 125 A", + "nl": " levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:tesla_supercharger:current=350 A", + "then": { + "en": "Tesla Supercharger outputs at most 350 A", + "nl": " levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "question": { + "en": "What power output does a single plug of type Tesla Supercharger offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}", + "nl": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" + }, + "freeform": { + "key": "socket:tesla_supercharger:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger:output=120 kw", + "then": { + "en": "Tesla Supercharger outputs at most 120 kw", + "nl": " levert een vermogen van maximaal 120 kw" + } + }, + { + "if": "socket:socket:tesla_supercharger:output=150 kw", + "then": { + "en": "Tesla Supercharger outputs at most 150 kw", + "nl": " levert een vermogen van maximaal 150 kw" + } + }, + { + "if": "socket:socket:tesla_supercharger:output=250 kw", + "then": { + "en": "Tesla Supercharger outputs at most 250 kw", + "nl": " levert een vermogen van maximaal 250 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "question": { + "en": "How much plugs of type Type 2 (mennekes) are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:type2", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "question": { + "en": "What voltage do the plugs with Type 2 (mennekes) offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Type 2 (mennekes) outputs {socket:type2:voltage} volt", + "nl": " heeft een spanning van {socket:type2:voltage} volt" + }, + "freeform": { + "key": "socket:type2:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2:voltage=230 V", + "then": { + "en": "Type 2 (mennekes) outputs 230 volt", + "nl": " heeft een spanning van 230 volt" + } + }, + { + "if": "socket:socket:type2:voltage=400 V", + "then": { + "en": "Type 2 (mennekes) outputs 400 volt", + "nl": " heeft een spanning van 400 volt" + } + } + ], + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "question": { + "en": "What current do the plugs with Type 2 (mennekes) offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Type 2 (mennekes) outputs at most {socket:type2:current}A", + "nl": " levert een stroom van maximaal {socket:type2:current}A" + }, + "freeform": { + "key": "socket:type2:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2:current=16 A", + "then": { + "en": "Type 2 (mennekes) outputs at most 16 A", + "nl": " levert een stroom van maximaal 16 A" + } + }, + { + "if": "socket:socket:type2:current=32 A", + "then": { + "en": "Type 2 (mennekes) outputs at most 32 A", + "nl": " levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "question": { + "en": "What power output does a single plug of type Type 2 (mennekes) offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Type 2 (mennekes) outputs at most {socket:type2:output}", + "nl": " levert een vermogen van maximaal {socket:type2:output}" + }, + "freeform": { + "key": "socket:type2:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2:output=11 kw", + "then": { + "en": "Type 2 (mennekes) outputs at most 11 kw", + "nl": " levert een vermogen van maximaal 11 kw" + } + }, + { + "if": "socket:socket:type2:output=22 kw", + "then": { + "en": "Type 2 (mennekes) outputs at most 22 kw", + "nl": " levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "question": { + "en": "How much plugs of type Type 2 CCS (mennekes) are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:type2_combo", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "question": { + "en": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt", + "nl": " heeft een spanning van {socket:type2_combo:voltage} volt" + }, + "freeform": { + "key": "socket:type2_combo:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_combo:voltage=500 V", + "then": { + "en": "Type 2 CCS (mennekes) outputs 500 volt", + "nl": " heeft een spanning van 500 volt" + } + }, + { + "if": "socket:socket:type2_combo:voltage=920 V", + "then": { + "en": "Type 2 CCS (mennekes) outputs 920 volt", + "nl": " heeft een spanning van 920 volt" + } + } + ], + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "question": { + "en": "What current do the plugs with Type 2 CCS (mennekes) offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A", + "nl": " levert een stroom van maximaal {socket:type2_combo:current}A" + }, + "freeform": { + "key": "socket:type2_combo:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_combo:current=125 A", + "then": { + "en": "Type 2 CCS (mennekes) outputs at most 125 A", + "nl": " levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:type2_combo:current=350 A", + "then": { + "en": "Type 2 CCS (mennekes) outputs at most 350 A", + "nl": " levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "question": { + "en": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}", + "nl": " levert een vermogen van maximaal {socket:type2_combo:output}" + }, + "freeform": { + "key": "socket:type2_combo:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_combo:output=50 kw", + "then": { + "en": "Type 2 CCS (mennekes) outputs at most 50 kw", + "nl": " levert een vermogen van maximaal 50 kw" + } + } + ], + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "#": "Authentication", + "question": { + "en": "What kind of authentication is available at the charging station?", + "it": "Quali sono gli orari di apertura di questa stazione di ricarica?", + "ja": "この充電ステーションはいつオープンしますか?", + "nb_NO": "Når åpnet denne ladestasjonen?", + "ru": "В какое время работает эта зарядная станция?", + "zh_Hant": "何時是充電站開放使用的時間?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "authentication:membership_card=yes", + "ifnot": "authentication:membership_card=no", + "then": { + "en": "Authentication by a membership card" + } + }, + { + "if": "authentication:app=yes", + "ifnot": "authentication:app=no", + "then": { + "en": "Authentication by an app" + } + }, + { + "if": "authentication:phone_call=yes", + "ifnot": "authentication:phone_call=no", + "then": { + "en": "Authentication via phone call is available" + } + }, + { + "if": "authentication:short_message=yes", + "ifnot": "authentication:short_message=no", + "then": { + "en": "Authentication via phone call is available" + } + }, + { + "if": "authentication:nfc=yes", + "ifnot": "authentication:nfc=no", + "then": { + "en": "Authentication via NFC is available" + } + }, + { + "if": "authentication:money_card=yes", + "ifnot": "authentication:money_card=no", + "then": { + "en": "Authentication via Money Card is available" + } + }, + { + "if": "authentication:debit_card=yes", + "ifnot": "authentication:debit_card=no", + "then": { + "en": "Authentication via debit card is available" + } + }, + { + "if": "authentication:none=yes", + "ifnot": "authentication:none=no", + "then": { + "en": "No authentication is needed" + } + } + ] + }, + { + "#": "Auth phone", + "render": { + "en": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}", + "it": "{network}", + "ja": "{network}", + "nb_NO": "{network}", + "ru": "{network}", + "zh_Hant": "{network}" + }, + "question": { + "en": "What's the phone number for authentication call or SMS?", + "it": "A quale rete appartiene questa stazione di ricarica?", + "ja": "この充電ステーションの運営チェーンはどこですか?", + "ru": "К какой сети относится эта станция?", + "zh_Hant": "充電站所屬的網路是?" + }, + "freeform": { + "key": "authentication:phone_call:number", + "type": "phone" + }, + "condition": { + "or": [ + "authentication:phone_call=yes", + "authentication:short_message=yes" + ] + }, + "it": { + "0": { + "then": "Non appartiene a una rete" + } + }, + "ja": { + "0": { + "then": "大規模な運営チェーンの一部ではない" + } + }, + "ru": { + "0": { + "then": "Не является частью более крупной сети" + } + }, + "zh_Hant": { + "0": { + "then": "不屬於大型網路" + } + } + }, + { + "#": "OH", + "render": "{opening_hours_table(opening_hours)}", + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + }, + "question": { + "en": "When is this charging station opened?" + }, + "mappings": [ + { + "if": "opening_hours=24/7", + "then": { + "en": "24/7 opened (including holidays)" + } + } + ] + }, + { + "#": "fee/charge", + "question": { + "en": "How much does one have to pay to use this charging station?", + "nl": "Hoeveel kost het gebruik van dit oplaadpunt?" + }, + "freeform": { + "key": "charge", + "addExtraTags": [ + "fee=yes" + ] + }, + "render": { + "en": "Using this charging station costs {charge}", + "nl": "Dit oplaadpunt gebruiken kost {charge}" + }, + "mappings": [ + { + "if": { + "and": [ + "fee=no", + "charge=" + ] + }, + "then": { + "nl": "Gratis te gebruiken", + "en": "Free to use" + } + } + ] + }, + { + "builtin": "payment-options", + "override": { + "condition": { + "or": [ + "fee=yes", + "charge~*" + ] + }, + "mappings+": [ + { + "if": "payment:app=yes", + "ifnot": "payment:app=no", + "then": { + "en": "Payment is done using a dedicated app", + "nl": "Betalen via een app van het netwerk" + } + } + ] + } + }, + { + "#": "maxstay", + "question": { + "en": "What is the maximum amount of time one is allowed to stay here?", + "nl": "Hoelang mag een voertuig hier blijven staan?" + }, + "freeform": { + "key": "maxstay" + }, + "render": { + "en": "One can stay at most {canonical(maxstay)}", + "nl": "De maximale parkeertijd hier is {canonical(maxstay)}" + }, + "mappings": [ + { + "if": "maxstay=unlimited", + "then": { + "en": "No timelimit on leaving your vehicle here", + "nl": "Geen maximum parkeertijd" + } + } + ] + }, + { + "#": "Network", + "render": { + "en": "Part of the network {network}" + }, + "question": { + "en": "Is this charging station part of a network?" + }, + "freeform": { + "key": "network" + }, + "mappings": [ + { + "if": "no:network=yes", + "then": { + "en": "Not part of a bigger network" + } + }, + { + "if": "network=none", + "then": { + "en": "Not part of a bigger network" + }, + "hideInAnswer": true + }, + { + "if": "network=AeroVironment", + "then": "AeroVironment" + }, + { + "if": "network=Blink", + "then": "Blink" + }, + { + "if": "network=eVgo", + "then": "eVgo" + } + ] + }, + { + "#": "Operator", + "question": "Who is the operator of this charging station?", + "render": "This charging station is operated by {operator}", + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": { + "and": [ + "network:={operator}" + ] + }, + "then": "Actually, {operator} is the network", + "addExtraTags": [ + "operator=" + ], + "hideInAnswer": "operator=" + } + ] + }, + { + "#": "phone", + "question": { + "en": "What number can one call if there is a problem with this charging station?" + }, + "render": { + "en": "In case of problems, call {phone}" + }, + "freeform": { + "key": "phone", + "type": "phone" + } + }, + { + "#": "email", + "question": { + "en": "What is the email address of the operator?" + }, + "render": { + "en": "In case of problems, send an email to {email}" + }, + "freeform": { + "key": "email", + "type": "email" + } + }, + { + "#": "website", + "question": { + "en": "What is the website of the operator?" + }, + "render": { + "en": "More info on {website}" + }, + "freeform": { + "key": "website", + "type": "url" + } + }, + "level", + { + "#": "ref", + "question": { + "en": "What is the reference number of this charging station?" + }, + "render": "Reference number is {ref}", + "freeform": { + "key": "ref" + } + }, + { + "#": "Operational status", + "question": { + "en": "Is this charging point in use?", + "nl": "Is dit oplaadpunt operationeel?" + }, + "mappings": [ + { + "if": "operational_status=broken", + "then": { + "en": "This charging station is broken", + "nl": "Dit oplaadpunt is kapot" + } + }, + { + "if": { + "and": [ + "planned:amenity=charging_station", + "amenity=" + ] + }, + "then": { + "en": "A charging station is planned here", + "nl": "Hier zal binnenkort een oplaadpunt gebouwd worden" + } + }, + { + "if": { + "and": [ + "construction:amenity=charging_station", + "amenity=" + ] + }, + "then": { + "en": "A charging station is constructed here", + "nl": "Hier wordt op dit moment een oplaadpunt gebouwd" + } + }, + { + "if": { + "and": [ + "disused:amenity=charging_station", + "amenity=" + ] + }, + "then": { + "en": "This charging station has beed permanently disabled and is not in use anymore but is still visible", + "nl": "Dit oplaadpunt is niet meer in gebruik maar is wel nog aanwezig" + } + }, + { + "if": "amenity=charging_station", + "then": { + "en": "This charging station works", + "nl": "Dit oplaadpunt werkt" + } + } + ] + } + ], + "icon": { + "render": "pin:#fff;./assets/themes/charging_stations/plug.svg", + "mappings": [ + { + "if": "bicycle=yes", + "then": "pin:#fff;./assets/themes/charging_stations/bicycle.svg" + }, + { + "if": { + "or": [ + "car=yes", + "motorcar=yes" + ] + }, + "then": "pin:#fff;./assets/themes/charging_stations/car.svg" } - } ] - } }, - { - "#": "maxstay", - "question": { - "en": "What is the maximum amount of time one is allowed to stay here?", - "nl": "Hoelang mag een voertuig hier blijven staan?" - }, - "freeform": { - "key": "maxstay" - }, - "render": { - "en": "One can stay at most {canonical(maxstay)}", - "nl": "De maximale parkeertijd hier is {canonical(maxstay)}" - }, - "mappings": [ + "iconOverlays": [ { - "if": "maxstay=unlimited", - "then": { - "en": "No timelimit on leaving your vehicle here", - "nl": "Geen maximum parkeertijd" - } + "if": { + "or": [ + "disused:amenity=charging_station", + "operational_status=broken" + ] + }, + "then": "cross_bottom_right:#c22;" + }, + { + "if": { + "or": [ + "proposed:amenity=charging_station", + "planned:amenity=charging_station" + ] + }, + "then": "./assets/layers/charging_station/under_construction.svg", + "badge": true + }, + { + "if": { + "and": [ + "bicycle=yes", + { + "or": [ + "motorcar=yes", + "car=yes" + ] + } + ] + }, + "then": "circle:#fff;./assets/themes/charging_stations/car.svg", + "badge": true } - ] + ], + "width": { + "render": "8" }, - { - "#": "Network", - "render": { - "en": "Part of the network {network}" - }, - "question": { - "en": "Is this charging station part of a network?" - }, - "freeform": { - "key": "network" - }, - "mappings": [ + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#00f" + }, + "presets": [ { - "if": "no:network=yes", - "then": { - "en": "Not part of a bigger network" - } - }, - { - "if": "network=none", - "then": { - "en": "Not part of a bigger network" - }, - "hideInAnswer": true - }, - { - "if": "network=AeroVironment", - "then": "AeroVironment" - }, - { - "if": "network=Blink", - "then": "Blink" - }, - { - "if": "network=eVgo", - "then": "eVgo" + "tags": [ + "amenity=charging_station" + ], + "title": { + "en": "Charging station" + }, + "preciseInput": { + "preferredBackground": "map" + } } - ] - }, - { - "#": "Operator", - "question": "Who is the operator of this charging station?", - "render": "This charging station is operated by {operator}", - "freeform": { - "key": "operator" - }, - "mappings": [ + ], + "wayHandling": 1, + "filter": [ { - "if": { - "and": [ - "network:={operator}" + "options": [ + { + "question": { + "en": "All vehicle types", + "nl": "Alle voertuigen" + } + }, + { + "question": { + "en": "Charging station for bicycles", + "nl": "Oplaadpunten voor fietsen" + }, + "osmTags": "bicycle=yes" + }, + { + "question": { + "en": "Charging station for cars", + "nl": "Oplaadpunten voor auto's" + }, + "osmTags": { + "or": [ + "car=yes", + "motorcar=yes" + ] + } + } + ] + }, + { + "options": [ + { + "question": { + "en": "Only working charging stations" + }, + "osmTags": { + "and": [ + "operational_status!=broken", + "amenity=charging_station" + ] + } + } + ] + }, + { + "options": [ + { + "question": { + "en": "All connectors", + "nl": "Alle types" + } + }, + { + "question": { + "en": "Has a Schuko wall plug without ground pin (CEE7/4 type F) connector", + "nl": "Heeft een Schuko stekker zonder aardingspin (CEE7/4 type F) " + }, + "osmTags": "socket:schuko~*" + }, + { + "question": { + "en": "Has a European wall plug with ground pin (CEE7/4 type E) connector", + "nl": "Heeft een Europese stekker met aardingspin (CEE7/4 type E) " + }, + "osmTags": "socket:typee~*" + }, + { + "question": { + "en": "Has a Chademo connector", + "nl": "Heeft een " + }, + "osmTags": "socket:chademo~*" + }, + { + "question": { + "en": "Has a Type 1 with cable (J1772) connector", + "nl": "Heeft een Type 1 met kabel (J1772) " + }, + "osmTags": "socket:type1_cable~*" + }, + { + "question": { + "en": "Has a Type 1 without cable (J1772) connector", + "nl": "Heeft een Type 1 zonder kabel (J1772) " + }, + "osmTags": "socket:type1~*" + }, + { + "question": { + "en": "Has a Type 1 CCS (aka Type 1 Combo) connector", + "nl": "Heeft een " + }, + "osmTags": "socket:type1_combo~*" + }, + { + "question": { + "en": "Has a Tesla Supercharger connector", + "nl": "Heeft een " + }, + "osmTags": "socket:tesla_supercharger~*" + }, + { + "question": { + "en": "Has a Type 2 (mennekes) connector", + "nl": "Heeft een " + }, + "osmTags": "socket:type2~*" + }, + { + "question": { + "en": "Has a Type 2 CCS (mennekes) connector", + "nl": "Heeft een " + }, + "osmTags": "socket:type2_combo~*" + } ] - }, - "then": "Actually, {operator} is the network", - "addExtraTags": [ - "operator=" - ], - "hideInAnswer": "operator=" } - ] - }, - { - "#": "phone", - "question": { - "en": "What number can one call if there is a problem with this charging station?" - }, - "render": { - "en": "In case of problems, call {phone}" - }, - "freeform": { - "key": "phone", - "type": "phone" - } - }, - { - "#": "email", - "question": { - "en": "What is the email address of the operator?" - }, - "render": { - "en": "In case of problems, send an email to {email}" - }, - "freeform": { - "key": "email", - "type": "email" - } - }, - { - "#": "website", - "question": { - "en": "What is the website of the operator?" - }, - "render": { - "en": "More info on {website}" - }, - "freeform": { - "key": "website", - "type": "url" - } - }, - "level", - { - "#": "ref", - "question": { - "en": "What is the reference number of this charging station?" - }, - "render": "Reference number is {ref}", - "freeform": { - "key": "ref" - } - }, - { - "#": "Operational status", - "question": { - "en": "Is this charging point in use?", - "nl": "Is dit oplaadpunt operationeel?" - }, - "mappings": [ + ], + "units": [ { - "if": "operational_status=broken", - "then": { - "en": "This charging station is broken", - "nl": "Dit oplaadpunt is kapot" - } - }, - { - "if": { - "and": [ - "planned:amenity=charging_station", - "amenity=" + "appliesToKey": [ + "maxstay" + ], + "applicableUnits": [ + { + "canonicalDenomination": "minutes", + "canonicalDenominationSingular": "minute", + "alternativeDenomination": [ + "m", + "min", + "mins", + "minuten", + "mns" + ], + "human": { + "en": " minutes", + "nl": " minuten" + }, + "humanSingular": { + "en": " minute", + "nl": " minuut" + } + }, + { + "canonicalDenomination": "hours", + "canonicalDenominationSingular": "hour", + "alternativeDenomination": [ + "h", + "hrs", + "hours", + "u", + "uur", + "uren" + ], + "human": { + "en": " hours", + "nl": " uren" + }, + "humanSingular": { + "en": " hour", + "nl": " uur" + } + }, + { + "canonicalDenomination": "days", + "canonicalDenominationSingular": "day", + "alternativeDenomination": [ + "dys", + "dagen", + "dag" + ], + "human": { + "en": " days", + "nl": " day" + }, + "humanSingular": { + "en": " day", + "nl": " dag" + } + } ] - }, - "then": { - "en": "A charging station is planned here", - "nl": "Hier zal binnenkort een oplaadpunt gebouwd worden" - } }, { - "if": { - "and": [ - "construction:amenity=charging_station", - "amenity=" - ] - }, - "then": { - "en": "A charging station is constructed here", - "nl": "Hier wordt op dit moment een oplaadpunt gebouwd" - } + "appliesToKey": [ + "socket:schuko:voltage", + "socket:typee:voltage", + "socket:chademo:voltage", + "socket:type1_cable:voltage", + "socket:type1:voltage", + "socket:type1_combo:voltage", + "socket:tesla_supercharger:voltage", + "socket:type2:voltage", + "socket:type2_combo:voltage" + ], + "applicableUnits": [ + { + "canonicalDenomination": "V", + "alternativeDenomination": [ + "v", + "volt", + "voltage", + "V", + "Volt" + ], + "human": { + "en": "Volts", + "nl": "volt" + } + } + ], + "eraseInvalidValues": true }, { - "if": { - "and": [ - "disused:amenity=charging_station", - "amenity=" - ] - }, - "then": { - "en": "This charging station has beed permanently disabled and is not in use anymore but is still visible", - "nl": "Dit oplaadpunt is niet meer in gebruik maar is wel nog aanwezig" - } + "appliesToKey": [ + "socket:schuko:current", + "socket:typee:current", + "socket:chademo:current", + "socket:type1_cable:current", + "socket:type1:current", + "socket:type1_combo:current", + "socket:tesla_supercharger:current", + "socket:type2:current", + "socket:type2_combo:current" + ], + "applicableUnits": [ + { + "canonicalDenomination": "A", + "alternativeDenomination": [ + "a", + "amp", + "amperage", + "A" + ], + "human": { + "en": "A", + "nl": "A" + } + } + ], + "eraseInvalidValues": true }, { - "if": "amenity=charging_station", - "then": { - "en": "This charging station works", - "nl": "Dit oplaadpunt werkt" - } + "appliesToKey": [ + "socket:schuko:output", + "socket:typee:output", + "socket:chademo:output", + "socket:type1_cable:output", + "socket:type1:output", + "socket:type1_combo:output", + "socket:tesla_supercharger:output", + "socket:type2:output", + "socket:type2_combo:output" + ], + "applicableUnits": [ + { + "canonicalDenomination": "kW", + "alternativeDenomination": [ + "kilowatt" + ], + "human": { + "en": "kilowatt", + "nl": "kilowatt" + } + }, + { + "canonicalDenomination": "mW", + "alternativeDenomination": [ + "megawatt" + ], + "human": { + "en": "megawatt", + "nl": "megawatt" + } + } + ], + "eraseInvalidValues": true } - ] - } - ], - "icon": { - "render": "pin:#fff;./assets/themes/charging_stations/plug.svg", - "mappings": [ - { - "if": "bicycle=yes", - "then": "pin:#fff;./assets/themes/charging_stations/bicycle.svg" - }, - { - "if": { - "or": [ - "car=yes", - "motorcar=yes" - ] - }, - "then": "pin:#fff;./assets/themes/charging_stations/car.svg" - } ] - }, - "iconOverlays": [ - { - "if": { - "or": [ - "disused:amenity=charging_station", - "operational_status=broken" - ] - }, - "then": "cross_bottom_right:#c22;" - }, - { - "if": { - "or": [ - "proposed:amenity=charging_station", - "planned:amenity=charging_station" - ] - }, - "then": "./assets/layers/charging_station/under_construction.svg", - "badge": true - }, - { - "if": { - "and": [ - "bicycle=yes", - { - "or": [ - "motorcar=yes", - "car=yes" - ] - } - ] - }, - "then": "circle:#fff;./assets/themes/charging_stations/car.svg", - "badge": true - } - ], - "width": { - "render": "8" - }, - "iconSize": { - "render": "50,50,bottom" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "amenity=charging_station" - ], - "title": { - "en": "Charging station" - }, - "preciseInput": { - "preferredBackground": "map" - } - } - ], - "wayHandling": 1, - "filter": [ - { - "options": [ - { - "question": { - "en": "All vehicle types", - "nl": "Alle voertuigen" - } - }, - { - "question": { - "en": "Charging station for bicycles", - "nl": "Oplaadpunten voor fietsen" - }, - "osmTags": "bicycle=yes" - }, - { - "question": { - "en": "Charging station for cars", - "nl": "Oplaadpunten voor auto's" - }, - "osmTags": { - "or": [ - "car=yes", - "motorcar=yes" - ] - } - } - ] - }, - { - "options": [ - { - "question": { - "en": "Only working charging stations" - }, - "osmTags": { - "and": [ - "operational_status!=broken", - "amenity=charging_station" - ] - } - } - ] - }, - { - "options": [ - { - "question": { - "en": "All connectors", - "nl": "Alle types" - } - }, - { - "question": { - "en": "Has a Schuko wall plug without ground pin (CEE7/4 type F) connector", - "nl": "Heeft een Schuko stekker zonder aardingspin (CEE7/4 type F) " - }, - "osmTags": "socket:schuko~*" - }, - { - "question": { - "en": "Has a European wall plug with ground pin (CEE7/4 type E) connector", - "nl": "Heeft een Europese stekker met aardingspin (CEE7/4 type E) " - }, - "osmTags": "socket:typee~*" - }, - { - "question": { - "en": "Has a Chademo connector", - "nl": "Heeft een " - }, - "osmTags": "socket:chademo~*" - }, - { - "question": { - "en": "Has a Type 1 with cable (J1772) connector", - "nl": "Heeft een Type 1 met kabel (J1772) " - }, - "osmTags": "socket:type1_cable~*" - }, - { - "question": { - "en": "Has a Type 1 without cable (J1772) connector", - "nl": "Heeft een Type 1 zonder kabel (J1772) " - }, - "osmTags": "socket:type1~*" - }, - { - "question": { - "en": "Has a Type 1 CCS (aka Type 1 Combo) connector", - "nl": "Heeft een " - }, - "osmTags": "socket:type1_combo~*" - }, - { - "question": { - "en": "Has a Tesla Supercharger connector", - "nl": "Heeft een " - }, - "osmTags": "socket:tesla_supercharger~*" - }, - { - "question": { - "en": "Has a Type 2 (mennekes) connector", - "nl": "Heeft een " - }, - "osmTags": "socket:type2~*" - }, - { - "question": { - "en": "Has a Type 2 CCS (mennekes) connector", - "nl": "Heeft een " - }, - "osmTags": "socket:type2_combo~*" - } - ] - } - ], - "units": [ - { - "appliesToKey": [ - "maxstay" - ], - "applicableUnits": [ - { - "canonicalDenomination": "minutes", - "canonicalDenominationSingular": "minute", - "alternativeDenomination": [ - "m", - "min", - "mins", - "minuten", - "mns" - ], - "human": { - "en": " minutes", - "nl": " minuten" - }, - "humanSingular": { - "en": " minute", - "nl": " minuut" - } - }, - { - "canonicalDenomination": "hours", - "canonicalDenominationSingular": "hour", - "alternativeDenomination": [ - "h", - "hrs", - "hours", - "u", - "uur", - "uren" - ], - "human": { - "en": " hours", - "nl": " uren" - }, - "humanSingular": { - "en": " hour", - "nl": " uur" - } - }, - { - "canonicalDenomination": "days", - "canonicalDenominationSingular": "day", - "alternativeDenomination": [ - "dys", - "dagen", - "dag" - ], - "human": { - "en": " days", - "nl": " day" - }, - "humanSingular": { - "en": " day", - "nl": " dag" - } - } - ] - }, - { - "appliesToKey": [ - "socket:schuko:voltage", - "socket:typee:voltage", - "socket:chademo:voltage", - "socket:type1_cable:voltage", - "socket:type1:voltage", - "socket:type1_combo:voltage", - "socket:tesla_supercharger:voltage", - "socket:type2:voltage", - "socket:type2_combo:voltage" - ], - "applicableUnits": [ - { - "canonicalDenomination": "V", - "alternativeDenomination": [ - "v", - "volt", - "voltage", - "V", - "Volt" - ], - "human": { - "en": "Volts", - "nl": "volt" - } - } - ], - "eraseInvalidValues": true - }, - { - "appliesToKey": [ - "socket:schuko:current", - "socket:typee:current", - "socket:chademo:current", - "socket:type1_cable:current", - "socket:type1:current", - "socket:type1_combo:current", - "socket:tesla_supercharger:current", - "socket:type2:current", - "socket:type2_combo:current" - ], - "applicableUnits": [ - { - "canonicalDenomination": "A", - "alternativeDenomination": [ - "a", - "amp", - "amperage", - "A" - ], - "human": { - "en": "A", - "nl": "A" - } - } - ], - "eraseInvalidValues": true - }, - { - "appliesToKey": [ - "socket:schuko:output", - "socket:typee:output", - "socket:chademo:output", - "socket:type1_cable:output", - "socket:type1:output", - "socket:type1_combo:output", - "socket:tesla_supercharger:output", - "socket:type2:output", - "socket:type2_combo:output" - ], - "applicableUnits": [ - { - "canonicalDenomination": "kW", - "alternativeDenomination": [ - "kilowatt" - ], - "human": { - "en": "kilowatt", - "nl": "kilowatt" - } - }, - { - "canonicalDenomination": "mW", - "alternativeDenomination": [ - "megawatt" - ], - "human": { - "en": "megawatt", - "nl": "megawatt" - } - } - ], - "eraseInvalidValues": true - } - ] } \ No newline at end of file diff --git a/assets/layers/crossings/crossings.json b/assets/layers/crossings/crossings.json index 876656d1f..46d3fae45 100644 --- a/assets/layers/crossings/crossings.json +++ b/assets/layers/crossings/crossings.json @@ -1,324 +1,324 @@ { - "id": "crossings", - "name": { - "en": "Crossings", - "nl": "Oversteekplaatsen" - }, - "description": { - "en": "Crossings for pedestrians and cyclists", - "nl": "Oversteekplaatsen voor voetgangers en fietsers" - }, - "source": { - "osmTags": { - "or": [ - "highway=traffic_signals", - "highway=crossing" - ] - } - }, - "minzoom": 17, - "title": { - "render": { - "en": "Crossing", - "nl": "Oversteekplaats" + "id": "crossings", + "name": { + "en": "Crossings", + "nl": "Oversteekplaatsen" }, - "mappings": [ - { - "if": "highway=traffic_signals", - "then": { - "en": "Traffic signal", - "nl": "Verkeerslicht" - } - }, - { - "if": "crossing=traffic_signals", - "then": { - "en": "Crossing with traffic signals", - "nl": "Oversteektplaats met verkeerslichten" - } - } - ] - }, - "icon": { - "render": "./assets/layers/crossings/pedestrian_crossing.svg", - "mappings": [ - { - "if": { - "or": [ - "highway=traffic_signals", - "crossing=traffic_signals" - ] - }, - "then": "./assets/layers/crossings/traffic_lights.svg" - } - ] - }, - "width": "5", - "presets": [ - { - "title": { - "en": "Crossing", - "nl": "Oversteekplaats" - }, - "tags": [ - "highway=crossing" - ], - "description": { - "en": "Crossing for pedestrians and/or cyclists", - "nl": "Oversteekplaats voor voetgangers en/of fietsers" - }, - "preciseInput": { - "preferredBackground": [ - "photo" - ], - "snapToLayer": "cycleways_and_roads", - "maxSnapDistance": 25 - } + "description": { + "en": "Crossings for pedestrians and cyclists", + "nl": "Oversteekplaatsen voor voetgangers en fietsers" }, - { - "title": { - "en": "Traffic signal", - "nl": "Verkeerslicht" - }, - "tags": [ - "highway=traffic_signals" - ], - "description": { - "en": "Traffic signal on a road", - "nl": "Verkeerslicht op een weg" - }, - "preciseInput": { - "preferredBackground": [ - "photo" - ], - "snapToLayer": "cycleways_and_roads", - "maxSnapDistance": 25 - } - } - ], - "tagRenderings": [ - { - "question": { - "en": "What kind of crossing is this?", - "nl": "Wat voor oversteekplaats is dit?" - }, - "condition": "highway=crossing", - "mappings": [ - { - "if": "crossing=uncontrolled", - "then": { - "en": "Crossing, without traffic lights", - "nl": "Oversteekplaats, zonder verkeerslichten" - } - }, - { - "if": "crossing=traffic_signals", - "then": { - "en": "Crossing with traffic signals", - "nl": "Oversteekplaats met verkeerslichten" - } - }, - { - "if": "crossing=zebra", - "then": { - "en": "Zebra crossing", - "nl": "Zebrapad" - }, - "hideInAnswer": true + "source": { + "osmTags": { + "or": [ + "highway=traffic_signals", + "highway=crossing" + ] } - ] }, - { - "question": { - "en": "Is this is a zebra crossing?", - "nl": "Is dit een zebrapad?" - }, - "condition": "crossing=uncontrolled", - "mappings": [ - { - "if": "crossing_ref=zebra", - "then": { - "en": "This is a zebra crossing", - "nl": "Dit is een zebrapad" - } + "minzoom": 17, + "title": { + "render": { + "en": "Crossing", + "nl": "Oversteekplaats" }, - { - "if": "crossing_ref=", - "then": { - "en": "This is not a zebra crossing", - "nl": "Dit is geen zebrapad" - } - } - ] - }, - { - "question": { - "en": "Is this crossing also for bicycles?", - "nl": "Is deze oversteekplaats ook voor fietsers" - }, - "condition": "highway=crossing", - "mappings": [ - { - "if": "bicycle=yes", - "then": { - "en": "A cyclist can use this crossing", - "nl": "Een fietser kan deze oversteekplaats gebruiken" - } - }, - { - "if": "bicycle=no", - "then": { - "en": "A cyclist can not use this crossing", - "nl": "Een fietser kan deze oversteekplaats niet gebruiken" - } - } - ] - }, - { - "question": { - "en": "Does this crossing have an island in the middle?", - "nl": "Heeft deze oversteekplaats een verkeerseiland in het midden?" - }, - "condition": "highway=crossing", - "mappings": [ - { - "if": "crossing:island=yes", - "then": { - "en": "This crossing has an island in the middle", - "nl": "Deze oversteekplaats heeft een verkeerseiland in het midden" - } - }, - { - "if": "crossing:island=no", - "then": { - "en": "This crossing does not have an island in the middle", - "nl": "Deze oversteekplaats heeft geen verkeerseiland in het midden" - } - } - ] - }, - { - "question": { - "en": "Does this crossing have tactile paving?", - "nl": "Heeft deze oversteekplaats een geleidelijn?" - }, - "condition": "highway=crossing", - "mappings": [ - { - "if": "tactile_paving=yes", - "then": { - "en": "This crossing has tactile paving", - "nl": "Deze oversteekplaats heeft een geleidelijn" - } - }, - { - "if": "tactile_paving=no", - "then": { - "en": "This crossing does not have tactile paving", - "nl": "Deze oversteekplaats heeft geen geleidelijn" - } - }, - { - "if": "tactile_paving=incorrect", - "then": { - "en": "This crossing has tactile paving, but is not correct", - "nl": "Deze oversteekplaats heeft een geleidelijn, die incorrect is." - }, - "hideInAnswer": true - } - ] - }, - { - "question": { - "en": "Does this traffic light have a button to request green light?", - "nl": "Heeft dit verkeerslicht een knop voor groen licht?" - }, - "condition": { - "or": [ - "highway=traffic_signals", - "crossing=traffic_signals" + "mappings": [ + { + "if": "highway=traffic_signals", + "then": { + "en": "Traffic signal", + "nl": "Verkeerslicht" + } + }, + { + "if": "crossing=traffic_signals", + "then": { + "en": "Crossing with traffic signals", + "nl": "Oversteektplaats met verkeerslichten" + } + } ] - }, - "mappings": [ - { - "if": "button_operated=yes", - "then": { - "en": "This traffic light has a button to request green light", - "nl": "Dit verkeerslicht heeft een knop voor groen licht" - } - }, - { - "if": "button_operated=no", - "then": { - "en": "This traffic light does not have a button to request green light", - "nl": "Dit verkeerlicht heeft geen knop voor groen licht" - } - } - ] }, - { - "question": { - "en": "Can a cyclist turn right when the light is red?", - "nl": "Mag een fietser rechtsaf slaan als het licht rood is?" - }, - "condition": "highway=traffic_signals", - "mappings": [ - { - "if": "red_turn:right:bicycle=yes", - "then": { - "en": "A cyclist can turn right if the light is red ", - "nl": "Een fietser mag wel rechtsaf slaan als het licht rood is " - }, - "hideInAnswer": "_country!=be" - }, - { - "if": "red_turn:right:bicycle=yes", - "then": { - "en": "A cyclist can turn right if the light is red", - "nl": "Een fietser mag wel rechtsaf slaan als het licht rood is" - }, - "hideInAnswer": "_country=be" - }, - { - "if": "red_turn:right:bicycle=no", - "then": { - "en": "A cyclist can not turn right if the light is red", - "nl": "Een fietser mag niet rechtsaf slaan als het licht rood is" - } - } - ] + "icon": { + "render": "./assets/layers/crossings/pedestrian_crossing.svg", + "mappings": [ + { + "if": { + "or": [ + "highway=traffic_signals", + "crossing=traffic_signals" + ] + }, + "then": "./assets/layers/crossings/traffic_lights.svg" + } + ] }, - { - "question": { - "en": "Can a cyclist go straight on when the light is red?", - "nl": "Mag een fietser rechtdoor gaan als het licht rood is?" - }, - "condition": "highway=traffic_signals", - "mappings": [ + "width": "5", + "presets": [ { - "if": "red_turn:straight:bicycle=yes", - "then": { - "en": "A cyclist can go straight on if the light is red ", - "nl": "Een fietser mag wel rechtdoor gaan als het licht rood is " - }, - "hideInAnswer": "_country!=be" + "title": { + "en": "Crossing", + "nl": "Oversteekplaats" + }, + "tags": [ + "highway=crossing" + ], + "description": { + "en": "Crossing for pedestrians and/or cyclists", + "nl": "Oversteekplaats voor voetgangers en/of fietsers" + }, + "preciseInput": { + "preferredBackground": [ + "photo" + ], + "snapToLayer": "cycleways_and_roads", + "maxSnapDistance": 25 + } }, { - "if": "red_turn:straight:bicycle=yes", - "then": { - "en": "A cyclist can go straight on if the light is red", - "nl": "Een fietser mag wel rechtdoor gaan als het licht rood is" - }, - "hideInAnswer": "_country=be" - }, - { - "if": "red_turn:straight:bicycle=no", - "then": { - "en": "A cyclist can not go straight on if the light is red", - "nl": "Een fietser mag niet rechtdoor gaan als het licht rood is" - } + "title": { + "en": "Traffic signal", + "nl": "Verkeerslicht" + }, + "tags": [ + "highway=traffic_signals" + ], + "description": { + "en": "Traffic signal on a road", + "nl": "Verkeerslicht op een weg" + }, + "preciseInput": { + "preferredBackground": [ + "photo" + ], + "snapToLayer": "cycleways_and_roads", + "maxSnapDistance": 25 + } } - ] - } - ] + ], + "tagRenderings": [ + { + "question": { + "en": "What kind of crossing is this?", + "nl": "Wat voor oversteekplaats is dit?" + }, + "condition": "highway=crossing", + "mappings": [ + { + "if": "crossing=uncontrolled", + "then": { + "en": "Crossing, without traffic lights", + "nl": "Oversteekplaats, zonder verkeerslichten" + } + }, + { + "if": "crossing=traffic_signals", + "then": { + "en": "Crossing with traffic signals", + "nl": "Oversteekplaats met verkeerslichten" + } + }, + { + "if": "crossing=zebra", + "then": { + "en": "Zebra crossing", + "nl": "Zebrapad" + }, + "hideInAnswer": true + } + ] + }, + { + "question": { + "en": "Is this is a zebra crossing?", + "nl": "Is dit een zebrapad?" + }, + "condition": "crossing=uncontrolled", + "mappings": [ + { + "if": "crossing_ref=zebra", + "then": { + "en": "This is a zebra crossing", + "nl": "Dit is een zebrapad" + } + }, + { + "if": "crossing_ref=", + "then": { + "en": "This is not a zebra crossing", + "nl": "Dit is geen zebrapad" + } + } + ] + }, + { + "question": { + "en": "Is this crossing also for bicycles?", + "nl": "Is deze oversteekplaats ook voor fietsers" + }, + "condition": "highway=crossing", + "mappings": [ + { + "if": "bicycle=yes", + "then": { + "en": "A cyclist can use this crossing", + "nl": "Een fietser kan deze oversteekplaats gebruiken" + } + }, + { + "if": "bicycle=no", + "then": { + "en": "A cyclist can not use this crossing", + "nl": "Een fietser kan deze oversteekplaats niet gebruiken" + } + } + ] + }, + { + "question": { + "en": "Does this crossing have an island in the middle?", + "nl": "Heeft deze oversteekplaats een verkeerseiland in het midden?" + }, + "condition": "highway=crossing", + "mappings": [ + { + "if": "crossing:island=yes", + "then": { + "en": "This crossing has an island in the middle", + "nl": "Deze oversteekplaats heeft een verkeerseiland in het midden" + } + }, + { + "if": "crossing:island=no", + "then": { + "en": "This crossing does not have an island in the middle", + "nl": "Deze oversteekplaats heeft geen verkeerseiland in het midden" + } + } + ] + }, + { + "question": { + "en": "Does this crossing have tactile paving?", + "nl": "Heeft deze oversteekplaats een geleidelijn?" + }, + "condition": "highway=crossing", + "mappings": [ + { + "if": "tactile_paving=yes", + "then": { + "en": "This crossing has tactile paving", + "nl": "Deze oversteekplaats heeft een geleidelijn" + } + }, + { + "if": "tactile_paving=no", + "then": { + "en": "This crossing does not have tactile paving", + "nl": "Deze oversteekplaats heeft geen geleidelijn" + } + }, + { + "if": "tactile_paving=incorrect", + "then": { + "en": "This crossing has tactile paving, but is not correct", + "nl": "Deze oversteekplaats heeft een geleidelijn, die incorrect is." + }, + "hideInAnswer": true + } + ] + }, + { + "question": { + "en": "Does this traffic light have a button to request green light?", + "nl": "Heeft dit verkeerslicht een knop voor groen licht?" + }, + "condition": { + "or": [ + "highway=traffic_signals", + "crossing=traffic_signals" + ] + }, + "mappings": [ + { + "if": "button_operated=yes", + "then": { + "en": "This traffic light has a button to request green light", + "nl": "Dit verkeerslicht heeft een knop voor groen licht" + } + }, + { + "if": "button_operated=no", + "then": { + "en": "This traffic light does not have a button to request green light", + "nl": "Dit verkeerlicht heeft geen knop voor groen licht" + } + } + ] + }, + { + "question": { + "en": "Can a cyclist turn right when the light is red?", + "nl": "Mag een fietser rechtsaf slaan als het licht rood is?" + }, + "condition": "highway=traffic_signals", + "mappings": [ + { + "if": "red_turn:right:bicycle=yes", + "then": { + "en": "A cyclist can turn right if the light is red ", + "nl": "Een fietser mag wel rechtsaf slaan als het licht rood is " + }, + "hideInAnswer": "_country!=be" + }, + { + "if": "red_turn:right:bicycle=yes", + "then": { + "en": "A cyclist can turn right if the light is red", + "nl": "Een fietser mag wel rechtsaf slaan als het licht rood is" + }, + "hideInAnswer": "_country=be" + }, + { + "if": "red_turn:right:bicycle=no", + "then": { + "en": "A cyclist can not turn right if the light is red", + "nl": "Een fietser mag niet rechtsaf slaan als het licht rood is" + } + } + ] + }, + { + "question": { + "en": "Can a cyclist go straight on when the light is red?", + "nl": "Mag een fietser rechtdoor gaan als het licht rood is?" + }, + "condition": "highway=traffic_signals", + "mappings": [ + { + "if": "red_turn:straight:bicycle=yes", + "then": { + "en": "A cyclist can go straight on if the light is red ", + "nl": "Een fietser mag wel rechtdoor gaan als het licht rood is " + }, + "hideInAnswer": "_country!=be" + }, + { + "if": "red_turn:straight:bicycle=yes", + "then": { + "en": "A cyclist can go straight on if the light is red", + "nl": "Een fietser mag wel rechtdoor gaan als het licht rood is" + }, + "hideInAnswer": "_country=be" + }, + { + "if": "red_turn:straight:bicycle=no", + "then": { + "en": "A cyclist can not go straight on if the light is red", + "nl": "Een fietser mag niet rechtdoor gaan als het licht rood is" + } + } + ] + } + ] } \ No newline at end of file diff --git a/assets/layers/cycleways_and_roads/cycleways_and_roads.json b/assets/layers/cycleways_and_roads/cycleways_and_roads.json index 959dfa03c..a53d7e9f5 100644 --- a/assets/layers/cycleways_and_roads/cycleways_and_roads.json +++ b/assets/layers/cycleways_and_roads/cycleways_and_roads.json @@ -1,1170 +1,1170 @@ { - "id": "cycleways_and_roads", - "name": { - "en": "Cycleways and roads", - "nl": "Fietspaden, straten en wegen" - }, - "minzoom": 16, - "source": { - "osmTags": { - "or": [ - "highway=cycleway", - "cycleway=lane", - "cycleway=shared_lane", - "cycleway=track", - "cyclestreet=yes", - "highway=residential", - "highway=tertiary", - "highway=unclassified", - "highway=primary", - "highway=secondary", - { - "and": [ - "highway=path", - "bicycle=designated" - ] - } - ] - } - }, - "calculatedTags": [ - "_comfort_score=feat.score('https://raw.githubusercontent.com/pietervdvn/AspectedRouting/master/Examples/bicycle/aspects/bicycle.comfort.json')" - ], - "title": { - "render": { - "en": "Cycleways", - "nl": "Fietspaden" + "id": "cycleways_and_roads", + "name": { + "en": "Cycleways and roads", + "nl": "Fietspaden, straten en wegen" }, - "mappings": [ - { - "if": { - "or": [ - "highway=cycleway", - "highway=path" - ] - }, - "then": { - "nl": "Fietsweg", - "en": "Cycleway" - } - }, - { - "if": "cycleway=shared_lane", - "then": { - "nl": "Fietssuggestiestrook", - "en": "Shared lane" - } - }, - { - "if": "cycleway=lane", - "then": { - "nl": "Fietsstrook", - "en": "Bike lane" - } - }, - { - "if": "cycleway=track", - "then": { - "en": "Cycleway next to the road", - "nl": "Fietsweg naast de weg" - } - }, - { - "if": "cyclestreet=yes", - "then": { - "nl": "Fietsstraat", - "en": "Cyclestreet" - } - } - ] - }, - "description": {}, - "tagRenderings": [ - { - "#": "Cycleway type for a road", - "question": { - "en": "What kind of cycleway is here?", - "nl": "Wat voor fietspad is hier?" - }, - "condition": { - "and": [ - "highway!=cycleway", - "highway!=path" - ] - }, - "mappings": [ - { - "if": "cycleway=shared_lane", - "then": { - "en": "There is a shared lane", - "nl": "Er is een fietssuggestiestrook" - } - }, - { - "if": "cycleway=lane", - "then": { - "en": "There is a lane next to the road (separated with paint)", - "nl": "Er is een fietspad aangrenzend aan de weg (gescheiden met verf)" - } - }, - { - "if": "cycleway=track", - "then": { - "en": "There is a track, but no cycleway drawn separately from this road on the map.", - "nl": "Er is een fietspad (los van de weg), maar geen fietspad afzonderlijk getekend naast deze weg." - } - }, - { - "if": "cycleway=separate", - "then": { - "en": "There is a separately drawn cycleway", - "nl": "Er is een apart getekend fietspad." - } - }, - { - "if": "cycleway=no", - "then": { - "en": "There is no cycleway", - "nl": "Er is geen fietspad aanwezig" - }, - "hideInAnswer": "cycleway=opposite" - }, - { - "if": "cycleway=no", - "then": { - "en": "There is no cycleway", - "nl": "Er is geen fietspad aanwezig" - }, - "hideInAnswer": "cycleway!=opposite", - "addExtraTags": [ - "oneway:bicycle=no", - "fixme=Changed from cycleway=opposite" - ] - } - ] - }, - { - "#": "is lit?", - "question": { - "en": "Is this street lit?", - "nl": "Is deze weg verlicht?" - }, - "mappings": [ - { - "if": "lit=yes", - "then": { - "en": "This street is lit", - "nl": "Deze weg is verlicht" - } - }, - { - "if": "lit=no", - "then": { - "en": "This road is not lit", - "nl": "Deze weg is niet verlicht" - } - }, - { - "if": "lit=sunset-sunrise", - "then": { - "en": "This road is lit at night", - "nl": "Deze weg is 's nachts verlicht" - }, - "hideInAnswer": true - }, - { - "if": "lit=24/7", - "then": { - "en": "This road is lit 24/7", - "nl": "Deze weg is 24/7 verlicht" - } - } - ] - }, - { - "#": "Is this a cyclestreet? (For a road)", - "question": { - "en": "Is this a cyclestreet?", - "nl": "Is dit een fietsstraat?" - }, - "condition": { - "and": [ - "highway!=cycleway", - "highway!=path" - ] - }, - "mappings": [ - { - "if": "cyclestreet=yes", - "then": { - "en": "This is a cyclestreet, and a 30km/h zone.", - "nl": "Dit is een fietsstraat, en dus een 30km/h zone" - }, - "addExtraTags": [ - "overtaking:motor_vehicle=no", - "maxspeed=30" - ], - "hideInAnswer": "_country!=be" - }, - { - "if": "cyclestreet=yes", - "then": { - "en": "This is a cyclestreet", - "nl": "Dit is een fietsstraat" - }, - "hideInAnswer": "_country=be" - }, - { - "if": "cyclestreet=", - "then": { - "en": "This is not a cyclestreet.", - "nl": "Dit is geen fietsstraat" - }, - "addExtraTags": [ - "overtaking:motor_vehicle=" - ] - } - ] - }, - { - "#": "Maxspeed (for road)", - "render": { - "en": "The maximum speed on this road is {maxspeed} km/h", - "nl": "De maximumsnelheid op deze weg is {maxspeed} km/u" - }, - "freeform": { - "key": "maxspeed", - "type": "nat" - }, - "condition": { - "and": [ - "highway!=cycleway", - "highway!=path" - ] - }, - "mappings": [ - { - "if": "maxspeed=20", - "then": { - "en": "The maximum speed is 20 km/h", - "nl": "De maximumsnelheid is 20 km/u" - } - }, - { - "if": "maxspeed=30", - "then": { - "en": "The maximum speed is 30 km/h", - "nl": "De maximumsnelheid is 30 km/u" - } - }, - { - "if": "maxspeed=50", - "then": { - "en": "The maximum speed is 50 km/h", - "nl": "De maximumsnelheid is 50 km/u" - } - }, - { - "if": "maxspeed=70", - "then": { - "en": "The maximum speed is 70 km/h", - "nl": "De maximumsnelheid is 70 km/u" - } - }, - { - "if": "maxspeed=90", - "then": { - "en": "The maximum speed is 90 km/h", - "nl": "De maximumsnelheid is 90 km/u" - } - } - ], - "question": { - "en": "What is the maximum speed in this street?", - "nl": "Wat is de maximumsnelheid in deze straat?" - } - }, - { - "#": "Cycleway:surface", - "render": { - "en": "This cyleway is made of {cycleway:surface}", - "nl": "Dit fietspad is gemaakt van {cycleway:surface}" - }, - "freeform": { - "key": "cycleway:surface" - }, - "condition": { - "or": [ - "cycleway=shared_lane", - "cycleway=lane", - "cycleway=track" - ] - }, - "mappings": [ - { - "if": "cycleway:surface=unpaved", - "then": { - "en": "This cycleway is unpaved", - "nl": "Dit fietspad is onverhard" - }, - "hideInAnswer": true - }, - { - "if": "cycleway:surface=paved", - "then": { - "en": "This cycleway is paved", - "nl": "Dit fietspad is geplaveid" - }, - "hideInAnswer": true - }, - { - "if": "cycleway:surface=asphalt", - "then": { - "en": "This cycleway is made of asphalt", - "nl": "Dit fietspad is gemaakt van asfalt" - } - }, - { - "if": "cycleway:surface=paving_stones", - "then": { - "en": "This cycleway is made of smooth paving stones", - "nl": "Dit fietspad is gemaakt van straatstenen" - } - }, - { - "if": "cycleway:surface=concrete", - "then": { - "en": "This cycleway is made of concrete", - "nl": "Dit fietspad is gemaakt van beton" - } - }, - { - "if": "cycleway:surface=cobblestone", - "then": { - "en": "This cycleway is made of cobblestone (unhewn or sett)", - "nl": "Dit fietspad is gemaakt van kasseien (natuurlijk of verwerkt)" - }, - "hideInAnswer": true - }, - { - "if": "cycleway:surface=unhewn_cobblestone", - "then": { - "en": "This cycleway is made of raw, natural cobblestone", - "nl": "Dit fietspad is gemaakt van ruwe, natuurlijke kasseien" - } - }, - { - "if": "cycleway:surface=sett", - "then": { - "en": "This cycleway is made of flat, square cobblestone", - "nl": "Dit fietspad is gemaakt van vlakke, rechthoekige kasseien" - } - }, - { - "if": "cycleway:surface=wood", - "then": { - "en": "This cycleway is made of wood", - "nl": "Dit fietspad is gemaakt van hout" - } - }, - { - "if": "cycleway:surface=gravel", - "then": { - "en": "This cycleway is made of gravel", - "nl": "Dit fietspad is gemaakt van grind" - } - }, - { - "if": "cycleway:surface=fine_gravel", - "then": { - "en": "This cycleway is made of fine gravel", - "nl": "Dit fietspad is gemaakt van fijn grind" - } - }, - { - "if": "cycleway:surface=pebblestone", - "then": { - "en": "This cycleway is made of pebblestone", - "nl": "Dit fietspad is gemaakt van kiezelsteentjes" - } - }, - { - "if": "cycleway:surface=ground", - "then": { - "en": "This cycleway is made from raw ground", - "nl": "Dit fietspad is gemaakt van aarde" - } - } - ], - "question": { - "en": "What is the surface of the cycleway made from?", - "nl": "Waaruit is het oppervlak van het fietspad van gemaakt?" - } - }, - { - "#": "Cycleway:smoothness", - "question": { - "en": "What is the smoothness of this cycleway?", - "nl": "Wat is de kwaliteit van dit fietspad?" - }, - "condition": { - "or": [ - "cycleway=shared_lane", - "cycleway=lane", - "cycleway=track" - ] - }, - "mappings": [ - { - "if": "cycleway:smoothness=excellent", - "then": { - "en": "Usable for thin rollers: rollerblade, skateboard", - "nl": "Geschikt voor fijne rollers: rollerblade, skateboard" - } - }, - { - "if": "cycleway:smoothness=good", - "then": { - "en": "Usable for thin wheels: racing bike", - "nl": "Geschikt voor fijne wielen: racefiets" - } - }, - { - "if": "cycleway:smoothness=intermediate", - "then": { - "en": "Usable for normal wheels: city bike, wheelchair, scooter", - "nl": "Geschikt voor normale wielen: stadsfiets, rolstoel, scooter" - } - }, - { - "if": "cycleway:smoothness=bad", - "then": { - "en": "Usable for robust wheels: trekking bike, car, rickshaw", - "nl": "Geschikt voor brede wielen: trekfiets, auto, rickshaw" - } - }, - { - "if": "cycleway:smoothness=very_bad", - "then": { - "en": "Usable for vehicles with high clearance: light duty off-road vehicle", - "nl": "Geschikt voor voertuigen met hoge banden: lichte terreinwagen" - } - }, - { - "if": "cycleway:smoothness=horrible", - "then": { - "en": "Usable for off-road vehicles: heavy duty off-road vehicle", - "nl": "Geschikt voor terreinwagens: zware terreinwagen" - } - }, - { - "if": "cycleway:smoothness=very_horrible", - "then": { - "en": "Usable for specialized off-road vehicles: tractor, ATV", - "nl": "Geschikt voor gespecialiseerde terreinwagens: tractor, alleterreinwagen" - } - }, - { - "if": "cycleway:smoothness=impassable", - "then": { - "en": "Impassable / No wheeled vehicle", - "nl": "Niet geschikt voor voertuigen met wielen" - } - } - ] - }, - { - "#": "Surface of the road", - "render": { - "en": "This road is made of {surface}", - "nl": "Deze weg is gemaakt van {surface}" - }, - "freeform": { - "key": "surface" - }, - "mappings": [ - { - "if": "surface=unpaved", - "then": { - "en": "This cycleway is unhardened", - "nl": "Dit fietspad is onverhard" - }, - "hideInAnswer": true - }, - { - "if": "surface=paved", - "then": { - "en": "This cycleway is paved", - "nl": "Dit fietspad is geplaveid" - }, - "hideInAnswer": true - }, - { - "if": "surface=asphalt", - "then": { - "en": "This cycleway is made of asphalt", - "nl": "Dit fietspad is gemaakt van asfalt" - } - }, - { - "if": "surface=paving_stones", - "then": { - "en": "This cycleway is made of smooth paving stones", - "nl": "Dit fietspad is gemaakt van straatstenen" - } - }, - { - "if": "surface=concrete", - "then": { - "en": "This cycleway is made of concrete", - "nl": "Dit fietspad is gemaakt van beton" - } - }, - { - "if": "surface=cobblestone", - "then": { - "en": "This cycleway is made of cobblestone (unhewn or sett)", - "nl": "Dit fietspad is gemaakt van kasseien (natuurlijk of verwerkt)" - }, - "hideInAnswer": true - }, - { - "if": "surface=unhewn_cobblestone", - "then": { - "en": "This cycleway is made of raw, natural cobblestone", - "nl": "Dit fietspad is gemaakt van ruwe, natuurlijke kasseien" - } - }, - { - "if": "surface=sett", - "then": { - "en": "This cycleway is made of flat, square cobblestone", - "nl": "Dit fietspad is gemaakt van vlakke, rechthoekige kasseien" - } - }, - { - "if": "surface=wood", - "then": { - "en": "This cycleway is made of wood", - "nl": "Dit fietspad is gemaakt van hout" - } - }, - { - "if": "surface=gravel", - "then": { - "en": "This cycleway is made of gravel", - "nl": "Dit fietspad is gemaakt van grind" - } - }, - { - "if": "surface=fine_gravel", - "then": { - "en": "This cycleway is made of fine gravel", - "nl": "Dit fietspad is gemaakt van fijn grind" - } - }, - { - "if": "surface=pebblestone", - "then": { - "en": "This cycleway is made of pebblestone", - "nl": "Dit fietspad is gemaakt van kiezelsteentjes" - } - }, - { - "if": "surface=ground", - "then": { - "en": "This cycleway is made from raw ground", - "nl": "Dit fietspad is gemaakt van aarde" - } - } - ], - "question": { - "en": "What is the surface of the street made from?", - "nl": "Waaruit is het oppervlak van de straat gemaakt?" - } - }, - { - "#": "Surface of the street", - "question": { - "en": "What is the smoothness of this street?", - "nl": "Wat is de kwaliteit van deze straat?" - }, - "condition": { - "or": [ - "cycleway=no", - "highway=cycleway" - ] - }, - "mappings": [ - { - "if": "smoothness=excellent", - "then": { - "en": "Usable for thin rollers: rollerblade, skateboard" - } - }, - { - "if": "smoothness=good", - "then": { - "en": "Usable for thin wheels: racing bike" - } - }, - { - "if": "smoothness=intermediate", - "then": { - "en": "Usable for normal wheels: city bike, wheelchair, scooter" - } - }, - { - "if": "smoothness=bad", - "then": { - "en": "Usable for robust wheels: trekking bike, car, rickshaw" - } - }, - { - "if": "smoothness=very_bad", - "then": { - "en": "Usable for vehicles with high clearance: light duty off-road vehicle" - } - }, - { - "if": "smoothness=horrible", - "then": { - "en": "Usable for off-road vehicles: heavy duty off-road vehicle" - } - }, - { - "if": "smoothness=very_horrible", - "then": { - "en": "Usable for specialized off-road vehicles: tractor, ATV" - } - }, - { - "if": "smoothness=impassable", - "then": { - "en": "Impassable / No wheeled vehicle" - } - } - ] - }, - { - "#": "width:carriageway", - "condition": { - "and": [ - "highway!=cycleway", - "highway!=path" - ] - }, - "render": { - "en": "The carriage width of this road is {width:carriageway}m", - "nl": "De breedte van deze rijbaan in deze straat is {width:carriageway}m" - }, - "freeform": { - "key": "width:carriageway", - "type": "length", - "helperArgs": [ - "20", - "map" - ] - }, - "question": { - "en": "What is the carriage width of this road (in meters)?", - "nl": "Hoe breed is de rijbaan in deze straat (in meters)?" - } - }, - { - "question": { - "en": "What traffic sign does this cycleway have?", - "nl": "Welk verkeersbord heeft dit fietspad?" - }, - "condition": { - "or": [ - "cycleway=lane", - "cycleway=track" - ] - }, - "mappings": [ - { - "if": "cycleway:traffic_sign=BE:D7", - "then": { - "en": "Compulsory cycleway ", - "nl": "Verplicht fietspad " - }, - "hideInAnswer": "_country!=be" - }, - { - "if": "cycleway:traffic_sign~BE:D7;.*", - "then": { - "en": "Compulsory cycleway (with supplementary sign)
", - "nl": "Verplicht fietspad (met onderbord)
" - }, - "hideInAnswer": true - }, - { - "if": "cycleway:traffic_sign=BE:D9", - "then": { - "en": "Segregated foot/cycleway ", - "nl": "Afgescheiden voet-/fietspad " - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:foot=designated", - "cycleway:segregated=yes" - ] - }, - { - "if": "cycleway:traffic_sign=BE:D10", - "then": { - "en": "Unsegregated foot/cycleway ", - "nl": "Gedeeld voet-/fietspad " - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:foot=designated", - "cycleway:segregated=no" - ] - }, - { - "if": "cycleway:traffic_sign=none", - "then": { - "en": "No traffic sign present", - "nl": "Geen verkeersbord aanwezig" - } - } - ] - }, - { - "question": { - "en": "What traffic sign does this cycleway have?", - "nl": "Welk verkeersbord heeft dit fietspad?" - }, - "condition": { - "or": [ - "highway=cycleway", - "highway=path" - ] - }, - "mappings": [ - { - "if": "traffic_sign=BE:D7", - "then": { - "en": "Compulsory cycleway ", - "nl": "Verplicht fietspad " - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "bicycle=designated", - "mofa=designated", - "moped=yes", - "speed_pedelec=yes" - ] - }, - { - "if": "traffic_sign~BE:D7;.*", - "then": { - "en": "Compulsory cycleway (with supplementary sign)
", - "nl": "Verplicht fietspad (met onderbord)
" - }, - "hideInAnswer": true - }, - { - "if": "traffic_sign=BE:D9", - "then": { - "en": "Segregated foot/cycleway ", - "nl": "Afgescheiden voet-/fietspad " - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "foot=designated", - "bicycle=designated", - "mofa=designated", - "moped=no", - "speed_pedelec=no", - "segregated=yes" - ] - }, - { - "if": "traffic_sign=BE:D10", - "then": { - "en": "Unsegregated foot/cycleway ", - "nl": "Gedeeld voet-/fietspad " - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "foot=designated", - "bicycle=designated", - "mofa=designated", - "moped=no", - "speed_pedelec=no", - "segregated=no" - ] - }, - { - "if": "traffic_sign=none", - "then": { - "en": "No traffic sign present", - "nl": "Geen verkeersbord aanwezig" - } - } - ] - }, - { - "question": { - "en": "Does the traffic sign D7 () have a supplementary sign?", - "nl": "Heeft het verkeersbord D7 () een onderbord?" - }, - "condition": { - "or": [ - "cycleway:traffic_sign=BE:D7", - "cycleway:traffic_sign~BE:D7;.*" - ] - }, - "mappings": [ - { - "if": "cycleway:traffic_sign=BE:D7;BE:M6", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:moped=designated" - ] - }, - { - "if": "cycleway:traffic_sign=BE:D7;BE:M13", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:speed_pedelec=designated" - ] - }, - { - "if": "cycleway:traffic_sign=BE:D7;BE:M14", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:moped=designated", - "cycleway:speed_pedelec=designated" - ] - }, - { - "if": "cycleway:traffic_sign=BE:D7;BE:M7", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:moped=no" - ] - }, - { - "if": "cycleway:traffic_sign=BE:D7;BE:M15", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:speed_pedelec=no" - ] - }, - { - "if": "cycleway:traffic_sign=BE:D7;BE:M16", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "cycleway:moped=designated", - "cycleway:speed_pedelec=no" - ] - }, - { - "if": "cycleway:traffic_sign:supplementary=none", - "then": { - "en": "No supplementary traffic sign present", - "nl": "Geen onderbord aanwezig" - } - } - ] - }, - { - "question": { - "en": "Does the traffic sign D7 () have a supplementary sign?", - "nl": "Heeft het verkeersbord D7 () een onderbord?" - }, - "condition": { - "or": [ - "traffic_sign=BE:D7", - "traffic_sign~BE:D7;.*" - ] - }, - "mappings": [ - { - "if": "traffic_sign=BE:D7;BE:M6", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "moped=designated" - ] - }, - { - "if": "traffic_sign=BE:D7;BE:M13", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "speed_pedelec=designated" - ] - }, - { - "if": "traffic_sign=BE:D7;BE:M14", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "moped=designated", - "speed_pedelec=designated" - ] - }, - { - "if": "traffic_sign=BE:D7;BE:M7", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "moped=no" - ] - }, - { - "if": ":traffic_sign=BE:D7;BE:M15", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "speed_pedelec=no" - ] - }, - { - "if": "traffic_sign=BE:D7;BE:M16", - "then": { - "en": "", - "nl": "" - }, - "hideInAnswer": "_country!=be", - "addExtraTags": [ - "moped=designated", - "speed_pedelec=no" - ] - }, - { - "if": "traffic_sign:supplementary=none", - "then": { - "en": "No supplementary traffic sign present", - "nl": "Geen onderbord aanwezig" - } - } - ] - }, - { - "render": { - "en": "The buffer besides this cycleway is {cycleway:buffer} m", - "nl": "De schrikafstand van dit fietspad is {cycleway:buffer} m" - }, - "question": { - "en": "How wide is the gap between the cycleway and the road?", - "nl": "Hoe breed is de ruimte tussen het fietspad en de weg?" - }, - "condition": { - "or": [ - "cycleway=track", - "cycleway=lane" - ] - }, - "freeform": { - "key": "cycleway:buffer", - "type": "length", - "helperArgs": [ - "20", - "map" - ] - } - }, - { - "question": { - "en": "How is this cycleway separated from the road?", - "nl": "Hoe is dit fietspad gescheiden van de weg?" - }, - "condition": { - "or": [ - "cycleway=track", - "cycleway=lane" - ] - }, - "mappings": [ - { - "if": "cycleway:separation=dashed_line", - "then": { - "en": "This cycleway is separated by a dashed line", - "nl": "Dit fietspad is gescheiden van de weg met een onderbroken streep" - } - }, - { - "if": "cycleway:separation=solid_line", - "then": { - "en": "This cycleway is separated by a solid line", - "nl": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" - } - }, - { - "if": "cycleway:separation=parking_lane", - "then": { - "en": "This cycleway is separated by a parking lane", - "nl": "Dit fietspad is gescheiden van de weg met parkeervakken" - } - }, - { - "if": "cycleway:separation=kerb", - "then": { - "en": "This cycleway is separated by a kerb", - "nl": "Dit fietspad is gescheiden van de weg met een stoeprand" - } - } - ] - }, - { - "question": { - "en": "How is this cycleway separated from the road?", - "nl": "Hoe is dit fietspad gescheiden van de weg?" - }, - "condition": { - "or": [ - "highway=cycleway", - "highway=path" - ] - }, - "mappings": [ - { - "if": "separation=dashed_line", - "then": { - "en": "This cycleway is separated by a dashed line", - "nl": "Dit fietspad is gescheiden van de weg met een onderbroken streep" - } - }, - { - "if": "separation=solid_line", - "then": { - "en": "This cycleway is separated by a solid line", - "nl": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" - } - }, - { - "if": "separation=parking_lane", - "then": { - "en": "This cycleway is separated by a parking lane", - "nl": "Dit fietspad is gescheiden van de weg met parkeervakken" - } - }, - { - "if": "separation=kerb", - "then": { - "en": "This cycleway is separated by a kerb", - "nl": "Dit fietspad is gescheiden van de weg met een stoeprand" - } - } - ] - } - ], - "icon": { - "render": "./assets/themes/cycle_infra/bicycleway.svg" - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "rgba(170, 170, 170, 0.7)", - "mappings": [ - { - "if": "highway=cycleway", - "then": "rgba(0, 189, 141, 0.7)" - }, - { - "if": "highway=path", - "then": "rgba(204, 74, 207, 0.7)" - }, - { - "if": "cycleway=track", - "then": "rgba(113, 3, 200, 0.7)" - }, - { - "if": "cycleway=shared_lane", - "then": "rgba(74, 59, 247, 0.7)" - }, - { - "if": "cycleway=lane", - "then": "rgba(254, 155, 6, 0.9)" - }, - { - "if": "cyclestreet=yes", - "then": "rgba(57, 159, 191, 0.7)" - } - ] - }, - "dashArray": { - "render": "", - "mappings": [ - { - "if": { - "or": [ - "oneway=yes", - { - "or": [ + "minzoom": 16, + "source": { + "osmTags": { + "or": [ "highway=cycleway", - "highway=path" - ] - } - ] + "cycleway=lane", + "cycleway=shared_lane", + "cycleway=track", + "cyclestreet=yes", + "highway=residential", + "highway=tertiary", + "highway=unclassified", + "highway=primary", + "highway=secondary", + { + "and": [ + "highway=path", + "bicycle=designated" + ] + } + ] + } + }, + "calculatedTags": [ + "_comfort_score=feat.score('https://raw.githubusercontent.com/pietervdvn/AspectedRouting/master/Examples/bicycle/aspects/bicycle.comfort.json')" + ], + "title": { + "render": { + "en": "Cycleways", + "nl": "Fietspaden" }, - "then": "" - }, - { - "if": "cycleway=track", - "then": "" - }, - { - "if": "cycleway=shared_lane", - "then": "15 30" - }, - { - "if": "cycleway=lane", - "then": "25 15 15 15 25" - }, - { - "if": "cyclestreet=yes", - "then": "" - } - ] - } + "mappings": [ + { + "if": { + "or": [ + "highway=cycleway", + "highway=path" + ] + }, + "then": { + "nl": "Fietsweg", + "en": "Cycleway" + } + }, + { + "if": "cycleway=shared_lane", + "then": { + "nl": "Fietssuggestiestrook", + "en": "Shared lane" + } + }, + { + "if": "cycleway=lane", + "then": { + "nl": "Fietsstrook", + "en": "Bike lane" + } + }, + { + "if": "cycleway=track", + "then": { + "en": "Cycleway next to the road", + "nl": "Fietsweg naast de weg" + } + }, + { + "if": "cyclestreet=yes", + "then": { + "nl": "Fietsstraat", + "en": "Cyclestreet" + } + } + ] + }, + "description": {}, + "tagRenderings": [ + { + "#": "Cycleway type for a road", + "question": { + "en": "What kind of cycleway is here?", + "nl": "Wat voor fietspad is hier?" + }, + "condition": { + "and": [ + "highway!=cycleway", + "highway!=path" + ] + }, + "mappings": [ + { + "if": "cycleway=shared_lane", + "then": { + "en": "There is a shared lane", + "nl": "Er is een fietssuggestiestrook" + } + }, + { + "if": "cycleway=lane", + "then": { + "en": "There is a lane next to the road (separated with paint)", + "nl": "Er is een fietspad aangrenzend aan de weg (gescheiden met verf)" + } + }, + { + "if": "cycleway=track", + "then": { + "en": "There is a track, but no cycleway drawn separately from this road on the map.", + "nl": "Er is een fietspad (los van de weg), maar geen fietspad afzonderlijk getekend naast deze weg." + } + }, + { + "if": "cycleway=separate", + "then": { + "en": "There is a separately drawn cycleway", + "nl": "Er is een apart getekend fietspad." + } + }, + { + "if": "cycleway=no", + "then": { + "en": "There is no cycleway", + "nl": "Er is geen fietspad aanwezig" + }, + "hideInAnswer": "cycleway=opposite" + }, + { + "if": "cycleway=no", + "then": { + "en": "There is no cycleway", + "nl": "Er is geen fietspad aanwezig" + }, + "hideInAnswer": "cycleway!=opposite", + "addExtraTags": [ + "oneway:bicycle=no", + "fixme=Changed from cycleway=opposite" + ] + } + ] + }, + { + "#": "is lit?", + "question": { + "en": "Is this street lit?", + "nl": "Is deze weg verlicht?" + }, + "mappings": [ + { + "if": "lit=yes", + "then": { + "en": "This street is lit", + "nl": "Deze weg is verlicht" + } + }, + { + "if": "lit=no", + "then": { + "en": "This road is not lit", + "nl": "Deze weg is niet verlicht" + } + }, + { + "if": "lit=sunset-sunrise", + "then": { + "en": "This road is lit at night", + "nl": "Deze weg is 's nachts verlicht" + }, + "hideInAnswer": true + }, + { + "if": "lit=24/7", + "then": { + "en": "This road is lit 24/7", + "nl": "Deze weg is 24/7 verlicht" + } + } + ] + }, + { + "#": "Is this a cyclestreet? (For a road)", + "question": { + "en": "Is this a cyclestreet?", + "nl": "Is dit een fietsstraat?" + }, + "condition": { + "and": [ + "highway!=cycleway", + "highway!=path" + ] + }, + "mappings": [ + { + "if": "cyclestreet=yes", + "then": { + "en": "This is a cyclestreet, and a 30km/h zone.", + "nl": "Dit is een fietsstraat, en dus een 30km/h zone" + }, + "addExtraTags": [ + "overtaking:motor_vehicle=no", + "maxspeed=30" + ], + "hideInAnswer": "_country!=be" + }, + { + "if": "cyclestreet=yes", + "then": { + "en": "This is a cyclestreet", + "nl": "Dit is een fietsstraat" + }, + "hideInAnswer": "_country=be" + }, + { + "if": "cyclestreet=", + "then": { + "en": "This is not a cyclestreet.", + "nl": "Dit is geen fietsstraat" + }, + "addExtraTags": [ + "overtaking:motor_vehicle=" + ] + } + ] + }, + { + "#": "Maxspeed (for road)", + "render": { + "en": "The maximum speed on this road is {maxspeed} km/h", + "nl": "De maximumsnelheid op deze weg is {maxspeed} km/u" + }, + "freeform": { + "key": "maxspeed", + "type": "nat" + }, + "condition": { + "and": [ + "highway!=cycleway", + "highway!=path" + ] + }, + "mappings": [ + { + "if": "maxspeed=20", + "then": { + "en": "The maximum speed is 20 km/h", + "nl": "De maximumsnelheid is 20 km/u" + } + }, + { + "if": "maxspeed=30", + "then": { + "en": "The maximum speed is 30 km/h", + "nl": "De maximumsnelheid is 30 km/u" + } + }, + { + "if": "maxspeed=50", + "then": { + "en": "The maximum speed is 50 km/h", + "nl": "De maximumsnelheid is 50 km/u" + } + }, + { + "if": "maxspeed=70", + "then": { + "en": "The maximum speed is 70 km/h", + "nl": "De maximumsnelheid is 70 km/u" + } + }, + { + "if": "maxspeed=90", + "then": { + "en": "The maximum speed is 90 km/h", + "nl": "De maximumsnelheid is 90 km/u" + } + } + ], + "question": { + "en": "What is the maximum speed in this street?", + "nl": "Wat is de maximumsnelheid in deze straat?" + } + }, + { + "#": "Cycleway:surface", + "render": { + "en": "This cyleway is made of {cycleway:surface}", + "nl": "Dit fietspad is gemaakt van {cycleway:surface}" + }, + "freeform": { + "key": "cycleway:surface" + }, + "condition": { + "or": [ + "cycleway=shared_lane", + "cycleway=lane", + "cycleway=track" + ] + }, + "mappings": [ + { + "if": "cycleway:surface=unpaved", + "then": { + "en": "This cycleway is unpaved", + "nl": "Dit fietspad is onverhard" + }, + "hideInAnswer": true + }, + { + "if": "cycleway:surface=paved", + "then": { + "en": "This cycleway is paved", + "nl": "Dit fietspad is geplaveid" + }, + "hideInAnswer": true + }, + { + "if": "cycleway:surface=asphalt", + "then": { + "en": "This cycleway is made of asphalt", + "nl": "Dit fietspad is gemaakt van asfalt" + } + }, + { + "if": "cycleway:surface=paving_stones", + "then": { + "en": "This cycleway is made of smooth paving stones", + "nl": "Dit fietspad is gemaakt van straatstenen" + } + }, + { + "if": "cycleway:surface=concrete", + "then": { + "en": "This cycleway is made of concrete", + "nl": "Dit fietspad is gemaakt van beton" + } + }, + { + "if": "cycleway:surface=cobblestone", + "then": { + "en": "This cycleway is made of cobblestone (unhewn or sett)", + "nl": "Dit fietspad is gemaakt van kasseien (natuurlijk of verwerkt)" + }, + "hideInAnswer": true + }, + { + "if": "cycleway:surface=unhewn_cobblestone", + "then": { + "en": "This cycleway is made of raw, natural cobblestone", + "nl": "Dit fietspad is gemaakt van ruwe, natuurlijke kasseien" + } + }, + { + "if": "cycleway:surface=sett", + "then": { + "en": "This cycleway is made of flat, square cobblestone", + "nl": "Dit fietspad is gemaakt van vlakke, rechthoekige kasseien" + } + }, + { + "if": "cycleway:surface=wood", + "then": { + "en": "This cycleway is made of wood", + "nl": "Dit fietspad is gemaakt van hout" + } + }, + { + "if": "cycleway:surface=gravel", + "then": { + "en": "This cycleway is made of gravel", + "nl": "Dit fietspad is gemaakt van grind" + } + }, + { + "if": "cycleway:surface=fine_gravel", + "then": { + "en": "This cycleway is made of fine gravel", + "nl": "Dit fietspad is gemaakt van fijn grind" + } + }, + { + "if": "cycleway:surface=pebblestone", + "then": { + "en": "This cycleway is made of pebblestone", + "nl": "Dit fietspad is gemaakt van kiezelsteentjes" + } + }, + { + "if": "cycleway:surface=ground", + "then": { + "en": "This cycleway is made from raw ground", + "nl": "Dit fietspad is gemaakt van aarde" + } + } + ], + "question": { + "en": "What is the surface of the cycleway made from?", + "nl": "Waaruit is het oppervlak van het fietspad van gemaakt?" + } + }, + { + "#": "Cycleway:smoothness", + "question": { + "en": "What is the smoothness of this cycleway?", + "nl": "Wat is de kwaliteit van dit fietspad?" + }, + "condition": { + "or": [ + "cycleway=shared_lane", + "cycleway=lane", + "cycleway=track" + ] + }, + "mappings": [ + { + "if": "cycleway:smoothness=excellent", + "then": { + "en": "Usable for thin rollers: rollerblade, skateboard", + "nl": "Geschikt voor fijne rollers: rollerblade, skateboard" + } + }, + { + "if": "cycleway:smoothness=good", + "then": { + "en": "Usable for thin wheels: racing bike", + "nl": "Geschikt voor fijne wielen: racefiets" + } + }, + { + "if": "cycleway:smoothness=intermediate", + "then": { + "en": "Usable for normal wheels: city bike, wheelchair, scooter", + "nl": "Geschikt voor normale wielen: stadsfiets, rolstoel, scooter" + } + }, + { + "if": "cycleway:smoothness=bad", + "then": { + "en": "Usable for robust wheels: trekking bike, car, rickshaw", + "nl": "Geschikt voor brede wielen: trekfiets, auto, rickshaw" + } + }, + { + "if": "cycleway:smoothness=very_bad", + "then": { + "en": "Usable for vehicles with high clearance: light duty off-road vehicle", + "nl": "Geschikt voor voertuigen met hoge banden: lichte terreinwagen" + } + }, + { + "if": "cycleway:smoothness=horrible", + "then": { + "en": "Usable for off-road vehicles: heavy duty off-road vehicle", + "nl": "Geschikt voor terreinwagens: zware terreinwagen" + } + }, + { + "if": "cycleway:smoothness=very_horrible", + "then": { + "en": "Usable for specialized off-road vehicles: tractor, ATV", + "nl": "Geschikt voor gespecialiseerde terreinwagens: tractor, alleterreinwagen" + } + }, + { + "if": "cycleway:smoothness=impassable", + "then": { + "en": "Impassable / No wheeled vehicle", + "nl": "Niet geschikt voor voertuigen met wielen" + } + } + ] + }, + { + "#": "Surface of the road", + "render": { + "en": "This road is made of {surface}", + "nl": "Deze weg is gemaakt van {surface}" + }, + "freeform": { + "key": "surface" + }, + "mappings": [ + { + "if": "surface=unpaved", + "then": { + "en": "This cycleway is unhardened", + "nl": "Dit fietspad is onverhard" + }, + "hideInAnswer": true + }, + { + "if": "surface=paved", + "then": { + "en": "This cycleway is paved", + "nl": "Dit fietspad is geplaveid" + }, + "hideInAnswer": true + }, + { + "if": "surface=asphalt", + "then": { + "en": "This cycleway is made of asphalt", + "nl": "Dit fietspad is gemaakt van asfalt" + } + }, + { + "if": "surface=paving_stones", + "then": { + "en": "This cycleway is made of smooth paving stones", + "nl": "Dit fietspad is gemaakt van straatstenen" + } + }, + { + "if": "surface=concrete", + "then": { + "en": "This cycleway is made of concrete", + "nl": "Dit fietspad is gemaakt van beton" + } + }, + { + "if": "surface=cobblestone", + "then": { + "en": "This cycleway is made of cobblestone (unhewn or sett)", + "nl": "Dit fietspad is gemaakt van kasseien (natuurlijk of verwerkt)" + }, + "hideInAnswer": true + }, + { + "if": "surface=unhewn_cobblestone", + "then": { + "en": "This cycleway is made of raw, natural cobblestone", + "nl": "Dit fietspad is gemaakt van ruwe, natuurlijke kasseien" + } + }, + { + "if": "surface=sett", + "then": { + "en": "This cycleway is made of flat, square cobblestone", + "nl": "Dit fietspad is gemaakt van vlakke, rechthoekige kasseien" + } + }, + { + "if": "surface=wood", + "then": { + "en": "This cycleway is made of wood", + "nl": "Dit fietspad is gemaakt van hout" + } + }, + { + "if": "surface=gravel", + "then": { + "en": "This cycleway is made of gravel", + "nl": "Dit fietspad is gemaakt van grind" + } + }, + { + "if": "surface=fine_gravel", + "then": { + "en": "This cycleway is made of fine gravel", + "nl": "Dit fietspad is gemaakt van fijn grind" + } + }, + { + "if": "surface=pebblestone", + "then": { + "en": "This cycleway is made of pebblestone", + "nl": "Dit fietspad is gemaakt van kiezelsteentjes" + } + }, + { + "if": "surface=ground", + "then": { + "en": "This cycleway is made from raw ground", + "nl": "Dit fietspad is gemaakt van aarde" + } + } + ], + "question": { + "en": "What is the surface of the street made from?", + "nl": "Waaruit is het oppervlak van de straat gemaakt?" + } + }, + { + "#": "Surface of the street", + "question": { + "en": "What is the smoothness of this street?", + "nl": "Wat is de kwaliteit van deze straat?" + }, + "condition": { + "or": [ + "cycleway=no", + "highway=cycleway" + ] + }, + "mappings": [ + { + "if": "smoothness=excellent", + "then": { + "en": "Usable for thin rollers: rollerblade, skateboard" + } + }, + { + "if": "smoothness=good", + "then": { + "en": "Usable for thin wheels: racing bike" + } + }, + { + "if": "smoothness=intermediate", + "then": { + "en": "Usable for normal wheels: city bike, wheelchair, scooter" + } + }, + { + "if": "smoothness=bad", + "then": { + "en": "Usable for robust wheels: trekking bike, car, rickshaw" + } + }, + { + "if": "smoothness=very_bad", + "then": { + "en": "Usable for vehicles with high clearance: light duty off-road vehicle" + } + }, + { + "if": "smoothness=horrible", + "then": { + "en": "Usable for off-road vehicles: heavy duty off-road vehicle" + } + }, + { + "if": "smoothness=very_horrible", + "then": { + "en": "Usable for specialized off-road vehicles: tractor, ATV" + } + }, + { + "if": "smoothness=impassable", + "then": { + "en": "Impassable / No wheeled vehicle" + } + } + ] + }, + { + "#": "width:carriageway", + "condition": { + "and": [ + "highway!=cycleway", + "highway!=path" + ] + }, + "render": { + "en": "The carriage width of this road is {width:carriageway}m", + "nl": "De breedte van deze rijbaan in deze straat is {width:carriageway}m" + }, + "freeform": { + "key": "width:carriageway", + "type": "length", + "helperArgs": [ + "20", + "map" + ] + }, + "question": { + "en": "What is the carriage width of this road (in meters)?", + "nl": "Hoe breed is de rijbaan in deze straat (in meters)?" + } + }, + { + "question": { + "en": "What traffic sign does this cycleway have?", + "nl": "Welk verkeersbord heeft dit fietspad?" + }, + "condition": { + "or": [ + "cycleway=lane", + "cycleway=track" + ] + }, + "mappings": [ + { + "if": "cycleway:traffic_sign=BE:D7", + "then": { + "en": "Compulsory cycleway ", + "nl": "Verplicht fietspad " + }, + "hideInAnswer": "_country!=be" + }, + { + "if": "cycleway:traffic_sign~BE:D7;.*", + "then": { + "en": "Compulsory cycleway (with supplementary sign)
", + "nl": "Verplicht fietspad (met onderbord)
" + }, + "hideInAnswer": true + }, + { + "if": "cycleway:traffic_sign=BE:D9", + "then": { + "en": "Segregated foot/cycleway ", + "nl": "Afgescheiden voet-/fietspad " + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:foot=designated", + "cycleway:segregated=yes" + ] + }, + { + "if": "cycleway:traffic_sign=BE:D10", + "then": { + "en": "Unsegregated foot/cycleway ", + "nl": "Gedeeld voet-/fietspad " + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:foot=designated", + "cycleway:segregated=no" + ] + }, + { + "if": "cycleway:traffic_sign=none", + "then": { + "en": "No traffic sign present", + "nl": "Geen verkeersbord aanwezig" + } + } + ] + }, + { + "question": { + "en": "What traffic sign does this cycleway have?", + "nl": "Welk verkeersbord heeft dit fietspad?" + }, + "condition": { + "or": [ + "highway=cycleway", + "highway=path" + ] + }, + "mappings": [ + { + "if": "traffic_sign=BE:D7", + "then": { + "en": "Compulsory cycleway ", + "nl": "Verplicht fietspad " + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "bicycle=designated", + "mofa=designated", + "moped=yes", + "speed_pedelec=yes" + ] + }, + { + "if": "traffic_sign~BE:D7;.*", + "then": { + "en": "Compulsory cycleway (with supplementary sign)
", + "nl": "Verplicht fietspad (met onderbord)
" + }, + "hideInAnswer": true + }, + { + "if": "traffic_sign=BE:D9", + "then": { + "en": "Segregated foot/cycleway ", + "nl": "Afgescheiden voet-/fietspad " + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "foot=designated", + "bicycle=designated", + "mofa=designated", + "moped=no", + "speed_pedelec=no", + "segregated=yes" + ] + }, + { + "if": "traffic_sign=BE:D10", + "then": { + "en": "Unsegregated foot/cycleway ", + "nl": "Gedeeld voet-/fietspad " + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "foot=designated", + "bicycle=designated", + "mofa=designated", + "moped=no", + "speed_pedelec=no", + "segregated=no" + ] + }, + { + "if": "traffic_sign=none", + "then": { + "en": "No traffic sign present", + "nl": "Geen verkeersbord aanwezig" + } + } + ] + }, + { + "question": { + "en": "Does the traffic sign D7 () have a supplementary sign?", + "nl": "Heeft het verkeersbord D7 () een onderbord?" + }, + "condition": { + "or": [ + "cycleway:traffic_sign=BE:D7", + "cycleway:traffic_sign~BE:D7;.*" + ] + }, + "mappings": [ + { + "if": "cycleway:traffic_sign=BE:D7;BE:M6", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:moped=designated" + ] + }, + { + "if": "cycleway:traffic_sign=BE:D7;BE:M13", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:speed_pedelec=designated" + ] + }, + { + "if": "cycleway:traffic_sign=BE:D7;BE:M14", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:moped=designated", + "cycleway:speed_pedelec=designated" + ] + }, + { + "if": "cycleway:traffic_sign=BE:D7;BE:M7", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:moped=no" + ] + }, + { + "if": "cycleway:traffic_sign=BE:D7;BE:M15", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:speed_pedelec=no" + ] + }, + { + "if": "cycleway:traffic_sign=BE:D7;BE:M16", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "cycleway:moped=designated", + "cycleway:speed_pedelec=no" + ] + }, + { + "if": "cycleway:traffic_sign:supplementary=none", + "then": { + "en": "No supplementary traffic sign present", + "nl": "Geen onderbord aanwezig" + } + } + ] + }, + { + "question": { + "en": "Does the traffic sign D7 () have a supplementary sign?", + "nl": "Heeft het verkeersbord D7 () een onderbord?" + }, + "condition": { + "or": [ + "traffic_sign=BE:D7", + "traffic_sign~BE:D7;.*" + ] + }, + "mappings": [ + { + "if": "traffic_sign=BE:D7;BE:M6", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "moped=designated" + ] + }, + { + "if": "traffic_sign=BE:D7;BE:M13", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "speed_pedelec=designated" + ] + }, + { + "if": "traffic_sign=BE:D7;BE:M14", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "moped=designated", + "speed_pedelec=designated" + ] + }, + { + "if": "traffic_sign=BE:D7;BE:M7", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "moped=no" + ] + }, + { + "if": ":traffic_sign=BE:D7;BE:M15", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "speed_pedelec=no" + ] + }, + { + "if": "traffic_sign=BE:D7;BE:M16", + "then": { + "en": "", + "nl": "" + }, + "hideInAnswer": "_country!=be", + "addExtraTags": [ + "moped=designated", + "speed_pedelec=no" + ] + }, + { + "if": "traffic_sign:supplementary=none", + "then": { + "en": "No supplementary traffic sign present", + "nl": "Geen onderbord aanwezig" + } + } + ] + }, + { + "render": { + "en": "The buffer besides this cycleway is {cycleway:buffer} m", + "nl": "De schrikafstand van dit fietspad is {cycleway:buffer} m" + }, + "question": { + "en": "How wide is the gap between the cycleway and the road?", + "nl": "Hoe breed is de ruimte tussen het fietspad en de weg?" + }, + "condition": { + "or": [ + "cycleway=track", + "cycleway=lane" + ] + }, + "freeform": { + "key": "cycleway:buffer", + "type": "length", + "helperArgs": [ + "20", + "map" + ] + } + }, + { + "question": { + "en": "How is this cycleway separated from the road?", + "nl": "Hoe is dit fietspad gescheiden van de weg?" + }, + "condition": { + "or": [ + "cycleway=track", + "cycleway=lane" + ] + }, + "mappings": [ + { + "if": "cycleway:separation=dashed_line", + "then": { + "en": "This cycleway is separated by a dashed line", + "nl": "Dit fietspad is gescheiden van de weg met een onderbroken streep" + } + }, + { + "if": "cycleway:separation=solid_line", + "then": { + "en": "This cycleway is separated by a solid line", + "nl": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" + } + }, + { + "if": "cycleway:separation=parking_lane", + "then": { + "en": "This cycleway is separated by a parking lane", + "nl": "Dit fietspad is gescheiden van de weg met parkeervakken" + } + }, + { + "if": "cycleway:separation=kerb", + "then": { + "en": "This cycleway is separated by a kerb", + "nl": "Dit fietspad is gescheiden van de weg met een stoeprand" + } + } + ] + }, + { + "question": { + "en": "How is this cycleway separated from the road?", + "nl": "Hoe is dit fietspad gescheiden van de weg?" + }, + "condition": { + "or": [ + "highway=cycleway", + "highway=path" + ] + }, + "mappings": [ + { + "if": "separation=dashed_line", + "then": { + "en": "This cycleway is separated by a dashed line", + "nl": "Dit fietspad is gescheiden van de weg met een onderbroken streep" + } + }, + { + "if": "separation=solid_line", + "then": { + "en": "This cycleway is separated by a solid line", + "nl": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" + } + }, + { + "if": "separation=parking_lane", + "then": { + "en": "This cycleway is separated by a parking lane", + "nl": "Dit fietspad is gescheiden van de weg met parkeervakken" + } + }, + { + "if": "separation=kerb", + "then": { + "en": "This cycleway is separated by a kerb", + "nl": "Dit fietspad is gescheiden van de weg met een stoeprand" + } + } + ] + } + ], + "icon": { + "render": "./assets/themes/cycle_infra/bicycleway.svg" + }, + "width": { + "render": "8" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "rgba(170, 170, 170, 0.7)", + "mappings": [ + { + "if": "highway=cycleway", + "then": "rgba(0, 189, 141, 0.7)" + }, + { + "if": "highway=path", + "then": "rgba(204, 74, 207, 0.7)" + }, + { + "if": "cycleway=track", + "then": "rgba(113, 3, 200, 0.7)" + }, + { + "if": "cycleway=shared_lane", + "then": "rgba(74, 59, 247, 0.7)" + }, + { + "if": "cycleway=lane", + "then": "rgba(254, 155, 6, 0.9)" + }, + { + "if": "cyclestreet=yes", + "then": "rgba(57, 159, 191, 0.7)" + } + ] + }, + "dashArray": { + "render": "", + "mappings": [ + { + "if": { + "or": [ + "oneway=yes", + { + "or": [ + "highway=cycleway", + "highway=path" + ] + } + ] + }, + "then": "" + }, + { + "if": "cycleway=track", + "then": "" + }, + { + "if": "cycleway=shared_lane", + "then": "15 30" + }, + { + "if": "cycleway=lane", + "then": "25 15 15 15 25" + }, + { + "if": "cyclestreet=yes", + "then": "" + } + ] + } } \ No newline at end of file diff --git a/assets/layers/defibrillator/defibrillator.json b/assets/layers/defibrillator/defibrillator.json index edf46f6b9..f0d193c22 100644 --- a/assets/layers/defibrillator/defibrillator.json +++ b/assets/layers/defibrillator/defibrillator.json @@ -1,529 +1,529 @@ { - "id": "defibrillator", - "name": { - "en": "Defibrillators", - "ca": "Desfibril·ladors", - "es": "Desfibriladores", - "fr": "Défibrillateurs", - "nl": "Defibrillatoren", - "de": "Defibrillatoren", - "it": "Defibrillatori", - "ru": "Дефибрилляторы" - }, - "source": { - "osmTags": "emergency=defibrillator" - }, - "calculatedTags": [ - "_days_since_last_survey=Math.floor(new Date() - new Date(feat.properties['survey:date'])/(1000*60*60*24))", - "_recently_surveyed=Number(feat.properties._days_since_last_survey) <= 90" - ], - "minzoom": 12, - "title": { - "render": { - "en": "Defibrillator", - "ca": "Desfibril·lador", - "es": "Desfibrilador", - "fr": "Défibrillateur", - "nl": "Defibrillator", - "de": "Defibrillator", - "it": "Defibrillatore", - "ru": "Дефибриллятор" - } - }, - "icon": { - "render": "./assets/themes/aed/aed.svg", - "mappings": [ - { - "if": "_recently_surveyed=true", - "then": { - "en": "./assets/layers/defibrillator/aed_checked.svg", - "ru": "./assets/layers/defibrillator/aed_checked.svg", - "it": "./assets/layers/defibrillator/aed_checked.svg", - "fr": "./assets/layers/defibrillator/aed_checked.svg" + "id": "defibrillator", + "name": { + "en": "Defibrillators", + "ca": "Desfibril·ladors", + "es": "Desfibriladores", + "fr": "Défibrillateurs", + "nl": "Defibrillatoren", + "de": "Defibrillatoren", + "it": "Defibrillatori", + "ru": "Дефибрилляторы" + }, + "source": { + "osmTags": "emergency=defibrillator" + }, + "calculatedTags": [ + "_days_since_last_survey=Math.floor(new Date() - new Date(feat.properties['survey:date'])/(1000*60*60*24))", + "_recently_surveyed=Number(feat.properties._days_since_last_survey) <= 90" + ], + "minzoom": 12, + "title": { + "render": { + "en": "Defibrillator", + "ca": "Desfibril·lador", + "es": "Desfibrilador", + "fr": "Défibrillateur", + "nl": "Defibrillator", + "de": "Defibrillator", + "it": "Defibrillatore", + "ru": "Дефибриллятор" + } + }, + "icon": { + "render": "./assets/themes/aed/aed.svg", + "mappings": [ + { + "if": "_recently_surveyed=true", + "then": { + "en": "./assets/layers/defibrillator/aed_checked.svg", + "ru": "./assets/layers/defibrillator/aed_checked.svg", + "it": "./assets/layers/defibrillator/aed_checked.svg", + "fr": "./assets/layers/defibrillator/aed_checked.svg" + } + } + ] + }, + "color": "#0000ff", + "presets": [ + { + "title": { + "en": "Defibrillator", + "ca": "Desfibril·lador", + "es": "Desfibrilador", + "fr": "Défibrillateur", + "nl": "Defibrillator", + "de": "Defibrillator", + "it": "Defibrillatore", + "ru": "Дефибриллятор" + }, + "tags": [ + "emergency=defibrillator" + ], + "preciseInput": { + "preferredBackground": "map" + } + } + ], + "tagRenderings": [ + "images", + { + "question": { + "en": "Is this defibrillator located indoors?", + "ca": "Està el desfibril·lador a l'interior?", + "es": "¿Esté el desfibrilador en interior?", + "fr": "Ce défibrillateur est-il disposé en intérieur ?", + "nl": "Hangt deze defibrillator binnen of buiten?", + "de": "Befindet sich dieser Defibrillator im Gebäude?", + "it": "Questo defibrillatore si trova all’interno?" + }, + "mappings": [ + { + "if": "indoor=yes", + "then": { + "en": "This defibrillator is located indoors", + "ca": "Aquest desfibril·lador està a l'interior", + "es": "Este desfibrilador está en interior", + "fr": "Ce défibrillateur est en intérieur (dans un batiment)", + "nl": "Deze defibrillator bevindt zich in een gebouw", + "de": "Dieser Defibrillator befindet sich im Gebäude", + "it": "Questo defibrillatore si trova all’interno" + } + }, + { + "if": "indoor=no", + "then": { + "en": "This defibrillator is located outdoors", + "ca": "Aquest desfibril·lador està a l'exterior", + "es": "Este desfibrilador está en exterior", + "fr": "Ce défibrillateur est situé en extérieur", + "nl": "Deze defibrillator hangt buiten", + "de": "Dieser Defibrillator befindet sich im Freien", + "it": "Questo defibrillatore si trova all’esterno" + } + } + ] + }, + { + "question": { + "en": "Is this defibrillator freely accessible?", + "ca": "Està el desfibril·lador accessible lliurement?", + "es": "¿Está el desfibrilador accesible libremente?", + "fr": "Ce défibrillateur est-il librement accessible ?", + "nl": "Is deze defibrillator vrij toegankelijk?", + "de": "Ist dieser Defibrillator frei zugänglich?", + "it": "Questo defibrillatore è liberamente accessibile?" + }, + "render": { + "en": "Access is {access}", + "ca": "L'accés és {access}", + "es": "El acceso es {access}", + "fr": "{access} accessible", + "nl": "Toegankelijkheid is {access}", + "de": "Zugang ist {access}", + "it": "Accesso è {access}" + }, + "freeform": { + "key": "access", + "addExtraTags": [ + "fixme=Freeform field used for access - doublecheck the value" + ] + }, + "mappings": [ + { + "if": "access=yes", + "then": { + "en": "Publicly accessible", + "ca": "Accés lliure", + "es": "Acceso libre", + "fr": "Librement accessible", + "nl": "Publiek toegankelijk", + "de": "Öffentlich zugänglich", + "it": "Pubblicamente accessibile", + "ru": "Общедоступный" + } + }, + { + "if": "access=public", + "then": { + "en": "Publicly accessible", + "ca": "Publicament accessible", + "es": "Publicament accesible", + "fr": "Librement accessible", + "nl": "Publiek toegankelijk", + "de": "Öffentlich zugänglich", + "it": "Pubblicamente accessibile", + "ru": "Общедоступный" + }, + "hideInAnswer": true + }, + { + "if": "access=customers", + "then": { + "en": "Only accessible to customers", + "ca": "Només accessible a clients", + "es": "Sólo accesible a clientes", + "fr": "Réservé aux clients du lieu", + "nl": "Enkel toegankelijk voor klanten", + "de": "Nur für Kunden zugänglich", + "it": "Accessibile solo ai clienti", + "ru": "Доступно только для клиентов" + } + }, + { + "if": "access=private", + "then": { + "en": "Not accessible to the general public (e.g. only accesible to staff, the owners, ...)", + "ca": "No accessible al públic en general (ex. només accesible a treballadors, propietaris, ...)", + "es": "No accesible al público en general (ex. sólo accesible a trabajadores, propietarios, ...)", + "fr": "Non accessible au public (par exemple réservé au personnel, au propriétaire, ...)", + "nl": "Niet toegankelijk voor het publiek (bv. enkel voor personeel, de eigenaar, ...)", + "de": "Nicht für die Öffentlichkeit zugänglich (z.B. nur für das Personal, die Eigentümer, ...)", + "it": "Non accessibile al pubblico (ad esempio riservato al personale, ai proprietari, etc.)" + } + }, + { + "if": "access=no", + "then": { + "en": "Not accessible, possibly only for professional use", + "nl": "Niet toegankelijk, mogelijk enkel voor professionals", + "fr": "Pas accessible, peut-être uniquement à usage professionnel", + "it": "Non accessibile, potrebbe essere solo per uso professionale" + } + } + ] + }, + { + "render": { + "en": "There is no info about the type of device", + "nl": "Er is geen info over het soort toestel", + "fr": "Il n'y a pas d'information sur le type de dispositif", + "it": "Non vi sono informazioni riguardanti il tipo di questo dispositivo", + "de": "Es gibt keine Informationen über den Gerätetyp" + }, + "question": { + "en": "Is this a a regular automatic defibrillator or a manual defibrillator for professionals only?", + "nl": "Is dit een gewone automatische defibrillator of een manueel toestel enkel voor professionals?", + "fr": "Est-ce un défibrillateur automatique normal ou un défibrillateur manuel à usage professionnel uniquement ?", + "it": "Si tratta di un normale defibrillatore automatico o un defibrillatore manuale riservato ai professionisti?" + }, + "freeform": { + "key": "defibrillator" + }, + "condition": { + "and": [ + "access=no" + ] + }, + "mappings": [ + { + "if": "defibrillator=manual", + "then": { + "en": "This is a manual defibrillator for professionals", + "nl": "Dit is een manueel toestel enkel voor professionals", + "fr": "C'est un défibrillateur manuel pour professionnel", + "it": "Questo è un defibrillatore manuale per professionisti", + "de": "Dies ist ein manueller Defibrillator für den professionellen Einsatz" + } + }, + { + "if": "defibrillator=automatic", + "then": { + "en": "This is a normal automatic defibrillator", + "nl": "Dit is een gewone automatische defibrillator", + "fr": "C'est un défibrillateur automatique manuel", + "it": "È un normale defibrillatore automatico", + "ru": "Это обычный автоматический дефибриллятор" + } + } + ] + }, + { + "question": { + "en": "On which floor is this defibrillator located?", + "ca": "A quina planta està el desfibril·lador localitzat?", + "es": "¿En qué planta se encuentra el defibrilador localizado?", + "fr": "À quel étage est situé ce défibrillateur ?", + "nl": "Op welke verdieping bevindt deze defibrillator zich?", + "de": "In welchem Stockwerk befindet sich dieser Defibrillator?", + "it": "A che piano si trova questo defibrillatore?" + }, + "condition": { + "and": [ + "indoor=yes" + ] + }, + "freeform": { + "key": "level", + "type": "int" + }, + "render": { + "en": "This defibrillator is on floor {level}", + "ca": "Aquest desfibril·lador és a la planta {level}", + "es": "El desfibrilador se encuentra en la planta {level}", + "fr": "Ce défibrillateur est à l'étage {level}", + "nl": "De defibrillator bevindt zicht op verdieping {level}", + "de": "Dieser Defibrallator befindet sich im {level}. Stockwerk", + "it": "Questo defibrillatore è al piano {level}" + }, + "mappings": [ + { + "if": "level=0", + "then": { + "en": "This defibrillator is on the ground floor", + "nl": "Deze defibrillator bevindt zich gelijkvloers", + "fr": "Ce défibrillateur est au rez-de-chaussée", + "it": "Questo defibrillatore è al pian terreno", + "de": "Dieser Defibrillator befindet sich im Erdgeschoss" + } + }, + { + "if": "level=1", + "then": { + "en": "This defibrillator is on the first floor", + "nl": "Deze defibrillator is op de eerste verdieping", + "fr": "Ce défibrillateur est au premier étage", + "it": "Questo defibrillatore è al primo piano", + "de": "Dieser Defibrillator befindet sich in der ersten Etage" + } + } + ] + }, + { + "render": { + "nl": "Meer informatie over de locatie (lokale taal):
{defibrillator:location}", + "en": "Extra information about the location (in the local languagel):
{defibrillator:location}", + "fr": "Informations supplémentaires à propos de l'emplacement (dans la langue locale) :
{defibrillator:location}", + "it": "Informazioni supplementari circa la posizione (in lingua locale):
{defibrillator:location}", + "de": "Zusätzliche Informationen über den Standort (in der Landessprache):
{defibrillator:location}" + }, + "question": { + "en": "Please give some explanation on where the defibrillator can be found (in the local language)", + "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", + "es": "Da detalles de dónde se puede encontrar el desfibrilador (en el idioma local)", + "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur (dans la langue local)", + "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in de plaatselijke taal)", + "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (in der lokalen Sprache)", + "it": "Indica più precisamente dove si trova il defibrillatore (in lingua locale)" + }, + "freeform": { + "type": "text", + "key": "defibrillator:location" + } + }, + { + "render": { + "nl": "Meer informatie over de locatie (in het Engels):
{defibrillator:location:en}", + "en": "Extra information about the location (in English):
{defibrillator:location:en}", + "fr": "Informations supplémentaires à propos de l'emplacement (en anglais) :
{defibrillator:location}", + "it": "Informazioni supplementari circa la posizione (in inglese):
{defibrillator:location:en}", + "de": "Zusätzliche Informationen über den Standort (auf Englisch):
{defibrillator:location}" + }, + "question": { + "en": "Please give some explanation on where the defibrillator can be found (in English)", + "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", + "es": "Da detalles de dónde se puede encontrar el desfibrilador (en ingles)", + "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur (en englais)", + "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Engels)", + "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Englisch)", + "it": "Indica più precisamente dove si trova il defibrillatore (in inglese)" + }, + "freeform": { + "type": "text", + "key": "defibrillator:location:en" + } + }, + { + "render": { + "nl": "Meer informatie over de locatie (in het Frans):
{defibrillator:location:fr}", + "en": "Extra information about the location (in French):
{defibrillator:location:fr}", + "fr": "Informations supplémentaires à propos de l'emplacement (en Français) :
{defibrillator:location}", + "it": "Informazioni supplementari circa la posizione (in francese):
{defibrillator:location:fr}", + "de": "Zusätzliche Informationen zum Standort (auf Französisch):
{defibrillator:Standort:fr}" + }, + "question": { + "en": "Please give some explanation on where the defibrillator can be found (in French)", + "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", + "es": "Da detalles de dónde se puede encontrar el desfibrilador (en frances)", + "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur (en français)", + "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Frans)", + "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Französisch)", + "it": "Indica più precisamente dove si trova il defibrillatore (in francese)" + }, + "freeform": { + "type": "text", + "key": "defibrillator:location:fr" + } + }, + "wheelchair-access", + { + "render": { + "nl": "Officieel identificatienummer van het toestel: {ref}", + "en": "Official identification number of the device: {ref}", + "fr": "Numéro d'identification officiel de ce dispositif : {ref}", + "it": "Numero identificativo ufficiale di questo dispositivo:{ref}", + "de": "Offizielle Identifikationsnummer des Geräts: {ref}" + }, + "question": { + "en": "What is the official identification number of the device? (if visible on device)", + "nl": "Wat is het officieel identificatienummer van het toestel? (indien zichtbaar op toestel)", + "fr": "Quel est le numéro d'identification officiel de ce dispositif ? (si il est visible sur le dispositif)", + "it": "Qual è il numero identificativo ufficiale di questo dispositivo? (se visibile sul dispositivo)", + "de": "Wie lautet die offizielle Identifikationsnummer des Geräts? (falls am Gerät sichtbar)" + }, + "freeform": { + "type": "text", + "key": "ref" + } + }, + { + "render": { + "en": "Email for questions about this defibrillator: {email}", + "nl": "Email voor vragen over deze defibrillator: {email}", + "fr": "Adresse électronique pour des questions à propos de ce défibrillateur : {email}", + "it": "Indirizzo email per le domande su questo defibrillatore:{email}", + "de": "E-Mail für Fragen zu diesem Defibrillator: {email}" + }, + "question": { + "en": "What is the email for questions about this defibrillator?", + "nl": "Wat is het email-adres voor vragen over deze defibrillator", + "fr": "Quelle est l'adresse électronique pour des questions à propos de ce défibrillateur ?", + "it": "Qual è l’indirizzo email per le domande riguardanti questo defibrillatore?", + "de": "Wie lautet die E-Mail für Fragen zu diesem Defibrillator?" + }, + "freeform": { + "key": "email", + "type": "email" + } + }, + { + "render": { + "en": "Telephone for questions about this defibrillator: {phone}", + "fr": "Numéro de téléphone pour questions sur le défibrillateur : {phone}", + "nl": "Telefoonnummer voor vragen over deze defibrillator: {phone}", + "it": "Numero di telefono per le domande su questo defibrillatore:{phone}", + "de": "Telefonnummer für Fragen zu diesem Defibrillator: {phone}" + }, + "question": { + "en": "What is the phone number for questions about this defibrillator?", + "fr": "Quel est le numéro de téléphone pour questions sur le défibrillateur ?", + "nl": "Wat is het telefoonnummer voor vragen over deze defibrillator", + "it": "Qual è il numero di telefono per le domande riguardanti questo defibrillatore?", + "de": "Wie lautet die Telefonnummer für Fragen zu diesem Defibrillator?" + }, + "freeform": { + "key": "phone", + "type": "phone" + } + }, + { + "render": { + "en": "{opening_hours_table(opening_hours)}", + "nl": "{opening_hours_table(opening_hours)}", + "fr": "{opening_hours_table(opening_hours)}", + "it": "{opening_hours_table(opening_hours)}", + "ru": "{opening_hours_table(opening_hours)}" + }, + "question": { + "en": "At what times is this defibrillator available?", + "nl": "Wanneer is deze defibrillator beschikbaar?", + "fr": "À quels horaires ce défibrillateur est-il accessible ?", + "it": "In quali orari è disponibile questo defibrillatore?", + "ru": "В какое время доступен этот дефибриллятор?", + "de": "Zu welchen Zeiten ist dieser Defibrillator verfügbar?" + }, + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + }, + "mappings": [ + { + "if": "opening_hours=24/7", + "then": { + "en": "24/7 opened (including holidays)", + "nl": "24/7 open (inclusief feestdagen)", + "fr": "Ouvert 24/7 (jours feriés inclus)", + "it": "Aperto 24/7 (festivi inclusi)", + "de": "24/7 geöffnet (auch an Feiertagen)" + } + } + ] + }, + { + "render": { + "en": "Additional information: {description}", + "nl": "Aanvullende info: {description}", + "fr": "Informations supplémentaires : {description}", + "it": "Informazioni supplementari: {description}", + "ru": "Дополнительная информация: {description}", + "de": "Zusätzliche Informationen: {description}", + "id": "Informasi tambahan: {description}" + }, + "question": { + "en": "Is there any useful information for users that you haven't been able to describe above? (leave blank if no)", + "nl": "Is er nog iets bijzonder aan deze defibrillator dat je nog niet hebt kunnen meegeven? (laat leeg indien niet)", + "fr": "Y a-t-il des informations utiles pour les utilisateurs que vous n'avez pas pu décrire ci-dessus ? (laisser vide sinon)", + "it": "Vi sono altre informazioni utili agli utenti che non è stato possibile aggiungere prima? (lasciare vuoto in caso negativo)", + "de": "Gibt es nützliche Informationen für Benutzer, die Sie oben nicht beschreiben konnten? (leer lassen, wenn nein)" + }, + "freeform": { + "key": "description", + "type": "text" + } + }, + { + "question": { + "en": "When was this defibrillator last surveyed?", + "nl": "Wanneer is deze defibrillator het laatst gecontroleerd in OpenStreetMap?", + "fr": "Quand le défibrillateur a-t-il été vérifié pour la dernière fois ?", + "it": "Quando è stato verificato per l’ultima volta questo defibrillatore?", + "de": "Wann wurde dieser Defibrillator zuletzt überprüft?" + }, + "render": { + "en": "This defibrillator was last surveyed on {survey:date}", + "nl": "Deze defibrillator is nagekeken in OSM op {survey:date}", + "fr": "Ce défibrillateur a été vérifié pour la dernière fois le {survey:date}", + "it": "Questo defibrillatore è stato verificato per l‘ultima volta in data {survey:date}", + "de": "Dieser Defibrillator wurde zuletzt am {survey:date} überprüft" + }, + "freeform": { + "key": "survey:date", + "type": "date" + }, + "mappings": [ + { + "if": "survey:date:={_now:date}", + "then": { + "en": "Checked today!", + "nl": "Vandaag nagekeken!", + "fr": "Vérifié aujourd'hui !", + "it": "Verificato oggi!", + "ru": "Проверено сегодня!", + "de": "Heute überprüft!" + } + } + ] + }, + { + "render": { + "en": "Extra information for OpenStreetMap experts: {fixme}", + "nl": "Extra informatie voor OpenStreetMap experts: {fixme}", + "fr": "Informations supplémentaires pour les experts d'OpenStreetMap : {fixme}", + "it": "Informazioni supplementari per gli esperti di OpenStreetMap: {fixme}", + "de": "Zusätzliche Informationen für OpenStreetMap-Experten: {fixme}", + "ru": "Дополнительная информация для экспертов OpenStreetMap: {fixme}" + }, + "question": { + "en": "Is there something wrong with how this is mapped, that you weren't able to fix here? (leave a note to OpenStreetMap experts)", + "nl": "Is er iets mis met de informatie over deze defibrillator dat je hier niet opgelost kreeg? (laat hier een berichtje achter voor OpenStreetMap experts)", + "fr": "Y a-t-il quelque chose qui ne va pas dans la manière dont ça a été cartographié, et que vous n'avez pas pu réparer ici ? (laisser une note pour les experts d'OpenStreetMap)", + "it": "C’è qualcosa di sbagliato riguardante come è stato mappato, che non si è potuto correggere qua? (lascia una nota agli esperti di OpenStreetMap)", + "de": "Gibt es einen Fehler in der Kartierung, den Sie hier nicht beheben konnten? (hinterlasse eine Notiz an OpenStreetMap-Experten)" + }, + "freeform": { + "key": "fixme", + "type": "text" + } } - } ] - }, - "color": "#0000ff", - "presets": [ - { - "title": { - "en": "Defibrillator", - "ca": "Desfibril·lador", - "es": "Desfibrilador", - "fr": "Défibrillateur", - "nl": "Defibrillator", - "de": "Defibrillator", - "it": "Defibrillatore", - "ru": "Дефибриллятор" - }, - "tags": [ - "emergency=defibrillator" - ], - "preciseInput": { - "preferredBackground": "map" - } - } - ], - "tagRenderings": [ - "images", - { - "question": { - "en": "Is this defibrillator located indoors?", - "ca": "Està el desfibril·lador a l'interior?", - "es": "¿Esté el desfibrilador en interior?", - "fr": "Ce défibrillateur est-il disposé en intérieur ?", - "nl": "Hangt deze defibrillator binnen of buiten?", - "de": "Befindet sich dieser Defibrillator im Gebäude?", - "it": "Questo defibrillatore si trova all’interno?" - }, - "mappings": [ - { - "if": "indoor=yes", - "then": { - "en": "This defibrillator is located indoors", - "ca": "Aquest desfibril·lador està a l'interior", - "es": "Este desfibrilador está en interior", - "fr": "Ce défibrillateur est en intérieur (dans un batiment)", - "nl": "Deze defibrillator bevindt zich in een gebouw", - "de": "Dieser Defibrillator befindet sich im Gebäude", - "it": "Questo defibrillatore si trova all’interno" - } - }, - { - "if": "indoor=no", - "then": { - "en": "This defibrillator is located outdoors", - "ca": "Aquest desfibril·lador està a l'exterior", - "es": "Este desfibrilador está en exterior", - "fr": "Ce défibrillateur est situé en extérieur", - "nl": "Deze defibrillator hangt buiten", - "de": "Dieser Defibrillator befindet sich im Freien", - "it": "Questo defibrillatore si trova all’esterno" - } - } - ] - }, - { - "question": { - "en": "Is this defibrillator freely accessible?", - "ca": "Està el desfibril·lador accessible lliurement?", - "es": "¿Está el desfibrilador accesible libremente?", - "fr": "Ce défibrillateur est-il librement accessible ?", - "nl": "Is deze defibrillator vrij toegankelijk?", - "de": "Ist dieser Defibrillator frei zugänglich?", - "it": "Questo defibrillatore è liberamente accessibile?" - }, - "render": { - "en": "Access is {access}", - "ca": "L'accés és {access}", - "es": "El acceso es {access}", - "fr": "{access} accessible", - "nl": "Toegankelijkheid is {access}", - "de": "Zugang ist {access}", - "it": "Accesso è {access}" - }, - "freeform": { - "key": "access", - "addExtraTags": [ - "fixme=Freeform field used for access - doublecheck the value" - ] - }, - "mappings": [ - { - "if": "access=yes", - "then": { - "en": "Publicly accessible", - "ca": "Accés lliure", - "es": "Acceso libre", - "fr": "Librement accessible", - "nl": "Publiek toegankelijk", - "de": "Öffentlich zugänglich", - "it": "Pubblicamente accessibile", - "ru": "Общедоступный" - } - }, - { - "if": "access=public", - "then": { - "en": "Publicly accessible", - "ca": "Publicament accessible", - "es": "Publicament accesible", - "fr": "Librement accessible", - "nl": "Publiek toegankelijk", - "de": "Öffentlich zugänglich", - "it": "Pubblicamente accessibile", - "ru": "Общедоступный" - }, - "hideInAnswer": true - }, - { - "if": "access=customers", - "then": { - "en": "Only accessible to customers", - "ca": "Només accessible a clients", - "es": "Sólo accesible a clientes", - "fr": "Réservé aux clients du lieu", - "nl": "Enkel toegankelijk voor klanten", - "de": "Nur für Kunden zugänglich", - "it": "Accessibile solo ai clienti", - "ru": "Доступно только для клиентов" - } - }, - { - "if": "access=private", - "then": { - "en": "Not accessible to the general public (e.g. only accesible to staff, the owners, ...)", - "ca": "No accessible al públic en general (ex. només accesible a treballadors, propietaris, ...)", - "es": "No accesible al público en general (ex. sólo accesible a trabajadores, propietarios, ...)", - "fr": "Non accessible au public (par exemple réservé au personnel, au propriétaire, ...)", - "nl": "Niet toegankelijk voor het publiek (bv. enkel voor personeel, de eigenaar, ...)", - "de": "Nicht für die Öffentlichkeit zugänglich (z.B. nur für das Personal, die Eigentümer, ...)", - "it": "Non accessibile al pubblico (ad esempio riservato al personale, ai proprietari, etc.)" - } - }, - { - "if": "access=no", - "then": { - "en": "Not accessible, possibly only for professional use", - "nl": "Niet toegankelijk, mogelijk enkel voor professionals", - "fr": "Pas accessible, peut-être uniquement à usage professionnel", - "it": "Non accessibile, potrebbe essere solo per uso professionale" - } - } - ] - }, - { - "render": { - "en": "There is no info about the type of device", - "nl": "Er is geen info over het soort toestel", - "fr": "Il n'y a pas d'information sur le type de dispositif", - "it": "Non vi sono informazioni riguardanti il tipo di questo dispositivo", - "de": "Es gibt keine Informationen über den Gerätetyp" - }, - "question": { - "en": "Is this a a regular automatic defibrillator or a manual defibrillator for professionals only?", - "nl": "Is dit een gewone automatische defibrillator of een manueel toestel enkel voor professionals?", - "fr": "Est-ce un défibrillateur automatique normal ou un défibrillateur manuel à usage professionnel uniquement ?", - "it": "Si tratta di un normale defibrillatore automatico o un defibrillatore manuale riservato ai professionisti?" - }, - "freeform": { - "key": "defibrillator" - }, - "condition": { - "and": [ - "access=no" - ] - }, - "mappings": [ - { - "if": "defibrillator=manual", - "then": { - "en": "This is a manual defibrillator for professionals", - "nl": "Dit is een manueel toestel enkel voor professionals", - "fr": "C'est un défibrillateur manuel pour professionnel", - "it": "Questo è un defibrillatore manuale per professionisti", - "de": "Dies ist ein manueller Defibrillator für den professionellen Einsatz" - } - }, - { - "if": "defibrillator=automatic", - "then": { - "en": "This is a normal automatic defibrillator", - "nl": "Dit is een gewone automatische defibrillator", - "fr": "C'est un défibrillateur automatique manuel", - "it": "È un normale defibrillatore automatico", - "ru": "Это обычный автоматический дефибриллятор" - } - } - ] - }, - { - "question": { - "en": "On which floor is this defibrillator located?", - "ca": "A quina planta està el desfibril·lador localitzat?", - "es": "¿En qué planta se encuentra el defibrilador localizado?", - "fr": "À quel étage est situé ce défibrillateur ?", - "nl": "Op welke verdieping bevindt deze defibrillator zich?", - "de": "In welchem Stockwerk befindet sich dieser Defibrillator?", - "it": "A che piano si trova questo defibrillatore?" - }, - "condition": { - "and": [ - "indoor=yes" - ] - }, - "freeform": { - "key": "level", - "type": "int" - }, - "render": { - "en": "This defibrillator is on floor {level}", - "ca": "Aquest desfibril·lador és a la planta {level}", - "es": "El desfibrilador se encuentra en la planta {level}", - "fr": "Ce défibrillateur est à l'étage {level}", - "nl": "De defibrillator bevindt zicht op verdieping {level}", - "de": "Dieser Defibrallator befindet sich im {level}. Stockwerk", - "it": "Questo defibrillatore è al piano {level}" - }, - "mappings": [ - { - "if": "level=0", - "then": { - "en": "This defibrillator is on the ground floor", - "nl": "Deze defibrillator bevindt zich gelijkvloers", - "fr": "Ce défibrillateur est au rez-de-chaussée", - "it": "Questo defibrillatore è al pian terreno", - "de": "Dieser Defibrillator befindet sich im Erdgeschoss" - } - }, - { - "if": "level=1", - "then": { - "en": "This defibrillator is on the first floor", - "nl": "Deze defibrillator is op de eerste verdieping", - "fr": "Ce défibrillateur est au premier étage", - "it": "Questo defibrillatore è al primo piano", - "de": "Dieser Defibrillator befindet sich in der ersten Etage" - } - } - ] - }, - { - "render": { - "nl": "Meer informatie over de locatie (lokale taal):
{defibrillator:location}", - "en": "Extra information about the location (in the local languagel):
{defibrillator:location}", - "fr": "Informations supplémentaires à propos de l'emplacement (dans la langue locale) :
{defibrillator:location}", - "it": "Informazioni supplementari circa la posizione (in lingua locale):
{defibrillator:location}", - "de": "Zusätzliche Informationen über den Standort (in der Landessprache):
{defibrillator:location}" - }, - "question": { - "en": "Please give some explanation on where the defibrillator can be found (in the local language)", - "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", - "es": "Da detalles de dónde se puede encontrar el desfibrilador (en el idioma local)", - "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur (dans la langue local)", - "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in de plaatselijke taal)", - "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (in der lokalen Sprache)", - "it": "Indica più precisamente dove si trova il defibrillatore (in lingua locale)" - }, - "freeform": { - "type": "text", - "key": "defibrillator:location" - } - }, - { - "render": { - "nl": "Meer informatie over de locatie (in het Engels):
{defibrillator:location:en}", - "en": "Extra information about the location (in English):
{defibrillator:location:en}", - "fr": "Informations supplémentaires à propos de l'emplacement (en anglais) :
{defibrillator:location}", - "it": "Informazioni supplementari circa la posizione (in inglese):
{defibrillator:location:en}", - "de": "Zusätzliche Informationen über den Standort (auf Englisch):
{defibrillator:location}" - }, - "question": { - "en": "Please give some explanation on where the defibrillator can be found (in English)", - "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", - "es": "Da detalles de dónde se puede encontrar el desfibrilador (en ingles)", - "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur (en englais)", - "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Engels)", - "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Englisch)", - "it": "Indica più precisamente dove si trova il defibrillatore (in inglese)" - }, - "freeform": { - "type": "text", - "key": "defibrillator:location:en" - } - }, - { - "render": { - "nl": "Meer informatie over de locatie (in het Frans):
{defibrillator:location:fr}", - "en": "Extra information about the location (in French):
{defibrillator:location:fr}", - "fr": "Informations supplémentaires à propos de l'emplacement (en Français) :
{defibrillator:location}", - "it": "Informazioni supplementari circa la posizione (in francese):
{defibrillator:location:fr}", - "de": "Zusätzliche Informationen zum Standort (auf Französisch):
{defibrillator:Standort:fr}" - }, - "question": { - "en": "Please give some explanation on where the defibrillator can be found (in French)", - "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", - "es": "Da detalles de dónde se puede encontrar el desfibrilador (en frances)", - "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur (en français)", - "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Frans)", - "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Französisch)", - "it": "Indica più precisamente dove si trova il defibrillatore (in francese)" - }, - "freeform": { - "type": "text", - "key": "defibrillator:location:fr" - } - }, - "wheelchair-access", - { - "render": { - "nl": "Officieel identificatienummer van het toestel: {ref}", - "en": "Official identification number of the device: {ref}", - "fr": "Numéro d'identification officiel de ce dispositif : {ref}", - "it": "Numero identificativo ufficiale di questo dispositivo:{ref}", - "de": "Offizielle Identifikationsnummer des Geräts: {ref}" - }, - "question": { - "en": "What is the official identification number of the device? (if visible on device)", - "nl": "Wat is het officieel identificatienummer van het toestel? (indien zichtbaar op toestel)", - "fr": "Quel est le numéro d'identification officiel de ce dispositif ? (si il est visible sur le dispositif)", - "it": "Qual è il numero identificativo ufficiale di questo dispositivo? (se visibile sul dispositivo)", - "de": "Wie lautet die offizielle Identifikationsnummer des Geräts? (falls am Gerät sichtbar)" - }, - "freeform": { - "type": "text", - "key": "ref" - } - }, - { - "render": { - "en": "Email for questions about this defibrillator: {email}", - "nl": "Email voor vragen over deze defibrillator: {email}", - "fr": "Adresse électronique pour des questions à propos de ce défibrillateur : {email}", - "it": "Indirizzo email per le domande su questo defibrillatore:{email}", - "de": "E-Mail für Fragen zu diesem Defibrillator: {email}" - }, - "question": { - "en": "What is the email for questions about this defibrillator?", - "nl": "Wat is het email-adres voor vragen over deze defibrillator", - "fr": "Quelle est l'adresse électronique pour des questions à propos de ce défibrillateur ?", - "it": "Qual è l’indirizzo email per le domande riguardanti questo defibrillatore?", - "de": "Wie lautet die E-Mail für Fragen zu diesem Defibrillator?" - }, - "freeform": { - "key": "email", - "type": "email" - } - }, - { - "render": { - "en": "Telephone for questions about this defibrillator: {phone}", - "fr": "Numéro de téléphone pour questions sur le défibrillateur : {phone}", - "nl": "Telefoonnummer voor vragen over deze defibrillator: {phone}", - "it": "Numero di telefono per le domande su questo defibrillatore:{phone}", - "de": "Telefonnummer für Fragen zu diesem Defibrillator: {phone}" - }, - "question": { - "en": "What is the phone number for questions about this defibrillator?", - "fr": "Quel est le numéro de téléphone pour questions sur le défibrillateur ?", - "nl": "Wat is het telefoonnummer voor vragen over deze defibrillator", - "it": "Qual è il numero di telefono per le domande riguardanti questo defibrillatore?", - "de": "Wie lautet die Telefonnummer für Fragen zu diesem Defibrillator?" - }, - "freeform": { - "key": "phone", - "type": "phone" - } - }, - { - "render": { - "en": "{opening_hours_table(opening_hours)}", - "nl": "{opening_hours_table(opening_hours)}", - "fr": "{opening_hours_table(opening_hours)}", - "it": "{opening_hours_table(opening_hours)}", - "ru": "{opening_hours_table(opening_hours)}" - }, - "question": { - "en": "At what times is this defibrillator available?", - "nl": "Wanneer is deze defibrillator beschikbaar?", - "fr": "À quels horaires ce défibrillateur est-il accessible ?", - "it": "In quali orari è disponibile questo defibrillatore?", - "ru": "В какое время доступен этот дефибриллятор?", - "de": "Zu welchen Zeiten ist dieser Defibrillator verfügbar?" - }, - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - }, - "mappings": [ - { - "if": "opening_hours=24/7", - "then": { - "en": "24/7 opened (including holidays)", - "nl": "24/7 open (inclusief feestdagen)", - "fr": "Ouvert 24/7 (jours feriés inclus)", - "it": "Aperto 24/7 (festivi inclusi)", - "de": "24/7 geöffnet (auch an Feiertagen)" - } - } - ] - }, - { - "render": { - "en": "Additional information: {description}", - "nl": "Aanvullende info: {description}", - "fr": "Informations supplémentaires : {description}", - "it": "Informazioni supplementari: {description}", - "ru": "Дополнительная информация: {description}", - "de": "Zusätzliche Informationen: {description}", - "id": "Informasi tambahan: {description}" - }, - "question": { - "en": "Is there any useful information for users that you haven't been able to describe above? (leave blank if no)", - "nl": "Is er nog iets bijzonder aan deze defibrillator dat je nog niet hebt kunnen meegeven? (laat leeg indien niet)", - "fr": "Y a-t-il des informations utiles pour les utilisateurs que vous n'avez pas pu décrire ci-dessus ? (laisser vide sinon)", - "it": "Vi sono altre informazioni utili agli utenti che non è stato possibile aggiungere prima? (lasciare vuoto in caso negativo)", - "de": "Gibt es nützliche Informationen für Benutzer, die Sie oben nicht beschreiben konnten? (leer lassen, wenn nein)" - }, - "freeform": { - "key": "description", - "type": "text" - } - }, - { - "question": { - "en": "When was this defibrillator last surveyed?", - "nl": "Wanneer is deze defibrillator het laatst gecontroleerd in OpenStreetMap?", - "fr": "Quand le défibrillateur a-t-il été vérifié pour la dernière fois ?", - "it": "Quando è stato verificato per l’ultima volta questo defibrillatore?", - "de": "Wann wurde dieser Defibrillator zuletzt überprüft?" - }, - "render": { - "en": "This defibrillator was last surveyed on {survey:date}", - "nl": "Deze defibrillator is nagekeken in OSM op {survey:date}", - "fr": "Ce défibrillateur a été vérifié pour la dernière fois le {survey:date}", - "it": "Questo defibrillatore è stato verificato per l‘ultima volta in data {survey:date}", - "de": "Dieser Defibrillator wurde zuletzt am {survey:date} überprüft" - }, - "freeform": { - "key": "survey:date", - "type": "date" - }, - "mappings": [ - { - "if": "survey:date:={_now:date}", - "then": { - "en": "Checked today!", - "nl": "Vandaag nagekeken!", - "fr": "Vérifié aujourd'hui !", - "it": "Verificato oggi!", - "ru": "Проверено сегодня!", - "de": "Heute überprüft!" - } - } - ] - }, - { - "render": { - "en": "Extra information for OpenStreetMap experts: {fixme}", - "nl": "Extra informatie voor OpenStreetMap experts: {fixme}", - "fr": "Informations supplémentaires pour les experts d'OpenStreetMap : {fixme}", - "it": "Informazioni supplementari per gli esperti di OpenStreetMap: {fixme}", - "de": "Zusätzliche Informationen für OpenStreetMap-Experten: {fixme}", - "ru": "Дополнительная информация для экспертов OpenStreetMap: {fixme}" - }, - "question": { - "en": "Is there something wrong with how this is mapped, that you weren't able to fix here? (leave a note to OpenStreetMap experts)", - "nl": "Is er iets mis met de informatie over deze defibrillator dat je hier niet opgelost kreeg? (laat hier een berichtje achter voor OpenStreetMap experts)", - "fr": "Y a-t-il quelque chose qui ne va pas dans la manière dont ça a été cartographié, et que vous n'avez pas pu réparer ici ? (laisser une note pour les experts d'OpenStreetMap)", - "it": "C’è qualcosa di sbagliato riguardante come è stato mappato, che non si è potuto correggere qua? (lascia una nota agli esperti di OpenStreetMap)", - "de": "Gibt es einen Fehler in der Kartierung, den Sie hier nicht beheben konnten? (hinterlasse eine Notiz an OpenStreetMap-Experten)" - }, - "freeform": { - "key": "fixme", - "type": "text" - } - } - ] } \ No newline at end of file diff --git a/assets/layers/direction/direction.json b/assets/layers/direction/direction.json index fddfd64f3..4d3fd684d 100644 --- a/assets/layers/direction/direction.json +++ b/assets/layers/direction/direction.json @@ -1,47 +1,47 @@ { - "id": "direction", - "name": { - "en": "Direction visualization", - "nl": "Richtingsvisualisatie", - "fr": "Visualisation de la direction", - "it": "Visualizzazione della direzione", - "ru": "Визуализация направления" - }, - "minzoom": 16, - "source": { - "osmTags": { - "or": [ - "camera:direction~*", - "direction~*" - ] - } - }, - "doNotDownload": true, - "passAllFeatures": true, - "title": null, - "description": { - "en": "This layer visualizes directions", - "nl": "Deze laag toont de oriëntatie van een object", - "fr": "Cette couche visualise les directions", - "it": "Questo livello visualizza le direzioni" - }, - "tagRenderings": [], - "icon": { - "render": "direction_gradient:var(--catch-detail-color)", - "#": "For some weird reason, showing the icon in the layer control panel breaks the svg-gradient (because the svg gradient has a global color or smthng) - so we use a different icon without gradient", - "mappings": [ - { - "if": "id=node/-1", - "then": "direction:var(--catch-detail-color)" - } - ] - }, - "rotation": { - "render": "{_direction:numerical}deg" - }, - "iconSize": "200,200,center", - "color": "--catch-detail-color", - "stroke": "0", - "presets": [], - "wayHandling": 2 + "id": "direction", + "name": { + "en": "Direction visualization", + "nl": "Richtingsvisualisatie", + "fr": "Visualisation de la direction", + "it": "Visualizzazione della direzione", + "ru": "Визуализация направления" + }, + "minzoom": 16, + "source": { + "osmTags": { + "or": [ + "camera:direction~*", + "direction~*" + ] + } + }, + "doNotDownload": true, + "passAllFeatures": true, + "title": null, + "description": { + "en": "This layer visualizes directions", + "nl": "Deze laag toont de oriëntatie van een object", + "fr": "Cette couche visualise les directions", + "it": "Questo livello visualizza le direzioni" + }, + "tagRenderings": [], + "icon": { + "render": "direction_gradient:var(--catch-detail-color)", + "#": "For some weird reason, showing the icon in the layer control panel breaks the svg-gradient (because the svg gradient has a global color or smthng) - so we use a different icon without gradient", + "mappings": [ + { + "if": "id=node/-1", + "then": "direction:var(--catch-detail-color)" + } + ] + }, + "rotation": { + "render": "{_direction:numerical}deg" + }, + "iconSize": "200,200,center", + "color": "--catch-detail-color", + "stroke": "0", + "presets": [], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/drinking_water/drinking_water.json b/assets/layers/drinking_water/drinking_water.json index 7663f584b..67f61d5ff 100644 --- a/assets/layers/drinking_water/drinking_water.json +++ b/assets/layers/drinking_water/drinking_water.json @@ -1,61 +1,6 @@ { - "id": "drinking_water", - "name": { - "en": "Drinking water", - "nl": "Drinkbaar water", - "fr": "Eau potable", - "gl": "Auga potábel", - "de": "Trinkwasser", - "it": "Acqua potabile", - "ru": "Питьевая вода", - "id": "Air minum" - }, - "title": { - "render": { - "en": "Drinking water", - "nl": "Drinkbaar water", - "fr": "Eau potable", - "gl": "Auga potábel", - "de": "Trinkwasser", - "it": "Acqua potabile", - "ru": "Питьевая вода", - "id": "Air minum" - } - }, - "icon": { - "render": "pin:#6BC4F7;./assets/layers/drinking_water/drips.svg" - }, - "iconOverlays": [ - { - "if": { - "or": [ - "operational_status=broken", - "operational_status=closed" - ] - }, - "then": "close:#c33", - "badge": true - } - ], - "iconSize": "40,40,bottom", - "source": { - "osmTags": { - "and": [ - "amenity=drinking_water", - "access!=permissive", - "access!=private" - ] - } - }, - "calculatedTags": [ - "_closest_other_drinking_water_id=feat.closest('drinking_water').id", - "_closest_other_drinking_water_distance=Math.floor(feat.distanceTo(feat.closest('drinking_water')) * 1000)" - ], - "minzoom": 13, - "wayHandling": 1, - "presets": [ - { - "title": { + "id": "drinking_water", + "name": { "en": "Drinking water", "nl": "Drinkbaar water", "fr": "Eau potable", @@ -64,105 +9,160 @@ "it": "Acqua potabile", "ru": "Питьевая вода", "id": "Air minum" - }, - "tags": [ - "amenity=drinking_water" - ] - } - ], - "color": "#6bc4f7", - "tagRenderings": [ - "images", - { - "#": "Still in use?", - "question": { - "en": "Is this drinking water spot still operational?", - "nl": "Is deze drinkwaterkraan nog steeds werkende?", - "it": "Questo punto di acqua potabile è sempre funzionante?", - "fr": "Ce point d'eau potable est-il toujours opérationnel ?", - "de": "Ist diese Trinkwasserstelle noch in Betrieb?" - }, - "render": { - "en": "The operational status is {operational_status", - "nl": "Deze waterkraan-status is {operational_status}", - "it": "Lo stato operativo è {operational_status}", - "fr": "L'état opérationnel est {operational_status", - "de": "Der Betriebsstatus ist {operational_status" - }, - "freeform": { - "key": "operational_status" - }, - "mappings": [ - { - "if": "operational_status=", - "then": { - "en": "This drinking water works", - "nl": "Deze drinkwaterfontein werkt", - "it": "La fontanella funziona", - "fr": "Cette fontaine fonctionne" - } - }, - { - "if": "operational_status=broken", - "then": { - "en": "This drinking water is broken", - "nl": "Deze drinkwaterfontein is kapot", - "it": "La fontanella è guasta", - "fr": "Cette fontaine est cassée" - } - }, - { - "if": "operational_status=closed", - "then": { - "en": "This drinking water is closed", - "nl": "Deze drinkwaterfontein is afgesloten", - "it": "La fontanella è chiusa", - "fr": "Cette fontaine est fermée" - } - } - ] }, - { - "#": "Bottle refill", - "question": { - "en": "How easy is it to fill water bottles?", - "nl": "Hoe gemakkelijk is het om drinkbussen bij te vullen?", - "de": "Wie einfach ist es, Wasserflaschen zu füllen?", - "it": "Quanto è facile riempire d’acqua le bottiglie?", - "fr": "Est-il facile de remplir des bouteilles d'eau ?" - }, - "mappings": [ + "title": { + "render": { + "en": "Drinking water", + "nl": "Drinkbaar water", + "fr": "Eau potable", + "gl": "Auga potábel", + "de": "Trinkwasser", + "it": "Acqua potabile", + "ru": "Питьевая вода", + "id": "Air minum" + } + }, + "icon": { + "render": "pin:#6BC4F7;./assets/layers/drinking_water/drips.svg" + }, + "iconOverlays": [ { - "if": "bottle=yes", - "then": { - "en": "It is easy to refill water bottles", - "nl": "Een drinkbus bijvullen gaat makkelijk", - "de": "Es ist einfach, Wasserflaschen nachzufüllen", - "it": "È facile riempire d’acqua le bottiglie", - "fr": "Il est facile de remplir les bouteilles d'eau" - } + "if": { + "or": [ + "operational_status=broken", + "operational_status=closed" + ] + }, + "then": "close:#c33", + "badge": true + } + ], + "iconSize": "40,40,bottom", + "source": { + "osmTags": { + "and": [ + "amenity=drinking_water", + "access!=permissive", + "access!=private" + ] + } + }, + "calculatedTags": [ + "_closest_other_drinking_water_id=feat.closest('drinking_water').id", + "_closest_other_drinking_water_distance=Math.floor(feat.distanceTo(feat.closest('drinking_water')) * 1000)" + ], + "minzoom": 13, + "wayHandling": 1, + "presets": [ + { + "title": { + "en": "Drinking water", + "nl": "Drinkbaar water", + "fr": "Eau potable", + "gl": "Auga potábel", + "de": "Trinkwasser", + "it": "Acqua potabile", + "ru": "Питьевая вода", + "id": "Air minum" + }, + "tags": [ + "amenity=drinking_water" + ] + } + ], + "color": "#6bc4f7", + "tagRenderings": [ + "images", + { + "#": "Still in use?", + "question": { + "en": "Is this drinking water spot still operational?", + "nl": "Is deze drinkwaterkraan nog steeds werkende?", + "it": "Questo punto di acqua potabile è sempre funzionante?", + "fr": "Ce point d'eau potable est-il toujours opérationnel ?", + "de": "Ist diese Trinkwasserstelle noch in Betrieb?" + }, + "render": { + "en": "The operational status is {operational_status", + "nl": "Deze waterkraan-status is {operational_status}", + "it": "Lo stato operativo è {operational_status}", + "fr": "L'état opérationnel est {operational_status", + "de": "Der Betriebsstatus ist {operational_status" + }, + "freeform": { + "key": "operational_status" + }, + "mappings": [ + { + "if": "operational_status=", + "then": { + "en": "This drinking water works", + "nl": "Deze drinkwaterfontein werkt", + "it": "La fontanella funziona", + "fr": "Cette fontaine fonctionne" + } + }, + { + "if": "operational_status=broken", + "then": { + "en": "This drinking water is broken", + "nl": "Deze drinkwaterfontein is kapot", + "it": "La fontanella è guasta", + "fr": "Cette fontaine est cassée" + } + }, + { + "if": "operational_status=closed", + "then": { + "en": "This drinking water is closed", + "nl": "Deze drinkwaterfontein is afgesloten", + "it": "La fontanella è chiusa", + "fr": "Cette fontaine est fermée" + } + } + ] }, { - "if": "bottle=no", - "then": { - "en": "Water bottles may not fit", - "nl": "Een drinkbus past moeilijk", - "de": "Wasserflaschen passen möglicherweise nicht", - "it": "Le bottiglie d’acqua potrebbero non entrare", - "fr": "Les bouteilles d'eau peuvent ne pas passer" - } + "#": "Bottle refill", + "question": { + "en": "How easy is it to fill water bottles?", + "nl": "Hoe gemakkelijk is het om drinkbussen bij te vullen?", + "de": "Wie einfach ist es, Wasserflaschen zu füllen?", + "it": "Quanto è facile riempire d’acqua le bottiglie?", + "fr": "Est-il facile de remplir des bouteilles d'eau ?" + }, + "mappings": [ + { + "if": "bottle=yes", + "then": { + "en": "It is easy to refill water bottles", + "nl": "Een drinkbus bijvullen gaat makkelijk", + "de": "Es ist einfach, Wasserflaschen nachzufüllen", + "it": "È facile riempire d’acqua le bottiglie", + "fr": "Il est facile de remplir les bouteilles d'eau" + } + }, + { + "if": "bottle=no", + "then": { + "en": "Water bottles may not fit", + "nl": "Een drinkbus past moeilijk", + "de": "Wasserflaschen passen möglicherweise nicht", + "it": "Le bottiglie d’acqua potrebbero non entrare", + "fr": "Les bouteilles d'eau peuvent ne pas passer" + } + } + ] + }, + { + "render": { + "en": "There is another drinking water fountain at {_closest_other_drinking_water_distance} meter", + "nl": "Er bevindt zich een ander drinkwaterpunt op {_closest_other_drinking_water_distance} meter", + "it": "C’è un’altra fontanella a {_closest_other_drinking_water_distance} metri", + "de": "Ein weiterer Trinkwasserbrunnen befindet sich in {_closest_other_drinking_water_distance} Meter", + "fr": "Une autre source d’eau potable est à {_closest_other_drinking_water_distance} mètres a>" + }, + "condition": "_closest_other_drinking_water_id~*" } - ] - }, - { - "render": { - "en": "There is another drinking water fountain at {_closest_other_drinking_water_distance} meter", - "nl": "Er bevindt zich een ander drinkwaterpunt op {_closest_other_drinking_water_distance} meter", - "it": "C’è un’altra fontanella a {_closest_other_drinking_water_distance} metri", - "de": "Ein weiterer Trinkwasserbrunnen befindet sich in {_closest_other_drinking_water_distance} Meter", - "fr": "Une autre source d’eau potable est à {_closest_other_drinking_water_distance} mètres a>" - }, - "condition": "_closest_other_drinking_water_id~*" - } - ] + ] } \ No newline at end of file diff --git a/assets/layers/food/food.json b/assets/layers/food/food.json index 9dcb0f1dd..a63c06cbc 100644 --- a/assets/layers/food/food.json +++ b/assets/layers/food/food.json @@ -1,618 +1,618 @@ { - "id": "food", - "name": { - "nl": "Eetgelegenheden", - "en": "Restaurants and fast food" - }, - "source": { - "osmTags": { - "or": [ - "amenity=fast_food", - "amenity=restaurant" - ] - } - }, - "wayHandling": 1, - "icon": { - "render": "circle:white;./assets/layers/food/restaurant.svg", - "mappings": [ - { - "if": { - "and": [ - "amenity=fast_food", - "cuisine=friture" - ] - }, - "then": "circle:white;./assets/layers/food/fries.svg" - }, - { - "if": "amenity=fast_food", - "then": "circle:white;./assets/layers/food/fastfood.svg" - } - ] - }, - "iconOverlays": [ - { - "if": "opening_hours~*", - "then": "isOpen", - "badge": true + "id": "food", + "name": { + "nl": "Eetgelegenheden", + "en": "Restaurants and fast food" }, - { - "if": { - "or": [ - "diet:vegetarian=yes", - "diet:vegan=yes" + "source": { + "osmTags": { + "or": [ + "amenity=fast_food", + "amenity=restaurant" + ] + } + }, + "wayHandling": 1, + "icon": { + "render": "circle:white;./assets/layers/food/restaurant.svg", + "mappings": [ + { + "if": { + "and": [ + "amenity=fast_food", + "cuisine=friture" + ] + }, + "then": "circle:white;./assets/layers/food/fries.svg" + }, + { + "if": "amenity=fast_food", + "then": "circle:white;./assets/layers/food/fastfood.svg" + } ] - }, - "then": { - "render": "circle:white;./assets/themes/fritures/Vegetarian-mark.svg" - }, - "badge": true - } - ], - "label": { - "mappings": [ - { - "if": "name~*", - "then": "
{name}
" - } - ] - }, - "presets": [ - { - "title": { - "en": "restaurant", - "nl": "restaurant" - }, - "tags": [ - "amenity=restaurant" - ], - "description": { - "nl": "Een eetgegelegenheid waar je aan tafel wordt bediend", - "en": "A formal eating place with sit-down facilities selling full meals served by waiters" - }, - "preciseInput": { - "preferredBackground": "map" - } }, - { - "title": { - "en": "fastfood", - "nl": "fastfood-zaak" - }, - "tags": [ - "amenity=fast_food" - ], - "description": { - "nl": "Een zaak waar je snel bediend wordt, vaak met de focus op afhalen. Zitgelegenheid is eerder beperkt (of zelfs afwezig)", - "en": "A food business concentrating on fast counter-only service and take-away food" - }, - "preciseInput": { - "preferredBackground": "map" - } - }, - { - "title": { - "en": "fries shop", - "nl": "frituur" - }, - "tags": [ - "amenity=fast_food", - "cuisine=friture" - ], - "description": { - "nl": "Een fastfood-zaak waar je frieten koopt" - }, - "preciseInput": { - "preferredBackground": "map" - } - } - ], - "title": { - "render": { - "nl": "Eetgelegenheid" - }, - "mappings": [ - { - "if": { - "and": [ - "name~*", - "amenity=restaurant" - ] - }, - "then": { - "nl": "Restaurant {name}", - "en": "Restaurant {name}" - } - }, - { - "if": { - "and": [ - "name~*", - "amenity=fast_food" - ] - }, - "then": { - "nl": "Fastfood-zaak {name}", - "en": "Fastfood {name}" - } - } - ] - }, - "tagRenderings": [ - "images", - { - "#": "Name", - "question": { - "nl": "Wat is de naam van deze eetgelegenheid?", - "en": "What is the name of this restaurant?" - }, - "render": { - "nl": "De naam van deze eetgelegeheid is {name}", - "en": "The name of this restaurant is {name}" - }, - "freeform": { - "key": "name" - } - }, - { - "#": "Fastfood vs restaurant", - "question": { - "en": "What type of business is this?", - "nl": "Wat voor soort zaak is dit?" - }, - "mappings": [ + "iconOverlays": [ { - "if": "amenity=fast_food", - "then": { - "nl": "Dit is een fastfood-zaak. De focus ligt op snelle bediening, zitplaatsen zijn vaak beperkt en functioneel" - } + "if": "opening_hours~*", + "then": "isOpen", + "badge": true }, { - "if": "amenity=restaurant", - "then": { - "nl": "Dit is een restaurant. De focus ligt op een aangename ervaring waar je aan tafel wordt bediend" - } + "if": { + "or": [ + "diet:vegetarian=yes", + "diet:vegan=yes" + ] + }, + "then": { + "render": "circle:white;./assets/themes/fritures/Vegetarian-mark.svg" + }, + "badge": true } - ] - }, - "opening_hours", - "website", - "email", - "phone", - "payment-options", - "wheelchair-access", - { - "#": "Cuisine", - "question": { - "nl": "Welk soort gerechten worden hier geserveerd?", - "en": "Which food is served here?" - }, - "render": { - "nl": "Deze plaats serveert vooral {cuisine}", - "en": "This place mostly serves {cuisine}" - }, - "freeform": { - "key": "cuisine", - "addExtraTags": [ - "fixme=Freeform tag `cuisine` used, to be doublechecked" + ], + "label": { + "mappings": [ + { + "if": "name~*", + "then": "
{name}
" + } ] - }, - "mappings": [ - { - "if": "cuisine=pizza", - "then": { - "en": "This is a pizzeria", - "nl": "Dit is een pizzeria" - } - }, - { - "if": "cuisine=friture", - "then": { - "en": "This is a friture", - "nl": "Dit is een frituur" - } - }, - { - "if": "cuisine=pasta", - "then": { - "en": "Mainly serves pasta", - "nl": "Dit is een pastazaak" - } - }, - { - "if": "cuisine=kebab", - "then": { - "nl": "Dit is een kebabzaak" - } - }, - { - "if": "cuisine=sandwich", - "then": { - "nl": "Dit is een broodjeszaak" - } - }, - { - "if": "cuisine=burger", - "then": { - "nl": "Dit is een hamburgerrestaurant" - } - }, - { - "if": "cuisine=sushi", - "then": { - "nl": "Dit is een sushirestaurant" - } - }, - { - "if": "cuisine=coffee", - "then": { - "nl": "Dit is een koffiezaak" - } - }, - { - "if": "cuisine=italian", - "then": { - "nl": "Dit is een Italiaans restaurant (dat meer dan enkel pasta of pizza verkoopt)" - } - }, - { - "if": "cuisine=french", - "then": { - "nl": "Dit is een Frans restaurant" - } - }, - { - "if": "cuisine=chinese", - "then": { - "nl": "Dit is een Chinees restaurant" - } - }, - { - "if": "cuisine=greek", - "then": { - "nl": "Dit is een Grieks restaurant" - } - }, - { - "if": "cuisine=indian", - "then": { - "nl": "Dit is een Indisch restaurant" - } - }, - { - "if": "cuisine=turkish", - "then": { - "nl": "Dit is een Turks restaurant (dat meer dan enkel kebab verkoopt)" - } - }, - { - "if": "cuisine=thai", - "then": { - "nl": "Dit is een Thaïs restaurant" - } - } - ] }, - { - "#": "Takeaway", - "question": { - "nl": "Biedt deze zaak een afhaalmogelijkheid aan?", - "en": "Does this place offer takea-way?" - }, - "mappings": [ + "presets": [ { - "if": "takeaway=only", - "then": { - "en": "This is a take-away only business", - "nl": "Hier is enkel afhaal mogelijk" - } + "title": { + "en": "restaurant", + "nl": "restaurant" + }, + "tags": [ + "amenity=restaurant" + ], + "description": { + "nl": "Een eetgegelegenheid waar je aan tafel wordt bediend", + "en": "A formal eating place with sit-down facilities selling full meals served by waiters" + }, + "preciseInput": { + "preferredBackground": "map" + } }, { - "if": "takeaway=yes", - "then": { - "en": "Take-away is possible here", - "nl": "Eten kan hier afgehaald worden" - } + "title": { + "en": "fastfood", + "nl": "fastfood-zaak" + }, + "tags": [ + "amenity=fast_food" + ], + "description": { + "nl": "Een zaak waar je snel bediend wordt, vaak met de focus op afhalen. Zitgelegenheid is eerder beperkt (of zelfs afwezig)", + "en": "A food business concentrating on fast counter-only service and take-away food" + }, + "preciseInput": { + "preferredBackground": "map" + } }, { - "if": "takeaway=no", - "then": { - "en": "Take-away is not possible here", - "nl": "Hier is geen afhaalmogelijkheid" - } + "title": { + "en": "fries shop", + "nl": "frituur" + }, + "tags": [ + "amenity=fast_food", + "cuisine=friture" + ], + "description": { + "nl": "Een fastfood-zaak waar je frieten koopt" + }, + "preciseInput": { + "preferredBackground": "map" + } } - ] + ], + "title": { + "render": { + "nl": "Eetgelegenheid" + }, + "mappings": [ + { + "if": { + "and": [ + "name~*", + "amenity=restaurant" + ] + }, + "then": { + "nl": "Restaurant {name}", + "en": "Restaurant {name}" + } + }, + { + "if": { + "and": [ + "name~*", + "amenity=fast_food" + ] + }, + "then": { + "nl": "Fastfood-zaak {name}", + "en": "Fastfood {name}" + } + } + ] }, - { - "#": "Vegetarian (no friture)", - "question": { - "nl": "Heeft deze eetgelegenheid een vegetarische optie?", - "en": "Does this restaurant have a vegetarian option?" - }, - "mappings": [ + "tagRenderings": [ + "images", { - "if": "diet:vegetarian=no", - "then": { - "nl": "Geen vegetarische opties beschikbaar" - } + "#": "Name", + "question": { + "nl": "Wat is de naam van deze eetgelegenheid?", + "en": "What is the name of this restaurant?" + }, + "render": { + "nl": "De naam van deze eetgelegeheid is {name}", + "en": "The name of this restaurant is {name}" + }, + "freeform": { + "key": "name" + } }, { - "if": "diet:vegetarian=limited", - "then": { - "nl": "Beperkte vegetarische opties zijn beschikbaar" - } - }, - { - "if": "diet:vegetarian=yes", - "then": { - "nl": "Vegetarische opties zijn beschikbaar" - } - }, - { - "if": "diet:vegetarian=only", - "then": { - "nl": "Enkel vegetarische opties zijn beschikbaar" - } - } - ], - "condition": "cuisine!=friture" - }, - { - "#": "Vegan (no friture)", - "question": { - "nl": "Heeft deze eetgelegenheid een veganistische optie?" - }, - "mappings": [ - { - "if": "diet:vegan=no", - "then": { - "nl": "Geen veganistische opties beschikbaar" - } - }, - { - "if": "diet:vegan=limited", - "then": { - "nl": "Beperkte veganistische opties zijn beschikbaar" - } - }, - { - "if": "diet:vegan=yes", - "then": { - "nl": "Veganistische opties zijn beschikbaar" - } - }, - { - "if": "diet:vegan=only", - "then": { - "nl": "Enkel veganistische opties zijn beschikbaar" - } - } - ], - "condition": "cuisine!=friture" - }, - { - "#": "halal (no friture)", - "question": { - "en": "Does this restaurant offer a halal menu?", - "nl": "Heeft dit restaurant halal opties?" - }, - "mappings": [ - { - "if": "diet:halal=no", - "then": { - "en": "There are no halal options available", - "nl": "Er zijn geen halal opties aanwezig" - } - }, - { - "if": "diet:halal=limited", - "then": { - "en": "There is a small halal menu", - "nl": "Er zijn een beperkt aantal halal opties" - } - }, - { - "if": "diet:halal=yes", - "then": { - "nl": "Halal menu verkrijgbaar", - "en": "There is a halal menu" - } - }, - { - "if": "diet:halal=only", - "then": { - "nl": "Enkel halal opties zijn beschikbaar", - "en": "Only halal options are available" - } - } - ], - "condition": "cuisine!=friture" - }, - { - "question": { - "nl": "Heeft deze frituur vegetarische snacks?", - "fr": "Cette friterie est-elle équipée de snacks végétariens ?" - }, - "mappings": [ - { - "if": "diet:vegetarian=yes", - "then": { - "nl": "Er zijn vegetarische snacks aanwezig", - "fr": "Des collations végétariens sont disponibles" - } - }, - { - "if": "diet:vegetarian=limited", - "then": { - "nl": "Slechts enkele vegetarische snacks", - "fr": "Quelques snacks végétariens seulement" - } - }, - { - "if": "diet:vegetarian=no", - "then": { - "nl": "Geen vegetarische snacks beschikbaar", - "fr": "Pas d'en-cas végétariens disponibles" - } - } - ], - "condition": "cuisine=friture" - }, - { - "question": { - "nl": "Heeft deze frituur veganistische snacks?", - "fr": "Cette friterie est-elle équipée de snacks végétaliens ?" - }, - "mappings": [ - { - "if": "diet:vegan=yes", - "then": { - "nl": "Er zijn veganistische snacks aanwezig", - "fr": "Des collations végétaliens sont disponibles" - } - }, - { - "if": "diet:vegan=limited", - "then": { - "nl": "Slechts enkele veganistische snacks", - "fr": "Quelques snacks végétaliens seulement" - } - }, - { - "if": "diet:vegan=no", - "then": { - "nl": "Geen veganistische snacks beschikbaar", - "fr": "Pas d'en-cas végétaliens disponibles" - } - } - ], - "condition": "cuisine=friture" - }, - { - "question": { - "nl": "Bakt deze frituur met dierlijk vet of met plantaardige olie?", - "fr": "Cette friteuse fonctionne-t-elle avec de la graisse animale ou végétale ?" - }, - "mappings": [ - { - "if": "friture:oil=vegetable", - "then": { - "nl": "Plantaardige olie", - "fr": "Huile végétale" - } - }, - { - "if": "friture:oil=animal", - "then": { - "nl": "Dierlijk vet", - "fr": "Graisse animale" - } - } - ], - "condition": "cuisine=friture" - }, - { - "question": { - "nl": "Als je je eigen container (bv. kookpot of kleine potjes voor saus) meeneemt, gebruikt de frituur deze dan om je bestelling in te doen?", - "fr": "Est-il proposé d’utiliser ses propres contenants pour sa commande ?
", - "en": "If you bring your own container (such as a cooking pot and small pots), is it used to package your order?
", - "ja": "お客様が持参容器(調理用の鍋や小さな鍋など)をもってきた場合は、注文の梱包に使用されますか?
" - }, - "mappings": [ - { - "if": "reusable_packaging:accept=yes", - "then": { - "nl": "Je mag je eigen containers meenemen om je bestelling in mee te nemen en zo minder afval te maken", - "fr": "Vous pouvez apporter vos contenants pour votre commande, limitant l’usage de matériaux à usage unique et les déchets", - "en": "You can bring your own containers to get your order, saving on single-use packaging material and thus waste", - "ja": "自分の容器を持ってきて、注文を受け取ることができ、使い捨ての梱包材を節約して、無駄を省くことができます" - } - }, - { - "if": "reusable_packaging:accept=no", - "then": { - "nl": "Je mag geen eigen containers meenemen om je bestelling in mee te nemen", - "fr": "Apporter ses propres contenants n’est pas permis", - "en": "Bringing your own container is not allowed", - "ja": "独自の容器を持参することはできません", - "ru": "Приносить свою тару не разрешено" - } - }, - { - "if": "reusable_packaging:accept=only", - "then": { - "nl": "Je moet je eigen containers meenemen om je bestelling in mee te nemen.", - "en": "You must bring your own container to order here.", - "ja": "自身の容器が注文に必要。", - "fr": "Il est obligatoire d’apporter ses propres contenants" - } - } - ], - "condition": "cuisine=friture" - } - ], - "filter": [ - { - "options": [ - { - "question": { - "en": "Opened now", - "nl": "Nu geopened" - }, - "osmTags": "_isOpen=yes" - } - ] - }, - { - "options": [ - { - "question": { - "en": "Has a vegetarian menu", - "nl": "Heeft een vegetarisch menu" - }, - "osmTags": { - "or": [ - "diet:vegetarian=yes", - "diet:vegetarian=only", - "diet:vegan=yes", - "diet:vegan=only" + "#": "Fastfood vs restaurant", + "question": { + "en": "What type of business is this?", + "nl": "Wat voor soort zaak is dit?" + }, + "mappings": [ + { + "if": "amenity=fast_food", + "then": { + "nl": "Dit is een fastfood-zaak. De focus ligt op snelle bediening, zitplaatsen zijn vaak beperkt en functioneel" + } + }, + { + "if": "amenity=restaurant", + "then": { + "nl": "Dit is een restaurant. De focus ligt op een aangename ervaring waar je aan tafel wordt bediend" + } + } ] - } - } - ] - }, - { - "options": [ + }, + "opening_hours", + "website", + "email", + "phone", + "payment-options", + "wheelchair-access", { - "question": { - "en": "Has a vegan menu", - "nl": "Heeft een veganistisch menu" - }, - "osmTags": { - "or": [ - "diet:vegan=yes", - "diet:vegan=only" + "#": "Cuisine", + "question": { + "nl": "Welk soort gerechten worden hier geserveerd?", + "en": "Which food is served here?" + }, + "render": { + "nl": "Deze plaats serveert vooral {cuisine}", + "en": "This place mostly serves {cuisine}" + }, + "freeform": { + "key": "cuisine", + "addExtraTags": [ + "fixme=Freeform tag `cuisine` used, to be doublechecked" + ] + }, + "mappings": [ + { + "if": "cuisine=pizza", + "then": { + "en": "This is a pizzeria", + "nl": "Dit is een pizzeria" + } + }, + { + "if": "cuisine=friture", + "then": { + "en": "This is a friture", + "nl": "Dit is een frituur" + } + }, + { + "if": "cuisine=pasta", + "then": { + "en": "Mainly serves pasta", + "nl": "Dit is een pastazaak" + } + }, + { + "if": "cuisine=kebab", + "then": { + "nl": "Dit is een kebabzaak" + } + }, + { + "if": "cuisine=sandwich", + "then": { + "nl": "Dit is een broodjeszaak" + } + }, + { + "if": "cuisine=burger", + "then": { + "nl": "Dit is een hamburgerrestaurant" + } + }, + { + "if": "cuisine=sushi", + "then": { + "nl": "Dit is een sushirestaurant" + } + }, + { + "if": "cuisine=coffee", + "then": { + "nl": "Dit is een koffiezaak" + } + }, + { + "if": "cuisine=italian", + "then": { + "nl": "Dit is een Italiaans restaurant (dat meer dan enkel pasta of pizza verkoopt)" + } + }, + { + "if": "cuisine=french", + "then": { + "nl": "Dit is een Frans restaurant" + } + }, + { + "if": "cuisine=chinese", + "then": { + "nl": "Dit is een Chinees restaurant" + } + }, + { + "if": "cuisine=greek", + "then": { + "nl": "Dit is een Grieks restaurant" + } + }, + { + "if": "cuisine=indian", + "then": { + "nl": "Dit is een Indisch restaurant" + } + }, + { + "if": "cuisine=turkish", + "then": { + "nl": "Dit is een Turks restaurant (dat meer dan enkel kebab verkoopt)" + } + }, + { + "if": "cuisine=thai", + "then": { + "nl": "Dit is een Thaïs restaurant" + } + } ] - } - } - ] - }, - { - "options": [ + }, { - "question": { - "en": "Has a halal menu", - "nl": "Heeft een halal menu" - }, - "osmTags": { - "or": [ - "diet:halal=yes", - "diet:halal=only" + "#": "Takeaway", + "question": { + "nl": "Biedt deze zaak een afhaalmogelijkheid aan?", + "en": "Does this place offer takea-way?" + }, + "mappings": [ + { + "if": "takeaway=only", + "then": { + "en": "This is a take-away only business", + "nl": "Hier is enkel afhaal mogelijk" + } + }, + { + "if": "takeaway=yes", + "then": { + "en": "Take-away is possible here", + "nl": "Eten kan hier afgehaald worden" + } + }, + { + "if": "takeaway=no", + "then": { + "en": "Take-away is not possible here", + "nl": "Hier is geen afhaalmogelijkheid" + } + } ] - } + }, + { + "#": "Vegetarian (no friture)", + "question": { + "nl": "Heeft deze eetgelegenheid een vegetarische optie?", + "en": "Does this restaurant have a vegetarian option?" + }, + "mappings": [ + { + "if": "diet:vegetarian=no", + "then": { + "nl": "Geen vegetarische opties beschikbaar" + } + }, + { + "if": "diet:vegetarian=limited", + "then": { + "nl": "Beperkte vegetarische opties zijn beschikbaar" + } + }, + { + "if": "diet:vegetarian=yes", + "then": { + "nl": "Vegetarische opties zijn beschikbaar" + } + }, + { + "if": "diet:vegetarian=only", + "then": { + "nl": "Enkel vegetarische opties zijn beschikbaar" + } + } + ], + "condition": "cuisine!=friture" + }, + { + "#": "Vegan (no friture)", + "question": { + "nl": "Heeft deze eetgelegenheid een veganistische optie?" + }, + "mappings": [ + { + "if": "diet:vegan=no", + "then": { + "nl": "Geen veganistische opties beschikbaar" + } + }, + { + "if": "diet:vegan=limited", + "then": { + "nl": "Beperkte veganistische opties zijn beschikbaar" + } + }, + { + "if": "diet:vegan=yes", + "then": { + "nl": "Veganistische opties zijn beschikbaar" + } + }, + { + "if": "diet:vegan=only", + "then": { + "nl": "Enkel veganistische opties zijn beschikbaar" + } + } + ], + "condition": "cuisine!=friture" + }, + { + "#": "halal (no friture)", + "question": { + "en": "Does this restaurant offer a halal menu?", + "nl": "Heeft dit restaurant halal opties?" + }, + "mappings": [ + { + "if": "diet:halal=no", + "then": { + "en": "There are no halal options available", + "nl": "Er zijn geen halal opties aanwezig" + } + }, + { + "if": "diet:halal=limited", + "then": { + "en": "There is a small halal menu", + "nl": "Er zijn een beperkt aantal halal opties" + } + }, + { + "if": "diet:halal=yes", + "then": { + "nl": "Halal menu verkrijgbaar", + "en": "There is a halal menu" + } + }, + { + "if": "diet:halal=only", + "then": { + "nl": "Enkel halal opties zijn beschikbaar", + "en": "Only halal options are available" + } + } + ], + "condition": "cuisine!=friture" + }, + { + "question": { + "nl": "Heeft deze frituur vegetarische snacks?", + "fr": "Cette friterie est-elle équipée de snacks végétariens ?" + }, + "mappings": [ + { + "if": "diet:vegetarian=yes", + "then": { + "nl": "Er zijn vegetarische snacks aanwezig", + "fr": "Des collations végétariens sont disponibles" + } + }, + { + "if": "diet:vegetarian=limited", + "then": { + "nl": "Slechts enkele vegetarische snacks", + "fr": "Quelques snacks végétariens seulement" + } + }, + { + "if": "diet:vegetarian=no", + "then": { + "nl": "Geen vegetarische snacks beschikbaar", + "fr": "Pas d'en-cas végétariens disponibles" + } + } + ], + "condition": "cuisine=friture" + }, + { + "question": { + "nl": "Heeft deze frituur veganistische snacks?", + "fr": "Cette friterie est-elle équipée de snacks végétaliens ?" + }, + "mappings": [ + { + "if": "diet:vegan=yes", + "then": { + "nl": "Er zijn veganistische snacks aanwezig", + "fr": "Des collations végétaliens sont disponibles" + } + }, + { + "if": "diet:vegan=limited", + "then": { + "nl": "Slechts enkele veganistische snacks", + "fr": "Quelques snacks végétaliens seulement" + } + }, + { + "if": "diet:vegan=no", + "then": { + "nl": "Geen veganistische snacks beschikbaar", + "fr": "Pas d'en-cas végétaliens disponibles" + } + } + ], + "condition": "cuisine=friture" + }, + { + "question": { + "nl": "Bakt deze frituur met dierlijk vet of met plantaardige olie?", + "fr": "Cette friteuse fonctionne-t-elle avec de la graisse animale ou végétale ?" + }, + "mappings": [ + { + "if": "friture:oil=vegetable", + "then": { + "nl": "Plantaardige olie", + "fr": "Huile végétale" + } + }, + { + "if": "friture:oil=animal", + "then": { + "nl": "Dierlijk vet", + "fr": "Graisse animale" + } + } + ], + "condition": "cuisine=friture" + }, + { + "question": { + "nl": "Als je je eigen container (bv. kookpot of kleine potjes voor saus) meeneemt, gebruikt de frituur deze dan om je bestelling in te doen?", + "fr": "Est-il proposé d’utiliser ses propres contenants pour sa commande ?
", + "en": "If you bring your own container (such as a cooking pot and small pots), is it used to package your order?
", + "ja": "お客様が持参容器(調理用の鍋や小さな鍋など)をもってきた場合は、注文の梱包に使用されますか?
" + }, + "mappings": [ + { + "if": "reusable_packaging:accept=yes", + "then": { + "nl": "Je mag je eigen containers meenemen om je bestelling in mee te nemen en zo minder afval te maken", + "fr": "Vous pouvez apporter vos contenants pour votre commande, limitant l’usage de matériaux à usage unique et les déchets", + "en": "You can bring your own containers to get your order, saving on single-use packaging material and thus waste", + "ja": "自分の容器を持ってきて、注文を受け取ることができ、使い捨ての梱包材を節約して、無駄を省くことができます" + } + }, + { + "if": "reusable_packaging:accept=no", + "then": { + "nl": "Je mag geen eigen containers meenemen om je bestelling in mee te nemen", + "fr": "Apporter ses propres contenants n’est pas permis", + "en": "Bringing your own container is not allowed", + "ja": "独自の容器を持参することはできません", + "ru": "Приносить свою тару не разрешено" + } + }, + { + "if": "reusable_packaging:accept=only", + "then": { + "nl": "Je moet je eigen containers meenemen om je bestelling in mee te nemen.", + "en": "You must bring your own container to order here.", + "ja": "自身の容器が注文に必要。", + "fr": "Il est obligatoire d’apporter ses propres contenants" + } + } + ], + "condition": "cuisine=friture" } - ] - } - ] + ], + "filter": [ + { + "options": [ + { + "question": { + "en": "Opened now", + "nl": "Nu geopened" + }, + "osmTags": "_isOpen=yes" + } + ] + }, + { + "options": [ + { + "question": { + "en": "Has a vegetarian menu", + "nl": "Heeft een vegetarisch menu" + }, + "osmTags": { + "or": [ + "diet:vegetarian=yes", + "diet:vegetarian=only", + "diet:vegan=yes", + "diet:vegan=only" + ] + } + } + ] + }, + { + "options": [ + { + "question": { + "en": "Has a vegan menu", + "nl": "Heeft een veganistisch menu" + }, + "osmTags": { + "or": [ + "diet:vegan=yes", + "diet:vegan=only" + ] + } + } + ] + }, + { + "options": [ + { + "question": { + "en": "Has a halal menu", + "nl": "Heeft een halal menu" + }, + "osmTags": { + "or": [ + "diet:halal=yes", + "diet:halal=only" + ] + } + } + ] + } + ] } \ No newline at end of file diff --git a/assets/layers/ghost_bike/ghost_bike.json b/assets/layers/ghost_bike/ghost_bike.json index 68020ab52..3183b7283 100644 --- a/assets/layers/ghost_bike/ghost_bike.json +++ b/assets/layers/ghost_bike/ghost_bike.json @@ -1,186 +1,186 @@ { - "id": "ghost_bike", - "name": { - "en": "Ghost bikes", - "nl": "Witte Fietsen", - "de": "Geisterrad", - "it": "Bici fantasma", - "fr": "Vélos fantômes", - "eo": "Fantombiciklo", - "es": "Bicicleta blanca", - "fi": "Haamupyörä", - "gl": "Bicicleta pantasma", - "hu": "Emlékkerékpár", - "ja": "ゴーストバイク", - "nb_NO": "Spøkelsessykler", - "pl": "Duch roweru", - "pt_BR": "Bicicleta fantasma", - "ru": "Велосипед Ghost", - "sv": "Spökcykel", - "zh_Hant": "幽靈單車" - }, - "source": { - "osmTags": "memorial=ghost_bike" - }, - "minzoom": 0, - "title": { - "render": { - "en": "Ghost bike", - "nl": "Witte Fiets", - "de": "Geisterrad", - "it": "Bici fantasma", - "fr": "Vélo fantôme", - "eo": "Fantombiciklo", - "es": "Bicicleta blanca", - "fi": "Haamupyörä", - "gl": "Bicicleta pantasma", - "hu": "Emlékkerékpár", - "ja": "ゴーストバイク", - "nb_NO": "Spøkelsessykler", - "pl": "Duch roweru", - "pt_BR": "Bicicleta fantasma", - "ru": "Велосипед Ghost", - "sv": "Spökcykel", - "zh_Hant": "幽靈單車" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "en": "Ghost bike in the remembrance of {name}", - "nl": "Witte fiets ter nagedachtenis van {name}", - "de": "Geisterrad im Gedenken an {name}", - "it": "Bici fantasma in ricordo di {name}", - "fr": "Vélo fantôme en souvenir de {name}" - } - } - ] - }, - "icon": "./assets/layers/ghost_bike/ghost_bike.svg", - "iconSize": "40,40,bottom", - "width": "5", - "color": "#000", - "wayHandling": 1, - "presets": [ - { - "title": { - "en": "Ghost bike", - "nl": "Witte fiets", + "id": "ghost_bike", + "name": { + "en": "Ghost bikes", + "nl": "Witte Fietsen", "de": "Geisterrad", "it": "Bici fantasma", - "fr": "Vélo fantôme" - }, - "tags": [ - "historic=memorial", - "memorial=ghost_bike" - ] - } - ], - "tagRenderings": [ - { - "render": { - "en": "A ghost bike is a memorial for a cyclist who died in a traffic accident, in the form of a white bicycle placed permanently near the accident location.", - "nl": "Een Witte Fiets (of Spookfiets) is een aandenken aan een fietser die bij een verkeersongeval om het leven kwam. Het gaat over een witgeschilderde fiets die geplaatst werd in de buurt van het ongeval.", - "de": "Ein Geisterrad ist ein Denkmal für einen Radfahrer, der bei einem Verkehrsunfall ums Leben kam, in Form eines weißen Fahrrades, das dauerhaft in der Nähe des Unfallortes aufgestellt wird.", - "it": "Una bici fantasma è il memoriale di un ciclista che è morto in un incidente stradale e che ha la forma di una bicicletta bianca piazzata in maniera stabile vicino al luogo dell’incidente.", - "fr": "Un vélo fantôme est un monument commémoratif pour un cycliste décédé dans un accident de la route, sous la forme d'un vélo blanc placé en permanence près du lieu de l'accident." - } + "fr": "Vélos fantômes", + "eo": "Fantombiciklo", + "es": "Bicicleta blanca", + "fi": "Haamupyörä", + "gl": "Bicicleta pantasma", + "hu": "Emlékkerékpár", + "ja": "ゴーストバイク", + "nb_NO": "Spøkelsessykler", + "pl": "Duch roweru", + "pt_BR": "Bicicleta fantasma", + "ru": "Велосипед Ghost", + "sv": "Spökcykel", + "zh_Hant": "幽靈單車" }, - "images", - { - "question": { - "en": "Whom is remembered by this ghost bike?
Please respect privacy - only fill out the name if it is widely published or marked on the cycle. Opt to leave out the family name.
", - "nl": "Aan wie is deze witte fiets een eerbetoon?
Respecteer privacy - voeg enkel een naam toe indien die op de fiets staat of gepubliceerd is. Eventueel voeg je enkel de voornaam toe.
", - "de": "An wen erinnert dieses Geisterrad?
Bitte respektieren Sie die Privatsphäre - geben Sie den Namen nur an, wenn er weit verbreitet oder auf dem Fahrrad markiert ist. Den Familiennamen können Sie weglassen.
", - "it": "A chi è dedicata questa bici fantasma?
Rispetta la privacy (compila solo il nome se questo è stato ampiamente pubblicato o se è scritto sulla bici). Decidi se è il caso di non inserire il cognome.
", - "fr": "À qui est dédié ce vélo fantôme ?
Veuillez respecter la vie privée – ajoutez le nom seulement s'il est largement publié ou marqué sur le vélo. Choisissez de ne pas indiquer le nom de famille
" - }, - "render": { - "en": "In remembrance of {name}", - "nl": "Ter nagedachtenis van {name}", - "de": "Im Gedenken an {name}", - "it": "In ricordo di {name}", - "fr": "En souvenir de {name}", - "ru": "В знак памяти о {name}" - }, - "freeform": { - "key": "name" - }, - "mappings": [ + "source": { + "osmTags": "memorial=ghost_bike" + }, + "minzoom": 0, + "title": { + "render": { + "en": "Ghost bike", + "nl": "Witte Fiets", + "de": "Geisterrad", + "it": "Bici fantasma", + "fr": "Vélo fantôme", + "eo": "Fantombiciklo", + "es": "Bicicleta blanca", + "fi": "Haamupyörä", + "gl": "Bicicleta pantasma", + "hu": "Emlékkerékpár", + "ja": "ゴーストバイク", + "nb_NO": "Spøkelsessykler", + "pl": "Duch roweru", + "pt_BR": "Bicicleta fantasma", + "ru": "Велосипед Ghost", + "sv": "Spökcykel", + "zh_Hant": "幽靈單車" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "en": "Ghost bike in the remembrance of {name}", + "nl": "Witte fiets ter nagedachtenis van {name}", + "de": "Geisterrad im Gedenken an {name}", + "it": "Bici fantasma in ricordo di {name}", + "fr": "Vélo fantôme en souvenir de {name}" + } + } + ] + }, + "icon": "./assets/layers/ghost_bike/ghost_bike.svg", + "iconSize": "40,40,bottom", + "width": "5", + "color": "#000", + "wayHandling": 1, + "presets": [ { - "if": "noname=yes", - "then": { - "en": "No name is marked on the bike", - "nl": "De naam is niet aangeduid op de fiets", - "de": "Auf dem Fahrrad ist kein Name angegeben", - "it": "Nessun nome scritto sulla bici", - "fr": "Aucun nom n'est marqué sur le vélo" - } + "title": { + "en": "Ghost bike", + "nl": "Witte fiets", + "de": "Geisterrad", + "it": "Bici fantasma", + "fr": "Vélo fantôme" + }, + "tags": [ + "historic=memorial", + "memorial=ghost_bike" + ] } - ] - }, - { - "question": { - "en": "On what webpage can one find more information about the Ghost bike or the accident?", - "nl": "Op welke website kan men meer informatie vinden over de Witte fiets of over het ongeval?", - "de": "Auf welcher Webseite kann man mehr Informationen über das Geisterrad oder den Unfall finden?", - "it": "In quale pagina web si possono trovare informazioni sulla bici fantasma o l’incidente?", - "fr": "Sur quelle page web peut-on trouver plus d'informations sur le Vélo fantôme ou l'accident ?" - }, - "render": { - "en": "
More information is available", - "nl": "Meer informatie", - "de": "Mehr Informationen", - "it": "Sono disponibili ulteriori informazioni", - "ru": "Доступна более подробная информация", - "fr": "Plus d'informations sont disponibles", - "id": "Informasi lanjut tersedia" - }, - "freeform": { - "type": "url", - "key": "source" - } - }, - { - "question": { - "en": "What is the inscription on this Ghost bike?", - "nl": "Wat is het opschrift op deze witte fiets?", - "de": "Wie lautet die Inschrift auf diesem Geisterrad?", - "it": "Che cosa è scritto sulla bici fantasma?", - "fr": "Quelle est l'inscription sur ce vélo fantôme ?" - }, - "render": { - "en": "{inscription}", - "nl": "{inscription}", - "de": "{inscription}", - "ca": "{inscription}", - "fr": "{inscription}", - "it": "{inscription}", - "ru": "{inscription}", - "id": "{inscription}" - }, - "freeform": { - "key": "inscription" - } - }, - { - "question": { - "nl": "Wanneer werd deze witte fiets geplaatst?", - "en": "When was this Ghost bike installed?", - "it": "Quando è stata installata questa bici fantasma?", - "fr": "Quand ce vélo fantôme a-t-il été installée ?" - }, - "render": { - "nl": "Geplaatst op {start_date}", - "en": "Placed on {start_date}", - "it": "Piazzata in data {start_date}", - "fr": "Placé le {start_date}", - "ru": "Установлен {start_date}" - }, - "freeform": { - "key": "start_date", - "type": "date" - } - } - ] + ], + "tagRenderings": [ + { + "render": { + "en": "A ghost bike is a memorial for a cyclist who died in a traffic accident, in the form of a white bicycle placed permanently near the accident location.", + "nl": "Een Witte Fiets (of Spookfiets) is een aandenken aan een fietser die bij een verkeersongeval om het leven kwam. Het gaat over een witgeschilderde fiets die geplaatst werd in de buurt van het ongeval.", + "de": "Ein Geisterrad ist ein Denkmal für einen Radfahrer, der bei einem Verkehrsunfall ums Leben kam, in Form eines weißen Fahrrades, das dauerhaft in der Nähe des Unfallortes aufgestellt wird.", + "it": "Una bici fantasma è il memoriale di un ciclista che è morto in un incidente stradale e che ha la forma di una bicicletta bianca piazzata in maniera stabile vicino al luogo dell’incidente.", + "fr": "Un vélo fantôme est un monument commémoratif pour un cycliste décédé dans un accident de la route, sous la forme d'un vélo blanc placé en permanence près du lieu de l'accident." + } + }, + "images", + { + "question": { + "en": "Whom is remembered by this ghost bike?
Please respect privacy - only fill out the name if it is widely published or marked on the cycle. Opt to leave out the family name.
", + "nl": "Aan wie is deze witte fiets een eerbetoon?
Respecteer privacy - voeg enkel een naam toe indien die op de fiets staat of gepubliceerd is. Eventueel voeg je enkel de voornaam toe.
", + "de": "An wen erinnert dieses Geisterrad?
Bitte respektieren Sie die Privatsphäre - geben Sie den Namen nur an, wenn er weit verbreitet oder auf dem Fahrrad markiert ist. Den Familiennamen können Sie weglassen.
", + "it": "A chi è dedicata questa bici fantasma?
Rispetta la privacy (compila solo il nome se questo è stato ampiamente pubblicato o se è scritto sulla bici). Decidi se è il caso di non inserire il cognome.
", + "fr": "À qui est dédié ce vélo fantôme ?
Veuillez respecter la vie privée – ajoutez le nom seulement s'il est largement publié ou marqué sur le vélo. Choisissez de ne pas indiquer le nom de famille
" + }, + "render": { + "en": "In remembrance of {name}", + "nl": "Ter nagedachtenis van {name}", + "de": "Im Gedenken an {name}", + "it": "In ricordo di {name}", + "fr": "En souvenir de {name}", + "ru": "В знак памяти о {name}" + }, + "freeform": { + "key": "name" + }, + "mappings": [ + { + "if": "noname=yes", + "then": { + "en": "No name is marked on the bike", + "nl": "De naam is niet aangeduid op de fiets", + "de": "Auf dem Fahrrad ist kein Name angegeben", + "it": "Nessun nome scritto sulla bici", + "fr": "Aucun nom n'est marqué sur le vélo" + } + } + ] + }, + { + "question": { + "en": "On what webpage can one find more information about the Ghost bike or the accident?", + "nl": "Op welke website kan men meer informatie vinden over de Witte fiets of over het ongeval?", + "de": "Auf welcher Webseite kann man mehr Informationen über das Geisterrad oder den Unfall finden?", + "it": "In quale pagina web si possono trovare informazioni sulla bici fantasma o l’incidente?", + "fr": "Sur quelle page web peut-on trouver plus d'informations sur le Vélo fantôme ou l'accident ?" + }, + "render": { + "en": "More information is available", + "nl": "Meer informatie", + "de": "Mehr Informationen", + "it": "Sono disponibili ulteriori informazioni", + "ru": "Доступна более подробная информация", + "fr": "Plus d'informations sont disponibles", + "id": "Informasi lanjut tersedia" + }, + "freeform": { + "type": "url", + "key": "source" + } + }, + { + "question": { + "en": "What is the inscription on this Ghost bike?", + "nl": "Wat is het opschrift op deze witte fiets?", + "de": "Wie lautet die Inschrift auf diesem Geisterrad?", + "it": "Che cosa è scritto sulla bici fantasma?", + "fr": "Quelle est l'inscription sur ce vélo fantôme ?" + }, + "render": { + "en": "{inscription}", + "nl": "{inscription}", + "de": "{inscription}", + "ca": "{inscription}", + "fr": "{inscription}", + "it": "{inscription}", + "ru": "{inscription}", + "id": "{inscription}" + }, + "freeform": { + "key": "inscription" + } + }, + { + "question": { + "nl": "Wanneer werd deze witte fiets geplaatst?", + "en": "When was this Ghost bike installed?", + "it": "Quando è stata installata questa bici fantasma?", + "fr": "Quand ce vélo fantôme a-t-il été installée ?" + }, + "render": { + "nl": "Geplaatst op {start_date}", + "en": "Placed on {start_date}", + "it": "Piazzata in data {start_date}", + "fr": "Placé le {start_date}", + "ru": "Установлен {start_date}" + }, + "freeform": { + "key": "start_date", + "type": "date" + } + } + ] } \ No newline at end of file diff --git a/assets/layers/grass_in_parks/grass_in_parks.json b/assets/layers/grass_in_parks/grass_in_parks.json index 9a48eb2be..f9dcd0f23 100644 --- a/assets/layers/grass_in_parks/grass_in_parks.json +++ b/assets/layers/grass_in_parks/grass_in_parks.json @@ -1,53 +1,53 @@ { - "id": "grass_in_parks", - "name": { - "nl": "Toegankelijke grasvelden in parken" - }, - "source": { - "osmTags": { - "or": [ - "name=Park Oude God", - { - "and": [ - "landuse=grass", + "id": "grass_in_parks", + "name": { + "nl": "Toegankelijke grasvelden in parken" + }, + "source": { + "osmTags": { + "or": [ + "name=Park Oude God", + { + "and": [ + "landuse=grass", + { + "or": [ + "access=public", + "access=yes" + ] + } + ] + } + ] + }, + "overpassScript": "way[\"leisure\"=\"park\"];node(w);is_in;area._[\"leisure\"=\"park\"];(way(area)[\"landuse\"=\"grass\"]; node(w); );" + }, + "minzoom": 0, + "title": { + "render": { + "nl": "Speelweide in een park" + }, + "mappings": [ { - "or": [ - "access=public", - "access=yes" - ] + "if": "name~*", + "then": { + "nl": "{name}" + } } - ] - } - ] + ] }, - "overpassScript": "way[\"leisure\"=\"park\"];node(w);is_in;area._[\"leisure\"=\"park\"];(way(area)[\"landuse\"=\"grass\"]; node(w); );" - }, - "minzoom": 0, - "title": { - "render": { - "nl": "Speelweide in een park" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "nl": "{name}" + "icon": "./assets/themes/playgrounds/playground.svg", + "iconSize": "40,40,center", + "width": "1", + "color": "#0f0", + "wayHandling": 2, + "tagRenderings": [ + "images", + { + "render": "Op dit grasveld in het park mag je spelen, picnicken, zitten, ..." + }, + { + "render": "{reviews(name, landuse=grass )}" } - } ] - }, - "icon": "./assets/themes/playgrounds/playground.svg", - "iconSize": "40,40,center", - "width": "1", - "color": "#0f0", - "wayHandling": 2, - "tagRenderings": [ - "images", - { - "render": "Op dit grasveld in het park mag je spelen, picnicken, zitten, ..." - }, - { - "render": "{reviews(name, landuse=grass )}" - } - ] } \ No newline at end of file diff --git a/assets/layers/information_board/information_board.json b/assets/layers/information_board/information_board.json index 4b0c47f4f..f25c71245 100644 --- a/assets/layers/information_board/information_board.json +++ b/assets/layers/information_board/information_board.json @@ -1,57 +1,57 @@ { - "id": "information_board", - "name": { - "nl": "Informatieborden", - "en": "Information boards", - "it": "Pannelli informativi", - "fr": "Panneaux d'informations", - "de": "Informationstafeln", - "ru": "Информационные щиты" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - "information=board" - ] - } - }, - "title": { - "render": { - "nl": "Informatiebord", - "en": "Information board", - "it": "Pannello informativo", - "fr": "Panneau d'informations", - "de": "Informationstafel", - "ru": "Информационный щит" - } - }, - "tagRenderings": [ - "images" - ], - "icon": { - "render": "./assets/layers/information_board/board.svg" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "tourism=information", - "information=board" - ], - "title": { - "nl": "Informatiebord", - "en": "Information board", - "it": "Pannello informativo", - "fr": "Panneau d'informations", - "de": "Informationstafel", - "ru": "Информационный щит" - } - } - ] + "id": "information_board", + "name": { + "nl": "Informatieborden", + "en": "Information boards", + "it": "Pannelli informativi", + "fr": "Panneaux d'informations", + "de": "Informationstafeln", + "ru": "Информационные щиты" + }, + "minzoom": 12, + "source": { + "osmTags": { + "and": [ + "information=board" + ] + } + }, + "title": { + "render": { + "nl": "Informatiebord", + "en": "Information board", + "it": "Pannello informativo", + "fr": "Panneau d'informations", + "de": "Informationstafel", + "ru": "Информационный щит" + } + }, + "tagRenderings": [ + "images" + ], + "icon": { + "render": "./assets/layers/information_board/board.svg" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "tourism=information", + "information=board" + ], + "title": { + "nl": "Informatiebord", + "en": "Information board", + "it": "Pannello informativo", + "fr": "Panneau d'informations", + "de": "Informationstafel", + "ru": "Информационный щит" + } + } + ] } \ No newline at end of file diff --git a/assets/layers/map/map.json b/assets/layers/map/map.json index 0f3374791..3bc09c947 100644 --- a/assets/layers/map/map.json +++ b/assets/layers/map/map.json @@ -1,229 +1,229 @@ { - "id": "map", - "name": { - "en": "Maps", - "nl": "Kaarten", - "it": "Mappe", - "ru": "Карты", - "fr": "Cartes", - "de": "Karten" - }, - "minzoom": 12, - "source": { - "osmTags": { - "or": [ - "tourism=map", - "information=map" - ] - } - }, - "title": { - "render": { - "en": "Map", - "nl": "Kaart", - "it": "Mappa", - "ru": "Карта", - "fr": "Carte", - "de": "Karte" - } - }, - "description": { - "en": "A map, meant for tourists which is permanently installed in the public space", - "nl": "Een permantent geinstalleerde kaart", - "it": "Una mappa, destinata ai turisti e che è sistemata in maniera permanente in uno spazio pubblico", - "fr": "Une carte, destinée aux touristes, installée en permanence dans l'espace public" - }, - "tagRenderings": [ - "images", - { - "question": { - "en": "On which data is this map based?", - "nl": "Op welke data is deze kaart gebaseerd?", - "it": "Su quali dati si basa questa mappa?", - "fr": "Sur quelles données cette carte est-elle basée ?", - "de": "Auf welchen Daten basiert diese Karte?" - }, - "mappings": [ - { - "if": { - "and": [ - "map_source=OpenStreetMap", - "not:map_source=" - ] - }, - "then": { - "en": "This map is based on OpenStreetMap", - "nl": "Deze kaart is gebaseerd op OpenStreetMap", - "it": "Questa mappa si basa su OpenStreetMap", - "ru": "Эта карта основана на OpenStreetMap", - "fr": "Cette carte est basée sur OpenStreetMap", - "de": "Diese Karte basiert auf OpenStreetMap" - } - } - ], - "freeform": { - "key": "map_source" - }, - "render": { - "en": "This map is based on {map_source}", - "nl": "Deze kaart is gebaseerd op {map_source}", - "it": "Questa mappa si basa su {map_source}", - "ru": "Эта карта основана на {map_source}", - "fr": "Cette carte est basée sur {map_source}", - "de": "Diese Karte basiert auf {map_source}" - } + "id": "map", + "name": { + "en": "Maps", + "nl": "Kaarten", + "it": "Mappe", + "ru": "Карты", + "fr": "Cartes", + "de": "Karten" }, - { - "question": { - "en": "Is the OpenStreetMap-attribution given?", - "nl": "Is de attributie voor OpenStreetMap aanwezig?", - "it": "L’attribuzione a OpenStreetMap è presente?", - "de": "Ist die OpenStreetMap-Attribution vorhanden?", - "fr": "L’attribution à OpenStreetMap est elle-présente ?" - }, - "mappings": [ - { - "if": { - "and": [ - "map_source:attribution=yes" + "minzoom": 12, + "source": { + "osmTags": { + "or": [ + "tourism=map", + "information=map" ] - }, - "then": { - "en": "OpenStreetMap is clearly attributed, including the ODBL-license", - "nl": "De OpenStreetMap-attributie is duidelijk aangegeven, zelf met vermelding van \"ODBL\" ", - "it": "L’attribuzione a OpenStreetMap è chiaramente specificata, inclusa la licenza ODBL", - "de": "OpenStreetMap ist eindeutig attributiert, einschließlich der ODBL-Lizenz", - "fr": "L’attribution est clairement inscrite ainsi que la licence ODBL" - } - }, - { - "if": { - "and": [ - "map_source:attribution=incomplete" - ] - }, - "then": { - "en": "OpenStreetMap is clearly attributed, but the license is not mentioned", - "nl": "OpenStreetMap is duidelijk aangegeven, maar de licentievermelding ontbreekt", - "it": "L’attribuzione a OpenStreetMap è chiaramente specificata ma la licenza non compare", - "de": "OpenStreetMap ist eindeutig attributiert, aber die Lizenz wird nicht erwähnt", - "fr": "L’attribution est clairement inscrite mais la licence est absente" - } - }, - { - "if": { - "and": [ - "map_source:attribution=sticker" - ] - }, - "then": { - "en": "OpenStreetMap wasn't mentioned, but someone put an OpenStreetMap-sticker on it", - "nl": "OpenStreetMap was oorspronkelijk niet aangeduid, maar iemand plaatste er een sticker", - "it": "Non era presente alcun cenno a OpenStreetMap ma qualcuno vi ha attaccato un adesivo di OpenStreetMap", - "de": "OpenStreetMap wurde nicht erwähnt, aber jemand hat einen OpenStreetMap-Aufkleber darauf geklebt", - "fr": "OpenStreetMap n’est pas mentionné, un sticker OpenStreetMap a été collé" - } - }, - { - "if": { - "and": [ - "map_source:attribution=none" - ] - }, - "then": { - "en": "There is no attribution at all", - "nl": "Er is geen attributie", - "it": "Non c’è alcuna attribuzione", - "fr": "Il n'y a aucune attribution", - "de": "Es gibt überhaupt keine Namensnennung" - } - }, - { - "if": { - "and": [ - "map_source:attribution=no" - ] - }, - "then": { - "nl": "Er is geen attributie", - "en": "There is no attribution at all", - "it": "Non c’è alcuna attribuzione", - "fr": "Il n'y a aucune attribution", - "de": "Es gibt überhaupt keine Namensnennung" - }, - "hideInAnswer": true } - ], - "condition": { - "or": [ - "map_source~(O|)pen(S|s)treet(M|m)ap", - "map_source=osm", - "map_source=OSM" + }, + "title": { + "render": { + "en": "Map", + "nl": "Kaart", + "it": "Mappa", + "ru": "Карта", + "fr": "Carte", + "de": "Karte" + } + }, + "description": { + "en": "A map, meant for tourists which is permanently installed in the public space", + "nl": "Een permantent geinstalleerde kaart", + "it": "Una mappa, destinata ai turisti e che è sistemata in maniera permanente in uno spazio pubblico", + "fr": "Une carte, destinée aux touristes, installée en permanence dans l'espace public" + }, + "tagRenderings": [ + "images", + { + "question": { + "en": "On which data is this map based?", + "nl": "Op welke data is deze kaart gebaseerd?", + "it": "Su quali dati si basa questa mappa?", + "fr": "Sur quelles données cette carte est-elle basée ?", + "de": "Auf welchen Daten basiert diese Karte?" + }, + "mappings": [ + { + "if": { + "and": [ + "map_source=OpenStreetMap", + "not:map_source=" + ] + }, + "then": { + "en": "This map is based on OpenStreetMap", + "nl": "Deze kaart is gebaseerd op OpenStreetMap", + "it": "Questa mappa si basa su OpenStreetMap", + "ru": "Эта карта основана на OpenStreetMap", + "fr": "Cette carte est basée sur OpenStreetMap", + "de": "Diese Karte basiert auf OpenStreetMap" + } + } + ], + "freeform": { + "key": "map_source" + }, + "render": { + "en": "This map is based on {map_source}", + "nl": "Deze kaart is gebaseerd op {map_source}", + "it": "Questa mappa si basa su {map_source}", + "ru": "Эта карта основана на {map_source}", + "fr": "Cette carte est basée sur {map_source}", + "de": "Diese Karte basiert auf {map_source}" + } + }, + { + "question": { + "en": "Is the OpenStreetMap-attribution given?", + "nl": "Is de attributie voor OpenStreetMap aanwezig?", + "it": "L’attribuzione a OpenStreetMap è presente?", + "de": "Ist die OpenStreetMap-Attribution vorhanden?", + "fr": "L’attribution à OpenStreetMap est elle-présente ?" + }, + "mappings": [ + { + "if": { + "and": [ + "map_source:attribution=yes" + ] + }, + "then": { + "en": "OpenStreetMap is clearly attributed, including the ODBL-license", + "nl": "De OpenStreetMap-attributie is duidelijk aangegeven, zelf met vermelding van \"ODBL\" ", + "it": "L’attribuzione a OpenStreetMap è chiaramente specificata, inclusa la licenza ODBL", + "de": "OpenStreetMap ist eindeutig attributiert, einschließlich der ODBL-Lizenz", + "fr": "L’attribution est clairement inscrite ainsi que la licence ODBL" + } + }, + { + "if": { + "and": [ + "map_source:attribution=incomplete" + ] + }, + "then": { + "en": "OpenStreetMap is clearly attributed, but the license is not mentioned", + "nl": "OpenStreetMap is duidelijk aangegeven, maar de licentievermelding ontbreekt", + "it": "L’attribuzione a OpenStreetMap è chiaramente specificata ma la licenza non compare", + "de": "OpenStreetMap ist eindeutig attributiert, aber die Lizenz wird nicht erwähnt", + "fr": "L’attribution est clairement inscrite mais la licence est absente" + } + }, + { + "if": { + "and": [ + "map_source:attribution=sticker" + ] + }, + "then": { + "en": "OpenStreetMap wasn't mentioned, but someone put an OpenStreetMap-sticker on it", + "nl": "OpenStreetMap was oorspronkelijk niet aangeduid, maar iemand plaatste er een sticker", + "it": "Non era presente alcun cenno a OpenStreetMap ma qualcuno vi ha attaccato un adesivo di OpenStreetMap", + "de": "OpenStreetMap wurde nicht erwähnt, aber jemand hat einen OpenStreetMap-Aufkleber darauf geklebt", + "fr": "OpenStreetMap n’est pas mentionné, un sticker OpenStreetMap a été collé" + } + }, + { + "if": { + "and": [ + "map_source:attribution=none" + ] + }, + "then": { + "en": "There is no attribution at all", + "nl": "Er is geen attributie", + "it": "Non c’è alcuna attribuzione", + "fr": "Il n'y a aucune attribution", + "de": "Es gibt überhaupt keine Namensnennung" + } + }, + { + "if": { + "and": [ + "map_source:attribution=no" + ] + }, + "then": { + "nl": "Er is geen attributie", + "en": "There is no attribution at all", + "it": "Non c’è alcuna attribuzione", + "fr": "Il n'y a aucune attribution", + "de": "Es gibt überhaupt keine Namensnennung" + }, + "hideInAnswer": true + } + ], + "condition": { + "or": [ + "map_source~(O|)pen(S|s)treet(M|m)ap", + "map_source=osm", + "map_source=OSM" + ] + } + } + ], + "icon": { + "render": "./assets/layers/map/map.svg", + "mappings": [ + { + "if": { + "and": [ + "map_source=OpenStreetMap", + "map_source:attribution=sticker" + ] + }, + "then": "./assets/layers/map/map-stickered.svg" + }, + { + "if": { + "and": [ + "map_source=OpenStreetMap", + "map_source:attribution=yes" + ] + }, + "then": "./assets/layers/map/osm-logo-white-bg.svg" + }, + { + "if": { + "and": [ + "map_source=OpenStreetMap" + ] + }, + "then": "./assets/layers/map/osm-logo-buggy-attr.svg" + } ] - } - } - ], - "icon": { - "render": "./assets/layers/map/map.svg", - "mappings": [ - { - "if": { - "and": [ - "map_source=OpenStreetMap", - "map_source:attribution=sticker" - ] - }, - "then": "./assets/layers/map/map-stickered.svg" - }, - { - "if": { - "and": [ - "map_source=OpenStreetMap", - "map_source:attribution=yes" - ] - }, - "then": "./assets/layers/map/osm-logo-white-bg.svg" - }, - { - "if": { - "and": [ - "map_source=OpenStreetMap" - ] - }, - "then": "./assets/layers/map/osm-logo-buggy-attr.svg" - } - ] - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "50,50,center" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "tourism=map" - ], - "title": { - "en": "Map", - "nl": "Kaart", - "it": "Mappa", - "ru": "Карта", - "fr": "Carte", - "de": "Karte" - }, - "description": { - "en": "Add a missing map", - "nl": "Voeg een ontbrekende kaart toe", - "it": "Aggiungi una mappa mancante", - "fr": "Ajouter une carte manquante", - "de": "Fehlende Karte hinzufügen" - } - } - ], - "wayHandling": 2 + }, + "width": { + "render": "8" + }, + "iconSize": { + "render": "50,50,center" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "tourism=map" + ], + "title": { + "en": "Map", + "nl": "Kaart", + "it": "Mappa", + "ru": "Карта", + "fr": "Carte", + "de": "Karte" + }, + "description": { + "en": "Add a missing map", + "nl": "Voeg een ontbrekende kaart toe", + "it": "Aggiungi una mappa mancante", + "fr": "Ajouter une carte manquante", + "de": "Fehlende Karte hinzufügen" + } + } + ], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/nature_reserve/nature_reserve.json b/assets/layers/nature_reserve/nature_reserve.json index 3b4b7b7d4..2f217743d 100644 --- a/assets/layers/nature_reserve/nature_reserve.json +++ b/assets/layers/nature_reserve/nature_reserve.json @@ -1,462 +1,462 @@ { - "id": "nature_reserve", - "name": { - "nl": "Natuurgebied" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - { - "or": [ - "leisure=nature_reserve", + "id": "nature_reserve", + "name": { + "nl": "Natuurgebied" + }, + "minzoom": 12, + "source": { + "osmTags": { + "and": [ + { + "or": [ + "leisure=nature_reserve", + { + "and": [ + "protect_class!=98", + "boundary=protected_area" + ] + } + ] + } + ] + } + }, + "title": { + "render": { + "nl": "Natuurgebied" + }, + "mappings": [ { - "and": [ - "protect_class!=98", - "boundary=protected_area" - ] + "if": { + "and": [ + "name:nl~*" + ] + }, + "then": { + "nl": "{name:nl}" + } + }, + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "{name}" + } } - ] - } - ] - } - }, - "title": { - "render": { - "nl": "Natuurgebied" + ] }, - "mappings": [ - { - "if": { - "and": [ - "name:nl~*" - ] + "description": { + "nl": "Een natuurgebied is een gebied waar actief ruimte gemaakt word voor de natuur. Typisch zijn deze in beheer van Natuurpunt of het Agentschap Natuur en Bos of zijn deze erkend door de overheid." + }, + "tagRenderings": [ + "images", + { + "#": "Access tag", + "render": { + "nl": "De toegankelijkheid van dit gebied is: {access:description}" + }, + "question": { + "nl": "Is dit gebied toegankelijk?" + }, + "freeform": { + "key": "access:description" + }, + "mappings": [ + { + "if": { + "and": [ + "access=yes", + "fee=" + ] + }, + "then": { + "nl": "Vrij toegankelijk" + } + }, + { + "if": { + "and": [ + "access=no", + "fee=" + ] + }, + "then": { + "nl": "Niet toegankelijk" + } + }, + { + "if": { + "and": [ + "access=private", + "fee=" + ] + }, + "then": { + "nl": "Niet toegankelijk, want privégebied" + } + }, + { + "if": { + "and": [ + "access=permissive", + "fee=" + ] + }, + "then": { + "nl": "Toegankelijk, ondanks dat het privegebied is" + } + }, + { + "if": { + "and": [ + "access=guided", + "fee=" + ] + }, + "then": { + "nl": "Enkel toegankelijk met een gids of tijdens een activiteit" + } + }, + { + "if": { + "and": [ + "access=yes", + "fee=yes" + ] + }, + "then": { + "nl": "Toegankelijk mits betaling" + } + } + ] }, - "then": { - "nl": "{name:nl}" - } - }, - { - "if": { - "and": [ - "name~*" - ] + { + "#": "Operator tag", + "render": { + "nl": "Beheer door {operator}" + }, + "question": { + "nl": "Wie beheert dit gebied?" + }, + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": { + "and": [ + "operator=Natuurpunt" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door Natuurpunt" + } + }, + { + "if": { + "and": [ + "operator~(n|N)atuurpunt.*" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door {operator}" + }, + "hideInAnswer": true + }, + { + "if": { + "and": [ + "operator=Agentschap Natuur en Bos" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" + } + } + ] }, - "then": { - "nl": "{name}" + { + "#": "Name:nl-tag", + "render": { + "nl": "Dit gebied heet {name:nl}" + }, + "question": { + "nl": "Wat is de Nederlandstalige naam van dit gebied?" + }, + "freeform": { + "key": "name:nl" + }, + "condition": { + "and": [ + "name:nl~*" + ] + } + }, + { + "#": "Name tag", + "render": { + "nl": "Dit gebied heet {name}" + }, + "question": { + "nl": "Wat is de naam van dit gebied?" + }, + "freeform": { + "key": "name", + "addExtraTags": [ + "noname=" + ] + }, + "condition": { + "and": [ + "name:nl=" + ] + }, + "mappings": [ + { + "if": { + "and": [ + "noname=yes", + "name=" + ] + }, + "then": { + "nl": "Dit gebied heeft geen naam" + } + } + ] + }, + { + "#": "Dogs?", + "question": { + "nl": "Zijn honden toegelaten in dit gebied?", + "en": "Are dogs allowed in this nature reserve?", + "it": "I cani sono ammessi in questa riserva naturale?", + "fr": "Les chiens sont-ils autorisés dans cette réserve naturelle ?", + "de": "Sind Hunde in diesem Naturschutzgebiet erlaubt?" + }, + "condition": { + "or": [ + "access=yes", + "access=permissive", + "access=guided" + ] + }, + "mappings": [ + { + "if": "dog=leashed", + "then": { + "nl": "Honden moeten aan de leiband", + "en": "Dogs have to be leashed", + "it": "I cani devono essere tenuti al guinzaglio", + "fr": "Les chiens doivent être tenus en laisse", + "de": "Hunde müssen angeleint sein" + } + }, + { + "if": "dog=no", + "then": { + "nl": "Honden zijn niet toegestaan", + "en": "No dogs allowed", + "it": "I cani non sono ammessi", + "fr": "Chiens interdits", + "de": "Hunde sind nicht erlaubt" + } + }, + { + "if": "dog=yes", + "then": { + "nl": "Honden zijn welkom en mogen vrij rondlopen", + "en": "Dogs are allowed to roam freely", + "it": "I cani sono liberi di girare liberi", + "fr": "Les chiens sont autorisés à se promener librement", + "de": "Hunde dürfen frei herumlaufen" + } + } + ] + }, + { + "#": "Website", + "question": { + "en": "On which webpage can one find more information about this nature reserve?", + "nl": "Op welke webpagina kan men meer informatie vinden over dit natuurgebied?", + "it": "In quale pagina web si possono trovare altre informazioni riguardanti questa riserva naturale?", + "fr": "Sur quelle page web peut-on trouver plus d'informations sur cette réserve naturelle ?", + "de": "Auf welcher Webseite kann man mehr Informationen über dieses Naturschutzgebiet finden?" + }, + "render": "{website}", + "freeform": { + "key": "website", + "type": "url" + } + }, + { + "#": "Curator", + "question": { + "nl": "Wie is de conservator van dit gebied?
Respecteer privacy - geef deze naam enkel als die duidelijk is gepubliceerd", + "en": "Whom is the curator of this nature reserve?
Respect privacy - only fill out a name if this is widely published", + "it": "Chi è il curatore di questa riserva naturale?
Rispetta la privacy (scrivi il nome solo se questo è noto pubblicamente)", + "fr": "Qui est en charge de la conservation de la réserve ?
À ne remplir seulement que si le nom est diffusé au public" + }, + "render": { + "nl": "{curator} is de beheerder van dit gebied", + "en": "{curator} is the curator of this nature reserve", + "it": "{curator} è il curatore di questa riserva naturale", + "fr": "{curator} est en charge de la conservation de la réserve" + }, + "freeform": { + "key": "curator", + "type": "string" + } + }, + { + "#": "Email", + "question": { + "nl": "Waar kan men naartoe emailen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke emailadressen als deze elders zijn gepubliceerd", + "en": "What email adress can one send to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal email address if this is widely published", + "it": "Qual è l’indirizzo email a cui scrivere per fare domande o segnalare problemi su questa riserva naturale?
Rispetta la privacy (compila l’indirizzo email personale solo se è stato reso pubblico)", + "fr": "À quelle adresse courriel peut-on envoyer des questions et des problèmes concernant cette réserve naturelle ?
Respecter la vie privée – renseignez une adresse électronique personnelle seulement si celle-ci est largement publiée" + }, + "render": { + "nl": "{email}", + "en": "{email}", + "ca": "{email}", + "de": "{email}", + "fr": "{email}", + "it": "{email}", + "ru": "{email}", + "id": "{email}" + }, + "freeform": { + "key": "email", + "type": "email" + } + }, + { + "#": "phone", + "question": { + "nl": "Waar kan men naartoe bellen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke telefoonnummers als deze elders zijn gepubliceerd", + "en": "What phone number can one call to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal phone number address if this is widely published", + "it": "Quale numero di telefono comporre per fare domande o segnalare problemi riguardanti questa riserva naturale?br/>Rispetta la privacy (inserisci il numero di telefono privato solo se questo è noto pubblicamente)", + "fr": "Quel numéro de téléphone peut-on appeler pour poser des questions et résoudre des problèmes concernant cette réserve naturelle ?
Respecter la vie privée – renseignez un numéro de téléphone personnel seulement si celui-ci est largement publié" + }, + "render": { + "nl": "{phone}", + "en": "{phone}", + "ca": "{phone}", + "de": "{phone}", + "fr": "{phone}", + "it": "{phone}", + "ru": "{phone}", + "id": "{phone}" + }, + "freeform": { + "key": "phone", + "type": "phone" + } + }, + { + "#": "Non-editable description {description}", + "render": { + "nl": "Extra info: {description}" + }, + "freeform": { + "key": "description" + } + }, + { + "#": "Editable description {description:0}", + "question": "Is er extra info die je kwijt wil?", + "render": { + "nl": "Extra info: {description:0}" + }, + "freeform": { + "key": "description:0" + } + }, + { + "#": "Surface area", + "render": { + "en": "Surface area: {_surface:ha}Ha", + "nl": "Totale oppervlakte: {_surface:ha}Ha", + "it": "Area: {_surface:ha} ha", + "fr": "Superficie : {_surface:ha} ha" + }, + "mappings": [ + { + "if": "_surface:ha=0", + "then": { + "*": "" + } + } + ] + } + ], + "wayHandling": 2, + "icon": { + "render": "./assets/themes/buurtnatuur/nature_reserve.svg" + }, + "width": { + "render": "1" + }, + "iconSize": { + "render": "50,50,center" + }, + "color": { + "render": "#3c3" + }, + "presets": [ + { + "tags": [ + "leisure=nature_reserve", + "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" + ], + "title": { + "nl": "Natuurreservaat" + }, + "description": { + "nl": "Voeg een ontbrekend, erkend natuurreservaat toe, bv. een gebied dat beheerd wordt door het ANB of natuurpunt" + } + } + ], + "filter": [ + { + "options": [ + { + "question": { + "nl": "Vrij te bezoeken" + }, + "osmTags": "access=yes" + } + ] + }, + { + "options": [ + { + "question": { + "nl": "Alle natuurgebieden" + } + }, + { + "question": { + "nl": "Honden mogen vrij rondlopen" + }, + "osmTags": "dog=yes" + }, + { + "question": { + "nl": "Honden welkom aan de leiband" + }, + "osmTags": { + "or": [ + "dog=yes", + "dog=leashed" + ] + } + } + ] } - } ] - }, - "description": { - "nl": "Een natuurgebied is een gebied waar actief ruimte gemaakt word voor de natuur. Typisch zijn deze in beheer van Natuurpunt of het Agentschap Natuur en Bos of zijn deze erkend door de overheid." - }, - "tagRenderings": [ - "images", - { - "#": "Access tag", - "render": { - "nl": "De toegankelijkheid van dit gebied is: {access:description}" - }, - "question": { - "nl": "Is dit gebied toegankelijk?" - }, - "freeform": { - "key": "access:description" - }, - "mappings": [ - { - "if": { - "and": [ - "access=yes", - "fee=" - ] - }, - "then": { - "nl": "Vrij toegankelijk" - } - }, - { - "if": { - "and": [ - "access=no", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk" - } - }, - { - "if": { - "and": [ - "access=private", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk, want privégebied" - } - }, - { - "if": { - "and": [ - "access=permissive", - "fee=" - ] - }, - "then": { - "nl": "Toegankelijk, ondanks dat het privegebied is" - } - }, - { - "if": { - "and": [ - "access=guided", - "fee=" - ] - }, - "then": { - "nl": "Enkel toegankelijk met een gids of tijdens een activiteit" - } - }, - { - "if": { - "and": [ - "access=yes", - "fee=yes" - ] - }, - "then": { - "nl": "Toegankelijk mits betaling" - } - } - ] - }, - { - "#": "Operator tag", - "render": { - "nl": "Beheer door {operator}" - }, - "question": { - "nl": "Wie beheert dit gebied?" - }, - "freeform": { - "key": "operator" - }, - "mappings": [ - { - "if": { - "and": [ - "operator=Natuurpunt" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door Natuurpunt" - } - }, - { - "if": { - "and": [ - "operator~(n|N)atuurpunt.*" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door {operator}" - }, - "hideInAnswer": true - }, - { - "if": { - "and": [ - "operator=Agentschap Natuur en Bos" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" - } - } - ] - }, - { - "#": "Name:nl-tag", - "render": { - "nl": "Dit gebied heet {name:nl}" - }, - "question": { - "nl": "Wat is de Nederlandstalige naam van dit gebied?" - }, - "freeform": { - "key": "name:nl" - }, - "condition": { - "and": [ - "name:nl~*" - ] - } - }, - { - "#": "Name tag", - "render": { - "nl": "Dit gebied heet {name}" - }, - "question": { - "nl": "Wat is de naam van dit gebied?" - }, - "freeform": { - "key": "name", - "addExtraTags": [ - "noname=" - ] - }, - "condition": { - "and": [ - "name:nl=" - ] - }, - "mappings": [ - { - "if": { - "and": [ - "noname=yes", - "name=" - ] - }, - "then": { - "nl": "Dit gebied heeft geen naam" - } - } - ] - }, - { - "#": "Dogs?", - "question": { - "nl": "Zijn honden toegelaten in dit gebied?", - "en": "Are dogs allowed in this nature reserve?", - "it": "I cani sono ammessi in questa riserva naturale?", - "fr": "Les chiens sont-ils autorisés dans cette réserve naturelle ?", - "de": "Sind Hunde in diesem Naturschutzgebiet erlaubt?" - }, - "condition": { - "or": [ - "access=yes", - "access=permissive", - "access=guided" - ] - }, - "mappings": [ - { - "if": "dog=leashed", - "then": { - "nl": "Honden moeten aan de leiband", - "en": "Dogs have to be leashed", - "it": "I cani devono essere tenuti al guinzaglio", - "fr": "Les chiens doivent être tenus en laisse", - "de": "Hunde müssen angeleint sein" - } - }, - { - "if": "dog=no", - "then": { - "nl": "Honden zijn niet toegestaan", - "en": "No dogs allowed", - "it": "I cani non sono ammessi", - "fr": "Chiens interdits", - "de": "Hunde sind nicht erlaubt" - } - }, - { - "if": "dog=yes", - "then": { - "nl": "Honden zijn welkom en mogen vrij rondlopen", - "en": "Dogs are allowed to roam freely", - "it": "I cani sono liberi di girare liberi", - "fr": "Les chiens sont autorisés à se promener librement", - "de": "Hunde dürfen frei herumlaufen" - } - } - ] - }, - { - "#": "Website", - "question": { - "en": "On which webpage can one find more information about this nature reserve?", - "nl": "Op welke webpagina kan men meer informatie vinden over dit natuurgebied?", - "it": "In quale pagina web si possono trovare altre informazioni riguardanti questa riserva naturale?", - "fr": "Sur quelle page web peut-on trouver plus d'informations sur cette réserve naturelle ?", - "de": "Auf welcher Webseite kann man mehr Informationen über dieses Naturschutzgebiet finden?" - }, - "render": "{website}", - "freeform": { - "key": "website", - "type": "url" - } - }, - { - "#": "Curator", - "question": { - "nl": "Wie is de conservator van dit gebied?
Respecteer privacy - geef deze naam enkel als die duidelijk is gepubliceerd", - "en": "Whom is the curator of this nature reserve?
Respect privacy - only fill out a name if this is widely published", - "it": "Chi è il curatore di questa riserva naturale?
Rispetta la privacy (scrivi il nome solo se questo è noto pubblicamente)", - "fr": "Qui est en charge de la conservation de la réserve ?
À ne remplir seulement que si le nom est diffusé au public" - }, - "render": { - "nl": "{curator} is de beheerder van dit gebied", - "en": "{curator} is the curator of this nature reserve", - "it": "{curator} è il curatore di questa riserva naturale", - "fr": "{curator} est en charge de la conservation de la réserve" - }, - "freeform": { - "key": "curator", - "type": "string" - } - }, - { - "#": "Email", - "question": { - "nl": "Waar kan men naartoe emailen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke emailadressen als deze elders zijn gepubliceerd", - "en": "What email adress can one send to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal email address if this is widely published", - "it": "Qual è l’indirizzo email a cui scrivere per fare domande o segnalare problemi su questa riserva naturale?
Rispetta la privacy (compila l’indirizzo email personale solo se è stato reso pubblico)", - "fr": "À quelle adresse courriel peut-on envoyer des questions et des problèmes concernant cette réserve naturelle ?
Respecter la vie privée – renseignez une adresse électronique personnelle seulement si celle-ci est largement publiée" - }, - "render": { - "nl": "{email}", - "en": "{email}", - "ca": "{email}", - "de": "{email}", - "fr": "{email}", - "it": "{email}", - "ru": "{email}", - "id": "{email}" - }, - "freeform": { - "key": "email", - "type": "email" - } - }, - { - "#": "phone", - "question": { - "nl": "Waar kan men naartoe bellen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke telefoonnummers als deze elders zijn gepubliceerd", - "en": "What phone number can one call to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal phone number address if this is widely published", - "it": "Quale numero di telefono comporre per fare domande o segnalare problemi riguardanti questa riserva naturale?br/>Rispetta la privacy (inserisci il numero di telefono privato solo se questo è noto pubblicamente)", - "fr": "Quel numéro de téléphone peut-on appeler pour poser des questions et résoudre des problèmes concernant cette réserve naturelle ?
Respecter la vie privée – renseignez un numéro de téléphone personnel seulement si celui-ci est largement publié" - }, - "render": { - "nl": "{phone}", - "en": "{phone}", - "ca": "{phone}", - "de": "{phone}", - "fr": "{phone}", - "it": "{phone}", - "ru": "{phone}", - "id": "{phone}" - }, - "freeform": { - "key": "phone", - "type": "phone" - } - }, - { - "#": "Non-editable description {description}", - "render": { - "nl": "Extra info: {description}" - }, - "freeform": { - "key": "description" - } - }, - { - "#": "Editable description {description:0}", - "question": "Is er extra info die je kwijt wil?", - "render": { - "nl": "Extra info: {description:0}" - }, - "freeform": { - "key": "description:0" - } - }, - { - "#": "Surface area", - "render": { - "en": "Surface area: {_surface:ha}Ha", - "nl": "Totale oppervlakte: {_surface:ha}Ha", - "it": "Area: {_surface:ha} ha", - "fr": "Superficie : {_surface:ha} ha" - }, - "mappings": [ - { - "if": "_surface:ha=0", - "then": { - "*": "" - } - } - ] - } - ], - "wayHandling": 2, - "icon": { - "render": "./assets/themes/buurtnatuur/nature_reserve.svg" - }, - "width": { - "render": "1" - }, - "iconSize": { - "render": "50,50,center" - }, - "color": { - "render": "#3c3" - }, - "presets": [ - { - "tags": [ - "leisure=nature_reserve", - "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" - ], - "title": { - "nl": "Natuurreservaat" - }, - "description": { - "nl": "Voeg een ontbrekend, erkend natuurreservaat toe, bv. een gebied dat beheerd wordt door het ANB of natuurpunt" - } - } - ], - "filter": [ - { - "options": [ - { - "question": { - "nl": "Vrij te bezoeken" - }, - "osmTags": "access=yes" - } - ] - }, - { - "options": [ - { - "question": { - "nl": "Alle natuurgebieden" - } - }, - { - "question": { - "nl": "Honden mogen vrij rondlopen" - }, - "osmTags": "dog=yes" - }, - { - "question": { - "nl": "Honden welkom aan de leiband" - }, - "osmTags": { - "or": [ - "dog=yes", - "dog=leashed" - ] - } - } - ] - } - ] } \ No newline at end of file diff --git a/assets/layers/observation_tower/observation_tower.json b/assets/layers/observation_tower/observation_tower.json index 373621fe4..3a13b9776 100644 --- a/assets/layers/observation_tower/observation_tower.json +++ b/assets/layers/observation_tower/observation_tower.json @@ -1,183 +1,183 @@ { - "id": "observation_tower", - "name": { - "en": "Observation towers", - "nl": "Uitkijktorens" - }, - "minzoom": 8, - "title": { - "render": { - "en": "Observation tower", - "nl": "Uitkijktoren" + "id": "observation_tower", + "name": { + "en": "Observation towers", + "nl": "Uitkijktorens" }, - "mappings": [ - { - "if": "name~*", - "then": { - "en": "{name}", - "nl": "{name}" - } - } - ] - }, - "description": { - "en": "Towers with a panoramic view", - "nl": "Torens om van het uitzicht te genieten" - }, - "tagRenderings": [ - "images", - { - "#": "name", - "question": { - "en": "What is the name of this tower?", - "nl": "Heeft deze toren een naam?" - }, - "render": { - "en": "This tower is called {name}", - "nl": "Deze toren heet {name}" - }, - "freeform": { - "key": "name" - }, - "mappings": [ - { - "if": "noname=yes", - "then": { - "en": "This tower doesn't have a specific name", - "nl": "Deze toren heeft geen specifieke naam" - } - } - ] - }, - { - "#": "Height", - "question": { - "en": "What is the height of this tower?", - "nl": "Hoe hoog is deze toren?" - }, - "render": { - "en": "This tower is {height} high", - "nl": "Deze toren is {height} hoog" - }, - "freeform": { - "key": "height", - "type": "pfloat" - } - }, - { - "#": "Operator", - "question": { - "en": "Who maintains this tower?", - "nl": "Wie onderhoudt deze toren?" - }, - "render": { - "nl": "Wordt onderhouden door {operator}", - "en": "Maintained by {operator}" - }, - "freeform": { - "key": "operator" - } - }, - "website", - { - "#": "Fee", - "question": { - "en": "How much does one have to pay to enter this tower?", - "nl": "Hoeveel moet men betalen om deze toren te bezoeken?" - }, - "render": { - "en": "Visiting this tower costs {charge}", - "nl": "Deze toren bezoeken kost {charge}" - }, - "freeform": { - "key": "charge", - "addExtraTags": [ - "fee=yes" + "minzoom": 8, + "title": { + "render": { + "en": "Observation tower", + "nl": "Uitkijktoren" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "en": "{name}", + "nl": "{name}" + } + } ] - }, - "mappings": [ + }, + "description": { + "en": "Towers with a panoramic view", + "nl": "Torens om van het uitzicht te genieten" + }, + "tagRenderings": [ + "images", { - "if": { - "and": [ - "fee=no", - "charge=" + "#": "name", + "question": { + "en": "What is the name of this tower?", + "nl": "Heeft deze toren een naam?" + }, + "render": { + "en": "This tower is called {name}", + "nl": "Deze toren heet {name}" + }, + "freeform": { + "key": "name" + }, + "mappings": [ + { + "if": "noname=yes", + "then": { + "en": "This tower doesn't have a specific name", + "nl": "Deze toren heeft geen specifieke naam" + } + } ] - }, - "then": { - "en": "Free to visit", - "nl": "Gratis te bezoeken" - } - } - ] - }, - { - "#": "Payment methods", - "builtin": "payment-options", - "override": { - "condition": { - "or": [ - "fee=yes", - "charge~*" - ] - } - } - }, - "wheelchair-access" - ], - "wayHandling": 1, - "icon": { - "render": "circle:white;./assets/layers/observation_tower/Tower_observation.svg" - }, - "width": { - "render": "2" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "man_made=tower", - "tower:type=observation" - ], - "title": { - "en": "observation tower", - "nl": "Uitkijktoren" - }, - "description": { - "nl": "Een publiek toegankelijke uitkijktoren" - } - } - ], - "source": { - "osmTags": { - "and": [ - "tower:type=observation" - ] - } - }, - "units": [ - { - "appliesToKey": [ - "height" - ], - "applicableUnits": [ + }, { - "canonicalDenomination": "m", - "alternativeDenomination": [ - "meter", - "mtr" - ], - "human": { - "nl": " meter", - "en": " meter" - } + "#": "Height", + "question": { + "en": "What is the height of this tower?", + "nl": "Hoe hoog is deze toren?" + }, + "render": { + "en": "This tower is {height} high", + "nl": "Deze toren is {height} hoog" + }, + "freeform": { + "key": "height", + "type": "pfloat" + } + }, + { + "#": "Operator", + "question": { + "en": "Who maintains this tower?", + "nl": "Wie onderhoudt deze toren?" + }, + "render": { + "nl": "Wordt onderhouden door {operator}", + "en": "Maintained by {operator}" + }, + "freeform": { + "key": "operator" + } + }, + "website", + { + "#": "Fee", + "question": { + "en": "How much does one have to pay to enter this tower?", + "nl": "Hoeveel moet men betalen om deze toren te bezoeken?" + }, + "render": { + "en": "Visiting this tower costs {charge}", + "nl": "Deze toren bezoeken kost {charge}" + }, + "freeform": { + "key": "charge", + "addExtraTags": [ + "fee=yes" + ] + }, + "mappings": [ + { + "if": { + "and": [ + "fee=no", + "charge=" + ] + }, + "then": { + "en": "Free to visit", + "nl": "Gratis te bezoeken" + } + } + ] + }, + { + "#": "Payment methods", + "builtin": "payment-options", + "override": { + "condition": { + "or": [ + "fee=yes", + "charge~*" + ] + } + } + }, + "wheelchair-access" + ], + "wayHandling": 1, + "icon": { + "render": "circle:white;./assets/layers/observation_tower/Tower_observation.svg" + }, + "width": { + "render": "2" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "man_made=tower", + "tower:type=observation" + ], + "title": { + "en": "observation tower", + "nl": "Uitkijktoren" + }, + "description": { + "nl": "Een publiek toegankelijke uitkijktoren" + } } - ], - "eraseInvalidValues": true - } - ] + ], + "source": { + "osmTags": { + "and": [ + "tower:type=observation" + ] + } + }, + "units": [ + { + "appliesToKey": [ + "height" + ], + "applicableUnits": [ + { + "canonicalDenomination": "m", + "alternativeDenomination": [ + "meter", + "mtr" + ], + "human": { + "nl": " meter", + "en": " meter" + } + } + ], + "eraseInvalidValues": true + } + ] } \ No newline at end of file diff --git a/assets/layers/parking/parking.json b/assets/layers/parking/parking.json index d4d1cab73..a17bd5987 100644 --- a/assets/layers/parking/parking.json +++ b/assets/layers/parking/parking.json @@ -1,192 +1,192 @@ { - "id": "parking", - "name": { - "nl": "parking" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - { - "or": [ - "amenity=parking", - "amenity=motorcycle_parking", - "amenity=bicycle_parking" - ] - } - ] - } - }, - "title": { - "render": { - "nl": "Parking" + "id": "parking", + "name": { + "nl": "parking" }, - "mappings": [ - { - "if": "amenity=parking", - "then": { - "nl": "{name:nl}" + "minzoom": 12, + "source": { + "osmTags": { + "and": [ + { + "or": [ + "amenity=parking", + "amenity=motorcycle_parking", + "amenity=bicycle_parking" + ] + } + ] } - }, - { - "if": "amenity=motorcycle_parking", - "then": { - "nl": "{name}" + }, + "title": { + "render": { + "nl": "Parking" + }, + "mappings": [ + { + "if": "amenity=parking", + "then": { + "nl": "{name:nl}" + } + }, + { + "if": "amenity=motorcycle_parking", + "then": { + "nl": "{name}" + } + }, + { + "if": "amenity=bicycle_parking", + "then": { + "nl": "Fietsenstalling" + } + } + ] + }, + "icon": { + "render": "./assets/layers/parking/parking.svg" + }, + "description": { + "nl": "Parking" + }, + "tagRenderings": [ + "images", + { + "#": "Access tag", + "render": { + "nl": "De toegankelijkheid van dit gebied is: {access:description}" + }, + "question": { + "nl": "Is dit gebied toegankelijk?" + }, + "freeform": { + "key": "access:description" + }, + "mappings": [ + { + "if": { + "and": [ + "access=yes", + "fee=" + ] + }, + "then": { + "nl": "Vrij toegankelijk" + } + }, + { + "if": { + "and": [ + "access=no", + "fee=" + ] + }, + "then": { + "nl": "Niet toegankelijk" + } + }, + { + "if": { + "and": [ + "access=private", + "fee=" + ] + }, + "then": { + "nl": "Niet toegankelijk, want privégebied" + } + }, + { + "if": { + "and": [ + "access=permissive", + "fee=" + ] + }, + "then": { + "nl": "Toegankelijk, ondanks dat het privegebied is" + } + }, + { + "if": { + "and": [ + "access=guided", + "fee=" + ] + }, + "then": { + "nl": "Enkel toegankelijk met een gids of tijdens een activiteit" + } + }, + { + "if": { + "and": [ + "access=yes", + "fee=yes" + ] + }, + "then": { + "nl": "Toegankelijk mits betaling" + } + } + ] + }, + { + "#": "Operator tag", + "render": { + "nl": "Beheer door {operator}" + }, + "question": { + "nl": "Wie beheert dit pad?" + }, + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": { + "and": [ + "operator=Natuurpunt" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door Natuurpunt" + } + }, + { + "if": { + "and": [ + "operator~(n|N)atuurpunt.*" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door {operator}" + }, + "hideInAnswer": true + } + ] } - }, - { - "if": "amenity=bicycle_parking", - "then": { - "nl": "Fietsenstalling" + ], + "wayHandling": 1, + "iconSize": { + "render": "36,36,center" + }, + "color": { + "render": "#E1AD01" + }, + "presets": [ + { + "tags": [ + "amenity=parking", + "amenity=motorcycle_parking", + "amenity=bicycle_parking", + "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" + ], + "title": { + "nl": "Paden" + }, + "description": { + "nl": "Voeg een ontbrekend, erkend pad toe." + } } - } ] - }, - "icon": { - "render": "./assets/layers/parking/parking.svg" - }, - "description": { - "nl": "Parking" - }, - "tagRenderings": [ - "images", - { - "#": "Access tag", - "render": { - "nl": "De toegankelijkheid van dit gebied is: {access:description}" - }, - "question": { - "nl": "Is dit gebied toegankelijk?" - }, - "freeform": { - "key": "access:description" - }, - "mappings": [ - { - "if": { - "and": [ - "access=yes", - "fee=" - ] - }, - "then": { - "nl": "Vrij toegankelijk" - } - }, - { - "if": { - "and": [ - "access=no", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk" - } - }, - { - "if": { - "and": [ - "access=private", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk, want privégebied" - } - }, - { - "if": { - "and": [ - "access=permissive", - "fee=" - ] - }, - "then": { - "nl": "Toegankelijk, ondanks dat het privegebied is" - } - }, - { - "if": { - "and": [ - "access=guided", - "fee=" - ] - }, - "then": { - "nl": "Enkel toegankelijk met een gids of tijdens een activiteit" - } - }, - { - "if": { - "and": [ - "access=yes", - "fee=yes" - ] - }, - "then": { - "nl": "Toegankelijk mits betaling" - } - } - ] - }, - { - "#": "Operator tag", - "render": { - "nl": "Beheer door {operator}" - }, - "question": { - "nl": "Wie beheert dit pad?" - }, - "freeform": { - "key": "operator" - }, - "mappings": [ - { - "if": { - "and": [ - "operator=Natuurpunt" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door Natuurpunt" - } - }, - { - "if": { - "and": [ - "operator~(n|N)atuurpunt.*" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door {operator}" - }, - "hideInAnswer": true - } - ] - } - ], - "wayHandling": 1, - "iconSize": { - "render": "36,36,center" - }, - "color": { - "render": "#E1AD01" - }, - "presets": [ - { - "tags": [ - "amenity=parking", - "amenity=motorcycle_parking", - "amenity=bicycle_parking", - "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" - ], - "title": { - "nl": "Paden" - }, - "description": { - "nl": "Voeg een ontbrekend, erkend pad toe." - } - } - ] } \ No newline at end of file diff --git a/assets/layers/picnic_table/picnic_table.json b/assets/layers/picnic_table/picnic_table.json index e35c08ca0..9bea66671 100644 --- a/assets/layers/picnic_table/picnic_table.json +++ b/assets/layers/picnic_table/picnic_table.json @@ -1,104 +1,104 @@ { - "id": "picnic_table", - "name": { - "en": "Picnic tables", - "nl": "Picnictafels", - "it": "Tavoli da picnic", - "ru": "Столы для пикника", - "fr": "Tables de pique-nique", - "de": "Picknick-Tische" - }, - "minzoom": 12, - "source": { - "osmTags": "leisure=picnic_table" - }, - "title": { - "render": { - "en": "Picnic table", - "nl": "Picnictafel", - "it": "Tavolo da picnic", - "ru": "Стол для пикника", - "fr": "Table de pique-nique", - "de": "Picknick-Tisch" - } - }, - "description": { - "en": "The layer showing picnic tables", - "nl": "Deze laag toont picnictafels", - "it": "Il livello che mostra i tavoli da picnic", - "fr": "La couche montrant les tables de pique-nique", - "ru": "Слой, отображающий столы для пикника" - }, - "tagRenderings": [ - { - "question": { - "en": "What material is this picnic table made of?", - "nl": "Van welk materiaal is deze picnictafel gemaakt?", - "it": "Di che materiale è fatto questo tavolo da picnic?", - "de": "Aus welchem Material besteht dieser Picknicktisch?", - "ru": "Из чего изготовлен этот стол для пикника?", - "fr": "En quel matériau est faite la table de pique-nique ?" - }, - "render": { - "en": "This picnic table is made of {material}", - "nl": "Deze picnictafel is gemaakt van {material}", - "it": "Questo tavolo da picnic è fatto di {material}", - "de": "Dieser Picknicktisch besteht aus {material}", - "ru": "Этот стол для пикника сделан из {material}", - "fr": "La table est faite en {material}" - }, - "freeform": { - "key": "material" - }, - "mappings": [ - { - "if": "material=wood", - "then": { - "en": "This is a wooden picnic table", - "nl": "Deze picnictafel is gemaakt uit hout", - "it": "È un tavolo da picnic in legno", - "ru": "Это деревянный стол для пикника", - "de": "Dies ist ein Picknicktisch aus Holz", - "fr": "C’est une table en bois" - } - }, - { - "if": "material=concrete", - "then": { - "en": "This is a concrete picnic table", - "nl": "Deze picnictafel is gemaakt uit beton", - "it": "È un tavolo da picnic in cemento", - "ru": "Это бетонный стол для пикника", - "de": "Dies ist ein Picknicktisch aus Beton", - "fr": "C’est une table en béton" - } + "id": "picnic_table", + "name": { + "en": "Picnic tables", + "nl": "Picnictafels", + "it": "Tavoli da picnic", + "ru": "Столы для пикника", + "fr": "Tables de pique-nique", + "de": "Picknick-Tische" + }, + "minzoom": 12, + "source": { + "osmTags": "leisure=picnic_table" + }, + "title": { + "render": { + "en": "Picnic table", + "nl": "Picnictafel", + "it": "Tavolo da picnic", + "ru": "Стол для пикника", + "fr": "Table de pique-nique", + "de": "Picknick-Tisch" } - ] - } - ], - "icon": { - "render": "circle:#e6cf39;./assets/layers/picnic_table/picnic_table.svg" - }, - "iconSize": { - "render": "35,35,center" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "leisure=picnic_table" - ], - "title": { - "en": "Picnic table", - "nl": "Picnic-tafel", - "it": "Tavolo da picnic", - "ru": "Стол для пикника", - "de": "Picknicktisch", - "fr": "Table de pique-nique" - } - } - ], - "wayHandling": 1 + }, + "description": { + "en": "The layer showing picnic tables", + "nl": "Deze laag toont picnictafels", + "it": "Il livello che mostra i tavoli da picnic", + "fr": "La couche montrant les tables de pique-nique", + "ru": "Слой, отображающий столы для пикника" + }, + "tagRenderings": [ + { + "question": { + "en": "What material is this picnic table made of?", + "nl": "Van welk materiaal is deze picnictafel gemaakt?", + "it": "Di che materiale è fatto questo tavolo da picnic?", + "de": "Aus welchem Material besteht dieser Picknicktisch?", + "ru": "Из чего изготовлен этот стол для пикника?", + "fr": "En quel matériau est faite la table de pique-nique ?" + }, + "render": { + "en": "This picnic table is made of {material}", + "nl": "Deze picnictafel is gemaakt van {material}", + "it": "Questo tavolo da picnic è fatto di {material}", + "de": "Dieser Picknicktisch besteht aus {material}", + "ru": "Этот стол для пикника сделан из {material}", + "fr": "La table est faite en {material}" + }, + "freeform": { + "key": "material" + }, + "mappings": [ + { + "if": "material=wood", + "then": { + "en": "This is a wooden picnic table", + "nl": "Deze picnictafel is gemaakt uit hout", + "it": "È un tavolo da picnic in legno", + "ru": "Это деревянный стол для пикника", + "de": "Dies ist ein Picknicktisch aus Holz", + "fr": "C’est une table en bois" + } + }, + { + "if": "material=concrete", + "then": { + "en": "This is a concrete picnic table", + "nl": "Deze picnictafel is gemaakt uit beton", + "it": "È un tavolo da picnic in cemento", + "ru": "Это бетонный стол для пикника", + "de": "Dies ist ein Picknicktisch aus Beton", + "fr": "C’est une table en béton" + } + } + ] + } + ], + "icon": { + "render": "circle:#e6cf39;./assets/layers/picnic_table/picnic_table.svg" + }, + "iconSize": { + "render": "35,35,center" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "leisure=picnic_table" + ], + "title": { + "en": "Picnic table", + "nl": "Picnic-tafel", + "it": "Tavolo da picnic", + "ru": "Стол для пикника", + "de": "Picknicktisch", + "fr": "Table de pique-nique" + } + } + ], + "wayHandling": 1 } \ No newline at end of file diff --git a/assets/layers/play_forest/play_forest.json b/assets/layers/play_forest/play_forest.json index 5bbc4b512..cc6edbb31 100644 --- a/assets/layers/play_forest/play_forest.json +++ b/assets/layers/play_forest/play_forest.json @@ -1,115 +1,115 @@ { - "id": "play_forest", - "name": { - "nl": "Speelbossen" - }, - "minzoom": 13, - "source": { - "osmTags": { - "and": [ - "playground=forest" - ] - } - }, - "title": { - "render": { - "nl": "Speelbos" + "id": "play_forest", + "name": { + "nl": "Speelbossen" }, - "mappings": [ - { - "if": "name~Speelbos.*", - "then": { - "nl": "{name}" + "minzoom": 13, + "source": { + "osmTags": { + "and": [ + "playground=forest" + ] } - }, - { - "if": "name~*", - "then": { - "nl": "Speelbos {name}" - } - } - ] - }, - "description": { - "nl": "Een speelbos is een vrij toegankelijke zone in een bos" - }, - "tagRenderings": [ - "images", - { - "question": "Wie beheert dit gebied?", - "render": "Dit gebied wordt beheerd door {operator}", - "freeform": { - "key": "operator" - }, - "mappings": [ + }, + "title": { + "render": { + "nl": "Speelbos" + }, + "mappings": [ + { + "if": "name~Speelbos.*", + "then": { + "nl": "{name}" + } + }, + { + "if": "name~*", + "then": { + "nl": "Speelbos {name}" + } + } + ] + }, + "description": { + "nl": "Een speelbos is een vrij toegankelijke zone in een bos" + }, + "tagRenderings": [ + "images", { - "if": "operator~[aA][nN][bB]", - "then": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos", - "hideInAnswer": true + "question": "Wie beheert dit gebied?", + "render": "Dit gebied wordt beheerd door {operator}", + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": "operator~[aA][nN][bB]", + "then": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos", + "hideInAnswer": true + }, + { + "if": "operator=Agenstchap Natuur en Bos", + "then": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" + } + ] }, { - "if": "operator=Agenstchap Natuur en Bos", - "then": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" - } - ] - }, - { - "question": "Wanneer is deze speelzone toegankelijk?", - "mappings": [ - { - "if": "opening_hours=08:00-22:00", - "then": "Het hele jaar door overdag toegankelijk (van 08:00 tot 22:00)" + "question": "Wanneer is deze speelzone toegankelijk?", + "mappings": [ + { + "if": "opening_hours=08:00-22:00", + "then": "Het hele jaar door overdag toegankelijk (van 08:00 tot 22:00)" + }, + { + "if": "opening_hours=Jul-Aug 08:00-22:00", + "then": "Enkel in de zomervakantie en overdag toegankelijk (van 1 juli tot 31 augustus, van 08:00 tot 22:00" + } + ] }, { - "if": "opening_hours=Jul-Aug 08:00-22:00", - "then": "Enkel in de zomervakantie en overdag toegankelijk (van 1 juli tot 31 augustus, van 08:00 tot 22:00" + "question": "Wie kan men emailen indien er problemen zijn met de speelzone?", + "render": "De bevoegde dienst kan bereikt worden via {email}", + "freeform": { + "key": "email", + "type": "email" + } + }, + { + "question": "Wie kan men bellen indien er problemen zijn met de speelzone?", + "render": "De bevoegde dienst kan getelefoneerd worden via {phone}", + "freeform": { + "key": "phone", + "type": "phone" + } + }, + "questions", + { + "render": "{reviews(name, play_forest)}" } - ] + ], + "hideFromOverview": false, + "icon": { + "render": "./assets/layers/play_forest/icon.svg" }, - { - "question": "Wie kan men emailen indien er problemen zijn met de speelzone?", - "render": "De bevoegde dienst kan bereikt worden via {email}", - "freeform": { - "key": "email", - "type": "email" - } + "width": { + "render": "2" }, - { - "question": "Wie kan men bellen indien er problemen zijn met de speelzone?", - "render": "De bevoegde dienst kan getelefoneerd worden via {phone}", - "freeform": { - "key": "phone", - "type": "phone" - } + "iconSize": { + "render": "40,40,center" }, - "questions", - { - "render": "{reviews(name, play_forest)}" - } - ], - "hideFromOverview": false, - "icon": { - "render": "./assets/layers/play_forest/icon.svg" - }, - "width": { - "render": "2" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#007055" - }, - "presets": [ - { - "title": "Speelbos", - "tags": [ - "leisure=playground", - "playground=forest", - "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" - ], - "description": "Een zone in het bos, duidelijk gemarkeerd als speelzone met de overeenkomstige borden.
" - } - ], - "wayHandling": 2 + "color": { + "render": "#007055" + }, + "presets": [ + { + "title": "Speelbos", + "tags": [ + "leisure=playground", + "playground=forest", + "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" + ], + "description": "Een zone in het bos, duidelijk gemarkeerd als speelzone met de overeenkomstige borden.
" + } + ], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/playground/playground.json b/assets/layers/playground/playground.json index 6b6fe357f..e2d3e8a72 100644 --- a/assets/layers/playground/playground.json +++ b/assets/layers/playground/playground.json @@ -1,520 +1,520 @@ { - "id": "playground", - "name": { - "nl": "Speeltuinen", - "en": "Playgrounds", - "ru": "Детские площадки", - "de": "Spielplätze", - "it": "Campi da gioco", - "fr": "Aire de jeu" - }, - "minzoom": 13, - "source": { - "osmTags": { - "and": [ - "leisure=playground", - "playground!=forest" - ] - } - }, - "calculatedTags": [ - "_size_classification=Number(feat.properties._surface) < 10 ? 'small' : (Number(feat.properties._surface) < 100 ? 'medium' : 'large') " - ], - "description": { - "nl": "Speeltuinen", - "en": "Playgrounds", - "it": "Parchi giochi", - "ru": "Детские площадки", - "de": "Spielplätze", - "fr": "Aire de jeu" - }, - "title": { - "render": { - "nl": "Speeltuin", - "en": "Playground", - "it": "Parco giochi", - "ru": "Детская площадка", - "de": "Spielplatz", - "fr": "Aire de jeu" + "id": "playground", + "name": { + "nl": "Speeltuinen", + "en": "Playgrounds", + "ru": "Детские площадки", + "de": "Spielplätze", + "it": "Campi da gioco", + "fr": "Aire de jeu" }, - "mappings": [ - { - "if": "name~*", - "then": { - "nl": "Speeltuin {name}", - "en": "Playground {name}", - "it": "Parco giochi {name}", - "ru": "Детская площадка {name}", - "de": "Spielplatz {name}", - "fr": "Aire de jeu {name}" + "minzoom": 13, + "source": { + "osmTags": { + "and": [ + "leisure=playground", + "playground!=forest" + ] } - } - ] - }, - "tagRenderings": [ - "images", - { - "question": { - "nl": "Wat is de ondergrond van deze speeltuin?
Indien er verschillende ondergronden zijn, neem de meest voorkomende", - "en": "Which is the surface of this playground?
If there are multiple, select the most occuring one", - "it": "Qual è la superficie di questo parco giochi?
Se ve ne è più di una, seleziona quella predominante", - "de": "Welche Oberfläche hat dieser Spielplatz?
Wenn es mehrere gibt, wähle die am häufigsten vorkommende aus", - "fr": "De quelle matière est la surface de l’aire de jeu ?
Pour plusieurs matières, sélectionner la principale" - }, - "render": { - "nl": "De ondergrond is {surface}", - "en": "The surface is {surface}", - "it": "La superficie è {surface}", - "ru": "Поверхность - {surface}", - "de": "Die Oberfläche ist {surface}", - "fr": "La surface est en {surface}" - }, - "freeform": { - "key": "surface" - }, - "mappings": [ - { - "if": "surface=grass", - "then": { - "nl": "De ondergrond is gras", - "en": "The surface is grass", - "it": "La superficie è prato", - "ru": "Поверхность - трава", - "de": "Die Oberfläche ist Gras", - "fr": "La surface est en gazon" - } - }, - { - "if": "surface=sand", - "then": { - "nl": "De ondergrond is zand", - "en": "The surface is sand", - "it": "La superficie è sabbia", - "ru": "Поверхность - песок", - "de": "Die Oberfläche ist Sand", - "fr": "La surface est en sable" - } - }, - { - "if": "surface=woodchips", - "then": { - "nl": "De ondergrond bestaat uit houtsnippers", - "en": "The surface consist of woodchips", - "it": "La superficie consiste di trucioli di legno", - "de": "Die Oberfläche besteht aus Holzschnitzeln", - "ru": "Покрытие из щепы", - "fr": "La surface est en copeaux de bois" - } - }, - { - "if": "surface=paving_stones", - "then": { - "nl": "De ondergrond bestaat uit stoeptegels", - "en": "The surface is paving stones", - "it": "La superficie è mattonelle regolari", - "ru": "Поверхность - брусчатка", - "de": "Die Oberfläche ist Pflastersteine", - "fr": "La surface est en pavés" - } - }, - { - "if": "surface=asphalt", - "then": { - "nl": "De ondergrond is asfalt", - "en": "The surface is asphalt", - "it": "La superficie è asfalto", - "ru": "Поверхность - асфальт", - "de": "Die Oberfläche ist Asphalt", - "fr": "La surface est en bitume" - } - }, - { - "if": "surface=concrete", - "then": { - "nl": "De ondergrond is beton", - "en": "The surface is concrete", - "it": "La superficie è cemento", - "ru": "Поверхность - бетон", - "de": "Die Oberfläche ist Beton", - "fr": "La surface est en béton" - } - }, - { - "if": "surface=unpaved", - "then": { - "nl": "De ondergrond is onverhard", - "en": "The surface is unpaved", - "it": "La superficie è non pavimentato", - "de": "Die Oberfläche ist unbefestigt", - "fr": "La surface n’a pas de revêtement" - }, - "hideInAnswer": true - }, - { - "if": "surface=paved", - "then": { - "nl": "De ondergrond is verhard", - "en": "The surface is paved", - "it": "La superficie è pavimentato", - "de": "Die Oberfläche ist befestigt", - "fr": "La surface a un revêtement" - }, - "hideInAnswer": true - } - ] }, - { - "question": { - "nl": "Is deze speeltuin 's nachts verlicht?", - "en": "Is this playground lit at night?", - "it": "È illuminato di notte questo parco giochi?", - "fr": "Ce terrain de jeux est-il éclairé la nuit ?", - "de": "Ist dieser Spielplatz nachts beleuchtet?", - "ru": "Эта игровая площадка освещается ночью?" - }, - "mappings": [ - { - "if": "lit=yes", - "then": { - "nl": "Deze speeltuin is 's nachts verlicht", - "en": "This playground is lit at night", - "it": "Questo parco giochi è illuminato di notte", - "de": "Dieser Spielplatz ist nachts beleuchtet", - "ru": "Эта детская площадка освещается ночью", - "fr": "L’aire de jeu est éclairée de nuit" - } - }, - { - "if": "lit=no", - "then": { - "nl": "Deze speeltuin is 's nachts niet verlicht", - "en": "This playground is not lit at night", - "it": "Questo parco giochi non è illuminato di notte", - "de": "Dieser Spielplatz ist nachts nicht beleuchtet", - "ru": "Эта детская площадка не освещается ночью", - "fr": "L’aire de jeu n’est pas éclairée de nuit" - } - } - ] + "calculatedTags": [ + "_size_classification=Number(feat.properties._surface) < 10 ? 'small' : (Number(feat.properties._surface) < 100 ? 'medium' : 'large') " + ], + "description": { + "nl": "Speeltuinen", + "en": "Playgrounds", + "it": "Parchi giochi", + "ru": "Детские площадки", + "de": "Spielplätze", + "fr": "Aire de jeu" }, - { - "render": { - "nl": "Toegankelijk vanaf {min_age} jaar oud", - "en": "Accessible to kids older than {min_age} years", - "it": "Accessibile ai bambini di almeno {min_age} anni", - "ru": "Доступно для детей старше {min_age} лет", - "fr": "Accessible aux enfants de plus de {min_age} ans" - }, - "question": { - "nl": "Wat is de minimale leeftijd om op deze speeltuin te mogen?", - "en": "What is the minimum age required to access this playground?", - "it": "Qual è l’età minima per accedere a questo parco giochi?", - "fr": "Quel est l'âge minimal requis pour accéder à ce terrain de jeux ?", - "ru": "С какого возраста доступна эта детская площадка?" - }, - "freeform": { - "key": "min_age", - "type": "pnat" - } - }, - { - "render": { - "nl": "Toegankelijk tot {max_age}", - "en": "Accessible to kids of at most {max_age}", - "it": "Accessibile ai bambini di età inferiore a {max_age}", - "fr": "Accessible aux enfants de {max_age} au maximum", - "ru": "Доступно детям до {max_age}" - }, - "question": { - "nl": "Wat is de maximaal toegestane leeftijd voor deze speeltuin?", - "en": "What is the maximum age allowed to access this playground?", - "it": "Qual è l’età massima per accedere a questo parco giochi?", - "fr": "Quel est l’âge maximum autorisé pour utiliser l’aire de jeu ?" - }, - "freeform": { - "key": "max_age", - "type": "pnat" - } - }, - { - "question": { - "nl": "Wie beheert deze speeltuin?", - "en": "Who operates this playground?", - "it": "Chi è il responsabile di questo parco giochi?", - "de": "Wer betreibt diesen Spielplatz?", - "fr": "Qui est en charge de l’exploitation de l’aire de jeu ?" - }, - "render": { - "nl": "Beheer door {operator}", - "en": "Operated by {operator}", - "it": "Gestito da {operator}", - "fr": "Exploité par {operator}", - "de": "Betrieben von {operator}" - }, - "freeform": { - "key": "operator" - } - }, - { - "question": { - "nl": "Is deze speeltuin vrij toegankelijk voor het publiek?", - "en": "Is this playground accessible to the general public?", - "it": "Questo parco giochi è pubblicamente accessibile?", - "de": "Ist dieser Spielplatz für die Allgemeinheit zugänglich?", - "fr": "L’aire de jeu est-elle accessible au public ?" - }, - "mappings": [ - { - "if": "access=", - "then": { - "en": "Accessible to the general public", - "nl": "Vrij toegankelijk voor het publiek", - "it": "Accessibile pubblicamente", - "de": "Zugänglich für die Allgemeinheit", - "fr": "Accessible au public" - }, - "hideInAnswer": true + "title": { + "render": { + "nl": "Speeltuin", + "en": "Playground", + "it": "Parco giochi", + "ru": "Детская площадка", + "de": "Spielplatz", + "fr": "Aire de jeu" }, - { - "if": "access=yes", - "then": { - "en": "Accessible to the general public", - "nl": "Vrij toegankelijk voor het publiek", - "it": "Accessibile pubblicamente", - "de": "Zugänglich für die Allgemeinheit", - "fr": "Accessible au public" - } - }, - { - "if": "access=customers", - "then": { - "en": "Only accessible for clients of the operating business", - "nl": "Enkel toegankelijk voor klanten van de bijhorende zaak", - "it": "Accessibile solamente ai clienti dell’attività che lo gestisce", - "de": "Nur für Kunden des Betreibers zugänglich", - "fr": "Réservée aux clients" - } - }, - { - "if": "access=students", - "then": { - "en": "Only accessible to students of the school", - "nl": "Vrij toegankelijk voor scholieren van de school", - "it": "Accessibile solamente agli studenti della scuola", - "de": "Nur für Schüler der Schule zugänglich", - "fr": "Réservée aux élèves de l’école" - } - }, - { - "if": "access=private", - "then": { - "en": "Not accessible", - "nl": "Niet vrij toegankelijk", - "it": "Non accessibile", - "ru": "Недоступно", - "fr": "Non accessible", - "de": "Nicht zugänglich" - } - } - ] - }, - { - "question": { - "nl": "Wie kan men emailen indien er problemen zijn met de speeltuin?", - "en": "What is the email address of the playground maintainer?", - "it": "Qual è l’indirizzo email del gestore di questo parco giochi?", - "fr": "Quelle est l'adresse électronique du responsable de l'aire de jeux ?", - "de": "Wie lautet die E-Mail Adresse des Spielplatzbetreuers?" - }, - "render": { - "nl": "De bevoegde dienst kan bereikt worden via {email}", - "en": "{email}", - "ca": "{email}", - "de": "{email}", - "fr": "{email}", - "it": "{email}", - "ru": "{email}", - "id": "{email}" - }, - "freeform": { - "key": "email", - "type": "email" - } - }, - { - "question": { - "nl": "Wie kan men bellen indien er problemen zijn met de speeltuin?", - "en": "What is the phone number of the playground maintainer?", - "fr": "Quel est le numéro de téléphone du responsable du terrain de jeux ?", - "it": "Qual è il numero di telefono del gestore del campetto?" - }, - "render": { - "nl": "De bevoegde dienst kan getelefoneerd worden via {phone}", - "en": "{phone}", - "ca": "{phone}", - "de": "{phone}", - "fr": "{phone}", - "ru": "{phone}", - "id": "{phone}", - "it": "{phone}" - }, - "freeform": { - "key": "phone", - "type": "phone" - } - }, - { - "question": { - "nl": "Is deze speeltuin toegankelijk voor rolstoelgebruikers?", - "en": "Is this playground accessible to wheelchair users?", - "fr": "Ce terrain de jeux est-il accessible aux personnes en fauteuil roulant ?", - "de": "Ist dieser Spielplatz für Rollstuhlfahrer zugänglich?", - "it": "Il campetto è accessibile a persone in sedia a rotelle?", - "ru": "Доступна ли детская площадка пользователям кресел-колясок?" - }, - "mappings": [ - { - "if": "wheelchair=yes", - "then": { - "nl": "Geheel toegankelijk voor rolstoelgebruikers", - "en": "Completely accessible for wheelchair users", - "fr": "Entièrement accessible aux personnes en fauteuil roulant", - "de": "Vollständig zugänglich für Rollstuhlfahrer", - "it": "Completamente accessibile in sedia a rotelle", - "ru": "Полностью доступна пользователям кресел-колясок" - } - }, - { - "if": "wheelchair=limited", - "then": { - "nl": "Beperkt toegankelijk voor rolstoelgebruikers", - "en": "Limited accessibility for wheelchair users", - "fr": "Accessibilité limitée pour les personnes en fauteuil roulant", - "de": "Eingeschränkte Zugänglichkeit für Rollstuhlfahrer", - "it": "Accesso limitato in sedia a rotelle", - "ru": "Частично доступна пользователям кресел-колясок" - } - }, - { - "if": "wheelchair=no", - "then": { - "nl": "Niet toegankelijk voor rolstoelgebruikers", - "en": "Not accessible for wheelchair users", - "fr": "Non accessible aux personnes en fauteuil roulant", - "de": "Nicht zugänglich für Rollstuhlfahrer", - "it": "Non accessibile in sedia a rotelle", - "ru": "Недоступна пользователям кресел-колясок" - } - } - ] - }, - { - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - }, - "render": "{opening_hours_table(opening_hours)}", - "question": { - "nl": "Op welke uren is deze speeltuin toegankelijk?", - "en": "When is this playground accessible?", - "fr": "Quand ce terrain de jeux est-il accessible ?", - "it": "Quando si può accedere a questo campetto?", - "ru": "Когда открыта эта игровая площадка?" - }, - "mappings": [ - { - "if": "opening_hours=sunrise-sunset", - "then": { - "nl": "Van zonsopgang tot zonsondergang", - "en": "Accessible from sunrise till sunset", - "fr": "Accessible du lever au coucher du soleil", - "it": "Si può accedere dall'alba al tramonto", - "ru": "Открыто от рассвета до заката" - } - }, - { - "if": "opening_hours=24/7", - "then": { - "nl": "Dag en nacht toegankelijk", - "en": "Always accessible", - "fr": "Toujours accessible", - "ru": "Всегда доступен", - "it": "Si può sempre accedere" - } - }, - { - "if": "opening_hours=", - "then": { - "nl": "Dag en nacht toegankelijk", - "en": "Always accessible", - "ru": "Всегда доступен", - "fr": "Toujours accessible", - "it": "Si può sempre accedere" - }, - "hideInAnswer": true - } - ] - }, - "questions", - { - "render": "{reviews(name, playground)}" - } - ], - "icon": { - "render": "./assets/themes/playgrounds/playground.svg" - }, - "iconOverlays": [ - { - "if": { - "and": [ - "opening_hours!=24/7", - "opening_hours~*" + "mappings": [ + { + "if": "name~*", + "then": { + "nl": "Speeltuin {name}", + "en": "Playground {name}", + "it": "Parco giochi {name}", + "ru": "Детская площадка {name}", + "de": "Spielplatz {name}", + "fr": "Aire de jeu {name}" + } + } ] - }, - "then": "isOpen", - "badge": true - } - ], - "width": { - "render": "1" - }, - "iconSize": { - "render": "40,40,center", - "mappings": [ - { - "if": "id~node/.*", - "then": "40,40,center" - }, - { - "if": "_size_classification=small", - "then": "25,25,center" - }, - { - "if": "_size_classification=medium", - "then": "40,40,center" - }, - { - "if": "_size_classification=large", - "then": "60,60,center" - } - ] - }, - "color": { - "render": "#5dbaa9" - }, - "presets": [ - { - "tags": [ - "leisure=playground" - ], - "title": { - "nl": "Speeltuin", - "en": "Playground", - "ru": "Детская площадка", - "fr": "Terrain de jeux", - "it": "Campetto" - } - } - ], - "wayHandling": 2 + }, + "tagRenderings": [ + "images", + { + "question": { + "nl": "Wat is de ondergrond van deze speeltuin?
Indien er verschillende ondergronden zijn, neem de meest voorkomende", + "en": "Which is the surface of this playground?
If there are multiple, select the most occuring one", + "it": "Qual è la superficie di questo parco giochi?
Se ve ne è più di una, seleziona quella predominante", + "de": "Welche Oberfläche hat dieser Spielplatz?
Wenn es mehrere gibt, wähle die am häufigsten vorkommende aus", + "fr": "De quelle matière est la surface de l’aire de jeu ?
Pour plusieurs matières, sélectionner la principale" + }, + "render": { + "nl": "De ondergrond is {surface}", + "en": "The surface is {surface}", + "it": "La superficie è {surface}", + "ru": "Поверхность - {surface}", + "de": "Die Oberfläche ist {surface}", + "fr": "La surface est en {surface}" + }, + "freeform": { + "key": "surface" + }, + "mappings": [ + { + "if": "surface=grass", + "then": { + "nl": "De ondergrond is gras", + "en": "The surface is grass", + "it": "La superficie è prato", + "ru": "Поверхность - трава", + "de": "Die Oberfläche ist Gras", + "fr": "La surface est en gazon" + } + }, + { + "if": "surface=sand", + "then": { + "nl": "De ondergrond is zand", + "en": "The surface is sand", + "it": "La superficie è sabbia", + "ru": "Поверхность - песок", + "de": "Die Oberfläche ist Sand", + "fr": "La surface est en sable" + } + }, + { + "if": "surface=woodchips", + "then": { + "nl": "De ondergrond bestaat uit houtsnippers", + "en": "The surface consist of woodchips", + "it": "La superficie consiste di trucioli di legno", + "de": "Die Oberfläche besteht aus Holzschnitzeln", + "ru": "Покрытие из щепы", + "fr": "La surface est en copeaux de bois" + } + }, + { + "if": "surface=paving_stones", + "then": { + "nl": "De ondergrond bestaat uit stoeptegels", + "en": "The surface is paving stones", + "it": "La superficie è mattonelle regolari", + "ru": "Поверхность - брусчатка", + "de": "Die Oberfläche ist Pflastersteine", + "fr": "La surface est en pavés" + } + }, + { + "if": "surface=asphalt", + "then": { + "nl": "De ondergrond is asfalt", + "en": "The surface is asphalt", + "it": "La superficie è asfalto", + "ru": "Поверхность - асфальт", + "de": "Die Oberfläche ist Asphalt", + "fr": "La surface est en bitume" + } + }, + { + "if": "surface=concrete", + "then": { + "nl": "De ondergrond is beton", + "en": "The surface is concrete", + "it": "La superficie è cemento", + "ru": "Поверхность - бетон", + "de": "Die Oberfläche ist Beton", + "fr": "La surface est en béton" + } + }, + { + "if": "surface=unpaved", + "then": { + "nl": "De ondergrond is onverhard", + "en": "The surface is unpaved", + "it": "La superficie è non pavimentato", + "de": "Die Oberfläche ist unbefestigt", + "fr": "La surface n’a pas de revêtement" + }, + "hideInAnswer": true + }, + { + "if": "surface=paved", + "then": { + "nl": "De ondergrond is verhard", + "en": "The surface is paved", + "it": "La superficie è pavimentato", + "de": "Die Oberfläche ist befestigt", + "fr": "La surface a un revêtement" + }, + "hideInAnswer": true + } + ] + }, + { + "question": { + "nl": "Is deze speeltuin 's nachts verlicht?", + "en": "Is this playground lit at night?", + "it": "È illuminato di notte questo parco giochi?", + "fr": "Ce terrain de jeux est-il éclairé la nuit ?", + "de": "Ist dieser Spielplatz nachts beleuchtet?", + "ru": "Эта игровая площадка освещается ночью?" + }, + "mappings": [ + { + "if": "lit=yes", + "then": { + "nl": "Deze speeltuin is 's nachts verlicht", + "en": "This playground is lit at night", + "it": "Questo parco giochi è illuminato di notte", + "de": "Dieser Spielplatz ist nachts beleuchtet", + "ru": "Эта детская площадка освещается ночью", + "fr": "L’aire de jeu est éclairée de nuit" + } + }, + { + "if": "lit=no", + "then": { + "nl": "Deze speeltuin is 's nachts niet verlicht", + "en": "This playground is not lit at night", + "it": "Questo parco giochi non è illuminato di notte", + "de": "Dieser Spielplatz ist nachts nicht beleuchtet", + "ru": "Эта детская площадка не освещается ночью", + "fr": "L’aire de jeu n’est pas éclairée de nuit" + } + } + ] + }, + { + "render": { + "nl": "Toegankelijk vanaf {min_age} jaar oud", + "en": "Accessible to kids older than {min_age} years", + "it": "Accessibile ai bambini di almeno {min_age} anni", + "ru": "Доступно для детей старше {min_age} лет", + "fr": "Accessible aux enfants de plus de {min_age} ans" + }, + "question": { + "nl": "Wat is de minimale leeftijd om op deze speeltuin te mogen?", + "en": "What is the minimum age required to access this playground?", + "it": "Qual è l’età minima per accedere a questo parco giochi?", + "fr": "Quel est l'âge minimal requis pour accéder à ce terrain de jeux ?", + "ru": "С какого возраста доступна эта детская площадка?" + }, + "freeform": { + "key": "min_age", + "type": "pnat" + } + }, + { + "render": { + "nl": "Toegankelijk tot {max_age}", + "en": "Accessible to kids of at most {max_age}", + "it": "Accessibile ai bambini di età inferiore a {max_age}", + "fr": "Accessible aux enfants de {max_age} au maximum", + "ru": "Доступно детям до {max_age}" + }, + "question": { + "nl": "Wat is de maximaal toegestane leeftijd voor deze speeltuin?", + "en": "What is the maximum age allowed to access this playground?", + "it": "Qual è l’età massima per accedere a questo parco giochi?", + "fr": "Quel est l’âge maximum autorisé pour utiliser l’aire de jeu ?" + }, + "freeform": { + "key": "max_age", + "type": "pnat" + } + }, + { + "question": { + "nl": "Wie beheert deze speeltuin?", + "en": "Who operates this playground?", + "it": "Chi è il responsabile di questo parco giochi?", + "de": "Wer betreibt diesen Spielplatz?", + "fr": "Qui est en charge de l’exploitation de l’aire de jeu ?" + }, + "render": { + "nl": "Beheer door {operator}", + "en": "Operated by {operator}", + "it": "Gestito da {operator}", + "fr": "Exploité par {operator}", + "de": "Betrieben von {operator}" + }, + "freeform": { + "key": "operator" + } + }, + { + "question": { + "nl": "Is deze speeltuin vrij toegankelijk voor het publiek?", + "en": "Is this playground accessible to the general public?", + "it": "Questo parco giochi è pubblicamente accessibile?", + "de": "Ist dieser Spielplatz für die Allgemeinheit zugänglich?", + "fr": "L’aire de jeu est-elle accessible au public ?" + }, + "mappings": [ + { + "if": "access=", + "then": { + "en": "Accessible to the general public", + "nl": "Vrij toegankelijk voor het publiek", + "it": "Accessibile pubblicamente", + "de": "Zugänglich für die Allgemeinheit", + "fr": "Accessible au public" + }, + "hideInAnswer": true + }, + { + "if": "access=yes", + "then": { + "en": "Accessible to the general public", + "nl": "Vrij toegankelijk voor het publiek", + "it": "Accessibile pubblicamente", + "de": "Zugänglich für die Allgemeinheit", + "fr": "Accessible au public" + } + }, + { + "if": "access=customers", + "then": { + "en": "Only accessible for clients of the operating business", + "nl": "Enkel toegankelijk voor klanten van de bijhorende zaak", + "it": "Accessibile solamente ai clienti dell’attività che lo gestisce", + "de": "Nur für Kunden des Betreibers zugänglich", + "fr": "Réservée aux clients" + } + }, + { + "if": "access=students", + "then": { + "en": "Only accessible to students of the school", + "nl": "Vrij toegankelijk voor scholieren van de school", + "it": "Accessibile solamente agli studenti della scuola", + "de": "Nur für Schüler der Schule zugänglich", + "fr": "Réservée aux élèves de l’école" + } + }, + { + "if": "access=private", + "then": { + "en": "Not accessible", + "nl": "Niet vrij toegankelijk", + "it": "Non accessibile", + "ru": "Недоступно", + "fr": "Non accessible", + "de": "Nicht zugänglich" + } + } + ] + }, + { + "question": { + "nl": "Wie kan men emailen indien er problemen zijn met de speeltuin?", + "en": "What is the email address of the playground maintainer?", + "it": "Qual è l’indirizzo email del gestore di questo parco giochi?", + "fr": "Quelle est l'adresse électronique du responsable de l'aire de jeux ?", + "de": "Wie lautet die E-Mail Adresse des Spielplatzbetreuers?" + }, + "render": { + "nl": "De bevoegde dienst kan bereikt worden via {email}", + "en": "{email}", + "ca": "{email}", + "de": "{email}", + "fr": "{email}", + "it": "{email}", + "ru": "{email}", + "id": "{email}" + }, + "freeform": { + "key": "email", + "type": "email" + } + }, + { + "question": { + "nl": "Wie kan men bellen indien er problemen zijn met de speeltuin?", + "en": "What is the phone number of the playground maintainer?", + "fr": "Quel est le numéro de téléphone du responsable du terrain de jeux ?", + "it": "Qual è il numero di telefono del gestore del campetto?" + }, + "render": { + "nl": "De bevoegde dienst kan getelefoneerd worden via {phone}", + "en": "{phone}", + "ca": "{phone}", + "de": "{phone}", + "fr": "{phone}", + "ru": "{phone}", + "id": "{phone}", + "it": "{phone}" + }, + "freeform": { + "key": "phone", + "type": "phone" + } + }, + { + "question": { + "nl": "Is deze speeltuin toegankelijk voor rolstoelgebruikers?", + "en": "Is this playground accessible to wheelchair users?", + "fr": "Ce terrain de jeux est-il accessible aux personnes en fauteuil roulant ?", + "de": "Ist dieser Spielplatz für Rollstuhlfahrer zugänglich?", + "it": "Il campetto è accessibile a persone in sedia a rotelle?", + "ru": "Доступна ли детская площадка пользователям кресел-колясок?" + }, + "mappings": [ + { + "if": "wheelchair=yes", + "then": { + "nl": "Geheel toegankelijk voor rolstoelgebruikers", + "en": "Completely accessible for wheelchair users", + "fr": "Entièrement accessible aux personnes en fauteuil roulant", + "de": "Vollständig zugänglich für Rollstuhlfahrer", + "it": "Completamente accessibile in sedia a rotelle", + "ru": "Полностью доступна пользователям кресел-колясок" + } + }, + { + "if": "wheelchair=limited", + "then": { + "nl": "Beperkt toegankelijk voor rolstoelgebruikers", + "en": "Limited accessibility for wheelchair users", + "fr": "Accessibilité limitée pour les personnes en fauteuil roulant", + "de": "Eingeschränkte Zugänglichkeit für Rollstuhlfahrer", + "it": "Accesso limitato in sedia a rotelle", + "ru": "Частично доступна пользователям кресел-колясок" + } + }, + { + "if": "wheelchair=no", + "then": { + "nl": "Niet toegankelijk voor rolstoelgebruikers", + "en": "Not accessible for wheelchair users", + "fr": "Non accessible aux personnes en fauteuil roulant", + "de": "Nicht zugänglich für Rollstuhlfahrer", + "it": "Non accessibile in sedia a rotelle", + "ru": "Недоступна пользователям кресел-колясок" + } + } + ] + }, + { + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + }, + "render": "{opening_hours_table(opening_hours)}", + "question": { + "nl": "Op welke uren is deze speeltuin toegankelijk?", + "en": "When is this playground accessible?", + "fr": "Quand ce terrain de jeux est-il accessible ?", + "it": "Quando si può accedere a questo campetto?", + "ru": "Когда открыта эта игровая площадка?" + }, + "mappings": [ + { + "if": "opening_hours=sunrise-sunset", + "then": { + "nl": "Van zonsopgang tot zonsondergang", + "en": "Accessible from sunrise till sunset", + "fr": "Accessible du lever au coucher du soleil", + "it": "Si può accedere dall'alba al tramonto", + "ru": "Открыто от рассвета до заката" + } + }, + { + "if": "opening_hours=24/7", + "then": { + "nl": "Dag en nacht toegankelijk", + "en": "Always accessible", + "fr": "Toujours accessible", + "ru": "Всегда доступен", + "it": "Si può sempre accedere" + } + }, + { + "if": "opening_hours=", + "then": { + "nl": "Dag en nacht toegankelijk", + "en": "Always accessible", + "ru": "Всегда доступен", + "fr": "Toujours accessible", + "it": "Si può sempre accedere" + }, + "hideInAnswer": true + } + ] + }, + "questions", + { + "render": "{reviews(name, playground)}" + } + ], + "icon": { + "render": "./assets/themes/playgrounds/playground.svg" + }, + "iconOverlays": [ + { + "if": { + "and": [ + "opening_hours!=24/7", + "opening_hours~*" + ] + }, + "then": "isOpen", + "badge": true + } + ], + "width": { + "render": "1" + }, + "iconSize": { + "render": "40,40,center", + "mappings": [ + { + "if": "id~node/.*", + "then": "40,40,center" + }, + { + "if": "_size_classification=small", + "then": "25,25,center" + }, + { + "if": "_size_classification=medium", + "then": "40,40,center" + }, + { + "if": "_size_classification=large", + "then": "60,60,center" + } + ] + }, + "color": { + "render": "#5dbaa9" + }, + "presets": [ + { + "tags": [ + "leisure=playground" + ], + "title": { + "nl": "Speeltuin", + "en": "Playground", + "ru": "Детская площадка", + "fr": "Terrain de jeux", + "it": "Campetto" + } + } + ], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/public_bookcase/public_bookcase.json b/assets/layers/public_bookcase/public_bookcase.json index 234e9d379..786d7e220 100644 --- a/assets/layers/public_bookcase/public_bookcase.json +++ b/assets/layers/public_bookcase/public_bookcase.json @@ -1,475 +1,475 @@ { - "id": "public_bookcase", - "name": { - "en": "Bookcases", - "nl": "Boekenruilkastjes", - "de": "Bücherschränke", - "fr": "Microbibliothèque", - "ru": "Книжные шкафы", - "it": "Microbiblioteche" - }, - "description": { - "en": "A streetside cabinet with books, accessible to anyone", - "nl": "Een straatkastje met boeken voor iedereen", - "de": "Ein Bücherschrank am Straßenrand mit Büchern, für jedermann zugänglich", - "fr": "Une armoire ou une boite contenant des livres en libre accès", - "it": "Una vetrinetta ai bordi della strada contenente libri, aperta al pubblico", - "ru": "Уличный шкаф с книгами, доступными для всех" - }, - "source": { - "osmTags": "amenity=public_bookcase" - }, - "minzoom": 12, - "wayHandling": 2, - "title": { - "render": { - "en": "Bookcase", - "nl": "Boekenruilkast", - "de": "Bücherschrank", - "fr": "Microbibliothèque", - "ru": "Книжный шкаф", - "it": "Microbiblioteca" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "en": "Public bookcase {name}", - "nl": "Boekenruilkast {name}", - "de": "Öffentlicher Bücherschrank {name}", - "fr": "Microbibliothèque {name}", - "ru": "Общественный книжный шкаф {name}", - "it": "Microbiblioteca pubblica {name}" - } - } - ] - }, - "icon": { - "render": "./assets/themes/bookcases/bookcase.svg;" - }, - "label": { - "mappings": [ - { - "if": "name~*", - "then": "
{name}
" - } - ] - }, - "color": { - "render": "#0000ff" - }, - "width": { - "render": "8" - }, - "presets": [ - { - "title": { - "en": "Bookcase", - "nl": "Boekenruilkast", - "de": "Bücherschrank", + "id": "public_bookcase", + "name": { + "en": "Bookcases", + "nl": "Boekenruilkastjes", + "de": "Bücherschränke", "fr": "Microbibliothèque", - "ru": "Книжный шкаф", - "it": "Microbiblioteca" - }, - "tags": [ - "amenity=public_bookcase" - ], - "preciseInput": { - "preferredBackground": "photo" - } - } - ], - "tagRenderings": [ - "images", - { - "render": "{minimap():height: 9rem; border-radius: 2.5rem; overflow:hidden;border:1px solid gray}" + "ru": "Книжные шкафы", + "it": "Microbiblioteche" }, - { - "render": { - "en": "The name of this bookcase is {name}", - "nl": "De naam van dit boekenruilkastje is {name}", - "de": "Der Name dieses Bücherschrank lautet {name}", - "fr": "Le nom de cette microbibliothèque est {name}", - "ru": "Название книжного шкафа — {name}", - "it": "Questa microbiblioteca si chiama {name}" - }, - "question": { - "en": "What is the name of this public bookcase?", - "nl": "Wat is de naam van dit boekenuilkastje?", - "de": "Wie heißt dieser öffentliche Bücherschrank?", - "fr": "Quel est le nom de cette microbibliothèque ?", - "ru": "Как называется этот общественный книжный шкаф?", - "it": "Come si chiama questa microbiblioteca pubblica?" - }, - "freeform": { - "key": "name" - }, - "mappings": [ + "description": { + "en": "A streetside cabinet with books, accessible to anyone", + "nl": "Een straatkastje met boeken voor iedereen", + "de": "Ein Bücherschrank am Straßenrand mit Büchern, für jedermann zugänglich", + "fr": "Une armoire ou une boite contenant des livres en libre accès", + "it": "Una vetrinetta ai bordi della strada contenente libri, aperta al pubblico", + "ru": "Уличный шкаф с книгами, доступными для всех" + }, + "source": { + "osmTags": "amenity=public_bookcase" + }, + "minzoom": 12, + "wayHandling": 2, + "title": { + "render": { + "en": "Bookcase", + "nl": "Boekenruilkast", + "de": "Bücherschrank", + "fr": "Microbibliothèque", + "ru": "Книжный шкаф", + "it": "Microbiblioteca" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "en": "Public bookcase {name}", + "nl": "Boekenruilkast {name}", + "de": "Öffentlicher Bücherschrank {name}", + "fr": "Microbibliothèque {name}", + "ru": "Общественный книжный шкаф {name}", + "it": "Microbiblioteca pubblica {name}" + } + } + ] + }, + "icon": { + "render": "./assets/themes/bookcases/bookcase.svg;" + }, + "label": { + "mappings": [ + { + "if": "name~*", + "then": "
{name}
" + } + ] + }, + "color": { + "render": "#0000ff" + }, + "width": { + "render": "8" + }, + "presets": [ { - "if": { + "title": { + "en": "Bookcase", + "nl": "Boekenruilkast", + "de": "Bücherschrank", + "fr": "Microbibliothèque", + "ru": "Книжный шкаф", + "it": "Microbiblioteca" + }, + "tags": [ + "amenity=public_bookcase" + ], + "preciseInput": { + "preferredBackground": "photo" + } + } + ], + "tagRenderings": [ + "images", + { + "render": "{minimap():height: 9rem; border-radius: 2.5rem; overflow:hidden;border:1px solid gray}" + }, + { + "render": { + "en": "The name of this bookcase is {name}", + "nl": "De naam van dit boekenruilkastje is {name}", + "de": "Der Name dieses Bücherschrank lautet {name}", + "fr": "Le nom de cette microbibliothèque est {name}", + "ru": "Название книжного шкафа — {name}", + "it": "Questa microbiblioteca si chiama {name}" + }, + "question": { + "en": "What is the name of this public bookcase?", + "nl": "Wat is de naam van dit boekenuilkastje?", + "de": "Wie heißt dieser öffentliche Bücherschrank?", + "fr": "Quel est le nom de cette microbibliothèque ?", + "ru": "Как называется этот общественный книжный шкаф?", + "it": "Come si chiama questa microbiblioteca pubblica?" + }, + "freeform": { + "key": "name" + }, + "mappings": [ + { + "if": { + "and": [ + "noname=yes", + "name=" + ] + }, + "then": { + "en": "This bookcase doesn't have a name", + "nl": "Dit boekenruilkastje heeft geen naam", + "de": "Dieser Bücherschrank hat keinen Namen", + "fr": "Cette microbibliothèque n'a pas de nom", + "ru": "У этого книжного шкафа нет названия", + "it": "Questa microbiblioteca non ha un nome proprio" + } + } + ] + }, + { + "render": { + "en": "{capacity} books fit in this bookcase", + "nl": "Er passen {capacity} boeken", + "de": "{capacity} Bücher passen in diesen Bücherschrank", + "fr": "{capacity} livres peuvent entrer dans cette microbibliothèque", + "it": "Questa microbiblioteca può contenere fino a {capacity} libri", + "ru": "{capacity} книг помещается в этот книжный шкаф" + }, + "question": { + "en": "How many books fit into this public bookcase?", + "nl": "Hoeveel boeken passen er in dit boekenruilkastje?", + "de": "Wie viele Bücher passen in diesen öffentlichen Bücherschrank?", + "fr": "Combien de livres peuvent entrer dans cette microbibliothèque ?", + "ru": "Сколько книг помещается в этом общественном книжном шкафу?", + "it": "Quanti libri può contenere questa microbiblioteca?" + }, + "freeform": { + "key": "capacity", + "type": "nat", + "inline": true + } + }, + { + "question": { + "en": "What kind of books can be found in this public bookcase?", + "nl": "Voor welke doelgroep zijn de meeste boeken in dit boekenruilkastje?", + "de": "Welche Art von Büchern sind in diesem öffentlichen Bücherschrank zu finden?", + "fr": "Quel type de livres peut-on dans cette microbibliothèque ?", + "it": "Che tipo di libri si possono trovare in questa microbiblioteca?", + "ru": "Какие книги можно найти в этом общественном книжном шкафу?" + }, + "mappings": [ + { + "if": "books=children", + "then": { + "en": "Mostly children books", + "nl": "Voornamelijk kinderboeken", + "de": "Vorwiegend Kinderbücher", + "fr": "Livres pour enfants", + "ru": "В основном детские книги", + "it": "Principalmente libri per l'infanzia" + } + }, + { + "if": "books=adults", + "then": { + "en": "Mostly books for adults", + "nl": "Voornamelijk boeken voor volwassenen", + "de": "Vorwiegend Bücher für Erwachsene", + "fr": "Livres pour les adultes", + "ru": "В основном книги для взрослых", + "it": "Principalmente libri per persone in età adulta" + } + }, + { + "if": "books=children;adults", + "then": { + "en": "Both books for kids and adults", + "nl": "Boeken voor zowel kinderen als volwassenen", + "de": "Sowohl Bücher für Kinder als auch für Erwachsene", + "fr": "Livres pour enfants et adultes également", + "it": "Sia libri per l'infanzia, sia per l'età adulta", + "ru": "Книги и для детей, и для взрослых" + } + } + ] + }, + { + "question": { + "en": "Is this bookcase located outdoors?", + "nl": "Staat dit boekenruilkastje binnen of buiten?", + "de": "Befindet sich dieser Bücherschrank im Freien?", + "fr": "Cette microbiliothèque est-elle en extérieur ?", + "it": "Questa microbiblioteca si trova all'aperto?" + }, + "mappings": [ + { + "then": { + "en": "This bookcase is located indoors", + "nl": "Dit boekenruilkastje staat binnen", + "de": "Dieser Bücherschrank befindet sich im Innenbereich", + "fr": "Cette microbibliothèque est en intérieur", + "it": "Questa microbiblioteca si trova al chiuso" + }, + "if": "indoor=yes" + }, + { + "then": { + "en": "This bookcase is located outdoors", + "nl": "Dit boekenruilkastje staat buiten", + "de": "Dieser Bücherschrank befindet sich im Freien", + "fr": "Cette microbibliothèque est en extérieur", + "it": "Questa microbiblioteca si trova all'aperto" + }, + "if": "indoor=no" + }, + { + "then": { + "en": "This bookcase is located outdoors", + "nl": "Dit boekenruilkastje staat buiten", + "de": "Dieser Bücherschrank befindet sich im Freien", + "fr": "Cette microbibliothèque est en extérieur", + "it": "Questa microbiblioteca si trova all'aperto" + }, + "if": "indoor=", + "hideInAnswer": true + } + ] + }, + { + "question": { + "en": "Is this public bookcase freely accessible?", + "nl": "Is dit boekenruilkastje publiek toegankelijk?", + "de": "Ist dieser öffentliche Bücherschrank frei zugänglich?", + "fr": "Cette microbibliothèque est-elle librement accèssible ?", + "it": "Questa microbiblioteca è ad accesso libero?", + "ru": "Имеется ли свободный доступ к этому общественному книжному шкафу?" + }, + "condition": "indoor=yes", + "mappings": [ + { + "then": { + "en": "Publicly accessible", + "nl": "Publiek toegankelijk", + "de": "Öffentlich zugänglich", + "fr": "Accèssible au public", + "it": "È ad accesso libero", + "ru": "Свободный доступ" + }, + "if": "access=yes" + }, + { + "then": { + "en": "Only accessible to customers", + "nl": "Enkel toegankelijk voor klanten", + "de": "Nur für Kunden zugänglich", + "fr": "Accèssible aux clients", + "it": "L'accesso è riservato ai clienti" + }, + "if": "access=customers" + } + ] + }, + { + "question": { + "en": "Who maintains this public bookcase?", + "nl": "Wie is verantwoordelijk voor dit boekenruilkastje?", + "de": "Wer unterhält diesen öffentlichen Bücherschrank?", + "fr": "Qui entretien cette microbibliothèque ?", + "it": "Chi mantiene questa microbiblioteca?" + }, + "render": { + "en": "Operated by {operator}", + "nl": "Onderhouden door {operator}", + "de": "Betrieben von {operator}", + "fr": "Entretenue par {operator}", + "it": "È gestita da {operator}" + }, + "freeform": { + "type": "string", + "key": "operator" + } + }, + { + "question": { + "en": "Is this public bookcase part of a bigger network?", + "nl": "Is dit boekenruilkastje deel van een netwerk?", + "de": "Ist dieser öffentliche Bücherschrank Teil eines größeren Netzwerks?", + "fr": "Cette microbibliothèque fait-elle partie d'un réseau/groupe ?", + "it": "Questa microbiblioteca fa parte di una rete?" + }, + "render": { + "en": "This public bookcase is part of {brand}", + "nl": "Dit boekenruilkastje is deel van het netwerk {brand}", + "de": "Dieser Bücherschrank ist Teil von {brand}", + "fr": "Cette microbibliothèque fait partie du groupe {brand}", + "it": "Questa microbiblioteca fa parte di {brand}" + }, + "condition": "ref=", + "freeform": { + "key": "brand" + }, + "mappings": [ + { + "then": { + "en": "Part of the network 'Little Free Library'", + "nl": "Deel van het netwerk 'Little Free Library'", + "de": "Teil des Netzwerks 'Little Free Library'", + "fr": "Fait partie du réseau Little Free Library", + "it": "Fa parte della rete 'Little Free Library'" + }, + "if": { + "and": [ + "brand=Little Free Library", + "nobrand=" + ] + } + }, + { + "if": { + "and": [ + "nobrand=yes", + "brand=" + ] + }, + "then": { + "en": "This public bookcase is not part of a bigger network", + "nl": "Dit boekenruilkastje maakt geen deel uit van een netwerk", + "de": "Dieser öffentliche Bücherschrank ist nicht Teil eines größeren Netzwerks", + "fr": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe", + "it": "Questa microbiblioteca non fa parte di una rete" + } + } + ] + }, + { + "render": { + "en": "The reference number of this public bookcase within {brand} is {ref}", + "nl": "Het referentienummer binnen {brand} is {ref}", + "de": "Die Referenznummer dieses öffentlichen Bücherschranks innerhalb {brand} lautet {ref}", + "fr": "Cette microbibliothèque du réseau {brand} possède le numéro {ref}", + "it": "Il numero identificativo di questa microbiblioteca nella rete {brand} è {ref}" + }, + "question": { + "en": "What is the reference number of this public bookcase?", + "nl": "Wat is het referentienummer van dit boekenruilkastje?", + "de": "Wie lautet die Referenznummer dieses öffentlichen Bücherschranks?", + "fr": "Quelle est le numéro de référence de cette microbibliothèque ?", + "it": "Qual è il numero identificativo di questa microbiblioteca?" + }, + "condition": "brand~*", + "freeform": { + "key": "ref" + }, + "mappings": [ + { + "then": { + "en": "This bookcase is not part of a bigger network", + "nl": "Dit boekenruilkastje maakt geen deel uit van een netwerk", + "de": "Dieser Bücherschrank ist nicht Teil eines größeren Netzwerks", + "fr": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe", + "it": "Questa microbiblioteca non fa parte di una rete" + }, + "if": { + "and": [ + "nobrand=yes", + "brand=", + "ref=" + ] + } + } + ] + }, + { + "question": { + "en": "When was this public bookcase installed?", + "nl": "Op welke dag werd dit boekenruilkastje geinstalleerd?", + "de": "Wann wurde dieser öffentliche Bücherschrank installiert?", + "fr": "Quand a été installée cette microbibliothèque ?", + "it": "Quando è stata inaugurata questa microbiblioteca?", + "ru": "Когда был установлен этот общественный книжный шкаф?" + }, + "render": { + "en": "Installed on {start_date}", + "nl": "Geplaatst op {start_date}", + "de": "Installiert am {start_date}", + "fr": "Installée le {start_date}", + "it": "È stata inaugurata il {start_date}", + "ru": "Установлен {start_date}" + }, + "freeform": { + "key": "start_date", + "type": "date" + } + }, + { + "render": { + "en": "More info on the website", + "nl": "Meer info op de website", + "de": "Weitere Informationen auf der Webseite", + "fr": "Plus d'infos sur le site web", + "ru": "Более подробная информация на сайте", + "it": "Maggiori informazioni sul sito web" + }, + "question": { + "en": "Is there a website with more information about this public bookcase?", + "nl": "Is er een website over dit boekenruilkastje?", + "de": "Gibt es eine Website mit weiteren Informationen über diesen öffentlichen Bücherschrank?", + "fr": "Y a-t-il un site web avec plus d'informations sur cette microbibliothèque ?", + "it": "C'è un sito web con maggiori informazioni su questa microbiblioteca?", + "ru": "Есть ли веб-сайт с более подробной информацией об этом общественном книжном шкафе?" + }, + "freeform": { + "key": "website", + "type": "url" + } + } + ], + "deletion": { + "softDeletionTags": { "and": [ - "noname=yes", - "name=" + "disused:amenity=public_bookcase", + "amenity=" ] - }, - "then": { - "en": "This bookcase doesn't have a name", - "nl": "Dit boekenruilkastje heeft geen naam", - "de": "Dieser Bücherschrank hat keinen Namen", - "fr": "Cette microbibliothèque n'a pas de nom", - "ru": "У этого книжного шкафа нет названия", - "it": "Questa microbiblioteca non ha un nome proprio" - } - } - ] - }, - { - "render": { - "en": "{capacity} books fit in this bookcase", - "nl": "Er passen {capacity} boeken", - "de": "{capacity} Bücher passen in diesen Bücherschrank", - "fr": "{capacity} livres peuvent entrer dans cette microbibliothèque", - "it": "Questa microbiblioteca può contenere fino a {capacity} libri", - "ru": "{capacity} книг помещается в этот книжный шкаф" - }, - "question": { - "en": "How many books fit into this public bookcase?", - "nl": "Hoeveel boeken passen er in dit boekenruilkastje?", - "de": "Wie viele Bücher passen in diesen öffentlichen Bücherschrank?", - "fr": "Combien de livres peuvent entrer dans cette microbibliothèque ?", - "ru": "Сколько книг помещается в этом общественном книжном шкафу?", - "it": "Quanti libri può contenere questa microbiblioteca?" - }, - "freeform": { - "key": "capacity", - "type": "nat", - "inline": true - } - }, - { - "question": { - "en": "What kind of books can be found in this public bookcase?", - "nl": "Voor welke doelgroep zijn de meeste boeken in dit boekenruilkastje?", - "de": "Welche Art von Büchern sind in diesem öffentlichen Bücherschrank zu finden?", - "fr": "Quel type de livres peut-on dans cette microbibliothèque ?", - "it": "Che tipo di libri si possono trovare in questa microbiblioteca?", - "ru": "Какие книги можно найти в этом общественном книжном шкафу?" - }, - "mappings": [ - { - "if": "books=children", - "then": { - "en": "Mostly children books", - "nl": "Voornamelijk kinderboeken", - "de": "Vorwiegend Kinderbücher", - "fr": "Livres pour enfants", - "ru": "В основном детские книги", - "it": "Principalmente libri per l'infanzia" - } }, - { - "if": "books=adults", - "then": { - "en": "Mostly books for adults", - "nl": "Voornamelijk boeken voor volwassenen", - "de": "Vorwiegend Bücher für Erwachsene", - "fr": "Livres pour les adultes", - "ru": "В основном книги для взрослых", - "it": "Principalmente libri per persone in età adulta" - } - }, - { - "if": "books=children;adults", - "then": { - "en": "Both books for kids and adults", - "nl": "Boeken voor zowel kinderen als volwassenen", - "de": "Sowohl Bücher für Kinder als auch für Erwachsene", - "fr": "Livres pour enfants et adultes également", - "it": "Sia libri per l'infanzia, sia per l'età adulta", - "ru": "Книги и для детей, и для взрослых" - } - } - ] + "neededChangesets": 5 }, - { - "question": { - "en": "Is this bookcase located outdoors?", - "nl": "Staat dit boekenruilkastje binnen of buiten?", - "de": "Befindet sich dieser Bücherschrank im Freien?", - "fr": "Cette microbiliothèque est-elle en extérieur ?", - "it": "Questa microbiblioteca si trova all'aperto?" - }, - "mappings": [ + "filter": [ { - "then": { - "en": "This bookcase is located indoors", - "nl": "Dit boekenruilkastje staat binnen", - "de": "Dieser Bücherschrank befindet sich im Innenbereich", - "fr": "Cette microbibliothèque est en intérieur", - "it": "Questa microbiblioteca si trova al chiuso" - }, - "if": "indoor=yes" - }, - { - "then": { - "en": "This bookcase is located outdoors", - "nl": "Dit boekenruilkastje staat buiten", - "de": "Dieser Bücherschrank befindet sich im Freien", - "fr": "Cette microbibliothèque est en extérieur", - "it": "Questa microbiblioteca si trova all'aperto" - }, - "if": "indoor=no" - }, - { - "then": { - "en": "This bookcase is located outdoors", - "nl": "Dit boekenruilkastje staat buiten", - "de": "Dieser Bücherschrank befindet sich im Freien", - "fr": "Cette microbibliothèque est en extérieur", - "it": "Questa microbiblioteca si trova all'aperto" - }, - "if": "indoor=", - "hideInAnswer": true - } - ] - }, - { - "question": { - "en": "Is this public bookcase freely accessible?", - "nl": "Is dit boekenruilkastje publiek toegankelijk?", - "de": "Ist dieser öffentliche Bücherschrank frei zugänglich?", - "fr": "Cette microbibliothèque est-elle librement accèssible ?", - "it": "Questa microbiblioteca è ad accesso libero?", - "ru": "Имеется ли свободный доступ к этому общественному книжному шкафу?" - }, - "condition": "indoor=yes", - "mappings": [ - { - "then": { - "en": "Publicly accessible", - "nl": "Publiek toegankelijk", - "de": "Öffentlich zugänglich", - "fr": "Accèssible au public", - "it": "È ad accesso libero", - "ru": "Свободный доступ" - }, - "if": "access=yes" - }, - { - "then": { - "en": "Only accessible to customers", - "nl": "Enkel toegankelijk voor klanten", - "de": "Nur für Kunden zugänglich", - "fr": "Accèssible aux clients", - "it": "L'accesso è riservato ai clienti" - }, - "if": "access=customers" - } - ] - }, - { - "question": { - "en": "Who maintains this public bookcase?", - "nl": "Wie is verantwoordelijk voor dit boekenruilkastje?", - "de": "Wer unterhält diesen öffentlichen Bücherschrank?", - "fr": "Qui entretien cette microbibliothèque ?", - "it": "Chi mantiene questa microbiblioteca?" - }, - "render": { - "en": "Operated by {operator}", - "nl": "Onderhouden door {operator}", - "de": "Betrieben von {operator}", - "fr": "Entretenue par {operator}", - "it": "È gestita da {operator}" - }, - "freeform": { - "type": "string", - "key": "operator" - } - }, - { - "question": { - "en": "Is this public bookcase part of a bigger network?", - "nl": "Is dit boekenruilkastje deel van een netwerk?", - "de": "Ist dieser öffentliche Bücherschrank Teil eines größeren Netzwerks?", - "fr": "Cette microbibliothèque fait-elle partie d'un réseau/groupe ?", - "it": "Questa microbiblioteca fa parte di una rete?" - }, - "render": { - "en": "This public bookcase is part of {brand}", - "nl": "Dit boekenruilkastje is deel van het netwerk {brand}", - "de": "Dieser Bücherschrank ist Teil von {brand}", - "fr": "Cette microbibliothèque fait partie du groupe {brand}", - "it": "Questa microbiblioteca fa parte di {brand}" - }, - "condition": "ref=", - "freeform": { - "key": "brand" - }, - "mappings": [ - { - "then": { - "en": "Part of the network 'Little Free Library'", - "nl": "Deel van het netwerk 'Little Free Library'", - "de": "Teil des Netzwerks 'Little Free Library'", - "fr": "Fait partie du réseau Little Free Library", - "it": "Fa parte della rete 'Little Free Library'" - }, - "if": { - "and": [ - "brand=Little Free Library", - "nobrand=" + "options": [ + { + "question": "Kinderboeken aanwezig?", + "osmTags": "books~.*children.*" + } ] - } }, { - "if": { - "and": [ - "nobrand=yes", - "brand=" + "options": [ + { + "question": "Boeken voor volwassenen aanwezig?", + "osmTags": "books~.*adults.*" + } ] - }, - "then": { - "en": "This public bookcase is not part of a bigger network", - "nl": "Dit boekenruilkastje maakt geen deel uit van een netwerk", - "de": "Dieser öffentliche Bücherschrank ist nicht Teil eines größeren Netzwerks", - "fr": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe", - "it": "Questa microbiblioteca non fa parte di una rete" - } - } - ] - }, - { - "render": { - "en": "The reference number of this public bookcase within {brand} is {ref}", - "nl": "Het referentienummer binnen {brand} is {ref}", - "de": "Die Referenznummer dieses öffentlichen Bücherschranks innerhalb {brand} lautet {ref}", - "fr": "Cette microbibliothèque du réseau {brand} possède le numéro {ref}", - "it": "Il numero identificativo di questa microbiblioteca nella rete {brand} è {ref}" - }, - "question": { - "en": "What is the reference number of this public bookcase?", - "nl": "Wat is het referentienummer van dit boekenruilkastje?", - "de": "Wie lautet die Referenznummer dieses öffentlichen Bücherschranks?", - "fr": "Quelle est le numéro de référence de cette microbibliothèque ?", - "it": "Qual è il numero identificativo di questa microbiblioteca?" - }, - "condition": "brand~*", - "freeform": { - "key": "ref" - }, - "mappings": [ - { - "then": { - "en": "This bookcase is not part of a bigger network", - "nl": "Dit boekenruilkastje maakt geen deel uit van een netwerk", - "de": "Dieser Bücherschrank ist nicht Teil eines größeren Netzwerks", - "fr": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe", - "it": "Questa microbiblioteca non fa parte di una rete" - }, - "if": { - "and": [ - "nobrand=yes", - "brand=", - "ref=" - ] - } - } - ] - }, - { - "question": { - "en": "When was this public bookcase installed?", - "nl": "Op welke dag werd dit boekenruilkastje geinstalleerd?", - "de": "Wann wurde dieser öffentliche Bücherschrank installiert?", - "fr": "Quand a été installée cette microbibliothèque ?", - "it": "Quando è stata inaugurata questa microbiblioteca?", - "ru": "Когда был установлен этот общественный книжный шкаф?" - }, - "render": { - "en": "Installed on {start_date}", - "nl": "Geplaatst op {start_date}", - "de": "Installiert am {start_date}", - "fr": "Installée le {start_date}", - "it": "È stata inaugurata il {start_date}", - "ru": "Установлен {start_date}" - }, - "freeform": { - "key": "start_date", - "type": "date" - } - }, - { - "render": { - "en": "More info on the website", - "nl": "Meer info op de website", - "de": "Weitere Informationen auf der Webseite", - "fr": "Plus d'infos sur le site web", - "ru": "Более подробная информация на сайте", - "it": "Maggiori informazioni sul sito web" - }, - "question": { - "en": "Is there a website with more information about this public bookcase?", - "nl": "Is er een website over dit boekenruilkastje?", - "de": "Gibt es eine Website mit weiteren Informationen über diesen öffentlichen Bücherschrank?", - "fr": "Y a-t-il un site web avec plus d'informations sur cette microbibliothèque ?", - "it": "C'è un sito web con maggiori informazioni su questa microbiblioteca?", - "ru": "Есть ли веб-сайт с более подробной информацией об этом общественном книжном шкафе?" - }, - "freeform": { - "key": "website", - "type": "url" - } - } - ], - "deletion": { - "softDeletionTags": { - "and": [ - "disused:amenity=public_bookcase", - "amenity=" - ] - }, - "neededChangesets": 5 - }, - "filter": [ - { - "options": [ - { - "question": "Kinderboeken aanwezig?", - "osmTags": "books~.*children.*" - } - ] - }, - { - "options": [ - { - "question": "Boeken voor volwassenen aanwezig?", - "osmTags": "books~.*adults.*" - } - ] - }, - { - "options": [ - { - "question": "Binnen of buiten", - "osmTags": { - "and": [] - } }, { - "question": "Binnen?", - "osmTags": "indoor=yes" - }, - { - "question": "Buiten?", - "osmTags": { - "or": [ - "indoor=no", - "indoor=" + "options": [ + { + "question": "Binnen of buiten", + "osmTags": { + "and": [] + } + }, + { + "question": "Binnen?", + "osmTags": "indoor=yes" + }, + { + "question": "Buiten?", + "osmTags": { + "or": [ + "indoor=no", + "indoor=" + ] + } + } ] - } } - ] - } - ] + ] } \ No newline at end of file diff --git a/assets/layers/slow_roads/slow_roads.json b/assets/layers/slow_roads/slow_roads.json index 2afbca07f..5ef6d2feb 100644 --- a/assets/layers/slow_roads/slow_roads.json +++ b/assets/layers/slow_roads/slow_roads.json @@ -1,253 +1,253 @@ { - "id": "slow_roads", - "name": { - "nl": "Paadjes, trage wegen en autoluwe straten" - }, - "icon": "./assets/layers/slow_roads/slow_road.svg", - "minzoom": 16, - "source": { - "osmTags": { - "and": [ - { - "or": [ - "highway=pedestrian", - "highway=footway", - "highway=path", - "highway=bridleway", - "highway=living_street", - "highway=track" - ] - }, - "access!=no", - "access!=private" - ] - } - }, - "title": { - "render": { - "nl": "Trage weg" + "id": "slow_roads", + "name": { + "nl": "Paadjes, trage wegen en autoluwe straten" }, - "mappings": [ - { - "if": "name~*", - "then": { - "nl": "{name}" + "icon": "./assets/layers/slow_roads/slow_road.svg", + "minzoom": 16, + "source": { + "osmTags": { + "and": [ + { + "or": [ + "highway=pedestrian", + "highway=footway", + "highway=path", + "highway=bridleway", + "highway=living_street", + "highway=track" + ] + }, + "access!=no", + "access!=private" + ] } - }, - { - "if": "highway=footway", - "then": { - "nl": "Voetpad" - } - }, - { - "if": "highway=cycleway", - "then": { - "nl": "Fietspad" - } - }, - { - "if": "highway=pedestrian", - "then": { - "nl": "Voetgangersstraat" - } - }, - { - "if": "highway=living_street", - "then": { - "nl": "Woonerf" - } - }, - { - "if": "highway=path", - "then": "Klein pad" - } - ] - }, - "tagRenderings": [ - "images", - { - "mappings": [ - { - "if": "highway=living_street", - "then": { - "nl:": "
Dit is een woonerf:
  • Voetgangers mogen hier de volledige breedte van de straat gebruiken
  • Gemotoriseerd verkeer mag maximaal 20km/h rijden
" - } - }, - { - "if": "highway=pedestrian", - "then": { - "nl": "Dit is een brede, autovrije straat" - } - }, - { - "if": "highway=footway", - "then": { - "nl": "Dit is een voetpaadje" - } - }, - { - "if": "highway=path", - "then": { - "nl": "Dit is een wegeltje of bospad" - } - }, - { - "if": "highway=bridleway", - "then": { - "nl": "Dit is een ruiterswegel" - } - }, - { - "if": "highway=track", - "then": { - "nl": "Dit is een tractorspoor of weg om landbouwgrond te bereikken" - } - } - ] }, - { - "question": { - "nl": "Wat is de wegverharding van dit pad?" - }, - "render": { - "nl": "De ondergrond is {surface}", - "en": "The surface is {surface}", - "ru": "Поверхность - {surface}", - "fr": "La surface en {surface}", - "it": "La superficie è {surface}" - }, - "freeform": { - "key": "surface" - }, - "mappings": [ - { - "if": "surface=grass", - "then": { - "nl": "De ondergrond is gras", - "en": "The surface is grass", - "ru": "Поверхность - трава", - "fr": "La surface est en herbe", - "it": "La superficie è erba" - } + "title": { + "render": { + "nl": "Trage weg" }, - { - "if": "surface=ground", - "then": { - "nl": "De ondergrond is aarde", - "en": "The surface is ground", - "ru": "Поверхность - земля", - "fr": "La surface est en terre", - "it": "La superficie è terreno" - } - }, - { - "if": "surface=unpaved", - "then": { - "nl": "De ondergrond is onverhard", - "en": "The surface is unpaved", - "fr": "La surface est non pavée", - "it": "La superficie è non pavimentata" - }, - "hideInAnswer": true - }, - { - "if": "surface=sand", - "then": { - "nl": "De ondergrond is zand", - "en": "The surface is sand", - "ru": "Поверхность - песок", - "fr": "La surface est en sable", - "it": "La superficie è sabbia" - } - }, - { - "if": "surface=paving_stones", - "then": { - "nl": "De ondergrond bestaat uit stoeptegels", - "en": "The surface is paving stones", - "ru": "Поверхность - брусчатка", - "it": "La superficie è pietre irregolari", - "fr": "La surface est en pierres pavées" - } - }, - { - "if": "surface=asphalt", - "then": { - "nl": "De ondergrond is asfalt", - "en": "The surface is asphalt", - "ru": "Поверхность - асфальт", - "it": "La superficie è asfalto", - "fr": "La surface est en bitume" - } - }, - { - "if": "surface=concrete", - "then": { - "nl": "De ondergrond is beton", - "en": "The surface is concrete", - "ru": "Поверхность - бетон", - "fr": "La surface est en béton", - "it": "La superficie è calcestruzzo" - } - }, - { - "if": "surface=paved", - "then": { - "nl": "De ondergrond is verhard", - "en": "The surface is paved", - "fr": "La surface est pavée", - "it": "La superficie è pavimentata" - }, - "hideInAnswer": true - } - ] + "mappings": [ + { + "if": "name~*", + "then": { + "nl": "{name}" + } + }, + { + "if": "highway=footway", + "then": { + "nl": "Voetpad" + } + }, + { + "if": "highway=cycleway", + "then": { + "nl": "Fietspad" + } + }, + { + "if": "highway=pedestrian", + "then": { + "nl": "Voetgangersstraat" + } + }, + { + "if": "highway=living_street", + "then": { + "nl": "Woonerf" + } + }, + { + "if": "highway=path", + "then": "Klein pad" + } + ] }, - { - "question": "Is deze weg 's nachts verlicht?", - "mappings": [ + "tagRenderings": [ + "images", { - "if": "lit=yes", - "then": "'s nachts verlicht" + "mappings": [ + { + "if": "highway=living_street", + "then": { + "nl:": "
Dit is een woonerf:
  • Voetgangers mogen hier de volledige breedte van de straat gebruiken
  • Gemotoriseerd verkeer mag maximaal 20km/h rijden
" + } + }, + { + "if": "highway=pedestrian", + "then": { + "nl": "Dit is een brede, autovrije straat" + } + }, + { + "if": "highway=footway", + "then": { + "nl": "Dit is een voetpaadje" + } + }, + { + "if": "highway=path", + "then": { + "nl": "Dit is een wegeltje of bospad" + } + }, + { + "if": "highway=bridleway", + "then": { + "nl": "Dit is een ruiterswegel" + } + }, + { + "if": "highway=track", + "then": { + "nl": "Dit is een tractorspoor of weg om landbouwgrond te bereikken" + } + } + ] }, { - "if": "lit=no", - "then": "Niet verlicht" + "question": { + "nl": "Wat is de wegverharding van dit pad?" + }, + "render": { + "nl": "De ondergrond is {surface}", + "en": "The surface is {surface}", + "ru": "Поверхность - {surface}", + "fr": "La surface en {surface}", + "it": "La superficie è {surface}" + }, + "freeform": { + "key": "surface" + }, + "mappings": [ + { + "if": "surface=grass", + "then": { + "nl": "De ondergrond is gras", + "en": "The surface is grass", + "ru": "Поверхность - трава", + "fr": "La surface est en herbe", + "it": "La superficie è erba" + } + }, + { + "if": "surface=ground", + "then": { + "nl": "De ondergrond is aarde", + "en": "The surface is ground", + "ru": "Поверхность - земля", + "fr": "La surface est en terre", + "it": "La superficie è terreno" + } + }, + { + "if": "surface=unpaved", + "then": { + "nl": "De ondergrond is onverhard", + "en": "The surface is unpaved", + "fr": "La surface est non pavée", + "it": "La superficie è non pavimentata" + }, + "hideInAnswer": true + }, + { + "if": "surface=sand", + "then": { + "nl": "De ondergrond is zand", + "en": "The surface is sand", + "ru": "Поверхность - песок", + "fr": "La surface est en sable", + "it": "La superficie è sabbia" + } + }, + { + "if": "surface=paving_stones", + "then": { + "nl": "De ondergrond bestaat uit stoeptegels", + "en": "The surface is paving stones", + "ru": "Поверхность - брусчатка", + "it": "La superficie è pietre irregolari", + "fr": "La surface est en pierres pavées" + } + }, + { + "if": "surface=asphalt", + "then": { + "nl": "De ondergrond is asfalt", + "en": "The surface is asphalt", + "ru": "Поверхность - асфальт", + "it": "La superficie è asfalto", + "fr": "La surface est en bitume" + } + }, + { + "if": "surface=concrete", + "then": { + "nl": "De ondergrond is beton", + "en": "The surface is concrete", + "ru": "Поверхность - бетон", + "fr": "La surface est en béton", + "it": "La superficie è calcestruzzo" + } + }, + { + "if": "surface=paved", + "then": { + "nl": "De ondergrond is verhard", + "en": "The surface is paved", + "fr": "La surface est pavée", + "it": "La superficie è pavimentata" + }, + "hideInAnswer": true + } + ] + }, + { + "question": "Is deze weg 's nachts verlicht?", + "mappings": [ + { + "if": "lit=yes", + "then": "'s nachts verlicht" + }, + { + "if": "lit=no", + "then": "Niet verlicht" + } + ] } - ] - } - ], - "width": { - "render": "7" - }, - "dashArray": { - "render": "", - "mappings": [ - { - "if": "highway=cycleway", - "then": "" - }, - { - "if": "highway=path", - "then": "0 12" - }, - { - "if": { - "or": [ - "highway=footway", - "highway=pedestrian" - ] - }, - "then": "12 18" - }, - { - "if": "highway=living_street", - "then": "12 12 0 12" - } - ] - }, - "color": { - "render": "#eaba2a" - }, - "presets": [] + ], + "width": { + "render": "7" + }, + "dashArray": { + "render": "", + "mappings": [ + { + "if": "highway=cycleway", + "then": "" + }, + { + "if": "highway=path", + "then": "0 12" + }, + { + "if": { + "or": [ + "highway=footway", + "highway=pedestrian" + ] + }, + "then": "12 18" + }, + { + "if": "highway=living_street", + "then": "12 12 0 12" + } + ] + }, + "color": { + "render": "#eaba2a" + }, + "presets": [] } \ No newline at end of file diff --git a/assets/layers/sport_pitch/sport_pitch.json b/assets/layers/sport_pitch/sport_pitch.json index b871523f7..17e47f206 100644 --- a/assets/layers/sport_pitch/sport_pitch.json +++ b/assets/layers/sport_pitch/sport_pitch.json @@ -1,486 +1,486 @@ { - "id": "sport_pitch", - "name": { - "nl": "Sportterrein", - "fr": "Terrains de sport", - "en": "Sport pitches", - "ru": "Спортивные площадки", - "it": "Campi sportivi" - }, - "wayHandling": 1, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - "leisure=pitch" - ] - } - }, - "calculatedTags": [ - "_size_classification=Number(feat.properties._surface) < 200 ? 'small' : (Number(feat.properties._surface) < 750 ? 'medium' : 'large') " - ], - "title": { - "render": { - "nl": "Sportterrein", - "fr": "Terrain de sport", - "en": "Sport pitch", - "ru": "Спортивная площадка", - "it": "Campo sportivo" - } - }, - "description": { - "nl": "Een sportterrein", - "fr": "Un terrain de sport", - "en": "A sport pitch", - "it": "Un campo sportivo", - "ru": "Спортивная площадка" - }, - "tagRenderings": [ - "images", - { - "render": { - "nl": "Hier kan men {sport} beoefenen", - "fr": "Ici on joue au {sport}", - "en": "{sport} is played here", - "it": "Qui si gioca a {sport}" - }, - "freeform": { - "key": "sport" - }, - "question": { - "nl": "Welke sporten kan men hier beoefenen?", - "fr": "À quel sport peut-on jouer ici ?", - "en": "Which sport can be played here?", - "it": "Quale sport si gioca qui?" - }, - "multiAnswer": true, - "mappings": [ - { - "if": { - "and": [ - "sport=basketball" - ] - }, - "then": { - "nl": "Hier kan men basketbal spelen", - "fr": "Ici, on joue au basketball", - "en": "Basketball is played here", - "it": "Qui si gioca a basket", - "ru": "Здесь можно играть в баскетбол" - } - }, - { - "if": { - "and": [ - "sport=soccer" - ] - }, - "then": { - "nl": "Hier kan men voetbal spelen", - "fr": "Ici, on joue au football", - "en": "Soccer is played here", - "it": "Qui si gioca a calcio", - "ru": "Здесь можно играть в футбол" - } - }, - { - "if": { - "and": [ - "sport=table_tennis" - ] - }, - "then": { - "nl": "Dit is een pingpongtafel", - "fr": "C'est une table de ping-pong", - "en": "This is a pingpong table", - "ru": "Это стол для пинг-понга", - "it": "Questo è un tavolo da ping pong" - } - }, - { - "if": { - "and": [ - "sport=tennis" - ] - }, - "then": { - "nl": "Hier kan men tennis spelen", - "fr": "Ici, on joue au tennis", - "en": "Tennis is played here", - "it": "Qui si gioca a tennis", - "ru": "Здесь можно играть в теннис" - } - }, - { - "if": { - "and": [ - "sport=korfball" - ] - }, - "then": { - "nl": "Hier kan men korfbal spelen", - "fr": "Ici, on joue au korfball", - "en": "Korfball is played here", - "it": "Qui si gioca a korfball", - "ru": "Здесь можно играть в корфбол" - } - }, - { - "if": { - "and": [ - "sport=basket" - ] - }, - "then": { - "nl": "Hier kan men basketbal beoefenen", - "fr": "Ici, on joue au basketball", - "en": "Basketball is played here", - "it": "Qui si gioca a basket", - "ru": "Здесь можно играть в баскетбол" - }, - "hideInAnswer": true - } - ] - }, - { - "question": { - "nl": "Wat is de ondergrond van dit sportveld?", - "fr": "De quelle surface est fait ce terrain de sport ?", - "en": "Which is the surface of this sport pitch?", - "it": "Qual è la superficie di questo campo sportivo?", - "ru": "Какое покрытие на этой спортивной площадке?" - }, - "render": { - "nl": "De ondergrond is {surface}", - "fr": "La surface est {surface}", - "en": "The surface is {surface}", - "ru": "Поверхность - {surface}", - "it": "La superficie è {surface}" - }, - "freeform": { - "key": "surface" - }, - "mappings": [ - { - "if": "surface=grass", - "then": { - "nl": "De ondergrond is gras", - "fr": "La surface est de l'herbe", - "en": "The surface is grass", - "ru": "Поверхность - трава", - "it": "La superficie è erba" - } - }, - { - "if": "surface=sand", - "then": { - "nl": "De ondergrond is zand", - "fr": "La surface est du sable", - "en": "The surface is sand", - "ru": "Поверхность - песок", - "it": "La superficie è sabbia" - } - }, - { - "if": "surface=paving_stones", - "then": { - "nl": "De ondergrond bestaat uit stoeptegels", - "fr": "La surface est des pavés", - "en": "The surface is paving stones", - "ru": "Поверхность - брусчатка", - "it": "La superficie è pietre irregolari" - } - }, - { - "if": "surface=asphalt", - "then": { - "nl": "De ondergrond is asfalt", - "fr": "La surface est de l'asphalte", - "en": "The surface is asphalt", - "ru": "Поверхность - асфальт", - "it": "La superficie è asfalto" - } - }, - { - "if": "surface=concrete", - "then": { - "nl": "De ondergrond is beton", - "fr": "La surface est du béton", - "en": "The surface is concrete", - "ru": "Поверхность - бетон", - "it": "La superficie è calcestruzzo" - } - } - ] - }, - { - "question": { - "nl": "Is dit sportterrein publiek toegankelijk?", - "fr": "Est-ce que ce terrain de sport est accessible au public ?", - "en": "Is this sport pitch publicly accessible?", - "it": "Questo campo sportivo è aperto al pubblico?", - "ru": "Есть ли свободный доступ к этой спортивной площадке?" - }, - "mappings": [ - { - "if": "access=public", - "then": { - "nl": "Publiek toegankelijk", - "fr": "Accessible au public", - "en": "Public access", - "it": "Aperto al pubblico", - "ru": "Свободный доступ" - } - }, - { - "if": "access=limited", - "then": { - "nl": "Beperkt toegankelijk (enkel na reservatie, tijdens bepaalde uren, ...)", - "fr": "Accès limité (par exemple uniquement sur réservation, à certains horaires…)", - "en": "Limited access (e.g. only with an appointment, during certain hours, ...)", - "it": "Accesso limitato (p.es. solo con prenotazione, in certi orari, ...)", - "ru": "Ограниченный доступ (напр., только по записи, в определённые часы, ...)" - } - }, - { - "if": "access=members", - "then": { - "nl": "Enkel toegankelijk voor leden van de bijhorende sportclub", - "fr": "Accessible uniquement aux membres du club", - "en": "Only accessible for members of the club", - "it": "Accesso limitato ai membri dell'associazione", - "ru": "Доступ только членам клуба" - } - }, - { - "if": "access=private", - "then": { - "nl": "Privaat en niet toegankelijk", - "fr": "Privé - Pas accessible au public", - "en": "Private - not accessible to the public", - "it": "Privato - non aperto al pubblico" - } - } - ] - }, - { - "question": { - "nl": "Moet men reserveren om gebruik te maken van dit sportveld?", - "fr": "Doit-on réserver pour utiliser ce terrain de sport ?", - "en": "Does one have to make an appointment to use this sport pitch?", - "it": "È necessario prenotarsi per usare questo campo sportivo?", - "ru": "Нужна ли предварительная запись для доступа на эту спортивную площадку?" - }, - "condition": { - "and": [ - "access!=public", - "access!=private", - "access!=members" - ] - }, - "mappings": [ - { - "if": "reservation=required", - "then": { - "nl": "Reserveren is verplicht om gebruik te maken van dit sportterrein", - "fr": "Il est obligatoire de réserver pour utiliser ce terrain de sport", - "en": "Making an appointment is obligatory to use this sport pitch", - "it": "La prenotazione è obbligatoria per usare questo campo sportivo" - } - }, - { - "if": "reservation=recommended", - "then": { - "nl": "Reserveren is sterk aangeraden om gebruik te maken van dit sportterrein", - "fr": "Il est recommendé de réserver pour utiliser ce terrain de sport", - "en": "Making an appointment is recommended when using this sport pitch", - "it": "La prenotazione è consigliata per usare questo campo sportivo", - "ru": "Желательна предварительная запись для доступа на эту спортивную площадку" - } - }, - { - "if": "reservation=yes", - "then": { - "nl": "Reserveren is mogelijk, maar geen voorwaarde", - "fr": "Il est possible de réserver, mais ce n'est pas nécéssaire pour utiliser ce terrain de sport", - "en": "Making an appointment is possible, but not necessary to use this sport pitch", - "it": "La prenotazione è consentita, ma non è obbligatoria per usare questo campo sportivo", - "ru": "Предварительная запись для доступа на эту спортивную площадку возможна, но не обязательна" - } - }, - { - "if": "reservation=no", - "then": { - "nl": "Reserveren is niet mogelijk", - "fr": "On ne peut pas réserver", - "en": "Making an appointment is not possible", - "it": "Non è possibile prenotare", - "ru": "Невозможна предварительная запись" - } - } - ] - }, - { - "question": { - "nl": "Wat is het telefoonnummer van de bevoegde dienst of uitbater?", - "fr": "Quel est le numéro de téléphone du gérant ?", - "en": "What is the phone number of the operator?", - "it": "Qual è il numero di telefono del gestore?" - }, - "freeform": { - "key": "phone", - "type": "phone" - }, - "render": "{phone}" - }, - { - "question": { - "nl": "Wat is het email-adres van de bevoegde dienst of uitbater?", - "fr": "Quelle est l'adresse courriel du gérant ?", - "en": "What is the email address of the operator?", - "it": "Qual è l'indirizzo email del gestore?" - }, - "freeform": { - "key": "email", - "type": "email" - }, - "render": "{email}" - }, - { - "question": { - "nl": "Wanneer is dit sportveld toegankelijk?", - "fr": "Quand ce terrain est-il accessible ?", - "en": "When is this pitch accessible?", - "it": "Quando è aperto questo campo sportivo?", - "ru": "В какое время доступна эта площадка?" - }, - "render": "Openingsuren: {opening_hours_table()}", - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - }, - "mappings": [ - { - "if": "opening_hours=", - "then": "24/7 toegankelijk", - "hideInAnswer": true - }, - { - "if": "opening_hours=24/7", - "then": { - "nl": "24/7 toegankelijk", - "fr": "Accessible en permanence", - "en": "Always accessible", - "ru": "Всегда доступен", - "it": "Sempre aperto" - } - } - ], - "condition": "access~*" - }, - "questions", - { - "render": "{reviews(name, sportpitch)}" - } - ], - "icon": { - "render": "circle:white;./assets/layers/sport_pitch/sport_pitch.svg", - "mappings": [ - { - "if": { - "or": [ - "sport=baseball", - "sport=basketball", - "sport=beachvolleyball", - "sport=boules", - "sport=skateboard", - "sport=soccer", - "sport=table_tennis", - "sport=tennis", - "sport=volleyball" - ] - }, - "then": "circle:white;./assets/layers/sport_pitch/{sport}.svg" - } - ] - }, - "iconOverlays": [ - { - "if": { - "and": [ - "opening_hours!=24/7", - "opening_hours~*" - ] - }, - "then": "isOpen", - "badge": true - }, - { - "if": { - "or": [ - "access=customers", - "access=private", - "access=no" - ] - }, - "then": "circle:white;./assets/layers/sport_pitch/lock.svg", - "badge": true - } - ], - "width": { - "render": "1" - }, - "iconSize": { - "render": "25,25,center", - "mappings": [ - { - "if": { - "or": [ - "_size_classification=medium", - "id~node/.*" - ] - }, - "then": "40,40,center" - }, - { - "if": "_size_classification=small", - "then": "25,25,center" - }, - { - "if": "_size_classification=large", - "then": "50,50,center" - } - ] - }, - "color": { - "render": "#7cb82f" - }, - "presets": [ - { - "title": { - "nl": "Ping-pong tafel", - "fr": "Table de ping-pong", - "en": "Tabletennis table", - "it": "Tavolo da tennistavolo", - "ru": "Стол для настольного тенниса" - }, - "tags": [ - "leisure=pitch", - "sport=table_tennis" - ] - }, - { - "title": { + "id": "sport_pitch", + "name": { "nl": "Sportterrein", - "fr": "Terrain de sport", - "en": "Sport pitch", - "ru": "Спортивная площадка", - "it": "Campo sportivo" - }, - "tags": [ - "leisure=pitch", - "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" - ] - } - ] + "fr": "Terrains de sport", + "en": "Sport pitches", + "ru": "Спортивные площадки", + "it": "Campi sportivi" + }, + "wayHandling": 1, + "minzoom": 12, + "source": { + "osmTags": { + "and": [ + "leisure=pitch" + ] + } + }, + "calculatedTags": [ + "_size_classification=Number(feat.properties._surface) < 200 ? 'small' : (Number(feat.properties._surface) < 750 ? 'medium' : 'large') " + ], + "title": { + "render": { + "nl": "Sportterrein", + "fr": "Terrain de sport", + "en": "Sport pitch", + "ru": "Спортивная площадка", + "it": "Campo sportivo" + } + }, + "description": { + "nl": "Een sportterrein", + "fr": "Un terrain de sport", + "en": "A sport pitch", + "it": "Un campo sportivo", + "ru": "Спортивная площадка" + }, + "tagRenderings": [ + "images", + { + "render": { + "nl": "Hier kan men {sport} beoefenen", + "fr": "Ici on joue au {sport}", + "en": "{sport} is played here", + "it": "Qui si gioca a {sport}" + }, + "freeform": { + "key": "sport" + }, + "question": { + "nl": "Welke sporten kan men hier beoefenen?", + "fr": "À quel sport peut-on jouer ici ?", + "en": "Which sport can be played here?", + "it": "Quale sport si gioca qui?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": { + "and": [ + "sport=basketball" + ] + }, + "then": { + "nl": "Hier kan men basketbal spelen", + "fr": "Ici, on joue au basketball", + "en": "Basketball is played here", + "it": "Qui si gioca a basket", + "ru": "Здесь можно играть в баскетбол" + } + }, + { + "if": { + "and": [ + "sport=soccer" + ] + }, + "then": { + "nl": "Hier kan men voetbal spelen", + "fr": "Ici, on joue au football", + "en": "Soccer is played here", + "it": "Qui si gioca a calcio", + "ru": "Здесь можно играть в футбол" + } + }, + { + "if": { + "and": [ + "sport=table_tennis" + ] + }, + "then": { + "nl": "Dit is een pingpongtafel", + "fr": "C'est une table de ping-pong", + "en": "This is a pingpong table", + "ru": "Это стол для пинг-понга", + "it": "Questo è un tavolo da ping pong" + } + }, + { + "if": { + "and": [ + "sport=tennis" + ] + }, + "then": { + "nl": "Hier kan men tennis spelen", + "fr": "Ici, on joue au tennis", + "en": "Tennis is played here", + "it": "Qui si gioca a tennis", + "ru": "Здесь можно играть в теннис" + } + }, + { + "if": { + "and": [ + "sport=korfball" + ] + }, + "then": { + "nl": "Hier kan men korfbal spelen", + "fr": "Ici, on joue au korfball", + "en": "Korfball is played here", + "it": "Qui si gioca a korfball", + "ru": "Здесь можно играть в корфбол" + } + }, + { + "if": { + "and": [ + "sport=basket" + ] + }, + "then": { + "nl": "Hier kan men basketbal beoefenen", + "fr": "Ici, on joue au basketball", + "en": "Basketball is played here", + "it": "Qui si gioca a basket", + "ru": "Здесь можно играть в баскетбол" + }, + "hideInAnswer": true + } + ] + }, + { + "question": { + "nl": "Wat is de ondergrond van dit sportveld?", + "fr": "De quelle surface est fait ce terrain de sport ?", + "en": "Which is the surface of this sport pitch?", + "it": "Qual è la superficie di questo campo sportivo?", + "ru": "Какое покрытие на этой спортивной площадке?" + }, + "render": { + "nl": "De ondergrond is {surface}", + "fr": "La surface est {surface}", + "en": "The surface is {surface}", + "ru": "Поверхность - {surface}", + "it": "La superficie è {surface}" + }, + "freeform": { + "key": "surface" + }, + "mappings": [ + { + "if": "surface=grass", + "then": { + "nl": "De ondergrond is gras", + "fr": "La surface est de l'herbe", + "en": "The surface is grass", + "ru": "Поверхность - трава", + "it": "La superficie è erba" + } + }, + { + "if": "surface=sand", + "then": { + "nl": "De ondergrond is zand", + "fr": "La surface est du sable", + "en": "The surface is sand", + "ru": "Поверхность - песок", + "it": "La superficie è sabbia" + } + }, + { + "if": "surface=paving_stones", + "then": { + "nl": "De ondergrond bestaat uit stoeptegels", + "fr": "La surface est des pavés", + "en": "The surface is paving stones", + "ru": "Поверхность - брусчатка", + "it": "La superficie è pietre irregolari" + } + }, + { + "if": "surface=asphalt", + "then": { + "nl": "De ondergrond is asfalt", + "fr": "La surface est de l'asphalte", + "en": "The surface is asphalt", + "ru": "Поверхность - асфальт", + "it": "La superficie è asfalto" + } + }, + { + "if": "surface=concrete", + "then": { + "nl": "De ondergrond is beton", + "fr": "La surface est du béton", + "en": "The surface is concrete", + "ru": "Поверхность - бетон", + "it": "La superficie è calcestruzzo" + } + } + ] + }, + { + "question": { + "nl": "Is dit sportterrein publiek toegankelijk?", + "fr": "Est-ce que ce terrain de sport est accessible au public ?", + "en": "Is this sport pitch publicly accessible?", + "it": "Questo campo sportivo è aperto al pubblico?", + "ru": "Есть ли свободный доступ к этой спортивной площадке?" + }, + "mappings": [ + { + "if": "access=public", + "then": { + "nl": "Publiek toegankelijk", + "fr": "Accessible au public", + "en": "Public access", + "it": "Aperto al pubblico", + "ru": "Свободный доступ" + } + }, + { + "if": "access=limited", + "then": { + "nl": "Beperkt toegankelijk (enkel na reservatie, tijdens bepaalde uren, ...)", + "fr": "Accès limité (par exemple uniquement sur réservation, à certains horaires…)", + "en": "Limited access (e.g. only with an appointment, during certain hours, ...)", + "it": "Accesso limitato (p.es. solo con prenotazione, in certi orari, ...)", + "ru": "Ограниченный доступ (напр., только по записи, в определённые часы, ...)" + } + }, + { + "if": "access=members", + "then": { + "nl": "Enkel toegankelijk voor leden van de bijhorende sportclub", + "fr": "Accessible uniquement aux membres du club", + "en": "Only accessible for members of the club", + "it": "Accesso limitato ai membri dell'associazione", + "ru": "Доступ только членам клуба" + } + }, + { + "if": "access=private", + "then": { + "nl": "Privaat en niet toegankelijk", + "fr": "Privé - Pas accessible au public", + "en": "Private - not accessible to the public", + "it": "Privato - non aperto al pubblico" + } + } + ] + }, + { + "question": { + "nl": "Moet men reserveren om gebruik te maken van dit sportveld?", + "fr": "Doit-on réserver pour utiliser ce terrain de sport ?", + "en": "Does one have to make an appointment to use this sport pitch?", + "it": "È necessario prenotarsi per usare questo campo sportivo?", + "ru": "Нужна ли предварительная запись для доступа на эту спортивную площадку?" + }, + "condition": { + "and": [ + "access!=public", + "access!=private", + "access!=members" + ] + }, + "mappings": [ + { + "if": "reservation=required", + "then": { + "nl": "Reserveren is verplicht om gebruik te maken van dit sportterrein", + "fr": "Il est obligatoire de réserver pour utiliser ce terrain de sport", + "en": "Making an appointment is obligatory to use this sport pitch", + "it": "La prenotazione è obbligatoria per usare questo campo sportivo" + } + }, + { + "if": "reservation=recommended", + "then": { + "nl": "Reserveren is sterk aangeraden om gebruik te maken van dit sportterrein", + "fr": "Il est recommendé de réserver pour utiliser ce terrain de sport", + "en": "Making an appointment is recommended when using this sport pitch", + "it": "La prenotazione è consigliata per usare questo campo sportivo", + "ru": "Желательна предварительная запись для доступа на эту спортивную площадку" + } + }, + { + "if": "reservation=yes", + "then": { + "nl": "Reserveren is mogelijk, maar geen voorwaarde", + "fr": "Il est possible de réserver, mais ce n'est pas nécéssaire pour utiliser ce terrain de sport", + "en": "Making an appointment is possible, but not necessary to use this sport pitch", + "it": "La prenotazione è consentita, ma non è obbligatoria per usare questo campo sportivo", + "ru": "Предварительная запись для доступа на эту спортивную площадку возможна, но не обязательна" + } + }, + { + "if": "reservation=no", + "then": { + "nl": "Reserveren is niet mogelijk", + "fr": "On ne peut pas réserver", + "en": "Making an appointment is not possible", + "it": "Non è possibile prenotare", + "ru": "Невозможна предварительная запись" + } + } + ] + }, + { + "question": { + "nl": "Wat is het telefoonnummer van de bevoegde dienst of uitbater?", + "fr": "Quel est le numéro de téléphone du gérant ?", + "en": "What is the phone number of the operator?", + "it": "Qual è il numero di telefono del gestore?" + }, + "freeform": { + "key": "phone", + "type": "phone" + }, + "render": "{phone}" + }, + { + "question": { + "nl": "Wat is het email-adres van de bevoegde dienst of uitbater?", + "fr": "Quelle est l'adresse courriel du gérant ?", + "en": "What is the email address of the operator?", + "it": "Qual è l'indirizzo email del gestore?" + }, + "freeform": { + "key": "email", + "type": "email" + }, + "render": "{email}" + }, + { + "question": { + "nl": "Wanneer is dit sportveld toegankelijk?", + "fr": "Quand ce terrain est-il accessible ?", + "en": "When is this pitch accessible?", + "it": "Quando è aperto questo campo sportivo?", + "ru": "В какое время доступна эта площадка?" + }, + "render": "Openingsuren: {opening_hours_table()}", + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + }, + "mappings": [ + { + "if": "opening_hours=", + "then": "24/7 toegankelijk", + "hideInAnswer": true + }, + { + "if": "opening_hours=24/7", + "then": { + "nl": "24/7 toegankelijk", + "fr": "Accessible en permanence", + "en": "Always accessible", + "ru": "Всегда доступен", + "it": "Sempre aperto" + } + } + ], + "condition": "access~*" + }, + "questions", + { + "render": "{reviews(name, sportpitch)}" + } + ], + "icon": { + "render": "circle:white;./assets/layers/sport_pitch/sport_pitch.svg", + "mappings": [ + { + "if": { + "or": [ + "sport=baseball", + "sport=basketball", + "sport=beachvolleyball", + "sport=boules", + "sport=skateboard", + "sport=soccer", + "sport=table_tennis", + "sport=tennis", + "sport=volleyball" + ] + }, + "then": "circle:white;./assets/layers/sport_pitch/{sport}.svg" + } + ] + }, + "iconOverlays": [ + { + "if": { + "and": [ + "opening_hours!=24/7", + "opening_hours~*" + ] + }, + "then": "isOpen", + "badge": true + }, + { + "if": { + "or": [ + "access=customers", + "access=private", + "access=no" + ] + }, + "then": "circle:white;./assets/layers/sport_pitch/lock.svg", + "badge": true + } + ], + "width": { + "render": "1" + }, + "iconSize": { + "render": "25,25,center", + "mappings": [ + { + "if": { + "or": [ + "_size_classification=medium", + "id~node/.*" + ] + }, + "then": "40,40,center" + }, + { + "if": "_size_classification=small", + "then": "25,25,center" + }, + { + "if": "_size_classification=large", + "then": "50,50,center" + } + ] + }, + "color": { + "render": "#7cb82f" + }, + "presets": [ + { + "title": { + "nl": "Ping-pong tafel", + "fr": "Table de ping-pong", + "en": "Tabletennis table", + "it": "Tavolo da tennistavolo", + "ru": "Стол для настольного тенниса" + }, + "tags": [ + "leisure=pitch", + "sport=table_tennis" + ] + }, + { + "title": { + "nl": "Sportterrein", + "fr": "Terrain de sport", + "en": "Sport pitch", + "ru": "Спортивная площадка", + "it": "Campo sportivo" + }, + "tags": [ + "leisure=pitch", + "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" + ] + } + ] } \ No newline at end of file diff --git a/assets/layers/surveillance_camera/surveillance_camera.json b/assets/layers/surveillance_camera/surveillance_camera.json index 7a6a4248c..40bed359f 100644 --- a/assets/layers/surveillance_camera/surveillance_camera.json +++ b/assets/layers/surveillance_camera/surveillance_camera.json @@ -1,484 +1,484 @@ { - "id": "surveillance_camera", - "name": { - "en": "Surveillance camera's", - "nl": "Bewakingscamera's", - "ru": "Камеры наблюдения", - "fr": "Caméras de surveillance", - "it": "Videocamere di sorveglianza" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - "man_made=surveillance", - { - "or": [ - "surveillance:type=camera", - "surveillance:type=ALPR", - "surveillance:type=ANPR" - ] - } - ] - } - }, - "title": { - "render": { - "en": "Surveillance Camera", - "nl": "Bewakingscamera", - "ru": "Камера наблюдения", - "fr": "Caméra de surveillance", - "it": "Videocamera di sorveglianza" - } - }, - "tagRenderings": [ - "images", - { - "#": "Camera type: fixed; panning; dome", - "question": { - "en": "What kind of camera is this?", - "nl": "Wat voor soort camera is dit?", - "fr": "Quel genre de caméra est-ce ?", - "it": "Di che tipo di videocamera si tratta?", - "ru": "Какая это камера?" - }, - "mappings": [ - { - "if": { - "and": [ - "camera:type=fixed" - ] - }, - "then": { - "en": "A fixed (non-moving) camera", - "nl": "Een vaste camera", - "fr": "Une caméra fixe (non mobile)", - "it": "Una videocamera fissa (non semovente)" - } - }, - { - "if": { - "and": [ - "camera:type=dome" - ] - }, - "then": { - "en": "A dome camera (which can turn)", - "nl": "Een dome (bolvormige camera die kan draaien)", - "fr": "Une caméra dôme (qui peut tourner)", - "it": "Una videocamera a cupola (che può ruotare)", - "ru": "Камера с поворотным механизмом" - } - }, - { - "if": { - "and": [ - "camera:type=panning" - ] - }, - "then": { - "en": "A panning camera", - "nl": "Een camera die (met een motor) van links naar rechts kan draaien", - "ru": "Панорамная камера", - "fr": "Une caméra panoramique", - "it": "Una videocamera panoramica" - } - } - ] + "id": "surveillance_camera", + "name": { + "en": "Surveillance camera's", + "nl": "Bewakingscamera's", + "ru": "Камеры наблюдения", + "fr": "Caméras de surveillance", + "it": "Videocamere di sorveglianza" }, - { - "#": "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view", - "question": { - "en": "In which geographical direction does this camera film?", - "nl": "In welke geografische richting filmt deze camera?", - "fr": "Dans quelle direction géographique cette caméra filme-t-elle ?", - "it": "In quale direzione geografica punta questa videocamera?" - }, - "render": { - "en": "Films to a compass heading of {camera:direction}", - "nl": "Filmt in kompasrichting {camera:direction}", - "fr": "Filme dans une direction {camera:direction}", - "it": "Punta in direzione {camera:direction}" - }, - "condition": { - "or": [ - "camera:direction~*", - "direction~*", - "camera:type!=dome", - { + "minzoom": 12, + "source": { + "osmTags": { "and": [ - "camera:type=dome", - "camera:mount=wall" + "man_made=surveillance", + { + "or": [ + "surveillance:type=camera", + "surveillance:type=ALPR", + "surveillance:type=ANPR" + ] + } ] - } - ] - }, - "freeform": { - "key": "camera:direction", - "type": "direction" - }, - "mappings": [ - { - "if": { - "and": [ - "camera:direction=", - "direction~*" - ] - }, - "then": { - "en": "Films to a compass heading of {direction}", - "nl": "Filmt in kompasrichting {direction}", - "fr": "Filme dans une direction {direction}", - "it": "Punta in direzione {direction}" - }, - "hideInAnswer": true } - ] }, - { - "#": "Operator", - "freeform": { - "key": "operator" - }, - "question": { - "en": "Who operates this CCTV?", - "nl": "Wie beheert deze bewakingscamera?", - "fr": "Qui exploite ce système de vidéosurveillance ?", - "it": "Chi gestisce questa videocamera a circuito chiuso?" - }, - "render": { - "en": "Operated by {operator}", - "nl": "Beheer door {operator}", - "fr": "Exploité par {operator}", - "it": "È gestita da {operator}" - } - }, - { - "#": "Surveillance type: public, outdoor, indoor", - "question": { - "en": "What kind of surveillance is this camera", - "nl": "Wat soort bewaking wordt hier uitgevoerd?", - "fr": "Quel genre de surveillance est cette caméra", - "it": "Che cosa sorveglia questa videocamera" - }, - "mappings": [ - { - "if": { - "and": [ - "surveillance=public" - ] - }, - "then": { - "en": "A public area is surveilled, such as a street, a bridge, a square, a park, a train station, a public corridor or tunnel,...", - "nl": "Bewaking van de publieke ruilmte, dus een straat, een brug, een park, een plein, een stationsgebouw, een publiek toegankelijke gang of tunnel...", - "fr": "Une zone publique est surveillée, telle qu'une rue, un pont, une place, un parc, une gare, un couloir ou un tunnel public…", - "it": "Sorveglia un'area pubblica, come una strada, un ponte, una piazza, un parco, una stazione, un passaggio o un sottopasso pubblico, ..." - } - }, - { - "if": { - "and": [ - "surveillance=outdoor" - ] - }, - "then": { - "en": "An outdoor, yet private area is surveilled (e.g. a parking lot, a fuel station, courtyard, entrance, private driveway, ...)", - "nl": "Een buitenruimte met privaat karakter (zoals een privé-oprit, een parking, tankstation, ...)", - "fr": "Une zone extérieure, mais privée, est surveillée (par exemple, un parking, une station-service, une cour, une entrée, une allée privée, etc.)", - "it": "Sorveglia un'area esterna di proprietà privata (un parcheggio, una stazione di servizio, un cortile, un ingresso, un vialetto privato, ...)" - } - }, - { - "if": { - "and": [ - "surveillance=indoor" - ] - }, - "then": { - "nl": "Een private binnenruimte wordt bewaakt, bv. een winkel, een parkeergarage, ...", - "en": "A private indoor area is surveilled, e.g. a shop, a private underground parking, ...", - "fr": "Une zone intérieure privée est surveillée, par exemple un magasin, un parking souterrain privé…", - "it": "Sorveglia un ambiente interno di proprietà privata, per esempio un negozio, un parcheggio sotterraneo privato, ..." - } + "title": { + "render": { + "en": "Surveillance Camera", + "nl": "Bewakingscamera", + "ru": "Камера наблюдения", + "fr": "Caméra de surveillance", + "it": "Videocamera di sorveglianza" } - ] }, - { - "#": "Indoor camera? This isn't clear for 'public'-cameras", - "question": { - "en": "Is the public space surveilled by this camera an indoor or outdoor space?", - "nl": "Bevindt de bewaakte publieke ruimte camera zich binnen of buiten?", - "fr": "L'espace public surveillé par cette caméra est-il un espace intérieur ou extérieur ?", - "it": "Lo spazio pubblico sorvegliato da questa videocamera è all'aperto o al chiuso?" - }, - "condition": { - "and": [ - "surveillance:type=public" - ] - }, - "mappings": [ + "tagRenderings": [ + "images", { - "if": "indoor=yes", - "then": { - "en": "This camera is located indoors", - "nl": "Deze camera bevindt zich binnen", - "fr": "Cette caméra est située à l'intérieur", - "it": "Questa videocamera si trova al chiuso" - } + "#": "Camera type: fixed; panning; dome", + "question": { + "en": "What kind of camera is this?", + "nl": "Wat voor soort camera is dit?", + "fr": "Quel genre de caméra est-ce ?", + "it": "Di che tipo di videocamera si tratta?", + "ru": "Какая это камера?" + }, + "mappings": [ + { + "if": { + "and": [ + "camera:type=fixed" + ] + }, + "then": { + "en": "A fixed (non-moving) camera", + "nl": "Een vaste camera", + "fr": "Une caméra fixe (non mobile)", + "it": "Una videocamera fissa (non semovente)" + } + }, + { + "if": { + "and": [ + "camera:type=dome" + ] + }, + "then": { + "en": "A dome camera (which can turn)", + "nl": "Een dome (bolvormige camera die kan draaien)", + "fr": "Une caméra dôme (qui peut tourner)", + "it": "Una videocamera a cupola (che può ruotare)", + "ru": "Камера с поворотным механизмом" + } + }, + { + "if": { + "and": [ + "camera:type=panning" + ] + }, + "then": { + "en": "A panning camera", + "nl": "Een camera die (met een motor) van links naar rechts kan draaien", + "ru": "Панорамная камера", + "fr": "Une caméra panoramique", + "it": "Una videocamera panoramica" + } + } + ] }, { - "if": "indoor=no", - "then": { - "en": "This camera is located outdoors", - "nl": "Deze camera bevindt zich buiten", - "fr": "Cette caméra est située à l'extérieur", - "it": "Questa videocamera si trova all'aperto", - "ru": "Эта камера расположена снаружи" - } + "#": "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view", + "question": { + "en": "In which geographical direction does this camera film?", + "nl": "In welke geografische richting filmt deze camera?", + "fr": "Dans quelle direction géographique cette caméra filme-t-elle ?", + "it": "In quale direzione geografica punta questa videocamera?" + }, + "render": { + "en": "Films to a compass heading of {camera:direction}", + "nl": "Filmt in kompasrichting {camera:direction}", + "fr": "Filme dans une direction {camera:direction}", + "it": "Punta in direzione {camera:direction}" + }, + "condition": { + "or": [ + "camera:direction~*", + "direction~*", + "camera:type!=dome", + { + "and": [ + "camera:type=dome", + "camera:mount=wall" + ] + } + ] + }, + "freeform": { + "key": "camera:direction", + "type": "direction" + }, + "mappings": [ + { + "if": { + "and": [ + "camera:direction=", + "direction~*" + ] + }, + "then": { + "en": "Films to a compass heading of {direction}", + "nl": "Filmt in kompasrichting {direction}", + "fr": "Filme dans une direction {direction}", + "it": "Punta in direzione {direction}" + }, + "hideInAnswer": true + } + ] }, { - "if": "indoor=", - "then": { - "en": "This camera is probably located outdoors", - "nl": "Deze camera bevindt zich waarschijnlijk buiten", - "fr": "Cette caméra est probablement située à l'extérieur", - "it": "Questa videocamera si trova probabilmente all'esterno", - "ru": "Возможно, эта камера расположена снаружи" - }, - "hideInAnswer": true + "#": "Operator", + "freeform": { + "key": "operator" + }, + "question": { + "en": "Who operates this CCTV?", + "nl": "Wie beheert deze bewakingscamera?", + "fr": "Qui exploite ce système de vidéosurveillance ?", + "it": "Chi gestisce questa videocamera a circuito chiuso?" + }, + "render": { + "en": "Operated by {operator}", + "nl": "Beheer door {operator}", + "fr": "Exploité par {operator}", + "it": "È gestita da {operator}" + } + }, + { + "#": "Surveillance type: public, outdoor, indoor", + "question": { + "en": "What kind of surveillance is this camera", + "nl": "Wat soort bewaking wordt hier uitgevoerd?", + "fr": "Quel genre de surveillance est cette caméra", + "it": "Che cosa sorveglia questa videocamera" + }, + "mappings": [ + { + "if": { + "and": [ + "surveillance=public" + ] + }, + "then": { + "en": "A public area is surveilled, such as a street, a bridge, a square, a park, a train station, a public corridor or tunnel,...", + "nl": "Bewaking van de publieke ruilmte, dus een straat, een brug, een park, een plein, een stationsgebouw, een publiek toegankelijke gang of tunnel...", + "fr": "Une zone publique est surveillée, telle qu'une rue, un pont, une place, un parc, une gare, un couloir ou un tunnel public…", + "it": "Sorveglia un'area pubblica, come una strada, un ponte, una piazza, un parco, una stazione, un passaggio o un sottopasso pubblico, ..." + } + }, + { + "if": { + "and": [ + "surveillance=outdoor" + ] + }, + "then": { + "en": "An outdoor, yet private area is surveilled (e.g. a parking lot, a fuel station, courtyard, entrance, private driveway, ...)", + "nl": "Een buitenruimte met privaat karakter (zoals een privé-oprit, een parking, tankstation, ...)", + "fr": "Une zone extérieure, mais privée, est surveillée (par exemple, un parking, une station-service, une cour, une entrée, une allée privée, etc.)", + "it": "Sorveglia un'area esterna di proprietà privata (un parcheggio, una stazione di servizio, un cortile, un ingresso, un vialetto privato, ...)" + } + }, + { + "if": { + "and": [ + "surveillance=indoor" + ] + }, + "then": { + "nl": "Een private binnenruimte wordt bewaakt, bv. een winkel, een parkeergarage, ...", + "en": "A private indoor area is surveilled, e.g. a shop, a private underground parking, ...", + "fr": "Une zone intérieure privée est surveillée, par exemple un magasin, un parking souterrain privé…", + "it": "Sorveglia un ambiente interno di proprietà privata, per esempio un negozio, un parcheggio sotterraneo privato, ..." + } + } + ] + }, + { + "#": "Indoor camera? This isn't clear for 'public'-cameras", + "question": { + "en": "Is the public space surveilled by this camera an indoor or outdoor space?", + "nl": "Bevindt de bewaakte publieke ruimte camera zich binnen of buiten?", + "fr": "L'espace public surveillé par cette caméra est-il un espace intérieur ou extérieur ?", + "it": "Lo spazio pubblico sorvegliato da questa videocamera è all'aperto o al chiuso?" + }, + "condition": { + "and": [ + "surveillance:type=public" + ] + }, + "mappings": [ + { + "if": "indoor=yes", + "then": { + "en": "This camera is located indoors", + "nl": "Deze camera bevindt zich binnen", + "fr": "Cette caméra est située à l'intérieur", + "it": "Questa videocamera si trova al chiuso" + } + }, + { + "if": "indoor=no", + "then": { + "en": "This camera is located outdoors", + "nl": "Deze camera bevindt zich buiten", + "fr": "Cette caméra est située à l'extérieur", + "it": "Questa videocamera si trova all'aperto", + "ru": "Эта камера расположена снаружи" + } + }, + { + "if": "indoor=", + "then": { + "en": "This camera is probably located outdoors", + "nl": "Deze camera bevindt zich waarschijnlijk buiten", + "fr": "Cette caméra est probablement située à l'extérieur", + "it": "Questa videocamera si trova probabilmente all'esterno", + "ru": "Возможно, эта камера расположена снаружи" + }, + "hideInAnswer": true + } + ] + }, + { + "#": "Level", + "question": { + "en": "On which level is this camera located?", + "nl": "Op welke verdieping bevindt deze camera zich?", + "fr": "À quel niveau se trouve cette caméra ?", + "it": "A che piano si trova questa videocamera?" + }, + "render": { + "en": "Located on level {level}", + "nl": "Bevindt zich op verdieping {level}", + "fr": "Situé au niveau {level}", + "it": "Si trova al piano {level}" + }, + "freeform": { + "key": "level", + "type": "nat" + }, + "condition": { + "or": [ + "indoor=yes", + "surveillance:type=ye" + ] + } + }, + { + "#": "Surveillance:zone", + "question": { + "en": "What exactly is surveilled here?", + "nl": "Wat wordt hier precies bewaakt?", + "fr": "Qu'est-ce qui est surveillé ici ?", + "it": "Che cosa è sorvegliato qui?" + }, + "freeform": { + "key": "surveillance:zone" + }, + "render": { + "en": " Surveills a {surveillance:zone}", + "nl": "Bewaakt een {surveillance:zone}", + "fr": " Surveille un(e) {surveillance:zone}", + "it": " Sorveglia una {surveillance:zone}" + }, + "mappings": [ + { + "if": { + "and": [ + "surveillance:zone=parking" + ] + }, + "then": { + "en": "Surveills a parking", + "nl": "Bewaakt een parking", + "fr": "Surveille un parking", + "it": "Sorveglia un parcheggio" + } + }, + { + "if": { + "and": [ + "surveillance:zone=traffic" + ] + }, + "then": { + "en": "Surveills the traffic", + "nl": "Bewaakt het verkeer", + "fr": "Surveille la circulation", + "it": "Sorveglia il traffico" + } + }, + { + "if": { + "and": [ + "surveillance:zone=entrance" + ] + }, + "then": { + "en": "Surveills an entrance", + "nl": "Bewaakt een ingang", + "fr": "Surveille une entrée", + "it": "Sorveglia un ingresso" + } + }, + { + "if": { + "and": [ + "surveillance:zone=corridor" + ] + }, + "then": { + "en": "Surveills a corridor", + "nl": "Bewaakt een gang", + "fr": "Surveille un couloir", + "it": "Sorveglia un corridoio" + } + }, + { + "if": { + "and": [ + "surveillance:zone=public_transport_platform" + ] + }, + "then": { + "en": "Surveills a public tranport platform", + "nl": "Bewaakt een perron of bushalte", + "fr": "Surveille un quai de transport public", + "it": "Sorveglia una pensilina del trasporto pubblico" + } + }, + { + "if": { + "and": [ + "surveillance:zone=shop" + ] + }, + "then": { + "en": "Surveills a shop", + "nl": "Bewaakt een winkel", + "fr": "Surveille un magasin", + "it": "Sorveglia un negozio" + } + } + ] + }, + { + "#": "camera:mount", + "question": { + "en": "How is this camera placed?", + "nl": "Hoe is deze camera geplaatst?", + "fr": "Comment cette caméra est-elle placée ?", + "it": "Com'è posizionata questa telecamera?", + "ru": "Как расположена эта камера?" + }, + "render": { + "en": "Mounting method: {mount}", + "nl": "Montage: {camera:mount}", + "fr": "Méthode de montage : {mount}", + "it": "Metodo di montaggio: {mount}" + }, + "freeform": { + "key": "camera:mount" + }, + "mappings": [ + { + "if": "camera:mount=wall", + "then": { + "en": "This camera is placed against a wall", + "nl": "Deze camera hangt aan een muur", + "fr": "Cette caméra est placée contre un mur", + "it": "Questa telecamera è posizionata contro un muro" + } + }, + { + "if": "camera:mount=pole", + "then": { + "en": "This camera is placed one a pole", + "nl": "Deze camera staat op een paal", + "fr": "Cette caméra est placée sur un poteau", + "it": "Questa telecamera è posizionata su un palo" + } + }, + { + "if": "camera:mount=ceiling", + "then": { + "en": "This camera is placed on the ceiling", + "nl": "Deze camera hangt aan het plafond", + "fr": "Cette caméra est placée au plafond", + "it": "Questa telecamera è posizionata sul soffitto" + } + } + ] } - ] - }, - { - "#": "Level", - "question": { - "en": "On which level is this camera located?", - "nl": "Op welke verdieping bevindt deze camera zich?", - "fr": "À quel niveau se trouve cette caméra ?", - "it": "A che piano si trova questa videocamera?" - }, - "render": { - "en": "Located on level {level}", - "nl": "Bevindt zich op verdieping {level}", - "fr": "Situé au niveau {level}", - "it": "Si trova al piano {level}" - }, - "freeform": { - "key": "level", - "type": "nat" - }, - "condition": { - "or": [ - "indoor=yes", - "surveillance:type=ye" - ] - } - }, - { - "#": "Surveillance:zone", - "question": { - "en": "What exactly is surveilled here?", - "nl": "Wat wordt hier precies bewaakt?", - "fr": "Qu'est-ce qui est surveillé ici ?", - "it": "Che cosa è sorvegliato qui?" - }, - "freeform": { - "key": "surveillance:zone" - }, - "render": { - "en": " Surveills a {surveillance:zone}", - "nl": "Bewaakt een {surveillance:zone}", - "fr": " Surveille un(e) {surveillance:zone}", - "it": " Sorveglia una {surveillance:zone}" - }, - "mappings": [ - { - "if": { - "and": [ - "surveillance:zone=parking" - ] - }, - "then": { - "en": "Surveills a parking", - "nl": "Bewaakt een parking", - "fr": "Surveille un parking", - "it": "Sorveglia un parcheggio" - } - }, - { - "if": { - "and": [ - "surveillance:zone=traffic" - ] - }, - "then": { - "en": "Surveills the traffic", - "nl": "Bewaakt het verkeer", - "fr": "Surveille la circulation", - "it": "Sorveglia il traffico" - } - }, - { - "if": { - "and": [ - "surveillance:zone=entrance" - ] - }, - "then": { - "en": "Surveills an entrance", - "nl": "Bewaakt een ingang", - "fr": "Surveille une entrée", - "it": "Sorveglia un ingresso" - } - }, - { - "if": { - "and": [ - "surveillance:zone=corridor" - ] - }, - "then": { - "en": "Surveills a corridor", - "nl": "Bewaakt een gang", - "fr": "Surveille un couloir", - "it": "Sorveglia un corridoio" - } - }, - { - "if": { - "and": [ - "surveillance:zone=public_transport_platform" - ] - }, - "then": { - "en": "Surveills a public tranport platform", - "nl": "Bewaakt een perron of bushalte", - "fr": "Surveille un quai de transport public", - "it": "Sorveglia una pensilina del trasporto pubblico" - } - }, - { - "if": { - "and": [ - "surveillance:zone=shop" - ] - }, - "then": { - "en": "Surveills a shop", - "nl": "Bewaakt een winkel", - "fr": "Surveille un magasin", - "it": "Sorveglia un negozio" - } - } - ] - }, - { - "#": "camera:mount", - "question": { - "en": "How is this camera placed?", - "nl": "Hoe is deze camera geplaatst?", - "fr": "Comment cette caméra est-elle placée ?", - "it": "Com'è posizionata questa telecamera?", - "ru": "Как расположена эта камера?" - }, - "render": { - "en": "Mounting method: {mount}", - "nl": "Montage: {camera:mount}", - "fr": "Méthode de montage : {mount}", - "it": "Metodo di montaggio: {mount}" - }, - "freeform": { - "key": "camera:mount" - }, - "mappings": [ - { - "if": "camera:mount=wall", - "then": { - "en": "This camera is placed against a wall", - "nl": "Deze camera hangt aan een muur", - "fr": "Cette caméra est placée contre un mur", - "it": "Questa telecamera è posizionata contro un muro" - } - }, - { - "if": "camera:mount=pole", - "then": { - "en": "This camera is placed one a pole", - "nl": "Deze camera staat op een paal", - "fr": "Cette caméra est placée sur un poteau", - "it": "Questa telecamera è posizionata su un palo" - } - }, - { - "if": "camera:mount=ceiling", - "then": { - "en": "This camera is placed on the ceiling", - "nl": "Deze camera hangt aan het plafond", - "fr": "Cette caméra est placée au plafond", - "it": "Questa telecamera è posizionata sul soffitto" - } - } - ] - } - ], - "icon": { - "render": "./assets/themes/surveillance/logo.svg", - "mappings": [ - { - "if": "camera:type=dome", - "then": "./assets/themes/surveillance/dome.svg" - }, - { - "if": "_direction:leftright=right", - "then": "./assets/themes/surveillance/cam_right.svg" - }, - { - "if": "_direction:leftright=left", - "then": "./assets/themes/surveillance/cam_left.svg" - } - ] - }, - "rotation": { - "#": "Note: {camera:direction} is substituted by a number, giving the string 'calc(123deg + 90deg)' ; it is this string that is used as css property, which interprets the calc", - "render": "calc({_direction:numerical}deg + 90deg)", - "mappings": [ - { - "if": "camera:type=dome", - "then": "0" - }, - { - "if": "_direction:leftright=right", - "then": "calc({_direction:numerical}deg - 90deg)" - } - ] - }, - "width": { - "render": "8" - }, - "iconSize": { - "mappings": [ - { - "if": "camera:type=dome", - "then": "50,50,center" - }, - { - "if": "_direction:leftright~*", - "then": "100,35,center" - } ], - "render": "50,50,center" - }, - "color": { - "render": "#f00" - }, - "presets": [ - { - "tags": [ - "man_made=surveillance", - "surveillance:type=camera" - ], - "title": "Surveillance camera" - } - ], - "wayHandling": 2 + "icon": { + "render": "./assets/themes/surveillance/logo.svg", + "mappings": [ + { + "if": "camera:type=dome", + "then": "./assets/themes/surveillance/dome.svg" + }, + { + "if": "_direction:leftright=right", + "then": "./assets/themes/surveillance/cam_right.svg" + }, + { + "if": "_direction:leftright=left", + "then": "./assets/themes/surveillance/cam_left.svg" + } + ] + }, + "rotation": { + "#": "Note: {camera:direction} is substituted by a number, giving the string 'calc(123deg + 90deg)' ; it is this string that is used as css property, which interprets the calc", + "render": "calc({_direction:numerical}deg + 90deg)", + "mappings": [ + { + "if": "camera:type=dome", + "then": "0" + }, + { + "if": "_direction:leftright=right", + "then": "calc({_direction:numerical}deg - 90deg)" + } + ] + }, + "width": { + "render": "8" + }, + "iconSize": { + "mappings": [ + { + "if": "camera:type=dome", + "then": "50,50,center" + }, + { + "if": "_direction:leftright~*", + "then": "100,35,center" + } + ], + "render": "50,50,center" + }, + "color": { + "render": "#f00" + }, + "presets": [ + { + "tags": [ + "man_made=surveillance", + "surveillance:type=camera" + ], + "title": "Surveillance camera" + } + ], + "wayHandling": 2 } \ No newline at end of file diff --git a/assets/layers/toilet/toilet.json b/assets/layers/toilet/toilet.json index e70dc2b78..0963a1bab 100644 --- a/assets/layers/toilet/toilet.json +++ b/assets/layers/toilet/toilet.json @@ -1,405 +1,405 @@ { - "id": "toilet", - "name": { - "en": "Toilets", - "de": "Toiletten", - "fr": "Toilettes", - "nl": "Toiletten", - "ru": "Туалеты", - "it": "Servizi igienici" - }, - "minzoom": 12, - "source": { - "osmTags": "amenity=toilets" - }, - "title": { - "render": { - "en": "Toilet", - "de": "Toilette", - "fr": "Toilettes", - "nl": "Toilet", - "ru": "Туалет", - "it": "Servizi igienici" - } - }, - "icon": { - "render": "./assets/layers/toilet/toilets.svg", - "mappings": [ - { - "if": "wheelchair=yes", - "then": "./assets/layers/toilet/wheelchair.svg" - }, - { - "if": { - "or": [ - "toilets:position=urinals", - "toilets:position=urinal" - ] - }, - "then": "./assets/layers/toilet/urinal.svg" - } - ] - }, - "color": { - "render": "#0000ff" - }, - "wayHandling": 1, - "presets": [ - { - "title": { - "en": "Toilet", - "de": "Toilette", + "id": "toilet", + "name": { + "en": "Toilets", + "de": "Toiletten", "fr": "Toilettes", - "nl": "Toilet", - "ru": "Туалет", + "nl": "Toiletten", + "ru": "Туалеты", "it": "Servizi igienici" - }, - "tags": [ - "amenity=toilets" - ], - "description": { - "en": "A publicly accessible toilet or restroom", - "de": "Eine öffentlich zugängliche Toilette", - "fr": "Des toilettes", - "nl": "Een publieke toilet", - "it": "Servizi igienici aperti al pubblico", - "ru": "Туалет или комната отдыха со свободным доступом" - } }, - { - "title": { - "en": "Toilets with wheelchair accessible toilet", - "de": "Toiletten mit rollstuhlgerechter Toilette", - "fr": "Toilettes accessible aux personnes à mobilité réduite", - "nl": "Een rolstoeltoegankelijke toilet", - "it": "Servizi igienici accessibili per persone in sedia a rotelle", - "ru": "Туалет с доступом для пользователей кресел-колясок" - }, - "tags": [ - "amenity=toilets", - "wheelchair=yes" - ], - "description": { - "en": "A restroom which has at least one wheelchair-accessible toilet", - "de": "Eine Toilettenanlage mit mindestens einer rollstuhlgerechten Toilette", - "fr": "Toilettes avec au moins un WC accessible aux personnes à mobilité réduite", - "nl": "Deze toiletten hebben op zijn minst één rolstoeltoegankelijke WC", - "it": "Servizi igienici che hanno almeno una toilette accessibile a persone in sedia a rotelle" - } - } - ], - "tagRenderings": [ - "images", - { - "question": { - "en": "Are these toilets publicly accessible?", - "de": "Sind diese Toiletten öffentlich zugänglich?", - "fr": "Ces toilettes sont-elles accessibles au public ?", - "nl": "Zijn deze toiletten publiek toegankelijk?", - "it": "Questi servizi igienici sono aperti al pubblico?", - "ru": "Есть ли свободный доступ к этим туалетам?" - }, - "render": { - "en": "Access is {access}", - "de": "Zugang ist {access}", - "fr": "L'accès est {access}", - "nl": "Toegankelijkheid is {access}", - "it": "L'accesso è {access}" - }, - "freeform": { - "key": "access", - "addExtraTags": [ - "fixme=the tag access was filled out by the user and might need refinement" + "minzoom": 12, + "source": { + "osmTags": "amenity=toilets" + }, + "title": { + "render": { + "en": "Toilet", + "de": "Toilette", + "fr": "Toilettes", + "nl": "Toilet", + "ru": "Туалет", + "it": "Servizi igienici" + } + }, + "icon": { + "render": "./assets/layers/toilet/toilets.svg", + "mappings": [ + { + "if": "wheelchair=yes", + "then": "./assets/layers/toilet/wheelchair.svg" + }, + { + "if": { + "or": [ + "toilets:position=urinals", + "toilets:position=urinal" + ] + }, + "then": "./assets/layers/toilet/urinal.svg" + } ] - }, - "mappings": [ - { - "if": "access=yes", - "then": { - "en": "Public access", - "de": "Öffentlicher Zugang", - "fr": "Accès publique", - "nl": "Publiek toegankelijk", - "it": "Accesso pubblico", - "ru": "Свободный доступ" - } - }, - { - "if": "access=customers", - "then": { - "en": "Only access to customers", - "de": "Nur Zugang für Kunden", - "fr": "Accès réservé aux clients", - "nl": "Enkel toegang voor klanten", - "it": "Accesso riservato ai clienti e alle clienti" - } - }, - { - "if": "access=no", - "then": { - "en": "Not accessible", - "de": "Nicht zugänglich", - "fr": "Toilettes privées", - "nl": "Niet toegankelijk", - "ru": "Недоступно", - "it": "Non accessibile" - } - }, - { - "if": "access=key", - "then": { - "en": "Accessible, but one has to ask a key to enter", - "de": "Zugänglich, aber man muss einen Schlüssel für die Eingabe verlangen", - "fr": "Accessible, mais vous devez demander la clé", - "nl": "Toegankelijk na het vragen van de sleutel", - "it": "Accessibile, ma occorre chiedere una chiave per accedere" - } - }, - { - "if": "access=public", - "then": { - "en": "Public access", - "de": "Öffentlicher Zugang", - "fr": "Accès publique", - "nl": "Publiek toegankelijk", - "it": "Accesso pubblico", - "ru": "Свободный доступ" - }, - "hideInAnswer": true - } - ] }, - { - "question": { - "en": "Are these toilets free to use?", - "de": "Können diese Toiletten kostenlos benutzt werden?", - "fr": "Ces toilettes sont-elles payantes ?", - "nl": "Zijn deze toiletten gratis te gebruiken?", - "it": "Questi servizi igienici sono gratuiti?" - }, - "mappings": [ - { - "then": { - "en": "These are paid toilets", - "de": "Dies sind bezahlte Toiletten", - "fr": "Toilettes payantes", - "nl": "Men moet betalen om deze toiletten te gebruiken", - "ru": "Это платные туалеты", - "it": "Questi servizi igienici sono a pagamento" - }, - "if": "fee=yes" - }, - { - "if": "fee=no", - "then": { - "en": "Free to use", - "de": "Kostenlose Nutzung", - "fr": "Toilettes gratuites", - "nl": "Gratis te gebruiken", - "it": "Gratis" - } - } - ] + "color": { + "render": "#0000ff" }, - { - "question": { - "en": "How much does one have to pay for these toilets?", - "de": "Wie viel muss man für diese Toiletten bezahlen?", - "fr": "Quel est le prix d'accès de ces toilettes ?", - "nl": "Hoeveel moet men betalen om deze toiletten te gebruiken?", - "it": "Quanto costa l'accesso a questi servizi igienici?", - "ru": "Сколько стоит посещение туалета?" - }, - "render": { - "en": "The fee is {charge}", - "de": "Die Gebühr beträgt {charge}", - "fr": "Le prix est {charge}", - "nl": "De toiletten gebruiken kost {charge}", - "it": "La tariffa è {charge}", - "ru": "Стоимость {charge}" - }, - "condition": "fee=yes", - "freeform": { - "key": "charge", - "type": "string" - } - }, - { - "question": { - "en": "Is there a dedicated toilet for wheelchair users", - "de": "Gibt es eine Toilette für Rollstuhlfahrer?", - "fr": "Y a-t-il des toilettes réservées aux personnes en fauteuil roulant ?", - "nl": "Is er een rolstoeltoegankelijke toilet voorzien?", - "it": "C'è un WC riservato alle persone in sedia a rotelle" - }, - "mappings": [ + "wayHandling": 1, + "presets": [ { - "then": { - "en": "There is a dedicated toilet for wheelchair users", - "de": "Es gibt eine Toilette für Rollstuhlfahrer", - "fr": "Il y a des toilettes réservées pour les personnes à mobilité réduite", - "nl": "Er is een toilet voor rolstoelgebruikers", - "it": "C'è un WC riservato alle persone in sedia a rotelle" - }, - "if": "wheelchair=yes" + "title": { + "en": "Toilet", + "de": "Toilette", + "fr": "Toilettes", + "nl": "Toilet", + "ru": "Туалет", + "it": "Servizi igienici" + }, + "tags": [ + "amenity=toilets" + ], + "description": { + "en": "A publicly accessible toilet or restroom", + "de": "Eine öffentlich zugängliche Toilette", + "fr": "Des toilettes", + "nl": "Een publieke toilet", + "it": "Servizi igienici aperti al pubblico", + "ru": "Туалет или комната отдыха со свободным доступом" + } }, { - "if": "wheelchair=no", - "then": { - "en": "No wheelchair access", - "de": "Kein Zugang für Rollstuhlfahrer", - "fr": "Non accessible aux personnes à mobilité réduite", - "nl": "Niet toegankelijk voor rolstoelgebruikers", - "it": "Non accessibile in sedia a rotelle", - "ru": "Недоступно пользователям кресел-колясок" - } + "title": { + "en": "Toilets with wheelchair accessible toilet", + "de": "Toiletten mit rollstuhlgerechter Toilette", + "fr": "Toilettes accessible aux personnes à mobilité réduite", + "nl": "Een rolstoeltoegankelijke toilet", + "it": "Servizi igienici accessibili per persone in sedia a rotelle", + "ru": "Туалет с доступом для пользователей кресел-колясок" + }, + "tags": [ + "amenity=toilets", + "wheelchair=yes" + ], + "description": { + "en": "A restroom which has at least one wheelchair-accessible toilet", + "de": "Eine Toilettenanlage mit mindestens einer rollstuhlgerechten Toilette", + "fr": "Toilettes avec au moins un WC accessible aux personnes à mobilité réduite", + "nl": "Deze toiletten hebben op zijn minst één rolstoeltoegankelijke WC", + "it": "Servizi igienici che hanno almeno una toilette accessibile a persone in sedia a rotelle" + } } - ] - }, - { - "question": { - "en": "Which kind of toilets are this?", - "de": "Welche Art von Toiletten sind das?", - "fr": "De quel type sont ces toilettes ?", - "nl": "Welke toiletten zijn dit?", - "it": "Di che tipo di servizi igienici si tratta?", - "ru": "Какие это туалеты?" - }, - "mappings": [ + ], + "tagRenderings": [ + "images", { - "if": "toilets:position=seated", - "then": { - "en": "There are only seated toilets", - "de": "Es gibt nur Sitztoiletten", - "fr": "Il y a uniquement des sièges de toilettes", - "nl": "Er zijn enkel WC's om op te zitten", - "it": "Ci sono solo WC con sedile" - } + "question": { + "en": "Are these toilets publicly accessible?", + "de": "Sind diese Toiletten öffentlich zugänglich?", + "fr": "Ces toilettes sont-elles accessibles au public ?", + "nl": "Zijn deze toiletten publiek toegankelijk?", + "it": "Questi servizi igienici sono aperti al pubblico?", + "ru": "Есть ли свободный доступ к этим туалетам?" + }, + "render": { + "en": "Access is {access}", + "de": "Zugang ist {access}", + "fr": "L'accès est {access}", + "nl": "Toegankelijkheid is {access}", + "it": "L'accesso è {access}" + }, + "freeform": { + "key": "access", + "addExtraTags": [ + "fixme=the tag access was filled out by the user and might need refinement" + ] + }, + "mappings": [ + { + "if": "access=yes", + "then": { + "en": "Public access", + "de": "Öffentlicher Zugang", + "fr": "Accès publique", + "nl": "Publiek toegankelijk", + "it": "Accesso pubblico", + "ru": "Свободный доступ" + } + }, + { + "if": "access=customers", + "then": { + "en": "Only access to customers", + "de": "Nur Zugang für Kunden", + "fr": "Accès réservé aux clients", + "nl": "Enkel toegang voor klanten", + "it": "Accesso riservato ai clienti e alle clienti" + } + }, + { + "if": "access=no", + "then": { + "en": "Not accessible", + "de": "Nicht zugänglich", + "fr": "Toilettes privées", + "nl": "Niet toegankelijk", + "ru": "Недоступно", + "it": "Non accessibile" + } + }, + { + "if": "access=key", + "then": { + "en": "Accessible, but one has to ask a key to enter", + "de": "Zugänglich, aber man muss einen Schlüssel für die Eingabe verlangen", + "fr": "Accessible, mais vous devez demander la clé", + "nl": "Toegankelijk na het vragen van de sleutel", + "it": "Accessibile, ma occorre chiedere una chiave per accedere" + } + }, + { + "if": "access=public", + "then": { + "en": "Public access", + "de": "Öffentlicher Zugang", + "fr": "Accès publique", + "nl": "Publiek toegankelijk", + "it": "Accesso pubblico", + "ru": "Свободный доступ" + }, + "hideInAnswer": true + } + ] }, { - "if": "toilets:position=urinal", - "then": { - "en": "There are only urinals here", - "de": "Hier gibt es nur Pissoirs", - "fr": "Il y a uniquement des urinoirs", - "nl": "Er zijn enkel urinoirs", - "it": "Ci sono solo urinali" - } + "question": { + "en": "Are these toilets free to use?", + "de": "Können diese Toiletten kostenlos benutzt werden?", + "fr": "Ces toilettes sont-elles payantes ?", + "nl": "Zijn deze toiletten gratis te gebruiken?", + "it": "Questi servizi igienici sono gratuiti?" + }, + "mappings": [ + { + "then": { + "en": "These are paid toilets", + "de": "Dies sind bezahlte Toiletten", + "fr": "Toilettes payantes", + "nl": "Men moet betalen om deze toiletten te gebruiken", + "ru": "Это платные туалеты", + "it": "Questi servizi igienici sono a pagamento" + }, + "if": "fee=yes" + }, + { + "if": "fee=no", + "then": { + "en": "Free to use", + "de": "Kostenlose Nutzung", + "fr": "Toilettes gratuites", + "nl": "Gratis te gebruiken", + "it": "Gratis" + } + } + ] }, { - "if": "toilets:position=squat", - "then": { - "en": "There are only squat toilets here", - "de": "Es gibt hier nur Hocktoiletten", - "fr": "Il y a uniquement des toilettes turques", - "nl": "Er zijn enkel hurktoiletten", - "it": "Ci sono solo turche" - } + "question": { + "en": "How much does one have to pay for these toilets?", + "de": "Wie viel muss man für diese Toiletten bezahlen?", + "fr": "Quel est le prix d'accès de ces toilettes ?", + "nl": "Hoeveel moet men betalen om deze toiletten te gebruiken?", + "it": "Quanto costa l'accesso a questi servizi igienici?", + "ru": "Сколько стоит посещение туалета?" + }, + "render": { + "en": "The fee is {charge}", + "de": "Die Gebühr beträgt {charge}", + "fr": "Le prix est {charge}", + "nl": "De toiletten gebruiken kost {charge}", + "it": "La tariffa è {charge}", + "ru": "Стоимость {charge}" + }, + "condition": "fee=yes", + "freeform": { + "key": "charge", + "type": "string" + } }, { - "if": "toilets:position=seated;urinal", - "then": { - "en": "Both seated toilets and urinals are available here", - "de": "Sowohl Sitztoiletten als auch Pissoirs sind hier verfügbar", - "fr": "Il y a des sièges de toilettes et des urinoirs", - "nl": "Er zijn zowel urinoirs als zittoiletten", - "it": "Ci sono sia sedili, sia urinali" - } + "question": { + "en": "Is there a dedicated toilet for wheelchair users", + "de": "Gibt es eine Toilette für Rollstuhlfahrer?", + "fr": "Y a-t-il des toilettes réservées aux personnes en fauteuil roulant ?", + "nl": "Is er een rolstoeltoegankelijke toilet voorzien?", + "it": "C'è un WC riservato alle persone in sedia a rotelle" + }, + "mappings": [ + { + "then": { + "en": "There is a dedicated toilet for wheelchair users", + "de": "Es gibt eine Toilette für Rollstuhlfahrer", + "fr": "Il y a des toilettes réservées pour les personnes à mobilité réduite", + "nl": "Er is een toilet voor rolstoelgebruikers", + "it": "C'è un WC riservato alle persone in sedia a rotelle" + }, + "if": "wheelchair=yes" + }, + { + "if": "wheelchair=no", + "then": { + "en": "No wheelchair access", + "de": "Kein Zugang für Rollstuhlfahrer", + "fr": "Non accessible aux personnes à mobilité réduite", + "nl": "Niet toegankelijk voor rolstoelgebruikers", + "it": "Non accessibile in sedia a rotelle", + "ru": "Недоступно пользователям кресел-колясок" + } + } + ] + }, + { + "question": { + "en": "Which kind of toilets are this?", + "de": "Welche Art von Toiletten sind das?", + "fr": "De quel type sont ces toilettes ?", + "nl": "Welke toiletten zijn dit?", + "it": "Di che tipo di servizi igienici si tratta?", + "ru": "Какие это туалеты?" + }, + "mappings": [ + { + "if": "toilets:position=seated", + "then": { + "en": "There are only seated toilets", + "de": "Es gibt nur Sitztoiletten", + "fr": "Il y a uniquement des sièges de toilettes", + "nl": "Er zijn enkel WC's om op te zitten", + "it": "Ci sono solo WC con sedile" + } + }, + { + "if": "toilets:position=urinal", + "then": { + "en": "There are only urinals here", + "de": "Hier gibt es nur Pissoirs", + "fr": "Il y a uniquement des urinoirs", + "nl": "Er zijn enkel urinoirs", + "it": "Ci sono solo urinali" + } + }, + { + "if": "toilets:position=squat", + "then": { + "en": "There are only squat toilets here", + "de": "Es gibt hier nur Hocktoiletten", + "fr": "Il y a uniquement des toilettes turques", + "nl": "Er zijn enkel hurktoiletten", + "it": "Ci sono solo turche" + } + }, + { + "if": "toilets:position=seated;urinal", + "then": { + "en": "Both seated toilets and urinals are available here", + "de": "Sowohl Sitztoiletten als auch Pissoirs sind hier verfügbar", + "fr": "Il y a des sièges de toilettes et des urinoirs", + "nl": "Er zijn zowel urinoirs als zittoiletten", + "it": "Ci sono sia sedili, sia urinali" + } + } + ] + }, + { + "question": { + "en": "Is a changing table (to change diapers) available?", + "de": "Ist ein Wickeltisch (zum Wechseln der Windeln) vorhanden?", + "fr": "Ces toilettes disposent-elles d'une table à langer ?", + "nl": "Is er een luiertafel beschikbaar?", + "it": "È disponibile un fasciatoio (per cambiare i pannolini)?" + }, + "mappings": [ + { + "then": { + "en": "A changing table is available", + "de": "Ein Wickeltisch ist verfügbar", + "fr": "Une table à langer est disponible", + "nl": "Er is een luiertafel", + "it": "È disponibile un fasciatoio" + }, + "if": "changing_table=yes" + }, + { + "if": "changing_table=no", + "then": { + "en": "No changing table is available", + "de": "Es ist kein Wickeltisch verfügbar", + "fr": "Aucune table à langer", + "nl": "Geen luiertafel", + "it": "Non è disponibile un fasciatoio" + } + } + ] + }, + { + "question": { + "en": "Where is the changing table located?", + "de": "Wo befindet sich der Wickeltisch?", + "fr": "Où se situe la table à langer ?", + "nl": "Waar bevindt de luiertafel zich?", + "it": "Dove si trova il fasciatoio?" + }, + "render": { + "en": "The changing table is located at {changing_table:location}", + "de": "Die Wickeltabelle befindet sich in {changing_table:location}", + "fr": "Emplacement de la table à langer : {changing_table:location}", + "nl": "De luiertafel bevindt zich in {changing_table:location}", + "it": "Il fasciatoio si trova presso {changing_table:location}" + }, + "condition": "changing_table=yes", + "freeform": { + "key": "changing_table:location" + }, + "mappings": [ + { + "then": { + "en": "The changing table is in the toilet for women. ", + "de": "Der Wickeltisch befindet sich in der Damentoilette. ", + "fr": "La table à langer est dans les toilettes pour femmes. ", + "nl": "De luiertafel bevindt zich in de vrouwentoiletten ", + "it": "Il fasciatoio è nei servizi igienici femminili. " + }, + "if": "changing_table:location=female_toilet" + }, + { + "then": { + "en": "The changing table is in the toilet for men. ", + "de": "Der Wickeltisch befindet sich in der Herrentoilette. ", + "fr": "La table à langer est dans les toilettes pour hommes. ", + "nl": "De luiertafel bevindt zich in de herentoiletten ", + "it": "Il fasciatoio è nei servizi igienici maschili. " + }, + "if": "changing_table:location=male_toilet" + }, + { + "if": "changing_table:location=wheelchair_toilet", + "then": { + "en": "The changing table is in the toilet for wheelchair users. ", + "de": "Der Wickeltisch befindet sich in der Toilette für Rollstuhlfahrer. ", + "fr": "La table à langer est dans les toilettes pour personnes à mobilité réduite. ", + "nl": "De luiertafel bevindt zich in de rolstoeltoegankelijke toilet ", + "it": "Il fasciatoio è nei servizi igienici per persone in sedia a rotelle. " + } + }, + { + "if": "changing_table:location=dedicated_room", + "then": { + "en": "The changing table is in a dedicated room. ", + "de": "Der Wickeltisch befindet sich in einem eigenen Raum. ", + "fr": "La table à langer est dans un espace dédié. ", + "nl": "De luiertafel bevindt zich in een daartoe voorziene kamer ", + "it": "Il fasciatoio è in una stanza dedicata. " + } + } + ] } - ] - }, - { - "question": { - "en": "Is a changing table (to change diapers) available?", - "de": "Ist ein Wickeltisch (zum Wechseln der Windeln) vorhanden?", - "fr": "Ces toilettes disposent-elles d'une table à langer ?", - "nl": "Is er een luiertafel beschikbaar?", - "it": "È disponibile un fasciatoio (per cambiare i pannolini)?" - }, - "mappings": [ - { - "then": { - "en": "A changing table is available", - "de": "Ein Wickeltisch ist verfügbar", - "fr": "Une table à langer est disponible", - "nl": "Er is een luiertafel", - "it": "È disponibile un fasciatoio" - }, - "if": "changing_table=yes" - }, - { - "if": "changing_table=no", - "then": { - "en": "No changing table is available", - "de": "Es ist kein Wickeltisch verfügbar", - "fr": "Aucune table à langer", - "nl": "Geen luiertafel", - "it": "Non è disponibile un fasciatoio" - } - } - ] - }, - { - "question": { - "en": "Where is the changing table located?", - "de": "Wo befindet sich der Wickeltisch?", - "fr": "Où se situe la table à langer ?", - "nl": "Waar bevindt de luiertafel zich?", - "it": "Dove si trova il fasciatoio?" - }, - "render": { - "en": "The changing table is located at {changing_table:location}", - "de": "Die Wickeltabelle befindet sich in {changing_table:location}", - "fr": "Emplacement de la table à langer : {changing_table:location}", - "nl": "De luiertafel bevindt zich in {changing_table:location}", - "it": "Il fasciatoio si trova presso {changing_table:location}" - }, - "condition": "changing_table=yes", - "freeform": { - "key": "changing_table:location" - }, - "mappings": [ - { - "then": { - "en": "The changing table is in the toilet for women. ", - "de": "Der Wickeltisch befindet sich in der Damentoilette. ", - "fr": "La table à langer est dans les toilettes pour femmes. ", - "nl": "De luiertafel bevindt zich in de vrouwentoiletten ", - "it": "Il fasciatoio è nei servizi igienici femminili. " - }, - "if": "changing_table:location=female_toilet" - }, - { - "then": { - "en": "The changing table is in the toilet for men. ", - "de": "Der Wickeltisch befindet sich in der Herrentoilette. ", - "fr": "La table à langer est dans les toilettes pour hommes. ", - "nl": "De luiertafel bevindt zich in de herentoiletten ", - "it": "Il fasciatoio è nei servizi igienici maschili. " - }, - "if": "changing_table:location=male_toilet" - }, - { - "if": "changing_table:location=wheelchair_toilet", - "then": { - "en": "The changing table is in the toilet for wheelchair users. ", - "de": "Der Wickeltisch befindet sich in der Toilette für Rollstuhlfahrer. ", - "fr": "La table à langer est dans les toilettes pour personnes à mobilité réduite. ", - "nl": "De luiertafel bevindt zich in de rolstoeltoegankelijke toilet ", - "it": "Il fasciatoio è nei servizi igienici per persone in sedia a rotelle. " - } - }, - { - "if": "changing_table:location=dedicated_room", - "then": { - "en": "The changing table is in a dedicated room. ", - "de": "Der Wickeltisch befindet sich in einem eigenen Raum. ", - "fr": "La table à langer est dans un espace dédié. ", - "nl": "De luiertafel bevindt zich in een daartoe voorziene kamer ", - "it": "Il fasciatoio è in una stanza dedicata. " - } - } - ] - } - ] + ] } \ No newline at end of file diff --git a/assets/layers/trail/trail.json b/assets/layers/trail/trail.json index 4638de35e..c2c43c48b 100644 --- a/assets/layers/trail/trail.json +++ b/assets/layers/trail/trail.json @@ -1,207 +1,207 @@ { - "id": "trail", - "name": { - "en": "Trails", - "nl": "Wandeltochten" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - { - "or": [ - "route=hiking", - "route=bycicle", - "route=horse" - ] - } - ] - } - }, - "title": { - "render": { - "en": "Trail", - "nl": "Wandeltocht" + "id": "trail", + "name": { + "en": "Trails", + "nl": "Wandeltochten" }, - "mappings": [ - { - "if": "name~*", - "then": "{name}" - } - ] - }, - "tagRenderings": [ - "images", - { - "render": { - "en": "The trail is {_length:km} kilometers long", - "nl": "Deze wandeling is {_length:km} kilometer lang" - } - }, - { - "#": "Name", - "question": { - "nl": "Wat is de naam van deze wandeling?" - }, - "render": { - "nl": "Deze wandeling heet {name}" - }, - "freeform": { - "key": "name" - } - }, - { - "#": "Operator tag", - "render": { - "nl": "Beheer door {operator}" - }, - "question": { - "nl": "Wie beheert deze wandeltocht?" - }, - "freeform": { - "key": "operator" - }, - "mappings": [ - { - "if": { + "minzoom": 12, + "source": { + "osmTags": { "and": [ - "operator=Natuurpunt" + { + "or": [ + "route=hiking", + "route=bycicle", + "route=horse" + ] + } ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door Natuurpunt" - } + } + }, + "title": { + "render": { + "en": "Trail", + "nl": "Wandeltocht" + }, + "mappings": [ + { + "if": "name~*", + "then": "{name}" + } + ] + }, + "tagRenderings": [ + "images", + { + "render": { + "en": "The trail is {_length:km} kilometers long", + "nl": "Deze wandeling is {_length:km} kilometer lang" + } }, { - "if": { - "and": [ - "operator~(n|N)atuurpunt.*" + "#": "Name", + "question": { + "nl": "Wat is de naam van deze wandeling?" + }, + "render": { + "nl": "Deze wandeling heet {name}" + }, + "freeform": { + "key": "name" + } + }, + { + "#": "Operator tag", + "render": { + "nl": "Beheer door {operator}" + }, + "question": { + "nl": "Wie beheert deze wandeltocht?" + }, + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": { + "and": [ + "operator=Natuurpunt" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door Natuurpunt" + } + }, + { + "if": { + "and": [ + "operator~(n|N)atuurpunt.*" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door {operator}" + }, + "hideInAnswer": true + } + ] + }, + { + "#": "Color", + "question": { + "nl": "Welke kleur heeft deze wandeling?" + }, + "render": { + "nl": "Deze wandeling heeft kleur {colour}" + }, + "freeform": { + "key": "colour", + "type": "color" + }, + "mappings": [ + { + "if": "colour=blue", + "then": { + "nl": "Blauwe wandeling", + "en": "Blue trail" + } + }, + { + "if": "colour=red", + "then": { + "nl": "Rode wandeling", + "en": "Red trail" + } + }, + { + "if": "colour=green", + "then": { + "nl": "Groene wandeling", + "en": "Green trail" + } + }, + { + "if": "colour=yellow", + "then": { + "nl": "Gele wandeling", + "en": "Yellow trail" + } + } + ] + }, + { + "#": "Wheelchair access", + "question": { + "nl": "Is deze wandeling toegankelijk met de rolstoel?" + }, + "mappings": [ + { + "then": { + "nl": "deze wandeltocht is toegankelijk met de rolstoel" + }, + "if": "wheelchair=yes" + }, + { + "then": { + "nl": "deze wandeltocht is niet toegankelijk met de rolstoel" + }, + "if": "wheelchair=no" + } + ] + }, + { + "#": "pushchair access", + "question": { + "nl": "Is deze wandeltocht toegankelijk met de buggy?" + }, + "mappings": [ + { + "then": { + "nl": "deze wandeltocht is toegankelijk met de buggy" + }, + "if": "pushchair=yes" + }, + { + "then": { + "nl": "deze wandeltocht is niet toegankelijk met de buggy" + }, + "if": "pushchair=no" + } ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door {operator}" - }, - "hideInAnswer": true } - ] + ], + "icon": { + "render": "./assets/layers/trail/trail.svg", + "mappings": [ + { + "if": "wheelchair=yes", + "then": "./assets/layers/trail/wheelchair.svg" + }, + { + "if": "pushchair=yes", + "then": "./assets/layers/trail/pushchair.svg" + } + ] }, - { - "#": "Color", - "question": { - "nl": "Welke kleur heeft deze wandeling?" - }, - "render": { - "nl": "Deze wandeling heeft kleur {colour}" - }, - "freeform": { - "key": "colour", - "type": "color" - }, - "mappings": [ - { - "if": "colour=blue", - "then": { - "nl": "Blauwe wandeling", - "en": "Blue trail" - } - }, - { - "if": "colour=red", - "then": { - "nl": "Rode wandeling", - "en": "Red trail" - } - }, - { - "if": "colour=green", - "then": { - "nl": "Groene wandeling", - "en": "Green trail" - } - }, - { - "if": "colour=yellow", - "then": { - "nl": "Gele wandeling", - "en": "Yellow trail" - } - } - ] + "description": { + "nl": "Aangeduide wandeltochten" }, - { - "#": "Wheelchair access", - "question": { - "nl": "Is deze wandeling toegankelijk met de rolstoel?" - }, - "mappings": [ - { - "then": { - "nl": "deze wandeltocht is toegankelijk met de rolstoel" - }, - "if": "wheelchair=yes" - }, - { - "then": { - "nl": "deze wandeltocht is niet toegankelijk met de rolstoel" - }, - "if": "wheelchair=no" - } - ] + "wayHandling": 0, + "width": { + "render": "3" }, - { - "#": "pushchair access", - "question": { - "nl": "Is deze wandeltocht toegankelijk met de buggy?" - }, - "mappings": [ - { - "then": { - "nl": "deze wandeltocht is toegankelijk met de buggy" - }, - "if": "pushchair=yes" - }, - { - "then": { - "nl": "deze wandeltocht is niet toegankelijk met de buggy" - }, - "if": "pushchair=no" - } - ] + "iconSize": { + "render": "35,35,center" + }, + "color": { + "render": "#335D9F", + "mappings": [ + { + "if": "colour~*", + "then": "{colour}" + } + ] + }, + "dashArray": { + "render": "5 5" } - ], - "icon": { - "render": "./assets/layers/trail/trail.svg", - "mappings": [ - { - "if": "wheelchair=yes", - "then": "./assets/layers/trail/wheelchair.svg" - }, - { - "if": "pushchair=yes", - "then": "./assets/layers/trail/pushchair.svg" - } - ] - }, - "description": { - "nl": "Aangeduide wandeltochten" - }, - "wayHandling": 0, - "width": { - "render": "3" - }, - "iconSize": { - "render": "35,35,center" - }, - "color": { - "render": "#335D9F", - "mappings": [ - { - "if": "colour~*", - "then": "{colour}" - } - ] - }, - "dashArray": { - "render": "5 5" - } } \ No newline at end of file diff --git a/assets/layers/tree_node/tree_node.json b/assets/layers/tree_node/tree_node.json index 31e348441..3ae7384d6 100644 --- a/assets/layers/tree_node/tree_node.json +++ b/assets/layers/tree_node/tree_node.json @@ -1,559 +1,559 @@ { - "id": "tree_node", - "name": { - "nl": "Boom", - "en": "Tree", - "it": "Albero", - "ru": "Дерево", - "fr": "Arbre" - }, - "minzoom": 14, - "source": { - "osmTags": { - "and": [ - "natural=tree" - ] - } - }, - "title": { - "render": { - "nl": "Boom", - "en": "Tree", - "it": "Albero", - "ru": "Дерево", - "fr": "Arbre" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "nl": "{name}", - "en": "{name}", - "ca": "{name}", - "de": "{name}", - "fr": "{name}", - "it": "{name}", - "ru": "{name}", - "id": "{name}" - } - } - ] - }, - "tagRenderings": [ - "images", - { - "render": { - "nl": "Hoogte: {height}", - "en": "Height: {height}", - "it": "Altezza: {height}", - "ru": "Высота: {height}", - "fr": "Hauteur : {height}" - }, - "condition": { - "and": [ - "height~*" - ] - }, - "mappings": [ - { - "if": { - "and": [ - "height~^[0-9.]+$" - ] - }, - "then": { - "nl": "Hoogte: {height} m", - "en": "Height: {height} m", - "it": "Altezza: {height} m", - "ru": "Высота: {height} м", - "fr": "Hauteur : {height} m" - } - } - ] - }, - { - "question": { - "nl": "Is dit een naald- of loofboom?", - "en": "Is this a broadleaved or needleleaved tree?", - "it": "Si tratta di un albero latifoglia o aghifoglia?", - "fr": "Cet arbre est-il un feuillu ou un résineux ?" - }, - "mappings": [ - { - "if": { - "and": [ - "leaf_type=broadleaved" - ] - }, - "then": { - "nl": "\"\"/ Loofboom", - "en": "\"\"/ Broadleaved", - "it": "\"\"/ Latifoglia", - "fr": "\"\"/ Feuillu" - } - }, - { - "if": { - "and": [ - "leaf_type=needleleaved" - ] - }, - "then": { - "nl": "\"\"/ Naaldboom", - "en": "\"\"/ Needleleaved", - "it": "\"\"/ Aghifoglia", - "fr": "\"\"/ Résineux" - } - }, - { - "if": { - "and": [ - "leaf_type=leafless" - ] - }, - "then": { - "nl": "\"\"/ Permanent bladloos", - "en": "\"\"/ Permanently leafless", - "it": "\"\"/ Privo di foglie (permanente)", - "fr": "\"\"/ Sans feuilles (Permanent)" - }, - "hideInAnswer": true - } - ] - }, - { - "question": { - "nl": "Hoe significant is deze boom? Kies het eerste antwoord dat van toepassing is.", - "en": "How significant is this tree? Choose the first answer that applies.", - "it": "Quanto significativo è questo albero? Scegli la prima risposta che corrisponde.", - "fr": "Quelle est l'importance de cet arbre ? Choisissez la première réponse qui s'applique." - }, - "mappings": [ - { - "if": { - "and": [ - "denotation=landmark" - ] - }, - "then": { - "nl": "De boom valt op door zijn grootte of prominente locatie. Hij is nuttig voor navigatie.", - "en": "The tree is remarkable due to its size or prominent location. It is useful for navigation.", - "it": "È un albero notevole per le sue dimensioni o per la posizione prominente. È utile alla navigazione.", - "fr": "L'arbre est remarquable en raison de sa taille ou de son emplacement proéminent. Il est utile pour la navigation." - } - }, - { - "if": { - "and": [ - "denotation=natural_monument" - ] - }, - "then": { - "nl": "De boom is een natuurlijk monument, bijvoorbeeld doordat hij bijzonder oud of van een waardevolle soort is.", - "en": "The tree is a natural monument, e.g. because it is especially old, or of a valuable species.", - "it": "L’albero è un monumento naturale, ad esempio perché specialmente antico o appartenente a specie importanti.", - "fr": "Cet arbre est un monument naturel (ex : âge, espèce, etc…)" - } - }, - { - "if": { - "and": [ - "denotation=agricultural" - ] - }, - "then": { - "nl": "De boom wordt voor landbouwdoeleinden gebruikt, bijvoorbeeld in een boomgaard.", - "en": "The tree is used for agricultural purposes, e.g. in an orchard.", - "it": "L’albero è usato per scopi agricoli, ad esempio in un frutteto.", - "fr": "Cet arbre est utilisé à but d’agriculture (ex : dans un verger)" - } - }, - { - "if": { - "and": [ - "denotation=park" - ] - }, - "then": { - "nl": "De boom staat in een park of dergelijke (begraafplaats, schoolterrein, …).", - "en": "The tree is in a park or similar (cemetery, school grounds, …).", - "it": "L’albero è in un parco o qualcosa di simile (cimitero, aree didattiche, etc.).", - "fr": "Cet arbre est dans un parc ou une aire similaire (ex : cimetière, cour d’école, …)." - } - }, - { - "if": { - "and": [ - "denotation=garden" - ] - }, - "then": { - "nl": "De boom staat in de tuin bij een woning/flatgebouw.", - "en": "The tree is a residential garden.", - "it": "L’albero è un giardino residenziale.", - "fr": "Cet arbre est dans une cour résidentielle." - } - }, - { - "if": { - "and": [ - "denotation=avenue" - ] - }, - "then": { - "nl": "Dit is een laanboom.", - "en": "This is a tree along an avenue.", - "it": "Fa parte di un viale alberato.", - "fr": "C'est un arbre le long d'une avenue." - } - }, - { - "if": { - "and": [ - "denotation=urban" - ] - }, - "then": { - "nl": "De boom staat in een woonkern.", - "en": "The tree is an urban area.", - "it": "L’albero si trova in un’area urbana.", - "fr": "L'arbre est une zone urbaine." - } - }, - { - "if": { - "and": [ - "denotation=none" - ] - }, - "then": { - "nl": "De boom staat buiten een woonkern.", - "en": "The tree is outside of an urban area.", - "it": "L’albero si trova fuori dall’area urbana.", - "fr": "Cet arbre est en zone rurale." - } - } - ] - }, - { - "question": { - "nl": "Is deze boom groenblijvend of bladverliezend?", - "en": "Is this tree evergreen or deciduous?", - "it": "È un sempreverde o caduco?", - "ru": "Это дерево вечнозелёное или листопадное?", - "fr": "L’arbre est-il à feuillage persistant ou caduc ?" - }, - "mappings": [ - { - "if": { - "and": [ - "leaf_cycle=deciduous" - ] - }, - "then": { - "nl": "Bladverliezend: de boom is een periode van het jaar kaal.", - "en": "Deciduous: the tree loses its leaves for some time of the year.", - "it": "Caduco: l’albero perde le sue foglie per un periodo dell’anno.", - "ru": "Листопадное: у дерева опадают листья в определённое время года.", - "fr": "Caduc : l’arbre perd son feuillage une partie de l’année." - } - }, - { - "if": { - "and": [ - "leaf_cycle=evergreen" - ] - }, - "then": { - "nl": "Groenblijvend.", - "en": "Evergreen.", - "it": "Sempreverde.", - "fr": "À feuilles persistantes.", - "ru": "Вечнозелёное." - } - } - ], - "condition": { - "and": [ - "leaf_type!~^leafless$" - ] - } - }, - { - "render": { - "nl": "Naam: {name}", - "en": "Name: {name}", - "it": "Nome: {name}", - "ru": "Название: {name}", - "fr": "Nom : {name}", - "id": "Nama: {name}" - }, - "question": { - "nl": "Heeft de boom een naam?", - "en": "Does the tree have a name?", - "it": "L’albero ha un nome?", - "fr": "L'arbre a-t-il un nom ?", - "ru": "Есть ли у этого дерева название?" - }, - "freeform": { - "key": "name", - "addExtraTags": [ - "noname=" - ] - }, - "mappings": [ - { - "if": { - "and": [ - "name=", - "noname=yes" - ] - }, - "then": { - "nl": "De boom heeft geen naam.", - "en": "The tree does not have a name.", - "it": "L’albero non ha un nome.", - "fr": "L'arbre n'a pas de nom.", - "ru": "У этого дерева нет названия." - } - } - ], - "condition": { - "or": [ - "denotation=landmark", - "denotation=natural_monument", - "name~*" - ] - } - }, - { - "question": { - "nl": "Is deze boom erkend als erfgoed?", - "en": "Is this tree registered heritage?", - "it": "Quest’albero è registrato come patrimonio?", - "fr": "Cet arbre est-il inscrit au patrimoine ?" - }, - "mappings": [ - { - "if": { - "and": [ - "heritage=4", - "heritage:operator=OnroerendErfgoed" - ] - }, - "then": { - "nl": "\"\"/ Erkend als houtig erfgoed door Onroerend Erfgoed Vlaanderen", - "en": "\"\"/ Registered as heritage by Onroerend Erfgoed Flanders", - "it": "\"\"/Registrato come patrimonio da Onroerend Erfgoed Flanders", - "fr": "\"\"/ Fait partie du patrimoine par Onroerend Erfgoed" - } - }, - { - "if": { - "and": [ - "heritage=4", - "heritage:operator=aatl" - ] - }, - "then": { - "nl": "Erkend als natuurlijk erfgoed door Directie Cultureel Erfgoed Brussel", - "en": "Registered as heritage by Direction du Patrimoine culturel Brussels", - "it": "Registrato come patrimonio da Direction du Patrimoine culturel di Bruxelles", - "fr": "Enregistré comme patrimoine par la Direction du Patrimoine culturel Bruxelles" - } - }, - { - "if": { - "and": [ - "heritage=yes", - "heritage:operator=" - ] - }, - "then": { - "nl": "Erkend als erfgoed door een andere organisatie", - "en": "Registered as heritage by a different organisation", - "it": "Registrato come patrimonio da un’organizzazione differente", - "fr": "Enregistré comme patrimoine par une autre organisation" - } - }, - { - "if": { - "and": [ - "heritage=no", - "heritage:operator=" - ] - }, - "then": { - "nl": "Niet erkend als erfgoed", - "en": "Not registered as heritage", - "it": "Non è registrato come patrimonio", - "fr": "Non enregistré comme patrimoine" - } - }, - { - "if": { - "and": [ - "heritage~*" - ] - }, - "then": { - "nl": "Erkend als erfgoed door een andere organisatie", - "en": "Registered as heritage by a different organisation", - "it": "Registrato come patrimonio da un’organizzazione differente", - "fr": "Enregistré comme patrimoine par une autre organisation" - }, - "hideInAnswer": true - } - ], - "condition": { - "or": [ - "denotation=landmark", - "denotation=natural_monument" - ] - } - }, - { - "render": { - "nl": "\"\"/ Onroerend Erfgoed-ID: {ref:OnroerendErfgoed}", - "en": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", - "it": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", - "ru": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", - "fr": "\"\"/ Identifiant Onroerend Erfgoed : {ref:OnroerendErfgoed}" - }, - "question": { - "nl": "Wat is het ID uitgegeven door Onroerend Erfgoed Vlaanderen?", - "en": "What is the ID issued by Onroerend Erfgoed Flanders?", - "it": "Qual è l’ID rilasciato da Onroerend Erfgoed Flanders?", - "fr": "Quel est son identifiant donné par Onroerend Erfgoed ?" - }, - "freeform": { - "key": "ref:OnroerendErfgoed", - "type": "nat" - }, - "condition": { - "and": [ - "heritage=4", - "heritage:operator=OnroerendErfgoed" - ] - } - }, - { - "render": { - "nl": "\"\"/ Wikidata: {wikidata}", - "en": "\"\"/ Wikidata: {wikidata}", - "it": "\"\"/ Wikidata: {wikidata}", - "ru": "\"\"/ Wikidata: {wikidata}", - "fr": "\"\"/ Wikidata : {wikidata}" - }, - "question": { - "nl": "Wat is het Wikidata-ID van deze boom?", - "en": "What is the Wikidata ID for this tree?", - "it": "Qual è l’ID Wikidata per questo albero?", - "fr": "Quel est l'identifiant Wikidata de cet arbre ?" - }, - "freeform": { - "key": "wikidata", - "type": "wikidata" - }, - "condition": { - "or": [ - "denotation=landmark", - "denotation=natural_monument", - "wikidata~*" - ] - } - } - ], - "icon": { - "render": "circle:#ffffff;./assets/themes/trees/unknown.svg", - "mappings": [ - { - "if": { - "and": [ - "leaf_type=broadleaved" - ] - }, - "then": "circle:#ffffff;./assets/themes/trees/broadleaved.svg" - }, - { - "if": { - "and": [ - "leaf_type=needleleaved" - ] - }, - "then": "circle:#ffffff;./assets/themes/trees/needleleaved.svg" - } - ] - }, - "wayHandling": 1, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,bottom" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "natural=tree", - "leaf_type=broadleaved" - ], - "title": { - "nl": "Loofboom", - "en": "Broadleaved tree", - "it": "Albero latifoglia", - "fr": "Arbre feuillu", - "ru": "Лиственное дерево" - }, - "description": { - "nl": "Een boom van een soort die blaadjes heeft, bijvoorbeeld eik of populier.", - "en": "A tree of a species with leaves, such as oak or populus.", - "it": "Un albero di una specie con foglie larghe come la quercia o il pioppo.", - "fr": "Un arbre d'une espèce avec de larges feuilles, comme le chêne ou le peuplier." - } - }, - { - "tags": [ - "natural=tree", - "leaf_type=needleleaved" - ], - "title": { - "nl": "Naaldboom", - "en": "Needleleaved tree", - "it": "Albero aghifoglia", - "ru": "Хвойное дерево", - "fr": "Arbre résineux" - }, - "description": { - "nl": "Een boom van een soort met naalden, bijvoorbeeld den of spar.", - "en": "A tree of a species with needles, such as pine or spruce.", - "it": "Un albero di una specie con aghi come il pino o l’abete.", - "ru": "Дерево с хвоей (иглами), например, сосна или ель.", - "fr": "Une espèce d’arbre avec des épines comme le pin ou l’épicéa." - } - }, - { - "tags": [ - "natural=tree" - ], - "title": { + "id": "tree_node", + "name": { "nl": "Boom", "en": "Tree", "it": "Albero", "ru": "Дерево", - "fr": "Arbre", - "id": "Pohon" - }, - "description": { - "nl": "Wanneer je niet zeker bent of het nu een loof- of naaldboom is.", - "en": "If you're not sure whether it's a broadleaved or needleleaved tree.", - "it": "Qualora non si sia sicuri se si tratta di un albero latifoglia o aghifoglia.", - "fr": "Si vous n'êtes pas sûr(e) de savoir s'il s'agit d'un arbre à feuilles larges ou à aiguilles.", - "ru": "Если вы не уверены в том, лиственное это дерево или хвойное." - } - } - ] + "fr": "Arbre" + }, + "minzoom": 14, + "source": { + "osmTags": { + "and": [ + "natural=tree" + ] + } + }, + "title": { + "render": { + "nl": "Boom", + "en": "Tree", + "it": "Albero", + "ru": "Дерево", + "fr": "Arbre" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "nl": "{name}", + "en": "{name}", + "ca": "{name}", + "de": "{name}", + "fr": "{name}", + "it": "{name}", + "ru": "{name}", + "id": "{name}" + } + } + ] + }, + "tagRenderings": [ + "images", + { + "render": { + "nl": "Hoogte: {height}", + "en": "Height: {height}", + "it": "Altezza: {height}", + "ru": "Высота: {height}", + "fr": "Hauteur : {height}" + }, + "condition": { + "and": [ + "height~*" + ] + }, + "mappings": [ + { + "if": { + "and": [ + "height~^[0-9.]+$" + ] + }, + "then": { + "nl": "Hoogte: {height} m", + "en": "Height: {height} m", + "it": "Altezza: {height} m", + "ru": "Высота: {height} м", + "fr": "Hauteur : {height} m" + } + } + ] + }, + { + "question": { + "nl": "Is dit een naald- of loofboom?", + "en": "Is this a broadleaved or needleleaved tree?", + "it": "Si tratta di un albero latifoglia o aghifoglia?", + "fr": "Cet arbre est-il un feuillu ou un résineux ?" + }, + "mappings": [ + { + "if": { + "and": [ + "leaf_type=broadleaved" + ] + }, + "then": { + "nl": "\"\"/ Loofboom", + "en": "\"\"/ Broadleaved", + "it": "\"\"/ Latifoglia", + "fr": "\"\"/ Feuillu" + } + }, + { + "if": { + "and": [ + "leaf_type=needleleaved" + ] + }, + "then": { + "nl": "\"\"/ Naaldboom", + "en": "\"\"/ Needleleaved", + "it": "\"\"/ Aghifoglia", + "fr": "\"\"/ Résineux" + } + }, + { + "if": { + "and": [ + "leaf_type=leafless" + ] + }, + "then": { + "nl": "\"\"/ Permanent bladloos", + "en": "\"\"/ Permanently leafless", + "it": "\"\"/ Privo di foglie (permanente)", + "fr": "\"\"/ Sans feuilles (Permanent)" + }, + "hideInAnswer": true + } + ] + }, + { + "question": { + "nl": "Hoe significant is deze boom? Kies het eerste antwoord dat van toepassing is.", + "en": "How significant is this tree? Choose the first answer that applies.", + "it": "Quanto significativo è questo albero? Scegli la prima risposta che corrisponde.", + "fr": "Quelle est l'importance de cet arbre ? Choisissez la première réponse qui s'applique." + }, + "mappings": [ + { + "if": { + "and": [ + "denotation=landmark" + ] + }, + "then": { + "nl": "De boom valt op door zijn grootte of prominente locatie. Hij is nuttig voor navigatie.", + "en": "The tree is remarkable due to its size or prominent location. It is useful for navigation.", + "it": "È un albero notevole per le sue dimensioni o per la posizione prominente. È utile alla navigazione.", + "fr": "L'arbre est remarquable en raison de sa taille ou de son emplacement proéminent. Il est utile pour la navigation." + } + }, + { + "if": { + "and": [ + "denotation=natural_monument" + ] + }, + "then": { + "nl": "De boom is een natuurlijk monument, bijvoorbeeld doordat hij bijzonder oud of van een waardevolle soort is.", + "en": "The tree is a natural monument, e.g. because it is especially old, or of a valuable species.", + "it": "L’albero è un monumento naturale, ad esempio perché specialmente antico o appartenente a specie importanti.", + "fr": "Cet arbre est un monument naturel (ex : âge, espèce, etc…)" + } + }, + { + "if": { + "and": [ + "denotation=agricultural" + ] + }, + "then": { + "nl": "De boom wordt voor landbouwdoeleinden gebruikt, bijvoorbeeld in een boomgaard.", + "en": "The tree is used for agricultural purposes, e.g. in an orchard.", + "it": "L’albero è usato per scopi agricoli, ad esempio in un frutteto.", + "fr": "Cet arbre est utilisé à but d’agriculture (ex : dans un verger)" + } + }, + { + "if": { + "and": [ + "denotation=park" + ] + }, + "then": { + "nl": "De boom staat in een park of dergelijke (begraafplaats, schoolterrein, …).", + "en": "The tree is in a park or similar (cemetery, school grounds, …).", + "it": "L’albero è in un parco o qualcosa di simile (cimitero, aree didattiche, etc.).", + "fr": "Cet arbre est dans un parc ou une aire similaire (ex : cimetière, cour d’école, …)." + } + }, + { + "if": { + "and": [ + "denotation=garden" + ] + }, + "then": { + "nl": "De boom staat in de tuin bij een woning/flatgebouw.", + "en": "The tree is a residential garden.", + "it": "L’albero è un giardino residenziale.", + "fr": "Cet arbre est dans une cour résidentielle." + } + }, + { + "if": { + "and": [ + "denotation=avenue" + ] + }, + "then": { + "nl": "Dit is een laanboom.", + "en": "This is a tree along an avenue.", + "it": "Fa parte di un viale alberato.", + "fr": "C'est un arbre le long d'une avenue." + } + }, + { + "if": { + "and": [ + "denotation=urban" + ] + }, + "then": { + "nl": "De boom staat in een woonkern.", + "en": "The tree is an urban area.", + "it": "L’albero si trova in un’area urbana.", + "fr": "L'arbre est une zone urbaine." + } + }, + { + "if": { + "and": [ + "denotation=none" + ] + }, + "then": { + "nl": "De boom staat buiten een woonkern.", + "en": "The tree is outside of an urban area.", + "it": "L’albero si trova fuori dall’area urbana.", + "fr": "Cet arbre est en zone rurale." + } + } + ] + }, + { + "question": { + "nl": "Is deze boom groenblijvend of bladverliezend?", + "en": "Is this tree evergreen or deciduous?", + "it": "È un sempreverde o caduco?", + "ru": "Это дерево вечнозелёное или листопадное?", + "fr": "L’arbre est-il à feuillage persistant ou caduc ?" + }, + "mappings": [ + { + "if": { + "and": [ + "leaf_cycle=deciduous" + ] + }, + "then": { + "nl": "Bladverliezend: de boom is een periode van het jaar kaal.", + "en": "Deciduous: the tree loses its leaves for some time of the year.", + "it": "Caduco: l’albero perde le sue foglie per un periodo dell’anno.", + "ru": "Листопадное: у дерева опадают листья в определённое время года.", + "fr": "Caduc : l’arbre perd son feuillage une partie de l’année." + } + }, + { + "if": { + "and": [ + "leaf_cycle=evergreen" + ] + }, + "then": { + "nl": "Groenblijvend.", + "en": "Evergreen.", + "it": "Sempreverde.", + "fr": "À feuilles persistantes.", + "ru": "Вечнозелёное." + } + } + ], + "condition": { + "and": [ + "leaf_type!~^leafless$" + ] + } + }, + { + "render": { + "nl": "Naam: {name}", + "en": "Name: {name}", + "it": "Nome: {name}", + "ru": "Название: {name}", + "fr": "Nom : {name}", + "id": "Nama: {name}" + }, + "question": { + "nl": "Heeft de boom een naam?", + "en": "Does the tree have a name?", + "it": "L’albero ha un nome?", + "fr": "L'arbre a-t-il un nom ?", + "ru": "Есть ли у этого дерева название?" + }, + "freeform": { + "key": "name", + "addExtraTags": [ + "noname=" + ] + }, + "mappings": [ + { + "if": { + "and": [ + "name=", + "noname=yes" + ] + }, + "then": { + "nl": "De boom heeft geen naam.", + "en": "The tree does not have a name.", + "it": "L’albero non ha un nome.", + "fr": "L'arbre n'a pas de nom.", + "ru": "У этого дерева нет названия." + } + } + ], + "condition": { + "or": [ + "denotation=landmark", + "denotation=natural_monument", + "name~*" + ] + } + }, + { + "question": { + "nl": "Is deze boom erkend als erfgoed?", + "en": "Is this tree registered heritage?", + "it": "Quest’albero è registrato come patrimonio?", + "fr": "Cet arbre est-il inscrit au patrimoine ?" + }, + "mappings": [ + { + "if": { + "and": [ + "heritage=4", + "heritage:operator=OnroerendErfgoed" + ] + }, + "then": { + "nl": "\"\"/ Erkend als houtig erfgoed door Onroerend Erfgoed Vlaanderen", + "en": "\"\"/ Registered as heritage by Onroerend Erfgoed Flanders", + "it": "\"\"/Registrato come patrimonio da Onroerend Erfgoed Flanders", + "fr": "\"\"/ Fait partie du patrimoine par Onroerend Erfgoed" + } + }, + { + "if": { + "and": [ + "heritage=4", + "heritage:operator=aatl" + ] + }, + "then": { + "nl": "Erkend als natuurlijk erfgoed door Directie Cultureel Erfgoed Brussel", + "en": "Registered as heritage by Direction du Patrimoine culturel Brussels", + "it": "Registrato come patrimonio da Direction du Patrimoine culturel di Bruxelles", + "fr": "Enregistré comme patrimoine par la Direction du Patrimoine culturel Bruxelles" + } + }, + { + "if": { + "and": [ + "heritage=yes", + "heritage:operator=" + ] + }, + "then": { + "nl": "Erkend als erfgoed door een andere organisatie", + "en": "Registered as heritage by a different organisation", + "it": "Registrato come patrimonio da un’organizzazione differente", + "fr": "Enregistré comme patrimoine par une autre organisation" + } + }, + { + "if": { + "and": [ + "heritage=no", + "heritage:operator=" + ] + }, + "then": { + "nl": "Niet erkend als erfgoed", + "en": "Not registered as heritage", + "it": "Non è registrato come patrimonio", + "fr": "Non enregistré comme patrimoine" + } + }, + { + "if": { + "and": [ + "heritage~*" + ] + }, + "then": { + "nl": "Erkend als erfgoed door een andere organisatie", + "en": "Registered as heritage by a different organisation", + "it": "Registrato come patrimonio da un’organizzazione differente", + "fr": "Enregistré comme patrimoine par une autre organisation" + }, + "hideInAnswer": true + } + ], + "condition": { + "or": [ + "denotation=landmark", + "denotation=natural_monument" + ] + } + }, + { + "render": { + "nl": "\"\"/ Onroerend Erfgoed-ID: {ref:OnroerendErfgoed}", + "en": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", + "it": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", + "ru": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", + "fr": "\"\"/ Identifiant Onroerend Erfgoed : {ref:OnroerendErfgoed}" + }, + "question": { + "nl": "Wat is het ID uitgegeven door Onroerend Erfgoed Vlaanderen?", + "en": "What is the ID issued by Onroerend Erfgoed Flanders?", + "it": "Qual è l’ID rilasciato da Onroerend Erfgoed Flanders?", + "fr": "Quel est son identifiant donné par Onroerend Erfgoed ?" + }, + "freeform": { + "key": "ref:OnroerendErfgoed", + "type": "nat" + }, + "condition": { + "and": [ + "heritage=4", + "heritage:operator=OnroerendErfgoed" + ] + } + }, + { + "render": { + "nl": "\"\"/ Wikidata: {wikidata}", + "en": "\"\"/ Wikidata: {wikidata}", + "it": "\"\"/ Wikidata: {wikidata}", + "ru": "\"\"/ Wikidata: {wikidata}", + "fr": "\"\"/ Wikidata : {wikidata}" + }, + "question": { + "nl": "Wat is het Wikidata-ID van deze boom?", + "en": "What is the Wikidata ID for this tree?", + "it": "Qual è l’ID Wikidata per questo albero?", + "fr": "Quel est l'identifiant Wikidata de cet arbre ?" + }, + "freeform": { + "key": "wikidata", + "type": "wikidata" + }, + "condition": { + "or": [ + "denotation=landmark", + "denotation=natural_monument", + "wikidata~*" + ] + } + } + ], + "icon": { + "render": "circle:#ffffff;./assets/themes/trees/unknown.svg", + "mappings": [ + { + "if": { + "and": [ + "leaf_type=broadleaved" + ] + }, + "then": "circle:#ffffff;./assets/themes/trees/broadleaved.svg" + }, + { + "if": { + "and": [ + "leaf_type=needleleaved" + ] + }, + "then": "circle:#ffffff;./assets/themes/trees/needleleaved.svg" + } + ] + }, + "wayHandling": 1, + "width": { + "render": "8" + }, + "iconSize": { + "render": "40,40,bottom" + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "natural=tree", + "leaf_type=broadleaved" + ], + "title": { + "nl": "Loofboom", + "en": "Broadleaved tree", + "it": "Albero latifoglia", + "fr": "Arbre feuillu", + "ru": "Лиственное дерево" + }, + "description": { + "nl": "Een boom van een soort die blaadjes heeft, bijvoorbeeld eik of populier.", + "en": "A tree of a species with leaves, such as oak or populus.", + "it": "Un albero di una specie con foglie larghe come la quercia o il pioppo.", + "fr": "Un arbre d'une espèce avec de larges feuilles, comme le chêne ou le peuplier." + } + }, + { + "tags": [ + "natural=tree", + "leaf_type=needleleaved" + ], + "title": { + "nl": "Naaldboom", + "en": "Needleleaved tree", + "it": "Albero aghifoglia", + "ru": "Хвойное дерево", + "fr": "Arbre résineux" + }, + "description": { + "nl": "Een boom van een soort met naalden, bijvoorbeeld den of spar.", + "en": "A tree of a species with needles, such as pine or spruce.", + "it": "Un albero di una specie con aghi come il pino o l’abete.", + "ru": "Дерево с хвоей (иглами), например, сосна или ель.", + "fr": "Une espèce d’arbre avec des épines comme le pin ou l’épicéa." + } + }, + { + "tags": [ + "natural=tree" + ], + "title": { + "nl": "Boom", + "en": "Tree", + "it": "Albero", + "ru": "Дерево", + "fr": "Arbre", + "id": "Pohon" + }, + "description": { + "nl": "Wanneer je niet zeker bent of het nu een loof- of naaldboom is.", + "en": "If you're not sure whether it's a broadleaved or needleleaved tree.", + "it": "Qualora non si sia sicuri se si tratta di un albero latifoglia o aghifoglia.", + "fr": "Si vous n'êtes pas sûr(e) de savoir s'il s'agit d'un arbre à feuilles larges ou à aiguilles.", + "ru": "Если вы не уверены в том, лиственное это дерево или хвойное." + } + } + ] } \ No newline at end of file diff --git a/assets/layers/viewpoint/viewpoint.json b/assets/layers/viewpoint/viewpoint.json index f231df77b..31f2452bc 100644 --- a/assets/layers/viewpoint/viewpoint.json +++ b/assets/layers/viewpoint/viewpoint.json @@ -1,73 +1,73 @@ { - "id": "viewpoint", - "name": { - "en": "Viewpoint", - "nl": "Uitzicht", - "de": "Aussichtspunkt", - "fr": "Point de vue", - "it": "Punto panoramico", - "ru": "Смотровая площадка", - "id": "Sudut pandang" - }, - "description": { - "en": "A nice viewpoint or nice view. Ideal to add an image if no other category fits", - "nl": "Een mooi uitzicht - ideaal om een foto toe te voegen wanneer iets niet in een andere categorie past", - "de": "Ein schöner Aussichtspunkt oder eine schöne Aussicht. Ideal zum Hinzufügen eines Bildes, wenn keine andere Kategorie passt", - "fr": "Un beau point de vue ou une belle vue. Idéal pour ajouter une image si aucune autre catégorie ne convient", - "it": "Un punto panoramico che offre una bella vista. L'ideale è aggiungere un'immagine, se nessun'altra categoria è appropriata" - }, - "source": { - "osmTags": "tourism=viewpoint" - }, - "minzoom": 14, - "icon": "./assets/layers/viewpoint/viewpoint.svg", - "iconSize": "20,20,center", - "color": "#ffffff", - "width": "5", - "wayhandling": 2, - "presets": [ - { - "title": { + "id": "viewpoint", + "name": { "en": "Viewpoint", "nl": "Uitzicht", "de": "Aussichtspunkt", "fr": "Point de vue", - "ru": "Смотровая площадка", "it": "Punto panoramico", + "ru": "Смотровая площадка", "id": "Sudut pandang" - }, - "tags": [ - "tourism=viewpoint" - ] - } - ], - "title": { - "render": { - "en": "Viewpoint", - "nl": "Uitzicht", - "de": "Aussichtspunkt", - "fr": "Point de vue", - "ru": "Смотровая площадка", - "it": "Punto panoramico", - "id": "Sudut pandang" - } - }, - "tagRenderings": [ - "images", - { - "question": { - "en": "Do you want to add a description?", - "nl": "Zijn er bijzonderheden die je wilt toevoegen?", - "de": "Möchten Sie eine Beschreibung hinzufügen?", - "ru": "Вы хотите добавить описание?", - "fr": "Voulez-vous ajouter une description ?", - "it": "Vuoi aggiungere una descrizione?", - "id": "Apakah Anda ingin menambahkan deskripsi?" - }, - "render": "{description}", - "freeform": { - "key": "description" - } - } - ] + }, + "description": { + "en": "A nice viewpoint or nice view. Ideal to add an image if no other category fits", + "nl": "Een mooi uitzicht - ideaal om een foto toe te voegen wanneer iets niet in een andere categorie past", + "de": "Ein schöner Aussichtspunkt oder eine schöne Aussicht. Ideal zum Hinzufügen eines Bildes, wenn keine andere Kategorie passt", + "fr": "Un beau point de vue ou une belle vue. Idéal pour ajouter une image si aucune autre catégorie ne convient", + "it": "Un punto panoramico che offre una bella vista. L'ideale è aggiungere un'immagine, se nessun'altra categoria è appropriata" + }, + "source": { + "osmTags": "tourism=viewpoint" + }, + "minzoom": 14, + "icon": "./assets/layers/viewpoint/viewpoint.svg", + "iconSize": "20,20,center", + "color": "#ffffff", + "width": "5", + "wayhandling": 2, + "presets": [ + { + "title": { + "en": "Viewpoint", + "nl": "Uitzicht", + "de": "Aussichtspunkt", + "fr": "Point de vue", + "ru": "Смотровая площадка", + "it": "Punto panoramico", + "id": "Sudut pandang" + }, + "tags": [ + "tourism=viewpoint" + ] + } + ], + "title": { + "render": { + "en": "Viewpoint", + "nl": "Uitzicht", + "de": "Aussichtspunkt", + "fr": "Point de vue", + "ru": "Смотровая площадка", + "it": "Punto panoramico", + "id": "Sudut pandang" + } + }, + "tagRenderings": [ + "images", + { + "question": { + "en": "Do you want to add a description?", + "nl": "Zijn er bijzonderheden die je wilt toevoegen?", + "de": "Möchten Sie eine Beschreibung hinzufügen?", + "ru": "Вы хотите добавить описание?", + "fr": "Voulez-vous ajouter une description ?", + "it": "Vuoi aggiungere una descrizione?", + "id": "Apakah Anda ingin menambahkan deskripsi?" + }, + "render": "{description}", + "freeform": { + "key": "description" + } + } + ] } \ No newline at end of file diff --git a/assets/layers/village_green/village_green.json b/assets/layers/village_green/village_green.json index 02dc02293..96fd02f3e 100644 --- a/assets/layers/village_green/village_green.json +++ b/assets/layers/village_green/village_green.json @@ -1,37 +1,37 @@ { - "id": "village_green", - "name": { - "nl": "Speelweide" - }, - "source": { - "osmTags": "landuse=village_green" - }, - "minzoom": 0, - "title": { - "render": { - "nl": "Speelweide" + "id": "village_green", + "name": { + "nl": "Speelweide" }, - "mappings": [ - { - "if": "name~*", - "then": { - "nl": "{name}" + "source": { + "osmTags": "landuse=village_green" + }, + "minzoom": 0, + "title": { + "render": { + "nl": "Speelweide" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "nl": "{name}" + } + } + ] + }, + "icon": "./assets/themes/playgrounds/playground.svg", + "iconSize": "40,40,center", + "width": "1", + "color": "#937f20", + "wayHandling": 2, + "tagRenderings": [ + "images", + { + "render": "Dit is een klein stukje openbaar groen waar je mag spelen, picnicken, zitten, ..." + }, + { + "render": "{reviews(name, landuse=village_green )}" } - } ] - }, - "icon": "./assets/themes/playgrounds/playground.svg", - "iconSize": "40,40,center", - "width": "1", - "color": "#937f20", - "wayHandling": 2, - "tagRenderings": [ - "images", - { - "render": "Dit is een klein stukje openbaar groen waar je mag spelen, picnicken, zitten, ..." - }, - { - "render": "{reviews(name, landuse=village_green )}" - } - ] } \ No newline at end of file diff --git a/assets/layers/visitor_information_centre/visitor_information_centre.json b/assets/layers/visitor_information_centre/visitor_information_centre.json index 10c3cd0de..1f066376a 100644 --- a/assets/layers/visitor_information_centre/visitor_information_centre.json +++ b/assets/layers/visitor_information_centre/visitor_information_centre.json @@ -1,65 +1,65 @@ { - "id": "visitor_information_centre", - "name": { - "en": "Visitor Information Centre", - "nl": "Bezoekerscentrum" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - { - "or": [ - "information=visitor_centre", - "information=office" - ] - } - ] - } - }, - "title": { - "render": { - "nl": "{name}", - "en": "{name}" + "id": "visitor_information_centre", + "name": { + "en": "Visitor Information Centre", + "nl": "Bezoekerscentrum" }, - "mappings": [ - { - "if": { - "and": [ - "name:nl~*" - ] - }, - "then": { - "nl": "{name:nl}" + "minzoom": 12, + "source": { + "osmTags": { + "and": [ + { + "or": [ + "information=visitor_centre", + "information=office" + ] + } + ] } - }, - { - "if": { - "and": [ - "name~*" - ] + }, + "title": { + "render": { + "nl": "{name}", + "en": "{name}" }, - "then": { - "nl": "{name}", - "en": "{name}" - } - } - ] - }, - "description": { - "en": "A visitor center offers information about a specific attraction or place of interest where it is located.", - "nl": "Een bezoekerscentrum biedt informatie over een specifieke attractie of bezienswaardigheid waar het is gevestigd." - }, - "tagRenderings": [], - "icon": { - "render": "./assets/layers/visitor_information_centre/information.svg" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#E64C00" - }, - "presets": [], - "wayHandling": 1 + "mappings": [ + { + "if": { + "and": [ + "name:nl~*" + ] + }, + "then": { + "nl": "{name:nl}" + } + }, + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "{name}", + "en": "{name}" + } + } + ] + }, + "description": { + "en": "A visitor center offers information about a specific attraction or place of interest where it is located.", + "nl": "Een bezoekerscentrum biedt informatie over een specifieke attractie of bezienswaardigheid waar het is gevestigd." + }, + "tagRenderings": [], + "icon": { + "render": "./assets/layers/visitor_information_centre/information.svg" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#E64C00" + }, + "presets": [], + "wayHandling": 1 } \ No newline at end of file diff --git a/assets/layers/waste_basket/waste_basket.json b/assets/layers/waste_basket/waste_basket.json index 1dd17348b..8561f5c60 100644 --- a/assets/layers/waste_basket/waste_basket.json +++ b/assets/layers/waste_basket/waste_basket.json @@ -1,118 +1,118 @@ { - "id": "waste_basket", - "name": { - "en": "Waste Basket", - "nl": "Vuilnisbak" - }, - "minzoom": 17, - "source": { - "osmTags": { - "and": [ - "amenity=waste_basket" - ] - } - }, - "title": { - "render": { - "en": "Waste Basket", - "nl": "Vuilnisbak" - } - }, - "description": { - "en": "This is a public waste basket, thrash can, where you can throw away your thrash.", - "nl": "Dit is een publieke vuilnisbak waar je je afval kan weggooien." - }, - "tagRenderings": [ - { - "question": { - "en": "What kind of waste basket is this?", - "nl": "Wat voor soort vuilnisbak is dit?" - }, - "multiAnswer": true, - "mappings": [ - { - "if": "waste=", - "then": { - "en": "A waste basket for general waste", - "nl": "Een vuilnisbak voor zwerfvuil" - }, - "hideInAnswer": true - }, - { - "if": "waste=trash", - "then": { - "en": "A waste basket for general waste", - "nl": "Een vuilnisbak voor zwerfvuil" - } - }, - { - "if": "waste=dog_excrement", - "then": { - "en": "A waste basket for dog excrements", - "nl": "Een vuilnisbak specifiek voor hondenuitwerpselen" - } - }, - { - "if": "waste=cigarettes", - "then": { - "en": "A waste basket for cigarettes", - "nl": "Een vuilnisbak voor sigarettenpeuken" - } - }, - { - "if": "waste=drugs", - "then": { - "en": "A waste basket for drugs", - "nl": "Een vuilnisbak voor (vervallen) medicatie en drugs" - } - }, - { - "if": "waste=sharps", - "then": { - "en": "A waste basket for needles and other sharp objects", - "nl": "Een vuilnisbak voor injectienaalden en andere scherpe voorwerpen" - } - } - ] - } - ], - "icon": { - "render": "./assets/themes/waste_basket/waste_basket.svg" - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,center", - "mappings": [ - { - "if": { - "and": [ - "amenity=waste_basket" - ] - }, - "then": { - "en": "Waste Basket", - "nl": "Vuilnisbak" - } - } - ] - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "amenity=waste_basket" - ], - "title": { + "id": "waste_basket", + "name": { "en": "Waste Basket", "nl": "Vuilnisbak" - }, - "presiceInput": { - "preferredBackground": "photo" - } - } - ] + }, + "minzoom": 17, + "source": { + "osmTags": { + "and": [ + "amenity=waste_basket" + ] + } + }, + "title": { + "render": { + "en": "Waste Basket", + "nl": "Vuilnisbak" + } + }, + "description": { + "en": "This is a public waste basket, thrash can, where you can throw away your thrash.", + "nl": "Dit is een publieke vuilnisbak waar je je afval kan weggooien." + }, + "tagRenderings": [ + { + "question": { + "en": "What kind of waste basket is this?", + "nl": "Wat voor soort vuilnisbak is dit?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "waste=", + "then": { + "en": "A waste basket for general waste", + "nl": "Een vuilnisbak voor zwerfvuil" + }, + "hideInAnswer": true + }, + { + "if": "waste=trash", + "then": { + "en": "A waste basket for general waste", + "nl": "Een vuilnisbak voor zwerfvuil" + } + }, + { + "if": "waste=dog_excrement", + "then": { + "en": "A waste basket for dog excrements", + "nl": "Een vuilnisbak specifiek voor hondenuitwerpselen" + } + }, + { + "if": "waste=cigarettes", + "then": { + "en": "A waste basket for cigarettes", + "nl": "Een vuilnisbak voor sigarettenpeuken" + } + }, + { + "if": "waste=drugs", + "then": { + "en": "A waste basket for drugs", + "nl": "Een vuilnisbak voor (vervallen) medicatie en drugs" + } + }, + { + "if": "waste=sharps", + "then": { + "en": "A waste basket for needles and other sharp objects", + "nl": "Een vuilnisbak voor injectienaalden en andere scherpe voorwerpen" + } + } + ] + } + ], + "icon": { + "render": "./assets/themes/waste_basket/waste_basket.svg" + }, + "width": { + "render": "8" + }, + "iconSize": { + "render": "40,40,center", + "mappings": [ + { + "if": { + "and": [ + "amenity=waste_basket" + ] + }, + "then": { + "en": "Waste Basket", + "nl": "Vuilnisbak" + } + } + ] + }, + "color": { + "render": "#00f" + }, + "presets": [ + { + "tags": [ + "amenity=waste_basket" + ], + "title": { + "en": "Waste Basket", + "nl": "Vuilnisbak" + }, + "presiceInput": { + "preferredBackground": "photo" + } + } + ] } \ No newline at end of file diff --git a/assets/layers/watermill/watermill.json b/assets/layers/watermill/watermill.json index 02b74566e..8fca7a9d6 100644 --- a/assets/layers/watermill/watermill.json +++ b/assets/layers/watermill/watermill.json @@ -1,173 +1,173 @@ { - "id": "watermill", - "name": { - "nl": "watermolens", - "en": "Watermill" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - "man_made=watermill" - ] - } - }, - "title": { - "render": { - "nl": "Watermolens" + "id": "watermill", + "name": { + "nl": "watermolens", + "en": "Watermill" }, - "mappings": [ - { - "if": { - "and": [ - "name:nl~*" - ] - }, - "then": { - "nl": "{name:nl}" + "minzoom": 12, + "source": { + "osmTags": { + "and": [ + "man_made=watermill" + ] } - }, - { - "if": { - "and": [ - "name~*" - ] - }, - "then": { - "nl": "{name}" - } - } - ] - }, - "description": { - "nl": "Watermolens" - }, - "tagRenderings": [ - "images", - { - "#": "Access tag", - "render": { - "nl": "De toegankelijkheid van dit gebied is: {access:description}" - }, - "question": { - "nl": "Is dit gebied toegankelijk?" - }, - "freeform": { - "key": "access:description" - }, - "mappings": [ - { - "if": { - "and": [ - "access=yes", - "fee=" - ] - }, - "then": { - "nl": "Vrij toegankelijk" - } - }, - { - "if": { - "and": [ - "access=no", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk" - } - }, - { - "if": { - "and": [ - "access=private", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk, want privégebied" - } - }, - { - "if": { - "and": [ - "access=permissive", - "fee=" - ] - }, - "then": { - "nl": "Toegankelijk, ondanks dat het privegebied is" - } - }, - { - "if": { - "and": [ - "access=guided", - "fee=" - ] - }, - "then": { - "nl": "Enkel toegankelijk met een gids of tijdens een activiteit" - } - }, - { - "if": { - "and": [ - "access=yes", - "fee=yes" - ] - }, - "then": { - "nl": "Toegankelijk mits betaling" - } - } - ] }, - { - "#": "Operator tag", - "render": { - "nl": "Beheer door {operator}" - }, - "question": { - "nl": "Wie beheert dit pad?" - }, - "freeform": { - "key": "operator" - }, - "mappings": [ + "title": { + "render": { + "nl": "Watermolens" + }, + "mappings": [ + { + "if": { + "and": [ + "name:nl~*" + ] + }, + "then": { + "nl": "{name:nl}" + } + }, + { + "if": { + "and": [ + "name~*" + ] + }, + "then": { + "nl": "{name}" + } + } + ] + }, + "description": { + "nl": "Watermolens" + }, + "tagRenderings": [ + "images", { - "if": { - "and": [ - "operator=Natuurpunt" + "#": "Access tag", + "render": { + "nl": "De toegankelijkheid van dit gebied is: {access:description}" + }, + "question": { + "nl": "Is dit gebied toegankelijk?" + }, + "freeform": { + "key": "access:description" + }, + "mappings": [ + { + "if": { + "and": [ + "access=yes", + "fee=" + ] + }, + "then": { + "nl": "Vrij toegankelijk" + } + }, + { + "if": { + "and": [ + "access=no", + "fee=" + ] + }, + "then": { + "nl": "Niet toegankelijk" + } + }, + { + "if": { + "and": [ + "access=private", + "fee=" + ] + }, + "then": { + "nl": "Niet toegankelijk, want privégebied" + } + }, + { + "if": { + "and": [ + "access=permissive", + "fee=" + ] + }, + "then": { + "nl": "Toegankelijk, ondanks dat het privegebied is" + } + }, + { + "if": { + "and": [ + "access=guided", + "fee=" + ] + }, + "then": { + "nl": "Enkel toegankelijk met een gids of tijdens een activiteit" + } + }, + { + "if": { + "and": [ + "access=yes", + "fee=yes" + ] + }, + "then": { + "nl": "Toegankelijk mits betaling" + } + } ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door Natuurpunt" - } }, { - "if": { - "and": [ - "operator~(n|N)atuurpunt.*" + "#": "Operator tag", + "render": { + "nl": "Beheer door {operator}" + }, + "question": { + "nl": "Wie beheert dit pad?" + }, + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": { + "and": [ + "operator=Natuurpunt" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door Natuurpunt" + } + }, + { + "if": { + "and": [ + "operator~(n|N)atuurpunt.*" + ] + }, + "then": { + "nl": "Dit gebied wordt beheerd door {operator}" + }, + "hideInAnswer": true + } ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door {operator}" - }, - "hideInAnswer": true } - ] + ], + "wayHandling": 1, + "icon": { + "render": "./assets/layers/watermill/watermill.svg" + }, + "iconSize": { + "render": "50,50,center" + }, + "color": { + "render": "#FFC0CB" } - ], - "wayHandling": 1, - "icon": { - "render": "./assets/layers/watermill/watermill.svg" - }, - "iconSize": { - "render": "50,50,center" - }, - "color": { - "render": "#FFC0CB" - } } \ No newline at end of file diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index f5f59afd8..aa15d9c3b 100644 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -295,7 +295,7 @@ function mergeLayerTranslations() { const layerFiles = ScriptUtils.getLayerFiles(); for (const layerFile of layerFiles) { mergeLayerTranslation(layerFile.parsed, layerFile.path, loadTranslationFilesFrom("layers")) - writeFileSync(layerFile.path, JSON.stringify(layerFile.parsed, null, " ")) + writeFileSync(layerFile.path, JSON.stringify(layerFile.parsed, null, " ")) } } From e47224ecb812bc7be23c578f9c50105f99c564a5 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 22 Sep 2021 17:15:30 +0200 Subject: [PATCH 03/65] Small fixes to the UK-addresses theme --- Logic/ExtraFunction.ts | 17 ++++++++++++----- assets/themes/uk_addresses/uk_addresses.json | 12 ++++++++---- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Logic/ExtraFunction.ts b/Logic/ExtraFunction.ts index 8b6834e09..04f7a64f6 100644 --- a/Logic/ExtraFunction.ts +++ b/Logic/ExtraFunction.ts @@ -134,11 +134,18 @@ export class ExtraFunction { args: ["list of features or layer name", "amount of features", "unique tag key (optional)", "maxDistanceInMeters (optional)"] }, (params, feature) => { - return (features, amount, uniqueTag, maxDistanceInMeters) => ExtraFunction.GetClosestNFeatures(params, feature, features, { - maxFeatures: Number(amount), - uniqueTag: uniqueTag, - maxDistance: Number(maxDistanceInMeters) - }) + + return (features, amount, uniqueTag, maxDistanceInMeters) => { + let distance : number = Number(maxDistanceInMeters) + if(isNaN(distance)){ + distance = undefined + } + return ExtraFunction.GetClosestNFeatures(params, feature, features, { + maxFeatures: Number(amount), + uniqueTag: uniqueTag, + maxDistance: distance + }); + } } ) diff --git a/assets/themes/uk_addresses/uk_addresses.json b/assets/themes/uk_addresses/uk_addresses.json index 654bb2177..e43f867ed 100644 --- a/assets/themes/uk_addresses/uk_addresses.json +++ b/assets/themes/uk_addresses/uk_addresses.json @@ -149,17 +149,17 @@ "mappings": [ { "if": "addr:street:={_closest_street:0:name}", - "then": "{_closest_street:0:name} {_closest_street:0:distance}m", + "then": "Located in {_closest_street:0:name} (~{_closest_street:0:distance}m away)", "hideInAnswer": "_closest_street:0:name=" }, { "if": "addr:street:={_closest_street:1:name}", - "then": "{_closest_street:1:name} {_closest_street:1:distance}m", + "then": "Located in {_closest_street:1:name} (~{_closest_street:1:distance}m away)", "hideInAnswer": "_closest_street:1:name=" }, { "if": "addr:street:={_closest_street:2:name}", - "then": "{_closest_street:2:name} {_closest_street:2:distance}m", + "then": "Located in {_closest_street:2:name} (~{_closest_street:2:distance}m away)", "hideInAnswer": "_closest_street:2:name=" } ], @@ -214,7 +214,11 @@ } ] }, - "presets": [] + "presets": [ + { + + } + ] }, { "id": "named_streets", From e18eb06f14c1b29eec0e8bdff77e3337d7103685 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 22 Sep 2021 17:29:50 +0200 Subject: [PATCH 04/65] Add better error handling, fixes #452 --- InitUiElements.ts | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/InitUiElements.ts b/InitUiElements.ts index e3e61ce2e..f6a6ce803 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -39,6 +39,8 @@ import LayoutConfig from "./Models/ThemeConfig/LayoutConfig"; import LayerConfig from "./Models/ThemeConfig/LayerConfig"; import Minimap from "./UI/Base/Minimap"; import Constants from "./Models/Constants"; +import Combine from "./UI/Base/Combine"; +import {SubtleButton} from "./UI/Base/SubtleButton"; export class InitUiElements { static InitAll( @@ -209,8 +211,8 @@ export class InitUiElements { static LoadLayoutFromHash( userLayoutParam: UIEventSource ): [LayoutConfig, string] { - try { let hash = location.hash.substr(1); + try { const layoutFromBase64 = userLayoutParam.data; // layoutFromBase64 contains the name of the theme. This is partly to do tracking with goat counter @@ -249,9 +251,21 @@ export class InitUiElements { userLayoutParam.setData(layoutToUse.id); return [layoutToUse, btoa(Utils.MinifyJSON(JSON.stringify(json)))]; } catch (e) { - new FixedUiElement( - "Error: could not parse the custom layout:
" + e - ).AttachTo("centermessage"); + + if(hash === undefined || hash.length < 10){ + e = "Did you effectively add a theme? It seems no data could be found." + } + + new Combine([ + "Error: could not parse the custom layout:", + e, + new SubtleButton("./assets/svg/mapcomplete_logo.svg", + "Go back to the theme overview", + {url: window.location.protocol+"//"+ window.location.hostname+"/index.html", newTab: false}) + + ]) + .SetClass("flex flex-col") + .AttachTo("centermessage"); throw e; } } From b9f96155defc760f390d9b94015b1903801e5b22 Mon Sep 17 00:00:00 2001 From: Tobias Jordans Date: Wed, 22 Sep 2021 18:53:08 +0200 Subject: [PATCH 05/65] Dev Instructions: Install `wget` `npm run init` requires `wget` to be installed but the error message is tiny and easy to miss. Without wget preset, the init tasks does not all it needs to do. Documenting it in the instructions explicitly works around this issue. --- Docs/Development_deployment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/Development_deployment.md b/Docs/Development_deployment.md index 9fa81f836..f95b7d284 100644 --- a/Docs/Development_deployment.md +++ b/Docs/Development_deployment.md @@ -30,6 +30,7 @@ To develop and build MapComplete, you 0. Make a fork and clone the repository. 1. Install `npm`. Linux: `sudo apt install npm` (or your favourite package manager), Windows: install nodeJS: https://nodejs.org/en/download/ +0. Install `wget`, `brew install wget` 3. Run `npm run init` and generate some additional dependencies and generated files. Note that it'll install the dependencies too 4. Run `npm run start` to host a local testversion at http://localhost:1234/index.html @@ -125,4 +126,3 @@ Overview of package.json-scripts - `deploy:staging`,`deploy:pietervdvn`, `deploy:production`: deploy the latest code on various locations - `lint`: get depressed by the amount of warnings - `clean`: remove some generated files which are annoying in the repo - From 204b431df0902069db9537c2a6a6c2f3fa6ec224 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 22 Sep 2021 20:12:53 +0200 Subject: [PATCH 06/65] Add more types to the charging stations theme, better merge if translations already exist --- InitUiElements.ts | 2 +- Models/Constants.ts | 2 +- .../charging_station/charging_station.json | 750 +++++++++++++++++- .../charging_station.protojson | 28 +- assets/layers/charging_station/csvToJson.ts | 83 +- assets/layers/charging_station/types.csv | 24 +- 6 files changed, 851 insertions(+), 38 deletions(-) diff --git a/InitUiElements.ts b/InitUiElements.ts index f6a6ce803..1835c4e07 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -258,7 +258,7 @@ export class InitUiElements { new Combine([ "Error: could not parse the custom layout:", - e, + new FixedUiElement(""+e).SetClass("alert"), new SubtleButton("./assets/svg/mapcomplete_logo.svg", "Go back to the theme overview", {url: window.location.protocol+"//"+ window.location.hostname+"/index.html", newTab: false}) diff --git a/Models/Constants.ts b/Models/Constants.ts index 539ab8c6f..ec3fd96e6 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.9.12"; + public static vNumber = "0.9.13"; // The user journey states thresholds when a new feature gets unlocked public static userJourney = { diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json index 4446049ab..c726b52dd 100644 --- a/assets/layers/charging_station/charging_station.json +++ b/assets/layers/charging_station/charging_station.json @@ -93,8 +93,13 @@ ] }, { - "question": "Who is allowed to use this charging station?", - "render": "Access is {access}", + "#": "access", + "question": { + "en": "Who is allowed to use this charging station?" + }, + "render": { + "en": "Access is {access}" + }, "freeform": { "key": "access", "addExtraTags": [ @@ -142,6 +147,7 @@ } }, { + "#": "Available_charging_stations (generated)", "question": { "en": "Which charging stations are available here?" }, @@ -153,6 +159,18 @@ "then": { "en": " Schuko wall plug without ground pin (CEE7/4 type F)", "nl": " Schuko stekker zonder aardingspin (CEE7/4 type F)" + }, + "hideInAnswer": { + "or": [ + "_country!=be", + "_country!=fr", + "_country!=ma", + "_country!=tn", + "_country!=pl", + "_country!=cs", + "_country!=sk", + "_country!=mo" + ] } }, { @@ -335,10 +353,105 @@ "nl": " " }, "hideInAnswer": true + }, + { + "if": "socket:type2_cable=1", + "ifnot": "socket:type2_cable=", + "then": { + "en": " Type 2 with cable (mennekes)", + "nl": " Type 2 met kabel (J1772)" + } + }, + { + "if": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=1" + ] + }, + "then": { + "en": " Type 2 with cable (mennekes)", + "nl": " Type 2 met kabel (J1772)" + }, + "hideInAnswer": true + }, + { + "if": "socket:tesla_supercharger_ccs=1", + "ifnot": "socket:tesla_supercharger_ccs=", + "then": { + "en": " Tesla Supercharger CCS (a branded type2_css)", + "nl": " " + } + }, + { + "if": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=1" + ] + }, + "then": { + "en": " Tesla Supercharger CCS (a branded type2_css)", + "nl": " " + }, + "hideInAnswer": true + }, + { + "if": "socket:tesla_destination=1", + "ifnot": "socket:tesla_destination=", + "then": { + "en": " Tesla Supercharger (destination)", + "nl": " " + }, + "hideInAnswer": { + "or": [ + "_country!=us" + ] + } + }, + { + "if": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=1" + ] + }, + "then": { + "en": " Tesla Supercharger (destination)", + "nl": " " + }, + "hideInAnswer": true + }, + { + "if": "socket:tesla_destination=1", + "ifnot": "socket:tesla_destination=", + "then": { + "en": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)", + "nl": " " + }, + "hideInAnswer": { + "or": [ + "_country=us" + ] + } + }, + { + "if": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=1" + ] + }, + "then": { + "en": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)", + "nl": " " + }, + "hideInAnswer": true } ] }, { + "#": "plugs-0", "question": { "en": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", "nl": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?" @@ -359,6 +472,7 @@ } }, { + "#": "voltage-0", "question": { "en": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", "nl": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) " @@ -388,6 +502,7 @@ } }, { + "#": "current-0", "question": { "en": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", "nl": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" @@ -417,6 +532,7 @@ } }, { + "#": "power-output-0", "question": { "en": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", "nl": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" @@ -446,6 +562,7 @@ } }, { + "#": "plugs-1", "question": { "en": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", "nl": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?" @@ -466,6 +583,7 @@ } }, { + "#": "voltage-1", "question": { "en": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", "nl": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) " @@ -495,6 +613,7 @@ } }, { + "#": "current-1", "question": { "en": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", "nl": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" @@ -524,6 +643,7 @@ } }, { + "#": "power-output-1", "question": { "en": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", "nl": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" @@ -560,6 +680,7 @@ } }, { + "#": "plugs-2", "question": { "en": "How much plugs of type Chademo are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -580,6 +701,7 @@ } }, { + "#": "voltage-2", "question": { "en": "What voltage do the plugs with Chademo offer?", "nl": "Welke spanning levert de stekker van type " @@ -609,6 +731,7 @@ } }, { + "#": "current-2", "question": { "en": "What current do the plugs with Chademo offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -638,6 +761,7 @@ } }, { + "#": "power-output-2", "question": { "en": "What power output does a single plug of type Chademo offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -667,6 +791,7 @@ } }, { + "#": "plugs-3", "question": { "en": "How much plugs of type Type 1 with cable (J1772) are available here?", "nl": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?" @@ -687,6 +812,7 @@ } }, { + "#": "voltage-3", "question": { "en": "What voltage do the plugs with Type 1 with cable (J1772) offer?", "nl": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) " @@ -723,6 +849,7 @@ } }, { + "#": "current-3", "question": { "en": "What current do the plugs with Type 1 with cable (J1772) offer?", "nl": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?" @@ -752,6 +879,7 @@ } }, { + "#": "power-output-3", "question": { "en": "What power output does a single plug of type Type 1 with cable (J1772) offer?", "nl": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?" @@ -788,6 +916,7 @@ } }, { + "#": "plugs-4", "question": { "en": "How much plugs of type Type 1 without cable (J1772) are available here?", "nl": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?" @@ -808,6 +937,7 @@ } }, { + "#": "voltage-4", "question": { "en": "What voltage do the plugs with Type 1 without cable (J1772) offer?", "nl": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) " @@ -844,6 +974,7 @@ } }, { + "#": "current-4", "question": { "en": "What current do the plugs with Type 1 without cable (J1772) offer?", "nl": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?" @@ -873,6 +1004,7 @@ } }, { + "#": "power-output-4", "question": { "en": "What power output does a single plug of type Type 1 without cable (J1772) offer?", "nl": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?" @@ -923,6 +1055,7 @@ } }, { + "#": "plugs-5", "question": { "en": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -943,6 +1076,7 @@ } }, { + "#": "voltage-5", "question": { "en": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", "nl": "Welke spanning levert de stekker van type " @@ -979,6 +1113,7 @@ } }, { + "#": "current-5", "question": { "en": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1015,6 +1150,7 @@ } }, { + "#": "power-output-5", "question": { "en": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1065,6 +1201,7 @@ } }, { + "#": "plugs-6", "question": { "en": "How much plugs of type Tesla Supercharger are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1085,6 +1222,7 @@ } }, { + "#": "voltage-6", "question": { "en": "What voltage do the plugs with Tesla Supercharger offer?", "nl": "Welke spanning levert de stekker van type " @@ -1114,6 +1252,7 @@ } }, { + "#": "current-6", "question": { "en": "What current do the plugs with Tesla Supercharger offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1150,6 +1289,7 @@ } }, { + "#": "power-output-6", "question": { "en": "What power output does a single plug of type Tesla Supercharger offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1193,6 +1333,7 @@ } }, { + "#": "plugs-7", "question": { "en": "How much plugs of type Type 2 (mennekes) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1213,6 +1354,7 @@ } }, { + "#": "voltage-7", "question": { "en": "What voltage do the plugs with Type 2 (mennekes) offer?", "nl": "Welke spanning levert de stekker van type " @@ -1249,6 +1391,7 @@ } }, { + "#": "current-7", "question": { "en": "What current do the plugs with Type 2 (mennekes) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1285,6 +1428,7 @@ } }, { + "#": "power-output-7", "question": { "en": "What power output does a single plug of type Type 2 (mennekes) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1321,6 +1465,7 @@ } }, { + "#": "plugs-8", "question": { "en": "How much plugs of type Type 2 CCS (mennekes) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1341,6 +1486,7 @@ } }, { + "#": "voltage-8", "question": { "en": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", "nl": "Welke spanning levert de stekker van type " @@ -1377,6 +1523,7 @@ } }, { + "#": "current-8", "question": { "en": "What current do the plugs with Type 2 CCS (mennekes) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1413,6 +1560,7 @@ } }, { + "#": "power-output-8", "question": { "en": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1441,6 +1589,527 @@ ] } }, + { + "#": "plugs-9", + "question": { + "en": "How much plugs of type Type 2 with cable (mennekes) are available here?", + "nl": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 2 with cable (mennekes) plugs of type Type 2 with cable (mennekes) available here", + "nl": "Hier zijn Type 2 met kabel (J1772) stekkers van het type Type 2 met kabel (J1772)" + }, + "freeform": { + "key": "socket:type2_cable", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "#": "voltage-9", + "question": { + "en": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", + "nl": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) " + }, + "render": { + "en": "Type 2 with cable (mennekes) outputs {socket:type2_cable:voltage} volt", + "nl": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt" + }, + "freeform": { + "key": "socket:type2_cable:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_cable:voltage=230 V", + "then": { + "en": "Type 2 with cable (mennekes) outputs 230 volt", + "nl": "Type 2 met kabel (J1772) heeft een spanning van 230 volt" + } + }, + { + "if": "socket:socket:type2_cable:voltage=400 V", + "then": { + "en": "Type 2 with cable (mennekes) outputs 400 volt", + "nl": "Type 2 met kabel (J1772) heeft een spanning van 400 volt" + } + } + ], + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "#": "current-9", + "question": { + "en": "What current do the plugs with Type 2 with cable (mennekes) offer?", + "nl": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?" + }, + "render": { + "en": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:current}A", + "nl": "Type 2 met kabel (J1772) levert een stroom van maximaal {socket:type2_cable:current}A" + }, + "freeform": { + "key": "socket:type2_cable:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_cable:current=16 A", + "then": { + "en": "Type 2 with cable (mennekes) outputs at most 16 A", + "nl": "Type 2 met kabel (J1772) levert een stroom van maximaal 16 A" + } + }, + { + "if": "socket:socket:type2_cable:current=32 A", + "then": { + "en": "Type 2 with cable (mennekes) outputs at most 32 A", + "nl": "Type 2 met kabel (J1772) levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "#": "power-output-9", + "question": { + "en": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?" + }, + "render": { + "en": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:output}", + "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal {socket:type2_cable:output}" + }, + "freeform": { + "key": "socket:type2_cable:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_cable:output=11 kw", + "then": { + "en": "Type 2 with cable (mennekes) outputs at most 11 kw", + "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal 11 kw" + } + }, + { + "if": "socket:socket:type2_cable:output=22 kw", + "then": { + "en": "Type 2 with cable (mennekes) outputs at most 22 kw", + "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "#": "plugs-10", + "question": { + "en": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Tesla Supercharger CCS (a branded type2_css) plugs of type Tesla Supercharger CCS (a branded type2_css) available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "#": "voltage-10", + "question": { + "en": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt", + "nl": " heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger_ccs:voltage=500 V", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt", + "nl": " heeft een spanning van 500 volt" + } + }, + { + "if": "socket:socket:tesla_supercharger_ccs:voltage=920 V", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs 920 volt", + "nl": " heeft een spanning van 920 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "#": "current-10", + "question": { + "en": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A", + "nl": " levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger_ccs:current=125 A", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A", + "nl": " levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:tesla_supercharger_ccs:current=350 A", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A", + "nl": " levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "#": "power-output-10", + "question": { + "en": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:output}", + "nl": " levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger_ccs:output=50 kw", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 50 kw", + "nl": " levert een vermogen van maximaal 50 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "#": "plugs-11", + "question": { + "en": "How much plugs of type Tesla Supercharger (destination) are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:tesla_destination", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "#": "voltage-11", + "question": { + "en": "What voltage do the plugs with Tesla Supercharger (destination) offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt", + "nl": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_destination:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:voltage=480 V", + "then": { + "en": "Tesla Supercharger (destination) outputs 480 volt", + "nl": " heeft een spanning van 480 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "#": "current-11", + "question": { + "en": "What current do the plugs with Tesla Supercharger (destination) offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A", + "nl": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "freeform": { + "key": "socket:tesla_destination:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:current=125 A", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 125 A", + "nl": " levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:tesla_destination:current=350 A", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 350 A", + "nl": " levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "#": "power-output-11", + "question": { + "en": "What power output does a single plug of type Tesla Supercharger (destination) offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:output}", + "nl": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "freeform": { + "key": "socket:tesla_destination:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:output=120 kw", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 120 kw", + "nl": " levert een vermogen van maximaal 120 kw" + } + }, + { + "if": "socket:socket:tesla_destination:output=150 kw", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 150 kw", + "nl": " levert een vermogen van maximaal 150 kw" + } + }, + { + "if": "socket:socket:tesla_destination:output=250 kw", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 250 kw", + "nl": " levert een vermogen van maximaal 250 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "#": "plugs-12", + "question": { + "en": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Tesla supercharger (destination (A Type 2 with cable branded as tesla) plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:tesla_destination", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "#": "voltage-12", + "question": { + "en": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt", + "nl": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_destination:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:voltage=230 V", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt", + "nl": " heeft een spanning van 230 volt" + } + }, + { + "if": "socket:socket:tesla_destination:voltage=400 V", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt", + "nl": " heeft een spanning van 400 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "#": "current-12", + "question": { + "en": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:current}A", + "nl": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "freeform": { + "key": "socket:tesla_destination:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:current=16 A", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 16 A", + "nl": " levert een stroom van maximaal 16 A" + } + }, + { + "if": "socket:socket:tesla_destination:current=32 A", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 32 A", + "nl": " levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "#": "power-output-12", + "question": { + "en": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:output}", + "nl": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "freeform": { + "key": "socket:tesla_destination:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:output=11 kw", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 11 kw", + "nl": " levert een vermogen van maximaal 11 kw" + } + }, + { + "if": "socket:socket:tesla_destination:output=22 kw", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 22 kw", + "nl": " levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, { "#": "Authentication", "question": { @@ -1610,6 +2279,7 @@ ] }, { + "#": "payment-options", "builtin": "payment-options", "override": { "condition": { @@ -1627,6 +2297,16 @@ "nl": "Betalen via een app van het netwerk" } } + ], + "mappings": [ + { + "if": "payment:app=yes", + "ifnot": "payment:app=no", + "then": { + "en": "Payment is done using a dedicated app", + "nl": "Betalen via een app van het netwerk" + } + } ] } }, @@ -1822,6 +2502,26 @@ } } ] + }, + { + "#": "Parking:fee", + "question": { + "en": "Does one have to pay a parking fee while charging?" + }, + "mappings": [ + { + "if": "parking:fee=no", + "then": { + "en": "No additional parking cost while charging" + } + }, + { + "if": "parking:fee=yes", + "then": { + "en": "An additional parking fee should be paid while charging" + } + } + ] } ], "icon": { @@ -2016,6 +2716,34 @@ "nl": "Heeft een " }, "osmTags": "socket:type2_combo~*" + }, + { + "question": { + "en": "Has a Type 2 with cable (mennekes) connector", + "nl": "Heeft een Type 2 met kabel (J1772) " + }, + "osmTags": "socket:type2_cable~*" + }, + { + "question": { + "en": "Has a Tesla Supercharger CCS (a branded type2_css) connector", + "nl": "Heeft een " + }, + "osmTags": "socket:tesla_supercharger_ccs~*" + }, + { + "question": { + "en": "Has a Tesla Supercharger (destination) connector", + "nl": "Heeft een " + }, + "osmTags": "socket:tesla_destination~*" + }, + { + "question": { + "en": "Has a Tesla supercharger (destination (A Type 2 with cable branded as tesla) connector", + "nl": "Heeft een " + }, + "osmTags": "socket:tesla_destination~*" } ] } @@ -2094,7 +2822,11 @@ "socket:type1_combo:voltage", "socket:tesla_supercharger:voltage", "socket:type2:voltage", - "socket:type2_combo:voltage" + "socket:type2_combo:voltage", + "socket:type2_cable:voltage", + "socket:tesla_supercharger_ccs:voltage", + "socket:tesla_destination:voltage", + "socket:tesla_destination:voltage" ], "applicableUnits": [ { @@ -2124,7 +2856,11 @@ "socket:type1_combo:current", "socket:tesla_supercharger:current", "socket:type2:current", - "socket:type2_combo:current" + "socket:type2_combo:current", + "socket:type2_cable:current", + "socket:tesla_supercharger_ccs:current", + "socket:tesla_destination:current", + "socket:tesla_destination:current" ], "applicableUnits": [ { @@ -2153,7 +2889,11 @@ "socket:type1_combo:output", "socket:tesla_supercharger:output", "socket:type2:output", - "socket:type2_combo:output" + "socket:type2_combo:output", + "socket:type2_cable:output", + "socket:tesla_supercharger_ccs:output", + "socket:tesla_destination:output", + "socket:tesla_destination:output" ], "applicableUnits": [ { diff --git a/assets/layers/charging_station/charging_station.protojson b/assets/layers/charging_station/charging_station.protojson index 7689ae905..536c876f1 100644 --- a/assets/layers/charging_station/charging_station.protojson +++ b/assets/layers/charging_station/charging_station.protojson @@ -93,8 +93,13 @@ ] }, { - "question": "Who is allowed to use this charging station?", - "render": "Access is {access}", + "#": "access", + "question": { + "en": "Who is allowed to use this charging station?" + }, + "render": { + "en": "Access is {access}" + }, "freeform": { "key": "access", "addExtraTags": [ @@ -141,7 +146,7 @@ "type": "pnat" } }, - $$$ + {"#": "$$$"}, { "#": "Authentication", "question": { @@ -311,6 +316,7 @@ ] }, { + "#": "payment-options", "builtin": "payment-options", "override": { "condition": { @@ -395,8 +401,12 @@ }, { "#": "Operator", - "question": "Who is the operator of this charging station?", - "render": "This charging station is operated by {operator}", + "question": { + "en": "Who is the operator of this charging station?" + }, + "render": { + "en": "This charging station is operated by {operator}" + }, "freeform": { "key": "operator" }, @@ -407,7 +417,9 @@ "network:={operator}" ] }, - "then": "Actually, {operator} is the network", + "then": { + "en": "Actually, {operator} is the network" + }, "addExtraTags": [ "operator=" ], @@ -460,7 +472,9 @@ "question": { "en": "What is the reference number of this charging station?" }, - "render": "Reference number is {ref}", + "render": { + "en": "Reference number is {ref}" + }, "freeform": { "key": "ref" } diff --git a/assets/layers/charging_station/csvToJson.ts b/assets/layers/charging_station/csvToJson.ts index 7ea31a10f..f02033f59 100644 --- a/assets/layers/charging_station/csvToJson.ts +++ b/assets/layers/charging_station/csvToJson.ts @@ -2,6 +2,7 @@ import {readFileSync, writeFileSync} from "fs"; import {Utils} from "../../../Utils"; import {TagRenderingConfigJson} from "../../../Models/ThemeConfig/Json/TagRenderingConfigJson"; import ScriptUtils from "../../../scripts/ScriptUtils"; +import {LayerConfigJson} from "../../../Models/ThemeConfig/Json/LayerConfigJson"; function colonSplit(value: string): string[] { @@ -13,6 +14,7 @@ function loadCsv(file): { image: string, description: Map, countryWhiteList?: string[], + countryBlackList?: string[], commonVoltages?: number[], commonCurrents?: number[], commonOutputs?: string[] @@ -27,7 +29,7 @@ function loadCsv(file): { } const v = {} - const colonSeperated = ["commonVoltages", "commonOutputs", "commonCurrents", "countryWhiteList"] + const colonSeperated = ["commonVoltages", "commonOutputs", "commonCurrents", "countryWhiteList","countryBlackList"] const descriptionTranslations = new Map() for (let j = 0; j < header.length; j++) { const key = header[j]; @@ -51,7 +53,7 @@ function loadCsv(file): { function run(file, protojson) { const overview_question_answers = [] - const questions: TagRenderingConfigJson[] = [] + const questions: (TagRenderingConfigJson & {"#": string})[] = [] const filterOptions: { question: any, osmTags?: string } [] = [ { question: { @@ -62,7 +64,8 @@ function run(file, protojson) { ] const entries = loadCsv(file) - for (const e of entries) { + for (let i = 0; i < entries.length; i++){ + const e = entries[i]; const txt = { en: ` ${e.description.get("en")}`, nl: ` ${e.description.get("nl")}` @@ -73,9 +76,15 @@ function run(file, protojson) { then: txt, } - if (e.countryWhiteList !== undefined && e.countryWhiteList.length > 0) { + if(e.countryWhiteList.length > 0 && e.countryBlackList.length > 0){ + throw "Error for type "+e.key+": don't defined both a whitelist and a blacklist" + } + if (e.countryWhiteList.length > 0) { const countries = e.countryWhiteList.map(country => "_country!=" + country) //HideInAnswer if it is in the wrong country json["hideInAnswer"] = {or: countries} + }else if (e.countryBlackList .length > 0) { + const countries = e.countryBlackList.map(country => "_country=" + country) //HideInAnswer if it is in the wrong country + json["hideInAnswer"] = {or: countries} } overview_question_answers.push(json) @@ -94,6 +103,7 @@ function run(file, protojson) { const descrWithImage_nl = `${e.description.get("nl")} ` questions.push({ + "#":"plugs-"+i, question: { en: `How much plugs of type ${descrWithImage_en} are available here?`, nl: `Hoeveel stekkers van type ${descrWithImage_nl} heeft dit oplaadpunt?`, @@ -112,6 +122,7 @@ function run(file, protojson) { }) questions.push({ + "#":"voltage-"+i, question: { en: `What voltage do the plugs with ${descrWithImage_en} offer?`, nl: `Welke spanning levert de stekker van type ${descrWithImage_nl}` @@ -140,6 +151,7 @@ function run(file, protojson) { questions.push({ + "#":"current-"+i, question: { en: `What current do the plugs with ${descrWithImage_en} offer?`, nl: `Welke stroom levert de stekker van type ${descrWithImage_nl}?`, @@ -168,6 +180,7 @@ function run(file, protojson) { questions.push({ + "#":"power-output-"+i, question: { en: `What power output does a single plug of type ${descrWithImage_en} offer?`, nl: `Welk vermogen levert een enkele stekker van type ${descrWithImage_nl}?`, @@ -204,6 +217,7 @@ function run(file, protojson) { } const toggles = { + "#":"Available_charging_stations (generated)", "question": { "en": "Which charging stations are available here?" }, @@ -213,9 +227,20 @@ function run(file, protojson) { questions.unshift(toggles) const stringified = questions.map(q => JSON.stringify(q, null, " ")) - let proto = readFileSync(protojson, "utf8") - proto = proto.replace("$$$", stringified.join(",\n") + ",") - proto = JSON.parse(proto) + let protoString = readFileSync(protojson, "utf8") + + protoString = protoString.replace("{\"#\": \"$$$\"}", stringified.join(",\n")) + const proto = JSON.parse(protoString) + proto.tagRenderings.forEach(tr => { + if(typeof tr === "string"){ + return; + } + if(tr["#"] === undefined || typeof tr["#"] !== "string"){ + console.error(tr) + throw "Every tagrendering should have an id, acting as comment" + } + }) + proto["filter"].push({ options: filterOptions }) @@ -274,7 +299,8 @@ function run(file, protojson) { } proto["units"].push(...extraUnits) - writeFileSync("charging_station.json", JSON.stringify(proto, undefined, " ")) + mergeTranslations("charging_station.json",proto) + writeFileSync("charging_station.json", JSON.stringify(proto, undefined, " ")) } @@ -302,22 +328,51 @@ async function queryTagInfo(file, type, clean: ((s: string) => string)) { } const countsArray = Array.from(counts.keys()) countsArray.sort() - // console.log(`${e.key}:${type} = ${countsArray.join(";")}`) - console.log(`${countsArray.join(";")}`) + console.log(`${e.key}:${type} = ${countsArray.join(";")}`) + // console.log(`${countsArray.join(";")}`) + } +} + +/** + * Adds the translations into the 'newConfig' object + * @param origPath + * @param newConfig + */ +function mergeTranslations(origPath, newConfig: LayerConfigJson){ + const oldFile = JSON.parse(readFileSync(origPath, "utf-8")) + const newFile = newConfig + const renderingsOld = oldFile.tagRenderings + delete oldFile.tagRenderings + const newRenderings = newFile.tagRenderings + Utils.Merge(oldFile, newFile) + + for (const oldRendering of renderingsOld) { + + const oldRenderingName = oldRendering["#"] + if(oldRenderingName === undefined){ + continue + } + const applicable = newRenderings.filter(r => r["#"] === oldRenderingName)[0] + if(applicable === undefined){ + continue; + } + Utils.Merge(oldRendering, applicable) } } try { run("types.csv", "charging_station.protojson") - // queryTagInfo("types.csv","voltage", true) - // queryTagInfo("types.csv", "current", true) - /* queryTagInfo("types.csv", "output", s => { + /*/ + queryTagInfo("types.csv","voltage", s => s.trim()) + queryTagInfo("types.csv", "current", s => s.trim()) + queryTagInfo("types.csv", "output", s => { if(s.endsWith("kW")){ s = s.substring(0, s.length - 2) } s = s.trim() return s + " kW" - })*/ + }) + //*/ } catch (e) { console.error(e) diff --git a/assets/layers/charging_station/types.csv b/assets/layers/charging_station/types.csv index 5cf989085..4b76be6a7 100644 --- a/assets/layers/charging_station/types.csv +++ b/assets/layers/charging_station/types.csv @@ -1,10 +1,14 @@ -key,image,description:en,countryWhitelist,commonVoltages,commonCurrents,commonOutputs,description:nl -socket:schuko,CEE7_4F.svg,Schuko wall plug without ground pin (CEE7/4 type F),be;fr;ma;tn;pl;cs;sk;mo,230,16,3.6 kW,Schuko stekker zonder aardingspin (CEE7/4 type F) -socket:typee,TypeE.svg,European wall plug with ground pin (CEE7/4 type E),,230,16,3 kW;22 kW;,Europese stekker met aardingspin (CEE7/4 type E) -socket:chademo,Chademo_type4.svg,Chademo,,500,120,50 kW, -socket:type1_cable,Type1_J1772.svg,Type 1 with cable (J1772),,200;240,32,3.7 kW;7 kW,Type 1 met kabel (J1772) -socket:type1,Type1_J1772.svg,Type 1 without cable (J1772),,200;240,32,3.7 kW;6.6 kW;7 kW;7.2 kW,Type 1 zonder kabel (J1772) -socket:type1_combo,Type1-ccs.svg,Type 1 CCS (aka Type 1 Combo),,400;1000,50;125,50 kW;62.5 kW;150 kW;350 kW;, -socket:tesla_supercharger,Tesla-hpwc-model-s.svg,Tesla Supercharger,,480,125;350,120 kW;150 kW;250 kW, -socket:type2,Type2_socket.svg,Type 2 (mennekes),,230;400,16;32,11 kW;22 kW, -socket:type2_combo,Type2_CCS.svg,Type 2 CCS (mennekes),,500;920,125;350,50 kW, +key,image,description:en,countryWhiteList,countryBlackList,commonVoltages,commonCurrents,commonOutputs,description:nl +socket:schuko,CEE7_4F.svg,Schuko wall plug without ground pin (CEE7/4 type F),be;fr;ma;tn;pl;cs;sk;mo,,230,16,3.6 kW,Schuko stekker zonder aardingspin (CEE7/4 type F) +socket:typee,TypeE.svg,European wall plug with ground pin (CEE7/4 type E),,,230,16,3 kW;22 kW;,Europese stekker met aardingspin (CEE7/4 type E) +socket:chademo,Chademo_type4.svg,Chademo,,,500,120,50 kW, +socket:type1_cable,Type1_J1772.svg,Type 1 with cable (J1772),,,200;240,32,3.7 kW;7 kW,Type 1 met kabel (J1772) +socket:type1,Type1_J1772.svg,Type 1 without cable (J1772),,,200;240,32,3.7 kW;6.6 kW;7 kW;7.2 kW,Type 1 zonder kabel (J1772) +socket:type1_combo,Type1-ccs.svg,Type 1 CCS (aka Type 1 Combo),,,400;1000,50;125,50 kW;62.5 kW;150 kW;350 kW;, +socket:tesla_supercharger,Tesla-hpwc-model-s.svg,Tesla Supercharger,,,480,125;350,120 kW;150 kW;250 kW, +socket:type2,Type2_socket.svg,Type 2 (mennekes),,,230;400,16;32,11 kW;22 kW, +socket:type2_combo,Type2_CCS.svg,Type 2 CCS (mennekes),,,500;920,125;350,50 kW, +socket:type2_cable,Type2_tethered.svg,Type 2 with cable (mennekes),,,230;400,16;32,11 kW;22 kW,Type 2 met kabel (J1772) +socket:tesla_supercharger_ccs,Type2_CCS.svg,Tesla Supercharger CCS (a branded type2_css),,,500;920,125;350,50 kW, +socket:tesla_destination,Tesla-hpwc-model-s.svg,Tesla Supercharger (destination),us,,480,125;350,120 kW;150 kW;250 kW, +socket:tesla_destination,Type2_tethered.svg,Tesla supercharger (destination (A Type 2 with cable branded as tesla),,us,230;400,16;32,11 kW;22 kW, From 5509b56de8b539489f7eec6bfa3475b5ba1c6042 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 22 Sep 2021 20:13:54 +0200 Subject: [PATCH 07/65] Add membership card as payment option --- assets/layers/charging_station/charging_station.protojson | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/assets/layers/charging_station/charging_station.protojson b/assets/layers/charging_station/charging_station.protojson index 536c876f1..39714ef8a 100644 --- a/assets/layers/charging_station/charging_station.protojson +++ b/assets/layers/charging_station/charging_station.protojson @@ -333,6 +333,14 @@ "en": "Payment is done using a dedicated app", "nl": "Betalen via een app van het netwerk" } + }, + { + "if": "payment:membership_card=yes", + "ifnot": "payment:membership_card=no", + "then": { + "en": "Payment is done using a membership card", + "nl": "Betalen via een lidkaart van het netwerk" + } } ] } From b1900cdbc660fe4d8d9ece956d2d48c1990ac204 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 22 Sep 2021 20:44:53 +0200 Subject: [PATCH 08/65] Small robustifications --- Models/ThemeConfig/LayerConfig.ts | 9 ++++++--- UI/Base/MinimapImplementation.ts | 16 ++++++++++++---- .../charging_station/charging_station.protojson | 4 +++- assets/themes/uk_addresses/uk_addresses.json | 7 +------ 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/Models/ThemeConfig/LayerConfig.ts b/Models/ThemeConfig/LayerConfig.ts index c3cadc1e0..18c9fe3b4 100644 --- a/Models/ThemeConfig/LayerConfig.ts +++ b/Models/ThemeConfig/LayerConfig.ts @@ -154,6 +154,9 @@ export default class LayerConfig { this.minzoom = json.minzoom ?? 0; this.minzoomVisible = json.minzoomVisible ?? this.minzoom; this.wayHandling = json.wayHandling ?? 0; + if(json.presets !== undefined && json.presets?.map === undefined){ + throw "Presets should be a list of items (at "+context+")" + } this.presets = (json.presets ?? []).map((pr, i) => { let preciseInput = undefined; @@ -492,8 +495,8 @@ export default class LayerConfig { const iconUrlStatic = render(this.icon); const self = this; - function genHtmlFromString(sourcePart: string, rotation: string): BaseUIElement { - const style = `width:100%;height:100%;transform: rotate( ${rotation} );display:block;position: absolute; top: 0; left: 0`; + function genHtmlFromString(sourcePart: string, rotation: string, style?: string): BaseUIElement { + style = style ?? `width:100%;height:100%;transform: rotate( ${rotation} );display:block;position: absolute; top: 0; left: 0`; let html: BaseUIElement = new FixedUiElement( `` ); @@ -537,7 +540,7 @@ export default class LayerConfig { .filter((prt) => prt != ""); for (const badgePartStr of partDefs) { - badgeParts.push(genHtmlFromString(badgePartStr, "0")); + badgeParts.push(genHtmlFromString(badgePartStr, "0", `width:unset;height:100%;display:block;`)); } const badgeCompound = new Combine(badgeParts).SetStyle( diff --git a/UI/Base/MinimapImplementation.ts b/UI/Base/MinimapImplementation.ts index 00fbc0f09..1761d1ada 100644 --- a/UI/Base/MinimapImplementation.ts +++ b/UI/Base/MinimapImplementation.ts @@ -50,7 +50,7 @@ export default class MinimapImplementation extends BaseUIElement implements Mini if (typeof factor === "number") { bounds = leaflet.getBounds() leaflet.setMaxBounds(bounds.pad(factor)) - }else{ + } else { // @ts-ignore leaflet.setMaxBounds(factor.toLeaflet()) bounds = leaflet.getBounds() @@ -114,8 +114,12 @@ export default class MinimapImplementation extends BaseUIElement implements Mini const self = this; // @ts-ignore const resizeObserver = new ResizeObserver(_ => { - self.InitMap(); - self.leafletMap?.data?.invalidateSize() + try { + self.InitMap(); + self.leafletMap?.data?.invalidateSize() + } catch (e) { + console.error("Could not construct a minimap:", e) + } }); resizeObserver.observe(div); @@ -141,8 +145,12 @@ export default class MinimapImplementation extends BaseUIElement implements Mini const location = this._location; const self = this; let currentLayer = this._background.data.layer() + let latLon = <[number, number]>[location.data?.lat ?? 0, location.data?.lon ?? 0] + if(isNaN(latLon[0]) || isNaN(latLon[1])){ + latLon = [0,0] + } const options = { - center: <[number, number]>[location.data?.lat ?? 0, location.data?.lon ?? 0], + center: latLon, zoom: location.data?.zoom ?? 2, layers: [currentLayer], zoomControl: false, diff --git a/assets/layers/charging_station/charging_station.protojson b/assets/layers/charging_station/charging_station.protojson index 39714ef8a..f33620e80 100644 --- a/assets/layers/charging_station/charging_station.protojson +++ b/assets/layers/charging_station/charging_station.protojson @@ -538,7 +538,9 @@ } }, { - "if": "amenity=charging_station", + "if": { + "and": ["amenity=charging_station","operational_status="] + }, "then": { "en": "This charging station works", "nl": "Dit oplaadpunt werkt" diff --git a/assets/themes/uk_addresses/uk_addresses.json b/assets/themes/uk_addresses/uk_addresses.json index e43f867ed..b89d25e60 100644 --- a/assets/themes/uk_addresses/uk_addresses.json +++ b/assets/themes/uk_addresses/uk_addresses.json @@ -213,12 +213,7 @@ "then": "#ff0" } ] - }, - "presets": [ - { - - } - ] + } }, { "id": "named_streets", From 3780c5d38049ce904e7ba1a39adbcf63af70ad14 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Thu, 23 Sep 2021 20:45:57 +0200 Subject: [PATCH 09/65] remove incorrect return value which causes unregistering of the callback --- UI/Base/VariableUIElement.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/Base/VariableUIElement.ts b/UI/Base/VariableUIElement.ts index fbc3bb564..144459a75 100644 --- a/UI/Base/VariableUIElement.ts +++ b/UI/Base/VariableUIElement.ts @@ -17,7 +17,7 @@ export class VariableUiElement extends BaseUIElement { } if (contents === undefined) { - return el; + return } if (typeof contents === "string") { el.innerHTML = contents; From c5e9448720f5b1afd0ea8b380492be3300dc2a1d Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 17:36:39 +0200 Subject: [PATCH 10/65] Add initial clustering per tile, very broken --- Docs/Tools/GenerateSeries.ts | 4 +- InitUiElements.ts | 118 +++++-- Logic/Actors/OverpassFeatureSource.ts | 79 +++-- Logic/ExtraFunction.ts | 5 +- Logic/FeatureSource/FeaturePipeline.ts | 31 +- .../Sources/FeatureSourceMerger.ts | 3 +- .../Sources/FilteringFeatureSource.ts | 26 +- Logic/FeatureSource/Sources/GeoJsonSource.ts | 6 +- .../Sources/RememberingSource.ts | 14 +- .../Sources/SimpleFeatureSource.ts | 3 +- .../Sources/StaticFeatureSource.ts | 7 +- .../WayHandlingApplyingFeatureSource.ts | 5 +- .../DynamicGeoJsonTileSource.ts | 4 +- .../TiledFeatureSource/DynamicTileSource.ts | 7 +- .../TiledFeatureSource/TileHierarchyMerger.ts | 5 +- .../TiledFeatureSource/TiledFeatureSource.ts | 17 +- .../TiledFromLocalStorageSource.ts | 13 +- Logic/GeoOperations.ts | 11 +- .../ImageProviders/ImageAttributionSource.ts | 9 +- Logic/ImageProviders/Imgur.ts | 52 +-- Logic/ImageProviders/Mapillary.ts | 53 ++- Logic/ImageProviders/Wikimedia.ts | 46 +-- Logic/MetaTagging.ts | 66 ++-- Logic/Osm/OsmConnection.ts | 1 + Logic/SimpleMetaTagger.ts | 52 +-- Models/Constants.ts | 1 + Models/ThemeConfig/LayerConfig.ts | 12 +- Models/ThemeConfig/LayoutConfig.ts | 4 +- Models/TileRange.ts | 102 ++++++ UI/Base/ScrollableFullScreen.ts | 2 + UI/Base/VariableUIElement.ts | 22 +- UI/BaseUIElement.ts | 2 - UI/Image/Attribution.ts | 11 +- UI/Image/DeleteImage.ts | 2 +- UI/Input/LocationInput.ts | 1 - UI/Popup/EditableTagRendering.ts | 6 +- UI/Popup/SplitRoadWizard.ts | 2 +- UI/ShowDataLayer/PerTileCountAggregator.ts | 156 +++++++++ UI/ShowDataLayer/ShowDataLayer.ts | 37 ++- UI/ShowDataLayer/ShowDataLayerOptions.ts | 1 + UI/ShowDataLayer/ShowTileInfo.ts | 79 +++++ Utils.ts | 105 +----- .../charging_station/charging_station.json | 136 +++++--- .../layers/drinking_water/drinking_water.json | 307 +++++++++--------- assets/layers/food/food.json | 1 + .../public_bookcase/public_bookcase.json | 2 +- assets/themes/benches/benches.json | 2 +- assets/themes/bicyclelib/bicyclelib.json | 2 +- .../bike_monitoring_stations.json | 2 +- assets/themes/binoculars/binoculars.json | 2 +- assets/themes/buurtnatuur/buurtnatuur.json | 2 +- .../themes/cafes_and_pubs/cafes_and_pubs.json | 2 +- assets/themes/campersite/campersite.json | 2 +- .../charging_stations/charging_stations.json | 2 +- assets/themes/climbing/climbing.json | 2 +- .../themes/cycle_highways/cycle_highways.json | 2 +- assets/themes/cycle_infra/cycle_infra.json | 2 +- assets/themes/cyclofix/cyclofix.json | 2 +- .../themes/facadegardens/facadegardens.json | 2 +- assets/themes/food/food.json | 2 +- assets/themes/fritures/fritures.json | 2 +- assets/themes/fruit_trees/fruit_trees.json | 2 +- assets/themes/ghostbikes/ghostbikes.json | 2 +- assets/themes/grb.json | 2 +- assets/themes/hackerspaces/hackerspaces.json | 2 +- assets/themes/hailhydrant/hailhydrant.json | 2 +- assets/themes/maps/maps.json | 2 +- assets/themes/nature/nature.json | 2 +- assets/themes/natuurpunt/natuurpunt.json | 2 +- .../observation_towers.json | 2 +- assets/themes/parkings/parkings.json | 2 +- assets/themes/personal/personal.json | 2 +- assets/themes/play_forests/play_forests.json | 2 +- assets/themes/playgrounds/playgrounds.json | 2 +- assets/themes/shops/shops.json | 2 +- assets/themes/speelplekken/speelplekken.json | 2 +- .../speelplekken/speelplekken_temp.json | 2 +- .../themes/sport_pitches/sport_pitches.json | 2 +- assets/themes/surveillance/surveillance.json | 2 +- .../toerisme_vlaanderen.json | 2 +- assets/themes/toilets/toilets.json | 2 +- assets/themes/trees/trees.json | 2 +- assets/themes/uk_addresses/uk_addresses.json | 2 +- assets/themes/waste_basket/waste_basket.json | 2 +- assets/themes/widths/width.json | 2 +- scripts/ScriptUtils.ts | 7 +- scripts/generateCache.ts | 12 +- scripts/generateTranslations.ts | 6 +- 88 files changed, 1080 insertions(+), 651 deletions(-) create mode 100644 UI/ShowDataLayer/PerTileCountAggregator.ts create mode 100644 UI/ShowDataLayer/ShowTileInfo.ts diff --git a/Docs/Tools/GenerateSeries.ts b/Docs/Tools/GenerateSeries.ts index 5cced5a6b..73e97e9a4 100644 --- a/Docs/Tools/GenerateSeries.ts +++ b/Docs/Tools/GenerateSeries.ts @@ -75,9 +75,7 @@ class StatsDownloader { while (url) { ScriptUtils.erasableLog(`Downloading stats for ${year}-${month}, page ${page} ${url}`) - const result = await ScriptUtils.DownloadJSON(url, { - headers: headers - }) + const result = await ScriptUtils.DownloadJSON(url, headers) page++; allFeatures.push(...result.features) if (result.features === undefined) { diff --git a/InitUiElements.ts b/InitUiElements.ts index c36b22b77..0bc6506d1 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -15,7 +15,6 @@ import Link from "./UI/Base/Link"; import * as personal from "./assets/themes/personal/personal.json"; import * as L from "leaflet"; import Img from "./UI/Base/Img"; -import UserDetails from "./Logic/Osm/OsmConnection"; import Attribution from "./UI/BigComponents/Attribution"; import BackgroundLayerResetter from "./Logic/Actors/BackgroundLayerResetter"; import FullWelcomePaneWithTabs from "./UI/BigComponents/FullWelcomePaneWithTabs"; @@ -38,6 +37,9 @@ import Minimap from "./UI/Base/Minimap"; import SelectedFeatureHandler from "./Logic/Actors/SelectedFeatureHandler"; import Combine from "./UI/Base/Combine"; import {SubtleButton} from "./UI/Base/SubtleButton"; +import ShowTileInfo from "./UI/ShowDataLayer/ShowTileInfo"; +import {Tiles} from "./Models/TileRange"; +import PerTileCountAggregator from "./UI/ShowDataLayer/PerTileCountAggregator"; export class InitUiElements { static InitAll( @@ -167,22 +169,38 @@ export class InitUiElements { ).AttachTo("messagesbox"); } - State.state.osmConnection.userDetails - .map((userDetails: UserDetails) => userDetails?.home) - .addCallbackAndRunD((home) => { - const color = getComputedStyle(document.body).getPropertyValue( - "--subtle-detail-color" - ); - const icon = L.icon({ - iconUrl: Img.AsData( - Svg.home_white_bg.replace(/#ffffff/g, color) - ), - iconSize: [30, 30], - iconAnchor: [15, 15], - }); - const marker = L.marker([home.lat, home.lon], {icon: icon}); - marker.addTo(State.state.leafletMap.data); + function addHomeMarker() { + const userDetails = State.state.osmConnection.userDetails.data; + if (userDetails === undefined) { + return false; + } + console.log("Adding home location of ", userDetails) + const home = userDetails.home; + if (home === undefined) { + return userDetails.loggedIn; // If logged in, the home is not set and we unregister. If not logged in, we stay registered if a login still comes + } + const leaflet = State.state.leafletMap.data; + if (leaflet === undefined) { + return false; + } + const color = getComputedStyle(document.body).getPropertyValue( + "--subtle-detail-color" + ); + const icon = L.icon({ + iconUrl: Img.AsData( + Svg.home_white_bg.replace(/#ffffff/g, color) + ), + iconSize: [30, 30], + iconAnchor: [15, 15], }); + const marker = L.marker([home.lat, home.lon], {icon: icon}); + marker.addTo(leaflet); + return true; + } + + State.state.osmConnection.userDetails + .addCallbackAndRunD(_ => addHomeMarker()); + State.state.leafletMap.addCallbackAndRunD(_ => addHomeMarker()) if (layoutToUse.id === personal.id) { updateFavs(); @@ -209,7 +227,7 @@ export class InitUiElements { static LoadLayoutFromHash( userLayoutParam: UIEventSource ): [LayoutConfig, string] { - let hash = location.hash.substr(1); + let hash = location.hash.substr(1); try { const layoutFromBase64 = userLayoutParam.data; // layoutFromBase64 contains the name of the theme. This is partly to do tracking with goat counter @@ -249,18 +267,18 @@ export class InitUiElements { userLayoutParam.setData(layoutToUse.id); return [layoutToUse, btoa(Utils.MinifyJSON(JSON.stringify(json)))]; } catch (e) { - - if(hash === undefined || hash.length < 10){ + + if (hash === undefined || hash.length < 10) { e = "Did you effectively add a theme? It seems no data could be found." } - + new Combine([ "Error: could not parse the custom layout:", - new FixedUiElement(""+e).SetClass("alert"), - new SubtleButton("./assets/svg/mapcomplete_logo.svg", - "Go back to the theme overview", - {url: window.location.protocol+"//"+ window.location.hostname+"/index.html", newTab: false}) - + new FixedUiElement("" + e).SetClass("alert"), + new SubtleButton("./assets/svg/mapcomplete_logo.svg", + "Go back to the theme overview", + {url: window.location.protocol + "//" + window.location.hostname + "/index.html", newTab: false}) + ]) .SetClass("flex flex-col") .AttachTo("centermessage"); @@ -361,12 +379,12 @@ export class InitUiElements { const layout = State.state.layoutToUse.data; if (layout.lockLocation) { if (layout.lockLocation === true) { - const tile = Utils.embedded_tile( + const tile = Tiles.embedded_tile( layout.startLat, layout.startLon, layout.startZoom - 1 ); - const bounds = Utils.tile_bounds(tile.z, tile.x, tile.y); + const bounds = Tiles.tile_bounds(tile.z, tile.x, tile.y); // We use the bounds to get a sense of distance for this zoom level const latDiff = bounds[0][0] - bounds[1][0]; const lonDiff = bounds[0][1] - bounds[1][1]; @@ -402,6 +420,9 @@ export class InitUiElements { const flayer = { isDisplayed: isDisplayed, layerDef: layer, + isSufficientlyZoomed: state.locationControl.map(l => { + return l.zoom >= (layer.minzoomVisible ?? layer.minzoom) + }), appliedFilters: new UIEventSource(undefined), }; flayers.push(flayer); @@ -409,13 +430,54 @@ export class InitUiElements { return flayers; }); + const clusterCounter = new PerTileCountAggregator(State.state.locationControl.map(l => { + const z = l.zoom + 1 + if(z < 7){ + return 7 + } + return z + })) + const clusterShow = Math.min(...State.state.layoutToUse.data.layers.map(layer => layer.minzoomVisible ?? layer.minzoom)) + new ShowDataLayer({ + features: clusterCounter, + leafletMap: State.state.leafletMap, + layerToShow: ShowTileInfo.styling, + doShowLayer: State.state.locationControl.map(l => l.zoom < clusterShow) + }) State.state.featurePipeline = new FeaturePipeline( source => { + const clustering = State.state.layoutToUse.data.clustering + const doShowFeatures = source.features.map( + f => { + const z = State.state.locationControl.data.zoom + if(z >= clustering.maxZoom){ + return true + } + if(z < source.layer.layerDef.minzoom){ + return false; + } + if(f.length > clustering.minNeededElements){ + console.log("Activating clustering for tile ", Tiles.tile_from_index(source.tileIndex)," as it has ", f.length, "features (clustering starts at)", clustering.minNeededElements) + return false + } + + return true + }, [State.state.locationControl] + ) + clusterCounter.addTile(source, doShowFeatures.map(b => !b)) + + /* + new ShowTileInfo({source: source, + leafletMap: State.state.leafletMap, + layer: source.layer.layerDef, + doShowLayer: doShowFeatures.map(b => !b) + })*/ new ShowDataLayer( { features: source, leafletMap: State.state.leafletMap, - layerToShow: source.layer.layerDef + layerToShow: source.layer.layerDef, + doShowLayer: doShowFeatures } ); }, state diff --git a/Logic/Actors/OverpassFeatureSource.ts b/Logic/Actors/OverpassFeatureSource.ts index 1e7ace7cd..7ddafacd8 100644 --- a/Logic/Actors/OverpassFeatureSource.ts +++ b/Logic/Actors/OverpassFeatureSource.ts @@ -24,9 +24,9 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour public readonly sufficientlyZoomed: UIEventSource; public readonly runningQuery: UIEventSource = new UIEventSource(false); public readonly timeout: UIEventSource = new UIEventSource(0); - + public readonly relationsTracker: RelationsTracker; - + private readonly retries: UIEventSource = new UIEventSource(0); /** @@ -44,7 +44,6 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; } - /** * The most important layer should go first, as that one gets first pick for the questions */ @@ -57,6 +56,7 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour readonly overpassTimeout: UIEventSource; readonly overpassMaxZoom: UIEventSource }) { + console.trace("Initializing an overpass FS") this.state = state @@ -153,7 +153,12 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour return new Overpass(new Or(filters), extraScripts, this.state.overpassUrl, this.state.overpassTimeout, this.relationsTracker); } - private update(): void { + private update() { + this.updateAsync().then(_ => { + }) + } + + private async updateAsync(): Promise { if (this.runningQuery.data) { console.log("Still running a query, not updating"); return; @@ -179,54 +184,46 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour const self = this; const overpass = this.GetFilter(); - + if (overpass === undefined) { return; } this.runningQuery.setData(true); - overpass.queryGeoJson(queryBounds). - then(([data, date]) => { - self._previousBounds.get(z).push(queryBounds); - self.retries.setData(0); - const features = data.features.map(f => ({feature: f, freshness: date})); - SimpleMetaTagger.objectMetaInfo.addMetaTags(features) - try{ - self.features.setData(features); - }catch(e){ - console.error("Got the overpass response, but could not process it: ", e, e.stack) - } - self.runningQuery.setData(false); - }) - .catch((reason) => { + let data: any = undefined + let date: Date = undefined + + do { + + try { + [data, date] = await overpass.queryGeoJson(queryBounds) + } catch (e) { + console.error(`QUERY FAILED (retrying in ${5 * self.retries.data} sec) due to`, e); + self.retries.data++; - self.ForceRefresh(); - self.timeout.setData(self.retries.data * 5); - console.error(`QUERY FAILED (retrying in ${5 * self.retries.data} sec) due to`, reason); self.retries.ping(); + + self.timeout.setData(self.retries.data * 5); self.runningQuery.setData(false); - function countDown() { - window?.setTimeout( - function () { - if (self.timeout.data > 1) { - self.timeout.setData(self.timeout.data - 1); - window.setTimeout( - countDown, - 1000 - ) - } else { - self.timeout.setData(0); - self.update() - } - }, 1000 - ) + while (self.timeout.data > 0) { + await Utils.waitFor(1000) + self.timeout.data-- + self.timeout.ping(); } - - countDown(); - } - ); + } while (data === undefined); + + self._previousBounds.get(z).push(queryBounds); + self.retries.setData(0); + + try { + data.features.forEach(feature => SimpleMetaTagger.objectMetaInfo.applyMetaTagsOnFeature(feature, date)); + self.features.setData(data.features.map(f => ({feature: f, freshness: date}))); + } catch (e) { + console.error("Got the overpass response, but could not process it: ", e, e.stack) + } + self.runningQuery.setData(false); } diff --git a/Logic/ExtraFunction.ts b/Logic/ExtraFunction.ts index 04f7a64f6..5839fca08 100644 --- a/Logic/ExtraFunction.ts +++ b/Logic/ExtraFunction.ts @@ -256,7 +256,7 @@ export class ExtraFunction { let closestFeatures: { feat: any, distance: number }[] = []; for(const featureList of features) { for (const otherFeature of featureList) { - if (otherFeature == feature || otherFeature.id == feature.id) { + if (otherFeature === feature || otherFeature.id === feature.id) { continue; // We ignore self } let distance = undefined; @@ -268,7 +268,8 @@ export class ExtraFunction { [feature._lon, feature._lat] ) } - if (distance === undefined) { + if (distance === undefined || distance === null) { + console.error("Could not calculate the distance between", feature, "and", otherFeature) throw "Undefined distance!" } if (distance > maxDistance) { diff --git a/Logic/FeatureSource/FeaturePipeline.ts b/Logic/FeatureSource/FeaturePipeline.ts index c6206eac4..1e033dad7 100644 --- a/Logic/FeatureSource/FeaturePipeline.ts +++ b/Logic/FeatureSource/FeaturePipeline.ts @@ -37,7 +37,7 @@ export default class FeaturePipeline implements FeatureSourceState { private readonly perLayerHierarchy: Map; constructor( - handleFeatureSource: (source: FeatureSourceForLayer) => void, + handleFeatureSource: (source: FeatureSourceForLayer & Tiled) => void, state: { filteredLayers: UIEventSource, locationControl: UIEventSource, @@ -52,7 +52,6 @@ export default class FeaturePipeline implements FeatureSourceState { const self = this const updater = new OverpassFeatureSource(state); - updater.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(updater)) this.overpassUpdater = updater; this.sufficientlyZoomed = updater.sufficientlyZoomed this.runningQuery = updater.runningQuery @@ -65,14 +64,15 @@ export default class FeaturePipeline implements FeatureSourceState { const perLayerHierarchy = new Map() this.perLayerHierarchy = perLayerHierarchy - const patchedHandleFeatureSource = function (src: FeatureSourceForLayer & IndexedFeatureSource) { + const patchedHandleFeatureSource = function (src: FeatureSourceForLayer & IndexedFeatureSource & Tiled) { // This will already contain the merged features for this tile. In other words, this will only be triggered once for every tile const srcFiltered = - new FilteringFeatureSource(state, + new FilteringFeatureSource(state, src.tileIndex, new WayHandlingApplyingFeatureSource( new ChangeGeometryApplicator(src, state.changes) ) ) + handleFeatureSource(srcFiltered) self.somethingLoaded.setData(true) }; @@ -102,10 +102,12 @@ export default class FeaturePipeline implements FeatureSourceState { if (source.geojsonZoomLevel === undefined) { // This is a 'load everything at once' geojson layer - // We split them up into tiles + // We split them up into tiles anyway const src = new GeoJsonSource(filteredLayer) TiledFeatureSource.createHierarchy(src, { layer: src.layer, + minZoomLevel:14, + dontEnforceMinZoom: true, registerTile: (tile) => { new RegisteringAllFromFeatureSourceActor(tile) addToHierarchy(tile, id) @@ -115,14 +117,11 @@ export default class FeaturePipeline implements FeatureSourceState { } else { new DynamicGeoJsonTileSource( filteredLayer, - src => TiledFeatureSource.createHierarchy(src, { - layer: src.layer, - registerTile: (tile) => { + tile => { new RegisteringAllFromFeatureSourceActor(tile) addToHierarchy(tile, id) tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) - } - }), + }, state ) } @@ -133,13 +132,17 @@ export default class FeaturePipeline implements FeatureSourceState { new PerLayerFeatureSourceSplitter(state.filteredLayers, (source) => TiledFeatureSource.createHierarchy(source, { layer: source.layer, + minZoomLevel: 14, + dontEnforceMinZoom: true, registerTile: (tile) => { // We save the tile data for the given layer to local storage new SaveTileToLocalStorageActor(tile, tile.tileIndex) - addToHierarchy(tile, source.layer.layerDef.id); + addToHierarchy(new RememberingSource(tile), source.layer.layerDef.id); + tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) + } }), - new RememberingSource(updater)) + updater) // Also load points/lines that are newly added. @@ -152,6 +155,8 @@ export default class FeaturePipeline implements FeatureSourceState { addToHierarchy(perLayer, perLayer.layer.layerDef.id) // AT last, we always apply the metatags whenever possible perLayer.features.addCallbackAndRunD(_ => self.applyMetaTags(perLayer)) + perLayer.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(perLayer)) + }, newGeometry ) @@ -166,6 +171,7 @@ export default class FeaturePipeline implements FeatureSourceState { private applyMetaTags(src: FeatureSourceForLayer){ const self = this + console.log("Applying metatagging onto ", src.name) MetaTagging.addMetatags( src.features.data, { @@ -183,6 +189,7 @@ export default class FeaturePipeline implements FeatureSourceState { private updateAllMetaTagging() { const self = this; + console.log("Reupdating all metatagging") this.perLayerHierarchy.forEach(hierarchy => { hierarchy.loadedTiles.forEach(src => { self.applyMetaTags(src) diff --git a/Logic/FeatureSource/Sources/FeatureSourceMerger.ts b/Logic/FeatureSource/Sources/FeatureSourceMerger.ts index fb349ae5d..44ae28543 100644 --- a/Logic/FeatureSource/Sources/FeatureSourceMerger.ts +++ b/Logic/FeatureSource/Sources/FeatureSourceMerger.ts @@ -7,6 +7,7 @@ import FeatureSource, {FeatureSourceForLayer, IndexedFeatureSource, Tiled} from import FilteredLayer from "../../../Models/FilteredLayer"; import {BBox} from "../../GeoOperations"; import {Utils} from "../../../Utils"; +import {Tiles} from "../../../Models/TileRange"; export default class FeatureSourceMerger implements FeatureSourceForLayer, Tiled, IndexedFeatureSource { @@ -23,7 +24,7 @@ export default class FeatureSourceMerger implements FeatureSourceForLayer, Tiled this.bbox = bbox; this._sources = sources; this.layer = layer; - this.name = "FeatureSourceMerger("+layer.layerDef.id+", "+Utils.tile_from_index(tileIndex).join(",")+")" + this.name = "FeatureSourceMerger("+layer.layerDef.id+", "+Tiles.tile_from_index(tileIndex).join(",")+")" const self = this; const handledSources = new Set(); diff --git a/Logic/FeatureSource/Sources/FilteringFeatureSource.ts b/Logic/FeatureSource/Sources/FilteringFeatureSource.ts index 6848f9f26..70d5a566c 100644 --- a/Logic/FeatureSource/Sources/FilteringFeatureSource.ts +++ b/Logic/FeatureSource/Sources/FilteringFeatureSource.ts @@ -1,24 +1,29 @@ import {UIEventSource} from "../../UIEventSource"; import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"; import FilteredLayer from "../../../Models/FilteredLayer"; -import {FeatureSourceForLayer} from "../FeatureSource"; +import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; import Hash from "../../Web/Hash"; +import {BBox} from "../../GeoOperations"; -export default class FilteringFeatureSource implements FeatureSourceForLayer { +export default class FilteringFeatureSource implements FeatureSourceForLayer , Tiled { public features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); public readonly name; public readonly layer: FilteredLayer; - +public readonly tileIndex : number + public readonly bbox : BBox constructor( state: { locationControl: UIEventSource<{ zoom: number }>, selectedElement: UIEventSource, }, + tileIndex, upstream: FeatureSourceForLayer ) { const self = this; this.name = "FilteringFeatureSource("+upstream.name+")" + this.tileIndex = tileIndex + this.bbox = BBox.fromTileIndex(tileIndex) this.layer = upstream.layer; const layer = upstream.layer; @@ -51,7 +56,7 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer { return false; } } - if (!FilteringFeatureSource.showLayer(layer, state.locationControl.data)) { + if (!layer.isDisplayed) { // The layer itself is either disabled or hidden due to zoom constraints // We should return true, but it might still match some other layer return false; @@ -66,10 +71,7 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer { update(); }); - let isShown = state.locationControl.map((l) => FilteringFeatureSource.showLayer(layer, l), - [layer.isDisplayed]) - - isShown.addCallback(isShown => { + layer.isDisplayed.addCallback(isShown => { if (isShown) { update(); } else { @@ -78,7 +80,7 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer { }); layer.appliedFilters.addCallback(_ => { - if(!isShown.data){ + if(!layer.isDisplayed.data){ // Currently not shown. // Note that a change in 'isSHown' will trigger an update as well, so we don't have to watch it another time return; @@ -93,10 +95,8 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer { layer: { isDisplayed: UIEventSource; layerDef: LayerConfig; - }, - location: { zoom: number }) { - return layer.isDisplayed.data && - layer.layerDef.minzoomVisible <= location.zoom; + }) { + return layer.isDisplayed.data; } } diff --git a/Logic/FeatureSource/Sources/GeoJsonSource.ts b/Logic/FeatureSource/Sources/GeoJsonSource.ts index e6d24fbca..6222fc729 100644 --- a/Logic/FeatureSource/Sources/GeoJsonSource.ts +++ b/Logic/FeatureSource/Sources/GeoJsonSource.ts @@ -6,6 +6,7 @@ import FilteredLayer from "../../../Models/FilteredLayer"; import {Utils} from "../../../Utils"; import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; import {BBox} from "../../GeoOperations"; +import {Tiles} from "../../../Models/TileRange"; export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { @@ -35,10 +36,10 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { .replace('{z}', "" + z) .replace('{x}', "" + x) .replace('{y}', "" + y) - this.tileIndex = Utils.tile_index(z, x, y) + this.tileIndex = Tiles.tile_index(z, x, y) this.bbox = BBox.fromTile(z, x, y) } else { - this.tileIndex = Utils.tile_index(0, 0, 0) + this.tileIndex = Tiles.tile_index(0, 0, 0) this.bbox = BBox.global; } @@ -89,7 +90,6 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { newFeatures.push({feature: feature, freshness: freshness}) } - console.debug("Downloaded " + newFeatures.length + " new features and " + skipped + " already seen features from " + url); if (newFeatures.length == 0) { return; diff --git a/Logic/FeatureSource/Sources/RememberingSource.ts b/Logic/FeatureSource/Sources/RememberingSource.ts index 99f422478..b31097061 100644 --- a/Logic/FeatureSource/Sources/RememberingSource.ts +++ b/Logic/FeatureSource/Sources/RememberingSource.ts @@ -2,17 +2,23 @@ * Every previously added point is remembered, but new points are added. * Data coming from upstream will always overwrite a previous value */ -import FeatureSource from "../FeatureSource"; +import FeatureSource, {Tiled} from "../FeatureSource"; import {UIEventSource} from "../../UIEventSource"; +import {BBox} from "../../GeoOperations"; -export default class RememberingSource implements FeatureSource { +export default class RememberingSource implements FeatureSource , Tiled{ public readonly features: UIEventSource<{ feature: any, freshness: Date }[]>; public readonly name; - - constructor(source: FeatureSource) { + public readonly tileIndex : number + public readonly bbox : BBox + + constructor(source: FeatureSource & Tiled) { const self = this; this.name = "RememberingSource of " + source.name; + this.tileIndex= source.tileIndex + this.bbox = source.bbox; + const empty = []; this.features = source.features.map(features => { const oldFeatures = self.features?.data ?? empty; diff --git a/Logic/FeatureSource/Sources/SimpleFeatureSource.ts b/Logic/FeatureSource/Sources/SimpleFeatureSource.ts index ad8d7be5d..b3a476f5f 100644 --- a/Logic/FeatureSource/Sources/SimpleFeatureSource.ts +++ b/Logic/FeatureSource/Sources/SimpleFeatureSource.ts @@ -3,13 +3,14 @@ import FilteredLayer from "../../../Models/FilteredLayer"; import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; import {BBox} from "../../GeoOperations"; import {Utils} from "../../../Utils"; +import {Tiles} from "../../../Models/TileRange"; export default class SimpleFeatureSource implements FeatureSourceForLayer, Tiled { public readonly features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); public readonly name: string = "SimpleFeatureSource"; public readonly layer: FilteredLayer; public readonly bbox: BBox = BBox.global; - public readonly tileIndex: number = Utils.tile_index(0, 0, 0); + public readonly tileIndex: number = Tiles.tile_index(0, 0, 0); constructor(layer: FilteredLayer) { this.name = "SimpleFeatureSource(" + layer.layerDef.id + ")" diff --git a/Logic/FeatureSource/Sources/StaticFeatureSource.ts b/Logic/FeatureSource/Sources/StaticFeatureSource.ts index 0cc58d656..d5795a1d5 100644 --- a/Logic/FeatureSource/Sources/StaticFeatureSource.ts +++ b/Logic/FeatureSource/Sources/StaticFeatureSource.ts @@ -8,12 +8,13 @@ export default class StaticFeatureSource implements FeatureSource { public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>; public readonly name: string = "StaticFeatureSource" - constructor(features: any[] | UIEventSource, useFeaturesDirectly = false) { + constructor(features: any[] | UIEventSource>, useFeaturesDirectly) { const now = new Date(); - if(useFeaturesDirectly){ + if (useFeaturesDirectly) { // @ts-ignore this.features = features - }else if (features instanceof UIEventSource) { + } else if (features instanceof UIEventSource) { + // @ts-ignore this.features = features.map(features => features.map(f => ({feature: f, freshness: now}))) } else { this.features = new UIEventSource(features.map(f => ({ diff --git a/Logic/FeatureSource/Sources/WayHandlingApplyingFeatureSource.ts b/Logic/FeatureSource/Sources/WayHandlingApplyingFeatureSource.ts index 37ee94b8a..cb36c4b21 100644 --- a/Logic/FeatureSource/Sources/WayHandlingApplyingFeatureSource.ts +++ b/Logic/FeatureSource/Sources/WayHandlingApplyingFeatureSource.ts @@ -12,10 +12,11 @@ export default class WayHandlingApplyingFeatureSource implements FeatureSourceFo public readonly layer; constructor(upstream: FeatureSourceForLayer) { - this.name = "Wayhandling(" + upstream.name+")"; + + this.name = "Wayhandling(" + upstream.name + ")"; this.layer = upstream.layer const layer = upstream.layer.layerDef; - + if (layer.wayHandling === LayerConfig.WAYHANDLING_DEFAULT) { // We don't have to do anything fancy // lets just wire up the upstream diff --git a/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts b/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts index 357db85d4..8843b182a 100644 --- a/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts @@ -1,5 +1,5 @@ import FilteredLayer from "../../../Models/FilteredLayer"; -import {FeatureSourceForLayer} from "../FeatureSource"; +import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; import {UIEventSource} from "../../UIEventSource"; import Loc from "../../../Models/Loc"; import DynamicTileSource from "./DynamicTileSource"; @@ -8,7 +8,7 @@ import GeoJsonSource from "../Sources/GeoJsonSource"; export default class DynamicGeoJsonTileSource extends DynamicTileSource { constructor(layer: FilteredLayer, - registerLayer: (layer: FeatureSourceForLayer) => void, + registerLayer: (layer: FeatureSourceForLayer & Tiled) => void, state: { locationControl: UIEventSource leafletMap: any diff --git a/Logic/FeatureSource/TiledFeatureSource/DynamicTileSource.ts b/Logic/FeatureSource/TiledFeatureSource/DynamicTileSource.ts index 43021587c..a6ef04458 100644 --- a/Logic/FeatureSource/TiledFeatureSource/DynamicTileSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/DynamicTileSource.ts @@ -6,6 +6,7 @@ import {Utils} from "../../../Utils"; import {UIEventSource} from "../../UIEventSource"; import Loc from "../../../Models/Loc"; import TileHierarchy from "./TileHierarchy"; +import {Tiles} from "../../../Models/TileRange"; /*** * A tiled source which dynamically loads the required tiles at a fixed zoom level @@ -46,9 +47,9 @@ export default class DynamicTileSource implements TileHierarchy Utils.tile_index(zoomlevel, x, y)).filter(i => !self._loadedTiles.has(i)) + const needed = Tiles.MapRange(tileRange, (x, y) => Tiles.tile_index(zoomlevel, x, y)).filter(i => !self._loadedTiles.has(i)) if (needed.length === 0) { return undefined } @@ -63,7 +64,7 @@ export default class DynamicTileSource implements TileHierarchy { public readonly loadedTiles: Map = new Map(); @@ -13,7 +14,7 @@ export class TileHierarchyMerger implements TileHierarchy void; - constructor(layer: FilteredLayer, handleTile: (src: FeatureSourceForLayer & IndexedFeatureSource, index: number) => void) { + constructor(layer: FilteredLayer, handleTile: (src: FeatureSourceForLayer & IndexedFeatureSource & Tiled, index: number) => void) { this.layer = layer; this._handleTile = handleTile; } @@ -37,7 +38,7 @@ export class TileHierarchyMerger implements TileHierarchy([src]) this.sources.set(index, sources) - const merger = new FeatureSourceMerger(this.layer, index, BBox.fromTile(...Utils.tile_from_index(index)), sources) + const merger = new FeatureSourceMerger(this.layer, index, BBox.fromTile(...Tiles.tile_from_index(index)), sources) this.loadedTiles.set(index, merger) this._handleTile(merger, index) } diff --git a/Logic/FeatureSource/TiledFeatureSource/TiledFeatureSource.ts b/Logic/FeatureSource/TiledFeatureSource/TiledFeatureSource.ts index 62a7c9e5e..2dcf3e6d2 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TiledFeatureSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TiledFeatureSource.ts @@ -4,7 +4,7 @@ import {Utils} from "../../../Utils"; import {BBox} from "../../GeoOperations"; import FilteredLayer from "../../../Models/FilteredLayer"; import TileHierarchy from "./TileHierarchy"; -import {feature} from "@turf/turf"; +import {Tiles} from "../../../Models/TileRange"; /** * Contains all features in a tiled fashion. @@ -41,12 +41,12 @@ export default class TiledFeatureSource implements Tiled, IndexedFeatureSource, this.x = x; this.y = y; this.bbox = BBox.fromTile(z, x, y) - this.tileIndex = Utils.tile_index(z, x, y) + this.tileIndex = Tiles.tile_index(z, x, y) this.name = `TiledFeatureSource(${z},${x},${y})` this.parent = parent; this.layer = options.layer options = options ?? {} - this.maxFeatureCount = options?.maxFeatureCount ?? 500; + this.maxFeatureCount = options?.maxFeatureCount ?? 250; this.maxzoom = options.maxZoomLevel ?? 18 this.options = options; if (parent === undefined) { @@ -61,7 +61,7 @@ export default class TiledFeatureSource implements Tiled, IndexedFeatureSource, } else { this.root = this.parent.root; this.loadedTiles = this.root.loadedTiles; - const i = Utils.tile_index(z, x, y) + const i = Tiles.tile_index(z, x, y) this.root.loadedTiles.set(i, this) } this.features = new UIEventSource([]) @@ -143,9 +143,7 @@ export default class TiledFeatureSource implements Tiled, IndexedFeatureSource, for (const feature of features) { const bbox = BBox.get(feature.feature) - if (this.options.minZoomLevel === undefined) { - - + if (this.options.dontEnforceMinZoom || this.options.minZoomLevel === undefined) { if (bbox.isContainedIn(this.upper_left.bbox)) { ulf.push(feature) } else if (bbox.isContainedIn(this.upper_right.bbox)) { @@ -186,6 +184,11 @@ export interface TiledFeatureSourceOptions { readonly maxFeatureCount?: number, readonly maxZoomLevel?: number, readonly minZoomLevel?: number, + /** + * IF minZoomLevel is set, and if a feature runs through a tile boundary, it would normally be duplicated. + * Setting 'dontEnforceMinZoomLevel' will still allow bigger zoom levels for those features + */ + readonly dontEnforceMinZoom?: boolean, readonly registerTile?: (tile: TiledFeatureSource & Tiled) => void, readonly layer?: FilteredLayer } \ No newline at end of file diff --git a/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts b/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts index e88a1d82d..3e879bd4a 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts @@ -6,6 +6,7 @@ import TileHierarchy from "./TileHierarchy"; import {Utils} from "../../../Utils"; import SaveTileToLocalStorageActor from "../Actors/SaveTileToLocalStorageActor"; import {BBox} from "../../GeoOperations"; +import {Tiles} from "../../../Models/TileRange"; export default class TiledFromLocalStorageSource implements TileHierarchy { public loadedTiles: Map = new Map(); @@ -17,6 +18,7 @@ export default class TiledFromLocalStorageSource implements TileHierarchy() const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layer.layerDef.id + "-" // @ts-ignore const indexes: number[] = Object.keys(localStorage) @@ -27,7 +29,7 @@ export default class TiledFromLocalStorageSource implements TileHierarchy Utils.tile_from_index(i).join("/")).join(", ")) + console.log("Layer", layer.layerDef.id, "has following tiles in available in localstorage", indexes.map(i => Tiles.tile_from_index(i).join("/")).join(", ")) const zLevels = indexes.map(i => i % 100) const indexesSet = new Set(indexes) @@ -57,9 +59,9 @@ export default class TiledFromLocalStorageSource implements TileHierarchy Utils.tile_index(z, x, y)) - .filter(i => !self.loadedTiles.has(i) && indexesSet.has(i)) + const tileRange = Tiles.TileRangeBetween(z, bounds.getNorth(), bounds.getEast(), bounds.getSouth(), bounds.getWest()) + const neededZ = Tiles.MapRange(tileRange, (x, y) => Tiles.tile_index(z, x, y)) + .filter(i => !self.loadedTiles.has(i) && !undefinedTiles.has(i) && indexesSet.has(i)) needed.push(...neededZ) } @@ -84,12 +86,13 @@ export default class TiledFromLocalStorageSource implements TileHierarchy(features), name: "FromLocalStorage(" + key + ")", tileIndex: neededIndex, - bbox: BBox.fromTile(...Utils.tile_from_index(neededIndex)) + bbox: BBox.fromTileIndex(neededIndex) } handleFeatureSource(src, neededIndex) self.loadedTiles.set(neededIndex, src) } catch (e) { console.error("Could not load data tile from local storage due to", e) + undefinedTiles.add(neededIndex) } } diff --git a/Logic/GeoOperations.ts b/Logic/GeoOperations.ts index 66fd90053..dd806ded4 100644 --- a/Logic/GeoOperations.ts +++ b/Logic/GeoOperations.ts @@ -1,5 +1,6 @@ import * as turf from '@turf/turf' import {Utils} from "../Utils"; +import {Tiles} from "../Models/TileRange"; export class GeoOperations { @@ -8,7 +9,7 @@ export class GeoOperations { } /** - * Converts a GeoJSon feature to a point feature + * Converts a GeoJson feature to a point GeoJson feature * @param feature */ static centerpoint(feature: any) { @@ -451,8 +452,12 @@ export class BBox { } } - static fromTile(z: number, x: number, y: number) { - return new BBox(Utils.tile_bounds_lon_lat(z, x, y)) + static fromTile(z: number, x: number, y: number): BBox { + return new BBox(Tiles.tile_bounds_lon_lat(z, x, y)) + } + + static fromTileIndex(i: number): BBox { + return BBox.fromTile(...Tiles.tile_from_index(i)) } getEast() { diff --git a/Logic/ImageProviders/ImageAttributionSource.ts b/Logic/ImageProviders/ImageAttributionSource.ts index 7841c899b..1f0f097b7 100644 --- a/Logic/ImageProviders/ImageAttributionSource.ts +++ b/Logic/ImageProviders/ImageAttributionSource.ts @@ -12,8 +12,11 @@ export default abstract class ImageAttributionSource { if (cached !== undefined) { return cached; } - const src = this.DownloadAttribution(url) + const src = new UIEventSource(undefined) this._cache.set(url, src) + this.DownloadAttribution(url).then(license => + src.setData(license)) + .catch(e => console.error("Could not download license information for ", url, " due to", e)) return src; } @@ -21,10 +24,10 @@ export default abstract class ImageAttributionSource { public abstract SourceIcon(backlinkSource?: string): BaseUIElement; /*Converts a value to a URL. Can return null if not applicable*/ - public PrepareUrl(value: string): string | UIEventSource{ + public PrepareUrl(value: string): string | UIEventSource { return value; } - protected abstract DownloadAttribution(url: string): UIEventSource; + protected abstract DownloadAttribution(url: string): Promise; } \ No newline at end of file diff --git a/Logic/ImageProviders/Imgur.ts b/Logic/ImageProviders/Imgur.ts index 4325d3e37..f85f3228a 100644 --- a/Logic/ImageProviders/Imgur.ts +++ b/Logic/ImageProviders/Imgur.ts @@ -2,8 +2,9 @@ import $ from "jquery" import {LicenseInfo} from "./Wikimedia"; import ImageAttributionSource from "./ImageAttributionSource"; -import {UIEventSource} from "../UIEventSource"; import BaseUIElement from "../../UI/BaseUIElement"; +import {Utils} from "../../Utils"; +import Constants from "../../Models/Constants"; export class Imgur extends ImageAttributionSource { @@ -86,50 +87,27 @@ export class Imgur extends ImageAttributionSource { return undefined; } - protected DownloadAttribution(url: string): UIEventSource { - const src = new UIEventSource(undefined) - - + protected async DownloadAttribution(url: string): Promise { const hash = url.substr("https://i.imgur.com/".length).split(".jpg")[0]; const apiUrl = 'https://api.imgur.com/3/image/' + hash; - const apiKey = '7070e7167f0a25a'; + const response = await Utils.downloadJson(apiUrl, {Authorization: 'Client-ID ' + Constants.ImgurApiKey}) - const settings = { - async: true, - crossDomain: true, - processData: false, - contentType: false, - type: 'GET', - url: apiUrl, - headers: { - Authorization: 'Client-ID ' + apiKey, - Accept: 'application/json', - }, - }; - // @ts-ignore - $.ajax(settings).done(function (response) { - const descr: string = response.data.description ?? ""; - const data: any = {}; - for (const tag of descr.split("\n")) { - const kv = tag.split(":"); - const k = kv[0]; - data[k] = kv[1].replace("\r", ""); - } + const descr: string = response.data.description ?? ""; + const data: any = {}; + for (const tag of descr.split("\n")) { + const kv = tag.split(":"); + const k = kv[0]; + data[k] = kv[1]?.replace("\r", ""); + } - const licenseInfo = new LicenseInfo(); + const licenseInfo = new LicenseInfo(); - licenseInfo.licenseShortName = data.license; - licenseInfo.artist = data.author; + licenseInfo.licenseShortName = data.license; + licenseInfo.artist = data.author; - src.setData(licenseInfo) - - }).fail((reason) => { - console.log("Getting metadata from to IMGUR failed", reason) - }); - - return src; + return licenseInfo } diff --git a/Logic/ImageProviders/Mapillary.ts b/Logic/ImageProviders/Mapillary.ts index 3f992dbce..ae5808a01 100644 --- a/Logic/ImageProviders/Mapillary.ts +++ b/Logic/ImageProviders/Mapillary.ts @@ -8,7 +8,7 @@ import {Utils} from "../../Utils"; export class Mapillary extends ImageAttributionSource { public static readonly singleton = new Mapillary(); - + private static readonly v4_cached_urls = new Map>(); private static readonly client_token_v3 = 'TXhLaWthQ1d4RUg0czVxaTVoRjFJZzowNDczNjUzNmIyNTQyYzI2' @@ -23,8 +23,8 @@ export class Mapillary extends ImageAttributionSource { isApiv4?: boolean } { if (value.startsWith("https://a.mapillary.com")) { - const key = value.substring(0, value.lastIndexOf("?")).substring(value.lastIndexOf("/") + 1) - return {key:key, isApiv4: !isNaN(Number(key))}; + const key = value.substring(0, value.lastIndexOf("?")).substring(value.lastIndexOf("/") + 1) + return {key: key, isApiv4: !isNaN(Number(key))}; } const newApiFormat = value.match(/https?:\/\/www.mapillary.com\/app\/\?pKey=([0-9]*)/) if (newApiFormat !== null) { @@ -32,11 +32,11 @@ export class Mapillary extends ImageAttributionSource { } const mapview = value.match(/https?:\/\/www.mapillary.com\/map\/im\/(.*)/) - if(mapview !== null){ + if (mapview !== null) { const key = mapview[1] - return {key:key, isApiv4: !isNaN(Number(key))}; + return {key: key, isApiv4: !isNaN(Number(key))}; } - + if (value.toLowerCase().startsWith("https://www.mapillary.com/map/im/")) { // Extract the key of the image @@ -62,48 +62,45 @@ export class Mapillary extends ImageAttributionSource { return `https://images.mapillary.com/${keyV.key}/thumb-640.jpg?client_id=${Mapillary.client_token_v3}` } else { const key = keyV.key; - if(Mapillary.v4_cached_urls.has(key)){ + if (Mapillary.v4_cached_urls.has(key)) { return Mapillary.v4_cached_urls.get(key) } - const metadataUrl ='https://graph.mapillary.com/' + key + '?fields=thumb_1024_url&&access_token=' + Mapillary.client_token_v4; + const metadataUrl = 'https://graph.mapillary.com/' + key + '?fields=thumb_1024_url&&access_token=' + Mapillary.client_token_v4; const source = new UIEventSource(undefined) Mapillary.v4_cached_urls.set(key, source) Utils.downloadJson(metadataUrl).then( - json => { - console.warn("Got response on mapillary image", json, json["thumb_1024_url"]) - return source.setData(json["thumb_1024_url"]); - } + json => { + console.warn("Got response on mapillary image", json, json["thumb_1024_url"]) + return source.setData(json["thumb_1024_url"]); + } ) return source } } - protected DownloadAttribution(url: string): UIEventSource { + protected async DownloadAttribution(url: string): Promise { const keyV = Mapillary.ExtractKeyFromURL(url) - if(keyV.isApiv4){ + if (keyV.isApiv4) { const license = new LicenseInfo() license.artist = "Contributor name unavailable"; license.license = "CC BY-SA 4.0"; // license.license = "Creative Commons Attribution-ShareAlike 4.0 International License"; license.attributionRequired = true; - return new UIEventSource(license) - + return license + } const key = keyV.key - - const metadataURL = `https://a.mapillary.com/v3/images/${key}?client_id=TXhLaWthQ1d4RUg0czVxaTVoRjFJZzowNDczNjUzNmIyNTQyYzI2` - const source = new UIEventSource(undefined) - Utils.downloadJson(metadataURL).then(data => { - const license = new LicenseInfo(); - license.artist = data.properties?.username; - license.licenseShortName = "CC BY-SA 4.0"; - license.license = "Creative Commons Attribution-ShareAlike 4.0 International License"; - license.attributionRequired = true; - source.setData(license); - }) - return source + const metadataURL = `https://a.mapillary.com/v3/images/${key}?client_id=TXhLaWthQ1d4RUg0czVxaTVoRjFJZzowNDczNjUzNmIyNTQyYzI2` + const data = await Utils.downloadJson(metadataURL) + const license = new LicenseInfo(); + license.artist = data.properties?.username; + license.licenseShortName = "CC BY-SA 4.0"; + license.license = "Creative Commons Attribution-ShareAlike 4.0 International License"; + license.attributionRequired = true; + + return license } } \ No newline at end of file diff --git a/Logic/ImageProviders/Wikimedia.ts b/Logic/ImageProviders/Wikimedia.ts index 32c762523..cd5aea5d5 100644 --- a/Logic/ImageProviders/Wikimedia.ts +++ b/Logic/ImageProviders/Wikimedia.ts @@ -1,7 +1,6 @@ import ImageAttributionSource from "./ImageAttributionSource"; import BaseUIElement from "../../UI/BaseUIElement"; import Svg from "../../Svg"; -import {UIEventSource} from "../UIEventSource"; import Link from "../../UI/Base/Link"; import {Utils} from "../../Utils"; @@ -124,43 +123,34 @@ export class Wikimedia extends ImageAttributionSource { .replace(/'/g, '%27'); } - protected DownloadAttribution(filename: string): UIEventSource { - - const source = new UIEventSource(undefined); - + protected async DownloadAttribution(filename: string): Promise { filename = Wikimedia.ExtractFileName(filename) if (filename === "") { - return source; + return undefined; } const url = "https://en.wikipedia.org/w/" + "api.php?action=query&prop=imageinfo&iiprop=extmetadata&" + "titles=" + filename + "&format=json&origin=*"; - Utils.downloadJson(url).then( - data => { - const licenseInfo = new LicenseInfo(); - const license = (data.query.pages[-1].imageinfo ?? [])[0]?.extmetadata; - if (license === undefined) { - console.error("This file has no usable metedata or license attached... Please fix the license info file yourself!") - source.setData(null) - return; - } + const data = await Utils.downloadJson(url) + const licenseInfo = new LicenseInfo(); + const license = (data.query.pages[-1].imageinfo ?? [])[0]?.extmetadata; + if (license === undefined) { + console.error("This file has no usable metedata or license attached... Please fix the license info file yourself!") + return undefined; + } - licenseInfo.artist = license.Artist?.value; - licenseInfo.license = license.License?.value; - licenseInfo.copyrighted = license.Copyrighted?.value; - licenseInfo.attributionRequired = license.AttributionRequired?.value; - licenseInfo.usageTerms = license.UsageTerms?.value; - licenseInfo.licenseShortName = license.LicenseShortName?.value; - licenseInfo.credit = license.Credit?.value; - licenseInfo.description = license.ImageDescription?.value; - source.setData(licenseInfo); - } - ) - - return source; + licenseInfo.artist = license.Artist?.value; + licenseInfo.license = license.License?.value; + licenseInfo.copyrighted = license.Copyrighted?.value; + licenseInfo.attributionRequired = license.AttributionRequired?.value; + licenseInfo.usageTerms = license.UsageTerms?.value; + licenseInfo.licenseShortName = license.LicenseShortName?.value; + licenseInfo.credit = license.Credit?.value; + licenseInfo.description = license.ImageDescription?.value; + return licenseInfo; } diff --git a/Logic/MetaTagging.ts b/Logic/MetaTagging.ts index 5745fa4ad..c7eda184b 100644 --- a/Logic/MetaTagging.ts +++ b/Logic/MetaTagging.ts @@ -2,6 +2,7 @@ import SimpleMetaTagger from "./SimpleMetaTagger"; import {ExtraFuncParams, ExtraFunction} from "./ExtraFunction"; import {UIEventSource} from "./UIEventSource"; import LayerConfig from "../Models/ThemeConfig/LayerConfig"; +import State from "../State"; /** @@ -20,50 +21,68 @@ export default class MetaTagging { * The given features should be part of the given layer */ public static addMetatags(features: { feature: any; freshness: Date }[], - params: ExtraFuncParams, - layer: LayerConfig, - options?: { - includeDates?: true | boolean, - includeNonDates?: true | boolean - }) { + params: ExtraFuncParams, + layer: LayerConfig, + options?: { + includeDates?: true | boolean, + includeNonDates?: true | boolean + }) { if (features === undefined || features.length === 0) { return; } - for (const metatag of SimpleMetaTagger.metatags) { - try { + const metatagsToApply: SimpleMetaTagger [] = [] + for (const metatag of SimpleMetaTagger.metatags) { if (metatag.includesDates) { if (options.includeDates ?? true) { - metatag.addMetaTags(features); + metatagsToApply.push(metatag) } } else { if (options.includeNonDates ?? true) { - metatag.addMetaTags(features); + metatagsToApply.push(metatag) } } - - } catch (e) { - console.error("Could not calculate metatag for ", metatag.keys.join(","), ":", e) } - } - // The functions - per layer - which add the new keys + // The calculated functions - per layer - which add the new keys const layerFuncs = this.createRetaggingFunc(layer) - if (layerFuncs !== undefined) { - for (const feature of features) { - try { - layerFuncs(params, feature.feature) - } catch (e) { - console.error(e) + for (let i = 0; i < features.length; i++) { + const ff = features[i]; + const feature = ff.feature + const freshness = ff.freshness + let somethingChanged = false + for (const metatag of metatagsToApply) { + try { + if(!metatag.keys.some(key => feature.properties[key] === undefined)){ + // All keys are already defined, we probably already ran this one + continue + } + somethingChanged = somethingChanged || metatag.applyMetaTagsOnFeature(feature, freshness) + } catch (e) { + console.error("Could not calculate metatag for ", metatag.keys.join(","), ":", e) + } + } + + if(layerFuncs !== undefined){ + try { + layerFuncs(params, feature) + } catch (e) { + console.error(e) + } + somethingChanged = true + } + + if(somethingChanged){ + State.state.allElements.getEventSourceById(feature.properties.id).ping() } } - } } + private static createRetaggingFunc(layer: LayerConfig): ((params: ExtraFuncParams, feature: any) => void) { const calculatedTags: [string, string][] = layer.calculatedTags; @@ -92,11 +111,13 @@ export default class MetaTagging { d = JSON.stringify(d); } feature.properties[key] = d; + console.log("Written a delayed calculated tag onto ", feature.properties.id, ": ", key, ":==", d) }) result = result.data } if (result === undefined || result === "") { + console.log("Calculated tag for", key, "gave undefined", feature.properties.id) return; } if (typeof result !== "string") { @@ -104,6 +125,7 @@ export default class MetaTagging { result = JSON.stringify(result); } feature.properties[key] = result; + console.log("Written a calculated tag onto ", feature.properties.id, ": ", key, ":==", result) } catch (e) { if (MetaTagging.errorPrintCount < MetaTagging.stopErrorOutputAt) { console.warn("Could not calculate a calculated tag defined by " + code + " due to " + e + ". This is code defined in the theme. Are you the theme creator? Doublecheck your code. Note that the metatags might not be stable on new features", e) diff --git a/Logic/Osm/OsmConnection.ts b/Logic/Osm/OsmConnection.ts index 01d18f8cd..5a5e82612 100644 --- a/Logic/Osm/OsmConnection.ts +++ b/Logic/Osm/OsmConnection.ts @@ -94,6 +94,7 @@ export class OsmConnection { self.AttemptLogin() } }); + this.isLoggedIn.addCallbackAndRunD(li => console.log("User is logged in!", li)) this._dryRun = dryRun; this.updateAuthObject(); diff --git a/Logic/SimpleMetaTagger.ts b/Logic/SimpleMetaTagger.ts index 6e8f3e0fc..4a2dac23b 100644 --- a/Logic/SimpleMetaTagger.ts +++ b/Logic/SimpleMetaTagger.ts @@ -31,7 +31,7 @@ export default class SimpleMetaTagger { "_version_number"], doc: "Information about the last edit of this object." }, - (feature) => {/*Note: also handled by 'UpdateTagsFromOsmAPI'*/ + (feature) => {/*Note: also called by 'UpdateTagsFromOsmAPI'*/ const tgs = feature.properties; @@ -48,6 +48,7 @@ export default class SimpleMetaTagger { move("changeset", "_last_edit:changeset") move("timestamp", "_last_edit:timestamp") move("version", "_version_number") + return true; } ) private static latlon = new SimpleMetaTagger({ @@ -62,6 +63,7 @@ export default class SimpleMetaTagger { feature.properties["_lon"] = "" + lon; feature._lon = lon; // This is dirty, I know feature._lat = lat; + return true; }) ); private static surfaceArea = new SimpleMetaTagger( @@ -74,6 +76,7 @@ export default class SimpleMetaTagger { feature.properties["_surface"] = "" + sqMeters; feature.properties["_surface:ha"] = "" + Math.floor(sqMeters / 1000) / 10; feature.area = sqMeters; + return true; }) ); @@ -118,9 +121,7 @@ export default class SimpleMetaTagger { } } - if (rewritten) { - State.state.allElements.getEventSourceById(feature.id).ping(); - } + return rewritten }) ) @@ -135,6 +136,7 @@ export default class SimpleMetaTagger { const km = Math.floor(l / 1000) const kmRest = Math.round((l - km * 1000) / 100) feature.properties["_length:km"] = "" + km + "." + kmRest + return true; }) ) private static country = new SimpleMetaTagger( @@ -144,7 +146,6 @@ export default class SimpleMetaTagger { }, feature => { - let centerPoint: any = GeoOperations.centerpoint(feature); const lat = centerPoint.geometry.coordinates[1]; const lon = centerPoint.geometry.coordinates[0]; @@ -157,11 +158,11 @@ export default class SimpleMetaTagger { const tagsSource = State.state.allElements.getEventSourceById(feature.properties.id); tagsSource.ping(); } - } catch (e) { console.warn(e) } }) + return false; } ) private static isOpen = new SimpleMetaTagger( @@ -174,7 +175,7 @@ export default class SimpleMetaTagger { if (Utils.runningFromConsole) { // We are running from console, thus probably creating a cache // isOpen is irrelevant - return + return false } const tagsSource = State.state.allElements.getEventSourceById(feature.properties.id); @@ -199,7 +200,7 @@ export default class SimpleMetaTagger { if (oldNextChange > (new Date()).getTime() && tags["_isOpen:oldvalue"] === tags["opening_hours"]) { // Already calculated and should not yet be triggered - return; + return false; } tags["_isOpen"] = oh.getState() ? "yes" : "no"; @@ -227,6 +228,7 @@ export default class SimpleMetaTagger { } } updateTags(); + return true; } catch (e) { console.warn("Error while parsing opening hours of ", tags.id, e); tags["_isOpen"] = "parse_error"; @@ -244,11 +246,11 @@ export default class SimpleMetaTagger { const tags = feature.properties; const direction = tags["camera:direction"] ?? tags["direction"]; if (direction === undefined) { - return; + return false; } const n = cardinalDirections[direction] ?? Number(direction); if (isNaN(n)) { - return; + return false; } // The % operator has range (-360, 360). We apply a trick to get [0, 360). @@ -256,7 +258,7 @@ export default class SimpleMetaTagger { tags["_direction:numerical"] = normalized; tags["_direction:leftright"] = normalized <= 180 ? "right" : "left"; - + return true; }) ) private static carriageWayWidth = new SimpleMetaTagger( @@ -268,7 +270,7 @@ export default class SimpleMetaTagger { const properties = feature.properties; if (properties["width:carriageway"] === undefined) { - return; + return false; } const carWidth = 2; @@ -366,7 +368,7 @@ export default class SimpleMetaTagger { properties["_width:difference"] = Utils.Round(targetWidth - width); properties["_width:difference:no_pedestrians"] = Utils.Round(targetWidthIgnoringPedestrians - width); - + return true; } ); private static currentTime = new SimpleMetaTagger( @@ -375,7 +377,7 @@ export default class SimpleMetaTagger { doc: "Adds the time that the data got loaded - pretty much the time of downloading from overpass. The format is YYYY-MM-DD hh:mm, aka 'sortable' aka ISO-8601-but-not-entirely", includesDates: true }, - (feature, _, freshness) => { + (feature, freshness) => { const now = new Date(); if (typeof freshness === "string") { @@ -394,7 +396,7 @@ export default class SimpleMetaTagger { feature.properties["_now:datetime"] = datetime(now); feature.properties["_loaded:date"] = date(freshness); feature.properties["_loaded:datetime"] = datetime(freshness); - + return true; } ) public static metatags = [ @@ -413,12 +415,18 @@ export default class SimpleMetaTagger { public readonly keys: string[]; public readonly doc: string; public readonly includesDates: boolean - private readonly _f: (feature: any, index: number, freshness: Date) => void; + public readonly applyMetaTagsOnFeature: (feature: any, freshness: Date) => boolean; - constructor(docs: { keys: string[], doc: string, includesDates?: boolean }, f: ((feature: any, index: number, freshness: Date) => void)) { + /*** + * A function that adds some extra data to a feature + * @param docs: what does this extra data do? + * @param f: apply the changes. Returns true if something changed + */ + constructor(docs: { keys: string[], doc: string, includesDates?: boolean }, + f: ((feature: any, freshness: Date) => boolean)) { this.keys = docs.keys; this.doc = docs.doc; - this._f = f; + this.applyMetaTagsOnFeature = f; this.includesDates = docs.includesDates ?? false; for (const key of docs.keys) { if (!key.startsWith('_') && key.toLowerCase().indexOf("theme") < 0) { @@ -450,12 +458,4 @@ export default class SimpleMetaTagger { return new Combine(subElements).SetClass("flex-col") } - public addMetaTags(features: { feature: any, freshness: Date }[]) { - for (let i = 0; i < features.length; i++) { - let feature = features[i]; - this._f(feature.feature, i, feature.freshness); - } - } - - } diff --git a/Models/Constants.ts b/Models/Constants.ts index d6f212ac6..66ca7227b 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -3,6 +3,7 @@ import {Utils} from "../Utils"; export default class Constants { public static vNumber = "0.10.0-alpha-1"; + public static ImgurApiKey = '7070e7167f0a25a' // The user journey states thresholds when a new feature gets unlocked public static userJourney = { diff --git a/Models/ThemeConfig/LayerConfig.ts b/Models/ThemeConfig/LayerConfig.ts index 18c9fe3b4..2ed02ae6d 100644 --- a/Models/ThemeConfig/LayerConfig.ts +++ b/Models/ThemeConfig/LayerConfig.ts @@ -18,6 +18,7 @@ import FilterConfig from "./FilterConfig"; import {Unit} from "../Unit"; import DeleteConfig from "./DeleteConfig"; import Svg from "../../Svg"; +import Img from "../../UI/Base/Img"; export default class LayerConfig { static WAYHANDLING_DEFAULT = 0; @@ -495,19 +496,20 @@ export default class LayerConfig { const iconUrlStatic = render(this.icon); const self = this; - function genHtmlFromString(sourcePart: string, rotation: string, style?: string): BaseUIElement { - style = style ?? `width:100%;height:100%;transform: rotate( ${rotation} );display:block;position: absolute; top: 0; left: 0`; + function genHtmlFromString(sourcePart: string, rotation: string): BaseUIElement { + const style = `width:100%;height:100%;transform: rotate( ${rotation} );display:block;position: absolute; top: 0; left: 0`; let html: BaseUIElement = new FixedUiElement( `` ); const match = sourcePart.match(/([a-zA-Z0-9_]*):([^;]*)/); if (match !== null && Svg.All[match[1] + ".svg"] !== undefined) { - html = new Combine([ + html = new Img( (Svg.All[match[1] + ".svg"] as string).replace( /#000000/g, match[2] ), - ]).SetStyle(style); + true + ).SetStyle(style); } return html; } @@ -540,7 +542,7 @@ export default class LayerConfig { .filter((prt) => prt != ""); for (const badgePartStr of partDefs) { - badgeParts.push(genHtmlFromString(badgePartStr, "0", `width:unset;height:100%;display:block;`)); + badgeParts.push(genHtmlFromString(badgePartStr, "0")); } const badgeCompound = new Combine(badgeParts).SetStyle( diff --git a/Models/ThemeConfig/LayoutConfig.ts b/Models/ThemeConfig/LayoutConfig.ts index dd0d472ed..b632d8a29 100644 --- a/Models/ThemeConfig/LayoutConfig.ts +++ b/Models/ThemeConfig/LayoutConfig.ts @@ -5,7 +5,6 @@ import SharedTagRenderings from "../../Customizations/SharedTagRenderings"; import AllKnownLayers from "../../Customizations/AllKnownLayers"; import {Utils} from "../../Utils"; import LayerConfig from "./LayerConfig"; -import {Unit} from "../Unit"; import {LayerConfigJson} from "./Json/LayerConfigJson"; export default class LayoutConfig { @@ -87,6 +86,9 @@ export default class LayoutConfig { this.startZoom = json.startZoom; this.startLat = json.startLat; this.startLon = json.startLon; + if(json.widenFactor < 1){ + throw "Widenfactor too small" + } this.widenFactor = json.widenFactor ?? 1.5; this.roamingRenderings = (json.roamingRenderings ?? []).map((tr, i) => { if (typeof tr === "string") { diff --git a/Models/TileRange.ts b/Models/TileRange.ts index e1dba5532..215d5a76f 100644 --- a/Models/TileRange.ts +++ b/Models/TileRange.ts @@ -5,4 +5,106 @@ export interface TileRange { yend: number, total: number, zoomlevel: number +} + +export class Tiles { + + public static MapRange(tileRange: TileRange, f: (x: number, y: number) => T): T[] { + const result: T[] = [] + for (let x = tileRange.xstart; x <= tileRange.xend; x++) { + for (let y = tileRange.ystart; y <= tileRange.yend; y++) { + const t = f(x, y); + result.push(t) + } + } + return result; + } + + + private static tile2long(x, z) { + return (x / Math.pow(2, z) * 360 - 180); + } + + private static tile2lat(y, z) { + const n = Math.PI - 2 * Math.PI * y / Math.pow(2, z); + return (180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)))); + } + + private static lon2tile(lon, zoom) { + return (Math.floor((lon + 180) / 360 * Math.pow(2, zoom))); + } + + private static lat2tile(lat, zoom) { + return (Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, zoom))); + } + + /** + * Calculates the tile bounds of the + * @param z + * @param x + * @param y + * @returns [[maxlat, minlon], [minlat, maxlon]] + */ + static tile_bounds(z: number, x: number, y: number): [[number, number], [number, number]] { + return [[Tiles.tile2lat(y, z), Tiles.tile2long(x, z)], [Tiles.tile2lat(y + 1, z), Tiles.tile2long(x + 1, z)]] + } + + + static tile_bounds_lon_lat(z: number, x: number, y: number): [[number, number], [number, number]] { + return [[Tiles.tile2long(x, z), Tiles.tile2lat(y, z)], [Tiles.tile2long(x + 1, z), Tiles.tile2lat(y + 1, z)]] + } + + /** + * Returns the centerpoint [lon, lat] of the specified tile + * @param z + * @param x + * @param y + */ + static centerPointOf(z: number, x: number, y: number): [number, number]{ + return [(Tiles.tile2long(x, z) + Tiles.tile2long(x+1, z)) / 2, (Tiles.tile2lat(y, z) + Tiles.tile2lat(y+1, z)) / 2] + } + + static tile_index(z: number, x: number, y: number): number { + return ((x * (2 << z)) + y) * 100 + z + } + /** + * Given a tile index number, returns [z, x, y] + * @param index + * @returns 'zxy' + */ + static tile_from_index(index: number): [number, number, number] { + const z = index % 100; + const factor = 2 << z + index = Math.floor(index / 100) + const x = Math.floor(index / factor) + return [z, x, index % factor] + } + + /** + * Return x, y of the tile containing (lat, lon) on the given zoom level + */ + static embedded_tile(lat: number, lon: number, z: number): { x: number, y: number, z: number } { + return {x: Tiles.lon2tile(lon, z), y: Tiles.lat2tile(lat, z), z: z} + } + + static TileRangeBetween(zoomlevel: number, lat0: number, lon0: number, lat1: number, lon1: number): TileRange { + const t0 = Tiles.embedded_tile(lat0, lon0, zoomlevel) + const t1 = Tiles.embedded_tile(lat1, lon1, zoomlevel) + + const xstart = Math.min(t0.x, t1.x) + const xend = Math.max(t0.x, t1.x) + const ystart = Math.min(t0.y, t1.y) + const yend = Math.max(t0.y, t1.y) + const total = (1 + xend - xstart) * (1 + yend - ystart) + + return { + xstart: xstart, + xend: xend, + ystart: ystart, + yend: yend, + total: total, + zoomlevel: zoomlevel + } + } + } \ No newline at end of file diff --git a/UI/Base/ScrollableFullScreen.ts b/UI/Base/ScrollableFullScreen.ts index 4a158ec0a..da8114f8c 100644 --- a/UI/Base/ScrollableFullScreen.ts +++ b/UI/Base/ScrollableFullScreen.ts @@ -36,6 +36,8 @@ export default class ScrollableFullScreen extends UIElement { this._component = this.BuildComponent(title("desktop"), content("desktop"), isShown) .SetClass("hidden md:block"); this._fullscreencomponent = this.BuildComponent(title("mobile"), content("mobile"), isShown); + + const self = this; isShown.addCallback(isShown => { if (isShown) { diff --git a/UI/Base/VariableUIElement.ts b/UI/Base/VariableUIElement.ts index fbc3bb564..cf53daf10 100644 --- a/UI/Base/VariableUIElement.ts +++ b/UI/Base/VariableUIElement.ts @@ -2,22 +2,23 @@ import {UIEventSource} from "../../Logic/UIEventSource"; import BaseUIElement from "../BaseUIElement"; export class VariableUiElement extends BaseUIElement { - private _element: HTMLElement; + private readonly _contents: UIEventSource; - constructor( - contents: UIEventSource - ) { + constructor(contents: UIEventSource) { super(); + this._contents = contents; - this._element = document.createElement("span"); - const el = this._element; - contents.addCallbackAndRun((contents) => { + } + + protected InnerConstructElement(): HTMLElement { + const el = document.createElement("span"); + this._contents.addCallbackAndRun((contents) => { while (el.firstChild) { el.removeChild(el.lastChild); } if (contents === undefined) { - return el; + return; } if (typeof contents === "string") { el.innerHTML = contents; @@ -35,9 +36,6 @@ export class VariableUiElement extends BaseUIElement { } } }); - } - - protected InnerConstructElement(): HTMLElement { - return this._element; + return el; } } diff --git a/UI/BaseUIElement.ts b/UI/BaseUIElement.ts index 99462acbd..a11db9319 100644 --- a/UI/BaseUIElement.ts +++ b/UI/BaseUIElement.ts @@ -100,8 +100,6 @@ export default abstract class BaseUIElement { throw "ERROR! This is not a correct baseUIElement: " + this.constructor.name } try { - - const el = this.InnerConstructElement(); if (el === undefined) { diff --git a/UI/Image/Attribution.ts b/UI/Image/Attribution.ts index 30040482f..9afd9b815 100644 --- a/UI/Image/Attribution.ts +++ b/UI/Image/Attribution.ts @@ -13,17 +13,16 @@ export default class Attribution extends VariableUiElement { } super( license.map((license: LicenseInfo) => { - - if (license?.artist === undefined) { - return undefined; + if(license === undefined){ + return undefined } - + return new Combine([ icon?.SetClass("block left").SetStyle("height: 2em; width: 2em; padding-right: 0.5em;"), new Combine([ - Translations.W(license.artist).SetClass("block font-bold"), - Translations.W((license.license ?? "") === "" ? "CC0" : (license.license ?? "")) + Translations.W(license?.artist ?? ".").SetClass("block font-bold"), + Translations.W((license?.license ?? "") === "" ? "CC0" : (license?.license ?? "")) ]).SetClass("flex flex-col") ]).SetClass("flex flex-row bg-black text-white text-sm absolute bottom-0 left-0 p-0.5 pl-5 pr-3 rounded-lg") diff --git a/UI/Image/DeleteImage.ts b/UI/Image/DeleteImage.ts index a5ee19266..fe3f2cf09 100644 --- a/UI/Image/DeleteImage.ts +++ b/UI/Image/DeleteImage.ts @@ -48,7 +48,7 @@ export default class DeleteImage extends Toggle { tags.map(tags => (tags[key] ?? "") !== "") ), undefined /*Login (and thus editing) is disabled*/, - State.state?.featureSwitchUserbadge ?? new UIEventSource(true) + State.state.osmConnection.isLoggedIn ) this.SetClass("cursor-pointer") } diff --git a/UI/Input/LocationInput.ts b/UI/Input/LocationInput.ts index a350e38d3..0621eccc8 100644 --- a/UI/Input/LocationInput.ts +++ b/UI/Input/LocationInput.ts @@ -9,7 +9,6 @@ import State from "../../State"; import AvailableBaseLayers from "../../Logic/Actors/AvailableBaseLayers"; import {BBox, GeoOperations} from "../../Logic/GeoOperations"; import ShowDataLayer from "../ShowDataLayer/ShowDataLayer"; -import * as L from "leaflet"; import ShowDataMultiLayer from "../ShowDataLayer/ShowDataMultiLayer"; import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"; import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; diff --git a/UI/Popup/EditableTagRendering.ts b/UI/Popup/EditableTagRendering.ts index 4e5c313f5..4c5a13ea5 100644 --- a/UI/Popup/EditableTagRendering.ts +++ b/UI/Popup/EditableTagRendering.ts @@ -31,8 +31,10 @@ export default class EditableTagRendering extends Toggle { const answerWithEditButton = new Combine([answer, - new Toggle(editButton, undefined, State.state.osmConnection.isLoggedIn)]) - .SetClass("flex justify-between w-full") + new Toggle(editButton, + undefined, + State.state.osmConnection.isLoggedIn) + ]).SetClass("flex justify-between w-full") const cancelbutton = diff --git a/UI/Popup/SplitRoadWizard.ts b/UI/Popup/SplitRoadWizard.ts index 01fb00d05..b1df0a5fa 100644 --- a/UI/Popup/SplitRoadWizard.ts +++ b/UI/Popup/SplitRoadWizard.ts @@ -71,7 +71,7 @@ export default class SplitRoadWizard extends Toggle { }) new ShowDataMultiLayer({ - features: new StaticFeatureSource([roadElement]), + features: new StaticFeatureSource([roadElement], false), layers: State.state.filteredLayers, leafletMap: miniMap.leafletMap, enablePopups: false, diff --git a/UI/ShowDataLayer/PerTileCountAggregator.ts b/UI/ShowDataLayer/PerTileCountAggregator.ts new file mode 100644 index 000000000..82e247f74 --- /dev/null +++ b/UI/ShowDataLayer/PerTileCountAggregator.ts @@ -0,0 +1,156 @@ +import FeatureSource, {FeatureSourceForLayer, Tiled} from "../../Logic/FeatureSource/FeatureSource"; +import {BBox} from "../../Logic/GeoOperations"; +import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; +import {UIEventSource} from "../../Logic/UIEventSource"; +import {Tiles} from "../../Models/TileRange"; + + +/** + * A feature source containing meta features. + * It will contain exactly one point for every tile of the specified (dynamic) zoom level + */ +export default class PerTileCountAggregator implements FeatureSource { + public readonly features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); + public readonly name: string = "PerTileCountAggregator" + + private readonly perTile: Map = new Map() + private readonly _requestedZoomLevel: UIEventSource; + + constructor(requestedZoomLevel: UIEventSource) { + this._requestedZoomLevel = requestedZoomLevel; + const self = this; + this._requestedZoomLevel.addCallbackAndRun(_ => self.update()) + } + + private update() { + const now = new Date() + const allCountsAsFeatures : {feature: any, freshness: Date}[] = [] + const aggregate = this.calculatePerTileCount() + aggregate.forEach((totalsPerLayer, tileIndex) => { + const totals = {} + let totalCount = 0 + totalsPerLayer.forEach((total, layerId) => { + totals[layerId] = total + totalCount += total + }) + totals["tileId"] = tileIndex + totals["count"] = totalCount + const feature = { + "type": "Feature", + "properties": totals, + "geometry": { + "type": "Point", + "coordinates": Tiles.centerPointOf(...Tiles.tile_from_index(tileIndex)) + } + } + allCountsAsFeatures.push({feature: feature, freshness: now}) + + const bbox= BBox.fromTileIndex(tileIndex) + const box = { + "type": "Feature", + "properties":totals, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [bbox.minLon, bbox.minLat], + [bbox.minLon, bbox.maxLat], + [bbox.maxLon, bbox.maxLat], + [bbox.maxLon, bbox.minLat], + [bbox.minLon, bbox.minLat] + ] + ] + } + } + allCountsAsFeatures.push({feature:box, freshness: now}) + }) + this.features.setData(allCountsAsFeatures) + } + + /** + * Calculates an aggregate count per tile and per subtile + * @private + */ + private calculatePerTileCount() { + const perTileCount = new Map>() + const targetZoom = this._requestedZoomLevel.data; + // We only search for tiles of the same zoomlevel or a higher zoomlevel, which is embedded + for (const singleTileCounter of Array.from(this.perTile.values())) { + + let tileZ = singleTileCounter.z + let tileX = singleTileCounter.x + let tileY = singleTileCounter.y + if (tileZ < targetZoom) { + continue; + } + + while (tileZ > targetZoom) { + tileX = Math.floor(tileX / 2) + tileY = Math.floor(tileY / 2) + tileZ-- + } + const tileI = Tiles.tile_index(tileZ, tileX, tileY) + let counts = perTileCount.get(tileI) + if (counts === undefined) { + counts = new Map() + perTileCount.set(tileI, counts) + } + singleTileCounter.countsPerLayer.data.forEach((count, layerId) => { + if (counts.has(layerId)) { + counts.set(layerId, count + counts.get(layerId)) + } else { + counts.set(layerId, count) + } + }) + } + return perTileCount; + } + + public addTile(tile: FeatureSourceForLayer & Tiled, shouldBeCounted: UIEventSource) { + let counter = this.perTile.get(tile.tileIndex) + if (counter === undefined) { + counter = new SingleTileCounter(tile.tileIndex) + this.perTile.set(tile.tileIndex, counter) + // We do **NOT** add a callback on the perTile index, even though we could! It'll update just fine without it + } + counter.addTileCount(tile, shouldBeCounted) + } + + +} + +/** + * Keeps track of a single tile + */ +class SingleTileCounter implements Tiled { + public readonly bbox: BBox; + public readonly tileIndex: number; + public readonly countsPerLayer: UIEventSource> = new UIEventSource>(new Map()) + private readonly registeredLayers: Map = new Map(); + public readonly z: number + public readonly x: number + public readonly y: number + + constructor(tileIndex: number) { + this.tileIndex = tileIndex + this.bbox = BBox.fromTileIndex(tileIndex) + const [z, x, y] = Tiles.tile_from_index(tileIndex) + this.z = z; + this.x = x; + this.y = y + } + + public addTileCount(source: FeatureSourceForLayer, shouldBeCounted: UIEventSource) { + const layer = source.layer.layerDef + this.registeredLayers.set(layer.id, layer) + const self = this + source.features.map(f => { + /*if (!shouldBeCounted.data) { + return; + }*/ + self.countsPerLayer.data.set(layer.id, f.length) + self.countsPerLayer.ping() + }, [shouldBeCounted]) + } + +} \ No newline at end of file diff --git a/UI/ShowDataLayer/ShowDataLayer.ts b/UI/ShowDataLayer/ShowDataLayer.ts index cdda7889b..278ea3597 100644 --- a/UI/ShowDataLayer/ShowDataLayer.ts +++ b/UI/ShowDataLayer/ShowDataLayer.ts @@ -41,13 +41,14 @@ export default class ShowDataLayer { options.leafletMap.addCallback(_ => self.update(options)); this.update(options); - State.state.selectedElement.addCallbackAndRunD(selected => { if (self._leafletMap.data === undefined) { return; } const v = self.leafletLayersPerId.get(selected.properties.id) - if(v === undefined){return;} + if (v === undefined) { + return; + } const leafletLayer = v.leafletlayer const feature = v.feature if (leafletLayer.getPopup().isOpen()) { @@ -66,6 +67,21 @@ export default class ShowDataLayer { } }) + + options.doShowLayer?.addCallbackAndRun(doShow => { + const mp = options.leafletMap.data; + if (this.geoLayer == undefined || mp == undefined) { + return; + } + if (doShow) { + mp.addLayer(this.geoLayer) + } else { + mp.removeLayer(this.geoLayer) + } + + + }) + } private update(options) { @@ -83,21 +99,19 @@ export default class ShowDataLayer { mp.removeLayer(this.geoLayer); } - this.geoLayer= this.CreateGeojsonLayer() + this.geoLayer = this.CreateGeojsonLayer() const allFeats = this._features.data; for (const feat of allFeats) { if (feat === undefined) { continue } - try{ + try { this.geoLayer.addData(feat); - }catch(e){ + } catch (e) { console.error("Could not add ", feat, "to the geojson layer in leaflet") } } - mp.addLayer(this.geoLayer) - if (options.zoomToFeatures ?? false) { try { mp.fitBounds(this.geoLayer.getBounds(), {animate: false}) @@ -105,6 +119,10 @@ export default class ShowDataLayer { console.error(e) } } + + if (options.doShowLayer?.data ?? true) { + mp.addLayer(this.geoLayer) + } } @@ -125,7 +143,8 @@ export default class ShowDataLayer { return; } - const tagSource = feature.properties.id === undefined ? new UIEventSource(feature.properties) : State.state.allElements.getEventSourceById(feature.properties.id) + const tagSource = feature.properties.id === undefined ? new UIEventSource(feature.properties) : + State.state.allElements.getEventSourceById(feature.properties.id) const clickable = !(layer.title === undefined && (layer.tagRenderings ?? []).length === 0) const style = layer.GenerateLeafletStyle(tagSource, clickable); const baseElement = style.icon.html; @@ -193,8 +212,10 @@ export default class ShowDataLayer { infobox.Activate(); }); + // Add the feature to the index to open the popup when needed this.leafletLayersPerId.set(feature.properties.id, {feature: feature, leafletlayer: leafletLayer}) + } private CreateGeojsonLayer(): L.Layer { diff --git a/UI/ShowDataLayer/ShowDataLayerOptions.ts b/UI/ShowDataLayer/ShowDataLayerOptions.ts index 349472351..2323ce067 100644 --- a/UI/ShowDataLayer/ShowDataLayerOptions.ts +++ b/UI/ShowDataLayer/ShowDataLayerOptions.ts @@ -6,4 +6,5 @@ export interface ShowDataLayerOptions { leafletMap: UIEventSource, enablePopups?: true | boolean, zoomToFeatures?: false | boolean, + doShowLayer?: UIEventSource } \ No newline at end of file diff --git a/UI/ShowDataLayer/ShowTileInfo.ts b/UI/ShowDataLayer/ShowTileInfo.ts new file mode 100644 index 000000000..a2fa322b6 --- /dev/null +++ b/UI/ShowDataLayer/ShowTileInfo.ts @@ -0,0 +1,79 @@ +import FeatureSource, {Tiled} from "../../Logic/FeatureSource/FeatureSource"; +import {UIEventSource} from "../../Logic/UIEventSource"; +import {Utils} from "../../Utils"; +import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; +import ShowDataLayer from "./ShowDataLayer"; +import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"; +import {GeoOperations} from "../../Logic/GeoOperations"; +import {Tiles} from "../../Models/TileRange"; + +export default class ShowTileInfo { + public static readonly styling = new LayerConfig({ + id: "tileinfo_styling", + title: { + render: "Tile {z}/{x}/{y}" + }, + tagRenderings: [ + "all_tags" + ], + source: { + osmTags: "tileId~*" + }, + color: {"render": "#3c3"}, + width: { + "render": "1" + }, + label: { + render: "
{count}
" + } + }, "tileinfo", true) + + constructor(options: { + source: FeatureSource & Tiled, leafletMap: UIEventSource, layer?: LayerConfig, + doShowLayer?: UIEventSource + }) { + + + const source = options.source + const metaFeature: UIEventSource = + source.features.map(features => { + const bbox = source.bbox + const [z, x, y] = Tiles.tile_from_index(source.tileIndex) + const box = { + "type": "Feature", + "properties": { + "z": z, + "x": x, + "y": y, + "tileIndex": source.tileIndex, + "source": source.name, + "count": features.length, + tileId: source.name + "/" + source.tileIndex + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [bbox.minLon, bbox.minLat], + [bbox.minLon, bbox.maxLat], + [bbox.maxLon, bbox.maxLat], + [bbox.maxLon, bbox.minLat], + [bbox.minLon, bbox.minLat] + ] + ] + } + } + const center = GeoOperations.centerpoint(box) + return [box, center] + }) + + new ShowDataLayer({ + layerToShow: ShowTileInfo.styling, + features: new StaticFeatureSource(metaFeature, false), + leafletMap: options.leafletMap, + doShowLayer: options.doShowLayer + }) + + } + +} \ No newline at end of file diff --git a/Utils.ts b/Utils.ts index 9f1373498..477598f79 100644 --- a/Utils.ts +++ b/Utils.ts @@ -10,7 +10,7 @@ export class Utils { */ public static runningFromConsole = typeof window === "undefined"; public static readonly assets_path = "./assets/svg/"; - public static externalDownloadFunction: (url: string) => Promise; + public static externalDownloadFunction: (url: string, headers?: any) => Promise; private static knownKeys = ["addExtraTags", "and", "calculatedTags", "changesetmessage", "clustering", "color", "condition", "customCss", "dashArray", "defaultBackgroundId", "description", "descriptionTail", "doNotDownload", "enableAddNewPoints", "enableBackgroundLayerSelection", "enableGeolocation", "enableLayers", "enableMoreQuests", "enableSearch", "enableShareScreen", "enableUserBadge", "freeform", "hideFromOverview", "hideInAnswer", "icon", "iconOverlays", "iconSize", "id", "if", "ifnot", "isShown", "key", "language", "layers", "lockLocation", "maintainer", "mappings", "maxzoom", "maxZoom", "minNeededElements", "minzoom", "multiAnswer", "name", "or", "osmTags", "passAllFeatures", "presets", "question", "render", "roaming", "roamingRenderings", "rotation", "shortDescription", "socialImage", "source", "startLat", "startLon", "startZoom", "tagRenderings", "tags", "then", "title", "titleIcons", "type", "version", "wayHandling", "widenFactor", "width"] private static extraKeys = ["nl", "en", "fr", "de", "pt", "es", "name", "phone", "email", "amenity", "leisure", "highway", "building", "yes", "no", "true", "false"] @@ -247,64 +247,6 @@ export class Utils { return dict.get(k); } - /** - * Calculates the tile bounds of the - * @param z - * @param x - * @param y - * @returns [[maxlat, minlon], [minlat, maxlon]] - */ - static tile_bounds(z: number, x: number, y: number): [[number, number], [number, number]] { - return [[Utils.tile2lat(y, z), Utils.tile2long(x, z)], [Utils.tile2lat(y + 1, z), Utils.tile2long(x + 1, z)]] - } - - static tile_bounds_lon_lat(z: number, x: number, y: number): [[number, number], [number, number]] { - return [[Utils.tile2long(x, z), Utils.tile2lat(y, z)], [Utils.tile2long(x + 1, z), Utils.tile2lat(y + 1, z)]] - } - - static tile_index(z: number, x: number, y: number): number { - return ((x * (2 << z)) + y) * 100 + z - } - - /** - * Given a tile index number, returns [z, x, y] - * @param index - * @returns 'zxy' - */ - static tile_from_index(index: number): [number, number, number] { - const z = index % 100; - const factor = 2 << z - index = Math.floor(index / 100) - return [z, Math.floor(index / factor), index % factor] - } - - /** - * Return x, y of the tile containing (lat, lon) on the given zoom level - */ - static embedded_tile(lat: number, lon: number, z: number): { x: number, y: number, z: number } { - return {x: Utils.lon2tile(lon, z), y: Utils.lat2tile(lat, z), z: z} - } - - static TileRangeBetween(zoomlevel: number, lat0: number, lon0: number, lat1: number, lon1: number): TileRange { - const t0 = Utils.embedded_tile(lat0, lon0, zoomlevel) - const t1 = Utils.embedded_tile(lat1, lon1, zoomlevel) - - const xstart = Math.min(t0.x, t1.x) - const xend = Math.max(t0.x, t1.x) - const ystart = Math.min(t0.y, t1.y) - const yend = Math.max(t0.y, t1.y) - const total = (1 + xend - xstart) * (1 + yend - ystart) - - return { - xstart: xstart, - xend: xend, - ystart: ystart, - yend: yend, - total: total, - zoomlevel: zoomlevel - } - } - public static MinifyJSON(stringified: string): string { stringified = stringified.replace(/\|/g, "||"); @@ -345,16 +287,7 @@ export class Utils { return result; } - public static MapRange(tileRange: TileRange, f: (x: number, y: number) => T): T[] { - const result: T[] = [] - for (let x = tileRange.xstart; x <= tileRange.xend; x++) { - for (let y = tileRange.ystart; y <= tileRange.yend; y++) { - const t = f(x, y); - result.push(t) - } - } - return result; - } + private static injectedDownloads = {} @@ -362,7 +295,7 @@ export class Utils { Utils.injectedDownloads[url] = data } - public static downloadJson(url: string): Promise { + public static downloadJson(url: string, headers?: any): Promise { const injected = Utils.injectedDownloads[url] if (injected !== undefined) { @@ -371,7 +304,7 @@ export class Utils { } if (this.externalDownloadFunction !== undefined) { - return this.externalDownloadFunction(url) + return this.externalDownloadFunction(url, headers) } return new Promise((resolve, reject) => { @@ -379,7 +312,6 @@ export class Utils { xhr.onload = () => { if (xhr.status == 200) { try { - console.log("Got a response! Parsing now...") resolve(JSON.parse(xhr.response)) } catch (e) { reject("Not a valid json: " + xhr.response) @@ -390,6 +322,13 @@ export class Utils { }; xhr.open('GET', url); xhr.setRequestHeader("accept", "application/json") + if (headers !== undefined) { + + for (const key in headers) { + xhr.setRequestHeader(key, headers[key]) + } + } + xhr.send(); } ) @@ -449,22 +388,6 @@ export class Utils { return bestColor ?? hex; } - private static tile2long(x, z) { - return (x / Math.pow(2, z) * 360 - 180); - } - - private static tile2lat(y, z) { - const n = Math.PI - 2 * Math.PI * y / Math.pow(2, z); - return (180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)))); - } - - private static lon2tile(lon, zoom) { - return (Math.floor((lon + 180) / 360 * Math.pow(2, zoom))); - } - - private static lat2tile(lat, zoom) { - return (Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, zoom))); - } private static colorDiff(c0: { r: number, g: number, b: number }, c1: { r: number, g: number, b: number }) { return Math.abs(c0.r - c1.r) + Math.abs(c0.g - c1.g) + Math.abs(c0.b - c1.b); @@ -506,5 +429,11 @@ export class Utils { } return copy } + + public static async waitFor(timeMillis: number): Promise { + return new Promise((resolve) => { + window.setTimeout(resolve, timeMillis); + }) + } } diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json index c726b52dd..03dc010ee 100644 --- a/assets/layers/charging_station/charging_station.json +++ b/assets/layers/charging_station/charging_station.json @@ -1592,8 +1592,13 @@ { "#": "plugs-9", "question": { - "en": "How much plugs of type Type 2 with cable (mennekes) are available here?", - "nl": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?" + "en": "What kind of authentication is available at the charging station?", + "nl": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?", + "it": "Quali sono gli orari di apertura di questa stazione di ricarica?", + "ja": "この充電ステーションはいつオープンしますか?", + "nb_NO": "Når åpnet denne ladestasjonen?", + "ru": "В какое время работает эта зарядная станция?", + "zh_Hant": "何時是充電站開放使用的時間?" }, "render": { "en": "There are Type 2 with cable (mennekes) plugs of type Type 2 with cable (mennekes) available here", @@ -1608,17 +1613,52 @@ "socket:type2_cable~*", "socket:type2_cable!=0" ] + }, + "en": { + "0": { + "then": "Authentication by a membership card" + }, + "1": { + "then": "Authentication by an app" + }, + "2": { + "then": "Authentication via phone call is available" + }, + "3": { + "then": "Authentication via phone call is available" + }, + "4": { + "then": "Authentication via NFC is available" + }, + "5": { + "then": "Authentication via Money Card is available" + }, + "6": { + "then": "Authentication via debit card is available" + }, + "7": { + "then": "No authentication is needed" + } } }, { "#": "voltage-9", "question": { - "en": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", - "nl": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) " + "en": "What's the phone number for authentication call or SMS?", + "nl": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) ", + "it": "A quale rete appartiene questa stazione di ricarica?", + "ja": "この充電ステーションの運営チェーンはどこですか?", + "ru": "К какой сети относится эта станция?", + "zh_Hant": "充電站所屬的網路是?" }, "render": { - "en": "Type 2 with cable (mennekes) outputs {socket:type2_cable:voltage} volt", - "nl": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt" + "en": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}", + "nl": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt", + "it": "{network}", + "ja": "{network}", + "nb_NO": "{network}", + "ru": "{network}", + "zh_Hant": "{network}" }, "freeform": { "key": "socket:type2_cable:voltage", @@ -1650,7 +1690,7 @@ { "#": "current-9", "question": { - "en": "What current do the plugs with Type 2 with cable (mennekes) offer?", + "en": "When is this charging station opened?", "nl": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?" }, "render": { @@ -1665,7 +1705,7 @@ { "if": "socket:socket:type2_cable:current=16 A", "then": { - "en": "Type 2 with cable (mennekes) outputs at most 16 A", + "en": "24/7 opened (including holidays)", "nl": "Type 2 met kabel (J1772) levert een stroom van maximaal 16 A" } }, @@ -1687,12 +1727,12 @@ { "#": "power-output-9", "question": { - "en": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?" + "en": "How much does one have to pay to use this charging station?", + "nl": "Hoeveel kost het gebruik van dit oplaadpunt?" }, "render": { - "en": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:output}", - "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal {socket:type2_cable:output}" + "en": "Using this charging station costs {charge}", + "nl": "Dit oplaadpunt gebruiken kost {charge}" }, "freeform": { "key": "socket:type2_cable:output", @@ -1702,8 +1742,8 @@ { "if": "socket:socket:type2_cable:output=11 kw", "then": { - "en": "Type 2 with cable (mennekes) outputs at most 11 kw", - "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal 11 kw" + "en": "Free to use", + "nl": "Gratis te gebruiken" } }, { @@ -1740,17 +1780,31 @@ "socket:tesla_supercharger_ccs~*", "socket:tesla_supercharger_ccs!=0" ] + }, + "en": { + "mappings+": { + "0": { + "then": "Payment is done using a dedicated app" + } + } + }, + "nl": { + "mappings+": { + "0": { + "then": "Betalen via een app van het netwerk" + } + } } }, { "#": "voltage-10", "question": { - "en": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", - "nl": "Welke spanning levert de stekker van type " + "en": "What is the maximum amount of time one is allowed to stay here?", + "nl": "Hoelang mag een voertuig hier blijven staan?" }, "render": { - "en": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt", - "nl": " heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" + "en": "One can stay at most {canonical(maxstay)}", + "nl": "De maximale parkeertijd hier is {canonical(maxstay)}" }, "freeform": { "key": "socket:tesla_supercharger_ccs:voltage", @@ -1760,8 +1814,8 @@ { "if": "socket:socket:tesla_supercharger_ccs:voltage=500 V", "then": { - "en": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt", - "nl": " heeft een spanning van 500 volt" + "en": "No timelimit on leaving your vehicle here", + "nl": "Geen maximum parkeertijd" } }, { @@ -1782,11 +1836,11 @@ { "#": "current-10", "question": { - "en": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "en": "Is this charging station part of a network?", "nl": "Welke stroom levert de stekker van type ?" }, "render": { - "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A", + "en": "Part of the network {network}", "nl": " levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" }, "freeform": { @@ -1797,14 +1851,14 @@ { "if": "socket:socket:tesla_supercharger_ccs:current=125 A", "then": { - "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A", + "en": "Not part of a bigger network", "nl": " levert een stroom van maximaal 125 A" } }, { "if": "socket:socket:tesla_supercharger_ccs:current=350 A", "then": { - "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A", + "en": "Not part of a bigger network", "nl": " levert een stroom van maximaal 350 A" } } @@ -1849,11 +1903,11 @@ { "#": "plugs-11", "question": { - "en": "How much plugs of type Tesla Supercharger (destination) are available here?", + "en": "What number can one call if there is a problem with this charging station?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" }, "render": { - "en": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here", + "en": "In case of problems, call {phone}", "nl": "Hier zijn stekkers van het type " }, "freeform": { @@ -1870,11 +1924,11 @@ { "#": "voltage-11", "question": { - "en": "What voltage do the plugs with Tesla Supercharger (destination) offer?", + "en": "What is the email address of the operator?", "nl": "Welke spanning levert de stekker van type " }, "render": { - "en": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt", + "en": "In case of problems, send an email to {email}", "nl": " heeft een spanning van {socket:tesla_destination:voltage} volt" }, "freeform": { @@ -1900,11 +1954,11 @@ { "#": "current-11", "question": { - "en": "What current do the plugs with Tesla Supercharger (destination) offer?", + "en": "What is the website of the operator?", "nl": "Welke stroom levert de stekker van type ?" }, "render": { - "en": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A", + "en": "More info on {website}", "nl": " levert een stroom van maximaal {socket:tesla_destination:current}A" }, "freeform": { @@ -1981,7 +2035,7 @@ { "#": "plugs-12", "question": { - "en": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", + "en": "What is the reference number of this charging station?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" }, "render": { @@ -2002,8 +2056,8 @@ { "#": "voltage-12", "question": { - "en": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "nl": "Welke spanning levert de stekker van type " + "en": "Is this charging point in use?", + "nl": "Is dit oplaadpunt operationeel?" }, "render": { "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt", @@ -2017,15 +2071,15 @@ { "if": "socket:socket:tesla_destination:voltage=230 V", "then": { - "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt", - "nl": " heeft een spanning van 230 volt" + "en": "This charging station is broken", + "nl": "Dit oplaadpunt is kapot" } }, { "if": "socket:socket:tesla_destination:voltage=400 V", "then": { - "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt", - "nl": " heeft een spanning van 400 volt" + "en": "A charging station is planned here", + "nl": "Hier zal binnenkort een oplaadpunt gebouwd worden" } } ], @@ -2296,6 +2350,14 @@ "en": "Payment is done using a dedicated app", "nl": "Betalen via een app van het netwerk" } + }, + { + "if": "payment:membership_card=yes", + "ifnot": "payment:membership_card=no", + "then": { + "en": "Payment is done using a membership card", + "nl": "Betalen via een lidkaart van het netwerk" + } } ], "mappings": [ diff --git a/assets/layers/drinking_water/drinking_water.json b/assets/layers/drinking_water/drinking_water.json index 3645da855..8b0651933 100644 --- a/assets/layers/drinking_water/drinking_water.json +++ b/assets/layers/drinking_water/drinking_water.json @@ -1,61 +1,6 @@ { - "id": "drinking_water", - "name": { - "en": "Drinking water", - "nl": "Drinkbaar water", - "fr": "Eau potable", - "gl": "Auga potábel", - "de": "Trinkwasser", - "it": "Acqua potabile", - "ru": "Питьевая вода", - "id": "Air minum" - }, - "title": { - "render": { - "en": "Drinking water", - "nl": "Drinkbaar water", - "fr": "Eau potable", - "gl": "Auga potábel", - "de": "Trinkwasser", - "it": "Acqua potabile", - "ru": "Питьевая вода", - "id": "Air minum" - } - }, - "icon": { - "render": "pin:#6BC4F7;./assets/layers/drinking_water/drips.svg" - }, - "iconOverlays": [ - { - "if": { - "or": [ - "operational_status=broken", - "operational_status=closed" - ] - }, - "then": "close:#c33", - "badge": true - } - ], - "iconSize": "40,40,bottom", - "source": { - "osmTags": { - "and": [ - "amenity=drinking_water", - "access!=permissive", - "access!=private" - ] - } - }, - "calculatedTags": [ - "_closest_other_drinking_water_id=feat.closest('drinking_water')?.id", - "_closest_other_drinking_water_distance=Math.floor(feat.distanceTo(feat.closest('drinking_water')).distance * 1000)" - ], - "minzoom": 13, - "wayHandling": 1, - "presets": [ - { - "title": { + "id": "drinking_water", + "name": { "en": "Drinking water", "nl": "Drinkbaar water", "fr": "Eau potable", @@ -64,105 +9,161 @@ "it": "Acqua potabile", "ru": "Питьевая вода", "id": "Air minum" - }, - "tags": [ - "amenity=drinking_water" - ] - } - ], - "color": "#6bc4f7", - "tagRenderings": [ - "images", - { - "#": "Still in use?", - "question": { - "en": "Is this drinking water spot still operational?", - "nl": "Is deze drinkwaterkraan nog steeds werkende?", - "it": "Questo punto di acqua potabile è sempre funzionante?", - "fr": "Ce point d'eau potable est-il toujours opérationnel ?", - "de": "Ist diese Trinkwasserstelle noch in Betrieb?" - }, - "render": { - "en": "The operational status is {operational_status", - "nl": "Deze waterkraan-status is {operational_status}", - "it": "Lo stato operativo è {operational_status}", - "fr": "L'état opérationnel est {operational_status", - "de": "Der Betriebsstatus ist {operational_status" - }, - "freeform": { - "key": "operational_status" - }, - "mappings": [ - { - "if": "operational_status=", - "then": { - "en": "This drinking water works", - "nl": "Deze drinkwaterfontein werkt", - "it": "La fontanella funziona", - "fr": "Cette fontaine fonctionne" - } - }, - { - "if": "operational_status=broken", - "then": { - "en": "This drinking water is broken", - "nl": "Deze drinkwaterfontein is kapot", - "it": "La fontanella è guasta", - "fr": "Cette fontaine est cassée" - } - }, - { - "if": "operational_status=closed", - "then": { - "en": "This drinking water is closed", - "nl": "Deze drinkwaterfontein is afgesloten", - "it": "La fontanella è chiusa", - "fr": "Cette fontaine est fermée" - } - } - ] }, - { - "#": "Bottle refill", - "question": { - "en": "How easy is it to fill water bottles?", - "nl": "Hoe gemakkelijk is het om drinkbussen bij te vullen?", - "de": "Wie einfach ist es, Wasserflaschen zu füllen?", - "it": "Quanto è facile riempire d’acqua le bottiglie?", - "fr": "Est-il facile de remplir des bouteilles d'eau ?" - }, - "mappings": [ + "title": { + "render": { + "en": "Drinking water", + "nl": "Drinkbaar water", + "fr": "Eau potable", + "gl": "Auga potábel", + "de": "Trinkwasser", + "it": "Acqua potabile", + "ru": "Питьевая вода", + "id": "Air minum" + } + }, + "icon": { + "render": "pin:#6BC4F7;./assets/layers/drinking_water/drips.svg" + }, + "iconOverlays": [ { - "if": "bottle=yes", - "then": { - "en": "It is easy to refill water bottles", - "nl": "Een drinkbus bijvullen gaat makkelijk", - "de": "Es ist einfach, Wasserflaschen nachzufüllen", - "it": "È facile riempire d’acqua le bottiglie", - "fr": "Il est facile de remplir les bouteilles d'eau" - } + "if": { + "or": [ + "operational_status=broken", + "operational_status=closed" + ] + }, + "then": "close:#c33", + "badge": true + } + ], + "iconSize": "40,40,bottom", + "source": { + "osmTags": { + "and": [ + "amenity=drinking_water", + "access!=permissive", + "access!=private" + ] + } + }, + "calculatedTags": [ + "_closest_other_drinking_water=feat.closestn('drinking_water', 1, 500).map(f => ({id: f.feat.id, distance: f.distance}))[0]", + "_closest_other_drinking_water_id=JSON.parse(feat.properties._closest_other_drinking_water)?.id", + "_closest_other_drinking_water_distance=Math.floor(JSON.parse(feat.properties._closest_other_drinking_water)?.distance * 1000)" + ], + "minzoom": 13, + "wayHandling": 1, + "presets": [ + { + "title": { + "en": "Drinking water", + "nl": "Drinkbaar water", + "fr": "Eau potable", + "gl": "Auga potábel", + "de": "Trinkwasser", + "it": "Acqua potabile", + "ru": "Питьевая вода", + "id": "Air minum" + }, + "tags": [ + "amenity=drinking_water" + ] + } + ], + "color": "#6bc4f7", + "tagRenderings": [ + "images", + { + "#": "Still in use?", + "question": { + "en": "Is this drinking water spot still operational?", + "nl": "Is deze drinkwaterkraan nog steeds werkende?", + "it": "Questo punto di acqua potabile è sempre funzionante?", + "fr": "Ce point d'eau potable est-il toujours opérationnel ?", + "de": "Ist diese Trinkwasserstelle noch in Betrieb?" + }, + "render": { + "en": "The operational status is {operational_status", + "nl": "Deze waterkraan-status is {operational_status}", + "it": "Lo stato operativo è {operational_status}", + "fr": "L'état opérationnel est {operational_status", + "de": "Der Betriebsstatus ist {operational_status" + }, + "freeform": { + "key": "operational_status" + }, + "mappings": [ + { + "if": "operational_status=", + "then": { + "en": "This drinking water works", + "nl": "Deze drinkwaterfontein werkt", + "it": "La fontanella funziona", + "fr": "Cette fontaine fonctionne" + } + }, + { + "if": "operational_status=broken", + "then": { + "en": "This drinking water is broken", + "nl": "Deze drinkwaterfontein is kapot", + "it": "La fontanella è guasta", + "fr": "Cette fontaine est cassée" + } + }, + { + "if": "operational_status=closed", + "then": { + "en": "This drinking water is closed", + "nl": "Deze drinkwaterfontein is afgesloten", + "it": "La fontanella è chiusa", + "fr": "Cette fontaine est fermée" + } + } + ] }, { - "if": "bottle=no", - "then": { - "en": "Water bottles may not fit", - "nl": "Een drinkbus past moeilijk", - "de": "Wasserflaschen passen möglicherweise nicht", - "it": "Le bottiglie d’acqua potrebbero non entrare", - "fr": "Les bouteilles d'eau peuvent ne pas passer" - } + "#": "Bottle refill", + "question": { + "en": "How easy is it to fill water bottles?", + "nl": "Hoe gemakkelijk is het om drinkbussen bij te vullen?", + "de": "Wie einfach ist es, Wasserflaschen zu füllen?", + "it": "Quanto è facile riempire d’acqua le bottiglie?", + "fr": "Est-il facile de remplir des bouteilles d'eau ?" + }, + "mappings": [ + { + "if": "bottle=yes", + "then": { + "en": "It is easy to refill water bottles", + "nl": "Een drinkbus bijvullen gaat makkelijk", + "de": "Es ist einfach, Wasserflaschen nachzufüllen", + "it": "È facile riempire d’acqua le bottiglie", + "fr": "Il est facile de remplir les bouteilles d'eau" + } + }, + { + "if": "bottle=no", + "then": { + "en": "Water bottles may not fit", + "nl": "Een drinkbus past moeilijk", + "de": "Wasserflaschen passen möglicherweise nicht", + "it": "Le bottiglie d’acqua potrebbero non entrare", + "fr": "Les bouteilles d'eau peuvent ne pas passer" + } + } + ] + }, + { + "render": { + "en": "There is another drinking water fountain at {_closest_other_drinking_water_distance} meter", + "nl": "Er bevindt zich een ander drinkwaterpunt op {_closest_other_drinking_water_distance} meter", + "it": "C’è un’altra fontanella a {_closest_other_drinking_water_distance} metri", + "de": "Ein weiterer Trinkwasserbrunnen befindet sich in {_closest_other_drinking_water_distance} Meter", + "fr": "Une autre source d’eau potable est à {_closest_other_drinking_water_distance} mètres a>" + }, + "condition": "_closest_other_drinking_water_id~*" } - ] - }, - { - "render": { - "en": "There is another drinking water fountain at {_closest_other_drinking_water_distance} meter", - "nl": "Er bevindt zich een ander drinkwaterpunt op {_closest_other_drinking_water_distance} meter", - "it": "C’è un’altra fontanella a {_closest_other_drinking_water_distance} metri", - "de": "Ein weiterer Trinkwasserbrunnen befindet sich in {_closest_other_drinking_water_distance} Meter", - "fr": "Une autre source d’eau potable est à {_closest_other_drinking_water_distance} mètres a>" - }, - "condition": "_closest_other_drinking_water_id~*" - } - ] + ] } \ No newline at end of file diff --git a/assets/layers/food/food.json b/assets/layers/food/food.json index 26dbcc65a..64b18a306 100644 --- a/assets/layers/food/food.json +++ b/assets/layers/food/food.json @@ -12,6 +12,7 @@ ] } }, + "minzoom": 12, "wayHandling": 1, "icon": { "render": "circle:white;./assets/layers/food/restaurant.svg", diff --git a/assets/layers/public_bookcase/public_bookcase.json b/assets/layers/public_bookcase/public_bookcase.json index 786d7e220..a4715ce5a 100644 --- a/assets/layers/public_bookcase/public_bookcase.json +++ b/assets/layers/public_bookcase/public_bookcase.json @@ -19,7 +19,7 @@ "source": { "osmTags": "amenity=public_bookcase" }, - "minzoom": 12, + "minzoom": 10, "wayHandling": 2, "title": { "render": { diff --git a/assets/themes/benches/benches.json b/assets/themes/benches/benches.json index a43292dbf..d94f88597 100644 --- a/assets/themes/benches/benches.json +++ b/assets/themes/benches/benches.json @@ -52,7 +52,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "", "layers": [ "bench", diff --git a/assets/themes/bicyclelib/bicyclelib.json b/assets/themes/bicyclelib/bicyclelib.json index fe40e2d34..3a8fb3e8e 100644 --- a/assets/themes/bicyclelib/bicyclelib.json +++ b/assets/themes/bicyclelib/bicyclelib.json @@ -40,7 +40,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 1.5, "roamingRenderings": [], "layers": [ "bicycle_library" diff --git a/assets/themes/bike_monitoring_station/bike_monitoring_stations.json b/assets/themes/bike_monitoring_station/bike_monitoring_stations.json index 5703e2ed5..f64339938 100644 --- a/assets/themes/bike_monitoring_station/bike_monitoring_stations.json +++ b/assets/themes/bike_monitoring_station/bike_monitoring_stations.json @@ -47,7 +47,7 @@ "startLat": 50.8435, "startLon": 4.3688, "startZoom": 14, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "", "layers": [ "bike_monitoring_station" diff --git a/assets/themes/binoculars/binoculars.json b/assets/themes/binoculars/binoculars.json index 0f9817e46..75622d3a5 100644 --- a/assets/themes/binoculars/binoculars.json +++ b/assets/themes/binoculars/binoculars.json @@ -22,7 +22,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "", "layers": [ "binocular" diff --git a/assets/themes/buurtnatuur/buurtnatuur.json b/assets/themes/buurtnatuur/buurtnatuur.json index 9c82e4d44..9c4f2a189 100644 --- a/assets/themes/buurtnatuur/buurtnatuur.json +++ b/assets/themes/buurtnatuur/buurtnatuur.json @@ -25,7 +25,7 @@ "startLat": 50.8435, "startLon": 4.3688, "startZoom": 16, - "widenFactor": 0.01, + "widenFactor": 1.2, "socialImage": "./assets/themes/buurtnatuur/social_image.jpg", "layers": [ { diff --git a/assets/themes/cafes_and_pubs/cafes_and_pubs.json b/assets/themes/cafes_and_pubs/cafes_and_pubs.json index 1f9b704f8..c7ec682d1 100644 --- a/assets/themes/cafes_and_pubs/cafes_and_pubs.json +++ b/assets/themes/cafes_and_pubs/cafes_and_pubs.json @@ -18,7 +18,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "", "layers": [ "cafe_pub" diff --git a/assets/themes/campersite/campersite.json b/assets/themes/campersite/campersite.json index 7b24124e5..592b9f544 100644 --- a/assets/themes/campersite/campersite.json +++ b/assets/themes/campersite/campersite.json @@ -47,7 +47,7 @@ "startLat": 43.14, "startLon": 3.14, "startZoom": 14, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "./assets/themes/campersite/Bar%C3%9Fel_Wohnmobilstellplatz.jpg", "layers": [ { diff --git a/assets/themes/charging_stations/charging_stations.json b/assets/themes/charging_stations/charging_stations.json index b193b4daf..16745dc60 100644 --- a/assets/themes/charging_stations/charging_stations.json +++ b/assets/themes/charging_stations/charging_stations.json @@ -39,7 +39,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "", "defaultBackgroundId": "CartoDB.Voyager", "layers": [ diff --git a/assets/themes/climbing/climbing.json b/assets/themes/climbing/climbing.json index 44a2520db..143fcddc3 100644 --- a/assets/themes/climbing/climbing.json +++ b/assets/themes/climbing/climbing.json @@ -48,7 +48,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "", "layers": [ { diff --git a/assets/themes/cycle_highways/cycle_highways.json b/assets/themes/cycle_highways/cycle_highways.json index 85a91aa7d..09312a9ea 100644 --- a/assets/themes/cycle_highways/cycle_highways.json +++ b/assets/themes/cycle_highways/cycle_highways.json @@ -21,7 +21,7 @@ "clustering": { "maxZoom": 1 }, - "widenFactor": 0.005, + "widenFactor": 1.1, "enableDownload": true, "enablePdfDownload": true, "layers": [ diff --git a/assets/themes/cycle_infra/cycle_infra.json b/assets/themes/cycle_infra/cycle_infra.json index 7446095d9..8af56b886 100644 --- a/assets/themes/cycle_infra/cycle_infra.json +++ b/assets/themes/cycle_infra/cycle_infra.json @@ -24,7 +24,7 @@ "startLat": 51, "startLon": 3.75, "startZoom": 11, - "widenFactor": 1, + "widenFactor": 1.5, "socialImage": "./assets/themes/cycle_infra/cycle-infra.svg", "enableDownload": true, "layers": [ diff --git a/assets/themes/cyclofix/cyclofix.json b/assets/themes/cyclofix/cyclofix.json index 2e1016d77..47a626736 100644 --- a/assets/themes/cyclofix/cyclofix.json +++ b/assets/themes/cyclofix/cyclofix.json @@ -40,7 +40,7 @@ "defaultBackgroundId": "CartoDB.Voyager", "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "assets/themes/cyclofix/logo.svg", "layers": [ "bike_cafe", diff --git a/assets/themes/facadegardens/facadegardens.json b/assets/themes/facadegardens/facadegardens.json index f3e28a1ef..08a87063c 100644 --- a/assets/themes/facadegardens/facadegardens.json +++ b/assets/themes/facadegardens/facadegardens.json @@ -38,7 +38,7 @@ "startLat": 51.02768, "startLon": 4.480705, "startZoom": 15, - "widenFactor": 0.05, + "widenFactor": 1.5, "socialImage": "", "layers": [ { diff --git a/assets/themes/food/food.json b/assets/themes/food/food.json index 416f9d161..fed26b560 100644 --- a/assets/themes/food/food.json +++ b/assets/themes/food/food.json @@ -18,7 +18,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 3, "socialImage": "", "layers": [ "food" diff --git a/assets/themes/fritures/fritures.json b/assets/themes/fritures/fritures.json index 33d83c0f5..fec9038cc 100644 --- a/assets/themes/fritures/fritures.json +++ b/assets/themes/fritures/fritures.json @@ -24,7 +24,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 3, "socialImage": "", "layers": [ { diff --git a/assets/themes/fruit_trees/fruit_trees.json b/assets/themes/fruit_trees/fruit_trees.json index 60d6e8a23..58b350f89 100644 --- a/assets/themes/fruit_trees/fruit_trees.json +++ b/assets/themes/fruit_trees/fruit_trees.json @@ -18,7 +18,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.001, + "widenFactor": 2, "socialImage": "", "hideFromOverview": true, "layers": [ diff --git a/assets/themes/ghostbikes/ghostbikes.json b/assets/themes/ghostbikes/ghostbikes.json index 229a32751..7c9aec38b 100644 --- a/assets/themes/ghostbikes/ghostbikes.json +++ b/assets/themes/ghostbikes/ghostbikes.json @@ -52,7 +52,7 @@ "startZoom": 1, "startLat": 0, "startLon": 0, - "widenFactor": 0.1, + "widenFactor": 5, "layers": [ "ghost_bike" ], diff --git a/assets/themes/grb.json b/assets/themes/grb.json index 37efacae0..dee3ca22f 100644 --- a/assets/themes/grb.json +++ b/assets/themes/grb.json @@ -18,7 +18,7 @@ "startLat": 51.2132, "startLon": 3.231, "startZoom": 14, - "widenFactor": 0.05, + "widenFactor": 2, "cacheTimeout": 3600, "socialImage": "", "layers": [ diff --git a/assets/themes/hackerspaces/hackerspaces.json b/assets/themes/hackerspaces/hackerspaces.json index 538bc0414..98bf59574 100644 --- a/assets/themes/hackerspaces/hackerspaces.json +++ b/assets/themes/hackerspaces/hackerspaces.json @@ -18,7 +18,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 5, "socialImage": "", "layers": [ { diff --git a/assets/themes/hailhydrant/hailhydrant.json b/assets/themes/hailhydrant/hailhydrant.json index c5cdd3795..c6e7a1f84 100644 --- a/assets/themes/hailhydrant/hailhydrant.json +++ b/assets/themes/hailhydrant/hailhydrant.json @@ -36,7 +36,7 @@ "startLat": 13.67801, "startLon": 121.6625, "startZoom": 6, - "widenFactor": 0.05, + "widenFactor": 3, "socialImage": "", "layers": [ { diff --git a/assets/themes/maps/maps.json b/assets/themes/maps/maps.json index e34cdce30..52d757a9d 100644 --- a/assets/themes/maps/maps.json +++ b/assets/themes/maps/maps.json @@ -36,7 +36,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 5, "socialImage": "", "layers": [ "map" diff --git a/assets/themes/nature/nature.json b/assets/themes/nature/nature.json index 9aeb9e498..0f8004e2c 100644 --- a/assets/themes/nature/nature.json +++ b/assets/themes/nature/nature.json @@ -18,7 +18,7 @@ "startLat": 51.20875, "startLon": 3.22435, "startZoom": 12, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "", "layers": [ "drinking_water", diff --git a/assets/themes/natuurpunt/natuurpunt.json b/assets/themes/natuurpunt/natuurpunt.json index 4616fae02..f0e921d38 100644 --- a/assets/themes/natuurpunt/natuurpunt.json +++ b/assets/themes/natuurpunt/natuurpunt.json @@ -23,7 +23,7 @@ "startLat": 51.20875, "startLon": 3.22435, "startZoom": 15, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "", "defaultBackgroundId": "CartoDB.Positron", "enablePdfDownload": true, diff --git a/assets/themes/observation_towers/observation_towers.json b/assets/themes/observation_towers/observation_towers.json index 2bdd0cbad..3ab5a6b58 100644 --- a/assets/themes/observation_towers/observation_towers.json +++ b/assets/themes/observation_towers/observation_towers.json @@ -22,7 +22,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 5, "socialImage": "", "layers": [ "observation_tower" diff --git a/assets/themes/parkings/parkings.json b/assets/themes/parkings/parkings.json index bb25e8bfd..ca322052c 100644 --- a/assets/themes/parkings/parkings.json +++ b/assets/themes/parkings/parkings.json @@ -22,7 +22,7 @@ "startLat": 51.20875, "startLon": 3.22435, "startZoom": 12, - "widenFactor": 0.05, + "widenFactor": 1.2, "socialImage": "", "layers": [ "parking" diff --git a/assets/themes/personal/personal.json b/assets/themes/personal/personal.json index 02e26cdbd..d9df14a7b 100644 --- a/assets/themes/personal/personal.json +++ b/assets/themes/personal/personal.json @@ -41,7 +41,7 @@ "startLat": 0, "startLon": 0, "startZoom": 16, - "widenFactor": 0.05, + "widenFactor": 3, "layers": [], "roamingRenderings": [] } \ No newline at end of file diff --git a/assets/themes/play_forests/play_forests.json b/assets/themes/play_forests/play_forests.json index bd824ee67..5c65a702a 100644 --- a/assets/themes/play_forests/play_forests.json +++ b/assets/themes/play_forests/play_forests.json @@ -19,7 +19,7 @@ "startLon": 0, "startZoom": 1, "hideFromOverview": true, - "widenFactor": 0.05, + "widenFactor": 3, "socialImage": "", "layers": [ "play_forest" diff --git a/assets/themes/playgrounds/playgrounds.json b/assets/themes/playgrounds/playgrounds.json index 418aa36bc..2908a88b4 100644 --- a/assets/themes/playgrounds/playgrounds.json +++ b/assets/themes/playgrounds/playgrounds.json @@ -38,7 +38,7 @@ "startLat": 50.535, "startLon": 4.399, "startZoom": 13, - "widenFactor": 0.05, + "widenFactor": 5, "socialImage": "", "layers": [ "playground" diff --git a/assets/themes/shops/shops.json b/assets/themes/shops/shops.json index 09209f3f4..706268e3d 100644 --- a/assets/themes/shops/shops.json +++ b/assets/themes/shops/shops.json @@ -34,7 +34,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 3, "socialImage": "", "layers": [ { diff --git a/assets/themes/speelplekken/speelplekken.json b/assets/themes/speelplekken/speelplekken.json index 21cb17212..a87466742 100644 --- a/assets/themes/speelplekken/speelplekken.json +++ b/assets/themes/speelplekken/speelplekken.json @@ -22,7 +22,7 @@ "startLat": 51.17174, "startLon": 4.449462, "startZoom": 12, - "widenFactor": 0.05, + "widenFactor": 1.2, "socialImage": "./assets/themes/speelplekken/social_image.jpg", "defaultBackgroundId": "CartoDB.Positron", "layers": [ diff --git a/assets/themes/speelplekken/speelplekken_temp.json b/assets/themes/speelplekken/speelplekken_temp.json index 867298215..752d793b3 100644 --- a/assets/themes/speelplekken/speelplekken_temp.json +++ b/assets/themes/speelplekken/speelplekken_temp.json @@ -20,7 +20,7 @@ "startLat": 51.17174, "startLon": 4.449462, "startZoom": 12, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "", "defaultBackgroundId": "CartoDB.Positron", "layers": [ diff --git a/assets/themes/sport_pitches/sport_pitches.json b/assets/themes/sport_pitches/sport_pitches.json index 7f1fdeebd..4db24cdd6 100644 --- a/assets/themes/sport_pitches/sport_pitches.json +++ b/assets/themes/sport_pitches/sport_pitches.json @@ -37,7 +37,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "", "layers": [ "sport_pitch" diff --git a/assets/themes/surveillance/surveillance.json b/assets/themes/surveillance/surveillance.json index 001045fd1..a61633b23 100644 --- a/assets/themes/surveillance/surveillance.json +++ b/assets/themes/surveillance/surveillance.json @@ -37,7 +37,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "", "defaultBackgroundId": "osm", "layers": [ diff --git a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json index be5567d5d..c09b548e8 100644 --- a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json +++ b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json @@ -20,7 +20,7 @@ "startZoom": 8, "startLat": 50.8536, "startLon": 4.433, - "widenFactor": 0.2, + "widenFactor": 2, "layers": [ { "builtin": [ diff --git a/assets/themes/toilets/toilets.json b/assets/themes/toilets/toilets.json index e343d9ea2..1d1567de4 100644 --- a/assets/themes/toilets/toilets.json +++ b/assets/themes/toilets/toilets.json @@ -35,7 +35,7 @@ "startZoom": 12, "startLat": 51.2095, "startLon": 3.2222, - "widenFactor": 0.05, + "widenFactor": 3, "icon": "./assets/themes/toilets/toilets.svg", "layers": [ "toilet" diff --git a/assets/themes/trees/trees.json b/assets/themes/trees/trees.json index ea26fdeca..52961293a 100644 --- a/assets/themes/trees/trees.json +++ b/assets/themes/trees/trees.json @@ -45,7 +45,7 @@ "startLat": 50.642, "startLon": 4.482, "startZoom": 8, - "widenFactor": 0.01, + "widenFactor": 1.5, "socialImage": "./assets/themes/trees/logo.svg", "clustering": { "maxZoom": 18 diff --git a/assets/themes/uk_addresses/uk_addresses.json b/assets/themes/uk_addresses/uk_addresses.json index b89d25e60..7de4c3a36 100644 --- a/assets/themes/uk_addresses/uk_addresses.json +++ b/assets/themes/uk_addresses/uk_addresses.json @@ -18,7 +18,7 @@ "startLat": -0.08528530407, "startLon": 51.52103754846, "startZoom": 18, - "widenFactor": 0.5, + "widenFactor": 1.5, "socialImage": "", "layers": [ { diff --git a/assets/themes/waste_basket/waste_basket.json b/assets/themes/waste_basket/waste_basket.json index 2a1ecef84..eb95d85eb 100644 --- a/assets/themes/waste_basket/waste_basket.json +++ b/assets/themes/waste_basket/waste_basket.json @@ -22,7 +22,7 @@ "startLat": 0, "startLon": 0, "startZoom": 1, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "", "layers": [ { diff --git a/assets/themes/widths/width.json b/assets/themes/widths/width.json index 5ee75eb7e..6e56d5f21 100644 --- a/assets/themes/widths/width.json +++ b/assets/themes/widths/width.json @@ -25,7 +25,7 @@ "startLat": 51.20875, "startLon": 3.22435, "startZoom": 14, - "widenFactor": 0.05, + "widenFactor": 2, "socialImage": "", "layers": [ { diff --git a/scripts/ScriptUtils.ts b/scripts/ScriptUtils.ts index 3551ba5f8..22cdd0d93 100644 --- a/scripts/ScriptUtils.ts +++ b/scripts/ScriptUtils.ts @@ -48,13 +48,10 @@ export default class ScriptUtils { }) } - public static DownloadJSON(url, options?: { - headers: any - }): Promise { + public static DownloadJSON(url, headers?: any): Promise { return new Promise((resolve, reject) => { try { - - const headers = options?.headers ?? {} + headers = headers ?? {} headers.accept = "application/json" console.log("Fetching", url) const urlObj = new URL(url) diff --git a/scripts/generateCache.ts b/scripts/generateCache.ts index 5a8377125..a5a915bde 100644 --- a/scripts/generateCache.ts +++ b/scripts/generateCache.ts @@ -14,7 +14,7 @@ import RelationsTracker from "../Logic/Osm/RelationsTracker"; import * as OsmToGeoJson from "osmtogeojson"; import MetaTagging from "../Logic/MetaTagging"; import {UIEventSource} from "../Logic/UIEventSource"; -import {TileRange} from "../Models/TileRange"; +import {TileRange, Tiles} from "../Models/TileRange"; import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"; import ScriptUtils from "./ScriptUtils"; import PerLayerFeatureSourceSplitter from "../Logic/FeatureSource/PerLayerFeatureSourceSplitter"; @@ -86,7 +86,7 @@ async function downloadRaw(targetdir: string, r: TileRange, overpass: Overpass)/ } console.log("x:", (x - r.xstart), "/", (r.xend - r.xstart), "; y:", (y - r.ystart), "/", (r.yend - r.ystart), "; total: ", downloaded, "/", r.total, "failed: ", failed, "skipped: ", skipped) - const boundsArr = Utils.tile_bounds(r.zoomlevel, x, y) + const boundsArr = Tiles.tile_bounds(r.zoomlevel, x, y) const bounds = { north: Math.max(boundsArr[0][0], boundsArr[1][0]), south: Math.min(boundsArr[0][0], boundsArr[1][0]), @@ -174,7 +174,7 @@ function loadAllTiles(targetdir: string, r: TileRange, theme: LayoutConfig, extr allFeatures.push(...geojson.features) } } - return new StaticFeatureSource(allFeatures) + return new StaticFeatureSource(allFeatures, false) } /** @@ -225,7 +225,7 @@ function postProcess(allFeatures: FeatureSource, theme: LayoutConfig, relationsT delete feature.feature["bbox"] } // Lets save this tile! - const [z, x, y] = Utils.tile_from_index(tile.tileIndex) + const [z, x, y] = Tiles.tile_from_index(tile.tileIndex) console.log("Writing tile ", z, x, y, layerId) const targetPath = geoJsonName(targetdir + "_" + layerId, x, y, z) createdTiles.push(tile.tileIndex) @@ -241,7 +241,7 @@ function postProcess(allFeatures: FeatureSource, theme: LayoutConfig, relationsT // Only thing left to do is to create the index const path = targetdir + "_" + layerId + "_overview.json" const perX = {} - createdTiles.map(i => Utils.tile_from_index(i)).forEach(([z, x, y]) => { + createdTiles.map(i => Tiles.tile_from_index(i)).forEach(([z, x, y]) => { const key = "" + x if (perX[key] === undefined) { perX[key] = [] @@ -279,7 +279,7 @@ async function main(args: string[]) { const lat1 = Number(args[5]) const lon1 = Number(args[6]) - const tileRange = Utils.TileRangeBetween(zoomlevel, lat0, lon0, lat1, lon1) + const tileRange = Tiles.TileRangeBetween(zoomlevel, lat0, lon0, lat1, lon1) const theme = AllKnownLayouts.allKnownLayouts.get(themeName) if (theme === undefined) { diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index ce05cf32b..6fda20b0b 100644 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -33,7 +33,7 @@ class TranslationPart { } const v = translations[translationsKey] if (typeof (v) != "string") { - console.error("Non-string object in translation: ", translations[translationsKey]) + console.error("Non-string object in translation while trying to add more translations to '", translationsKey ,"': ", v) throw "Error in an object depicting a translation: a non-string object was found. (" + context + ")\n You probably put some other section accidentally in the translation" } this.contents.set(translationsKey, v) @@ -41,9 +41,7 @@ class TranslationPart { } recursiveAdd(object: any, context: string) { - - - const isProbablyTranslationObject = knownLanguages.map(l => object.hasOwnProperty(l)).filter(x => x).length > 0; + const isProbablyTranslationObject = knownLanguages.some(l => object.hasOwnProperty(l)); if (isProbablyTranslationObject) { this.addTranslationObject(object, context) return; From f749cb0963c63341d1b566a9b7237a776f1c4065 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 17:49:47 +0200 Subject: [PATCH 11/65] Small changes --- Logic/MetaTagging.ts | 5 +---- assets/layers/drinking_water/drinking_water.json | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Logic/MetaTagging.ts b/Logic/MetaTagging.ts index c7eda184b..c02ed04e4 100644 --- a/Logic/MetaTagging.ts +++ b/Logic/MetaTagging.ts @@ -111,13 +111,11 @@ export default class MetaTagging { d = JSON.stringify(d); } feature.properties[key] = d; - console.log("Written a delayed calculated tag onto ", feature.properties.id, ": ", key, ":==", d) }) result = result.data } if (result === undefined || result === "") { - console.log("Calculated tag for", key, "gave undefined", feature.properties.id) return; } if (typeof result !== "string") { @@ -125,10 +123,9 @@ export default class MetaTagging { result = JSON.stringify(result); } feature.properties[key] = result; - console.log("Written a calculated tag onto ", feature.properties.id, ": ", key, ":==", result) } catch (e) { if (MetaTagging.errorPrintCount < MetaTagging.stopErrorOutputAt) { - console.warn("Could not calculate a calculated tag defined by " + code + " due to " + e + ". This is code defined in the theme. Are you the theme creator? Doublecheck your code. Note that the metatags might not be stable on new features", e) + console.warn("Could not calculate a calculated tag defined by " + code + " due to " + e + ". This is code defined in the theme. Are you the theme creator? Doublecheck your code. Note that the metatags might not be stable on new features", e,e.stack) MetaTagging.errorPrintCount++; if (MetaTagging.errorPrintCount == MetaTagging.stopErrorOutputAt) { console.error("Got ", MetaTagging.stopErrorOutputAt, " errors calculating this metatagging - stopping output now") diff --git a/assets/layers/drinking_water/drinking_water.json b/assets/layers/drinking_water/drinking_water.json index 8b0651933..abd282403 100644 --- a/assets/layers/drinking_water/drinking_water.json +++ b/assets/layers/drinking_water/drinking_water.json @@ -48,9 +48,9 @@ } }, "calculatedTags": [ - "_closest_other_drinking_water=feat.closestn('drinking_water', 1, 500).map(f => ({id: f.feat.id, distance: f.distance}))[0]", + "_closest_other_drinking_water=feat.closestn('drinking_water', 1, undefined, 5000).map(f => ({id: f.feat.id, distance: ''+f.distance}))[0]", "_closest_other_drinking_water_id=JSON.parse(feat.properties._closest_other_drinking_water)?.id", - "_closest_other_drinking_water_distance=Math.floor(JSON.parse(feat.properties._closest_other_drinking_water)?.distance * 1000)" + "_closest_other_drinking_water_distance=Math.floor(Number(JSON.parse(feat.properties._closest_other_drinking_water)?.distance) * 1000)" ], "minzoom": 13, "wayHandling": 1, From 1d6102f6dea21cdd98d0730492650601e3dcab3a Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 17:54:49 +0200 Subject: [PATCH 12/65] Add id to tagRenderingConfig --- Models/ThemeConfig/Json/TagRenderingConfigJson.ts | 7 +++++++ Models/ThemeConfig/TagRenderingConfig.ts | 2 ++ 2 files changed, 9 insertions(+) diff --git a/Models/ThemeConfig/Json/TagRenderingConfigJson.ts b/Models/ThemeConfig/Json/TagRenderingConfigJson.ts index 9152bf463..ab4552534 100644 --- a/Models/ThemeConfig/Json/TagRenderingConfigJson.ts +++ b/Models/ThemeConfig/Json/TagRenderingConfigJson.ts @@ -5,6 +5,13 @@ import {AndOrTagConfigJson} from "./TagConfigJson"; * If the desired tags are missing and a question is defined, a question will be shown instead. */ export interface TagRenderingConfigJson { + + /** + * The id of the tagrendering, should be an unique string. + * Used to keep the translations in sync + */ + id?: string, + /** * Renders this value. Note that "{key}"-parts are substituted by the corresponding values of the element. * If neither 'textFieldQuestion' nor 'mappings' are defined, this text is simply shown as default value. diff --git a/Models/ThemeConfig/TagRenderingConfig.ts b/Models/ThemeConfig/TagRenderingConfig.ts index 912152c2e..af092e462 100644 --- a/Models/ThemeConfig/TagRenderingConfig.ts +++ b/Models/ThemeConfig/TagRenderingConfig.ts @@ -13,6 +13,7 @@ import {Utils} from "../../Utils"; */ export default class TagRenderingConfig { + readonly id?: string; readonly render?: Translation; readonly question?: Translation; readonly condition?: TagsFilter; @@ -56,6 +57,7 @@ export default class TagRenderingConfig { return; } + this.id = json.id ?? ""; this.render = Translations.T(json.render, context + ".render"); this.question = Translations.T(json.question, context + ".question"); this.roaming = json.roaming ?? false; From d6aecc23a2130d0e934e123930e7a0402d362b45 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 17:56:09 +0200 Subject: [PATCH 13/65] Translation reset --- langs/layers/en.json | 235 ++++++++++++++++++++++++++++++++++++-- langs/layers/it.json | 4 +- langs/layers/ja.json | 4 +- langs/layers/nb_NO.json | 4 +- langs/layers/nl.json | 204 ++++++++++++++++++++++++++++++++- langs/layers/ru.json | 4 +- langs/layers/zh_Hant.json | 4 +- 7 files changed, 435 insertions(+), 24 deletions(-) diff --git a/langs/layers/en.json b/langs/layers/en.json index d7910039a..ee83b328d 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -922,6 +922,18 @@ }, "9": { "question": "Has a Type 2 CCS (mennekes) connector" + }, + "10": { + "question": "Has a Type 2 with cable (mennekes) connector" + }, + "11": { + "question": "Has a Tesla Supercharger CCS (a branded type2_css) connector" + }, + "12": { + "question": "Has a Tesla Supercharger (destination) connector" + }, + "13": { + "question": "Has a Tesla supercharger (destination (A Type 2 with cable branded as tesla) connector" } } } @@ -953,6 +965,10 @@ }, "question": "Which vehicles are allowed to charge here?" }, + "2": { + "question": "Who is allowed to use this charging station?", + "render": "Access is {access}" + }, "3": { "question": "How much vehicles can be charged here at the same time?", "render": "{capacity} vehicles can be charged here at the same time" @@ -1012,6 +1028,30 @@ }, "17": { "then": " Type 2 CCS (mennekes)" + }, + "18": { + "then": " Type 2 with cable (mennekes)" + }, + "19": { + "then": " Type 2 with cable (mennekes)" + }, + "20": { + "then": " Tesla Supercharger CCS (a branded type2_css)" + }, + "21": { + "then": " Tesla Supercharger CCS (a branded type2_css)" + }, + "22": { + "then": " Tesla Supercharger (destination)" + }, + "23": { + "then": " Tesla Supercharger (destination)" + }, + "24": { + "then": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)" + }, + "25": { + "then": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)" } }, "question": "Which charging stations are available here?" @@ -1356,6 +1396,163 @@ "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}" }, "41": { + "question": "How much plugs of type Type 2 with cable (mennekes) are available here?", + "render": "There are Type 2 with cable (mennekes) plugs of type Type 2 with cable (mennekes) available here" + }, + "42": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs 230 volt" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs {socket:type2_cable:voltage} volt" + }, + "43": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs at most 16 A" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:current}A" + }, + "44": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs at most 11 kw" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:output}" + }, + "45": { + "question": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", + "render": "There are Tesla Supercharger CCS (a branded type2_css) plugs of type Tesla Supercharger CCS (a branded type2_css) available here" + }, + "46": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt" + }, + "1": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs 920 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt" + }, + "47": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A" + }, + "48": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 50 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:output}" + }, + "49": { + "question": "How much plugs of type Tesla Supercharger (destination) are available here?", + "render": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here" + }, + "50": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs 480 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt" + }, + "51": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger (destination) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A" + }, + "52": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs at most 120 kw" + }, + "1": { + "then": "Tesla Supercharger (destination) outputs at most 150 kw" + }, + "2": { + "then": "Tesla Supercharger (destination) outputs at most 250 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:output}" + }, + "53": { + "question": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", + "render": "There are Tesla supercharger (destination (A Type 2 with cable branded as tesla) plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) available here" + }, + "54": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt" + }, + "55": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 16 A" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:current}A" + }, + "56": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 11 kw" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:output}" + }, + "57": { "mappings": { "0": { "then": "Authentication by a membership card" @@ -1384,11 +1581,11 @@ }, "question": "What kind of authentication is available at the charging station?" }, - "42": { + "58": { "question": "What's the phone number for authentication call or SMS?", "render": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}" }, - "43": { + "59": { "mappings": { "0": { "then": "24/7 opened (including holidays)" @@ -1396,7 +1593,7 @@ }, "question": "When is this charging station opened?" }, - "44": { + "60": { "mappings": { "0": { "then": "Free to use" @@ -1405,8 +1602,13 @@ "question": "How much does one have to pay to use this charging station?", "render": "Using this charging station costs {charge}" }, - "45": { + "61": { "override": { + "mappings": { + "0": { + "then": "Payment is done using a dedicated app" + } + }, "mappings+": { "0": { "then": "Payment is done using a dedicated app" @@ -1414,7 +1616,7 @@ } } }, - "46": { + "62": { "mappings": { "0": { "then": "No timelimit on leaving your vehicle here" @@ -1423,7 +1625,7 @@ "question": "What is the maximum amount of time one is allowed to stay here?", "render": "One can stay at most {canonical(maxstay)}" }, - "47": { + "63": { "mappings": { "0": { "then": "Not part of a bigger network" @@ -1435,22 +1637,22 @@ "question": "Is this charging station part of a network?", "render": "Part of the network {network}" }, - "49": { + "65": { "question": "What number can one call if there is a problem with this charging station?", "render": "In case of problems, call {phone}" }, - "50": { + "66": { "question": "What is the email address of the operator?", "render": "In case of problems, send an email to {email}" }, - "51": { + "67": { "question": "What is the website of the operator?", "render": "More info on {website}" }, - "53": { + "69": { "question": "What is the reference number of this charging station?" }, - "54": { + "70": { "mappings": { "0": { "then": "This charging station is broken" @@ -1469,6 +1671,17 @@ } }, "question": "Is this charging point in use?" + }, + "71": { + "mappings": { + "0": { + "then": "No additional parking cost while charging" + }, + "1": { + "then": "An additional parking fee should be paid while charging" + } + }, + "question": "Does one have to pay a parking fee while charging?" } }, "title": { diff --git a/langs/layers/it.json b/langs/layers/it.json index af1edc7e4..ffab4fe5d 100644 --- a/langs/layers/it.json +++ b/langs/layers/it.json @@ -694,10 +694,10 @@ "description": "Una stazione di ricarica", "name": "Stazioni di ricarica", "tagRenderings": { - "41": { + "57": { "question": "Quali sono gli orari di apertura di questa stazione di ricarica?" }, - "42": { + "58": { "question": "A quale rete appartiene questa stazione di ricarica?", "render": "{network}" } diff --git a/langs/layers/ja.json b/langs/layers/ja.json index 24b81b31b..c3276aa50 100644 --- a/langs/layers/ja.json +++ b/langs/layers/ja.json @@ -3,10 +3,10 @@ "description": "充電ステーション", "name": "充電ステーション", "tagRenderings": { - "41": { + "57": { "question": "この充電ステーションはいつオープンしますか?" }, - "42": { + "58": { "question": "この充電ステーションの運営チェーンはどこですか?", "render": "{network}" } diff --git a/langs/layers/nb_NO.json b/langs/layers/nb_NO.json index 12821e829..d3cfb1b18 100644 --- a/langs/layers/nb_NO.json +++ b/langs/layers/nb_NO.json @@ -108,10 +108,10 @@ "description": "En ladestasjon", "name": "Ladestasjoner", "tagRenderings": { - "41": { + "57": { "question": "Når åpnet denne ladestasjonen?" }, - "42": { + "58": { "render": "{network}" } }, diff --git a/langs/layers/nl.json b/langs/layers/nl.json index bddc9c255..c4ec78ae7 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -1024,6 +1024,18 @@ }, "9": { "question": "Heeft een " + }, + "10": { + "question": "Heeft een Type 2 met kabel (J1772) " + }, + "11": { + "question": "Heeft een " + }, + "12": { + "question": "Heeft een " + }, + "13": { + "question": "Heeft een " } } } @@ -1088,6 +1100,30 @@ }, "17": { "then": " " + }, + "18": { + "then": " Type 2 met kabel (J1772)" + }, + "19": { + "then": " Type 2 met kabel (J1772)" + }, + "20": { + "then": " " + }, + "21": { + "then": " " + }, + "22": { + "then": " " + }, + "23": { + "then": " " + }, + "24": { + "then": " " + }, + "25": { + "then": " " } } }, @@ -1430,7 +1466,164 @@ "question": "Welk vermogen levert een enkele stekker van type ?", "render": " levert een vermogen van maximaal {socket:type2_combo:output}" }, + "41": { + "question": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?", + "render": "Hier zijn Type 2 met kabel (J1772) stekkers van het type Type 2 met kabel (J1772)" + }, + "42": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) heeft een spanning van 230 volt" + }, + "1": { + "then": "Type 2 met kabel (J1772) heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) ", + "render": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt" + }, + "43": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 16 A" + }, + "1": { + "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?", + "render": "Type 2 met kabel (J1772) levert een stroom van maximaal {socket:type2_cable:current}A" + }, "44": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?", + "render": "Type 2 met kabel (J1772) levert een vermogen van maximaal {socket:type2_cable:output}" + }, + "45": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "46": { + "mappings": { + "0": { + "then": " heeft een spanning van 500 volt" + }, + "1": { + "then": " heeft een spanning van 920 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" + }, + "47": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" + }, + "48": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" + }, + "49": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "50": { + "mappings": { + "0": { + "then": " heeft een spanning van 480 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "51": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "52": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 120 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 150 kw" + }, + "2": { + "then": " levert een vermogen van maximaal 250 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "53": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "54": { + "mappings": { + "0": { + "then": " heeft een spanning van 230 volt" + }, + "1": { + "then": " heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "55": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 16 A" + }, + "1": { + "then": " levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "56": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "60": { "mappings": { "0": { "then": "Gratis te gebruiken" @@ -1439,8 +1632,13 @@ "question": "Hoeveel kost het gebruik van dit oplaadpunt?", "render": "Dit oplaadpunt gebruiken kost {charge}" }, - "45": { + "61": { "override": { + "mappings": { + "0": { + "then": "Betalen via een app van het netwerk" + } + }, "mappings+": { "0": { "then": "Betalen via een app van het netwerk" @@ -1448,7 +1646,7 @@ } } }, - "46": { + "62": { "mappings": { "0": { "then": "Geen maximum parkeertijd" @@ -1457,7 +1655,7 @@ "question": "Hoelang mag een voertuig hier blijven staan?", "render": "De maximale parkeertijd hier is {canonical(maxstay)}" }, - "54": { + "70": { "mappings": { "0": { "then": "Dit oplaadpunt is kapot" diff --git a/langs/layers/ru.json b/langs/layers/ru.json index 8993b6f05..1ac38e5af 100644 --- a/langs/layers/ru.json +++ b/langs/layers/ru.json @@ -521,10 +521,10 @@ "description": "Зарядная станция", "name": "Зарядные станции", "tagRenderings": { - "41": { + "57": { "question": "В какое время работает эта зарядная станция?" }, - "42": { + "58": { "question": "К какой сети относится эта станция?", "render": "{network}" } diff --git a/langs/layers/zh_Hant.json b/langs/layers/zh_Hant.json index 00df6ac59..7a04e7f13 100644 --- a/langs/layers/zh_Hant.json +++ b/langs/layers/zh_Hant.json @@ -391,10 +391,10 @@ "description": "充電站", "name": "充電站", "tagRenderings": { - "41": { + "57": { "question": "何時是充電站開放使用的時間?" }, - "42": { + "58": { "question": "充電站所屬的網路是?", "render": "{network}" } From f386c3a25f3c7dce9359eabbc17a632049d66df0 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 18:00:24 +0200 Subject: [PATCH 14/65] Convert comments in tagRenderings into IDs as they were mostly used like this --- assets/layers/barrier/barrier.json | 28 +- .../bicycle_tube_vending_machine.json | 4 +- assets/layers/bike_parking/bike_parking.json | 28 +- .../bike_repair_station.json | 8 +- assets/layers/cafe_pub/cafe_pub.json | 8 +- .../charging_station/charging_station.json | 280 +++++++++--------- .../cycleways_and_roads.json | 36 +-- .../layers/drinking_water/drinking_water.json | 8 +- assets/layers/food/food.json | 28 +- .../layers/nature_reserve/nature_reserve.json | 48 +-- .../observation_tower/observation_tower.json | 20 +- assets/layers/parking/parking.json | 8 +- .../surveillance_camera.json | 32 +- assets/layers/trail/trail.json | 20 +- assets/layers/watermill/watermill.json | 8 +- 15 files changed, 282 insertions(+), 282 deletions(-) diff --git a/assets/layers/barrier/barrier.json b/assets/layers/barrier/barrier.json index 7c215f8f5..f06b8e237 100644 --- a/assets/layers/barrier/barrier.json +++ b/assets/layers/barrier/barrier.json @@ -85,7 +85,6 @@ ], "tagRenderings": [ { - "#": "bicycle=yes/no", "question": { "en": "Can a bicycle go past this barrier?", "nl": "Kan een fietser langs deze barrière?" @@ -105,10 +104,10 @@ "nl": "Een fietser kan hier niet langs." } } - ] + ], + "id": "bicycle=yes/no" }, { - "#": "Bollard type", "question": { "en": "What kind of bollard is this?", "nl": "Wat voor soort paal is dit?" @@ -150,10 +149,10 @@ "nl": "Verzonken poller" } } - ] + ], + "id": "Bollard type" }, { - "#": "Cycle barrier type", "question": { "en": "What kind of cycling barrier is this?", "nl": "Wat voor fietshekjes zijn dit?" @@ -188,10 +187,10 @@ "nl": "Knijppoort, ruimte is smaller aan de top, dan aan de bodem " } } - ] + ], + "id": "Cycle barrier type" }, { - "#": "MaxWidth", "render": { "en": "Maximum width: {maxwidth:physical} m", "nl": "Maximumbreedte: {maxwidth:physical} m" @@ -213,10 +212,10 @@ "20", "map" ] - } + }, + "id": "MaxWidth" }, { - "#": "Space between barrier (cyclebarrier)", "render": { "en": "Space between barriers (along the length of the road): {width:separation} m", "nl": "Ruimte tussen barrières (langs de lengte van de weg): {width:separation} m" @@ -238,10 +237,10 @@ "21", "map" ] - } + }, + "id": "Space between barrier (cyclebarrier)" }, { - "#": "Width of opening (cyclebarrier)", "render": { "en": "Width of opening: {width:opening} m", "nl": "Breedte van de opening: {width:opening} m" @@ -263,10 +262,10 @@ "21", "map" ] - } + }, + "id": "Width of opening (cyclebarrier)" }, { - "#": "Overlap (cyclebarrier)", "render": { "en": "Overlap: {overlap} m" }, @@ -287,7 +286,8 @@ "21", "map" ] - } + }, + "id": "Overlap (cyclebarrier)" } ] } \ No newline at end of file diff --git a/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json b/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json index 44c088518..f8aceeb7c 100644 --- a/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json +++ b/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json @@ -84,7 +84,6 @@ "tagRenderings": [ "images", { - "#": "Still in use?", "question": { "en": "Is this vending machine still operational?", "nl": "Is deze verkoopsautomaat nog steeds werkende?", @@ -154,7 +153,8 @@ "pt_BR": "Esta máquina de venda automática está fechada" } } - ] + ], + "id": "Still in use?" }, { "question": "How much does a bicycle tube cost?", diff --git a/assets/layers/bike_parking/bike_parking.json b/assets/layers/bike_parking/bike_parking.json index 7153b1532..049bcac9e 100644 --- a/assets/layers/bike_parking/bike_parking.json +++ b/assets/layers/bike_parking/bike_parking.json @@ -66,7 +66,6 @@ "tagRenderings": [ "images", { - "#": "Bicycle parking type", "question": { "en": "What is the type of this bicycle parking?", "nl": "Van welk type is deze fietsparking?", @@ -201,10 +200,10 @@ "zh_Hant": "樓層當中標示為單車停車場的區域" } } - ] + ], + "id": "Bicycle parking type" }, { - "#": "Underground?", "question": { "en": "What is the relative location of this bicycle parking?", "nl": "Wat is de relatieve locatie van deze parking??", @@ -281,10 +280,10 @@ "pt_BR": "Estacionamento no telhado" } } - ] + ], + "id": "Underground?" }, { - "#": "Is covered?", "question": { "en": "Is this parking covered? Also select \"covered\" for indoor parkings.", "nl": "Is deze parking overdekt? Selecteer ook \"overdekt\" voor fietsparkings binnen een gebouw.", @@ -333,10 +332,10 @@ "pt_BR": "Este estacionamento não é coberto" } } - ] + ], + "id": "Is covered?" }, { - "#": "Capacity", "question": { "en": "How many bicycles fit in this bicycle parking (including possible cargo bicycles)?", "fr": "Combien de vélos entrent dans ce parking à vélos (y compris les éventuels vélos de transport) ?", @@ -360,10 +359,10 @@ "freeform": { "key": "capacity", "type": "nat" - } + }, + "id": "Capacity" }, { - "#": "Access", "question": { "en": "Who can use this bicycle parking?", "nl": "Wie mag er deze fietsenstalling gebruiken?", @@ -427,10 +426,10 @@ "pt_BR": "Acesso é limitado aos membros de uma escola, companhia ou organização" } } - ] + ], + "id": "Access" }, { - "#": "Cargo bike spaces?", "question": { "en": "Does this bicycle parking have spots for cargo bikes?", "nl": "Heeft deze fietsparking plaats voor bakfietsen?", @@ -480,10 +479,10 @@ "pt_BR": "Você não tem permissão para estacionar bicicletas de carga" } } - ] + ], + "id": "Cargo bike spaces?" }, { - "#": "Cargo bike capacity?", "question": { "en": "How many cargo bicycles fit in this bicycle parking?", "nl": "Voor hoeveel bakfietsen heeft deze fietsparking plaats?", @@ -506,7 +505,8 @@ "freeform": { "key": "capacity:cargo_bike", "type": "nat" - } + }, + "id": "Cargo bike capacity?" } ] } \ No newline at end of file diff --git a/assets/layers/bike_repair_station/bike_repair_station.json b/assets/layers/bike_repair_station/bike_repair_station.json index 226d8436c..f082e3862 100644 --- a/assets/layers/bike_repair_station/bike_repair_station.json +++ b/assets/layers/bike_repair_station/bike_repair_station.json @@ -364,7 +364,6 @@ ] }, { - "#": "Operational status", "question": { "en": "Is the bike pump still operational?", "nl": "Werkt de fietspomp nog?", @@ -403,10 +402,10 @@ "pl": "Pompka rowerowa jest sprawna" } } - ] + ], + "id": "Operational status" }, { - "#": "Email maintainer", "condition": { "and": [ "email~*", @@ -416,7 +415,8 @@ "render": { "en": "Report this bicycle pump as broken", "nl": "Rapporteer deze fietspomp als kapot" - } + }, + "id": "Email maintainer" }, { "question": { diff --git a/assets/layers/cafe_pub/cafe_pub.json b/assets/layers/cafe_pub/cafe_pub.json index 59d661966..3c03eb21a 100644 --- a/assets/layers/cafe_pub/cafe_pub.json +++ b/assets/layers/cafe_pub/cafe_pub.json @@ -107,7 +107,6 @@ "tagRenderings": [ "images", { - "#": "Name", "question": { "nl": "Wat is de naam van dit café?", "en": "What is the name of this pub?" @@ -118,10 +117,10 @@ }, "freeform": { "key": "name" - } + }, + "id": "Name" }, { - "#": "Classification", "question": { "en": "What kind of cafe is this", "nl": "Welk soort café is dit?" @@ -158,7 +157,8 @@ }, "hideInAnswer": "_country!=de" } - ] + ], + "id": "Classification" }, "opening_hours", "website", diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json index c726b52dd..729a74fb3 100644 --- a/assets/layers/charging_station/charging_station.json +++ b/assets/layers/charging_station/charging_station.json @@ -43,7 +43,6 @@ "tagRenderings": [ "images", { - "#": "Type", "question": { "en": "Which vehicles are allowed to charge here?" }, @@ -90,10 +89,10 @@ "en": "Buses can be charged here" } } - ] + ], + "id": "Type" }, { - "#": "access", "question": { "en": "Who is allowed to use this charging station?" }, @@ -129,10 +128,10 @@ "if": "access=private", "then": "Not accessible to the general public (e.g. only accessible to the owners, employees, ...)" } - ] + ], + "id": "access" }, { - "#": "capacity", "render": { "en": "{capacity} vehicles can be charged here at the same time", "nl": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" @@ -144,10 +143,10 @@ "freeform": { "key": "capacity", "type": "pnat" - } + }, + "id": "capacity" }, { - "#": "Available_charging_stations (generated)", "question": { "en": "Which charging stations are available here?" }, @@ -448,10 +447,10 @@ }, "hideInAnswer": true } - ] + ], + "id": "Available_charging_stations (generated)" }, { - "#": "plugs-0", "question": { "en": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", "nl": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?" @@ -469,10 +468,10 @@ "socket:schuko~*", "socket:schuko!=0" ] - } + }, + "id": "plugs-0" }, { - "#": "voltage-0", "question": { "en": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", "nl": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) " @@ -499,10 +498,10 @@ "socket:schuko~*", "socket:schuko!=0" ] - } + }, + "id": "voltage-0" }, { - "#": "current-0", "question": { "en": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", "nl": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" @@ -529,10 +528,10 @@ "socket:schuko~*", "socket:schuko!=0" ] - } + }, + "id": "current-0" }, { - "#": "power-output-0", "question": { "en": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", "nl": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" @@ -559,10 +558,10 @@ "socket:schuko~*", "socket:schuko!=0" ] - } + }, + "id": "power-output-0" }, { - "#": "plugs-1", "question": { "en": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", "nl": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?" @@ -580,10 +579,10 @@ "socket:typee~*", "socket:typee!=0" ] - } + }, + "id": "plugs-1" }, { - "#": "voltage-1", "question": { "en": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", "nl": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) " @@ -610,10 +609,10 @@ "socket:typee~*", "socket:typee!=0" ] - } + }, + "id": "voltage-1" }, { - "#": "current-1", "question": { "en": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", "nl": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" @@ -640,10 +639,10 @@ "socket:typee~*", "socket:typee!=0" ] - } + }, + "id": "current-1" }, { - "#": "power-output-1", "question": { "en": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", "nl": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" @@ -677,10 +676,10 @@ "socket:typee~*", "socket:typee!=0" ] - } + }, + "id": "power-output-1" }, { - "#": "plugs-2", "question": { "en": "How much plugs of type Chademo are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -698,10 +697,10 @@ "socket:chademo~*", "socket:chademo!=0" ] - } + }, + "id": "plugs-2" }, { - "#": "voltage-2", "question": { "en": "What voltage do the plugs with Chademo offer?", "nl": "Welke spanning levert de stekker van type " @@ -728,10 +727,10 @@ "socket:chademo~*", "socket:chademo!=0" ] - } + }, + "id": "voltage-2" }, { - "#": "current-2", "question": { "en": "What current do the plugs with Chademo offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -758,10 +757,10 @@ "socket:chademo~*", "socket:chademo!=0" ] - } + }, + "id": "current-2" }, { - "#": "power-output-2", "question": { "en": "What power output does a single plug of type Chademo offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -788,10 +787,10 @@ "socket:chademo~*", "socket:chademo!=0" ] - } + }, + "id": "power-output-2" }, { - "#": "plugs-3", "question": { "en": "How much plugs of type Type 1 with cable (J1772) are available here?", "nl": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?" @@ -809,10 +808,10 @@ "socket:type1_cable~*", "socket:type1_cable!=0" ] - } + }, + "id": "plugs-3" }, { - "#": "voltage-3", "question": { "en": "What voltage do the plugs with Type 1 with cable (J1772) offer?", "nl": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) " @@ -846,10 +845,10 @@ "socket:type1_cable~*", "socket:type1_cable!=0" ] - } + }, + "id": "voltage-3" }, { - "#": "current-3", "question": { "en": "What current do the plugs with Type 1 with cable (J1772) offer?", "nl": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?" @@ -876,10 +875,10 @@ "socket:type1_cable~*", "socket:type1_cable!=0" ] - } + }, + "id": "current-3" }, { - "#": "power-output-3", "question": { "en": "What power output does a single plug of type Type 1 with cable (J1772) offer?", "nl": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?" @@ -913,10 +912,10 @@ "socket:type1_cable~*", "socket:type1_cable!=0" ] - } + }, + "id": "power-output-3" }, { - "#": "plugs-4", "question": { "en": "How much plugs of type Type 1 without cable (J1772) are available here?", "nl": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?" @@ -934,10 +933,10 @@ "socket:type1~*", "socket:type1!=0" ] - } + }, + "id": "plugs-4" }, { - "#": "voltage-4", "question": { "en": "What voltage do the plugs with Type 1 without cable (J1772) offer?", "nl": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) " @@ -971,10 +970,10 @@ "socket:type1~*", "socket:type1!=0" ] - } + }, + "id": "voltage-4" }, { - "#": "current-4", "question": { "en": "What current do the plugs with Type 1 without cable (J1772) offer?", "nl": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?" @@ -1001,10 +1000,10 @@ "socket:type1~*", "socket:type1!=0" ] - } + }, + "id": "current-4" }, { - "#": "power-output-4", "question": { "en": "What power output does a single plug of type Type 1 without cable (J1772) offer?", "nl": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?" @@ -1052,10 +1051,10 @@ "socket:type1~*", "socket:type1!=0" ] - } + }, + "id": "power-output-4" }, { - "#": "plugs-5", "question": { "en": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1073,10 +1072,10 @@ "socket:type1_combo~*", "socket:type1_combo!=0" ] - } + }, + "id": "plugs-5" }, { - "#": "voltage-5", "question": { "en": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", "nl": "Welke spanning levert de stekker van type " @@ -1110,10 +1109,10 @@ "socket:type1_combo~*", "socket:type1_combo!=0" ] - } + }, + "id": "voltage-5" }, { - "#": "current-5", "question": { "en": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1147,10 +1146,10 @@ "socket:type1_combo~*", "socket:type1_combo!=0" ] - } + }, + "id": "current-5" }, { - "#": "power-output-5", "question": { "en": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1198,10 +1197,10 @@ "socket:type1_combo~*", "socket:type1_combo!=0" ] - } + }, + "id": "power-output-5" }, { - "#": "plugs-6", "question": { "en": "How much plugs of type Tesla Supercharger are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1219,10 +1218,10 @@ "socket:tesla_supercharger~*", "socket:tesla_supercharger!=0" ] - } + }, + "id": "plugs-6" }, { - "#": "voltage-6", "question": { "en": "What voltage do the plugs with Tesla Supercharger offer?", "nl": "Welke spanning levert de stekker van type " @@ -1249,10 +1248,10 @@ "socket:tesla_supercharger~*", "socket:tesla_supercharger!=0" ] - } + }, + "id": "voltage-6" }, { - "#": "current-6", "question": { "en": "What current do the plugs with Tesla Supercharger offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1286,10 +1285,10 @@ "socket:tesla_supercharger~*", "socket:tesla_supercharger!=0" ] - } + }, + "id": "current-6" }, { - "#": "power-output-6", "question": { "en": "What power output does a single plug of type Tesla Supercharger offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1330,10 +1329,10 @@ "socket:tesla_supercharger~*", "socket:tesla_supercharger!=0" ] - } + }, + "id": "power-output-6" }, { - "#": "plugs-7", "question": { "en": "How much plugs of type Type 2 (mennekes) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1351,10 +1350,10 @@ "socket:type2~*", "socket:type2!=0" ] - } + }, + "id": "plugs-7" }, { - "#": "voltage-7", "question": { "en": "What voltage do the plugs with Type 2 (mennekes) offer?", "nl": "Welke spanning levert de stekker van type " @@ -1388,10 +1387,10 @@ "socket:type2~*", "socket:type2!=0" ] - } + }, + "id": "voltage-7" }, { - "#": "current-7", "question": { "en": "What current do the plugs with Type 2 (mennekes) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1425,10 +1424,10 @@ "socket:type2~*", "socket:type2!=0" ] - } + }, + "id": "current-7" }, { - "#": "power-output-7", "question": { "en": "What power output does a single plug of type Type 2 (mennekes) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1462,10 +1461,10 @@ "socket:type2~*", "socket:type2!=0" ] - } + }, + "id": "power-output-7" }, { - "#": "plugs-8", "question": { "en": "How much plugs of type Type 2 CCS (mennekes) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1483,10 +1482,10 @@ "socket:type2_combo~*", "socket:type2_combo!=0" ] - } + }, + "id": "plugs-8" }, { - "#": "voltage-8", "question": { "en": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", "nl": "Welke spanning levert de stekker van type " @@ -1520,10 +1519,10 @@ "socket:type2_combo~*", "socket:type2_combo!=0" ] - } + }, + "id": "voltage-8" }, { - "#": "current-8", "question": { "en": "What current do the plugs with Type 2 CCS (mennekes) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1557,10 +1556,10 @@ "socket:type2_combo~*", "socket:type2_combo!=0" ] - } + }, + "id": "current-8" }, { - "#": "power-output-8", "question": { "en": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1587,10 +1586,10 @@ "socket:type2_combo~*", "socket:type2_combo!=0" ] - } + }, + "id": "power-output-8" }, { - "#": "plugs-9", "question": { "en": "How much plugs of type Type 2 with cable (mennekes) are available here?", "nl": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?" @@ -1608,10 +1607,10 @@ "socket:type2_cable~*", "socket:type2_cable!=0" ] - } + }, + "id": "plugs-9" }, { - "#": "voltage-9", "question": { "en": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", "nl": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) " @@ -1645,10 +1644,10 @@ "socket:type2_cable~*", "socket:type2_cable!=0" ] - } + }, + "id": "voltage-9" }, { - "#": "current-9", "question": { "en": "What current do the plugs with Type 2 with cable (mennekes) offer?", "nl": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?" @@ -1682,10 +1681,10 @@ "socket:type2_cable~*", "socket:type2_cable!=0" ] - } + }, + "id": "current-9" }, { - "#": "power-output-9", "question": { "en": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", "nl": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?" @@ -1719,10 +1718,10 @@ "socket:type2_cable~*", "socket:type2_cable!=0" ] - } + }, + "id": "power-output-9" }, { - "#": "plugs-10", "question": { "en": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1740,10 +1739,10 @@ "socket:tesla_supercharger_ccs~*", "socket:tesla_supercharger_ccs!=0" ] - } + }, + "id": "plugs-10" }, { - "#": "voltage-10", "question": { "en": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", "nl": "Welke spanning levert de stekker van type " @@ -1777,10 +1776,10 @@ "socket:tesla_supercharger_ccs~*", "socket:tesla_supercharger_ccs!=0" ] - } + }, + "id": "voltage-10" }, { - "#": "current-10", "question": { "en": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1814,10 +1813,10 @@ "socket:tesla_supercharger_ccs~*", "socket:tesla_supercharger_ccs!=0" ] - } + }, + "id": "current-10" }, { - "#": "power-output-10", "question": { "en": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1844,10 +1843,10 @@ "socket:tesla_supercharger_ccs~*", "socket:tesla_supercharger_ccs!=0" ] - } + }, + "id": "power-output-10" }, { - "#": "plugs-11", "question": { "en": "How much plugs of type Tesla Supercharger (destination) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1865,10 +1864,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - } + }, + "id": "plugs-11" }, { - "#": "voltage-11", "question": { "en": "What voltage do the plugs with Tesla Supercharger (destination) offer?", "nl": "Welke spanning levert de stekker van type " @@ -1895,10 +1894,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - } + }, + "id": "voltage-11" }, { - "#": "current-11", "question": { "en": "What current do the plugs with Tesla Supercharger (destination) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1932,10 +1931,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - } + }, + "id": "current-11" }, { - "#": "power-output-11", "question": { "en": "What power output does a single plug of type Tesla Supercharger (destination) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1976,10 +1975,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - } + }, + "id": "power-output-11" }, { - "#": "plugs-12", "question": { "en": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1997,10 +1996,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - } + }, + "id": "plugs-12" }, { - "#": "voltage-12", "question": { "en": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", "nl": "Welke spanning levert de stekker van type " @@ -2034,10 +2033,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - } + }, + "id": "voltage-12" }, { - "#": "current-12", "question": { "en": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -2071,10 +2070,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - } + }, + "id": "current-12" }, { - "#": "power-output-12", "question": { "en": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -2108,10 +2107,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - } + }, + "id": "power-output-12" }, { - "#": "Authentication", "question": { "en": "What kind of authentication is available at the charging station?", "it": "Quali sono gli orari di apertura di questa stazione di ricarica?", @@ -2178,10 +2177,10 @@ "en": "No authentication is needed" } } - ] + ], + "id": "Authentication" }, { - "#": "Auth phone", "render": { "en": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}", "it": "{network}", @@ -2226,10 +2225,10 @@ "0": { "then": "不屬於大型網路" } - } + }, + "id": "Auth phone" }, { - "#": "OH", "render": "{opening_hours_table(opening_hours)}", "freeform": { "key": "opening_hours", @@ -2245,10 +2244,10 @@ "en": "24/7 opened (including holidays)" } } - ] + ], + "id": "OH" }, { - "#": "fee/charge", "question": { "en": "How much does one have to pay to use this charging station?", "nl": "Hoeveel kost het gebruik van dit oplaadpunt?" @@ -2276,10 +2275,10 @@ "en": "Free to use" } } - ] + ], + "id": "fee/charge" }, { - "#": "payment-options", "builtin": "payment-options", "override": { "condition": { @@ -2308,10 +2307,10 @@ } } ] - } + }, + "id": "payment-options" }, { - "#": "maxstay", "question": { "en": "What is the maximum amount of time one is allowed to stay here?", "nl": "Hoelang mag een voertuig hier blijven staan?" @@ -2331,10 +2330,10 @@ "nl": "Geen maximum parkeertijd" } } - ] + ], + "id": "maxstay" }, { - "#": "Network", "render": { "en": "Part of the network {network}" }, @@ -2370,10 +2369,10 @@ "if": "network=eVgo", "then": "eVgo" } - ] + ], + "id": "Network" }, { - "#": "Operator", "question": "Who is the operator of this charging station?", "render": "This charging station is operated by {operator}", "freeform": { @@ -2392,10 +2391,10 @@ ], "hideInAnswer": "operator=" } - ] + ], + "id": "Operator" }, { - "#": "phone", "question": { "en": "What number can one call if there is a problem with this charging station?" }, @@ -2405,10 +2404,10 @@ "freeform": { "key": "phone", "type": "phone" - } + }, + "id": "phone" }, { - "#": "email", "question": { "en": "What is the email address of the operator?" }, @@ -2418,10 +2417,10 @@ "freeform": { "key": "email", "type": "email" - } + }, + "id": "email" }, { - "#": "website", "question": { "en": "What is the website of the operator?" }, @@ -2431,21 +2430,21 @@ "freeform": { "key": "website", "type": "url" - } + }, + "id": "website" }, "level", { - "#": "ref", "question": { "en": "What is the reference number of this charging station?" }, "render": "Reference number is {ref}", "freeform": { "key": "ref" - } + }, + "id": "ref" }, { - "#": "Operational status", "question": { "en": "Is this charging point in use?", "nl": "Is dit oplaadpunt operationeel?" @@ -2501,10 +2500,10 @@ "nl": "Dit oplaadpunt werkt" } } - ] + ], + "id": "Operational status" }, { - "#": "Parking:fee", "question": { "en": "Does one have to pay a parking fee while charging?" }, @@ -2521,7 +2520,8 @@ "en": "An additional parking fee should be paid while charging" } } - ] + ], + "id": "Parking:fee" } ], "icon": { diff --git a/assets/layers/cycleways_and_roads/cycleways_and_roads.json b/assets/layers/cycleways_and_roads/cycleways_and_roads.json index a53d7e9f5..491a232db 100644 --- a/assets/layers/cycleways_and_roads/cycleways_and_roads.json +++ b/assets/layers/cycleways_and_roads/cycleways_and_roads.json @@ -81,7 +81,6 @@ "description": {}, "tagRenderings": [ { - "#": "Cycleway type for a road", "question": { "en": "What kind of cycleway is here?", "nl": "Wat voor fietspad is hier?" @@ -141,10 +140,10 @@ "fixme=Changed from cycleway=opposite" ] } - ] + ], + "id": "Cycleway type for a road" }, { - "#": "is lit?", "question": { "en": "Is this street lit?", "nl": "Is deze weg verlicht?" @@ -179,10 +178,10 @@ "nl": "Deze weg is 24/7 verlicht" } } - ] + ], + "id": "is lit?" }, { - "#": "Is this a cyclestreet? (For a road)", "question": { "en": "Is this a cyclestreet?", "nl": "Is dit een fietsstraat?" @@ -224,10 +223,10 @@ "overtaking:motor_vehicle=" ] } - ] + ], + "id": "Is this a cyclestreet? (For a road)" }, { - "#": "Maxspeed (for road)", "render": { "en": "The maximum speed on this road is {maxspeed} km/h", "nl": "De maximumsnelheid op deze weg is {maxspeed} km/u" @@ -282,10 +281,10 @@ "question": { "en": "What is the maximum speed in this street?", "nl": "Wat is de maximumsnelheid in deze straat?" - } + }, + "id": "Maxspeed (for road)" }, { - "#": "Cycleway:surface", "render": { "en": "This cyleway is made of {cycleway:surface}", "nl": "Dit fietspad is gemaakt van {cycleway:surface}" @@ -399,10 +398,10 @@ "question": { "en": "What is the surface of the cycleway made from?", "nl": "Waaruit is het oppervlak van het fietspad van gemaakt?" - } + }, + "id": "Cycleway:surface" }, { - "#": "Cycleway:smoothness", "question": { "en": "What is the smoothness of this cycleway?", "nl": "Wat is de kwaliteit van dit fietspad?" @@ -471,10 +470,10 @@ "nl": "Niet geschikt voor voertuigen met wielen" } } - ] + ], + "id": "Cycleway:smoothness" }, { - "#": "Surface of the road", "render": { "en": "This road is made of {surface}", "nl": "Deze weg is gemaakt van {surface}" @@ -581,10 +580,10 @@ "question": { "en": "What is the surface of the street made from?", "nl": "Waaruit is het oppervlak van de straat gemaakt?" - } + }, + "id": "Surface of the road" }, { - "#": "Surface of the street", "question": { "en": "What is the smoothness of this street?", "nl": "Wat is de kwaliteit van deze straat?" @@ -644,10 +643,10 @@ "en": "Impassable / No wheeled vehicle" } } - ] + ], + "id": "Surface of the street" }, { - "#": "width:carriageway", "condition": { "and": [ "highway!=cycleway", @@ -669,7 +668,8 @@ "question": { "en": "What is the carriage width of this road (in meters)?", "nl": "Hoe breed is de rijbaan in deze straat (in meters)?" - } + }, + "id": "width:carriageway" }, { "question": { diff --git a/assets/layers/drinking_water/drinking_water.json b/assets/layers/drinking_water/drinking_water.json index 67f61d5ff..b5aac2c01 100644 --- a/assets/layers/drinking_water/drinking_water.json +++ b/assets/layers/drinking_water/drinking_water.json @@ -74,7 +74,6 @@ "tagRenderings": [ "images", { - "#": "Still in use?", "question": { "en": "Is this drinking water spot still operational?", "nl": "Is deze drinkwaterkraan nog steeds werkende?", @@ -120,10 +119,10 @@ "fr": "Cette fontaine est fermée" } } - ] + ], + "id": "Still in use?" }, { - "#": "Bottle refill", "question": { "en": "How easy is it to fill water bottles?", "nl": "Hoe gemakkelijk is het om drinkbussen bij te vullen?", @@ -152,7 +151,8 @@ "fr": "Les bouteilles d'eau peuvent ne pas passer" } } - ] + ], + "id": "Bottle refill" }, { "render": { diff --git a/assets/layers/food/food.json b/assets/layers/food/food.json index a63c06cbc..c606db4b3 100644 --- a/assets/layers/food/food.json +++ b/assets/layers/food/food.json @@ -142,7 +142,6 @@ "tagRenderings": [ "images", { - "#": "Name", "question": { "nl": "Wat is de naam van deze eetgelegenheid?", "en": "What is the name of this restaurant?" @@ -153,10 +152,10 @@ }, "freeform": { "key": "name" - } + }, + "id": "Name" }, { - "#": "Fastfood vs restaurant", "question": { "en": "What type of business is this?", "nl": "Wat voor soort zaak is dit?" @@ -174,7 +173,8 @@ "nl": "Dit is een restaurant. De focus ligt op een aangename ervaring waar je aan tafel wordt bediend" } } - ] + ], + "id": "Fastfood vs restaurant" }, "opening_hours", "website", @@ -183,7 +183,6 @@ "payment-options", "wheelchair-access", { - "#": "Cuisine", "question": { "nl": "Welk soort gerechten worden hier geserveerd?", "en": "Which food is served here?" @@ -292,10 +291,10 @@ "nl": "Dit is een Thaïs restaurant" } } - ] + ], + "id": "Cuisine" }, { - "#": "Takeaway", "question": { "nl": "Biedt deze zaak een afhaalmogelijkheid aan?", "en": "Does this place offer takea-way?" @@ -322,10 +321,10 @@ "nl": "Hier is geen afhaalmogelijkheid" } } - ] + ], + "id": "Takeaway" }, { - "#": "Vegetarian (no friture)", "question": { "nl": "Heeft deze eetgelegenheid een vegetarische optie?", "en": "Does this restaurant have a vegetarian option?" @@ -356,10 +355,10 @@ } } ], - "condition": "cuisine!=friture" + "condition": "cuisine!=friture", + "id": "Vegetarian (no friture)" }, { - "#": "Vegan (no friture)", "question": { "nl": "Heeft deze eetgelegenheid een veganistische optie?" }, @@ -389,10 +388,10 @@ } } ], - "condition": "cuisine!=friture" + "condition": "cuisine!=friture", + "id": "Vegan (no friture)" }, { - "#": "halal (no friture)", "question": { "en": "Does this restaurant offer a halal menu?", "nl": "Heeft dit restaurant halal opties?" @@ -427,7 +426,8 @@ } } ], - "condition": "cuisine!=friture" + "condition": "cuisine!=friture", + "id": "halal (no friture)" }, { "question": { diff --git a/assets/layers/nature_reserve/nature_reserve.json b/assets/layers/nature_reserve/nature_reserve.json index 2f217743d..5a3551d52 100644 --- a/assets/layers/nature_reserve/nature_reserve.json +++ b/assets/layers/nature_reserve/nature_reserve.json @@ -54,7 +54,6 @@ "tagRenderings": [ "images", { - "#": "Access tag", "render": { "nl": "De toegankelijkheid van dit gebied is: {access:description}" }, @@ -131,10 +130,10 @@ "nl": "Toegankelijk mits betaling" } } - ] + ], + "id": "Access tag" }, { - "#": "Operator tag", "render": { "nl": "Beheer door {operator}" }, @@ -176,10 +175,10 @@ "nl": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" } } - ] + ], + "id": "Operator tag" }, { - "#": "Name:nl-tag", "render": { "nl": "Dit gebied heet {name:nl}" }, @@ -193,10 +192,10 @@ "and": [ "name:nl~*" ] - } + }, + "id": "Name:nl-tag" }, { - "#": "Name tag", "render": { "nl": "Dit gebied heet {name}" }, @@ -226,10 +225,10 @@ "nl": "Dit gebied heeft geen naam" } } - ] + ], + "id": "Name tag" }, { - "#": "Dogs?", "question": { "nl": "Zijn honden toegelaten in dit gebied?", "en": "Are dogs allowed in this nature reserve?", @@ -275,10 +274,10 @@ "de": "Hunde dürfen frei herumlaufen" } } - ] + ], + "id": "Dogs?" }, { - "#": "Website", "question": { "en": "On which webpage can one find more information about this nature reserve?", "nl": "Op welke webpagina kan men meer informatie vinden over dit natuurgebied?", @@ -290,10 +289,10 @@ "freeform": { "key": "website", "type": "url" - } + }, + "id": "Website" }, { - "#": "Curator", "question": { "nl": "Wie is de conservator van dit gebied?
Respecteer privacy - geef deze naam enkel als die duidelijk is gepubliceerd", "en": "Whom is the curator of this nature reserve?
Respect privacy - only fill out a name if this is widely published", @@ -309,10 +308,10 @@ "freeform": { "key": "curator", "type": "string" - } + }, + "id": "Curator" }, { - "#": "Email", "question": { "nl": "Waar kan men naartoe emailen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke emailadressen als deze elders zijn gepubliceerd", "en": "What email adress can one send to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal email address if this is widely published", @@ -332,10 +331,10 @@ "freeform": { "key": "email", "type": "email" - } + }, + "id": "Email" }, { - "#": "phone", "question": { "nl": "Waar kan men naartoe bellen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke telefoonnummers als deze elders zijn gepubliceerd", "en": "What phone number can one call to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal phone number address if this is widely published", @@ -355,29 +354,29 @@ "freeform": { "key": "phone", "type": "phone" - } + }, + "id": "phone" }, { - "#": "Non-editable description {description}", "render": { "nl": "Extra info: {description}" }, "freeform": { "key": "description" - } + }, + "id": "Non-editable description {description}" }, { - "#": "Editable description {description:0}", "question": "Is er extra info die je kwijt wil?", "render": { "nl": "Extra info: {description:0}" }, "freeform": { "key": "description:0" - } + }, + "id": "Editable description {description:0}" }, { - "#": "Surface area", "render": { "en": "Surface area: {_surface:ha}Ha", "nl": "Totale oppervlakte: {_surface:ha}Ha", @@ -391,7 +390,8 @@ "*": "" } } - ] + ], + "id": "Surface area" } ], "wayHandling": 2, diff --git a/assets/layers/observation_tower/observation_tower.json b/assets/layers/observation_tower/observation_tower.json index 3a13b9776..fa9a00262 100644 --- a/assets/layers/observation_tower/observation_tower.json +++ b/assets/layers/observation_tower/observation_tower.json @@ -27,7 +27,6 @@ "tagRenderings": [ "images", { - "#": "name", "question": { "en": "What is the name of this tower?", "nl": "Heeft deze toren een naam?" @@ -47,10 +46,10 @@ "nl": "Deze toren heeft geen specifieke naam" } } - ] + ], + "id": "name" }, { - "#": "Height", "question": { "en": "What is the height of this tower?", "nl": "Hoe hoog is deze toren?" @@ -62,10 +61,10 @@ "freeform": { "key": "height", "type": "pfloat" - } + }, + "id": "Height" }, { - "#": "Operator", "question": { "en": "Who maintains this tower?", "nl": "Wie onderhoudt deze toren?" @@ -76,11 +75,11 @@ }, "freeform": { "key": "operator" - } + }, + "id": "Operator" }, "website", { - "#": "Fee", "question": { "en": "How much does one have to pay to enter this tower?", "nl": "Hoeveel moet men betalen om deze toren te bezoeken?" @@ -108,10 +107,10 @@ "nl": "Gratis te bezoeken" } } - ] + ], + "id": "Fee" }, { - "#": "Payment methods", "builtin": "payment-options", "override": { "condition": { @@ -120,7 +119,8 @@ "charge~*" ] } - } + }, + "id": "Payment methods" }, "wheelchair-access" ], diff --git a/assets/layers/parking/parking.json b/assets/layers/parking/parking.json index a17bd5987..1646d143e 100644 --- a/assets/layers/parking/parking.json +++ b/assets/layers/parking/parking.json @@ -51,7 +51,6 @@ "tagRenderings": [ "images", { - "#": "Access tag", "render": { "nl": "De toegankelijkheid van dit gebied is: {access:description}" }, @@ -128,10 +127,10 @@ "nl": "Toegankelijk mits betaling" } } - ] + ], + "id": "Access tag" }, { - "#": "Operator tag", "render": { "nl": "Beheer door {operator}" }, @@ -163,7 +162,8 @@ }, "hideInAnswer": true } - ] + ], + "id": "Operator tag" } ], "wayHandling": 1, diff --git a/assets/layers/surveillance_camera/surveillance_camera.json b/assets/layers/surveillance_camera/surveillance_camera.json index 40bed359f..7472ffd80 100644 --- a/assets/layers/surveillance_camera/surveillance_camera.json +++ b/assets/layers/surveillance_camera/surveillance_camera.json @@ -34,7 +34,6 @@ "tagRenderings": [ "images", { - "#": "Camera type: fixed; panning; dome", "question": { "en": "What kind of camera is this?", "nl": "Wat voor soort camera is dit?", @@ -84,10 +83,10 @@ "it": "Una videocamera panoramica" } } - ] + ], + "id": "Camera type: fixed; panning; dome" }, { - "#": "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view", "question": { "en": "In which geographical direction does this camera film?", "nl": "In welke geografische richting filmt deze camera?", @@ -133,10 +132,10 @@ }, "hideInAnswer": true } - ] + ], + "id": "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view" }, { - "#": "Operator", "freeform": { "key": "operator" }, @@ -151,10 +150,10 @@ "nl": "Beheer door {operator}", "fr": "Exploité par {operator}", "it": "È gestita da {operator}" - } + }, + "id": "Operator" }, { - "#": "Surveillance type: public, outdoor, indoor", "question": { "en": "What kind of surveillance is this camera", "nl": "Wat soort bewaking wordt hier uitgevoerd?", @@ -201,10 +200,10 @@ "it": "Sorveglia un ambiente interno di proprietà privata, per esempio un negozio, un parcheggio sotterraneo privato, ..." } } - ] + ], + "id": "Surveillance type: public, outdoor, indoor" }, { - "#": "Indoor camera? This isn't clear for 'public'-cameras", "question": { "en": "Is the public space surveilled by this camera an indoor or outdoor space?", "nl": "Bevindt de bewaakte publieke ruimte camera zich binnen of buiten?", @@ -247,10 +246,10 @@ }, "hideInAnswer": true } - ] + ], + "id": "Indoor camera? This isn't clear for 'public'-cameras" }, { - "#": "Level", "question": { "en": "On which level is this camera located?", "nl": "Op welke verdieping bevindt deze camera zich?", @@ -272,10 +271,10 @@ "indoor=yes", "surveillance:type=ye" ] - } + }, + "id": "Level" }, { - "#": "Surveillance:zone", "question": { "en": "What exactly is surveilled here?", "nl": "Wat wordt hier precies bewaakt?", @@ -370,10 +369,10 @@ "it": "Sorveglia un negozio" } } - ] + ], + "id": "Surveillance:zone" }, { - "#": "camera:mount", "question": { "en": "How is this camera placed?", "nl": "Hoe is deze camera geplaatst?", @@ -418,7 +417,8 @@ "it": "Questa telecamera è posizionata sul soffitto" } } - ] + ], + "id": "camera:mount" } ], "icon": { diff --git a/assets/layers/trail/trail.json b/assets/layers/trail/trail.json index c2c43c48b..4ad355a93 100644 --- a/assets/layers/trail/trail.json +++ b/assets/layers/trail/trail.json @@ -39,7 +39,6 @@ } }, { - "#": "Name", "question": { "nl": "Wat is de naam van deze wandeling?" }, @@ -48,10 +47,10 @@ }, "freeform": { "key": "name" - } + }, + "id": "Name" }, { - "#": "Operator tag", "render": { "nl": "Beheer door {operator}" }, @@ -83,10 +82,10 @@ }, "hideInAnswer": true } - ] + ], + "id": "Operator tag" }, { - "#": "Color", "question": { "nl": "Welke kleur heeft deze wandeling?" }, @@ -126,10 +125,10 @@ "en": "Yellow trail" } } - ] + ], + "id": "Color" }, { - "#": "Wheelchair access", "question": { "nl": "Is deze wandeling toegankelijk met de rolstoel?" }, @@ -146,10 +145,10 @@ }, "if": "wheelchair=no" } - ] + ], + "id": "Wheelchair access" }, { - "#": "pushchair access", "question": { "nl": "Is deze wandeltocht toegankelijk met de buggy?" }, @@ -166,7 +165,8 @@ }, "if": "pushchair=no" } - ] + ], + "id": "pushchair access" } ], "icon": { diff --git a/assets/layers/watermill/watermill.json b/assets/layers/watermill/watermill.json index 8fca7a9d6..1908dc8a0 100644 --- a/assets/layers/watermill/watermill.json +++ b/assets/layers/watermill/watermill.json @@ -45,7 +45,6 @@ "tagRenderings": [ "images", { - "#": "Access tag", "render": { "nl": "De toegankelijkheid van dit gebied is: {access:description}" }, @@ -122,10 +121,10 @@ "nl": "Toegankelijk mits betaling" } } - ] + ], + "id": "Access tag" }, { - "#": "Operator tag", "render": { "nl": "Beheer door {operator}" }, @@ -157,7 +156,8 @@ }, "hideInAnswer": true } - ] + ], + "id": "Operator tag" } ], "wayHandling": 1, From 4cb09ba8e70775a67390bfbce2ef654ffd1ef2f6 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 18:06:38 +0200 Subject: [PATCH 15/65] Drop widths theme --- Logic/SimpleMetaTagger.ts | 111 ------------- assets/themes/widths/icon.svg | 5 - assets/themes/widths/license_info.json | 8 - assets/themes/widths/width.json | 217 ------------------------- 4 files changed, 341 deletions(-) delete mode 100644 assets/themes/widths/icon.svg delete mode 100644 assets/themes/widths/license_info.json delete mode 100644 assets/themes/widths/width.json diff --git a/Logic/SimpleMetaTagger.ts b/Logic/SimpleMetaTagger.ts index 27f4225b9..0f8170a4e 100644 --- a/Logic/SimpleMetaTagger.ts +++ b/Logic/SimpleMetaTagger.ts @@ -251,116 +251,6 @@ export default class SimpleMetaTagger { }) ) - private static carriageWayWidth = new SimpleMetaTagger( - { - keys: ["_width:needed", "_width:needed:no_pedestrians", "_width:difference"], - doc: "Legacy for a specific project calculating the needed width for safe traffic on a road. Only activated if 'width:carriageway' is present" - }, - feature => { - - const properties = feature.properties; - if (properties["width:carriageway"] === undefined) { - return; - } - - const carWidth = 2; - const cyclistWidth = 1.5; - const pedestrianWidth = 0.75; - - - const _leftSideParking = - new And([new Tag("parking:lane:left", "parallel"), new Tag("parking:lane:right", "no_parking")]); - const _rightSideParking = - new And([new Tag("parking:lane:right", "parallel"), new Tag("parking:lane:left", "no_parking")]); - - const _bothSideParking = new Tag("parking:lane:both", "parallel"); - const _noSideParking = new Tag("parking:lane:both", "no_parking"); - const _otherParkingMode = - new Or([ - new Tag("parking:lane:both", "perpendicular"), - new Tag("parking:lane:left", "perpendicular"), - new Tag("parking:lane:right", "perpendicular"), - new Tag("parking:lane:both", "diagonal"), - new Tag("parking:lane:left", "diagonal"), - new Tag("parking:lane:right", "diagonal"), - ]) - - const _sidewalkBoth = new Tag("sidewalk", "both"); - const _sidewalkLeft = new Tag("sidewalk", "left"); - const _sidewalkRight = new Tag("sidewalk", "right"); - const _sidewalkNone = new Tag("sidewalk", "none"); - - - let parallelParkingCount = 0; - - - const _oneSideParking = new Or([_leftSideParking, _rightSideParking]); - - if (_oneSideParking.matchesProperties(properties)) { - parallelParkingCount = 1; - } else if (_bothSideParking.matchesProperties(properties)) { - parallelParkingCount = 2; - } else if (_noSideParking.matchesProperties(properties)) { - parallelParkingCount = 0; - } else if (_otherParkingMode.matchesProperties(properties)) { - parallelParkingCount = 0; - } else { - console.log("No parking data for ", properties.name, properties.id) - } - - - let pedestrianFlowNeeded; - if (_sidewalkBoth.matchesProperties(properties)) { - pedestrianFlowNeeded = 0; - } else if (_sidewalkNone.matchesProperties(properties)) { - pedestrianFlowNeeded = 2; - } else if (_sidewalkLeft.matchesProperties(properties) || _sidewalkRight.matchesProperties(properties)) { - pedestrianFlowNeeded = 1; - } else { - pedestrianFlowNeeded = -1; - } - - - let onewayCar = properties.oneway === "yes"; - let onewayBike = properties["oneway:bicycle"] === "yes" || - (onewayCar && properties["oneway:bicycle"] === undefined) - - let cyclingAllowed = - !(properties.bicycle === "use_sidepath" - || properties.bicycle === "no"); - - let carWidthUsed = (onewayCar ? 1 : 2) * carWidth; - properties["_width:needed:cars"] = Utils.Round(carWidthUsed); - properties["_width:needed:parking"] = Utils.Round(parallelParkingCount * carWidth) - - - let cyclistWidthUsed = 0; - if (cyclingAllowed) { - cyclistWidthUsed = (onewayBike ? 1 : 2) * cyclistWidth; - } - properties["_width:needed:cyclists"] = Utils.Round(cyclistWidthUsed) - - - const width = parseFloat(properties["width:carriageway"]); - - - const targetWidthIgnoringPedestrians = - carWidthUsed + - cyclistWidthUsed + - parallelParkingCount * carWidthUsed; - properties["_width:needed:no_pedestrians"] = Utils.Round(targetWidthIgnoringPedestrians); - - const pedestriansNeed = Math.max(0, pedestrianFlowNeeded) * pedestrianWidth; - const targetWidth = targetWidthIgnoringPedestrians + pedestriansNeed; - properties["_width:needed"] = Utils.Round(targetWidth); - properties["_width:needed:pedestrians"] = Utils.Round(pedestriansNeed) - - - properties["_width:difference"] = Utils.Round(targetWidth - width); - properties["_width:difference:no_pedestrians"] = Utils.Round(targetWidthIgnoringPedestrians - width); - - } - ); private static currentTime = new SimpleMetaTagger( { keys: ["_now:date", "_now:datetime", "_loaded:date", "_loaded:_datetime"], @@ -396,7 +286,6 @@ export default class SimpleMetaTagger { SimpleMetaTagger.canonicalize, SimpleMetaTagger.country, SimpleMetaTagger.isOpen, - SimpleMetaTagger.carriageWayWidth, SimpleMetaTagger.directionSimplified, SimpleMetaTagger.currentTime, SimpleMetaTagger.objectMetaInfo diff --git a/assets/themes/widths/icon.svg b/assets/themes/widths/icon.svg deleted file mode 100644 index 6a0bda749..000000000 --- a/assets/themes/widths/icon.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/assets/themes/widths/license_info.json b/assets/themes/widths/license_info.json deleted file mode 100644 index 20cd90555..000000000 --- a/assets/themes/widths/license_info.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "path": "icon.svg", - "license": "CC0; trivial", - "authors": [], - "sources": [] - } -] \ No newline at end of file diff --git a/assets/themes/widths/width.json b/assets/themes/widths/width.json deleted file mode 100644 index 5ee75eb7e..000000000 --- a/assets/themes/widths/width.json +++ /dev/null @@ -1,217 +0,0 @@ -{ - "id": "width", - "title": { - "nl": "Straatbreedtes" - }, - "shortDescription": { - "nl": "Is de straat breed genoeg?" - }, - "description": { - "nl": "

De straat is opgebruikt

\n

Er is steeds meer druk op de openbare ruimte. Voetgangers, fietsers, steps, auto's, bussen, bestelwagens, buggies, cargobikes, ... willen allemaal hun deel van de openbare ruimte.

\n

In deze studie nemen we Brugge onder de loep en kijken we hoe breed elke straat is én hoe breed elke straat zou moeten zijn voor een veilig én vlot verkeer.

\n

Legende

\n     Straat te smal voor veilig verkeer
\n     Straat is breed genoeg veilig verkeer
\n     Straat zonder voetpad, te smal als ook voetgangers plaats krijgen
\n     Woonerf, autoluw, autoloos of enkel plaatselijk verkeer
\n
\n
\n Een gestippelde lijn is een straat waar ook voor fietsers éénrichtingsverkeer geldt.
\n Klik op een straat om meer informatie te zien.\n

Hoe gaan we verder?

\n Verschillende ingrepen kunnen de stad teruggeven aan de inwoners en de stad leefbaarder en levendiger maken.
\n Denk aan:\n
    \n
  • De autovrije zone's uitbreiden
  • \n
  • De binnenstad fietszone maken
  • \n
  • Het aantal woonerven uitbreiden
  • \n
  • Grotere auto's meer belasten - ze nemen immers meer parkeerruimte in.
  • \n
  • Laat toeristen verplicht parkeren onder het zand; een (fiets)taxi kan hen naar hun hotel brengen
  • \n
  • Voorzie in elke straat enkele parkeerplaatsen voor kortparkeren. Zo kunnen leveringen, iemand afzetten,... gebeuren zonder op het voetpad en fietspad te parkeren
  • \n
" - }, - "language": [ - "nl" - ], - "hideFromOverview": true, - "enableUserBadge": false, - "enableShareScreen": false, - "enableMoreQuests": false, - "enableLayers": false, - "enableSearch": false, - "enableGeolocation": false, - "maintainer": "", - "icon": "./assets/themes/widths/icon.svg", - "version": "0", - "startLat": 51.20875, - "startLon": 3.22435, - "startZoom": 14, - "widenFactor": 0.05, - "socialImage": "", - "layers": [ - { - "id": "widths", - "name": { - "nl": "Straten met een breedte" - }, - "minzoom": 14, - "source": { - "osmTags": { - "and": [ - "width:carriageway~*" - ] - } - }, - "titleIcons": [], - "title": { - "render": { - "nl": "{name}" - }, - "condition": { - "and": [] - }, - "mappings": [ - { - "if": { - "and": [ - "name=" - ] - }, - "then": { - "nl": "Naamloos segmet" - } - } - ] - }, - "tagRenderings": [ - { - "render": "Deze straat is {width:carriageway}m breed", - "question": "Hoe breed is deze straat?", - "freeform": { - "key": "width:carriageway", - "type": "length", - "helperArgs": [ - 21, - "map" - ] - } - }, - { - "render": "Deze straat heeft {_width:difference}m te weinig:", - "mappings": [ - { - "if": { - "or": [ - "_width:difference~-.*", - "_width:difference=0.0" - ] - }, - "then": "Deze straat is breed genoeg:" - } - ] - }, - { - "render": "{_width:needed:cars}m voor het autoverkeer", - "mappings": [ - { - "if": "oneway=yes", - "then": "{_width:needed:cars}m voor het éénrichtings-autoverkeer" - }, - { - "if": "oneway=no", - "then": "{_width:needed:cars}m voor het tweerichtings-autoverkeer" - } - ] - }, - { - "render": "{_width:needed:parking}m voor het geparkeerde wagens", - "condition": "_width:needed:parking!=0.0" - }, - { - "render": "{_width:needed:cyclists}m voor fietsers", - "mappings": [ - { - "if": "bicycle=use_sidepath", - "then": "Fietsers hebben hier een vrijliggend fietspad en worden dus niet meegerekend" - }, - { - "if": "oneway:bicycle=yes", - "then": "{_width:needed:cyclists}m voor fietsers, die met de rijrichting mee moeten" - } - ] - }, - { - "render": "{_width:needed:pedestrians}m voor voetgangers", - "condition": "_width:needed:pedestrians!=0.0", - "mappings": [ - { - "if": { - "or": [ - "sidewalk=none", - "sidewalk=no" - ] - }, - "then": "{_width:needed:pedestrians}m voor voetgangers: er zijn hier geen voetpaden" - }, - { - "if": { - "or": [ - "sidewalk=left", - "sidewalk=right" - ] - }, - "then": "{_width:needed:pedestrians}m voor voetgangers: er is slechts aan één kant een voetpad" - } - ] - }, - { - "render": "{_width:needed}m nodig in het totaal" - } - ], - "icon": { - "render": "./assets/themes/widths/icon.svg" - }, - "width": { - "render": "4" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#00f", - "mappings": [ - { - "if": { - "or": [ - "access=destination", - "highway=living_street", - "highway=pedestrian", - "motor_vehicle=no", - "motor_vehicle=destination" - ] - }, - "then": "lightgrey" - }, - { - "if": "_width:difference~-.*", - "then": "#0f0" - }, - { - "if": { - "and": [ - "_width:difference!~-.*", - "_width:difference:no_pedestrians~-.*" - ] - }, - "then": "orange" - }, - { - "if": "_width:difference!~-.*", - "then": "#f00" - } - ] - }, - "dashArray": { - "render": "", - "mappings": [ - { - "if": { - "and": [ - "oneway=yes", - { - "or": [ - "oneway:bicycle=yes", - "oneway:bicycle=" - ] - } - ] - }, - "then": "5 6" - } - ] - }, - "presets": [] - } - ], - "roamingRenderings": [], - "defaultBackgroundId": "Stadia.AlidadeSmoothDark" -} \ No newline at end of file From 699e609fd71212a747faee732248f839a1d19e6a Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 18:15:21 +0200 Subject: [PATCH 16/65] Add some IDs and validation on IDS --- .../Json/TagRenderingConfigJson.ts | 2 +- Models/ThemeConfig/LayerConfig.ts | 7 + Models/ThemeConfig/TagRenderingConfig.ts | 3 +- .../openwindpowermap/openwindpowermap.json | 5 + assets/themes/speelplekken/speelplekken.json | 5 + .../speelplekken/speelplekken_temp.json | 283 ------------------ 6 files changed, 20 insertions(+), 285 deletions(-) delete mode 100644 assets/themes/speelplekken/speelplekken_temp.json diff --git a/Models/ThemeConfig/Json/TagRenderingConfigJson.ts b/Models/ThemeConfig/Json/TagRenderingConfigJson.ts index ab4552534..f700548ae 100644 --- a/Models/ThemeConfig/Json/TagRenderingConfigJson.ts +++ b/Models/ThemeConfig/Json/TagRenderingConfigJson.ts @@ -8,7 +8,7 @@ export interface TagRenderingConfigJson { /** * The id of the tagrendering, should be an unique string. - * Used to keep the translations in sync + * Used to keep the translations in sync. Only used in the tagRenderings-array of a layerConfig, not requered otherwise */ id?: string, diff --git a/Models/ThemeConfig/LayerConfig.ts b/Models/ThemeConfig/LayerConfig.ts index ee8c836fe..410c8b5ad 100644 --- a/Models/ThemeConfig/LayerConfig.ts +++ b/Models/ThemeConfig/LayerConfig.ts @@ -275,7 +275,14 @@ export default class LayerConfig { } this.tagRenderings = trs(json.tagRenderings, false); + + const missingIds = json.tagRenderings.filter(tr => typeof tr !== "string" && tr["builtin"] === undefined && tr["id"] === undefined); + if(missingIds.length > 0){ + console.error("Some tagRenderings of", this.id, "are missing an id:", missingIds) + throw "Missing ids in tagrenderings" + } + this.filters = (json.filter ?? []).map((option, i) => { return new FilterConfig(option, `${context}.filter-[${i}]`) }); diff --git a/Models/ThemeConfig/TagRenderingConfig.ts b/Models/ThemeConfig/TagRenderingConfig.ts index af092e462..4edd0da1d 100644 --- a/Models/ThemeConfig/TagRenderingConfig.ts +++ b/Models/ThemeConfig/TagRenderingConfig.ts @@ -13,7 +13,7 @@ import {Utils} from "../../Utils"; */ export default class TagRenderingConfig { - readonly id?: string; + readonly id: string; readonly render?: Translation; readonly question?: Translation; readonly condition?: TagsFilter; @@ -57,6 +57,7 @@ export default class TagRenderingConfig { return; } + this.id = json.id ?? ""; this.render = Translations.T(json.render, context + ".render"); this.question = Translations.T(json.question, context + ".question"); diff --git a/assets/themes/openwindpowermap/openwindpowermap.json b/assets/themes/openwindpowermap/openwindpowermap.json index b82db0942..a437a06bd 100644 --- a/assets/themes/openwindpowermap/openwindpowermap.json +++ b/assets/themes/openwindpowermap/openwindpowermap.json @@ -63,6 +63,7 @@ }, "tagRenderings": [ { + "id": "turbine-output", "render": { "en": "The power output of this wind turbine is {generator:output:electricity}.", "fr": "La puissance générée par cette éolienne est de {generator:output:electricity}." @@ -77,6 +78,7 @@ } }, { + "id": "turbine-operator", "render": { "en": "This wind turbine is operated by {operator}.", "fr": "Cette éolienne est opérée par {operator}." @@ -90,6 +92,7 @@ } }, { + "id": "turbine-height", "render": { "en": "The total height (including rotor radius) of this wind turbine is {height} metres.", "fr": "La hauteur totale, incluant les pales, est de {height} mètres." @@ -104,6 +107,7 @@ } }, { + "id": "turbine-diameter", "render": { "en": "The rotor diameter of this wind turbine is {rotor:diameter} metres.", "fr": "Le diamètre du rotor est de {rotor:diameter} mètres." @@ -118,6 +122,7 @@ } }, { + "id": "turbine-start-date", "render": { "en": "This wind turbine went into operation on/in {start_date}.", "fr": "L’éolienne est active depuis {start_date}." diff --git a/assets/themes/speelplekken/speelplekken.json b/assets/themes/speelplekken/speelplekken.json index 14e03b4d9..3ad9693d7 100644 --- a/assets/themes/speelplekken/speelplekken.json +++ b/assets/themes/speelplekken/speelplekken.json @@ -166,11 +166,13 @@ }, "tagRenderings": [ { + "id": "walk-length", "render": { "nl": "Deze wandeling is {_length:km}km lang" } }, { + "id":"walk-type", "mappings": [ { "if": "route=iwn", @@ -199,6 +201,7 @@ ] }, { + "id": "walk-description", "render": { "nl": "

Korte beschrijving:

{description}" }, @@ -209,6 +212,7 @@ } }, { + "id": "walk-operator", "question": { "nl": "Wie beheert deze wandeling en plaatst dus de signalisatiebordjes?" }, @@ -218,6 +222,7 @@ } }, { + "id": "walk-operator-email", "question": { "nl": "Naar wie kan men emailen bij problemen rond signalisatie?" }, diff --git a/assets/themes/speelplekken/speelplekken_temp.json b/assets/themes/speelplekken/speelplekken_temp.json deleted file mode 100644 index 867298215..000000000 --- a/assets/themes/speelplekken/speelplekken_temp.json +++ /dev/null @@ -1,283 +0,0 @@ -{ - "id": "speelplekken_temp", - "title": { - "nl": "Speelplekken in de Antwerpse Zuidrand" - }, - "shortDescription": { - "nl": "Speelplekken in de Antwerpse Zuidrand" - }, - "description": { - "nl": "Speelplekken in de Antwerpse Zuidrand. Een project van Provincie Antwerpen, in samenwerking met Createlli, Sportpret en OpenStreetMap België" - }, - "language": [ - "nl" - ], - "maintainer": "MapComplete", - "icon": "./assets/themes/speelplekken/logo.svg", - "hideFromOverview": true, - "lockLocation": true, - "version": "0", - "startLat": 51.17174, - "startLon": 4.449462, - "startZoom": 12, - "widenFactor": 0.05, - "socialImage": "", - "defaultBackgroundId": "CartoDB.Positron", - "layers": [ - { - "builtin": "play_forest", - "override": { - "source": { - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - }, - "icon": "./assets/themes/speelplekken/speelbos.svg", - "minzoom": 12 - }, - "calculatedTags": [ - "_is_shadowed=feat.overlapWith('shadow').length > 0 ? 'yes': ''" - ] - }, - { - "builtin": "playground", - "override": { - "icon": "./assets/themes/speelplekken/speeltuin.svg", - "minzoom": 14, - "source": { - "geoJsonLocal": "http://127.0.0.1:8080/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - }, - "calculatedTags": [ - "_is_shadowed=feat.overlapWith('shadow').length > 0 ? 'yes': ''" - ] - } - }, - { - "builtin": "village_green", - "override": { - "icon": "./assets/themes/speelplekken/speelweide.svg", - "minzoom": 14, - "source": { - "geoJsonLocal": "http://127.0.0.1:8080/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - }, - "calculatedTags": [ - "_is_shadowed=feat.overlapWith('shadow').length > 0 ? 'yes': ''" - ] - } - }, - { - "builtin": "grass_in_parks", - "override": { - "icon": "./assets/themes/speelplekken/speelweide.svg", - "minzoom": 14, - "source": { - "geoJsonLocal": "http://127.0.0.1:8080/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - }, - "calculatedTags": [ - "_is_shadowed=feat.overlapWith('shadow').length > 0 ? 'yes': ''" - ] - } - }, - { - "builtin": "sport_pitch", - "override": { - "minzoom": 15, - "source": { - "geoJsonLocal": "http://127.0.0.1:8080/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - }, - "calculatedTags": [ - "_is_shadowed=feat.overlapWith('shadow').length > 0 ? 'yes': ''" - ] - } - }, - { - "builtin": "slow_roads", - "override": { - "+tagRenderings": [ - { - "question": "Is dit een publiek toegankelijk pad?", - "mappings": [ - { - "if": "access=private", - "then": "Dit is een privaat pad" - }, - { - "if": "access=no", - "then": "Dit is een privaat pad", - "hideInAnswer": true - }, - { - "if": "access=permissive", - "then": "Dit pad is duidelijk in private eigendom, maar er hangen geen verbodsborden dus mag men erover" - } - ] - } - ], - "calculatedTags": [ - "_part_of_walking_routes=Array.from(new Set(feat.memberships().map(r => \"\" + r.relation.tags.name + \"\"))).join(', ')", - "_is_shadowed=feat.overlapWith('shadow').length > 0 ? 'yes': ''" - ], - "minzoom": 18, - "source": { - "geoJsonLocal": "http://127.0.0.1:8080/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - } - } - }, - { - "id": "walking_routes", - "name": { - "nl": "Wandelroutes van provincie Antwerpen" - }, - "description": "Walking routes by 'provincie Antwerpen'", - "source": { - "osmTags": { - "and": [ - "type=route", - "route=foot", - "operator~[pP]rovincie Antwerpen" - ] - }, - "geoJson": "https://pietervdvn.github.io/speelplekken_cache/speelplekken_{layer}_{z}_{x}_{y}.geojson", - "geoJsonZoomLevel": 14, - "isOsmCache": true - }, - "title": { - "render": "Wandeling {name}", - "mappings": [ - { - "if": "name~.*wandeling.*", - "then": "{name}" - } - ] - }, - "tagRenderings": [ - { - "render": { - "nl": "Deze wandeling is {_length:km}km lang" - } - }, - { - "mappings": [ - { - "if": "route=iwn", - "then": { - "nl": "Dit is een internationale wandelroute" - } - }, - { - "if": "route=nwn", - "then": { - "nl": "Dit is een nationale wandelroute" - } - }, - { - "if": "route=rwn", - "then": { - "nl": "Dit is een regionale wandelroute" - } - }, - { - "if": "route=lwn", - "then": { - "nl": "Dit is een lokale wandelroute" - } - } - ] - }, - { - "render": { - "nl": "

Korte beschrijving:

{description}" - }, - "question": "Geef een korte beschrijving van de wandeling (max 255 tekens)", - "freeform": { - "key": "description", - "type": "text" - } - }, - { - "question": { - "nl": "Wie beheert deze wandeling en plaatst dus de signalisatiebordjes?" - }, - "render": "Signalisatie geplaatst door {operator}", - "freeform": { - "key": "operator" - } - }, - { - "question": { - "nl": "Naar wie kan men emailen bij problemen rond signalisatie?" - }, - "render": { - "nl": "Bij problemen met signalisatie kan men emailen naar {operator:email}" - }, - "freeform": { - "key": "operator:email", - "type": "email" - } - }, - "questions", - "reviews" - ], - "color": { - "render": "#6d6", - "mappings": [ - { - "if": "color~*", - "then": "{color}" - }, - { - "if": "colour~*", - "then": "{colour}" - } - ] - }, - "width": { - "render": "9" - } - } - ], - "clustering": { - "maxZoom": 16, - "minNeededElements": 100 - }, - "roamingRenderings": [ - { - "render": "Maakt deel uit van {_part_of_walking_routes}", - "condition": "_part_of_walking_routes~*" - }, - { - "render": "Een kinder-reportage vinden jullie hier", - "freeform": { - "key": "video", - "type": "url" - }, - "question": "Wat is de link naar de video-reportage?" - } - ], - "overrideAll": { - "isShown": { - "render": "yes", - "mappings": [ - { - "if": "_is_shadowed=yes", - "then": "no" - } - ] - } - } -} \ No newline at end of file From a53a0f3b6f88db7dfbd3192c54343b0fea9c6144 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 18:16:18 +0200 Subject: [PATCH 17/65] Add translation names in an automated way --- assets/layers/bench/bench.json | 18 ++++++--- assets/layers/bench_at_pt/bench_at_pt.json | 6 ++- .../bicycle_library/bicycle_library.json | 6 ++- .../bicycle_tube_vending_machine.json | 9 +++-- assets/layers/bike_cafe/bike_cafe.json | 15 ++++--- .../layers/bike_cleaning/bike_cleaning.json | 6 ++- .../bike_repair_station.json | 15 ++++--- assets/layers/bike_shop/bike_shop.json | 18 ++++++--- assets/layers/binocular/binocular.json | 6 ++- assets/layers/birdhide/birdhide.json | 3 +- .../cycleways_and_roads.json | 3 +- .../layers/defibrillator/defibrillator.json | 39 ++++++++++++------- assets/layers/ghost_bike/ghost_bike.json | 12 ++++-- assets/layers/map/map.json | 3 +- assets/layers/picnic_table/picnic_table.json | 3 +- assets/layers/play_forest/play_forest.json | 9 +++-- assets/layers/playground/playground.json | 21 ++++++---- .../public_bookcase/public_bookcase.json | 21 ++++++---- assets/layers/slow_roads/slow_roads.json | 3 +- assets/layers/sport_pitch/sport_pitch.json | 15 ++++--- assets/layers/toilet/toilet.json | 9 +++-- assets/layers/tree_node/tree_node.json | 9 +++-- assets/layers/viewpoint/viewpoint.json | 3 +- 23 files changed, 168 insertions(+), 84 deletions(-) diff --git a/assets/layers/bench/bench.json b/assets/layers/bench/bench.json index a18a31723..5a94c40ad 100644 --- a/assets/layers/bench/bench.json +++ b/assets/layers/bench/bench.json @@ -121,7 +121,8 @@ "nb_NO": "Har denne beken et rygglene?", "pl": "Czy ta ławka ma oparcie?", "pt_BR": "Este assento tem um escosto?" - } + }, + "id": "bench-backrest" }, { "render": { @@ -157,7 +158,8 @@ "nb_NO": "Hvor mange sitteplasser har denne benken?", "pl": "Ile siedzeń ma ta ławka?", "pt_BR": "Quantos assentos este banco tem?" - } + }, + "id": "bench-seats" }, { "render": { @@ -308,7 +310,8 @@ "zh_Hant": "這個長椅 (座位) 是什麼做的?", "pt_BR": "De que é feito o banco (assento)?", "pl": "Z czego wykonana jest ławka (siedzisko)?" - } + }, + "id": "bench-material" }, { "question": { @@ -340,7 +343,8 @@ "freeform": { "key": "direction", "type": "direction" - } + }, + "id": "bench-direction" }, { "render": { @@ -521,7 +525,8 @@ "pl": "Kolor: żółty" } } - ] + ], + "id": "bench-colour" }, { "question": { @@ -557,7 +562,8 @@ "if": "survey:date:={_now:date}", "then": "Surveyed today!" } - ] + ], + "id": "bench-survey:date" } ], "icon": { diff --git a/assets/layers/bench_at_pt/bench_at_pt.json b/assets/layers/bench_at_pt/bench_at_pt.json index e585bae45..f619ededa 100644 --- a/assets/layers/bench_at_pt/bench_at_pt.json +++ b/assets/layers/bench_at_pt/bench_at_pt.json @@ -106,7 +106,8 @@ }, "freeform": { "key": "name" - } + }, + "id": "bench_at_pt-name" }, { "render": { @@ -127,7 +128,8 @@ "and": [ "bench=stand_up_bench" ] - } + }, + "id": "bench_at_pt-bench" } ], "icon": { diff --git a/assets/layers/bicycle_library/bicycle_library.json b/assets/layers/bicycle_library/bicycle_library.json index f2751c175..ac01b7ee2 100644 --- a/assets/layers/bicycle_library/bicycle_library.json +++ b/assets/layers/bicycle_library/bicycle_library.json @@ -79,7 +79,8 @@ }, "freeform": { "key": "name" - } + }, + "id": "bicycle_library-name" }, "website", "phone", @@ -155,7 +156,8 @@ "pt_BR": "Emprestar uma bicicleta custa €20/ano e €20 de garantia" } } - ] + ], + "id": "bicycle_library-charge" }, { "question": { diff --git a/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json b/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json index f8aceeb7c..2f2f97f4e 100644 --- a/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json +++ b/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json @@ -161,7 +161,8 @@ "render": "A bicycle tube costs {charge}", "freeform": { "key": "charge" - } + }, + "id": "bicycle_tube_vending_machine-charge" }, { "question": "How can one pay at this tube vending machine?", @@ -200,7 +201,8 @@ "then": "Schwalbe tubes are sold here" } ], - "multiAnswer": true + "multiAnswer": true, + "id": "bicycle_tube_vending_machine-brand" }, { "question": "Who maintains this vending machine?", @@ -217,7 +219,8 @@ ], "freeform": { "key": "operator" - } + }, + "id": "bicycle_tube_vending_machine-operator" }, { "question": "Are other bicycle bicycle accessories sold here?", diff --git a/assets/layers/bike_cafe/bike_cafe.json b/assets/layers/bike_cafe/bike_cafe.json index 93b07cd19..c4b2822c4 100644 --- a/assets/layers/bike_cafe/bike_cafe.json +++ b/assets/layers/bike_cafe/bike_cafe.json @@ -97,7 +97,8 @@ }, "freeform": { "key": "name" - } + }, + "id": "bike_cafe-name" }, { "question": { @@ -250,7 +251,8 @@ "render": "{website}", "freeform": { "key": "website" - } + }, + "id": "bike_cafe-website" }, { "question": { @@ -269,7 +271,8 @@ "freeform": { "key": "phone", "type": "phone" - } + }, + "id": "bike_cafe-phone" }, { "question": { @@ -288,7 +291,8 @@ "freeform": { "key": "email", "type": "email" - } + }, + "id": "bike_cafe-email" }, { "question": { @@ -305,7 +309,8 @@ "freeform": { "key": "opening_hours", "type": "opening_hours" - } + }, + "id": "bike_cafe-opening_hours" } ], "icon": { diff --git a/assets/layers/bike_cleaning/bike_cleaning.json b/assets/layers/bike_cleaning/bike_cleaning.json index bf92b1987..6c76d519b 100644 --- a/assets/layers/bike_cleaning/bike_cleaning.json +++ b/assets/layers/bike_cleaning/bike_cleaning.json @@ -114,7 +114,8 @@ "then": "The cleaning service has a fee" } ], - "roaming": true + "roaming": true, + "id": "bike_cleaning-service:bicycle:cleaning:charge" }, { "question": "How much does it cost to use the cleaning service?", @@ -141,7 +142,8 @@ "then": "The cleaning service has a fee" } ], - "roaming": false + "roaming": false, + "id": "bike_cleaning-charge" } ] } \ No newline at end of file diff --git a/assets/layers/bike_repair_station/bike_repair_station.json b/assets/layers/bike_repair_station/bike_repair_station.json index f082e3862..77382279c 100644 --- a/assets/layers/bike_repair_station/bike_repair_station.json +++ b/assets/layers/bike_repair_station/bike_repair_station.json @@ -224,7 +224,8 @@ "then": "De Fietsambassade Gent", "hideInAnswer": "_country!=be" } - ] + ], + "id": "bike_repair_station-operator" }, { "question": { @@ -235,7 +236,8 @@ "key": "email", "type": "email" }, - "render": "{email}" + "render": "{email}", + "id": "bike_repair_station-email" }, { "question": { @@ -246,7 +248,8 @@ "key": "phone", "type": "phone" }, - "render": "{phone}" + "render": "{phone}", + "id": "bike_repair_station-phone" }, { "question": { @@ -287,7 +290,8 @@ }, "hideInAnswer": true } - ] + ], + "id": "bike_repair_station-opening_hours" }, { "question": { @@ -481,7 +485,8 @@ "it": "Schrader (valvola delle auto)" } } - ] + ], + "id": "bike_repair_station-valves" }, { "question": { diff --git a/assets/layers/bike_shop/bike_shop.json b/assets/layers/bike_shop/bike_shop.json index 77d3833b1..23c471351 100644 --- a/assets/layers/bike_shop/bike_shop.json +++ b/assets/layers/bike_shop/bike_shop.json @@ -225,7 +225,8 @@ }, "freeform": { "key": "name" - } + }, + "id": "bike_shop-name" }, { "question": { @@ -243,7 +244,8 @@ "freeform": { "key": "website", "type": "url" - } + }, + "id": "bike_shop-website" }, { "question": { @@ -260,7 +262,8 @@ "freeform": { "key": "phone", "type": "phone" - } + }, + "id": "bike_shop-phone" }, { "question": { @@ -277,7 +280,8 @@ "freeform": { "key": "email", "type": "email" - } + }, + "id": "bike_shop-email" }, { "render": "{opening_hours_table(opening_hours)}", @@ -285,14 +289,16 @@ "freeform": { "key": "opening_hours", "type": "opening_hours" - } + }, + "id": "bike_shop-opening_hours" }, "description", { "render": "Enkel voor {access}", "freeform": { "key": "access" - } + }, + "id": "bike_shop-access" }, { "question": { diff --git a/assets/layers/binocular/binocular.json b/assets/layers/binocular/binocular.json index 1b2573e29..46ba8fe42 100644 --- a/assets/layers/binocular/binocular.json +++ b/assets/layers/binocular/binocular.json @@ -45,7 +45,8 @@ "question": { "en": "How much does one have to pay to use these binoculars?", "nl": "Hoeveel moet men betalen om deze verrekijker te gebruiken?" - } + }, + "id": "binocular-charge" }, { "question": { @@ -59,7 +60,8 @@ "freeform": { "key": "direction", "type": "direction" - } + }, + "id": "binocular-direction" } ], "icon": { diff --git a/assets/layers/birdhide/birdhide.json b/assets/layers/birdhide/birdhide.json index 4e1504864..a8c232bf5 100644 --- a/assets/layers/birdhide/birdhide.json +++ b/assets/layers/birdhide/birdhide.json @@ -184,7 +184,8 @@ "nl": "Beheer door het Agentschap Natuur en Bos " } } - ] + ], + "id": "birdhide-operator" } ], "icon": { diff --git a/assets/layers/cycleways_and_roads/cycleways_and_roads.json b/assets/layers/cycleways_and_roads/cycleways_and_roads.json index 491a232db..b622043a2 100644 --- a/assets/layers/cycleways_and_roads/cycleways_and_roads.json +++ b/assets/layers/cycleways_and_roads/cycleways_and_roads.json @@ -1007,7 +1007,8 @@ "20", "map" ] - } + }, + "id": "cycleways_and_roads-cycleway:buffer" }, { "question": { diff --git a/assets/layers/defibrillator/defibrillator.json b/assets/layers/defibrillator/defibrillator.json index f0d193c22..e0e4f44a7 100644 --- a/assets/layers/defibrillator/defibrillator.json +++ b/assets/layers/defibrillator/defibrillator.json @@ -191,7 +191,8 @@ "it": "Non accessibile, potrebbe essere solo per uso professionale" } } - ] + ], + "id": "defibrillator-access" }, { "render": { @@ -236,7 +237,8 @@ "ru": "Это обычный автоматический дефибриллятор" } } - ] + ], + "id": "defibrillator-defibrillator" }, { "question": { @@ -287,7 +289,8 @@ "de": "Dieser Defibrillator befindet sich in der ersten Etage" } } - ] + ], + "id": "defibrillator-level" }, { "render": { @@ -309,7 +312,8 @@ "freeform": { "type": "text", "key": "defibrillator:location" - } + }, + "id": "defibrillator-defibrillator:location" }, { "render": { @@ -331,7 +335,8 @@ "freeform": { "type": "text", "key": "defibrillator:location:en" - } + }, + "id": "defibrillator-defibrillator:location:en" }, { "render": { @@ -353,7 +358,8 @@ "freeform": { "type": "text", "key": "defibrillator:location:fr" - } + }, + "id": "defibrillator-defibrillator:location:fr" }, "wheelchair-access", { @@ -374,7 +380,8 @@ "freeform": { "type": "text", "key": "ref" - } + }, + "id": "defibrillator-ref" }, { "render": { @@ -394,7 +401,8 @@ "freeform": { "key": "email", "type": "email" - } + }, + "id": "defibrillator-email" }, { "render": { @@ -414,7 +422,8 @@ "freeform": { "key": "phone", "type": "phone" - } + }, + "id": "defibrillator-phone" }, { "render": { @@ -447,7 +456,8 @@ "de": "24/7 geöffnet (auch an Feiertagen)" } } - ] + ], + "id": "defibrillator-opening_hours" }, { "render": { @@ -469,7 +479,8 @@ "freeform": { "key": "description", "type": "text" - } + }, + "id": "defibrillator-description" }, { "question": { @@ -502,7 +513,8 @@ "de": "Heute überprüft!" } } - ] + ], + "id": "defibrillator-survey:date" }, { "render": { @@ -523,7 +535,8 @@ "freeform": { "key": "fixme", "type": "text" - } + }, + "id": "defibrillator-fixme" } ] } \ No newline at end of file diff --git a/assets/layers/ghost_bike/ghost_bike.json b/assets/layers/ghost_bike/ghost_bike.json index 3183b7283..5207992b4 100644 --- a/assets/layers/ghost_bike/ghost_bike.json +++ b/assets/layers/ghost_bike/ghost_bike.json @@ -117,7 +117,8 @@ "fr": "Aucun nom n'est marqué sur le vélo" } } - ] + ], + "id": "ghost_bike-name" }, { "question": { @@ -139,7 +140,8 @@ "freeform": { "type": "url", "key": "source" - } + }, + "id": "ghost_bike-source" }, { "question": { @@ -161,7 +163,8 @@ }, "freeform": { "key": "inscription" - } + }, + "id": "ghost_bike-inscription" }, { "question": { @@ -180,7 +183,8 @@ "freeform": { "key": "start_date", "type": "date" - } + }, + "id": "ghost_bike-start_date" } ] } \ No newline at end of file diff --git a/assets/layers/map/map.json b/assets/layers/map/map.json index 3bc09c947..991aa1524 100644 --- a/assets/layers/map/map.json +++ b/assets/layers/map/map.json @@ -71,7 +71,8 @@ "ru": "Эта карта основана на {map_source}", "fr": "Cette carte est basée sur {map_source}", "de": "Diese Karte basiert auf {map_source}" - } + }, + "id": "map-map_source" }, { "question": { diff --git a/assets/layers/picnic_table/picnic_table.json b/assets/layers/picnic_table/picnic_table.json index 9bea66671..dbe67a9af 100644 --- a/assets/layers/picnic_table/picnic_table.json +++ b/assets/layers/picnic_table/picnic_table.json @@ -73,7 +73,8 @@ "fr": "C’est une table en béton" } } - ] + ], + "id": "picnic_table-material" } ], "icon": { diff --git a/assets/layers/play_forest/play_forest.json b/assets/layers/play_forest/play_forest.json index cc6edbb31..4be4071ee 100644 --- a/assets/layers/play_forest/play_forest.json +++ b/assets/layers/play_forest/play_forest.json @@ -51,7 +51,8 @@ "if": "operator=Agenstchap Natuur en Bos", "then": "Dit gebied wordt beheerd door het Agentschap Natuur en Bos" } - ] + ], + "id": "play_forest-operator" }, { "question": "Wanneer is deze speelzone toegankelijk?", @@ -72,7 +73,8 @@ "freeform": { "key": "email", "type": "email" - } + }, + "id": "play_forest-email" }, { "question": "Wie kan men bellen indien er problemen zijn met de speelzone?", @@ -80,7 +82,8 @@ "freeform": { "key": "phone", "type": "phone" - } + }, + "id": "play_forest-phone" }, "questions", { diff --git a/assets/layers/playground/playground.json b/assets/layers/playground/playground.json index e2d3e8a72..9d5cdb5b0 100644 --- a/assets/layers/playground/playground.json +++ b/assets/layers/playground/playground.json @@ -161,7 +161,8 @@ }, "hideInAnswer": true } - ] + ], + "id": "playground-surface" }, { "question": { @@ -215,7 +216,8 @@ "freeform": { "key": "min_age", "type": "pnat" - } + }, + "id": "playground-min_age" }, { "render": { @@ -234,7 +236,8 @@ "freeform": { "key": "max_age", "type": "pnat" - } + }, + "id": "playground-max_age" }, { "question": { @@ -253,7 +256,8 @@ }, "freeform": { "key": "operator" - } + }, + "id": "playground-operator" }, { "question": { @@ -339,7 +343,8 @@ "freeform": { "key": "email", "type": "email" - } + }, + "id": "playground-email" }, { "question": { @@ -361,7 +366,8 @@ "freeform": { "key": "phone", "type": "phone" - } + }, + "id": "playground-phone" }, { "question": { @@ -453,7 +459,8 @@ }, "hideInAnswer": true } - ] + ], + "id": "playground-opening_hours" }, "questions", { diff --git a/assets/layers/public_bookcase/public_bookcase.json b/assets/layers/public_bookcase/public_bookcase.json index 786d7e220..258fff091 100644 --- a/assets/layers/public_bookcase/public_bookcase.json +++ b/assets/layers/public_bookcase/public_bookcase.json @@ -121,7 +121,8 @@ "it": "Questa microbiblioteca non ha un nome proprio" } } - ] + ], + "id": "public_bookcase-name" }, { "render": { @@ -144,7 +145,8 @@ "key": "capacity", "type": "nat", "inline": true - } + }, + "id": "public_bookcase-capacity" }, { "question": { @@ -285,7 +287,8 @@ "freeform": { "type": "string", "key": "operator" - } + }, + "id": "public_bookcase-operator" }, { "question": { @@ -337,7 +340,8 @@ "it": "Questa microbiblioteca non fa parte di una rete" } } - ] + ], + "id": "public_bookcase-brand" }, { "render": { @@ -375,7 +379,8 @@ ] } } - ] + ], + "id": "public_bookcase-ref" }, { "question": { @@ -397,7 +402,8 @@ "freeform": { "key": "start_date", "type": "date" - } + }, + "id": "public_bookcase-start_date" }, { "render": { @@ -419,7 +425,8 @@ "freeform": { "key": "website", "type": "url" - } + }, + "id": "public_bookcase-website" } ], "deletion": { diff --git a/assets/layers/slow_roads/slow_roads.json b/assets/layers/slow_roads/slow_roads.json index 5ef6d2feb..7e3a763d5 100644 --- a/assets/layers/slow_roads/slow_roads.json +++ b/assets/layers/slow_roads/slow_roads.json @@ -201,7 +201,8 @@ }, "hideInAnswer": true } - ] + ], + "id": "slow_roads-surface" }, { "question": "Is deze weg 's nachts verlicht?", diff --git a/assets/layers/sport_pitch/sport_pitch.json b/assets/layers/sport_pitch/sport_pitch.json index 17e47f206..6666ed6c9 100644 --- a/assets/layers/sport_pitch/sport_pitch.json +++ b/assets/layers/sport_pitch/sport_pitch.json @@ -140,7 +140,8 @@ }, "hideInAnswer": true } - ] + ], + "id": "sport_pitch-sport" }, { "question": { @@ -211,7 +212,8 @@ "it": "La superficie è calcestruzzo" } } - ] + ], + "id": "sport_pitch-surface" }, { "question": { @@ -331,7 +333,8 @@ "key": "phone", "type": "phone" }, - "render": "{phone}" + "render": "{phone}", + "id": "sport_pitch-phone" }, { "question": { @@ -344,7 +347,8 @@ "key": "email", "type": "email" }, - "render": "{email}" + "render": "{email}", + "id": "sport_pitch-email" }, { "question": { @@ -376,7 +380,8 @@ } } ], - "condition": "access~*" + "condition": "access~*", + "id": "sport_pitch-opening_hours" }, "questions", { diff --git a/assets/layers/toilet/toilet.json b/assets/layers/toilet/toilet.json index 0963a1bab..0b946addc 100644 --- a/assets/layers/toilet/toilet.json +++ b/assets/layers/toilet/toilet.json @@ -167,7 +167,8 @@ }, "hideInAnswer": true } - ] + ], + "id": "toilet-access" }, { "question": { @@ -222,7 +223,8 @@ "freeform": { "key": "charge", "type": "string" - } + }, + "id": "toilet-charge" }, { "question": { @@ -399,7 +401,8 @@ "it": "Il fasciatoio è in una stanza dedicata. " } } - ] + ], + "id": "toilet-changing_table:location" } ] } \ No newline at end of file diff --git a/assets/layers/tree_node/tree_node.json b/assets/layers/tree_node/tree_node.json index 3ae7384d6..34be5dbad 100644 --- a/assets/layers/tree_node/tree_node.json +++ b/assets/layers/tree_node/tree_node.json @@ -324,7 +324,8 @@ "denotation=natural_monument", "name~*" ] - } + }, + "id": "tree_node-name" }, { "question": { @@ -435,7 +436,8 @@ "heritage=4", "heritage:operator=OnroerendErfgoed" ] - } + }, + "id": "tree_node-ref:OnroerendErfgoed" }, { "render": { @@ -461,7 +463,8 @@ "denotation=natural_monument", "wikidata~*" ] - } + }, + "id": "tree_node-wikidata" } ], "icon": { diff --git a/assets/layers/viewpoint/viewpoint.json b/assets/layers/viewpoint/viewpoint.json index 31f2452bc..6f34c3159 100644 --- a/assets/layers/viewpoint/viewpoint.json +++ b/assets/layers/viewpoint/viewpoint.json @@ -67,7 +67,8 @@ "render": "{description}", "freeform": { "key": "description" - } + }, + "id": "viewpoint-description" } ] } \ No newline at end of file From d326facf395e6356e22f30f8807f0693b0b0e64f Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 18:21:22 +0200 Subject: [PATCH 18/65] Add some more ids, remove bike monitoring stations theme and layer --- .../bicycle_library/bicycle_library.json | 1 + .../bicycle_tube_vending_machine.json | 2 + assets/layers/bike_cafe/bike_cafe.json | 3 + .../bike_monitoring_station.json | 85 ----------------- .../bike_monitoring_station/license_info.json | 12 --- .../monitoring_station.svg | 95 ------------------- .../bike_monitoring_stations.json | 57 ----------- 7 files changed, 6 insertions(+), 249 deletions(-) delete mode 100644 assets/layers/bike_monitoring_station/bike_monitoring_station.json delete mode 100644 assets/layers/bike_monitoring_station/license_info.json delete mode 100644 assets/layers/bike_monitoring_station/monitoring_station.svg delete mode 100644 assets/themes/bike_monitoring_station/bike_monitoring_stations.json diff --git a/assets/layers/bicycle_library/bicycle_library.json b/assets/layers/bicycle_library/bicycle_library.json index ac01b7ee2..21e478e7b 100644 --- a/assets/layers/bicycle_library/bicycle_library.json +++ b/assets/layers/bicycle_library/bicycle_library.json @@ -160,6 +160,7 @@ "id": "bicycle_library-charge" }, { + "id": "bicycle-library-target-group", "question": { "en": "Who can lend bicycles here?", "nl": "Voor wie worden hier fietsen aangeboden?", diff --git a/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json b/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json index 2f2f97f4e..665a75942 100644 --- a/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json +++ b/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json @@ -165,6 +165,7 @@ "id": "bicycle_tube_vending_machine-charge" }, { + "id": "vending-machine-payment-methods", "question": "How can one pay at this tube vending machine?", "mappings": [ { @@ -223,6 +224,7 @@ "id": "bicycle_tube_vending_machine-operator" }, { + "id": "bicycle_tube_vending_maching-other-items", "question": "Are other bicycle bicycle accessories sold here?", "mappings": [ { diff --git a/assets/layers/bike_cafe/bike_cafe.json b/assets/layers/bike_cafe/bike_cafe.json index c4b2822c4..3619c7068 100644 --- a/assets/layers/bike_cafe/bike_cafe.json +++ b/assets/layers/bike_cafe/bike_cafe.json @@ -101,6 +101,7 @@ "id": "bike_cafe-name" }, { + "id": "bike_cafe-bike-pump", "question": { "en": "Does this bike cafe offer a bike pump for use by anyone?", "nl": "Biedt dit fietscafé een fietspomp aan voor iedereen?", @@ -144,6 +145,7 @@ ] }, { + "id": "bike_cafe-repair-tools", "question": { "en": "Are there tools here to repair your own bike?", "nl": "Biedt dit fietscafé gereedschap aan om je fiets zelf te herstellen?", @@ -190,6 +192,7 @@ ] }, { + "id": "bike_cafe-repair-service", "question": { "en": "Does this bike cafe repair bikes?", "nl": "Herstelt dit fietscafé fietsen?", diff --git a/assets/layers/bike_monitoring_station/bike_monitoring_station.json b/assets/layers/bike_monitoring_station/bike_monitoring_station.json deleted file mode 100644 index a20942f96..000000000 --- a/assets/layers/bike_monitoring_station/bike_monitoring_station.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "id": "bike_monitoring_station", - "name": { - "en": "Monitoring stations", - "nl": "Telstation", - "fr": "Stations de contrôle", - "it": "Stazioni di monitoraggio", - "zh_Hant": "監視站", - "ru": "Станции мониторинга", - "pt_BR": "Estações de monitoramento" - }, - "minzoom": 12, - "source": { - "osmTags": { - "and": [ - "man_made=monitoring_station", - "monitoring:bicycle=yes" - ] - } - }, - "title": { - "render": { - "nl": "Fietstelstation", - "en": "Bicycle counting station", - "fr": "Station de comptage de vélo", - "it": "Contabiciclette", - "de": "Fahrradzählstation", - "zh_Hant": "單車計數站", - "pt_BR": "Estação de contagem de bicicletas" - }, - "mappings": [ - { - "if": "name~*", - "then": { - "en": "Bicycle counting station {name}", - "nl": "Fietstelstation {name}", - "fr": "Station de comptage de vélo {name}", - "it": "Contabiciclette {name}", - "de": "Fahrradzählstation {name}", - "zh_Hant": "單車計數站 {name}", - "pl": "Stacja liczenia rowerów {name}", - "pt_BR": "Estação de contagem de bicicletas {name}" - } - }, - { - "if": "ref~*", - "then": { - "en": "Bicycle counting station {ref}", - "nl": "Fietstelstation {ref}", - "fr": "Station de comptage de vélo {ref}", - "it": "Contabiciclette {ref}", - "de": "Fahrradzählstation {ref}", - "zh_Hant": "單車計數站 {ref}", - "pl": "Stacja liczenia rowerów {ref}", - "pt_BR": "Estação de contagem de bicicletas {ref}" - } - } - ] - }, - "tagRenderings": [ - "images", - { - "render": "{live({url},{url:format},hour)} cyclists last hour
{live({url},{url:format},day)} cyclists today
{live({url},{url:format},year)} cyclists this year
", - "condition": { - "and": [ - "url~*", - "url:format~*" - ] - } - } - ], - "icon": { - "render": "./assets/layers/bike_monitoring_station/monitoring_station.svg" - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#00f" - }, - "presets": [] -} \ No newline at end of file diff --git a/assets/layers/bike_monitoring_station/license_info.json b/assets/layers/bike_monitoring_station/license_info.json deleted file mode 100644 index 45abb1c69..000000000 --- a/assets/layers/bike_monitoring_station/license_info.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "path": "monitoring_station.svg", - "license": "CC-BY-SA 3.0", - "authors": [ - "Fabián Alexis" - ], - "sources": [ - "https://commons.wikimedia.org/wiki/File:Antu_chronometer-reset.svg" - ] - } -] \ No newline at end of file diff --git a/assets/layers/bike_monitoring_station/monitoring_station.svg b/assets/layers/bike_monitoring_station/monitoring_station.svg deleted file mode 100644 index a780b4ea8..000000000 --- a/assets/layers/bike_monitoring_station/monitoring_station.svg +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/themes/bike_monitoring_station/bike_monitoring_stations.json b/assets/themes/bike_monitoring_station/bike_monitoring_stations.json deleted file mode 100644 index 5703e2ed5..000000000 --- a/assets/themes/bike_monitoring_station/bike_monitoring_stations.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "id": "bike_monitoring_stations", - "title": { - "en": "Bike Monitoring stations", - "nl": "Fietstelstations", - "it": "Stazioni di monitoraggio biciclette", - "ru": "Станции мониторинга велосипедов", - "ja": "自転車監視ステーション", - "zh_Hant": "自行車監視站", - "fr": "Station de comptage vélo", - "pt_BR": "Estações de monitoramento de bicicletas" - }, - "shortDescription": { - "en": "Bike monitoring stations with live data from Brussels Mobility", - "nl": "Fietstelstations met live data van Brussel Mobiliteit", - "it": "Stazioni di monitoraggio bici con dati in tempo reale forniti da Bruxelles Mobility", - "ru": "Станции мониторинга велосипедов с оперативными данными от Brussels Mobility", - "ja": "Brussels Mobilityのライブデータを使用した自転車モニタリングステーション", - "zh_Hant": "布魯塞爾車行資料的即時單車監視站資料", - "fr": "Station de comptage vélo avec données en temps réel par Bruxelles Mobilités", - "pt_BR": "Estações de monitoramento de bicicletas com dados ao vivo da Mobilidade de Bruxelas" - }, - "description": { - "en": "This theme shows bike monitoring stations with live data", - "nl": "Dit thema toont fietstelstations met live data", - "it": "Questo tema mostra le stazioni di monitoraggio bici con dati dal vivo", - "ru": "В этой теме показаны станции мониторинга велосипедов с данными в реальном времени", - "ja": "このテーマでは、ライブデータのある自転車監視ステーションを示します", - "zh_Hant": "這個主題顯示單車監視站的即時資料", - "fr": "Ce thème montre les données des compteurs en temps réel", - "pt_BR": "Este tema mostra as estações de monitoramento de bicicletas com dados ao vivo" - }, - "language": [ - "en", - "nl", - "it", - "ru", - "ja", - "zh_Hant", - "fr", - "pt_BR" - ], - "hideFromOverview": true, - "maintainer": "", - "icon": "./assets/layers/bike_monitoring_station/monitoring_station.svg", - "version": "0", - "startLat": 50.8435, - "startLon": 4.3688, - "startZoom": 14, - "widenFactor": 0.05, - "socialImage": "", - "layers": [ - "bike_monitoring_station" - ], - "roamingRenderings": [], - "defaultBackgroundId": "Stadia.AlidadeSmoothDark" -} \ No newline at end of file From 0efd83c9b6aa4456cbfb008d94d990a4ea482b8e Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 18:21:29 +0200 Subject: [PATCH 19/65] Add linting file --- scripts/lint.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 scripts/lint.ts diff --git a/scripts/lint.ts b/scripts/lint.ts new file mode 100644 index 000000000..f1e67ec68 --- /dev/null +++ b/scripts/lint.ts @@ -0,0 +1,30 @@ + +/* + * This script reads all theme and layer files and reformats them inplace + * Use with caution, make a commit beforehand! + */ + + +import ScriptUtils from "./ScriptUtils"; +import {readFileSync, writeFileSync} from "fs"; +import {tag} from "@turf/turf"; + +const layerFiles = ScriptUtils.getLayerFiles(); +for (const layerFile of layerFiles) { + console.log("Handling ", layerFile.path) + + for (const tagRendering of layerFile.parsed.tagRenderings) { + if(tagRendering["#"] !== undefined){ + tagRendering["id"] = tagRendering["#"] + delete tagRendering["#"] + } + if(tagRendering["id"] === undefined){ + if(tagRendering["freeform"]?.key !== undefined ) { + tagRendering["id"] = layerFile.parsed.id+"-"+tagRendering["freeform"]["key"] + } + } + } + + + writeFileSync(layerFile.path, JSON.stringify(layerFile.parsed, null, " ")) +} \ No newline at end of file From 01d80ef4e8f66b086aa7870437c75ac1061bbadc Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 19:56:40 +0200 Subject: [PATCH 20/65] Add more ID-s to the layer configs --- .../bike_repair_station.json | 8 +++-- assets/layers/bike_shop/bike_shop.json | 8 +++++ assets/layers/birdhide/birdhide.json | 2 ++ assets/layers/crossings/crossings.json | 8 +++++ .../cycleways_and_roads.json | 6 ++++ .../layers/defibrillator/defibrillator.json | 1 + .../layers/drinking_water/drinking_water.json | 1 + assets/layers/food/food.json | 4 +++ assets/layers/ghost_bike/ghost_bike.json | 1 + .../layers/grass_in_parks/grass_in_parks.json | 2 ++ assets/layers/map/map.json | 1 + assets/layers/play_forest/play_forest.json | 2 ++ assets/layers/playground/playground.json | 4 +++ .../public_bookcase/public_bookcase.json | 4 +++ assets/layers/slow_roads/slow_roads.json | 2 ++ assets/layers/sport_pitch/sport_pitch.json | 5 ++- assets/layers/toilet/toilet.json | 4 +++ assets/layers/trail/trail.json | 1 + assets/layers/tree_node/tree_node.json | 6 +++- .../layers/village_green/village_green.json | 2 ++ assets/layers/waste_basket/waste_basket.json | 1 + assets/themes/grb.json | 5 +++ assets/themes/hailhydrant/hailhydrant.json | 14 ++++++++ scripts/lint.ts | 32 ++++++++++++++----- 24 files changed, 112 insertions(+), 12 deletions(-) diff --git a/assets/layers/bike_repair_station/bike_repair_station.json b/assets/layers/bike_repair_station/bike_repair_station.json index 77382279c..5cef73ea7 100644 --- a/assets/layers/bike_repair_station/bike_repair_station.json +++ b/assets/layers/bike_repair_station/bike_repair_station.json @@ -135,6 +135,7 @@ "tagRenderings": [ "images", { + "id": "bike_repair_station-available-services", "question": { "en": "Which services are available at this bike station?", "nl": "Welke functies biedt dit fietspunt?", @@ -294,6 +295,7 @@ "id": "bike_repair_station-opening_hours" }, { + "id": "bike_repair_station-bike-chain-tool", "question": { "en": "Does this bike repair station have a special tool to repair your bike chain?", "nl": "Heeft dit herstelpunt een speciale reparatieset voor je ketting?", @@ -331,6 +333,7 @@ ] }, { + "id": "bike_repair_station-bike-stand", "question": { "en": "Does this bike station have a hook to hang your bike on or a stand to raise it?", "nl": "Heeft dit herstelpunt een haak of standaard om je fiets op te hangen/zetten?", @@ -488,7 +491,8 @@ ], "id": "bike_repair_station-valves" }, - { + { "id": "bike_repair_station-electrical_pump", + "question": { "en": "Is this an electric bike pump?", "nl": "Is dit een electrische fietspomp?", @@ -531,7 +535,7 @@ } ] }, - { + { "id": "bike_repair_station-manometer", "question": { "en": "Does the pump have a pressure indicator or manometer?", "nl": "Heeft deze pomp een luchtdrukmeter?", diff --git a/assets/layers/bike_shop/bike_shop.json b/assets/layers/bike_shop/bike_shop.json index 23c471351..571ff46e2 100644 --- a/assets/layers/bike_shop/bike_shop.json +++ b/assets/layers/bike_shop/bike_shop.json @@ -187,6 +187,7 @@ "tagRenderings": [ "images", { + "id": "bike_shop-is-bicycle_shop", "condition": { "and": [ "shop~*", @@ -301,6 +302,7 @@ "id": "bike_shop-access" }, { + "id": "bike_repair_sells-bikes", "question": { "en": "Does this shop sell bikes?", "nl": "Verkoopt deze fietszaak fietsen?", @@ -341,6 +343,7 @@ ] }, { + "id": "bike_repair_repairs-bikes", "question": { "en": "Does this shop repair bikes?", "nl": "Herstelt deze winkel fietsen?", @@ -407,6 +410,7 @@ ] }, { + "id": "bike_repair_rents-bikes", "question": { "en": "Does this shop rent out bikes?", "nl": "Verhuurt deze winkel fietsen?", @@ -447,6 +451,7 @@ ] }, { + "id": "bike_repair_second-hand-bikes", "question": { "en": "Does this shop sell second-hand bikes?", "nl": "Verkoopt deze winkel tweedehands fietsen?", @@ -496,6 +501,7 @@ ] }, { + "id": "bike_repair_bike-pump-service", "question": { "en": "Does this shop offer a bike pump for use by anyone?", "nl": "Biedt deze winkel een fietspomp aan voor iedereen?", @@ -542,6 +548,7 @@ ] }, { + "id": "bike_repair_tools-service", "question": { "en": "Are there tools here to repair your own bike?", "nl": "Biedt deze winkel gereedschap aan om je fiets zelf te herstellen?", @@ -588,6 +595,7 @@ ] }, { + "id": "bike_repair_bike-wash", "question": { "en": "Are bicycles washed here?", "nl": "Biedt deze winkel een fietsschoonmaak aan?", diff --git a/assets/layers/birdhide/birdhide.json b/assets/layers/birdhide/birdhide.json index a8c232bf5..01e2853f9 100644 --- a/assets/layers/birdhide/birdhide.json +++ b/assets/layers/birdhide/birdhide.json @@ -60,6 +60,7 @@ "tagRenderings": [ "images", { + "id": "bird-hide-shelter-or-wall", "question": { "nl": "Is dit een kijkwand of kijkhut?" }, @@ -115,6 +116,7 @@ ] }, { + "id": "bird-hide-wheelchair", "question": { "nl": "Is deze vogelkijkplaats rolstoeltoegankelijk?" }, diff --git a/assets/layers/crossings/crossings.json b/assets/layers/crossings/crossings.json index 46d3fae45..85ee0a38a 100644 --- a/assets/layers/crossings/crossings.json +++ b/assets/layers/crossings/crossings.json @@ -98,6 +98,7 @@ ], "tagRenderings": [ { + "id": "crossing-type", "question": { "en": "What kind of crossing is this?", "nl": "Wat voor oversteekplaats is dit?" @@ -129,6 +130,7 @@ ] }, { + "id": "crossing-is-zebra", "question": { "en": "Is this is a zebra crossing?", "nl": "Is dit een zebrapad?" @@ -152,6 +154,7 @@ ] }, { + "id": "crossing-bicycle-allowed", "question": { "en": "Is this crossing also for bicycles?", "nl": "Is deze oversteekplaats ook voor fietsers" @@ -175,6 +178,7 @@ ] }, { + "id": "crossing-has-island", "question": { "en": "Does this crossing have an island in the middle?", "nl": "Heeft deze oversteekplaats een verkeerseiland in het midden?" @@ -198,6 +202,7 @@ ] }, { + "id": "crossing-tactile", "question": { "en": "Does this crossing have tactile paving?", "nl": "Heeft deze oversteekplaats een geleidelijn?" @@ -229,6 +234,7 @@ ] }, { + "id": "crossing-button", "question": { "en": "Does this traffic light have a button to request green light?", "nl": "Heeft dit verkeerslicht een knop voor groen licht?" @@ -257,6 +263,7 @@ ] }, { + "id": "crossing-right-turn-through-red", "question": { "en": "Can a cyclist turn right when the light is red?", "nl": "Mag een fietser rechtsaf slaan als het licht rood is?" @@ -289,6 +296,7 @@ ] }, { + "id": "crossing-continue-through-red", "question": { "en": "Can a cyclist go straight on when the light is red?", "nl": "Mag een fietser rechtdoor gaan als het licht rood is?" diff --git a/assets/layers/cycleways_and_roads/cycleways_and_roads.json b/assets/layers/cycleways_and_roads/cycleways_and_roads.json index b622043a2..2b10d7ebc 100644 --- a/assets/layers/cycleways_and_roads/cycleways_and_roads.json +++ b/assets/layers/cycleways_and_roads/cycleways_and_roads.json @@ -672,6 +672,7 @@ "id": "width:carriageway" }, { + "id": "cycleway-lane-track-traffic-signs", "question": { "en": "What traffic sign does this cycleway have?", "nl": "Welk verkeersbord heeft dit fietspad?" @@ -733,6 +734,7 @@ ] }, { + "id": "cycleway-traffic-signs", "question": { "en": "What traffic sign does this cycleway have?", "nl": "Welk verkeersbord heeft dit fietspad?" @@ -808,6 +810,7 @@ ] }, { + "id": "cycleway-traffic-signs-supplementary", "question": { "en": "Does the traffic sign D7 () have a supplementary sign?", "nl": "Heeft het verkeersbord D7 () een onderbord?" @@ -897,6 +900,7 @@ ] }, { + "id": "cycleway-traffic-signs-D7-supplementary", "question": { "en": "Does the traffic sign D7 () have a supplementary sign?", "nl": "Heeft het verkeersbord D7 () een onderbord?" @@ -1011,6 +1015,7 @@ "id": "cycleways_and_roads-cycleway:buffer" }, { + "id": "cyclelan-segregation", "question": { "en": "How is this cycleway separated from the road?", "nl": "Hoe is dit fietspad gescheiden van de weg?" @@ -1053,6 +1058,7 @@ ] }, { + "id": "cycleway-segregation", "question": { "en": "How is this cycleway separated from the road?", "nl": "Hoe is dit fietspad gescheiden van de weg?" diff --git a/assets/layers/defibrillator/defibrillator.json b/assets/layers/defibrillator/defibrillator.json index e0e4f44a7..639020383 100644 --- a/assets/layers/defibrillator/defibrillator.json +++ b/assets/layers/defibrillator/defibrillator.json @@ -68,6 +68,7 @@ "tagRenderings": [ "images", { + "id": "defibrillator-indoors", "question": { "en": "Is this defibrillator located indoors?", "ca": "Està el desfibril·lador a l'interior?", diff --git a/assets/layers/drinking_water/drinking_water.json b/assets/layers/drinking_water/drinking_water.json index b5aac2c01..6d7820ab8 100644 --- a/assets/layers/drinking_water/drinking_water.json +++ b/assets/layers/drinking_water/drinking_water.json @@ -155,6 +155,7 @@ "id": "Bottle refill" }, { + "id": "render-closest-drinking-water", "render": { "en": "There is another drinking water fountain at {_closest_other_drinking_water_distance} meter", "nl": "Er bevindt zich een ander drinkwaterpunt op {_closest_other_drinking_water_distance} meter", diff --git a/assets/layers/food/food.json b/assets/layers/food/food.json index c606db4b3..f64472b27 100644 --- a/assets/layers/food/food.json +++ b/assets/layers/food/food.json @@ -430,6 +430,7 @@ "id": "halal (no friture)" }, { + "id": "friture-vegetarian", "question": { "nl": "Heeft deze frituur vegetarische snacks?", "fr": "Cette friterie est-elle équipée de snacks végétariens ?" @@ -460,6 +461,7 @@ "condition": "cuisine=friture" }, { + "id": "friture-vegan", "question": { "nl": "Heeft deze frituur veganistische snacks?", "fr": "Cette friterie est-elle équipée de snacks végétaliens ?" @@ -490,6 +492,7 @@ "condition": "cuisine=friture" }, { + "id": "friture-oil", "question": { "nl": "Bakt deze frituur met dierlijk vet of met plantaardige olie?", "fr": "Cette friteuse fonctionne-t-elle avec de la graisse animale ou végétale ?" @@ -513,6 +516,7 @@ "condition": "cuisine=friture" }, { + "id": "friture-take-your-container", "question": { "nl": "Als je je eigen container (bv. kookpot of kleine potjes voor saus) meeneemt, gebruikt de frituur deze dan om je bestelling in te doen?", "fr": "Est-il proposé d’utiliser ses propres contenants pour sa commande ?
", diff --git a/assets/layers/ghost_bike/ghost_bike.json b/assets/layers/ghost_bike/ghost_bike.json index 5207992b4..25a6097ef 100644 --- a/assets/layers/ghost_bike/ghost_bike.json +++ b/assets/layers/ghost_bike/ghost_bike.json @@ -78,6 +78,7 @@ ], "tagRenderings": [ { + "id": "ghost-bike-explanation", "render": { "en": "A ghost bike is a memorial for a cyclist who died in a traffic accident, in the form of a white bicycle placed permanently near the accident location.", "nl": "Een Witte Fiets (of Spookfiets) is een aandenken aan een fietser die bij een verkeersongeval om het leven kwam. Het gaat over een witgeschilderde fiets die geplaatst werd in de buurt van het ongeval.", diff --git a/assets/layers/grass_in_parks/grass_in_parks.json b/assets/layers/grass_in_parks/grass_in_parks.json index f9dcd0f23..a95d6e0eb 100644 --- a/assets/layers/grass_in_parks/grass_in_parks.json +++ b/assets/layers/grass_in_parks/grass_in_parks.json @@ -44,9 +44,11 @@ "tagRenderings": [ "images", { + "id": "explanation", "render": "Op dit grasveld in het park mag je spelen, picnicken, zitten, ..." }, { + "id": "grass-in-parks-reviews", "render": "{reviews(name, landuse=grass )}" } ] diff --git a/assets/layers/map/map.json b/assets/layers/map/map.json index 991aa1524..221bfa7ef 100644 --- a/assets/layers/map/map.json +++ b/assets/layers/map/map.json @@ -75,6 +75,7 @@ "id": "map-map_source" }, { + "id": "map-attribution", "question": { "en": "Is the OpenStreetMap-attribution given?", "nl": "Is de attributie voor OpenStreetMap aanwezig?", diff --git a/assets/layers/play_forest/play_forest.json b/assets/layers/play_forest/play_forest.json index 4be4071ee..0b1f2485e 100644 --- a/assets/layers/play_forest/play_forest.json +++ b/assets/layers/play_forest/play_forest.json @@ -55,6 +55,7 @@ "id": "play_forest-operator" }, { + "id": "play_forest-opening_hours", "question": "Wanneer is deze speelzone toegankelijk?", "mappings": [ { @@ -87,6 +88,7 @@ }, "questions", { + "id": "play_forest-reviews", "render": "{reviews(name, play_forest)}" } ], diff --git a/assets/layers/playground/playground.json b/assets/layers/playground/playground.json index 9d5cdb5b0..9e7daea5e 100644 --- a/assets/layers/playground/playground.json +++ b/assets/layers/playground/playground.json @@ -165,6 +165,7 @@ "id": "playground-surface" }, { + "id": "playground-lit", "question": { "nl": "Is deze speeltuin 's nachts verlicht?", "en": "Is this playground lit at night?", @@ -260,6 +261,7 @@ "id": "playground-operator" }, { + "id": "playground-access", "question": { "nl": "Is deze speeltuin vrij toegankelijk voor het publiek?", "en": "Is this playground accessible to the general public?", @@ -370,6 +372,7 @@ "id": "playground-phone" }, { + "id": "Playground-wheelchair", "question": { "nl": "Is deze speeltuin toegankelijk voor rolstoelgebruikers?", "en": "Is this playground accessible to wheelchair users?", @@ -464,6 +467,7 @@ }, "questions", { + "id": "playground-reviews", "render": "{reviews(name, playground)}" } ], diff --git a/assets/layers/public_bookcase/public_bookcase.json b/assets/layers/public_bookcase/public_bookcase.json index 258fff091..f00ec7874 100644 --- a/assets/layers/public_bookcase/public_bookcase.json +++ b/assets/layers/public_bookcase/public_bookcase.json @@ -82,6 +82,7 @@ "tagRenderings": [ "images", { + "id": "minimap", "render": "{minimap():height: 9rem; border-radius: 2.5rem; overflow:hidden;border:1px solid gray}" }, { @@ -149,6 +150,7 @@ "id": "public_bookcase-capacity" }, { + "id": "bookcase-booktypes", "question": { "en": "What kind of books can be found in this public bookcase?", "nl": "Voor welke doelgroep zijn de meeste boeken in dit boekenruilkastje?", @@ -194,6 +196,7 @@ ] }, { + "id": "bookcase-is-indoors", "question": { "en": "Is this bookcase located outdoors?", "nl": "Staat dit boekenruilkastje binnen of buiten?", @@ -236,6 +239,7 @@ ] }, { + "id": "bookcase-is-accessible", "question": { "en": "Is this public bookcase freely accessible?", "nl": "Is dit boekenruilkastje publiek toegankelijk?", diff --git a/assets/layers/slow_roads/slow_roads.json b/assets/layers/slow_roads/slow_roads.json index 7e3a763d5..50e7cd61d 100644 --- a/assets/layers/slow_roads/slow_roads.json +++ b/assets/layers/slow_roads/slow_roads.json @@ -67,6 +67,7 @@ "tagRenderings": [ "images", { + "id": "explanation", "mappings": [ { "if": "highway=living_street", @@ -205,6 +206,7 @@ "id": "slow_roads-surface" }, { + "id": "slow_road_is_lit", "question": "Is deze weg 's nachts verlicht?", "mappings": [ { diff --git a/assets/layers/sport_pitch/sport_pitch.json b/assets/layers/sport_pitch/sport_pitch.json index 6666ed6c9..29920a853 100644 --- a/assets/layers/sport_pitch/sport_pitch.json +++ b/assets/layers/sport_pitch/sport_pitch.json @@ -216,6 +216,7 @@ "id": "sport_pitch-surface" }, { + "id": "sport-pitch-access", "question": { "nl": "Is dit sportterrein publiek toegankelijk?", "fr": "Est-ce que ce terrain de sport est accessible au public ?", @@ -266,6 +267,7 @@ ] }, { + "id": "sport-pitch-reservation", "question": { "nl": "Moet men reserveren om gebruik te maken van dit sportveld?", "fr": "Doit-on réserver pour utiliser ce terrain de sport ?", @@ -384,7 +386,8 @@ "id": "sport_pitch-opening_hours" }, "questions", - { + { "id": "sport-pitch-reviews", + "render": "{reviews(name, sportpitch)}" } ], diff --git a/assets/layers/toilet/toilet.json b/assets/layers/toilet/toilet.json index 0b946addc..ef9260077 100644 --- a/assets/layers/toilet/toilet.json +++ b/assets/layers/toilet/toilet.json @@ -171,6 +171,7 @@ "id": "toilet-access" }, { + "id": "toilets-fee", "question": { "en": "Are these toilets free to use?", "de": "Können diese Toiletten kostenlos benutzt werden?", @@ -227,6 +228,7 @@ "id": "toilet-charge" }, { + "id": "toilets-wheelchair", "question": { "en": "Is there a dedicated toilet for wheelchair users", "de": "Gibt es eine Toilette für Rollstuhlfahrer?", @@ -259,6 +261,7 @@ ] }, { + "id": "toilets-type", "question": { "en": "Which kind of toilets are this?", "de": "Welche Art von Toiletten sind das?", @@ -311,6 +314,7 @@ ] }, { + "id": "toilets-changing-table", "question": { "en": "Is a changing table (to change diapers) available?", "de": "Ist ein Wickeltisch (zum Wechseln der Windeln) vorhanden?", diff --git a/assets/layers/trail/trail.json b/assets/layers/trail/trail.json index 4ad355a93..5cd3e7037 100644 --- a/assets/layers/trail/trail.json +++ b/assets/layers/trail/trail.json @@ -33,6 +33,7 @@ "tagRenderings": [ "images", { + "id": "trail-length", "render": { "en": "The trail is {_length:km} kilometers long", "nl": "Deze wandeling is {_length:km} kilometer lang" diff --git a/assets/layers/tree_node/tree_node.json b/assets/layers/tree_node/tree_node.json index 34be5dbad..07b30d220 100644 --- a/assets/layers/tree_node/tree_node.json +++ b/assets/layers/tree_node/tree_node.json @@ -42,6 +42,7 @@ "tagRenderings": [ "images", { + "id": "tree-height", "render": { "nl": "Hoogte: {height}", "en": "Height: {height}", @@ -72,6 +73,7 @@ ] }, { + "id": "tree-leaf_type", "question": { "nl": "Is dit een naald- of loofboom?", "en": "Is this a broadleaved or needleleaved tree?", @@ -122,6 +124,7 @@ ] }, { + "id": "tree-denotation", "question": { "nl": "Hoe significant is deze boom? Kies het eerste antwoord dat van toepassing is.", "en": "How significant is this tree? Choose the first answer that applies.", @@ -235,7 +238,7 @@ } ] }, - { + { "id": "tree-decidouous", "question": { "nl": "Is deze boom groenblijvend of bladverliezend?", "en": "Is this tree evergreen or deciduous?", @@ -328,6 +331,7 @@ "id": "tree_node-name" }, { + "id": "tree-heritage", "question": { "nl": "Is deze boom erkend als erfgoed?", "en": "Is this tree registered heritage?", diff --git a/assets/layers/village_green/village_green.json b/assets/layers/village_green/village_green.json index 96fd02f3e..9aa60fca4 100644 --- a/assets/layers/village_green/village_green.json +++ b/assets/layers/village_green/village_green.json @@ -28,9 +28,11 @@ "tagRenderings": [ "images", { + "id": "village_green-explanation", "render": "Dit is een klein stukje openbaar groen waar je mag spelen, picnicken, zitten, ..." }, { + "id": "village_green-reviews", "render": "{reviews(name, landuse=village_green )}" } ] diff --git a/assets/layers/waste_basket/waste_basket.json b/assets/layers/waste_basket/waste_basket.json index 8561f5c60..1cd888dcd 100644 --- a/assets/layers/waste_basket/waste_basket.json +++ b/assets/layers/waste_basket/waste_basket.json @@ -24,6 +24,7 @@ }, "tagRenderings": [ { + "id": "waste-basket-waste-types", "question": { "en": "What kind of waste basket is this?", "nl": "Wat voor soort vuilnisbak is dit?" diff --git a/assets/themes/grb.json b/assets/themes/grb.json index 37efacae0..c1c232985 100644 --- a/assets/themes/grb.json +++ b/assets/themes/grb.json @@ -61,6 +61,7 @@ }, "tagRenderings": [ { + "id": "grb-housenumber", "render": { "nl": "Het huisnummer is {addr:housenumber}" }, @@ -112,6 +113,7 @@ ] }, { + "id": "grb-unit", "question": "Wat is de wooneenheid-aanduiding?", "render": { "nl": "De wooneenheid-aanduiding is {addr:unit} " @@ -127,6 +129,7 @@ ] }, { + "id": "grb-street", "render": { "nl": "De straat is {addr:street}" }, @@ -138,6 +141,7 @@ } }, { + "id": "grb-fixme", "render": { "nl": "De fixme is {fixme}" }, @@ -161,6 +165,7 @@ ] }, { + "id": "grb-min-level", "render": { "nl": "Dit gebouw begint maar op de {building:min_level} verdieping" }, diff --git a/assets/themes/hailhydrant/hailhydrant.json b/assets/themes/hailhydrant/hailhydrant.json index c5cdd3795..d3c165c44 100644 --- a/assets/themes/hailhydrant/hailhydrant.json +++ b/assets/themes/hailhydrant/hailhydrant.json @@ -76,6 +76,7 @@ }, "tagRenderings": [ { + "id": "hydrant-color", "question": { "en": "What color is the hydrant?", "ja": "消火栓の色は何色ですか?", @@ -138,6 +139,7 @@ ] }, { + "id": "hydrant-type", "question": { "en": "What type of hydrant is it?", "ja": "どんな消火栓なんですか?", @@ -224,6 +226,7 @@ ] }, { + "id": "hydrant-state", "question": { "en": "Update the lifecycle status of the hydrant.", "ja": "消火栓のライフサイクルステータスを更新します。", @@ -351,6 +354,7 @@ }, "tagRenderings": [ { + "id": "extinguisher-location", "render": { "en": "Location: {location}", "ja": "場所:{location}", @@ -469,6 +473,7 @@ }, "tagRenderings": [ { + "id": "station-name", "freeform": { "key": "name" }, @@ -488,6 +493,7 @@ } }, { + "id": "station-street", "freeform": { "key": "addr:street" }, @@ -506,6 +512,7 @@ } }, { + "id": "station-place", "question": { "en": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", "ja": "このステーションの住所は?(例: 地区、村、または町の名称)", @@ -523,6 +530,7 @@ } }, { + "id": "station-agency", "question": { "en": "What agency operates this station?", "ja": "このステーションを運営しているのはどこですか?", @@ -553,6 +561,7 @@ ] }, { + "id": "station-operator", "question": { "en": "How is the station operator classified?", "ja": "ステーションの運営の分類は?", @@ -681,6 +690,7 @@ }, "tagRenderings": [ { + "id": "ambulance-name", "freeform": { "key": "name" }, @@ -698,6 +708,7 @@ } }, { + "id": "ambulance-street", "freeform": { "key": "addr:street" }, @@ -715,6 +726,7 @@ } }, { + "id": "ambulance-place", "question": { "en": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", "ja": "このステーションの住所は?(例: 地区、村、または町の名称)", @@ -731,6 +743,7 @@ } }, { + "id": "ambulance-agency", "question": { "en": "What agency operates this station?", "ja": "このステーションを運営しているのはどこですか?", @@ -747,6 +760,7 @@ "mappings": [] }, { + "id": "ambulance-operator-type", "question": { "en": "How is the station operator classified?", "ja": "ステーションの運営の分類は?", diff --git a/scripts/lint.ts b/scripts/lint.ts index f1e67ec68..afa33e29f 100644 --- a/scripts/lint.ts +++ b/scripts/lint.ts @@ -8,23 +8,39 @@ import ScriptUtils from "./ScriptUtils"; import {readFileSync, writeFileSync} from "fs"; import {tag} from "@turf/turf"; +import {LayerConfigJson} from "../Models/ThemeConfig/Json/LayerConfigJson"; -const layerFiles = ScriptUtils.getLayerFiles(); -for (const layerFile of layerFiles) { - console.log("Handling ", layerFile.path) - - for (const tagRendering of layerFile.parsed.tagRenderings) { +/** + * In place fix + */ +function fixLayerConfig(config: LayerConfigJson) : void{ + for (const tagRendering of config.tagRenderings) { if(tagRendering["#"] !== undefined){ tagRendering["id"] = tagRendering["#"] delete tagRendering["#"] } if(tagRendering["id"] === undefined){ if(tagRendering["freeform"]?.key !== undefined ) { - tagRendering["id"] = layerFile.parsed.id+"-"+tagRendering["freeform"]["key"] + tagRendering["id"] = config.id+"-"+tagRendering["freeform"]["key"] } } } - - +} + +const layerFiles = ScriptUtils.getLayerFiles(); +for (const layerFile of layerFiles) { + fixLayerConfig(layerFile.parsed) writeFileSync(layerFile.path, JSON.stringify(layerFile.parsed, null, " ")) +} + +const themeFiles = ScriptUtils.getThemeFiles() +for (const themeFile of themeFiles) { + for (const layerConfig of themeFile.parsed.layers) { + if(typeof layerConfig === "string" || layerConfig["builtin"]!== undefined){ + continue + } + // @ts-ignore + fixLayerConfig(layerConfig) + } + writeFileSync(themeFile.path, JSON.stringify(themeFile.parsed, null, " ")) } \ No newline at end of file From 39166ff806224590498d49b3711836613a5e4abe Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 19:58:11 +0200 Subject: [PATCH 21/65] Linting of layer files --- .../layers/bike_repair_station/bike_repair_station.json | 7 ++++--- assets/layers/sport_pitch/sport_pitch.json | 4 ++-- assets/layers/tree_node/tree_node.json | 3 ++- scripts/lint.ts | 9 +++++---- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/assets/layers/bike_repair_station/bike_repair_station.json b/assets/layers/bike_repair_station/bike_repair_station.json index 5cef73ea7..cd202c6c8 100644 --- a/assets/layers/bike_repair_station/bike_repair_station.json +++ b/assets/layers/bike_repair_station/bike_repair_station.json @@ -491,8 +491,8 @@ ], "id": "bike_repair_station-valves" }, - { "id": "bike_repair_station-electrical_pump", - + { + "id": "bike_repair_station-electrical_pump", "question": { "en": "Is this an electric bike pump?", "nl": "Is dit een electrische fietspomp?", @@ -535,7 +535,8 @@ } ] }, - { "id": "bike_repair_station-manometer", + { + "id": "bike_repair_station-manometer", "question": { "en": "Does the pump have a pressure indicator or manometer?", "nl": "Heeft deze pomp een luchtdrukmeter?", diff --git a/assets/layers/sport_pitch/sport_pitch.json b/assets/layers/sport_pitch/sport_pitch.json index 29920a853..90f1dca73 100644 --- a/assets/layers/sport_pitch/sport_pitch.json +++ b/assets/layers/sport_pitch/sport_pitch.json @@ -386,8 +386,8 @@ "id": "sport_pitch-opening_hours" }, "questions", - { "id": "sport-pitch-reviews", - + { + "id": "sport-pitch-reviews", "render": "{reviews(name, sportpitch)}" } ], diff --git a/assets/layers/tree_node/tree_node.json b/assets/layers/tree_node/tree_node.json index 07b30d220..bba09af12 100644 --- a/assets/layers/tree_node/tree_node.json +++ b/assets/layers/tree_node/tree_node.json @@ -238,7 +238,8 @@ } ] }, - { "id": "tree-decidouous", + { + "id": "tree-decidouous", "question": { "nl": "Is deze boom groenblijvend of bladverliezend?", "en": "Is this tree evergreen or deciduous?", diff --git a/scripts/lint.ts b/scripts/lint.ts index afa33e29f..63cf1ab2f 100644 --- a/scripts/lint.ts +++ b/scripts/lint.ts @@ -32,15 +32,16 @@ for (const layerFile of layerFiles) { fixLayerConfig(layerFile.parsed) writeFileSync(layerFile.path, JSON.stringify(layerFile.parsed, null, " ")) } - +/* const themeFiles = ScriptUtils.getThemeFiles() for (const themeFile of themeFiles) { - for (const layerConfig of themeFile.parsed.layers) { + for (const layerConfig of themeFile.parsed.layers ?? []) { if(typeof layerConfig === "string" || layerConfig["builtin"]!== undefined){ continue } // @ts-ignore fixLayerConfig(layerConfig) } - writeFileSync(themeFile.path, JSON.stringify(themeFile.parsed, null, " ")) -} \ No newline at end of file + // writeFileSync(themeFile.path, JSON.stringify(themeFile.parsed, null, " ")) +} +//*/ \ No newline at end of file From 0ca19a5a03f7fe3b653e33f9fe06b528f0dae3a1 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 19:59:51 +0200 Subject: [PATCH 22/65] Add ids to layers in themes --- assets/themes/artwork/artwork.json | 12 ++-- assets/themes/campersite/campersite.json | 21 ++++--- assets/themes/climbing/climbing.json | 55 ++++++++++--------- .../themes/cycle_highways/cycle_highways.json | 9 ++- .../themes/facadegardens/facadegardens.json | 9 ++- assets/themes/fruit_trees/fruit_trees.json | 12 ++-- assets/themes/hackerspaces/hackerspaces.json | 9 ++- assets/themes/shops/shops.json | 18 ++++-- assets/themes/speelplekken/speelplekken.json | 2 +- scripts/lint.ts | 8 ++- 10 files changed, 95 insertions(+), 60 deletions(-) diff --git a/assets/themes/artwork/artwork.json b/assets/themes/artwork/artwork.json index c02fc72fe..c03d7c023 100644 --- a/assets/themes/artwork/artwork.json +++ b/assets/themes/artwork/artwork.json @@ -342,7 +342,8 @@ "nb_NO": "Flisarbeid" } } - ] + ], + "id": "artwork-artwork_type" }, { "question": { @@ -369,7 +370,8 @@ }, "freeform": { "key": "artist_name" - } + }, + "id": "artwork-artist_name" }, { "question": { @@ -398,7 +400,8 @@ "freeform": { "key": "website", "type": "url" - } + }, + "id": "artwork-website" }, { "question": { @@ -426,7 +429,8 @@ "freeform": { "key": "wikidata", "type": "wikidata" - } + }, + "id": "artwork-wikidata" } ] } diff --git a/assets/themes/campersite/campersite.json b/assets/themes/campersite/campersite.json index 7b24124e5..566bb2e00 100644 --- a/assets/themes/campersite/campersite.json +++ b/assets/themes/campersite/campersite.json @@ -138,7 +138,8 @@ }, "freeform": { "key": "name" - } + }, + "id": "caravansites-name" }, { "question": { @@ -226,7 +227,8 @@ "and": [ "fee=yes" ] - } + }, + "id": "caravansites-charge" }, { "question": { @@ -295,7 +297,8 @@ "freeform": { "key": "capacity", "type": "pnat" - } + }, + "id": "caravansites-capacity" }, { "question": { @@ -491,7 +494,8 @@ "zh_Hant": "這個地方有網站嗎?", "fr": "Ce lieu a-t’il un site internet ?", "pt_BR": "Este lugar tem um website?" - } + }, + "id": "caravansites-website" }, { "question": { @@ -575,7 +579,8 @@ "freeform": { "key": "description", "type": "text" - } + }, + "id": "caravansites-description" }, "questions", "reviews" @@ -749,7 +754,8 @@ "and": [ "fee=yes" ] - } + }, + "id": "dumpstations-charge" }, { "question": { @@ -957,7 +963,8 @@ }, "freeform": { "key": "network" - } + }, + "id": "dumpstations-network" } ], "icon": { diff --git a/assets/themes/climbing/climbing.json b/assets/themes/climbing/climbing.json index 44a2520db..16765d8cb 100644 --- a/assets/themes/climbing/climbing.json +++ b/assets/themes/climbing/climbing.json @@ -138,7 +138,8 @@ }, "freeform": { "key": "name" - } + }, + "id": "climbing_club-name" }, { "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" @@ -268,7 +269,6 @@ "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" }, { - "#": "name", "render": { "en": "{name}", "nl": "{name}", @@ -288,7 +288,8 @@ }, "freeform": { "key": "name" - } + }, + "id": "name" }, "website", "phone", @@ -361,7 +362,6 @@ "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" }, { - "#": "Name", "render": { "en": "{name}", "nl": "{name}", @@ -401,10 +401,10 @@ "fr": "Cette voie n’a pas de nom" } } - ] + ], + "id": "Name" }, { - "#": "Length", "question": { "en": "How long is this climbing route (in meters)?", "nl": "Hoe lang is deze klimroute (in meters)?", @@ -423,10 +423,10 @@ "freeform": { "key": "climbing:length", "type": "pnat" - } + }, + "id": "Length" }, { - "#": "Difficulty", "question": { "en": "What is the difficulty of this climbing route according to the french/belgian system?", "nl": "Hoe moeilijk is deze klimroute volgens het Franse/Belgische systeem?", @@ -443,10 +443,10 @@ }, "freeform": { "key": "climbing:grade:french" - } + }, + "id": "Difficulty" }, { - "#": "Bolts", "question": { "en": "How much bolts does this route have before reaching the moulinette?", "fr": "Combien de prises cette voie possède avant d’atteindre la moulinette ?" @@ -478,25 +478,26 @@ "fr": "Cette voie n’a pas de prises" } } - ] + ], + "id": "Bolts" }, { - "#": "Description", "question": "Is there other relevant info?", "render": "

Description


{description}", "freeform": { "key": "description" - } + }, + "id": "Description" }, { - "#": "Rock type", "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" }, "freeform": { "key": "_embedding_features_with_rock:rock" - } + }, + "id": "Rock type" }, "reviews" ], @@ -621,31 +622,30 @@ "render": "{minimap(18, id, _contained_climbing_route_ids): height: 9rem; overflow: hidden; border-radius:3rem; }" }, { - "#": "Contained routes length hist", "render": { "en": "

Length overview

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

Résumé de longueur

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

Difficulties overview

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

Résumé des difficultés

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

Contains {_contained_climbing_routes_count} routes

    {_contained_climbing_routes}
", "fr": "

Contient {_contained_climbing_routes_count} voies

    {_contained_climbing_routes}
" }, - "condition": "_contained_climbing_routes~*" + "condition": "_contained_climbing_routes~*", + "id": "Containe {_contained_climbing_routes_count} routes" }, { - "#": "name", "render": { "en": "{name}", "nl": "{name}", @@ -682,10 +682,10 @@ "fr": "Ce site n’a pas de nom" } } - ] + ], + "id": "name" }, { - "#": "Type", "question": "What kind of climbing opportunity is this?", "mappings": [ { @@ -706,10 +706,10 @@ "if": "climbing=area", "then": "A climbing area with one or more climbing crags and/or boulders" } - ] + ], + "id": "Type" }, { - "#": "Rock type (crag/rock/cliff only)", "question": { "en": "What is the rock type here?", "fr": "Quel est le type de roche ?" @@ -737,7 +737,8 @@ "natural=cliff", "natural=bare_rock" ] - } + }, + "id": "Rock type (crag/rock/cliff only)" }, "reviews" ], diff --git a/assets/themes/cycle_highways/cycle_highways.json b/assets/themes/cycle_highways/cycle_highways.json index 85a91aa7d..d31bb7322 100644 --- a/assets/themes/cycle_highways/cycle_highways.json +++ b/assets/themes/cycle_highways/cycle_highways.json @@ -33,14 +33,16 @@ "question": "What is the name of this cycle highway?", "freeform": { "key": "name" - } + }, + "id": "cycle_highways-name" }, { "render": "Referentienummer is {ref}", "question": "What is the reference number of this cycle highway?", "freeform": { "key": "ref" - } + }, + "id": "cycle_highways-ref" }, { "render": "The current state of this link is {state}", @@ -84,7 +86,8 @@ "if": "state=", "then": "This link is operational and signposted" } - ] + ], + "id": "cycle_highways-state" }, { "render": "This part is {_length:km}km long" diff --git a/assets/themes/facadegardens/facadegardens.json b/assets/themes/facadegardens/facadegardens.json index f3e28a1ef..7fd95f76e 100644 --- a/assets/themes/facadegardens/facadegardens.json +++ b/assets/themes/facadegardens/facadegardens.json @@ -125,7 +125,8 @@ "freeform": { "type": "direction", "key": "direction" - } + }, + "id": "facadegardens-direction" }, { "mappings": [ @@ -241,7 +242,8 @@ "freeform": { "key": "start_date", "type": "text" - } + }, + "id": "facadegardens-start_date" }, { "mappings": [ @@ -355,7 +357,8 @@ "freeform": { "key": "description", "type": "text" - } + }, + "id": "facadegardens-description" } ], "icon": { diff --git a/assets/themes/fruit_trees/fruit_trees.json b/assets/themes/fruit_trees/fruit_trees.json index 60d6e8a23..f5c18a0ba 100644 --- a/assets/themes/fruit_trees/fruit_trees.json +++ b/assets/themes/fruit_trees/fruit_trees.json @@ -101,7 +101,8 @@ }, "freeform": { "key": "species:nl" - } + }, + "id": "fruitboom-species:nl" }, { "render": { @@ -117,7 +118,8 @@ "and": [ "species:nl~*" ] - } + }, + "id": "fruitboom-taxon" }, { "render": { @@ -128,7 +130,8 @@ }, "freeform": { "key": "description" - } + }, + "id": "fruitboom-description" }, { "render": { @@ -139,7 +142,8 @@ }, "freeform": { "key": "ref" - } + }, + "id": "fruitboom-ref" } ], "icon": { diff --git a/assets/themes/hackerspaces/hackerspaces.json b/assets/themes/hackerspaces/hackerspaces.json index 538bc0414..515205202 100644 --- a/assets/themes/hackerspaces/hackerspaces.json +++ b/assets/themes/hackerspaces/hackerspaces.json @@ -76,7 +76,8 @@ }, "freeform": { "key": "name" - } + }, + "id": "hackerspaces-name" }, "website", "email", @@ -103,7 +104,8 @@ "en": "Opened 24/7" } } - ] + ], + "id": "hackerspaces-opening_hours" }, "wheelchair-access", { @@ -143,7 +145,8 @@ "freeform": { "key": "start_date", "type": "date" - } + }, + "id": "hackerspaces-start_date" } ], "icon": { diff --git a/assets/themes/shops/shops.json b/assets/themes/shops/shops.json index 09209f3f4..e2db84ab7 100644 --- a/assets/themes/shops/shops.json +++ b/assets/themes/shops/shops.json @@ -111,7 +111,8 @@ "render": "This shop is called {name}", "freeform": { "key": "name" - } + }, + "id": "shops-name" }, { "render": { @@ -220,7 +221,8 @@ "ja": "自動車ディーラー" } } - ] + ], + "id": "shops-shop" }, { "render": { @@ -241,7 +243,8 @@ "freeform": { "key": "phone", "type": "phone" - } + }, + "id": "shops-phone" }, { "render": { @@ -262,7 +265,8 @@ "freeform": { "key": "website", "type": "url" - } + }, + "id": "shops-website" }, { "render": { @@ -282,7 +286,8 @@ "freeform": { "key": "email", "type": "email" - } + }, + "id": "shops-email" }, { "render": { @@ -301,7 +306,8 @@ "freeform": { "key": "opening_hours", "type": "opening_hours" - } + }, + "id": "shops-opening_hours" }, "questions", "reviews" diff --git a/assets/themes/speelplekken/speelplekken.json b/assets/themes/speelplekken/speelplekken.json index 3ad9693d7..5f9859bfe 100644 --- a/assets/themes/speelplekken/speelplekken.json +++ b/assets/themes/speelplekken/speelplekken.json @@ -172,7 +172,7 @@ } }, { - "id":"walk-type", + "id": "walk-type", "mappings": [ { "if": "route=iwn", diff --git a/scripts/lint.ts b/scripts/lint.ts index 63cf1ab2f..a4f3902a6 100644 --- a/scripts/lint.ts +++ b/scripts/lint.ts @@ -14,6 +14,10 @@ import {LayerConfigJson} from "../Models/ThemeConfig/Json/LayerConfigJson"; * In place fix */ function fixLayerConfig(config: LayerConfigJson) : void{ + if(config.tagRenderings === undefined){ + return + } + for (const tagRendering of config.tagRenderings) { if(tagRendering["#"] !== undefined){ tagRendering["id"] = tagRendering["#"] @@ -32,7 +36,7 @@ for (const layerFile of layerFiles) { fixLayerConfig(layerFile.parsed) writeFileSync(layerFile.path, JSON.stringify(layerFile.parsed, null, " ")) } -/* + const themeFiles = ScriptUtils.getThemeFiles() for (const themeFile of themeFiles) { for (const layerConfig of themeFile.parsed.layers ?? []) { @@ -42,6 +46,6 @@ for (const themeFile of themeFiles) { // @ts-ignore fixLayerConfig(layerConfig) } - // writeFileSync(themeFile.path, JSON.stringify(themeFile.parsed, null, " ")) + writeFileSync(themeFile.path, JSON.stringify(themeFile.parsed, null, " ")) } //*/ \ No newline at end of file From d65257b2c5c8e58e0aa8a4faec1cd512c1aa02bd Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 20:08:40 +0200 Subject: [PATCH 23/65] Add last missing ids --- Models/Constants.ts | 2 +- Models/ThemeConfig/LayerConfig.ts | 4 ++-- assets/themes/campersite/campersite.json | 11 +++++++++++ assets/themes/climbing/climbing.json | 7 +++++++ assets/themes/cycle_highways/cycle_highways.json | 5 ++--- assets/themes/facadegardens/facadegardens.json | 4 ++++ assets/themes/hackerspaces/hackerspaces.json | 4 +++- assets/themes/speelplekken/speelplekken.json | 2 ++ 8 files changed, 32 insertions(+), 7 deletions(-) diff --git a/Models/Constants.ts b/Models/Constants.ts index ec3fd96e6..7c8dacb48 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.9.13"; + public static vNumber = "0.9.14"; // The user journey states thresholds when a new feature gets unlocked public static userJourney = { diff --git a/Models/ThemeConfig/LayerConfig.ts b/Models/ThemeConfig/LayerConfig.ts index 410c8b5ad..371cd1b80 100644 --- a/Models/ThemeConfig/LayerConfig.ts +++ b/Models/ThemeConfig/LayerConfig.ts @@ -276,9 +276,9 @@ export default class LayerConfig { this.tagRenderings = trs(json.tagRenderings, false); - const missingIds = json.tagRenderings.filter(tr => typeof tr !== "string" && tr["builtin"] === undefined && tr["id"] === undefined); + const missingIds = json.tagRenderings?.filter(tr => typeof tr !== "string" && tr["builtin"] === undefined && tr["id"] === undefined) ?? []; - if(missingIds.length > 0){ + if(missingIds.length > 0 && official){ console.error("Some tagRenderings of", this.id, "are missing an id:", missingIds) throw "Missing ids in tagrenderings" } diff --git a/assets/themes/campersite/campersite.json b/assets/themes/campersite/campersite.json index 566bb2e00..d5730d2aa 100644 --- a/assets/themes/campersite/campersite.json +++ b/assets/themes/campersite/campersite.json @@ -142,6 +142,7 @@ "id": "caravansites-name" }, { + "id": "caravansites-fee", "question": { "en": "Does this place charge a fee?", "it": "Ha una tariffa questo luogo?", @@ -231,6 +232,7 @@ "id": "caravansites-charge" }, { + "id": "caravansites-sanitary-dump", "question": { "en": "Does this place have a sanitary dump station?", "it": "Questo luogo ha una stazione per lo scarico delle acque?", @@ -301,6 +303,7 @@ "id": "caravansites-capacity" }, { + "id": "caravansites-internet", "question": { "en": "Does this place provide internet access?", "id": "Tempat ini berbagi akses Web?", @@ -368,6 +371,7 @@ ] }, { + "id": "caravansites-internet-fee", "question": { "en": "Do you have to pay for the internet access?", "it": "Occorre pagare per avere l’accesso a internet?", @@ -418,6 +422,7 @@ } }, { + "id": "caravansites-toilets", "question": { "en": "Does this place have toilets?", "it": "Questo luogo dispone di servizi igienici?", @@ -498,6 +503,7 @@ "id": "caravansites-website" }, { + "id": "caravansites-long-term", "question": { "en": "Does this place offer spots for long term rental?", "ru": "Предлагает ли эта площадка места для долгосрочной аренды?", @@ -689,6 +695,7 @@ "tagRenderings": [ "images", { + "id": "dumpstations-fee", "question": { "en": "Does this place charge a fee?", "ru": "Взимается ли в этом месте плата?", @@ -758,6 +765,7 @@ "id": "dumpstations-charge" }, { + "id": "dumpstations-waterpoint", "question": { "en": "Does this place have a water point?", "ru": "Есть ли в этом месте водоснабжение?", @@ -800,6 +808,7 @@ ] }, { + "id": "dumpstations-grey-water", "question": { "en": "Can you dispose of grey water here?", "ru": "Можно ли здесь утилизировать серую воду?", @@ -839,6 +848,7 @@ ] }, { + "id": "dumpstations-chemical-waste", "question": { "en": "Can you dispose of chemical toilet waste here?", "ru": "Можно ли здесь утилизировать отходы химических туалетов?", @@ -881,6 +891,7 @@ ] }, { + "id": "dumpstations-access", "question": { "en": "Who can use this dump station?", "ja": "このゴミ捨て場は誰が使えるんですか?", diff --git a/assets/themes/climbing/climbing.json b/assets/themes/climbing/climbing.json index 16765d8cb..08885ebf0 100644 --- a/assets/themes/climbing/climbing.json +++ b/assets/themes/climbing/climbing.json @@ -142,6 +142,7 @@ "id": "climbing_club-name" }, { + "id": "minimap", "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" }, "website", @@ -266,6 +267,7 @@ "images", "questions", { + "id": "minimap", "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" }, { @@ -359,6 +361,7 @@ "images", "questions", { + "id": "minimap", "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" }, { @@ -619,6 +622,7 @@ "images", "questions", { + "id": "minimap", "render": "{minimap(18, id, _contained_climbing_route_ids): height: 9rem; overflow: hidden; border-radius:3rem; }" }, { @@ -835,9 +839,11 @@ }, "tagRenderings": [ { + "id": "minimap", "render": "{minimap(18): height: 5rem; overflow: hidden; border-radius:3rem; }" }, { + "id": "climbing-opportunity-name", "render": { "en": "{name}", "de": "{name}", @@ -851,6 +857,7 @@ "condition": "name~*" }, { + "id": "climbing-possible", "question": { "en": "Is climbing possible here?", "de": "Kann hier geklettert werden?", diff --git a/assets/themes/cycle_highways/cycle_highways.json b/assets/themes/cycle_highways/cycle_highways.json index d31bb7322..180b028c1 100644 --- a/assets/themes/cycle_highways/cycle_highways.json +++ b/assets/themes/cycle_highways/cycle_highways.json @@ -90,12 +90,11 @@ "id": "cycle_highways-state" }, { + "id": "cycle-highway-length", "render": "This part is {_length:km}km long" }, "website", - { - "render": "{all_tags()}" - } + "all_tags" ], "name": { "en": "cycle highways" diff --git a/assets/themes/facadegardens/facadegardens.json b/assets/themes/facadegardens/facadegardens.json index 7fd95f76e..34c574f5c 100644 --- a/assets/themes/facadegardens/facadegardens.json +++ b/assets/themes/facadegardens/facadegardens.json @@ -129,6 +129,7 @@ "id": "facadegardens-direction" }, { + "id": "facadegardens-sunshine", "mappings": [ { "if": { @@ -184,6 +185,7 @@ } }, { + "id": "facadegardens-rainbarrel", "question": { "nl": "Is er een regenton voorzien bij het tuintje?", "en": "Is there a water barrel installed for the garden?", @@ -246,6 +248,7 @@ "id": "facadegardens-start_date" }, { + "id": "facadegardens-edible", "mappings": [ { "if": { @@ -285,6 +288,7 @@ } }, { + "id": "facadegardens-plants", "question": { "nl": "Wat voor planten staan hier?", "en": "What kinds of plants grow here?", diff --git a/assets/themes/hackerspaces/hackerspaces.json b/assets/themes/hackerspaces/hackerspaces.json index 515205202..051742429 100644 --- a/assets/themes/hackerspaces/hackerspaces.json +++ b/assets/themes/hackerspaces/hackerspaces.json @@ -49,6 +49,7 @@ }, "tagRenderings": [ { + "id": "is_makerspace", "question": { "en": "Is this a hackerspace or a makerspace?" }, @@ -109,6 +110,7 @@ }, "wheelchair-access", { + "id": "hs-club-mate", "question": { "en": "Does this hackerspace serve Club Mate?" }, @@ -130,7 +132,7 @@ ] }, "then": { - "en": "This hackerspace is not worthy of the name hackerspace as it does not serve club mate" + "en": "This hackerspace does not serve club mate" } } ] diff --git a/assets/themes/speelplekken/speelplekken.json b/assets/themes/speelplekken/speelplekken.json index 5f9859bfe..1c669b6b5 100644 --- a/assets/themes/speelplekken/speelplekken.json +++ b/assets/themes/speelplekken/speelplekken.json @@ -262,10 +262,12 @@ "overrideAll": { "+tagRenderings": [ { + "id": "part-of-walk", "render": "Maakt deel uit van {_part_of_walking_routes}", "condition": "_part_of_walking_routes~*" }, { + "id": "has-video", "freeform": { "key": "_video:id" }, From a7d107ba63cda5c4e6997d785c5fb6fbaf37cb11 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 20:15:25 +0200 Subject: [PATCH 24/65] Reset of translations: dropped deleted theme translations --- langs/layers/de.json | 13 ------- langs/layers/en.json | 14 -------- langs/layers/fr.json | 14 -------- langs/layers/it.json | 14 -------- langs/layers/nl.json | 14 -------- langs/layers/pl.json | 12 ------- langs/layers/pt_BR.json | 14 -------- langs/layers/ru.json | 3 -- langs/layers/zh_Hant.json | 14 -------- langs/themes/en.json | 7 +--- langs/themes/fr.json | 5 --- langs/themes/it.json | 5 --- langs/themes/ja.json | 5 --- langs/themes/nl.json | 64 --------------------------------- langs/themes/pt_BR.json | 5 --- langs/themes/ru.json | 5 --- langs/themes/zh_Hant.json | 5 --- scripts/generateTranslations.ts | 36 ++++++++++++++++--- 18 files changed, 33 insertions(+), 216 deletions(-) diff --git a/langs/layers/de.json b/langs/layers/de.json index 0f91d9343..372ba5de9 100644 --- a/langs/layers/de.json +++ b/langs/layers/de.json @@ -252,19 +252,6 @@ "render": "Fahrrad-Reinigungsdienst" } }, - "bike_monitoring_station": { - "title": { - "mappings": { - "0": { - "then": "Fahrradzählstation {name}" - }, - "1": { - "then": "Fahrradzählstation {ref}" - } - }, - "render": "Fahrradzählstation" - } - }, "bike_parking": { "name": "Fahrrad-Parkplätze", "presets": { diff --git a/langs/layers/en.json b/langs/layers/en.json index ee83b328d..4ca798feb 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -360,20 +360,6 @@ "render": "Bike cleaning service" } }, - "bike_monitoring_station": { - "name": "Monitoring stations", - "title": { - "mappings": { - "0": { - "then": "Bicycle counting station {name}" - }, - "1": { - "then": "Bicycle counting station {ref}" - } - }, - "render": "Bicycle counting station" - } - }, "bike_parking": { "name": "Bike parking", "presets": { diff --git a/langs/layers/fr.json b/langs/layers/fr.json index 2c27049e9..44567b29c 100644 --- a/langs/layers/fr.json +++ b/langs/layers/fr.json @@ -269,20 +269,6 @@ "render": "Service de nettoyage de vélo" } }, - "bike_monitoring_station": { - "name": "Stations de contrôle", - "title": { - "mappings": { - "0": { - "then": "Station de comptage de vélo {name}" - }, - "1": { - "then": "Station de comptage de vélo {ref}" - } - }, - "render": "Station de comptage de vélo" - } - }, "bike_parking": { "name": "Parking à vélo", "presets": { diff --git a/langs/layers/it.json b/langs/layers/it.json index ffab4fe5d..4b714e5c9 100644 --- a/langs/layers/it.json +++ b/langs/layers/it.json @@ -269,20 +269,6 @@ "render": "Servizio lavaggio bici" } }, - "bike_monitoring_station": { - "name": "Stazioni di monitoraggio", - "title": { - "mappings": { - "0": { - "then": "Contabiciclette {name}" - }, - "1": { - "then": "Contabiciclette {ref}" - } - }, - "render": "Contabiciclette" - } - }, "bike_parking": { "name": "Parcheggio bici", "presets": { diff --git a/langs/layers/nl.json b/langs/layers/nl.json index c4ec78ae7..e7c5886e9 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -359,20 +359,6 @@ "render": "Fietsschoonmaakpunt" } }, - "bike_monitoring_station": { - "name": "Telstation", - "title": { - "mappings": { - "0": { - "then": "Fietstelstation {name}" - }, - "1": { - "then": "Fietstelstation {ref}" - } - }, - "render": "Fietstelstation" - } - }, "bike_parking": { "name": "Fietsparking", "presets": { diff --git a/langs/layers/pl.json b/langs/layers/pl.json index 682a45333..302194fd9 100644 --- a/langs/layers/pl.json +++ b/langs/layers/pl.json @@ -110,18 +110,6 @@ "bicycle_library": { "description": "Obiekt, w którym rowery można wypożyczyć na dłuższy okres" }, - "bike_monitoring_station": { - "title": { - "mappings": { - "0": { - "then": "Stacja liczenia rowerów {name}" - }, - "1": { - "then": "Stacja liczenia rowerów {ref}" - } - } - } - }, "bike_parking": { "name": "Parking dla rowerów", "presets": { diff --git a/langs/layers/pt_BR.json b/langs/layers/pt_BR.json index 835527f4b..1c8e1de2a 100644 --- a/langs/layers/pt_BR.json +++ b/langs/layers/pt_BR.json @@ -254,20 +254,6 @@ "render": "Serviço de limpeza de bicicletas" } }, - "bike_monitoring_station": { - "name": "Estações de monitoramento", - "title": { - "mappings": { - "0": { - "then": "Estação de contagem de bicicletas {name}" - }, - "1": { - "then": "Estação de contagem de bicicletas {ref}" - } - }, - "render": "Estação de contagem de bicicletas" - } - }, "bike_parking": { "name": "Estacionamento de bicicletas", "presets": { diff --git a/langs/layers/ru.json b/langs/layers/ru.json index 1ac38e5af..770366020 100644 --- a/langs/layers/ru.json +++ b/langs/layers/ru.json @@ -253,9 +253,6 @@ "render": "Велосипедное кафе" } }, - "bike_monitoring_station": { - "name": "Станции мониторинга" - }, "bike_parking": { "name": "Велопарковка", "presets": { diff --git a/langs/layers/zh_Hant.json b/langs/layers/zh_Hant.json index 7a04e7f13..7591ee2dd 100644 --- a/langs/layers/zh_Hant.json +++ b/langs/layers/zh_Hant.json @@ -269,20 +269,6 @@ "render": "單車清理服務" } }, - "bike_monitoring_station": { - "name": "監視站", - "title": { - "mappings": { - "0": { - "then": "單車計數站 {name}" - }, - "1": { - "then": "單車計數站 {ref}" - } - }, - "render": "單車計數站" - } - }, "bike_parking": { "name": "單車停車場", "presets": { diff --git a/langs/themes/en.json b/langs/themes/en.json index 2a8c449cd..b1e565d3a 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -91,11 +91,6 @@ "description": "A bicycle library is a place where bicycles can be lent, often for a small yearly fee. A notable use case are bicycle libraries for kids, which allows them to change for a bigger bike when they've outgrown their current bike", "title": "Bicycle libraries" }, - "bike_monitoring_stations": { - "description": "This theme shows bike monitoring stations with live data", - "shortDescription": "Bike monitoring stations with live data from Brussels Mobility", - "title": "Bike Monitoring stations" - }, "binoculars": { "description": "A map with binoculars fixed in place with a pole. It can typically be found on touristic locations, viewpoints, on top of panoramic towers or occasionally on a nature reserve.", "shortDescription": "A map with fixed binoculars", @@ -905,7 +900,7 @@ "then": "This hackerspace serves club mate" }, "1": { - "then": "This hackerspace is not worthy of the name hackerspace as it does not serve club mate" + "then": "This hackerspace does not serve club mate" } }, "question": "Does this hackerspace serve Club Mate?" diff --git a/langs/themes/fr.json b/langs/themes/fr.json index 8bf6696c9..c30ac520b 100644 --- a/langs/themes/fr.json +++ b/langs/themes/fr.json @@ -91,11 +91,6 @@ "description": "Une vélothèque est un endroit où on peut emprunter des vélos, souvent moyennant une petite somme annuelle. Un cas d'utilisation notable est celui des vélothèques pour les enfants, qui leur permettent de passer à un vélo plus grand quand ils sont trop grands pour leur vélo actuel", "title": "Vélothèques" }, - "bike_monitoring_stations": { - "description": "Ce thème montre les données des compteurs en temps réel", - "shortDescription": "Station de comptage vélo avec données en temps réel par Bruxelles Mobilités", - "title": "Station de comptage vélo" - }, "bookcases": { "description": "Une microbibliothèques, également appelée boite à livre, est un élément de mobilier urbain (étagère, armoire, etc) dans lequel sont stockés des livres et autres objets en accès libre. Découvrez les boites à livres prêt de chez vous, ou ajouter en une nouvelle à l'aide de votre compte OpenStreetMap.", "title": "Carte des microbibliothèques" diff --git a/langs/themes/it.json b/langs/themes/it.json index e75545c57..8f7487108 100644 --- a/langs/themes/it.json +++ b/langs/themes/it.json @@ -91,11 +91,6 @@ "description": "«Biciclette in prestito» è un luogo dove le biciclette possono essere prese in prestito, spesso in cambio di un piccolo contributo annuale. Un caso degno di nota è quello delle biciclette in prestito per bambini che permettono loro di cambiare le dimensioni della propria bici quando quella attuale diventa troppo piccola", "title": "Biciclette in prestito" }, - "bike_monitoring_stations": { - "description": "Questo tema mostra le stazioni di monitoraggio bici con dati dal vivo", - "shortDescription": "Stazioni di monitoraggio bici con dati in tempo reale forniti da Bruxelles Mobility", - "title": "Stazioni di monitoraggio biciclette" - }, "bookcases": { "description": "Una minibiblioteca è una piccola cabina a lato della strada, una scatola, una vecchia cabina telefonica o qualche altro contenitore che ospita libri. Tutti può lasciare o prendere un libro. Questa mappa punta a rappresentarle tutte. Puoi facilmente scoprire nuove minibiblioteche nelle tue vicinanze e, con un account gratuito su OpenStreetMap, puoi aggiungerne altre.", "title": "Mappa libera delle microbiblioteche" diff --git a/langs/themes/ja.json b/langs/themes/ja.json index 7e79f1844..d1b0cb22d 100644 --- a/langs/themes/ja.json +++ b/langs/themes/ja.json @@ -91,11 +91,6 @@ "description": "自転車ライブラリは、少額の年間料金で自転車を借りられる場所です。注目すべきユースケースとしては、子供向けの自転車ライブラリで、子どもの成長にあわせて大きな自転車へ借り替えられます", "title": "自転車ライブラリ" }, - "bike_monitoring_stations": { - "description": "このテーマでは、ライブデータのある自転車監視ステーションを示します", - "shortDescription": "Brussels Mobilityのライブデータを使用した自転車モニタリングステーション", - "title": "自転車監視ステーション" - }, "bookcases": { "description": "公共の本棚とは、本が保管されている小さな街角のキャビネット、箱、古い電話のトランク、その他の物のことです。誰でも本を置いたり持ったりすることができます。このマップは、すべての公共の本棚を収集することを目的としています。近くで新しい本棚を見つけることができ、無料のOpenStreetMapアカウントを使えば、お気に入りの本棚を簡単に追加できます。", "title": "オープン本棚マップ" diff --git a/langs/themes/nl.json b/langs/themes/nl.json index a27d74960..c35eab161 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -95,11 +95,6 @@ "description": "Een fietsbibliotheek is een plaats waar men een fiets kan lenen, vaak voor een klein bedrag per jaar. Een typisch voorbeeld zijn kinderfietsbibliotheken, waar men een fiets op maat van het kind kan lenen. Is het kind de fiets ontgroeid, dan kan het te kleine fietsje omgeruild worden voor een grotere.", "title": "Fietsbibliotheken" }, - "bike_monitoring_stations": { - "description": "Dit thema toont fietstelstations met live data", - "shortDescription": "Fietstelstations met live data van Brussel Mobiliteit", - "title": "Fietstelstations" - }, "binoculars": { "description": "Een kaart met verrekijkers die op een vaste plaats zijn gemonteerd", "shortDescription": "Een kaart met publieke verrekijker", @@ -1002,47 +997,6 @@ "shortDescription": "Speelplekken in de Antwerpse Zuidrand", "title": "Welkom bij de groendoener!" }, - "speelplekken_temp": { - "description": "Speelplekken in de Antwerpse Zuidrand. Een project van Provincie Antwerpen, in samenwerking met Createlli, Sportpret en OpenStreetMap België", - "layers": { - "6": { - "name": "Wandelroutes van provincie Antwerpen", - "tagRenderings": { - "0": { - "render": "Deze wandeling is {_length:km}km lang" - }, - "1": { - "mappings": { - "0": { - "then": "Dit is een internationale wandelroute" - }, - "1": { - "then": "Dit is een nationale wandelroute" - }, - "2": { - "then": "Dit is een regionale wandelroute" - }, - "3": { - "then": "Dit is een lokale wandelroute" - } - } - }, - "2": { - "render": "

Korte beschrijving:

{description}" - }, - "3": { - "question": "Wie beheert deze wandeling en plaatst dus de signalisatiebordjes?" - }, - "4": { - "question": "Naar wie kan men emailen bij problemen rond signalisatie?", - "render": "Bij problemen met signalisatie kan men emailen naar {operator:email}" - } - } - } - }, - "shortDescription": "Speelplekken in de Antwerpse Zuidrand", - "title": "Speelplekken in de Antwerpse Zuidrand" - }, "sport_pitches": { "description": "Een sportveld is een ingerichte plaats met infrastructuur om een sport te beoefenen", "shortDescription": "Deze kaart toont sportvelden", @@ -1071,23 +1025,5 @@ "description": "Op deze kaart vind je vuilnisbakken waar je afval in kan smijten. Ontbreekt er een vuilnisbak? Dan kan je die zelf toevoegen", "shortDescription": "Een kaart met vuilnisbakken", "title": "Vuilnisbak" - }, - "width": { - "description": "

De straat is opgebruikt

\n

Er is steeds meer druk op de openbare ruimte. Voetgangers, fietsers, steps, auto's, bussen, bestelwagens, buggies, cargobikes, ... willen allemaal hun deel van de openbare ruimte.

\n

In deze studie nemen we Brugge onder de loep en kijken we hoe breed elke straat is én hoe breed elke straat zou moeten zijn voor een veilig én vlot verkeer.

\n

Legende

\n     Straat te smal voor veilig verkeer
\n     Straat is breed genoeg veilig verkeer
\n     Straat zonder voetpad, te smal als ook voetgangers plaats krijgen
\n     Woonerf, autoluw, autoloos of enkel plaatselijk verkeer
\n
\n
\n Een gestippelde lijn is een straat waar ook voor fietsers éénrichtingsverkeer geldt.
\n Klik op een straat om meer informatie te zien.\n

Hoe gaan we verder?

\n Verschillende ingrepen kunnen de stad teruggeven aan de inwoners en de stad leefbaarder en levendiger maken.
\n Denk aan:\n
    \n
  • De autovrije zone's uitbreiden
  • \n
  • De binnenstad fietszone maken
  • \n
  • Het aantal woonerven uitbreiden
  • \n
  • Grotere auto's meer belasten - ze nemen immers meer parkeerruimte in.
  • \n
  • Laat toeristen verplicht parkeren onder het zand; een (fiets)taxi kan hen naar hun hotel brengen
  • \n
  • Voorzie in elke straat enkele parkeerplaatsen voor kortparkeren. Zo kunnen leveringen, iemand afzetten,... gebeuren zonder op het voetpad en fietspad te parkeren
  • \n
", - "layers": { - "0": { - "name": "Straten met een breedte", - "title": { - "mappings": { - "0": { - "then": "Naamloos segmet" - } - }, - "render": "{name}" - } - } - }, - "shortDescription": "Is de straat breed genoeg?", - "title": "Straatbreedtes" } } \ No newline at end of file diff --git a/langs/themes/pt_BR.json b/langs/themes/pt_BR.json index 56138ae8f..1b202d8aa 100644 --- a/langs/themes/pt_BR.json +++ b/langs/themes/pt_BR.json @@ -10,11 +10,6 @@ "bicyclelib": { "title": "Bibliotecas de bicicletas" }, - "bike_monitoring_stations": { - "description": "Este tema mostra as estações de monitoramento de bicicletas com dados ao vivo", - "shortDescription": "Estações de monitoramento de bicicletas com dados ao vivo da Mobilidade de Bruxelas", - "title": "Estações de monitoramento de bicicletas" - }, "bookcases": { "title": "Abrir Mapa de Estantes" }, diff --git a/langs/themes/ru.json b/langs/themes/ru.json index e4168c08d..e41b737a9 100644 --- a/langs/themes/ru.json +++ b/langs/themes/ru.json @@ -91,11 +91,6 @@ "description": "Велосипедная библиотека - это место, где велосипеды можно взять на время, часто за небольшую ежегодную плату. Примером использования являются библиотеки велосипедов для детей, что позволяет им сменить велосипед на больший, когда они перерастают свой нынешний велосипед", "title": "Велосипедные библиотеки" }, - "bike_monitoring_stations": { - "description": "В этой теме показаны станции мониторинга велосипедов с данными в реальном времени", - "shortDescription": "Станции мониторинга велосипедов с оперативными данными от Brussels Mobility", - "title": "Станции мониторинга велосипедов" - }, "bookcases": { "description": "Общественный книжный шкаф - это небольшой уличный шкаф, коробка, старый телефонный аппарат или другие предметы, где хранятся книги. Каждый может положить или взять книгу. Цель этой карты - собрать все эти книжные шкафы. Вы можете обнаружить новые книжные шкафы поблизости и, имея бесплатный аккаунт OpenStreetMap, быстро добавить свои любимые книжные шкафы.", "title": "Открытая карта книжных шкафов" diff --git a/langs/themes/zh_Hant.json b/langs/themes/zh_Hant.json index d60830222..42e84b918 100644 --- a/langs/themes/zh_Hant.json +++ b/langs/themes/zh_Hant.json @@ -91,11 +91,6 @@ "description": "單車圖書館是指每年支付小額費用,然後可以租用單車的地方。最有名的單車圖書館案例是給小孩的,能夠讓長大的小孩用目前的單車換成比較大的單車", "title": "單車圖書館" }, - "bike_monitoring_stations": { - "description": "這個主題顯示單車監視站的即時資料", - "shortDescription": "布魯塞爾車行資料的即時單車監視站資料", - "title": "自行車監視站" - }, "bookcases": { "description": "公共書架是街邊箱子、盒子、舊的電話亭或是其他存放書本的物件,每一個人都能放置或拿取書本。這份地圖收集所有類型的書架,你可以探索你附近新的書架,同時也能用免費的開放街圖帳號來快速新增你最愛的書架。", "title": "開放書架地圖" diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index aa15d9c3b..3097abecf 100644 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -49,12 +49,21 @@ class TranslationPart { return; } - for (const key in object) { + for (let key in object) { if (!object.hasOwnProperty(key)) { continue; } const v = object[key] + + if(typeof key === "number" && v["id"] !== undefined){ + // We use the embedded id as key instead of the index as this is more stable + // key = v["id"] + if(typeof key !== "string"){ + throw "Panic: found a non-string ID at"+context + } + } + if (v == null) { console.warn("Got a null value for key ", key) continue @@ -120,7 +129,10 @@ class TranslationPart { } } - +/** + * Checks that the given object only contains string-values + * @param tr + */ function isTranslation(tr: any): boolean { for (const key in tr) { if (typeof tr[key] !== "string") { @@ -130,6 +142,11 @@ function isTranslation(tr: any): boolean { return true; } +/** + * Converts a translation object into something that can be added to the 'generated translations' + * @param obj + * @param depth + */ function transformTranslation(obj: any, depth = 1) { if (isTranslation(obj)) { @@ -150,6 +167,9 @@ function transformTranslation(obj: any, depth = 1) { } +/** + * Generates the big compiledTranslations file + */ function genTranslations() { const translations = JSON.parse(fs.readFileSync("./assets/generated/translations.json", "utf-8")) const transformed = transformTranslation(translations); @@ -163,7 +183,10 @@ function genTranslations() { } -// Read 'lang/*.json', writes to 'assets/generated/translations.json' +/** + * Reads 'lang/*.json', writes them into to 'assets/generated/translations.json'. + * This is only for the core translations + */ function compileTranslationsFromWeblate() { const translations = ScriptUtils.readDirRecSync("./langs", 1) .filter(path => path.indexOf(".json") > 0) @@ -181,7 +204,11 @@ function compileTranslationsFromWeblate() { } -// Get all the strings out of the layers; writes them onto the weblate paths +/** + * Get all the strings out of the layers; writes them onto the weblate paths + * @param objects + * @param target + */ function generateTranslationsObjectFrom(objects: { path: string, parsed: { id: string } }[], target: string) { const tr = new TranslationPart(); @@ -218,6 +245,7 @@ function MergeTranslation(source: any, target: any, language: string, context: s if (!source.hasOwnProperty(key)) { continue } + const sourceV = source[key]; const targetV = target[key] if (typeof sourceV === "string") { From b7f60e97125b5de79821b9b512ece18fcbac176a Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 20:32:28 +0200 Subject: [PATCH 25/65] Use ids for tagrenderings in the translation files --- langs/layers/ca.json | 54 +- langs/layers/de.json | 882 ++++----- langs/layers/en.json | 2898 ++++++++++++++--------------- langs/layers/es.json | 50 +- langs/layers/fi.json | 48 +- langs/layers/fr.json | 1278 ++++++------- langs/layers/gl.json | 216 +-- langs/layers/hu.json | 116 +- langs/layers/id.json | 38 +- langs/layers/it.json | 1238 ++++++------- langs/layers/ja.json | 10 +- langs/layers/nb_NO.json | 76 +- langs/layers/nl.json | 3010 +++++++++++++++---------------- langs/layers/pl.json | 90 +- langs/layers/pt_BR.json | 338 ++-- langs/layers/ru.json | 674 +++---- langs/layers/zh_Hans.json | 132 +- langs/layers/zh_Hant.json | 260 +-- langs/layers/zh_Hanå¨s.json | 2 +- langs/themes/ca.json | 26 +- langs/themes/de.json | 174 +- langs/themes/en.json | 928 +++++----- langs/themes/es.json | 4 +- langs/themes/fr.json | 872 ++++----- langs/themes/id.json | 56 +- langs/themes/it.json | 350 ++-- langs/themes/ja.json | 784 ++++---- langs/themes/nb_NO.json | 126 +- langs/themes/nl.json | 496 ++--- langs/themes/pt_BR.json | 102 +- langs/themes/ru.json | 416 ++--- langs/themes/zh_Hant.json | 128 +- scripts/generateTranslations.ts | 32 +- 33 files changed, 7956 insertions(+), 7948 deletions(-) diff --git a/langs/layers/ca.json b/langs/layers/ca.json index 270daa003..1c12a8ed7 100644 --- a/langs/layers/ca.json +++ b/langs/layers/ca.json @@ -7,18 +7,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Aquest desfibril·lador està a l'interior" - }, - "1": { - "then": "Aquest desfibril·lador està a l'exterior" - } - }, - "question": "Està el desfibril·lador a l'interior?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Accés lliure" @@ -36,18 +25,29 @@ "question": "Està el desfibril·lador accessible lliurement?", "render": "L'accés és {access}" }, - "4": { + "defibrillator-defibrillator:location": { + "question": "Dóna detalls d'on es pot trobar el desfibril·lador" + }, + "defibrillator-defibrillator:location:en": { + "question": "Dóna detalls d'on es pot trobar el desfibril·lador" + }, + "defibrillator-defibrillator:location:fr": { + "question": "Dóna detalls d'on es pot trobar el desfibril·lador" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "Aquest desfibril·lador està a l'interior" + }, + "1": { + "then": "Aquest desfibril·lador està a l'exterior" + } + }, + "question": "Està el desfibril·lador a l'interior?" + }, + "defibrillator-level": { "question": "A quina planta està el desfibril·lador localitzat?", "render": "Aquest desfibril·lador és a la planta {level}" - }, - "5": { - "question": "Dóna detalls d'on es pot trobar el desfibril·lador" - }, - "6": { - "question": "Dóna detalls d'on es pot trobar el desfibril·lador" - }, - "7": { - "question": "Dóna detalls d'on es pot trobar el desfibril·lador" } }, "title": { @@ -56,27 +56,27 @@ }, "ghost_bike": { "tagRenderings": { - "4": { + "ghost_bike-inscription": { "render": "{inscription}" } } }, "nature_reserve": { "tagRenderings": { - "8": { + "Email": { "render": "{email}" }, - "9": { + "phone": { "render": "{phone}" } } }, "playground": { "tagRenderings": { - "7": { + "playground-email": { "render": "{email}" }, - "8": { + "playground-phone": { "render": "{phone}" } } diff --git a/langs/layers/de.json b/langs/layers/de.json index 372ba5de9..d98acb582 100644 --- a/langs/layers/de.json +++ b/langs/layers/de.json @@ -8,7 +8,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Rückenlehne: Ja" @@ -20,39 +20,7 @@ "question": "Hat diese Bank eine Rückenlehne?", "render": "Rückenlehne" }, - "2": { - "question": "Wie viele Sitzplätze hat diese Bank?", - "render": "{seats} Sitzplätze" - }, - "3": { - "mappings": { - "0": { - "then": "Material: Holz" - }, - "1": { - "then": "Material: Metall" - }, - "2": { - "then": "Material: Stein" - }, - "3": { - "then": "Material: Beton" - }, - "4": { - "then": "Material: Kunststoff" - }, - "5": { - "then": "Material: Stahl" - } - }, - "question": "Aus welchem Material besteht die Sitzbank (Sitzfläche)?", - "render": "Material: {material}" - }, - "4": { - "question": "In welche Richtung schaut man, wenn man auf der Bank sitzt?", - "render": "Wenn man auf der Bank sitzt, schaut man in Richtung {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Farbe: braun" @@ -82,7 +50,39 @@ "question": "Welche Farbe hat diese Sitzbank?", "render": "Farbe: {colour}" }, - "6": { + "bench-direction": { + "question": "In welche Richtung schaut man, wenn man auf der Bank sitzt?", + "render": "Wenn man auf der Bank sitzt, schaut man in Richtung {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Material: Holz" + }, + "1": { + "then": "Material: Metall" + }, + "2": { + "then": "Material: Stein" + }, + "3": { + "then": "Material: Beton" + }, + "4": { + "then": "Material: Kunststoff" + }, + "5": { + "then": "Material: Stahl" + } + }, + "question": "Aus welchem Material besteht die Sitzbank (Sitzfläche)?", + "render": "Material: {material}" + }, + "bench-seats": { + "question": "Wie viele Sitzplätze hat diese Bank?", + "render": "{seats} Sitzplätze" + }, + "bench-survey:date": { "question": "Wann wurde diese Bank zuletzt überprüft?", "render": "Diese Bank wurde zuletzt überprüft am {survey:date}" } @@ -94,11 +94,11 @@ "bench_at_pt": { "name": "Sitzbänke bei Haltestellen", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "Stehbank" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -116,19 +116,7 @@ "bicycle_library": { "description": "Eine Einrichtung, in der Fahrräder für längere Zeit geliehen werden können", "tagRenderings": { - "6": { - "mappings": { - "0": { - "then": "Das Ausleihen eines Fahrrads ist kostenlos" - }, - "1": { - "then": "Das Ausleihen eines Fahrrads kostet 20€ pro Jahr und 20€ Gebühr" - } - }, - "question": "Wie viel kostet das Ausleihen eines Fahrrads?", - "render": "Das Ausleihen eines Fahrrads kostet {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Fahrräder für Kinder verfügbar" @@ -141,6 +129,18 @@ } }, "question": "Wer kann hier Fahrräder ausleihen?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "Das Ausleihen eines Fahrrads ist kostenlos" + }, + "1": { + "then": "Das Ausleihen eines Fahrrads kostet 20€ pro Jahr und 20€ Gebühr" + } + }, + "question": "Wie viel kostet das Ausleihen eines Fahrrads?", + "render": "Das Ausleihen eines Fahrrads kostet {charge}" } } }, @@ -152,7 +152,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Dieser Automat funktioniert" @@ -180,11 +180,7 @@ } }, "tagRenderings": { - "1": { - "question": "Wie heißt dieses Fahrrad-Café?", - "render": "Dieses Fahrrad-Café heißt {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "Dieses Fahrrad-Café bietet eine Fahrradpumpe an, die von jedem benutzt werden kann" @@ -195,18 +191,17 @@ }, "question": "Bietet dieses Fahrrad-Café eine Fahrradpumpe an, die von jedem benutzt werden kann?" }, - "3": { - "mappings": { - "0": { - "then": "Dieses Fahrrad-Café bietet Werkzeuge für die selbständige Reparatur an" - }, - "1": { - "then": "Dieses Fahrrad-Café bietet keine Werkzeuge für die selbständige Reparatur an" - } - }, - "question": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?" + "bike_cafe-email": { + "question": "Wie lautet die E-Mail-Adresse von {name}?" }, - "4": { + "bike_cafe-name": { + "question": "Wie heißt dieses Fahrrad-Café?", + "render": "Dieses Fahrrad-Café heißt {name}" + }, + "bike_cafe-phone": { + "question": "Wie lautet die Telefonnummer von {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "Dieses Fahrrad-Café repariert Fahrräder" @@ -217,14 +212,19 @@ }, "question": "Repariert dieses Fahrrad-Café Fahrräder?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "Dieses Fahrrad-Café bietet Werkzeuge für die selbständige Reparatur an" + }, + "1": { + "then": "Dieses Fahrrad-Café bietet keine Werkzeuge für die selbständige Reparatur an" + } + }, + "question": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?" + }, + "bike_cafe-website": { "question": "Was ist die Webseite von {name}?" - }, - "6": { - "question": "Wie lautet die Telefonnummer von {name}?" - }, - "7": { - "question": "Wie lautet die E-Mail-Adresse von {name}?" } }, "title": { @@ -260,7 +260,16 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "Öffentlich zugänglich" + } + }, + "question": "Wer kann diesen Fahrradparplatz nutzen?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "0": { "then": "Fahrradbügel " @@ -290,7 +299,40 @@ "question": "Was ist die Art dieses Fahrrad-Parkplatzes?", "render": "Dies ist ein Fahrrad-Parkplatz der Art: {bicycle_parking}" }, - "2": { + "Capacity": { + "question": "Wie viele Fahrräder passen auf diesen Fahrrad-Parkplatz (einschließlich möglicher Lastenfahrräder)?", + "render": "Platz für {capacity} Fahrräder" + }, + "Cargo bike capacity?": { + "question": "Wie viele Lastenfahrräder passen auf diesen Fahrrad-Parkplatz?", + "render": "Auf diesen Parkplatz passen {capacity:cargo_bike} Lastenfahrräder" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "Dieser Parkplatz bietet Platz für Lastenfahrräder" + }, + "1": { + "then": "Dieser Parkplatz verfügt über ausgewiesene (offizielle) Plätze für Lastenfahrräder." + }, + "2": { + "then": "Es ist nicht erlaubt, Lastenfahrräder zu parken" + } + }, + "question": "Gibt es auf diesem Fahrrad-Parkplatz Plätze für Lastenfahrräder?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "Dieser Parkplatz ist überdacht (er hat ein Dach)" + }, + "1": { + "then": "Dieser Parkplatz ist nicht überdacht" + } + }, + "question": "Ist dieser Parkplatz überdacht? Wählen Sie auch \"überdacht\" für Innenparkplätze." + }, + "Underground?": { "mappings": { "0": { "then": "Tiefgarage" @@ -305,48 +347,6 @@ "then": "Ebenerdiges Parken" } } - }, - "3": { - "mappings": { - "0": { - "then": "Dieser Parkplatz ist überdacht (er hat ein Dach)" - }, - "1": { - "then": "Dieser Parkplatz ist nicht überdacht" - } - }, - "question": "Ist dieser Parkplatz überdacht? Wählen Sie auch \"überdacht\" für Innenparkplätze." - }, - "4": { - "question": "Wie viele Fahrräder passen auf diesen Fahrrad-Parkplatz (einschließlich möglicher Lastenfahrräder)?", - "render": "Platz für {capacity} Fahrräder" - }, - "5": { - "mappings": { - "0": { - "then": "Öffentlich zugänglich" - } - }, - "question": "Wer kann diesen Fahrradparplatz nutzen?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "Dieser Parkplatz bietet Platz für Lastenfahrräder" - }, - "1": { - "then": "Dieser Parkplatz verfügt über ausgewiesene (offizielle) Plätze für Lastenfahrräder." - }, - "2": { - "then": "Es ist nicht erlaubt, Lastenfahrräder zu parken" - } - }, - "question": "Gibt es auf diesem Fahrrad-Parkplatz Plätze für Lastenfahrräder?" - }, - "7": { - "question": "Wie viele Lastenfahrräder passen auf diesen Fahrrad-Parkplatz?", - "render": "Auf diesen Parkplatz passen {capacity:cargo_bike} Lastenfahrräder" } }, "title": { @@ -369,7 +369,18 @@ } }, "tagRenderings": { - "1": { + "Operational status": { + "mappings": { + "0": { + "then": "Die Fahrradpumpe ist kaputt" + }, + "1": { + "then": "Die Fahrradpumpe ist betriebsbereit" + } + }, + "question": "Ist die Fahrradpumpe noch funktionstüchtig?" + }, + "bike_repair_station-available-services": { "mappings": { "0": { "then": "Es ist nur eine Pumpe vorhanden" @@ -383,22 +394,7 @@ }, "question": "Welche Einrichtungen stehen an dieser Fahrradstation zur Verfügung?" }, - "2": { - "question": "Wer wartet diese Fahrradpumpe?", - "render": "Gewartet von {operator}" - }, - "5": { - "mappings": { - "0": { - "then": "Immer geöffnet" - }, - "1": { - "then": "Immer geöffnet" - } - }, - "question": "Wann ist diese Fahrradreparaturstelle geöffnet?" - }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "Es gibt ein Kettenwerkzeug" @@ -409,7 +405,7 @@ }, "question": "Verfügt diese Fahrrad-Reparaturstation über Spezialwerkzeug zur Reparatur von Fahrradketten?" }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "Es gibt einen Haken oder Ständer" @@ -420,18 +416,47 @@ }, "question": "Hat diese Fahrradstation einen Haken, an dem Sie Ihr Fahrrad aufhängen können, oder einen Ständer, um es anzuheben?" }, - "8": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { - "then": "Die Fahrradpumpe ist kaputt" + "then": "Manuelle Pumpe" }, "1": { - "then": "Die Fahrradpumpe ist betriebsbereit" + "then": "Elektrische Pumpe" } }, - "question": "Ist die Fahrradpumpe noch funktionstüchtig?" + "question": "Ist dies eine elektrische Fahrradpumpe?" }, - "10": { + "bike_repair_station-manometer": { + "mappings": { + "0": { + "then": "Es gibt ein Manometer" + }, + "1": { + "then": "Es gibt kein Manometer" + }, + "2": { + "then": "Es gibt ein Manometer, aber es ist kaputt" + } + }, + "question": "Verfügt die Pumpe über einen Druckanzeiger oder ein Manometer?" + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Immer geöffnet" + }, + "1": { + "then": "Immer geöffnet" + } + }, + "question": "Wann ist diese Fahrradreparaturstelle geöffnet?" + }, + "bike_repair_station-operator": { + "question": "Wer wartet diese Fahrradpumpe?", + "render": "Gewartet von {operator}" + }, + "bike_repair_station-valves": { "mappings": { "0": { "then": "Sklaverand (auch bekannt als Presta)" @@ -445,31 +470,6 @@ }, "question": "Welche Ventile werden unterstützt?", "render": "Diese Pumpe unterstützt die folgenden Ventile: {valves}" - }, - "11": { - "mappings": { - "0": { - "then": "Manuelle Pumpe" - }, - "1": { - "then": "Elektrische Pumpe" - } - }, - "question": "Ist dies eine elektrische Fahrradpumpe?" - }, - "12": { - "mappings": { - "0": { - "then": "Es gibt ein Manometer" - }, - "1": { - "then": "Es gibt kein Manometer" - }, - "2": { - "then": "Es gibt ein Manometer, aber es ist kaputt" - } - }, - "question": "Verfügt die Pumpe über einen Druckanzeiger oder ein Manometer?" } }, "title": { @@ -501,31 +501,43 @@ } }, "tagRenderings": { - "2": { - "question": "Wie heißt dieser Fahrradladen?", - "render": "Dieses Fahrradgeschäft heißt {name}" - }, - "3": { - "question": "Was ist die Webseite von {name}?" - }, - "4": { - "question": "Wie lautet die Telefonnummer von {name}?" - }, - "5": { - "question": "Wie lautet die E-Mail-Adresse von {name}?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "Dieses Geschäft verkauft Fahrräder" + "then": "Dieses Geschäft bietet eine Fahrradpumpe für alle an" }, "1": { - "then": "Dieses Geschäft verkauft keine Fahrräder" + "then": "Dieses Geschäft bietet für niemanden eine Fahrradpumpe an" } }, - "question": "Verkauft dieser Laden Fahrräder?" + "question": "Bietet dieses Geschäft eine Fahrradpumpe zur Benutzung für alle an?" }, - "10": { + "bike_repair_bike-wash": { + "mappings": { + "0": { + "then": "Dieses Geschäft reinigt Fahrräder" + }, + "1": { + "then": "Dieser Laden hat eine Anlage, in der man Fahrräder selbst reinigen kann" + }, + "2": { + "then": "Dieser Laden bietet keine Fahrradreinigung an" + } + }, + "question": "Werden hier Fahrräder gewaschen?" + }, + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "Dieses Geschäft vermietet Fahrräder" + }, + "1": { + "then": "Dieses Geschäft vermietet keine Fahrräder" + } + }, + "question": "Vermietet dieser Laden Fahrräder?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Dieses Geschäft repariert Fahrräder" @@ -542,18 +554,7 @@ }, "question": "Repariert dieses Geschäft Fahrräder?" }, - "11": { - "mappings": { - "0": { - "then": "Dieses Geschäft vermietet Fahrräder" - }, - "1": { - "then": "Dieses Geschäft vermietet keine Fahrräder" - } - }, - "question": "Vermietet dieser Laden Fahrräder?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "Dieses Geschäft verkauft gebrauchte Fahrräder" @@ -567,18 +568,18 @@ }, "question": "Verkauft dieses Geschäft gebrauchte Fahrräder?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "Dieses Geschäft bietet eine Fahrradpumpe für alle an" + "then": "Dieses Geschäft verkauft Fahrräder" }, "1": { - "then": "Dieses Geschäft bietet für niemanden eine Fahrradpumpe an" + "then": "Dieses Geschäft verkauft keine Fahrräder" } }, - "question": "Bietet dieses Geschäft eine Fahrradpumpe zur Benutzung für alle an?" + "question": "Verkauft dieser Laden Fahrräder?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "0": { "then": "Dieses Geschäft bietet Werkzeuge für die Heimwerkerreparatur an" @@ -592,19 +593,18 @@ }, "question": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?" }, - "15": { - "mappings": { - "0": { - "then": "Dieses Geschäft reinigt Fahrräder" - }, - "1": { - "then": "Dieser Laden hat eine Anlage, in der man Fahrräder selbst reinigen kann" - }, - "2": { - "then": "Dieser Laden bietet keine Fahrradreinigung an" - } - }, - "question": "Werden hier Fahrräder gewaschen?" + "bike_shop-email": { + "question": "Wie lautet die E-Mail-Adresse von {name}?" + }, + "bike_shop-name": { + "question": "Wie heißt dieser Fahrradladen?", + "render": "Dieses Fahrradgeschäft heißt {name}" + }, + "bike_shop-phone": { + "question": "Wie lautet die Telefonnummer von {name}?" + }, + "bike_shop-website": { + "question": "Was ist die Webseite von {name}?" } }, "title": { @@ -647,18 +647,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Dieser Defibrillator befindet sich im Gebäude" - }, - "1": { - "then": "Dieser Defibrillator befindet sich im Freien" - } - }, - "question": "Befindet sich dieser Defibrillator im Gebäude?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Öffentlich zugänglich" @@ -676,7 +665,7 @@ "question": "Ist dieser Defibrillator frei zugänglich?", "render": "Zugang ist {access}" }, - "3": { + "defibrillator-defibrillator": { "mappings": { "0": { "then": "Dies ist ein manueller Defibrillator für den professionellen Einsatz" @@ -684,7 +673,42 @@ }, "render": "Es gibt keine Informationen über den Gerätetyp" }, - "4": { + "defibrillator-defibrillator:location": { + "question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (in der lokalen Sprache)", + "render": "Zusätzliche Informationen über den Standort (in der Landessprache):
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:en": { + "question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Englisch)", + "render": "Zusätzliche Informationen über den Standort (auf Englisch):
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:fr": { + "question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Französisch)", + "render": "Zusätzliche Informationen zum Standort (auf Französisch):
{defibrillator:Standort:fr}" + }, + "defibrillator-description": { + "question": "Gibt es nützliche Informationen für Benutzer, die Sie oben nicht beschreiben konnten? (leer lassen, wenn nein)", + "render": "Zusätzliche Informationen: {description}" + }, + "defibrillator-email": { + "question": "Wie lautet die E-Mail für Fragen zu diesem Defibrillator?", + "render": "E-Mail für Fragen zu diesem Defibrillator: {email}" + }, + "defibrillator-fixme": { + "question": "Gibt es einen Fehler in der Kartierung, den Sie hier nicht beheben konnten? (hinterlasse eine Notiz an OpenStreetMap-Experten)", + "render": "Zusätzliche Informationen für OpenStreetMap-Experten: {fixme}" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "Dieser Defibrillator befindet sich im Gebäude" + }, + "1": { + "then": "Dieser Defibrillator befindet sich im Freien" + } + }, + "question": "Befindet sich dieser Defibrillator im Gebäude?" + }, + "defibrillator-level": { "mappings": { "0": { "then": "Dieser Defibrillator befindet sich im Erdgeschoss" @@ -696,31 +720,7 @@ "question": "In welchem Stockwerk befindet sich dieser Defibrillator?", "render": "Dieser Defibrallator befindet sich im {level}. Stockwerk" }, - "5": { - "question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (in der lokalen Sprache)", - "render": "Zusätzliche Informationen über den Standort (in der Landessprache):
{defibrillator:location}" - }, - "6": { - "question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Englisch)", - "render": "Zusätzliche Informationen über den Standort (auf Englisch):
{defibrillator:location}" - }, - "7": { - "question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Französisch)", - "render": "Zusätzliche Informationen zum Standort (auf Französisch):
{defibrillator:Standort:fr}" - }, - "9": { - "question": "Wie lautet die offizielle Identifikationsnummer des Geräts? (falls am Gerät sichtbar)", - "render": "Offizielle Identifikationsnummer des Geräts: {ref}" - }, - "10": { - "question": "Wie lautet die E-Mail für Fragen zu diesem Defibrillator?", - "render": "E-Mail für Fragen zu diesem Defibrillator: {email}" - }, - "11": { - "question": "Wie lautet die Telefonnummer für Fragen zu diesem Defibrillator?", - "render": "Telefonnummer für Fragen zu diesem Defibrillator: {phone}" - }, - "12": { + "defibrillator-opening_hours": { "mappings": { "0": { "then": "24/7 geöffnet (auch an Feiertagen)" @@ -728,11 +728,15 @@ }, "question": "Zu welchen Zeiten ist dieser Defibrillator verfügbar?" }, - "13": { - "question": "Gibt es nützliche Informationen für Benutzer, die Sie oben nicht beschreiben konnten? (leer lassen, wenn nein)", - "render": "Zusätzliche Informationen: {description}" + "defibrillator-phone": { + "question": "Wie lautet die Telefonnummer für Fragen zu diesem Defibrillator?", + "render": "Telefonnummer für Fragen zu diesem Defibrillator: {phone}" }, - "14": { + "defibrillator-ref": { + "question": "Wie lautet die offizielle Identifikationsnummer des Geräts? (falls am Gerät sichtbar)", + "render": "Offizielle Identifikationsnummer des Geräts: {ref}" + }, + "defibrillator-survey:date": { "mappings": { "0": { "then": "Heute überprüft!" @@ -740,10 +744,6 @@ }, "question": "Wann wurde dieser Defibrillator zuletzt überprüft?", "render": "Dieser Defibrillator wurde zuletzt am {survey:date} überprüft" - }, - "15": { - "question": "Gibt es einen Fehler in der Kartierung, den Sie hier nicht beheben konnten? (hinterlasse eine Notiz an OpenStreetMap-Experten)", - "render": "Zusätzliche Informationen für OpenStreetMap-Experten: {fixme}" } }, "title": { @@ -758,11 +758,7 @@ } }, "tagRenderings": { - "1": { - "question": "Ist diese Trinkwasserstelle noch in Betrieb?", - "render": "Der Betriebsstatus ist {operational_status" - }, - "2": { + "Bottle refill": { "mappings": { "0": { "then": "Es ist einfach, Wasserflaschen nachzufüllen" @@ -773,7 +769,11 @@ }, "question": "Wie einfach ist es, Wasserflaschen zu füllen?" }, - "3": { + "Still in use?": { + "question": "Ist diese Trinkwasserstelle noch in Betrieb?", + "render": "Der Betriebsstatus ist {operational_status" + }, + "render-closest-drinking-water": { "render": "Ein weiterer Trinkwasserbrunnen befindet sich in {_closest_other_drinking_water_distance} Meter" } }, @@ -789,10 +789,14 @@ } }, "tagRenderings": { - "0": { + "ghost-bike-explanation": { "render": "Ein Geisterrad ist ein Denkmal für einen Radfahrer, der bei einem Verkehrsunfall ums Leben kam, in Form eines weißen Fahrrades, das dauerhaft in der Nähe des Unfallortes aufgestellt wird." }, - "2": { + "ghost_bike-inscription": { + "question": "Wie lautet die Inschrift auf diesem Geisterrad?", + "render": "{inscription}" + }, + "ghost_bike-name": { "mappings": { "0": { "then": "Auf dem Fahrrad ist kein Name angegeben" @@ -801,13 +805,9 @@ "question": "An wen erinnert dieses Geisterrad?
Bitte respektieren Sie die Privatsphäre - geben Sie den Namen nur an, wenn er weit verbreitet oder auf dem Fahrrad markiert ist. Den Familiennamen können Sie weglassen.
", "render": "Im Gedenken an {name}" }, - "3": { + "ghost_bike-source": { "question": "Auf welcher Webseite kann man mehr Informationen über das Geisterrad oder den Unfall finden?", "render": "Mehr Informationen" - }, - "4": { - "question": "Wie lautet die Inschrift auf diesem Geisterrad?", - "render": "{inscription}" } }, "title": { @@ -839,16 +839,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Diese Karte basiert auf OpenStreetMap" - } - }, - "question": "Auf welchen Daten basiert diese Karte?", - "render": "Diese Karte basiert auf {map_source}" - }, - "2": { + "map-attribution": { "mappings": { "0": { "then": "OpenStreetMap ist eindeutig attributiert, einschließlich der ODBL-Lizenz" @@ -867,6 +858,15 @@ } }, "question": "Ist die OpenStreetMap-Attribution vorhanden?" + }, + "map-map_source": { + "mappings": { + "0": { + "then": "Diese Karte basiert auf OpenStreetMap" + } + }, + "question": "Auf welchen Daten basiert diese Karte?", + "render": "Diese Karte basiert auf {map_source}" } }, "title": { @@ -875,7 +875,7 @@ }, "nature_reserve": { "tagRenderings": { - "5": { + "Dogs?": { "mappings": { "0": { "then": "Hunde müssen angeleint sein" @@ -889,13 +889,13 @@ }, "question": "Sind Hunde in diesem Naturschutzgebiet erlaubt?" }, - "6": { - "question": "Auf welcher Webseite kann man mehr Informationen über dieses Naturschutzgebiet finden?" - }, - "8": { + "Email": { "render": "{email}" }, - "9": { + "Website": { + "question": "Auf welcher Webseite kann man mehr Informationen über dieses Naturschutzgebiet finden?" + }, + "phone": { "render": "{phone}" } } @@ -908,7 +908,7 @@ } }, "tagRenderings": { - "0": { + "picnic_table-material": { "mappings": { "0": { "then": "Dies ist ein Picknicktisch aus Holz" @@ -929,7 +929,63 @@ "description": "Spielplätze", "name": "Spielplätze", "tagRenderings": { - "1": { + "Playground-wheelchair": { + "mappings": { + "0": { + "then": "Vollständig zugänglich für Rollstuhlfahrer" + }, + "1": { + "then": "Eingeschränkte Zugänglichkeit für Rollstuhlfahrer" + }, + "2": { + "then": "Nicht zugänglich für Rollstuhlfahrer" + } + }, + "question": "Ist dieser Spielplatz für Rollstuhlfahrer zugänglich?" + }, + "playground-access": { + "mappings": { + "0": { + "then": "Zugänglich für die Allgemeinheit" + }, + "1": { + "then": "Zugänglich für die Allgemeinheit" + }, + "2": { + "then": "Nur für Kunden des Betreibers zugänglich" + }, + "3": { + "then": "Nur für Schüler der Schule zugänglich" + }, + "4": { + "then": "Nicht zugänglich" + } + }, + "question": "Ist dieser Spielplatz für die Allgemeinheit zugänglich?" + }, + "playground-email": { + "question": "Wie lautet die E-Mail Adresse des Spielplatzbetreuers?", + "render": "{email}" + }, + "playground-lit": { + "mappings": { + "0": { + "then": "Dieser Spielplatz ist nachts beleuchtet" + }, + "1": { + "then": "Dieser Spielplatz ist nachts nicht beleuchtet" + } + }, + "question": "Ist dieser Spielplatz nachts beleuchtet?" + }, + "playground-operator": { + "question": "Wer betreibt diesen Spielplatz?", + "render": "Betrieben von {operator}" + }, + "playground-phone": { + "render": "{phone}" + }, + "playground-surface": { "mappings": { "0": { "then": "Die Oberfläche ist Gras" @@ -958,62 +1014,6 @@ }, "question": "Welche Oberfläche hat dieser Spielplatz?
Wenn es mehrere gibt, wähle die am häufigsten vorkommende aus", "render": "Die Oberfläche ist {surface}" - }, - "2": { - "mappings": { - "0": { - "then": "Dieser Spielplatz ist nachts beleuchtet" - }, - "1": { - "then": "Dieser Spielplatz ist nachts nicht beleuchtet" - } - }, - "question": "Ist dieser Spielplatz nachts beleuchtet?" - }, - "5": { - "question": "Wer betreibt diesen Spielplatz?", - "render": "Betrieben von {operator}" - }, - "6": { - "mappings": { - "0": { - "then": "Zugänglich für die Allgemeinheit" - }, - "1": { - "then": "Zugänglich für die Allgemeinheit" - }, - "2": { - "then": "Nur für Kunden des Betreibers zugänglich" - }, - "3": { - "then": "Nur für Schüler der Schule zugänglich" - }, - "4": { - "then": "Nicht zugänglich" - } - }, - "question": "Ist dieser Spielplatz für die Allgemeinheit zugänglich?" - }, - "7": { - "question": "Wie lautet die E-Mail Adresse des Spielplatzbetreuers?", - "render": "{email}" - }, - "8": { - "render": "{phone}" - }, - "9": { - "mappings": { - "0": { - "then": "Vollständig zugänglich für Rollstuhlfahrer" - }, - "1": { - "then": "Eingeschränkte Zugänglichkeit für Rollstuhlfahrer" - }, - "2": { - "then": "Nicht zugänglich für Rollstuhlfahrer" - } - }, - "question": "Ist dieser Spielplatz für Rollstuhlfahrer zugänglich?" } }, "title": { @@ -1034,20 +1034,7 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "Dieser Bücherschrank hat keinen Namen" - } - }, - "question": "Wie heißt dieser öffentliche Bücherschrank?", - "render": "Der Name dieses Bücherschrank lautet {name}" - }, - "3": { - "question": "Wie viele Bücher passen in diesen öffentlichen Bücherschrank?", - "render": "{capacity} Bücher passen in diesen Bücherschrank" - }, - "4": { + "bookcase-booktypes": { "mappings": { "0": { "then": "Vorwiegend Kinderbücher" @@ -1061,7 +1048,18 @@ }, "question": "Welche Art von Büchern sind in diesem öffentlichen Bücherschrank zu finden?" }, - "5": { + "bookcase-is-accessible": { + "mappings": { + "0": { + "then": "Öffentlich zugänglich" + }, + "1": { + "then": "Nur für Kunden zugänglich" + } + }, + "question": "Ist dieser öffentliche Bücherschrank frei zugänglich?" + }, + "bookcase-is-indoors": { "mappings": { "0": { "then": "Dieser Bücherschrank befindet sich im Innenbereich" @@ -1075,22 +1073,7 @@ }, "question": "Befindet sich dieser Bücherschrank im Freien?" }, - "6": { - "mappings": { - "0": { - "then": "Öffentlich zugänglich" - }, - "1": { - "then": "Nur für Kunden zugänglich" - } - }, - "question": "Ist dieser öffentliche Bücherschrank frei zugänglich?" - }, - "7": { - "question": "Wer unterhält diesen öffentlichen Bücherschrank?", - "render": "Betrieben von {operator}" - }, - "8": { + "public_bookcase-brand": { "mappings": { "0": { "then": "Teil des Netzwerks 'Little Free Library'" @@ -1102,7 +1085,24 @@ "question": "Ist dieser öffentliche Bücherschrank Teil eines größeren Netzwerks?", "render": "Dieser Bücherschrank ist Teil von {brand}" }, - "9": { + "public_bookcase-capacity": { + "question": "Wie viele Bücher passen in diesen öffentlichen Bücherschrank?", + "render": "{capacity} Bücher passen in diesen Bücherschrank" + }, + "public_bookcase-name": { + "mappings": { + "0": { + "then": "Dieser Bücherschrank hat keinen Namen" + } + }, + "question": "Wie heißt dieser öffentliche Bücherschrank?", + "render": "Der Name dieses Bücherschrank lautet {name}" + }, + "public_bookcase-operator": { + "question": "Wer unterhält diesen öffentlichen Bücherschrank?", + "render": "Betrieben von {operator}" + }, + "public_bookcase-ref": { "mappings": { "0": { "then": "Dieser Bücherschrank ist nicht Teil eines größeren Netzwerks" @@ -1111,11 +1111,11 @@ "question": "Wie lautet die Referenznummer dieses öffentlichen Bücherschranks?", "render": "Die Referenznummer dieses öffentlichen Bücherschranks innerhalb {brand} lautet {ref}" }, - "10": { + "public_bookcase-start_date": { "question": "Wann wurde dieser öffentliche Bücherschrank installiert?", "render": "Installiert am {start_date}" }, - "11": { + "public_bookcase-website": { "question": "Gibt es eine Website mit weiteren Informationen über diesen öffentlichen Bücherschrank?", "render": "Weitere Informationen auf der Webseite" } @@ -1142,7 +1142,7 @@ } }, "tagRenderings": { - "1": { + "toilet-access": { "mappings": { "0": { "then": "Öffentlicher Zugang" @@ -1163,61 +1163,7 @@ "question": "Sind diese Toiletten öffentlich zugänglich?", "render": "Zugang ist {access}" }, - "2": { - "mappings": { - "0": { - "then": "Dies sind bezahlte Toiletten" - }, - "1": { - "then": "Kostenlose Nutzung" - } - }, - "question": "Können diese Toiletten kostenlos benutzt werden?" - }, - "3": { - "question": "Wie viel muss man für diese Toiletten bezahlen?", - "render": "Die Gebühr beträgt {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "Es gibt eine Toilette für Rollstuhlfahrer" - }, - "1": { - "then": "Kein Zugang für Rollstuhlfahrer" - } - }, - "question": "Gibt es eine Toilette für Rollstuhlfahrer?" - }, - "5": { - "mappings": { - "0": { - "then": "Es gibt nur Sitztoiletten" - }, - "1": { - "then": "Hier gibt es nur Pissoirs" - }, - "2": { - "then": "Es gibt hier nur Hocktoiletten" - }, - "3": { - "then": "Sowohl Sitztoiletten als auch Pissoirs sind hier verfügbar" - } - }, - "question": "Welche Art von Toiletten sind das?" - }, - "6": { - "mappings": { - "0": { - "then": "Ein Wickeltisch ist verfügbar" - }, - "1": { - "then": "Es ist kein Wickeltisch verfügbar" - } - }, - "question": "Ist ein Wickeltisch (zum Wechseln der Windeln) vorhanden?" - }, - "7": { + "toilet-changing_table:location": { "mappings": { "0": { "then": "Der Wickeltisch befindet sich in der Damentoilette. " @@ -1234,6 +1180,60 @@ }, "question": "Wo befindet sich der Wickeltisch?", "render": "Die Wickeltabelle befindet sich in {changing_table:location}" + }, + "toilet-charge": { + "question": "Wie viel muss man für diese Toiletten bezahlen?", + "render": "Die Gebühr beträgt {charge}" + }, + "toilets-changing-table": { + "mappings": { + "0": { + "then": "Ein Wickeltisch ist verfügbar" + }, + "1": { + "then": "Es ist kein Wickeltisch verfügbar" + } + }, + "question": "Ist ein Wickeltisch (zum Wechseln der Windeln) vorhanden?" + }, + "toilets-fee": { + "mappings": { + "0": { + "then": "Dies sind bezahlte Toiletten" + }, + "1": { + "then": "Kostenlose Nutzung" + } + }, + "question": "Können diese Toiletten kostenlos benutzt werden?" + }, + "toilets-type": { + "mappings": { + "0": { + "then": "Es gibt nur Sitztoiletten" + }, + "1": { + "then": "Hier gibt es nur Pissoirs" + }, + "2": { + "then": "Es gibt hier nur Hocktoiletten" + }, + "3": { + "then": "Sowohl Sitztoiletten als auch Pissoirs sind hier verfügbar" + } + }, + "question": "Welche Art von Toiletten sind das?" + }, + "toilets-wheelchair": { + "mappings": { + "0": { + "then": "Es gibt eine Toilette für Rollstuhlfahrer" + }, + "1": { + "then": "Kein Zugang für Rollstuhlfahrer" + } + }, + "question": "Gibt es eine Toilette für Rollstuhlfahrer?" } }, "title": { @@ -1258,7 +1258,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Möchten Sie eine Beschreibung hinzufügen?" } }, diff --git a/langs/layers/en.json b/langs/layers/en.json index 4ca798feb..79b62a672 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -13,18 +13,7 @@ } }, "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "A cyclist can go past this." - }, - "1": { - "then": "A cyclist can not go past this." - } - }, - "question": "Can a bicycle go past this barrier?" - }, - "1": { + "Bollard type": { "mappings": { "0": { "then": "Removable bollard" @@ -44,7 +33,7 @@ }, "question": "What kind of bollard is this?" }, - "2": { + "Cycle barrier type": { "mappings": { "0": { "then": "Single, just two barriers with a space inbetween " @@ -61,21 +50,32 @@ }, "question": "What kind of cycling barrier is this?" }, - "3": { + "MaxWidth": { "question": "How wide is the gap left over besides the barrier?", "render": "Maximum width: {maxwidth:physical} m" }, - "4": { + "Overlap (cyclebarrier)": { + "question": "How much overlap do the barriers have?", + "render": "Overlap: {overlap} m" + }, + "Space between barrier (cyclebarrier)": { "question": "How much space is there between the barriers (along the length of the road)?", "render": "Space between barriers (along the length of the road): {width:separation} m" }, - "5": { + "Width of opening (cyclebarrier)": { "question": "How wide is the smallest opening next to the barriers?", "render": "Width of opening: {width:opening} m" }, - "6": { - "question": "How much overlap do the barriers have?", - "render": "Overlap: {overlap} m" + "bicycle=yes/no": { + "mappings": { + "0": { + "then": "A cyclist can go past this." + }, + "1": { + "then": "A cyclist can not go past this." + } + }, + "question": "Can a bicycle go past this barrier?" } }, "title": { @@ -99,7 +99,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Backrest: Yes" @@ -111,39 +111,7 @@ "question": "Does this bench have a backrest?", "render": "Backrest" }, - "2": { - "question": "How many seats does this bench have?", - "render": "{seats} seats" - }, - "3": { - "mappings": { - "0": { - "then": "Material: wood" - }, - "1": { - "then": "Material: metal" - }, - "2": { - "then": "Material: stone" - }, - "3": { - "then": "Material: concrete" - }, - "4": { - "then": "Material: plastic" - }, - "5": { - "then": "Material: steel" - } - }, - "question": "What is the bench (seating) made from?", - "render": "Material: {material}" - }, - "4": { - "question": "In which direction are you looking when sitting on the bench?", - "render": "When sitting on the bench, one looks towards {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Colour: brown" @@ -173,7 +141,39 @@ "question": "Which colour does this bench have?", "render": "Colour: {colour}" }, - "6": { + "bench-direction": { + "question": "In which direction are you looking when sitting on the bench?", + "render": "When sitting on the bench, one looks towards {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Material: wood" + }, + "1": { + "then": "Material: metal" + }, + "2": { + "then": "Material: stone" + }, + "3": { + "then": "Material: concrete" + }, + "4": { + "then": "Material: plastic" + }, + "5": { + "then": "Material: steel" + } + }, + "question": "What is the bench (seating) made from?", + "render": "Material: {material}" + }, + "bench-seats": { + "question": "How many seats does this bench have?", + "render": "{seats} seats" + }, + "bench-survey:date": { "question": "When was this bench last surveyed?", "render": "This bench was last surveyed on {survey:date}" } @@ -185,11 +185,11 @@ "bench_at_pt": { "name": "Benches at public transport stops", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "Stand up bench" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -214,23 +214,7 @@ } }, "tagRenderings": { - "1": { - "question": "What is the name of this bicycle library?", - "render": "This bicycle library is called {name}" - }, - "6": { - "mappings": { - "0": { - "then": "Lending a bicycle is free" - }, - "1": { - "then": "Lending a bicycle costs €20/year and €20 warranty" - } - }, - "question": "How much does lending a bicycle cost?", - "render": "Lending a bicycle costs {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Bikes for children available" @@ -243,6 +227,22 @@ } }, "question": "Who can lend bicycles here?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "Lending a bicycle is free" + }, + "1": { + "then": "Lending a bicycle costs €20/year and €20 warranty" + } + }, + "question": "How much does lending a bicycle cost?", + "render": "Lending a bicycle costs {charge}" + }, + "bicycle_library-name": { + "question": "What is the name of this bicycle library?", + "render": "This bicycle library is called {name}" } }, "title": { @@ -257,7 +257,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "This vending machine works" @@ -285,11 +285,7 @@ } }, "tagRenderings": { - "1": { - "question": "What is the name of this bike cafe?", - "render": "This bike cafe is called {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "This bike cafe offers a bike pump for anyone" @@ -300,18 +296,20 @@ }, "question": "Does this bike cafe offer a bike pump for use by anyone?" }, - "3": { - "mappings": { - "0": { - "then": "This bike cafe offers tools for DIY repair" - }, - "1": { - "then": "This bike cafe doesn't offer tools for DIY repair" - } - }, - "question": "Are there tools here to repair your own bike?" + "bike_cafe-email": { + "question": "What is the email address of {name}?" }, - "4": { + "bike_cafe-name": { + "question": "What is the name of this bike cafe?", + "render": "This bike cafe is called {name}" + }, + "bike_cafe-opening_hours": { + "question": "When it this bike café opened?" + }, + "bike_cafe-phone": { + "question": "What is the phone number of {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "This bike cafe repairs bikes" @@ -322,17 +320,19 @@ }, "question": "Does this bike cafe repair bikes?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "This bike cafe offers tools for DIY repair" + }, + "1": { + "then": "This bike cafe doesn't offer tools for DIY repair" + } + }, + "question": "Are there tools here to repair your own bike?" + }, + "bike_cafe-website": { "question": "What is the website of {name}?" - }, - "6": { - "question": "What is the phone number of {name}?" - }, - "7": { - "question": "What is the email address of {name}?" - }, - "8": { - "question": "When it this bike café opened?" } }, "title": { @@ -368,7 +368,22 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "Publicly accessible" + }, + "1": { + "then": "Access is primarily for visitors to a business" + }, + "2": { + "then": "Access is limited to members of a school, company or organisation" + } + }, + "question": "Who can use this bicycle parking?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "0": { "then": "Staple racks " @@ -398,7 +413,40 @@ "question": "What is the type of this bicycle parking?", "render": "This is a bicycle parking of the type: {bicycle_parking}" }, - "2": { + "Capacity": { + "question": "How many bicycles fit in this bicycle parking (including possible cargo bicycles)?", + "render": "Place for {capacity} bikes" + }, + "Cargo bike capacity?": { + "question": "How many cargo bicycles fit in this bicycle parking?", + "render": "This parking fits {capacity:cargo_bike} cargo bikes" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "This parking has room for cargo bikes" + }, + "1": { + "then": "This parking has designated (official) spots for cargo bikes." + }, + "2": { + "then": "You're not allowed to park cargo bikes" + } + }, + "question": "Does this bicycle parking have spots for cargo bikes?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "This parking is covered (it has a roof)" + }, + "1": { + "then": "This parking is not covered" + } + }, + "question": "Is this parking covered? Also select \"covered\" for indoor parkings." + }, + "Underground?": { "mappings": { "0": { "then": "Underground parking" @@ -417,54 +465,6 @@ } }, "question": "What is the relative location of this bicycle parking?" - }, - "3": { - "mappings": { - "0": { - "then": "This parking is covered (it has a roof)" - }, - "1": { - "then": "This parking is not covered" - } - }, - "question": "Is this parking covered? Also select \"covered\" for indoor parkings." - }, - "4": { - "question": "How many bicycles fit in this bicycle parking (including possible cargo bicycles)?", - "render": "Place for {capacity} bikes" - }, - "5": { - "mappings": { - "0": { - "then": "Publicly accessible" - }, - "1": { - "then": "Access is primarily for visitors to a business" - }, - "2": { - "then": "Access is limited to members of a school, company or organisation" - } - }, - "question": "Who can use this bicycle parking?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "This parking has room for cargo bikes" - }, - "1": { - "then": "This parking has designated (official) spots for cargo bikes." - }, - "2": { - "then": "You're not allowed to park cargo bikes" - } - }, - "question": "Does this bicycle parking have spots for cargo bikes?" - }, - "7": { - "question": "How many cargo bicycles fit in this bicycle parking?", - "render": "This parking fits {capacity:cargo_bike} cargo bikes" } }, "title": { @@ -490,7 +490,21 @@ } }, "tagRenderings": { - "1": { + "Email maintainer": { + "render": "Report this bicycle pump as broken" + }, + "Operational status": { + "mappings": { + "0": { + "then": "The bike pump is broken" + }, + "1": { + "then": "The bike pump is operational" + } + }, + "question": "Is the bike pump still operational?" + }, + "bike_repair_station-available-services": { "mappings": { "0": { "then": "There is only a pump present" @@ -504,28 +518,7 @@ }, "question": "Which services are available at this bike station?" }, - "2": { - "question": "Who maintains this cycle pump?", - "render": "Maintained by {operator}" - }, - "3": { - "question": "What is the email address of the maintainer?" - }, - "4": { - "question": "What is the phone number of the maintainer?" - }, - "5": { - "mappings": { - "0": { - "then": "Always open" - }, - "1": { - "then": "Always open" - } - }, - "question": "When is this bicycle repair point open?" - }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "There is a chain tool" @@ -536,7 +529,7 @@ }, "question": "Does this bike repair station have a special tool to repair your bike chain?" }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "There is a hook or stand" @@ -547,21 +540,53 @@ }, "question": "Does this bike station have a hook to hang your bike on or a stand to raise it?" }, - "8": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { - "then": "The bike pump is broken" + "then": "Manual pump" }, "1": { - "then": "The bike pump is operational" + "then": "Electrical pump" } }, - "question": "Is the bike pump still operational?" + "question": "Is this an electric bike pump?" }, - "9": { - "render": "Report this bicycle pump as broken" + "bike_repair_station-email": { + "question": "What is the email address of the maintainer?" }, - "10": { + "bike_repair_station-manometer": { + "mappings": { + "0": { + "then": "There is a manometer" + }, + "1": { + "then": "There is no manometer" + }, + "2": { + "then": "There is manometer but it is broken" + } + }, + "question": "Does the pump have a pressure indicator or manometer?" + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Always open" + }, + "1": { + "then": "Always open" + } + }, + "question": "When is this bicycle repair point open?" + }, + "bike_repair_station-operator": { + "question": "Who maintains this cycle pump?", + "render": "Maintained by {operator}" + }, + "bike_repair_station-phone": { + "question": "What is the phone number of the maintainer?" + }, + "bike_repair_station-valves": { "mappings": { "0": { "then": "Sclaverand (also known as Presta)" @@ -575,31 +600,6 @@ }, "question": "What valves are supported?", "render": "This pump supports the following valves: {valves}" - }, - "11": { - "mappings": { - "0": { - "then": "Manual pump" - }, - "1": { - "then": "Electrical pump" - } - }, - "question": "Is this an electric bike pump?" - }, - "12": { - "mappings": { - "0": { - "then": "There is a manometer" - }, - "1": { - "then": "There is no manometer" - }, - "2": { - "then": "There is manometer but it is broken" - } - }, - "question": "Does the pump have a pressure indicator or manometer?" } }, "title": { @@ -632,34 +632,46 @@ } }, "tagRenderings": { - "1": { - "render": "This shop is specialized in selling {shop} and does bicycle related activities" - }, - "2": { - "question": "What is the name of this bicycle shop?", - "render": "This bicycle shop is called {name}" - }, - "3": { - "question": "What is the website of {name}?" - }, - "4": { - "question": "What is the phone number of {name}?" - }, - "5": { - "question": "What is the email address of {name}?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "This shop sells bikes" + "then": "This shop offers a bike pump for anyone" }, "1": { - "then": "This shop doesn't sell bikes" + "then": "This shop doesn't offer a bike pump for anyone" + }, + "2": { + "then": "There is bicycle pump, it is shown as a separate point " } }, - "question": "Does this shop sell bikes?" + "question": "Does this shop offer a bike pump for use by anyone?" }, - "10": { + "bike_repair_bike-wash": { + "mappings": { + "0": { + "then": "This shop cleans bicycles" + }, + "1": { + "then": "This shop has an installation where one can clean bicycles themselves" + }, + "2": { + "then": "This shop doesn't offer bicycle cleaning" + } + }, + "question": "Are bicycles washed here?" + }, + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "This shop rents out bikes" + }, + "1": { + "then": "This shop doesn't rent out bikes" + } + }, + "question": "Does this shop rent out bikes?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "This shop repairs bikes" @@ -676,18 +688,7 @@ }, "question": "Does this shop repair bikes?" }, - "11": { - "mappings": { - "0": { - "then": "This shop rents out bikes" - }, - "1": { - "then": "This shop doesn't rent out bikes" - } - }, - "question": "Does this shop rent out bikes?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "This shop sells second-hand bikes" @@ -701,21 +702,18 @@ }, "question": "Does this shop sell second-hand bikes?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "This shop offers a bike pump for anyone" + "then": "This shop sells bikes" }, "1": { - "then": "This shop doesn't offer a bike pump for anyone" - }, - "2": { - "then": "There is bicycle pump, it is shown as a separate point " + "then": "This shop doesn't sell bikes" } }, - "question": "Does this shop offer a bike pump for use by anyone?" + "question": "Does this shop sell bikes?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "0": { "then": "This shop offers tools for DIY repair" @@ -729,19 +727,21 @@ }, "question": "Are there tools here to repair your own bike?" }, - "15": { - "mappings": { - "0": { - "then": "This shop cleans bicycles" - }, - "1": { - "then": "This shop has an installation where one can clean bicycles themselves" - }, - "2": { - "then": "This shop doesn't offer bicycle cleaning" - } - }, - "question": "Are bicycles washed here?" + "bike_shop-email": { + "question": "What is the email address of {name}?" + }, + "bike_shop-is-bicycle_shop": { + "render": "This shop is specialized in selling {shop} and does bicycle related activities" + }, + "bike_shop-name": { + "question": "What is the name of this bicycle shop?", + "render": "This bicycle shop is called {name}" + }, + "bike_shop-phone": { + "question": "What is the phone number of {name}?" + }, + "bike_shop-website": { + "question": "What is the website of {name}?" } }, "title": { @@ -786,7 +786,7 @@ } }, "tagRenderings": { - "1": { + "binocular-charge": { "mappings": { "0": { "then": "Free to use" @@ -795,7 +795,7 @@ "question": "How much does one have to pay to use these binoculars?", "render": "Using these binoculars costs {charge}" }, - "2": { + "binocular-direction": { "question": "When looking through this binocular, in what direction does one look?", "render": "Looks towards {direction}°" } @@ -838,12 +838,12 @@ } }, "tagRenderings": { - "1": { + "Classification": { + "question": "What kind of cafe is this" + }, + "Name": { "question": "What is the name of this pub?", "render": "This pub is named {name}" - }, - "2": { - "question": "What kind of cafe is this" } }, "title": { @@ -931,35 +931,40 @@ } }, "tagRenderings": { - "1": { + "Auth phone": { + "question": "What's the phone number for authentication call or SMS?", + "render": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}" + }, + "Authentication": { "mappings": { "0": { - "then": "bicycles can be charged here" + "then": "Authentication by a membership card" }, "1": { - "then": "Cars can be charged here" + "then": "Authentication by an app" }, "2": { - "then": "Scooters can be charged here" + "then": "Authentication via phone call is available" }, "3": { - "then": "Heavy good vehicles (such as trucks) can be charged here" + "then": "Authentication via phone call is available" }, "4": { - "then": "Buses can be charged here" + "then": "Authentication via NFC is available" + }, + "5": { + "then": "Authentication via Money Card is available" + }, + "6": { + "then": "Authentication via debit card is available" + }, + "7": { + "then": "No authentication is needed" } }, - "question": "Which vehicles are allowed to charge here?" + "question": "What kind of authentication is available at the charging station?" }, - "2": { - "question": "Who is allowed to use this charging station?", - "render": "Access is {access}" - }, - "3": { - "question": "How much vehicles can be charged here at the same time?", - "render": "{capacity} vehicles can be charged here at the same time" - }, - "4": { + "Available_charging_stations (generated)": { "mappings": { "0": { "then": " Schuko wall plug without ground pin (CEE7/4 type F)" @@ -1042,576 +1047,7 @@ }, "question": "Which charging stations are available here?" }, - "5": { - "question": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", - "render": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here" - }, - "6": { - "mappings": { - "0": { - "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt" - } - }, - "question": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt" - }, - "7": { - "mappings": { - "0": { - "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A" - } - }, - "question": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:current}A" - }, - "8": { - "mappings": { - "0": { - "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw" - } - }, - "question": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}" - }, - "9": { - "question": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", - "render": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here" - }, - "10": { - "mappings": { - "0": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt" - } - }, - "question": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "render": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt" - }, - "11": { - "mappings": { - "0": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A" - } - }, - "question": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A" - }, - "12": { - "mappings": { - "0": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw" - }, - "1": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", - "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}" - }, - "13": { - "question": "How much plugs of type Chademo are available here?", - "render": "There are Chademo plugs of type Chademo available here" - }, - "14": { - "mappings": { - "0": { - "then": "Chademo outputs 500 volt" - } - }, - "question": "What voltage do the plugs with Chademo offer?", - "render": "Chademo outputs {socket:chademo:voltage} volt" - }, - "15": { - "mappings": { - "0": { - "then": "Chademo outputs at most 120 A" - } - }, - "question": "What current do the plugs with Chademo offer?", - "render": "Chademo outputs at most {socket:chademo:current}A" - }, - "16": { - "mappings": { - "0": { - "then": "Chademo outputs at most 50 kw" - } - }, - "question": "What power output does a single plug of type Chademo offer?", - "render": "Chademo outputs at most {socket:chademo:output}" - }, - "17": { - "question": "How much plugs of type Type 1 with cable (J1772) are available here?", - "render": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here" - }, - "18": { - "mappings": { - "0": { - "then": "Type 1 with cable (J1772) outputs 200 volt" - }, - "1": { - "then": "Type 1 with cable (J1772) outputs 240 volt" - } - }, - "question": "What voltage do the plugs with Type 1 with cable (J1772) offer?", - "render": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt" - }, - "19": { - "mappings": { - "0": { - "then": "Type 1 with cable (J1772) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 1 with cable (J1772) offer?", - "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A" - }, - "20": { - "mappings": { - "0": { - "then": "Type 1 with cable (J1772) outputs at most 3.7 kw" - }, - "1": { - "then": "Type 1 with cable (J1772) outputs at most 7 kw" - } - }, - "question": "What power output does a single plug of type Type 1 with cable (J1772) offer?", - "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}" - }, - "21": { - "question": "How much plugs of type Type 1 without cable (J1772) are available here?", - "render": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here" - }, - "22": { - "mappings": { - "0": { - "then": "Type 1 without cable (J1772) outputs 200 volt" - }, - "1": { - "then": "Type 1 without cable (J1772) outputs 240 volt" - } - }, - "question": "What voltage do the plugs with Type 1 without cable (J1772) offer?", - "render": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt" - }, - "23": { - "mappings": { - "0": { - "then": "Type 1 without cable (J1772) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 1 without cable (J1772) offer?", - "render": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A" - }, - "24": { - "mappings": { - "0": { - "then": "Type 1 without cable (J1772) outputs at most 3.7 kw" - }, - "1": { - "then": "Type 1 without cable (J1772) outputs at most 6.6 kw" - }, - "2": { - "then": "Type 1 without cable (J1772) outputs at most 7 kw" - }, - "3": { - "then": "Type 1 without cable (J1772) outputs at most 7.2 kw" - } - }, - "question": "What power output does a single plug of type Type 1 without cable (J1772) offer?", - "render": "Type 1 without cable (J1772) outputs at most {socket:type1:output}" - }, - "25": { - "question": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", - "render": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here" - }, - "26": { - "mappings": { - "0": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt" - }, - "1": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt" - } - }, - "question": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "render": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt" - }, - "27": { - "mappings": { - "0": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A" - }, - "1": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A" - } - }, - "question": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A" - }, - "28": { - "mappings": { - "0": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw" - }, - "1": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw" - }, - "2": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw" - }, - "3": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw" - } - }, - "question": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", - "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}" - }, - "29": { - "question": "How much plugs of type Tesla Supercharger are available here?", - "render": "There are Tesla Supercharger plugs of type Tesla Supercharger available here" - }, - "30": { - "mappings": { - "0": { - "then": "Tesla Supercharger outputs 480 volt" - } - }, - "question": "What voltage do the plugs with Tesla Supercharger offer?", - "render": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt" - }, - "31": { - "mappings": { - "0": { - "then": "Tesla Supercharger outputs at most 125 A" - }, - "1": { - "then": "Tesla Supercharger outputs at most 350 A" - } - }, - "question": "What current do the plugs with Tesla Supercharger offer?", - "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A" - }, - "32": { - "mappings": { - "0": { - "then": "Tesla Supercharger outputs at most 120 kw" - }, - "1": { - "then": "Tesla Supercharger outputs at most 150 kw" - }, - "2": { - "then": "Tesla Supercharger outputs at most 250 kw" - } - }, - "question": "What power output does a single plug of type Tesla Supercharger offer?", - "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}" - }, - "33": { - "question": "How much plugs of type Type 2 (mennekes) are available here?", - "render": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here" - }, - "34": { - "mappings": { - "0": { - "then": "Type 2 (mennekes) outputs 230 volt" - }, - "1": { - "then": "Type 2 (mennekes) outputs 400 volt" - } - }, - "question": "What voltage do the plugs with Type 2 (mennekes) offer?", - "render": "Type 2 (mennekes) outputs {socket:type2:voltage} volt" - }, - "35": { - "mappings": { - "0": { - "then": "Type 2 (mennekes) outputs at most 16 A" - }, - "1": { - "then": "Type 2 (mennekes) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 2 (mennekes) offer?", - "render": "Type 2 (mennekes) outputs at most {socket:type2:current}A" - }, - "36": { - "mappings": { - "0": { - "then": "Type 2 (mennekes) outputs at most 11 kw" - }, - "1": { - "then": "Type 2 (mennekes) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type Type 2 (mennekes) offer?", - "render": "Type 2 (mennekes) outputs at most {socket:type2:output}" - }, - "37": { - "question": "How much plugs of type Type 2 CCS (mennekes) are available here?", - "render": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here" - }, - "38": { - "mappings": { - "0": { - "then": "Type 2 CCS (mennekes) outputs 500 volt" - }, - "1": { - "then": "Type 2 CCS (mennekes) outputs 920 volt" - } - }, - "question": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", - "render": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt" - }, - "39": { - "mappings": { - "0": { - "then": "Type 2 CCS (mennekes) outputs at most 125 A" - }, - "1": { - "then": "Type 2 CCS (mennekes) outputs at most 350 A" - } - }, - "question": "What current do the plugs with Type 2 CCS (mennekes) offer?", - "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A" - }, - "40": { - "mappings": { - "0": { - "then": "Type 2 CCS (mennekes) outputs at most 50 kw" - } - }, - "question": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", - "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}" - }, - "41": { - "question": "How much plugs of type Type 2 with cable (mennekes) are available here?", - "render": "There are Type 2 with cable (mennekes) plugs of type Type 2 with cable (mennekes) available here" - }, - "42": { - "mappings": { - "0": { - "then": "Type 2 with cable (mennekes) outputs 230 volt" - }, - "1": { - "then": "Type 2 with cable (mennekes) outputs 400 volt" - } - }, - "question": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", - "render": "Type 2 with cable (mennekes) outputs {socket:type2_cable:voltage} volt" - }, - "43": { - "mappings": { - "0": { - "then": "Type 2 with cable (mennekes) outputs at most 16 A" - }, - "1": { - "then": "Type 2 with cable (mennekes) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 2 with cable (mennekes) offer?", - "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:current}A" - }, - "44": { - "mappings": { - "0": { - "then": "Type 2 with cable (mennekes) outputs at most 11 kw" - }, - "1": { - "then": "Type 2 with cable (mennekes) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", - "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:output}" - }, - "45": { - "question": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", - "render": "There are Tesla Supercharger CCS (a branded type2_css) plugs of type Tesla Supercharger CCS (a branded type2_css) available here" - }, - "46": { - "mappings": { - "0": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt" - }, - "1": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs 920 volt" - } - }, - "question": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", - "render": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt" - }, - "47": { - "mappings": { - "0": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A" - }, - "1": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A" - } - }, - "question": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", - "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A" - }, - "48": { - "mappings": { - "0": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 50 kw" - } - }, - "question": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", - "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:output}" - }, - "49": { - "question": "How much plugs of type Tesla Supercharger (destination) are available here?", - "render": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here" - }, - "50": { - "mappings": { - "0": { - "then": "Tesla Supercharger (destination) outputs 480 volt" - } - }, - "question": "What voltage do the plugs with Tesla Supercharger (destination) offer?", - "render": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt" - }, - "51": { - "mappings": { - "0": { - "then": "Tesla Supercharger (destination) outputs at most 125 A" - }, - "1": { - "then": "Tesla Supercharger (destination) outputs at most 350 A" - } - }, - "question": "What current do the plugs with Tesla Supercharger (destination) offer?", - "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A" - }, - "52": { - "mappings": { - "0": { - "then": "Tesla Supercharger (destination) outputs at most 120 kw" - }, - "1": { - "then": "Tesla Supercharger (destination) outputs at most 150 kw" - }, - "2": { - "then": "Tesla Supercharger (destination) outputs at most 250 kw" - } - }, - "question": "What power output does a single plug of type Tesla Supercharger (destination) offer?", - "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:output}" - }, - "53": { - "question": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", - "render": "There are Tesla supercharger (destination (A Type 2 with cable branded as tesla) plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) available here" - }, - "54": { - "mappings": { - "0": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt" - }, - "1": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt" - } - }, - "question": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt" - }, - "55": { - "mappings": { - "0": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 16 A" - }, - "1": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:current}A" - }, - "56": { - "mappings": { - "0": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 11 kw" - }, - "1": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:output}" - }, - "57": { - "mappings": { - "0": { - "then": "Authentication by a membership card" - }, - "1": { - "then": "Authentication by an app" - }, - "2": { - "then": "Authentication via phone call is available" - }, - "3": { - "then": "Authentication via phone call is available" - }, - "4": { - "then": "Authentication via NFC is available" - }, - "5": { - "then": "Authentication via Money Card is available" - }, - "6": { - "then": "Authentication via debit card is available" - }, - "7": { - "then": "No authentication is needed" - } - }, - "question": "What kind of authentication is available at the charging station?" - }, - "58": { - "question": "What's the phone number for authentication call or SMS?", - "render": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}" - }, - "59": { - "mappings": { - "0": { - "then": "24/7 opened (including holidays)" - } - }, - "question": "When is this charging station opened?" - }, - "60": { - "mappings": { - "0": { - "then": "Free to use" - } - }, - "question": "How much does one have to pay to use this charging station?", - "render": "Using this charging station costs {charge}" - }, - "61": { - "override": { - "mappings": { - "0": { - "then": "Payment is done using a dedicated app" - } - }, - "mappings+": { - "0": { - "then": "Payment is done using a dedicated app" - } - } - } - }, - "62": { - "mappings": { - "0": { - "then": "No timelimit on leaving your vehicle here" - } - }, - "question": "What is the maximum amount of time one is allowed to stay here?", - "render": "One can stay at most {canonical(maxstay)}" - }, - "63": { + "Network": { "mappings": { "0": { "then": "Not part of a bigger network" @@ -1623,22 +1059,15 @@ "question": "Is this charging station part of a network?", "render": "Part of the network {network}" }, - "65": { - "question": "What number can one call if there is a problem with this charging station?", - "render": "In case of problems, call {phone}" + "OH": { + "mappings": { + "0": { + "then": "24/7 opened (including holidays)" + } + }, + "question": "When is this charging station opened?" }, - "66": { - "question": "What is the email address of the operator?", - "render": "In case of problems, send an email to {email}" - }, - "67": { - "question": "What is the website of the operator?", - "render": "More info on {website}" - }, - "69": { - "question": "What is the reference number of this charging station?" - }, - "70": { + "Operational status": { "mappings": { "0": { "then": "This charging station is broken" @@ -1658,7 +1087,7 @@ }, "question": "Is this charging point in use?" }, - "71": { + "Parking:fee": { "mappings": { "0": { "then": "No additional parking cost while charging" @@ -1668,6 +1097,577 @@ } }, "question": "Does one have to pay a parking fee while charging?" + }, + "Type": { + "mappings": { + "0": { + "then": "bicycles can be charged here" + }, + "1": { + "then": "Cars can be charged here" + }, + "2": { + "then": "Scooters can be charged here" + }, + "3": { + "then": "Heavy good vehicles (such as trucks) can be charged here" + }, + "4": { + "then": "Buses can be charged here" + } + }, + "question": "Which vehicles are allowed to charge here?" + }, + "access": { + "question": "Who is allowed to use this charging station?", + "render": "Access is {access}" + }, + "capacity": { + "question": "How much vehicles can be charged here at the same time?", + "render": "{capacity} vehicles can be charged here at the same time" + }, + "current-0": { + "mappings": { + "0": { + "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A" + } + }, + "question": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:current}A" + }, + "current-1": { + "mappings": { + "0": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A" + } + }, + "question": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A" + }, + "current-10": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A" + }, + "current-11": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger (destination) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A" + }, + "current-12": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 16 A" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:current}A" + }, + "current-2": { + "mappings": { + "0": { + "then": "Chademo outputs at most 120 A" + } + }, + "question": "What current do the plugs with Chademo offer?", + "render": "Chademo outputs at most {socket:chademo:current}A" + }, + "current-3": { + "mappings": { + "0": { + "then": "Type 1 with cable (J1772) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 1 with cable (J1772) offer?", + "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A" + }, + "current-4": { + "mappings": { + "0": { + "then": "Type 1 without cable (J1772) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 1 without cable (J1772) offer?", + "render": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A" + }, + "current-5": { + "mappings": { + "0": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A" + }, + "1": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A" + } + }, + "question": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A" + }, + "current-6": { + "mappings": { + "0": { + "then": "Tesla Supercharger outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger offer?", + "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A" + }, + "current-7": { + "mappings": { + "0": { + "then": "Type 2 (mennekes) outputs at most 16 A" + }, + "1": { + "then": "Type 2 (mennekes) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 2 (mennekes) offer?", + "render": "Type 2 (mennekes) outputs at most {socket:type2:current}A" + }, + "current-8": { + "mappings": { + "0": { + "then": "Type 2 CCS (mennekes) outputs at most 125 A" + }, + "1": { + "then": "Type 2 CCS (mennekes) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Type 2 CCS (mennekes) offer?", + "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A" + }, + "current-9": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs at most 16 A" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:current}A" + }, + "email": { + "question": "What is the email address of the operator?", + "render": "In case of problems, send an email to {email}" + }, + "fee/charge": { + "mappings": { + "0": { + "then": "Free to use" + } + }, + "question": "How much does one have to pay to use this charging station?", + "render": "Using this charging station costs {charge}" + }, + "maxstay": { + "mappings": { + "0": { + "then": "No timelimit on leaving your vehicle here" + } + }, + "question": "What is the maximum amount of time one is allowed to stay here?", + "render": "One can stay at most {canonical(maxstay)}" + }, + "payment-options": { + "override": { + "mappings": { + "0": { + "then": "Payment is done using a dedicated app" + } + }, + "mappings+": { + "0": { + "then": "Payment is done using a dedicated app" + } + } + } + }, + "phone": { + "question": "What number can one call if there is a problem with this charging station?", + "render": "In case of problems, call {phone}" + }, + "plugs-0": { + "question": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", + "render": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here" + }, + "plugs-1": { + "question": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", + "render": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here" + }, + "plugs-10": { + "question": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", + "render": "There are Tesla Supercharger CCS (a branded type2_css) plugs of type Tesla Supercharger CCS (a branded type2_css) available here" + }, + "plugs-11": { + "question": "How much plugs of type Tesla Supercharger (destination) are available here?", + "render": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here" + }, + "plugs-12": { + "question": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", + "render": "There are Tesla supercharger (destination (A Type 2 with cable branded as tesla) plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) available here" + }, + "plugs-2": { + "question": "How much plugs of type Chademo are available here?", + "render": "There are Chademo plugs of type Chademo available here" + }, + "plugs-3": { + "question": "How much plugs of type Type 1 with cable (J1772) are available here?", + "render": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here" + }, + "plugs-4": { + "question": "How much plugs of type Type 1 without cable (J1772) are available here?", + "render": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here" + }, + "plugs-5": { + "question": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", + "render": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here" + }, + "plugs-6": { + "question": "How much plugs of type Tesla Supercharger are available here?", + "render": "There are Tesla Supercharger plugs of type Tesla Supercharger available here" + }, + "plugs-7": { + "question": "How much plugs of type Type 2 (mennekes) are available here?", + "render": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here" + }, + "plugs-8": { + "question": "How much plugs of type Type 2 CCS (mennekes) are available here?", + "render": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here" + }, + "plugs-9": { + "question": "How much plugs of type Type 2 with cable (mennekes) are available here?", + "render": "There are Type 2 with cable (mennekes) plugs of type Type 2 with cable (mennekes) available here" + }, + "power-output-0": { + "mappings": { + "0": { + "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw" + } + }, + "question": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}" + }, + "power-output-1": { + "mappings": { + "0": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw" + }, + "1": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", + "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}" + }, + "power-output-10": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 50 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:output}" + }, + "power-output-11": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs at most 120 kw" + }, + "1": { + "then": "Tesla Supercharger (destination) outputs at most 150 kw" + }, + "2": { + "then": "Tesla Supercharger (destination) outputs at most 250 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:output}" + }, + "power-output-12": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 11 kw" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:output}" + }, + "power-output-2": { + "mappings": { + "0": { + "then": "Chademo outputs at most 50 kw" + } + }, + "question": "What power output does a single plug of type Chademo offer?", + "render": "Chademo outputs at most {socket:chademo:output}" + }, + "power-output-3": { + "mappings": { + "0": { + "then": "Type 1 with cable (J1772) outputs at most 3.7 kw" + }, + "1": { + "then": "Type 1 with cable (J1772) outputs at most 7 kw" + } + }, + "question": "What power output does a single plug of type Type 1 with cable (J1772) offer?", + "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}" + }, + "power-output-4": { + "mappings": { + "0": { + "then": "Type 1 without cable (J1772) outputs at most 3.7 kw" + }, + "1": { + "then": "Type 1 without cable (J1772) outputs at most 6.6 kw" + }, + "2": { + "then": "Type 1 without cable (J1772) outputs at most 7 kw" + }, + "3": { + "then": "Type 1 without cable (J1772) outputs at most 7.2 kw" + } + }, + "question": "What power output does a single plug of type Type 1 without cable (J1772) offer?", + "render": "Type 1 without cable (J1772) outputs at most {socket:type1:output}" + }, + "power-output-5": { + "mappings": { + "0": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw" + }, + "1": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw" + }, + "2": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw" + }, + "3": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw" + } + }, + "question": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", + "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}" + }, + "power-output-6": { + "mappings": { + "0": { + "then": "Tesla Supercharger outputs at most 120 kw" + }, + "1": { + "then": "Tesla Supercharger outputs at most 150 kw" + }, + "2": { + "then": "Tesla Supercharger outputs at most 250 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger offer?", + "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}" + }, + "power-output-7": { + "mappings": { + "0": { + "then": "Type 2 (mennekes) outputs at most 11 kw" + }, + "1": { + "then": "Type 2 (mennekes) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Type 2 (mennekes) offer?", + "render": "Type 2 (mennekes) outputs at most {socket:type2:output}" + }, + "power-output-8": { + "mappings": { + "0": { + "then": "Type 2 CCS (mennekes) outputs at most 50 kw" + } + }, + "question": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", + "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}" + }, + "power-output-9": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs at most 11 kw" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:output}" + }, + "ref": { + "question": "What is the reference number of this charging station?" + }, + "voltage-0": { + "mappings": { + "0": { + "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt" + } + }, + "question": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt" + }, + "voltage-1": { + "mappings": { + "0": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt" + } + }, + "question": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "render": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt" + }, + "voltage-10": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt" + }, + "1": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs 920 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt" + }, + "voltage-11": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs 480 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt" + }, + "voltage-12": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt" + }, + "voltage-2": { + "mappings": { + "0": { + "then": "Chademo outputs 500 volt" + } + }, + "question": "What voltage do the plugs with Chademo offer?", + "render": "Chademo outputs {socket:chademo:voltage} volt" + }, + "voltage-3": { + "mappings": { + "0": { + "then": "Type 1 with cable (J1772) outputs 200 volt" + }, + "1": { + "then": "Type 1 with cable (J1772) outputs 240 volt" + } + }, + "question": "What voltage do the plugs with Type 1 with cable (J1772) offer?", + "render": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt" + }, + "voltage-4": { + "mappings": { + "0": { + "then": "Type 1 without cable (J1772) outputs 200 volt" + }, + "1": { + "then": "Type 1 without cable (J1772) outputs 240 volt" + } + }, + "question": "What voltage do the plugs with Type 1 without cable (J1772) offer?", + "render": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt" + }, + "voltage-5": { + "mappings": { + "0": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt" + }, + "1": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt" + } + }, + "question": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "render": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt" + }, + "voltage-6": { + "mappings": { + "0": { + "then": "Tesla Supercharger outputs 480 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger offer?", + "render": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt" + }, + "voltage-7": { + "mappings": { + "0": { + "then": "Type 2 (mennekes) outputs 230 volt" + }, + "1": { + "then": "Type 2 (mennekes) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Type 2 (mennekes) offer?", + "render": "Type 2 (mennekes) outputs {socket:type2:voltage} volt" + }, + "voltage-8": { + "mappings": { + "0": { + "then": "Type 2 CCS (mennekes) outputs 500 volt" + }, + "1": { + "then": "Type 2 CCS (mennekes) outputs 920 volt" + } + }, + "question": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", + "render": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt" + }, + "voltage-9": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs 230 volt" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs {socket:type2_cable:voltage} volt" + }, + "website": { + "question": "What is the website of the operator?", + "render": "More info on {website}" } }, "title": { @@ -1730,32 +1730,7 @@ } }, "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "Crossing, without traffic lights" - }, - "1": { - "then": "Crossing with traffic signals" - }, - "2": { - "then": "Zebra crossing" - } - }, - "question": "What kind of crossing is this?" - }, - "1": { - "mappings": { - "0": { - "then": "This is a zebra crossing" - }, - "1": { - "then": "This is not a zebra crossing" - } - }, - "question": "Is this is a zebra crossing?" - }, - "2": { + "crossing-bicycle-allowed": { "mappings": { "0": { "then": "A cyclist can use this crossing" @@ -1766,32 +1741,7 @@ }, "question": "Is this crossing also for bicycles?" }, - "3": { - "mappings": { - "0": { - "then": "This crossing has an island in the middle" - }, - "1": { - "then": "This crossing does not have an island in the middle" - } - }, - "question": "Does this crossing have an island in the middle?" - }, - "4": { - "mappings": { - "0": { - "then": "This crossing has tactile paving" - }, - "1": { - "then": "This crossing does not have tactile paving" - }, - "2": { - "then": "This crossing has tactile paving, but is not correct" - } - }, - "question": "Does this crossing have tactile paving?" - }, - "5": { + "crossing-button": { "mappings": { "0": { "then": "This traffic light has a button to request green light" @@ -1802,7 +1752,43 @@ }, "question": "Does this traffic light have a button to request green light?" }, - "6": { + "crossing-continue-through-red": { + "mappings": { + "0": { + "then": "A cyclist can go straight on if the light is red " + }, + "1": { + "then": "A cyclist can go straight on if the light is red" + }, + "2": { + "then": "A cyclist can not go straight on if the light is red" + } + }, + "question": "Can a cyclist go straight on when the light is red?" + }, + "crossing-has-island": { + "mappings": { + "0": { + "then": "This crossing has an island in the middle" + }, + "1": { + "then": "This crossing does not have an island in the middle" + } + }, + "question": "Does this crossing have an island in the middle?" + }, + "crossing-is-zebra": { + "mappings": { + "0": { + "then": "This is a zebra crossing" + }, + "1": { + "then": "This is not a zebra crossing" + } + }, + "question": "Is this is a zebra crossing?" + }, + "crossing-right-turn-through-red": { "mappings": { "0": { "then": "A cyclist can turn right if the light is red " @@ -1816,19 +1802,33 @@ }, "question": "Can a cyclist turn right when the light is red?" }, - "7": { + "crossing-tactile": { "mappings": { "0": { - "then": "A cyclist can go straight on if the light is red " + "then": "This crossing has tactile paving" }, "1": { - "then": "A cyclist can go straight on if the light is red" + "then": "This crossing does not have tactile paving" }, "2": { - "then": "A cyclist can not go straight on if the light is red" + "then": "This crossing has tactile paving, but is not correct" } }, - "question": "Can a cyclist go straight on when the light is red?" + "question": "Does this crossing have tactile paving?" + }, + "crossing-type": { + "mappings": { + "0": { + "then": "Crossing, without traffic lights" + }, + "1": { + "then": "Crossing with traffic signals" + }, + "2": { + "then": "Zebra crossing" + } + }, + "question": "What kind of crossing is this?" } }, "title": { @@ -1846,7 +1846,7 @@ "cycleways_and_roads": { "name": "Cycleways and roads", "tagRenderings": { - "0": { + "Cycleway type for a road": { "mappings": { "0": { "then": "There is a shared lane" @@ -1869,59 +1869,36 @@ }, "question": "What kind of cycleway is here?" }, - "1": { + "Cycleway:smoothness": { "mappings": { "0": { - "then": "This street is lit" + "then": "Usable for thin rollers: rollerblade, skateboard" }, "1": { - "then": "This road is not lit" + "then": "Usable for thin wheels: racing bike" }, "2": { - "then": "This road is lit at night" + "then": "Usable for normal wheels: city bike, wheelchair, scooter" }, "3": { - "then": "This road is lit 24/7" - } - }, - "question": "Is this street lit?" - }, - "2": { - "mappings": { - "0": { - "then": "This is a cyclestreet, and a 30km/h zone." - }, - "1": { - "then": "This is a cyclestreet" - }, - "2": { - "then": "This is not a cyclestreet." - } - }, - "question": "Is this a cyclestreet?" - }, - "3": { - "mappings": { - "0": { - "then": "The maximum speed is 20 km/h" - }, - "1": { - "then": "The maximum speed is 30 km/h" - }, - "2": { - "then": "The maximum speed is 50 km/h" - }, - "3": { - "then": "The maximum speed is 70 km/h" + "then": "Usable for robust wheels: trekking bike, car, rickshaw" }, "4": { - "then": "The maximum speed is 90 km/h" + "then": "Usable for vehicles with high clearance: light duty off-road vehicle" + }, + "5": { + "then": "Usable for off-road vehicles: heavy duty off-road vehicle" + }, + "6": { + "then": "Usable for specialized off-road vehicles: tractor, ATV" + }, + "7": { + "then": "Impassable / No wheeled vehicle" } }, - "question": "What is the maximum speed in this street?", - "render": "The maximum speed on this road is {maxspeed} km/h" + "question": "What is the smoothness of this cycleway?" }, - "4": { + "Cycleway:surface": { "mappings": { "0": { "then": "This cycleway is unpaved" @@ -1966,36 +1943,42 @@ "question": "What is the surface of the cycleway made from?", "render": "This cyleway is made of {cycleway:surface}" }, - "5": { + "Is this a cyclestreet? (For a road)": { "mappings": { "0": { - "then": "Usable for thin rollers: rollerblade, skateboard" + "then": "This is a cyclestreet, and a 30km/h zone." }, "1": { - "then": "Usable for thin wheels: racing bike" + "then": "This is a cyclestreet" }, "2": { - "then": "Usable for normal wheels: city bike, wheelchair, scooter" - }, - "3": { - "then": "Usable for robust wheels: trekking bike, car, rickshaw" - }, - "4": { - "then": "Usable for vehicles with high clearance: light duty off-road vehicle" - }, - "5": { - "then": "Usable for off-road vehicles: heavy duty off-road vehicle" - }, - "6": { - "then": "Usable for specialized off-road vehicles: tractor, ATV" - }, - "7": { - "then": "Impassable / No wheeled vehicle" + "then": "This is not a cyclestreet." } }, - "question": "What is the smoothness of this cycleway?" + "question": "Is this a cyclestreet?" }, - "6": { + "Maxspeed (for road)": { + "mappings": { + "0": { + "then": "The maximum speed is 20 km/h" + }, + "1": { + "then": "The maximum speed is 30 km/h" + }, + "2": { + "then": "The maximum speed is 50 km/h" + }, + "3": { + "then": "The maximum speed is 70 km/h" + }, + "4": { + "then": "The maximum speed is 90 km/h" + } + }, + "question": "What is the maximum speed in this street?", + "render": "The maximum speed on this road is {maxspeed} km/h" + }, + "Surface of the road": { "mappings": { "0": { "then": "This cycleway is unhardened" @@ -2040,7 +2023,7 @@ "question": "What is the surface of the street made from?", "render": "This road is made of {surface}" }, - "7": { + "Surface of the street": { "mappings": { "0": { "then": "Usable for thin rollers: rollerblade, skateboard" @@ -2069,11 +2052,24 @@ }, "question": "What is the smoothness of this street?" }, - "8": { - "question": "What is the carriage width of this road (in meters)?", - "render": "The carriage width of this road is {width:carriageway}m" + "cyclelan-segregation": { + "mappings": { + "0": { + "then": "This cycleway is separated by a dashed line" + }, + "1": { + "then": "This cycleway is separated by a solid line" + }, + "2": { + "then": "This cycleway is separated by a parking lane" + }, + "3": { + "then": "This cycleway is separated by a kerb" + } + }, + "question": "How is this cycleway separated from the road?" }, - "9": { + "cycleway-lane-track-traffic-signs": { "mappings": { "0": { "then": "Compulsory cycleway " @@ -2093,7 +2089,24 @@ }, "question": "What traffic sign does this cycleway have?" }, - "10": { + "cycleway-segregation": { + "mappings": { + "0": { + "then": "This cycleway is separated by a dashed line" + }, + "1": { + "then": "This cycleway is separated by a solid line" + }, + "2": { + "then": "This cycleway is separated by a parking lane" + }, + "3": { + "then": "This cycleway is separated by a kerb" + } + }, + "question": "How is this cycleway separated from the road?" + }, + "cycleway-traffic-signs": { "mappings": { "0": { "then": "Compulsory cycleway " @@ -2113,7 +2126,7 @@ }, "question": "What traffic sign does this cycleway have?" }, - "11": { + "cycleway-traffic-signs-D7-supplementary": { "mappings": { "0": { "then": "" @@ -2139,7 +2152,7 @@ }, "question": "Does the traffic sign D7 () have a supplementary sign?" }, - "12": { + "cycleway-traffic-signs-supplementary": { "mappings": { "0": { "then": "" @@ -2165,43 +2178,30 @@ }, "question": "Does the traffic sign D7 () have a supplementary sign?" }, - "13": { + "cycleways_and_roads-cycleway:buffer": { "question": "How wide is the gap between the cycleway and the road?", "render": "The buffer besides this cycleway is {cycleway:buffer} m" }, - "14": { + "is lit?": { "mappings": { "0": { - "then": "This cycleway is separated by a dashed line" + "then": "This street is lit" }, "1": { - "then": "This cycleway is separated by a solid line" + "then": "This road is not lit" }, "2": { - "then": "This cycleway is separated by a parking lane" + "then": "This road is lit at night" }, "3": { - "then": "This cycleway is separated by a kerb" + "then": "This road is lit 24/7" } }, - "question": "How is this cycleway separated from the road?" + "question": "Is this street lit?" }, - "15": { - "mappings": { - "0": { - "then": "This cycleway is separated by a dashed line" - }, - "1": { - "then": "This cycleway is separated by a solid line" - }, - "2": { - "then": "This cycleway is separated by a parking lane" - }, - "3": { - "then": "This cycleway is separated by a kerb" - } - }, - "question": "How is this cycleway separated from the road?" + "width:carriageway": { + "question": "What is the carriage width of this road (in meters)?", + "render": "The carriage width of this road is {width:carriageway}m" } }, "title": { @@ -2240,18 +2240,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "This defibrillator is located indoors" - }, - "1": { - "then": "This defibrillator is located outdoors" - } - }, - "question": "Is this defibrillator located indoors?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Publicly accessible" @@ -2272,7 +2261,7 @@ "question": "Is this defibrillator freely accessible?", "render": "Access is {access}" }, - "3": { + "defibrillator-defibrillator": { "mappings": { "0": { "then": "This is a manual defibrillator for professionals" @@ -2284,7 +2273,42 @@ "question": "Is this a a regular automatic defibrillator or a manual defibrillator for professionals only?", "render": "There is no info about the type of device" }, - "4": { + "defibrillator-defibrillator:location": { + "question": "Please give some explanation on where the defibrillator can be found (in the local language)", + "render": "Extra information about the location (in the local languagel):
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:en": { + "question": "Please give some explanation on where the defibrillator can be found (in English)", + "render": "Extra information about the location (in English):
{defibrillator:location:en}" + }, + "defibrillator-defibrillator:location:fr": { + "question": "Please give some explanation on where the defibrillator can be found (in French)", + "render": "Extra information about the location (in French):
{defibrillator:location:fr}" + }, + "defibrillator-description": { + "question": "Is there any useful information for users that you haven't been able to describe above? (leave blank if no)", + "render": "Additional information: {description}" + }, + "defibrillator-email": { + "question": "What is the email for questions about this defibrillator?", + "render": "Email for questions about this defibrillator: {email}" + }, + "defibrillator-fixme": { + "question": "Is there something wrong with how this is mapped, that you weren't able to fix here? (leave a note to OpenStreetMap experts)", + "render": "Extra information for OpenStreetMap experts: {fixme}" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "This defibrillator is located indoors" + }, + "1": { + "then": "This defibrillator is located outdoors" + } + }, + "question": "Is this defibrillator located indoors?" + }, + "defibrillator-level": { "mappings": { "0": { "then": "This defibrillator is on the ground floor" @@ -2296,31 +2320,7 @@ "question": "On which floor is this defibrillator located?", "render": "This defibrillator is on floor {level}" }, - "5": { - "question": "Please give some explanation on where the defibrillator can be found (in the local language)", - "render": "Extra information about the location (in the local languagel):
{defibrillator:location}" - }, - "6": { - "question": "Please give some explanation on where the defibrillator can be found (in English)", - "render": "Extra information about the location (in English):
{defibrillator:location:en}" - }, - "7": { - "question": "Please give some explanation on where the defibrillator can be found (in French)", - "render": "Extra information about the location (in French):
{defibrillator:location:fr}" - }, - "9": { - "question": "What is the official identification number of the device? (if visible on device)", - "render": "Official identification number of the device: {ref}" - }, - "10": { - "question": "What is the email for questions about this defibrillator?", - "render": "Email for questions about this defibrillator: {email}" - }, - "11": { - "question": "What is the phone number for questions about this defibrillator?", - "render": "Telephone for questions about this defibrillator: {phone}" - }, - "12": { + "defibrillator-opening_hours": { "mappings": { "0": { "then": "24/7 opened (including holidays)" @@ -2329,11 +2329,15 @@ "question": "At what times is this defibrillator available?", "render": "{opening_hours_table(opening_hours)}" }, - "13": { - "question": "Is there any useful information for users that you haven't been able to describe above? (leave blank if no)", - "render": "Additional information: {description}" + "defibrillator-phone": { + "question": "What is the phone number for questions about this defibrillator?", + "render": "Telephone for questions about this defibrillator: {phone}" }, - "14": { + "defibrillator-ref": { + "question": "What is the official identification number of the device? (if visible on device)", + "render": "Official identification number of the device: {ref}" + }, + "defibrillator-survey:date": { "mappings": { "0": { "then": "Checked today!" @@ -2341,10 +2345,6 @@ }, "question": "When was this defibrillator last surveyed?", "render": "This defibrillator was last surveyed on {survey:date}" - }, - "15": { - "question": "Is there something wrong with how this is mapped, that you weren't able to fix here? (leave a note to OpenStreetMap experts)", - "render": "Extra information for OpenStreetMap experts: {fixme}" } }, "title": { @@ -2363,7 +2363,18 @@ } }, "tagRenderings": { - "1": { + "Bottle refill": { + "mappings": { + "0": { + "then": "It is easy to refill water bottles" + }, + "1": { + "then": "Water bottles may not fit" + } + }, + "question": "How easy is it to fill water bottles?" + }, + "Still in use?": { "mappings": { "0": { "then": "This drinking water works" @@ -2378,18 +2389,7 @@ "question": "Is this drinking water spot still operational?", "render": "The operational status is {operational_status" }, - "2": { - "mappings": { - "0": { - "then": "It is easy to refill water bottles" - }, - "1": { - "then": "Water bottles may not fit" - } - }, - "question": "How easy is it to fill water bottles?" - }, - "3": { + "render-closest-drinking-water": { "render": "There is another drinking water fountain at {_closest_other_drinking_water_distance} meter" } }, @@ -2443,14 +2443,7 @@ } }, "tagRenderings": { - "1": { - "question": "What is the name of this restaurant?", - "render": "The name of this restaurant is {name}" - }, - "2": { - "question": "What type of business is this?" - }, - "9": { + "Cuisine": { "mappings": { "0": { "then": "This is a pizzeria" @@ -2465,7 +2458,14 @@ "question": "Which food is served here?", "render": "This place mostly serves {cuisine}" }, - "10": { + "Fastfood vs restaurant": { + "question": "What type of business is this?" + }, + "Name": { + "question": "What is the name of this restaurant?", + "render": "The name of this restaurant is {name}" + }, + "Takeaway": { "mappings": { "0": { "then": "This is a take-away only business" @@ -2479,10 +2479,24 @@ }, "question": "Does this place offer takea-way?" }, - "11": { + "Vegetarian (no friture)": { "question": "Does this restaurant have a vegetarian option?" }, - "13": { + "friture-take-your-container": { + "mappings": { + "0": { + "then": "You can bring your own containers to get your order, saving on single-use packaging material and thus waste" + }, + "1": { + "then": "Bringing your own container is not allowed" + }, + "2": { + "then": "You must bring your own container to order here." + } + }, + "question": "If you bring your own container (such as a cooking pot and small pots), is it used to package your order?
" + }, + "halal (no friture)": { "mappings": { "0": { "then": "There are no halal options available" @@ -2498,20 +2512,6 @@ } }, "question": "Does this restaurant offer a halal menu?" - }, - "17": { - "mappings": { - "0": { - "then": "You can bring your own containers to get your order, saving on single-use packaging material and thus waste" - }, - "1": { - "then": "Bringing your own container is not allowed" - }, - "2": { - "then": "You must bring your own container to order here." - } - }, - "question": "If you bring your own container (such as a cooking pot and small pots), is it used to package your order?
" } }, "title": { @@ -2533,10 +2533,14 @@ } }, "tagRenderings": { - "0": { + "ghost-bike-explanation": { "render": "A ghost bike is a memorial for a cyclist who died in a traffic accident, in the form of a white bicycle placed permanently near the accident location." }, - "2": { + "ghost_bike-inscription": { + "question": "What is the inscription on this Ghost bike?", + "render": "{inscription}" + }, + "ghost_bike-name": { "mappings": { "0": { "then": "No name is marked on the bike" @@ -2545,15 +2549,11 @@ "question": "Whom is remembered by this ghost bike?
Please respect privacy - only fill out the name if it is widely published or marked on the cycle. Opt to leave out the family name.
", "render": "In remembrance of {name}" }, - "3": { + "ghost_bike-source": { "question": "On what webpage can one find more information about the Ghost bike or the accident?", "render": "More information is available" }, - "4": { - "question": "What is the inscription on this Ghost bike?", - "render": "{inscription}" - }, - "5": { + "ghost_bike-start_date": { "question": "When was this Ghost bike installed?", "render": "Placed on {start_date}" } @@ -2588,16 +2588,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "This map is based on OpenStreetMap" - } - }, - "question": "On which data is this map based?", - "render": "This map is based on {map_source}" - }, - "2": { + "map-attribution": { "mappings": { "0": { "then": "OpenStreetMap is clearly attributed, including the ODBL-license" @@ -2616,6 +2607,15 @@ } }, "question": "Is the OpenStreetMap-attribution given?" + }, + "map-map_source": { + "mappings": { + "0": { + "then": "This map is based on OpenStreetMap" + } + }, + "question": "On which data is this map based?", + "render": "This map is based on {map_source}" } }, "title": { @@ -2624,7 +2624,11 @@ }, "nature_reserve": { "tagRenderings": { - "5": { + "Curator": { + "question": "Whom is the curator of this nature reserve?
Respect privacy - only fill out a name if this is widely published", + "render": "{curator} is the curator of this nature reserve" + }, + "Dogs?": { "mappings": { "0": { "then": "Dogs have to be leashed" @@ -2638,23 +2642,19 @@ }, "question": "Are dogs allowed in this nature reserve?" }, - "6": { - "question": "On which webpage can one find more information about this nature reserve?" - }, - "7": { - "question": "Whom is the curator of this nature reserve?
Respect privacy - only fill out a name if this is widely published", - "render": "{curator} is the curator of this nature reserve" - }, - "8": { + "Email": { "question": "What email adress can one send to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal email address if this is widely published", "render": "{email}" }, - "9": { + "Surface area": { + "render": "Surface area: {_surface:ha}Ha" + }, + "Website": { + "question": "On which webpage can one find more information about this nature reserve?" + }, + "phone": { "question": "What phone number can one call to with questions and problems with this nature reserve?
Respect privacy - only fill out a personal phone number address if this is widely published", "render": "{phone}" - }, - "12": { - "render": "Surface area: {_surface:ha}Ha" } } }, @@ -2667,24 +2667,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "This tower doesn't have a specific name" - } - }, - "question": "What is the name of this tower?", - "render": "This tower is called {name}" - }, - "2": { - "question": "What is the height of this tower?", - "render": "This tower is {height} high" - }, - "3": { - "question": "Who maintains this tower?", - "render": "Maintained by {operator}" - }, - "5": { + "Fee": { "mappings": { "0": { "then": "Free to visit" @@ -2692,6 +2675,23 @@ }, "question": "How much does one have to pay to enter this tower?", "render": "Visiting this tower costs {charge}" + }, + "Height": { + "question": "What is the height of this tower?", + "render": "This tower is {height} high" + }, + "Operator": { + "question": "Who maintains this tower?", + "render": "Maintained by {operator}" + }, + "name": { + "mappings": { + "0": { + "then": "This tower doesn't have a specific name" + } + }, + "question": "What is the name of this tower?", + "render": "This tower is called {name}" } }, "title": { @@ -2721,7 +2721,7 @@ } }, "tagRenderings": { - "0": { + "picnic_table-material": { "mappings": { "0": { "then": "This is a wooden picnic table" @@ -2747,7 +2747,86 @@ } }, "tagRenderings": { - "1": { + "Playground-wheelchair": { + "mappings": { + "0": { + "then": "Completely accessible for wheelchair users" + }, + "1": { + "then": "Limited accessibility for wheelchair users" + }, + "2": { + "then": "Not accessible for wheelchair users" + } + }, + "question": "Is this playground accessible to wheelchair users?" + }, + "playground-access": { + "mappings": { + "0": { + "then": "Accessible to the general public" + }, + "1": { + "then": "Accessible to the general public" + }, + "2": { + "then": "Only accessible for clients of the operating business" + }, + "3": { + "then": "Only accessible to students of the school" + }, + "4": { + "then": "Not accessible" + } + }, + "question": "Is this playground accessible to the general public?" + }, + "playground-email": { + "question": "What is the email address of the playground maintainer?", + "render": "{email}" + }, + "playground-lit": { + "mappings": { + "0": { + "then": "This playground is lit at night" + }, + "1": { + "then": "This playground is not lit at night" + } + }, + "question": "Is this playground lit at night?" + }, + "playground-max_age": { + "question": "What is the maximum age allowed to access this playground?", + "render": "Accessible to kids of at most {max_age}" + }, + "playground-min_age": { + "question": "What is the minimum age required to access this playground?", + "render": "Accessible to kids older than {min_age} years" + }, + "playground-opening_hours": { + "mappings": { + "0": { + "then": "Accessible from sunrise till sunset" + }, + "1": { + "then": "Always accessible" + }, + "2": { + "then": "Always accessible" + } + }, + "question": "When is this playground accessible?" + }, + "playground-operator": { + "question": "Who operates this playground?", + "render": "Operated by {operator}" + }, + "playground-phone": { + "question": "What is the phone number of the playground maintainer?", + "render": "{phone}" + }, + "playground-surface": { "mappings": { "0": { "then": "The surface is grass" @@ -2776,85 +2855,6 @@ }, "question": "Which is the surface of this playground?
If there are multiple, select the most occuring one", "render": "The surface is {surface}" - }, - "2": { - "mappings": { - "0": { - "then": "This playground is lit at night" - }, - "1": { - "then": "This playground is not lit at night" - } - }, - "question": "Is this playground lit at night?" - }, - "3": { - "question": "What is the minimum age required to access this playground?", - "render": "Accessible to kids older than {min_age} years" - }, - "4": { - "question": "What is the maximum age allowed to access this playground?", - "render": "Accessible to kids of at most {max_age}" - }, - "5": { - "question": "Who operates this playground?", - "render": "Operated by {operator}" - }, - "6": { - "mappings": { - "0": { - "then": "Accessible to the general public" - }, - "1": { - "then": "Accessible to the general public" - }, - "2": { - "then": "Only accessible for clients of the operating business" - }, - "3": { - "then": "Only accessible to students of the school" - }, - "4": { - "then": "Not accessible" - } - }, - "question": "Is this playground accessible to the general public?" - }, - "7": { - "question": "What is the email address of the playground maintainer?", - "render": "{email}" - }, - "8": { - "question": "What is the phone number of the playground maintainer?", - "render": "{phone}" - }, - "9": { - "mappings": { - "0": { - "then": "Completely accessible for wheelchair users" - }, - "1": { - "then": "Limited accessibility for wheelchair users" - }, - "2": { - "then": "Not accessible for wheelchair users" - } - }, - "question": "Is this playground accessible to wheelchair users?" - }, - "10": { - "mappings": { - "0": { - "then": "Accessible from sunrise till sunset" - }, - "1": { - "then": "Always accessible" - }, - "2": { - "then": "Always accessible" - } - }, - "question": "When is this playground accessible?" } }, "title": { @@ -2875,20 +2875,7 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "This bookcase doesn't have a name" - } - }, - "question": "What is the name of this public bookcase?", - "render": "The name of this bookcase is {name}" - }, - "3": { - "question": "How many books fit into this public bookcase?", - "render": "{capacity} books fit in this bookcase" - }, - "4": { + "bookcase-booktypes": { "mappings": { "0": { "then": "Mostly children books" @@ -2902,7 +2889,18 @@ }, "question": "What kind of books can be found in this public bookcase?" }, - "5": { + "bookcase-is-accessible": { + "mappings": { + "0": { + "then": "Publicly accessible" + }, + "1": { + "then": "Only accessible to customers" + } + }, + "question": "Is this public bookcase freely accessible?" + }, + "bookcase-is-indoors": { "mappings": { "0": { "then": "This bookcase is located indoors" @@ -2916,22 +2914,7 @@ }, "question": "Is this bookcase located outdoors?" }, - "6": { - "mappings": { - "0": { - "then": "Publicly accessible" - }, - "1": { - "then": "Only accessible to customers" - } - }, - "question": "Is this public bookcase freely accessible?" - }, - "7": { - "question": "Who maintains this public bookcase?", - "render": "Operated by {operator}" - }, - "8": { + "public_bookcase-brand": { "mappings": { "0": { "then": "Part of the network 'Little Free Library'" @@ -2943,7 +2926,24 @@ "question": "Is this public bookcase part of a bigger network?", "render": "This public bookcase is part of {brand}" }, - "9": { + "public_bookcase-capacity": { + "question": "How many books fit into this public bookcase?", + "render": "{capacity} books fit in this bookcase" + }, + "public_bookcase-name": { + "mappings": { + "0": { + "then": "This bookcase doesn't have a name" + } + }, + "question": "What is the name of this public bookcase?", + "render": "The name of this bookcase is {name}" + }, + "public_bookcase-operator": { + "question": "Who maintains this public bookcase?", + "render": "Operated by {operator}" + }, + "public_bookcase-ref": { "mappings": { "0": { "then": "This bookcase is not part of a bigger network" @@ -2952,11 +2952,11 @@ "question": "What is the reference number of this public bookcase?", "render": "The reference number of this public bookcase within {brand} is {ref}" }, - "10": { + "public_bookcase-start_date": { "question": "When was this public bookcase installed?", "render": "Installed on {start_date}" }, - "11": { + "public_bookcase-website": { "question": "Is there a website with more information about this public bookcase?", "render": "More info on the website" } @@ -2972,7 +2972,7 @@ }, "slow_roads": { "tagRenderings": { - "2": { + "slow_roads-surface": { "mappings": { "0": { "then": "The surface is grass" @@ -3015,7 +3015,55 @@ } }, "tagRenderings": { - "1": { + "sport-pitch-access": { + "mappings": { + "0": { + "then": "Public access" + }, + "1": { + "then": "Limited access (e.g. only with an appointment, during certain hours, ...)" + }, + "2": { + "then": "Only accessible for members of the club" + }, + "3": { + "then": "Private - not accessible to the public" + } + }, + "question": "Is this sport pitch publicly accessible?" + }, + "sport-pitch-reservation": { + "mappings": { + "0": { + "then": "Making an appointment is obligatory to use this sport pitch" + }, + "1": { + "then": "Making an appointment is recommended when using this sport pitch" + }, + "2": { + "then": "Making an appointment is possible, but not necessary to use this sport pitch" + }, + "3": { + "then": "Making an appointment is not possible" + } + }, + "question": "Does one have to make an appointment to use this sport pitch?" + }, + "sport_pitch-email": { + "question": "What is the email address of the operator?" + }, + "sport_pitch-opening_hours": { + "mappings": { + "1": { + "then": "Always accessible" + } + }, + "question": "When is this pitch accessible?" + }, + "sport_pitch-phone": { + "question": "What is the phone number of the operator?" + }, + "sport_pitch-sport": { "mappings": { "0": { "then": "Basketball is played here" @@ -3039,7 +3087,7 @@ "question": "Which sport can be played here?", "render": "{sport} is played here" }, - "2": { + "sport_pitch-surface": { "mappings": { "0": { "then": "The surface is grass" @@ -3059,54 +3107,6 @@ }, "question": "Which is the surface of this sport pitch?", "render": "The surface is {surface}" - }, - "3": { - "mappings": { - "0": { - "then": "Public access" - }, - "1": { - "then": "Limited access (e.g. only with an appointment, during certain hours, ...)" - }, - "2": { - "then": "Only accessible for members of the club" - }, - "3": { - "then": "Private - not accessible to the public" - } - }, - "question": "Is this sport pitch publicly accessible?" - }, - "4": { - "mappings": { - "0": { - "then": "Making an appointment is obligatory to use this sport pitch" - }, - "1": { - "then": "Making an appointment is recommended when using this sport pitch" - }, - "2": { - "then": "Making an appointment is possible, but not necessary to use this sport pitch" - }, - "3": { - "then": "Making an appointment is not possible" - } - }, - "question": "Does one have to make an appointment to use this sport pitch?" - }, - "5": { - "question": "What is the phone number of the operator?" - }, - "6": { - "question": "What is the email address of the operator?" - }, - "7": { - "mappings": { - "1": { - "then": "Always accessible" - } - }, - "question": "When is this pitch accessible?" } }, "title": { @@ -3116,7 +3116,7 @@ "surveillance_camera": { "name": "Surveillance camera's", "tagRenderings": { - "1": { + "Camera type: fixed; panning; dome": { "mappings": { "0": { "then": "A fixed (non-moving) camera" @@ -3130,34 +3130,7 @@ }, "question": "What kind of camera is this?" }, - "2": { - "mappings": { - "0": { - "then": "Films to a compass heading of {direction}" - } - }, - "question": "In which geographical direction does this camera film?", - "render": "Films to a compass heading of {camera:direction}" - }, - "3": { - "question": "Who operates this CCTV?", - "render": "Operated by {operator}" - }, - "4": { - "mappings": { - "0": { - "then": "A public area is surveilled, such as a street, a bridge, a square, a park, a train station, a public corridor or tunnel,..." - }, - "1": { - "then": "An outdoor, yet private area is surveilled (e.g. a parking lot, a fuel station, courtyard, entrance, private driveway, ...)" - }, - "2": { - "then": "A private indoor area is surveilled, e.g. a shop, a private underground parking, ..." - } - }, - "question": "What kind of surveillance is this camera" - }, - "5": { + "Indoor camera? This isn't clear for 'public'-cameras": { "mappings": { "0": { "then": "This camera is located indoors" @@ -3171,11 +3144,29 @@ }, "question": "Is the public space surveilled by this camera an indoor or outdoor space?" }, - "6": { + "Level": { "question": "On which level is this camera located?", "render": "Located on level {level}" }, - "7": { + "Operator": { + "question": "Who operates this CCTV?", + "render": "Operated by {operator}" + }, + "Surveillance type: public, outdoor, indoor": { + "mappings": { + "0": { + "then": "A public area is surveilled, such as a street, a bridge, a square, a park, a train station, a public corridor or tunnel,..." + }, + "1": { + "then": "An outdoor, yet private area is surveilled (e.g. a parking lot, a fuel station, courtyard, entrance, private driveway, ...)" + }, + "2": { + "then": "A private indoor area is surveilled, e.g. a shop, a private underground parking, ..." + } + }, + "question": "What kind of surveillance is this camera" + }, + "Surveillance:zone": { "mappings": { "0": { "then": "Surveills a parking" @@ -3199,7 +3190,7 @@ "question": "What exactly is surveilled here?", "render": " Surveills a {surveillance:zone}" }, - "8": { + "camera:mount": { "mappings": { "0": { "then": "This camera is placed against a wall" @@ -3213,6 +3204,15 @@ }, "question": "How is this camera placed?", "render": "Mounting method: {mount}" + }, + "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view": { + "mappings": { + "0": { + "then": "Films to a compass heading of {direction}" + } + }, + "question": "In which geographical direction does this camera film?", + "render": "Films to a compass heading of {camera:direction}" } }, "title": { @@ -3232,7 +3232,7 @@ } }, "tagRenderings": { - "1": { + "toilet-access": { "mappings": { "0": { "then": "Public access" @@ -3253,61 +3253,7 @@ "question": "Are these toilets publicly accessible?", "render": "Access is {access}" }, - "2": { - "mappings": { - "0": { - "then": "These are paid toilets" - }, - "1": { - "then": "Free to use" - } - }, - "question": "Are these toilets free to use?" - }, - "3": { - "question": "How much does one have to pay for these toilets?", - "render": "The fee is {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "There is a dedicated toilet for wheelchair users" - }, - "1": { - "then": "No wheelchair access" - } - }, - "question": "Is there a dedicated toilet for wheelchair users" - }, - "5": { - "mappings": { - "0": { - "then": "There are only seated toilets" - }, - "1": { - "then": "There are only urinals here" - }, - "2": { - "then": "There are only squat toilets here" - }, - "3": { - "then": "Both seated toilets and urinals are available here" - } - }, - "question": "Which kind of toilets are this?" - }, - "6": { - "mappings": { - "0": { - "then": "A changing table is available" - }, - "1": { - "then": "No changing table is available" - } - }, - "question": "Is a changing table (to change diapers) available?" - }, - "7": { + "toilet-changing_table:location": { "mappings": { "0": { "then": "The changing table is in the toilet for women. " @@ -3324,6 +3270,60 @@ }, "question": "Where is the changing table located?", "render": "The changing table is located at {changing_table:location}" + }, + "toilet-charge": { + "question": "How much does one have to pay for these toilets?", + "render": "The fee is {charge}" + }, + "toilets-changing-table": { + "mappings": { + "0": { + "then": "A changing table is available" + }, + "1": { + "then": "No changing table is available" + } + }, + "question": "Is a changing table (to change diapers) available?" + }, + "toilets-fee": { + "mappings": { + "0": { + "then": "These are paid toilets" + }, + "1": { + "then": "Free to use" + } + }, + "question": "Are these toilets free to use?" + }, + "toilets-type": { + "mappings": { + "0": { + "then": "There are only seated toilets" + }, + "1": { + "then": "There are only urinals here" + }, + "2": { + "then": "There are only squat toilets here" + }, + "3": { + "then": "Both seated toilets and urinals are available here" + } + }, + "question": "Which kind of toilets are this?" + }, + "toilets-wheelchair": { + "mappings": { + "0": { + "then": "There is a dedicated toilet for wheelchair users" + }, + "1": { + "then": "No wheelchair access" + } + }, + "question": "Is there a dedicated toilet for wheelchair users" } }, "title": { @@ -3333,10 +3333,7 @@ "trail": { "name": "Trails", "tagRenderings": { - "1": { - "render": "The trail is {_length:km} kilometers long" - }, - "4": { + "Color": { "mappings": { "0": { "then": "Blue trail" @@ -3351,6 +3348,9 @@ "then": "Yellow trail" } } + }, + "trail-length": { + "render": "The trail is {_length:km} kilometers long" } }, "title": { @@ -3374,29 +3374,18 @@ } }, "tagRenderings": { - "1": { + "tree-decidouous": { "mappings": { "0": { - "then": "Height: {height} m" - } - }, - "render": "Height: {height}" - }, - "2": { - "mappings": { - "0": { - "then": "\"\"/ Broadleaved" + "then": "Deciduous: the tree loses its leaves for some time of the year." }, "1": { - "then": "\"\"/ Needleleaved" - }, - "2": { - "then": "\"\"/ Permanently leafless" + "then": "Evergreen." } }, - "question": "Is this a broadleaved or needleleaved tree?" + "question": "Is this tree evergreen or deciduous?" }, - "3": { + "tree-denotation": { "mappings": { "0": { "then": "The tree is remarkable due to its size or prominent location. It is useful for navigation." @@ -3425,27 +3414,15 @@ }, "question": "How significant is this tree? Choose the first answer that applies." }, - "4": { + "tree-height": { "mappings": { "0": { - "then": "Deciduous: the tree loses its leaves for some time of the year." - }, - "1": { - "then": "Evergreen." + "then": "Height: {height} m" } }, - "question": "Is this tree evergreen or deciduous?" + "render": "Height: {height}" }, - "5": { - "mappings": { - "0": { - "then": "The tree does not have a name." - } - }, - "question": "Does the tree have a name?", - "render": "Name: {name}" - }, - "6": { + "tree-heritage": { "mappings": { "0": { "then": "\"\"/ Registered as heritage by Onroerend Erfgoed Flanders" @@ -3465,11 +3442,34 @@ }, "question": "Is this tree registered heritage?" }, - "7": { + "tree-leaf_type": { + "mappings": { + "0": { + "then": "\"\"/ Broadleaved" + }, + "1": { + "then": "\"\"/ Needleleaved" + }, + "2": { + "then": "\"\"/ Permanently leafless" + } + }, + "question": "Is this a broadleaved or needleleaved tree?" + }, + "tree_node-name": { + "mappings": { + "0": { + "then": "The tree does not have a name." + } + }, + "question": "Does the tree have a name?", + "render": "Name: {name}" + }, + "tree_node-ref:OnroerendErfgoed": { "question": "What is the ID issued by Onroerend Erfgoed Flanders?", "render": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}" }, - "8": { + "tree_node-wikidata": { "question": "What is the Wikidata ID for this tree?", "render": "\"\"/ Wikidata: {wikidata}" } @@ -3492,7 +3492,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Do you want to add a description?" } }, @@ -3528,7 +3528,7 @@ } }, "tagRenderings": { - "0": { + "waste-basket-waste-types": { "mappings": { "0": { "then": "A waste basket for general waste" diff --git a/langs/layers/es.json b/langs/layers/es.json index 2b1005bef..9746ea958 100644 --- a/langs/layers/es.json +++ b/langs/layers/es.json @@ -8,7 +8,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Respaldo: Si" @@ -20,11 +20,7 @@ "question": "¿Este banco tiene un respaldo?", "render": "Respaldo" }, - "2": { - "question": "¿Cuántos asientos tiene este banco?", - "render": "{seats} asientos" - }, - "3": { + "bench-material": { "mappings": { "0": { "then": "Material: madera" @@ -46,6 +42,10 @@ } }, "render": "Material: {material}" + }, + "bench-seats": { + "question": "¿Cuántos asientos tiene este banco?", + "render": "{seats} asientos" } }, "title": { @@ -66,18 +66,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Este desfibrilador está en interior" - }, - "1": { - "then": "Este desfibrilador está en exterior" - } - }, - "question": "¿Esté el desfibrilador en interior?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Acceso libre" @@ -95,18 +84,29 @@ "question": "¿Está el desfibrilador accesible libremente?", "render": "El acceso es {access}" }, - "4": { - "question": "¿En qué planta se encuentra el defibrilador localizado?", - "render": "El desfibrilador se encuentra en la planta {level}" - }, - "5": { + "defibrillator-defibrillator:location": { "question": "Da detalles de dónde se puede encontrar el desfibrilador (en el idioma local)" }, - "6": { + "defibrillator-defibrillator:location:en": { "question": "Da detalles de dónde se puede encontrar el desfibrilador (en ingles)" }, - "7": { + "defibrillator-defibrillator:location:fr": { "question": "Da detalles de dónde se puede encontrar el desfibrilador (en frances)" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "Este desfibrilador está en interior" + }, + "1": { + "then": "Este desfibrilador está en exterior" + } + }, + "question": "¿Esté el desfibrilador en interior?" + }, + "defibrillator-level": { + "question": "¿En qué planta se encuentra el defibrilador localizado?", + "render": "El desfibrilador se encuentra en la planta {level}" } }, "title": { diff --git a/langs/layers/fi.json b/langs/layers/fi.json index 3499be2da..abe9d2b7f 100644 --- a/langs/layers/fi.json +++ b/langs/layers/fi.json @@ -8,7 +8,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Selkänoja: kyllä" @@ -19,27 +19,7 @@ }, "render": "Selkänoja" }, - "3": { - "mappings": { - "0": { - "then": "Materiaali: puu" - }, - "2": { - "then": "Materiaali: kivi" - }, - "3": { - "then": "Materiaali: betoni" - }, - "4": { - "then": "Materiaali: muovi" - }, - "5": { - "then": "Materiaali: teräs" - } - }, - "render": "Materiaali: {material}" - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Väri: ruskea" @@ -67,6 +47,26 @@ } }, "render": "Väri: {colour}" + }, + "bench-material": { + "mappings": { + "0": { + "then": "Materiaali: puu" + }, + "2": { + "then": "Materiaali: kivi" + }, + "3": { + "then": "Materiaali: betoni" + }, + "4": { + "then": "Materiaali: muovi" + }, + "5": { + "then": "Materiaali: teräs" + } + }, + "render": "Materiaali: {material}" } }, "title": { @@ -75,7 +75,7 @@ }, "bench_at_pt": { "tagRenderings": { - "1": { + "bench_at_pt-name": { "render": "{name}" } }, @@ -85,7 +85,7 @@ }, "bike_parking": { "tagRenderings": { - "5": { + "Access": { "render": "{access}" } } diff --git a/langs/layers/fr.json b/langs/layers/fr.json index 44567b29c..009a50fc0 100644 --- a/langs/layers/fr.json +++ b/langs/layers/fr.json @@ -8,7 +8,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Dossier : Oui" @@ -20,39 +20,7 @@ "question": "Ce banc dispose-t-il d'un dossier ?", "render": "Dossier" }, - "2": { - "question": "De combien de places dispose ce banc ?", - "render": "{seats} places" - }, - "3": { - "mappings": { - "0": { - "then": "Matériau : bois" - }, - "1": { - "then": "Matériau : métal" - }, - "2": { - "then": "Matériau : pierre" - }, - "3": { - "then": "Matériau : béton" - }, - "4": { - "then": "Matériau : plastique" - }, - "5": { - "then": "Matériau : acier" - } - }, - "question": "De quel matériau ce banc est-il fait ?", - "render": "Matériau : {material}" - }, - "4": { - "question": "Dans quelle direction regardez-vous quand vous êtes assis sur le banc ?", - "render": "Assis sur le banc, on regarde vers {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Couleur : marron" @@ -82,7 +50,39 @@ "question": "Quelle est la couleur de ce banc ?", "render": "Couleur : {colour}" }, - "6": { + "bench-direction": { + "question": "Dans quelle direction regardez-vous quand vous êtes assis sur le banc ?", + "render": "Assis sur le banc, on regarde vers {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Matériau : bois" + }, + "1": { + "then": "Matériau : métal" + }, + "2": { + "then": "Matériau : pierre" + }, + "3": { + "then": "Matériau : béton" + }, + "4": { + "then": "Matériau : plastique" + }, + "5": { + "then": "Matériau : acier" + } + }, + "question": "De quel matériau ce banc est-il fait ?", + "render": "Matériau : {material}" + }, + "bench-seats": { + "question": "De combien de places dispose ce banc ?", + "render": "{seats} places" + }, + "bench-survey:date": { "question": "Quand ce banc a-t-il été contrôlé pour la dernière fois ?", "render": "Ce banc a été contrôlé pour la dernière fois le {survey:date}" } @@ -94,11 +94,11 @@ "bench_at_pt": { "name": "Bancs des arrêts de transport en commun", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "Banc assis debout" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -123,23 +123,7 @@ } }, "tagRenderings": { - "1": { - "question": "Quel est le nom de cette vélothèque ?", - "render": "Cette vélothèque s'appelle {name}" - }, - "6": { - "mappings": { - "0": { - "then": "L'emprunt de vélo est gratuit" - }, - "1": { - "then": "Emprunter un vélo coûte 20 €/an et 20 € de garantie" - } - }, - "question": "Combien coûte l'emprunt d'un vélo ?", - "render": "Emprunter un vélo coûte {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Vélos pour enfants disponibles" @@ -152,6 +136,22 @@ } }, "question": "Qui peut emprunter des vélos ici ?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "L'emprunt de vélo est gratuit" + }, + "1": { + "then": "Emprunter un vélo coûte 20 €/an et 20 € de garantie" + } + }, + "question": "Combien coûte l'emprunt d'un vélo ?", + "render": "Emprunter un vélo coûte {charge}" + }, + "bicycle_library-name": { + "question": "Quel est le nom de cette vélothèque ?", + "render": "Cette vélothèque s'appelle {name}" } }, "title": { @@ -166,7 +166,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Le distributeur automatique fonctionne" @@ -194,11 +194,7 @@ } }, "tagRenderings": { - "1": { - "question": "Quel est le nom de ce Café vélo ?", - "render": "Ce Café vélo s'appelle {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "Ce Café vélo offre une pompe en libre accès" @@ -209,18 +205,20 @@ }, "question": "Est-ce que ce Café vélo propose une pompe en libre accès ?" }, - "3": { - "mappings": { - "0": { - "then": "Ce Café vélo propose des outils pour réparer son vélo soi-même" - }, - "1": { - "then": "Ce Café vélo ne propose pas d'outils pour réparer son vélo soi-même" - } - }, - "question": "Est-ce qu'il y a des outils pour réparer soi-même son vélo ?" + "bike_cafe-email": { + "question": "Quelle est l'adresse électronique de {name} ?" }, - "4": { + "bike_cafe-name": { + "question": "Quel est le nom de ce Café vélo ?", + "render": "Ce Café vélo s'appelle {name}" + }, + "bike_cafe-opening_hours": { + "question": "Quand ce Café vélo est-t-il ouvert ?" + }, + "bike_cafe-phone": { + "question": "Quel est le numéro de téléphone de {name} ?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "Ce Café vélo répare les vélos" @@ -231,17 +229,19 @@ }, "question": "Est-ce que ce Café vélo répare les vélos ?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "Ce Café vélo propose des outils pour réparer son vélo soi-même" + }, + "1": { + "then": "Ce Café vélo ne propose pas d'outils pour réparer son vélo soi-même" + } + }, + "question": "Est-ce qu'il y a des outils pour réparer soi-même son vélo ?" + }, + "bike_cafe-website": { "question": "Quel est le site web de {name} ?" - }, - "6": { - "question": "Quel est le numéro de téléphone de {name} ?" - }, - "7": { - "question": "Quelle est l'adresse électronique de {name} ?" - }, - "8": { - "question": "Quand ce Café vélo est-t-il ouvert ?" } }, "title": { @@ -277,7 +277,22 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "Accessible publiquement" + }, + "1": { + "then": "Accès destiné principalement aux visiteurs d'un lieu" + }, + "2": { + "then": "Accès limité aux membres d'une école, entreprise ou organisation" + } + }, + "question": "Qui peut utiliser ce parking à vélo ?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "0": { "then": "Arceaux " @@ -307,7 +322,40 @@ "question": "Quel type de parking à vélos est-ce ?", "render": "Ceci est un parking à vélo de type {bicycle_parking}" }, - "2": { + "Capacity": { + "question": "Combien de vélos entrent dans ce parking à vélos (y compris les éventuels vélos de transport) ?", + "render": "Place pour {capacity} vélos" + }, + "Cargo bike capacity?": { + "question": "Combien de vélos de transport entrent dans ce parking à vélos ?", + "render": "Ce parking a de la place pour {capacity:cargo_bike} vélos de transport" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "Ce parking a de la place pour les vélos cargo" + }, + "1": { + "then": "Ce parking a des emplacements (officiellement) destinés aux vélos cargo." + }, + "2": { + "then": "Il est interdit de garer des vélos cargo" + } + }, + "question": "Est-ce que ce parking à vélo a des emplacements pour des vélos cargo ?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "Ce parking est couvert (il a un toit)" + }, + "1": { + "then": "Ce parking n'est pas couvert" + } + }, + "question": "Ce parking est-il couvert ? Sélectionnez aussi \"couvert\" pour les parkings en intérieur." + }, + "Underground?": { "mappings": { "0": { "then": "Parking souterrain" @@ -326,54 +374,6 @@ } }, "question": "Quelle est la position relative de ce parking à vélo ?" - }, - "3": { - "mappings": { - "0": { - "then": "Ce parking est couvert (il a un toit)" - }, - "1": { - "then": "Ce parking n'est pas couvert" - } - }, - "question": "Ce parking est-il couvert ? Sélectionnez aussi \"couvert\" pour les parkings en intérieur." - }, - "4": { - "question": "Combien de vélos entrent dans ce parking à vélos (y compris les éventuels vélos de transport) ?", - "render": "Place pour {capacity} vélos" - }, - "5": { - "mappings": { - "0": { - "then": "Accessible publiquement" - }, - "1": { - "then": "Accès destiné principalement aux visiteurs d'un lieu" - }, - "2": { - "then": "Accès limité aux membres d'une école, entreprise ou organisation" - } - }, - "question": "Qui peut utiliser ce parking à vélo ?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "Ce parking a de la place pour les vélos cargo" - }, - "1": { - "then": "Ce parking a des emplacements (officiellement) destinés aux vélos cargo." - }, - "2": { - "then": "Il est interdit de garer des vélos cargo" - } - }, - "question": "Est-ce que ce parking à vélo a des emplacements pour des vélos cargo ?" - }, - "7": { - "question": "Combien de vélos de transport entrent dans ce parking à vélos ?", - "render": "Ce parking a de la place pour {capacity:cargo_bike} vélos de transport" } }, "title": { @@ -399,7 +399,18 @@ } }, "tagRenderings": { - "1": { + "Operational status": { + "mappings": { + "0": { + "then": "La pompe à vélo est cassée" + }, + "1": { + "then": "La pompe est opérationnelle" + } + }, + "question": "La pompe à vélo fonctionne-t-elle toujours ?" + }, + "bike_repair_station-available-services": { "mappings": { "0": { "then": "Il y a seulement une pompe" @@ -413,22 +424,7 @@ }, "question": "Quels services sont valables à cette station vélo ?" }, - "2": { - "question": "Qui maintient cette pompe à vélo ?", - "render": "Mantenue par {operator}" - }, - "5": { - "mappings": { - "0": { - "then": "Ouvert en permanence" - }, - "1": { - "then": "Ouvert en permanence" - } - }, - "question": "Quand ce point de réparation de vélo est-il ouvert ?" - }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "Il y a un outil pour réparer la chaine" @@ -439,7 +435,7 @@ }, "question": "Est-ce que cette station vélo a un outil specifique pour réparer la chaîne du vélo ?" }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "Il y a un crochet ou une accroche" @@ -450,18 +446,47 @@ }, "question": "Est-ce que cette station vélo à un crochet pour suspendre son vélo ou une accroche pour l'élevé ?" }, - "8": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { - "then": "La pompe à vélo est cassée" + "then": "Pompe manuelle" }, "1": { - "then": "La pompe est opérationnelle" + "then": "Pompe électrique" } }, - "question": "La pompe à vélo fonctionne-t-elle toujours ?" + "question": "Est-ce que cette pompe est électrique ?" }, - "10": { + "bike_repair_station-manometer": { + "mappings": { + "0": { + "then": "Il y a un manomètre" + }, + "1": { + "then": "Il n'y a pas de manomètre" + }, + "2": { + "then": "Il y a un manomètre mais il est cassé" + } + }, + "question": "Est-ce que la pompe à un manomètre integré ?" + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Ouvert en permanence" + }, + "1": { + "then": "Ouvert en permanence" + } + }, + "question": "Quand ce point de réparation de vélo est-il ouvert ?" + }, + "bike_repair_station-operator": { + "question": "Qui maintient cette pompe à vélo ?", + "render": "Mantenue par {operator}" + }, + "bike_repair_station-valves": { "mappings": { "0": { "then": "Sclaverand (aussi appelé Presta)" @@ -475,31 +500,6 @@ }, "question": "Quelles valves sont compatibles ?", "render": "Cette pompe est compatible avec les valves suivantes : {valves}" - }, - "11": { - "mappings": { - "0": { - "then": "Pompe manuelle" - }, - "1": { - "then": "Pompe électrique" - } - }, - "question": "Est-ce que cette pompe est électrique ?" - }, - "12": { - "mappings": { - "0": { - "then": "Il y a un manomètre" - }, - "1": { - "then": "Il n'y a pas de manomètre" - }, - "2": { - "then": "Il y a un manomètre mais il est cassé" - } - }, - "question": "Est-ce que la pompe à un manomètre integré ?" } }, "title": { @@ -532,34 +532,46 @@ } }, "tagRenderings": { - "1": { - "render": "Ce magasin est spécialisé dans la vente de {shop} et a des activités liées au vélo" - }, - "2": { - "question": "Quel est le nom du magasin de vélos ?", - "render": "Ce magasin s'appelle {name}" - }, - "3": { - "question": "Quel est le site web de {name} ?" - }, - "4": { - "question": "Quel est le numéro de téléphone de {name} ?" - }, - "5": { - "question": "Quelle est l'adresse électronique de {name} ?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "Ce magasin vend des vélos" + "then": "Ce magasin offre une pompe en acces libre" }, "1": { - "then": "Ce magasin ne vend pas de vélo" + "then": "Ce magasin n'offre pas de pompe en libre accès" + }, + "2": { + "then": "Il y a une pompe à vélo, c'est indiqué comme un point séparé " } }, - "question": "Est-ce que ce magasin vend des vélos ?" + "question": "Est-ce que ce magasin offre une pompe en accès libre ?" }, - "10": { + "bike_repair_bike-wash": { + "mappings": { + "0": { + "then": "Ce magasin lave les vélos" + }, + "1": { + "then": "Ce magasin a une installation pour laver soi même des vélos" + }, + "2": { + "then": "Ce magasin ne fait pas le nettoyage de vélo" + } + }, + "question": "Lave-t-on les vélos ici ?" + }, + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "Ce magasin loue des vélos" + }, + "1": { + "then": "Ce magasin ne loue pas de vélos" + } + }, + "question": "Est-ce ce magasin loue des vélos ?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Ce magasin répare des vélos" @@ -576,18 +588,7 @@ }, "question": "Est-ce que ce magasin répare des vélos ?" }, - "11": { - "mappings": { - "0": { - "then": "Ce magasin loue des vélos" - }, - "1": { - "then": "Ce magasin ne loue pas de vélos" - } - }, - "question": "Est-ce ce magasin loue des vélos ?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "Ce magasin vend des vélos d'occasion" @@ -601,21 +602,18 @@ }, "question": "Est-ce ce magasin vend des vélos d'occasion ?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "Ce magasin offre une pompe en acces libre" + "then": "Ce magasin vend des vélos" }, "1": { - "then": "Ce magasin n'offre pas de pompe en libre accès" - }, - "2": { - "then": "Il y a une pompe à vélo, c'est indiqué comme un point séparé " + "then": "Ce magasin ne vend pas de vélo" } }, - "question": "Est-ce que ce magasin offre une pompe en accès libre ?" + "question": "Est-ce que ce magasin vend des vélos ?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "0": { "then": "Ce magasin offre des outils pour réparer son vélo soi-même" @@ -629,19 +627,21 @@ }, "question": "Est-ce qu'il y a des outils pour réparer son vélo dans ce magasin ?" }, - "15": { - "mappings": { - "0": { - "then": "Ce magasin lave les vélos" - }, - "1": { - "then": "Ce magasin a une installation pour laver soi même des vélos" - }, - "2": { - "then": "Ce magasin ne fait pas le nettoyage de vélo" - } - }, - "question": "Lave-t-on les vélos ici ?" + "bike_shop-email": { + "question": "Quelle est l'adresse électronique de {name} ?" + }, + "bike_shop-is-bicycle_shop": { + "render": "Ce magasin est spécialisé dans la vente de {shop} et a des activités liées au vélo" + }, + "bike_shop-name": { + "question": "Quel est le nom du magasin de vélos ?", + "render": "Ce magasin s'appelle {name}" + }, + "bike_shop-phone": { + "question": "Quel est le numéro de téléphone de {name} ?" + }, + "bike_shop-website": { + "question": "Quel est le site web de {name} ?" } }, "title": { @@ -691,18 +691,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Ce défibrillateur est en intérieur (dans un batiment)" - }, - "1": { - "then": "Ce défibrillateur est situé en extérieur" - } - }, - "question": "Ce défibrillateur est-il disposé en intérieur ?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Librement accessible" @@ -723,7 +712,7 @@ "question": "Ce défibrillateur est-il librement accessible ?", "render": "{access} accessible" }, - "3": { + "defibrillator-defibrillator": { "mappings": { "0": { "then": "C'est un défibrillateur manuel pour professionnel" @@ -735,7 +724,42 @@ "question": "Est-ce un défibrillateur automatique normal ou un défibrillateur manuel à usage professionnel uniquement ?", "render": "Il n'y a pas d'information sur le type de dispositif" }, - "4": { + "defibrillator-defibrillator:location": { + "question": "Veuillez indiquez plus précisément où se situe le défibrillateur (dans la langue local)", + "render": "Informations supplémentaires à propos de l'emplacement (dans la langue locale) :
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:en": { + "question": "Veuillez indiquez plus précisément où se situe le défibrillateur (en englais)", + "render": "Informations supplémentaires à propos de l'emplacement (en anglais) :
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:fr": { + "question": "Veuillez indiquez plus précisément où se situe le défibrillateur (en français)", + "render": "Informations supplémentaires à propos de l'emplacement (en Français) :
{defibrillator:location}" + }, + "defibrillator-description": { + "question": "Y a-t-il des informations utiles pour les utilisateurs que vous n'avez pas pu décrire ci-dessus ? (laisser vide sinon)", + "render": "Informations supplémentaires : {description}" + }, + "defibrillator-email": { + "question": "Quelle est l'adresse électronique pour des questions à propos de ce défibrillateur ?", + "render": "Adresse électronique pour des questions à propos de ce défibrillateur : {email}" + }, + "defibrillator-fixme": { + "question": "Y a-t-il quelque chose qui ne va pas dans la manière dont ça a été cartographié, et que vous n'avez pas pu réparer ici ? (laisser une note pour les experts d'OpenStreetMap)", + "render": "Informations supplémentaires pour les experts d'OpenStreetMap : {fixme}" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "Ce défibrillateur est en intérieur (dans un batiment)" + }, + "1": { + "then": "Ce défibrillateur est situé en extérieur" + } + }, + "question": "Ce défibrillateur est-il disposé en intérieur ?" + }, + "defibrillator-level": { "mappings": { "0": { "then": "Ce défibrillateur est au rez-de-chaussée" @@ -747,31 +771,7 @@ "question": "À quel étage est situé ce défibrillateur ?", "render": "Ce défibrillateur est à l'étage {level}" }, - "5": { - "question": "Veuillez indiquez plus précisément où se situe le défibrillateur (dans la langue local)", - "render": "Informations supplémentaires à propos de l'emplacement (dans la langue locale) :
{defibrillator:location}" - }, - "6": { - "question": "Veuillez indiquez plus précisément où se situe le défibrillateur (en englais)", - "render": "Informations supplémentaires à propos de l'emplacement (en anglais) :
{defibrillator:location}" - }, - "7": { - "question": "Veuillez indiquez plus précisément où se situe le défibrillateur (en français)", - "render": "Informations supplémentaires à propos de l'emplacement (en Français) :
{defibrillator:location}" - }, - "9": { - "question": "Quel est le numéro d'identification officiel de ce dispositif ? (si il est visible sur le dispositif)", - "render": "Numéro d'identification officiel de ce dispositif : {ref}" - }, - "10": { - "question": "Quelle est l'adresse électronique pour des questions à propos de ce défibrillateur ?", - "render": "Adresse électronique pour des questions à propos de ce défibrillateur : {email}" - }, - "11": { - "question": "Quel est le numéro de téléphone pour questions sur le défibrillateur ?", - "render": "Numéro de téléphone pour questions sur le défibrillateur : {phone}" - }, - "12": { + "defibrillator-opening_hours": { "mappings": { "0": { "then": "Ouvert 24/7 (jours feriés inclus)" @@ -780,11 +780,15 @@ "question": "À quels horaires ce défibrillateur est-il accessible ?", "render": "{opening_hours_table(opening_hours)}" }, - "13": { - "question": "Y a-t-il des informations utiles pour les utilisateurs que vous n'avez pas pu décrire ci-dessus ? (laisser vide sinon)", - "render": "Informations supplémentaires : {description}" + "defibrillator-phone": { + "question": "Quel est le numéro de téléphone pour questions sur le défibrillateur ?", + "render": "Numéro de téléphone pour questions sur le défibrillateur : {phone}" }, - "14": { + "defibrillator-ref": { + "question": "Quel est le numéro d'identification officiel de ce dispositif ? (si il est visible sur le dispositif)", + "render": "Numéro d'identification officiel de ce dispositif : {ref}" + }, + "defibrillator-survey:date": { "mappings": { "0": { "then": "Vérifié aujourd'hui !" @@ -792,10 +796,6 @@ }, "question": "Quand le défibrillateur a-t-il été vérifié pour la dernière fois ?", "render": "Ce défibrillateur a été vérifié pour la dernière fois le {survey:date}" - }, - "15": { - "question": "Y a-t-il quelque chose qui ne va pas dans la manière dont ça a été cartographié, et que vous n'avez pas pu réparer ici ? (laisser une note pour les experts d'OpenStreetMap)", - "render": "Informations supplémentaires pour les experts d'OpenStreetMap : {fixme}" } }, "title": { @@ -814,7 +814,18 @@ } }, "tagRenderings": { - "1": { + "Bottle refill": { + "mappings": { + "0": { + "then": "Il est facile de remplir les bouteilles d'eau" + }, + "1": { + "then": "Les bouteilles d'eau peuvent ne pas passer" + } + }, + "question": "Est-il facile de remplir des bouteilles d'eau ?" + }, + "Still in use?": { "mappings": { "0": { "then": "Cette fontaine fonctionne" @@ -829,18 +840,7 @@ "question": "Ce point d'eau potable est-il toujours opérationnel ?", "render": "L'état opérationnel est {operational_status" }, - "2": { - "mappings": { - "0": { - "then": "Il est facile de remplir les bouteilles d'eau" - }, - "1": { - "then": "Les bouteilles d'eau peuvent ne pas passer" - } - }, - "question": "Est-il facile de remplir des bouteilles d'eau ?" - }, - "3": { + "render-closest-drinking-water": { "render": "Une autre source d’eau potable est à {_closest_other_drinking_water_distance} mètres a>" } }, @@ -850,21 +850,32 @@ }, "food": { "tagRenderings": { - "14": { + "friture-oil": { "mappings": { "0": { - "then": "Des collations végétariens sont disponibles" + "then": "Huile végétale" }, "1": { - "then": "Quelques snacks végétariens seulement" - }, - "2": { - "then": "Pas d'en-cas végétariens disponibles" + "then": "Graisse animale" } }, - "question": "Cette friterie est-elle équipée de snacks végétariens ?" + "question": "Cette friteuse fonctionne-t-elle avec de la graisse animale ou végétale ?" }, - "15": { + "friture-take-your-container": { + "mappings": { + "0": { + "then": "Vous pouvez apporter vos contenants pour votre commande, limitant l’usage de matériaux à usage unique et les déchets" + }, + "1": { + "then": "Apporter ses propres contenants n’est pas permis" + }, + "2": { + "then": "Il est obligatoire d’apporter ses propres contenants" + } + }, + "question": "Est-il proposé d’utiliser ses propres contenants pour sa commande ?
" + }, + "friture-vegan": { "mappings": { "0": { "then": "Des collations végétaliens sont disponibles" @@ -878,30 +889,19 @@ }, "question": "Cette friterie est-elle équipée de snacks végétaliens ?" }, - "16": { + "friture-vegetarian": { "mappings": { "0": { - "then": "Huile végétale" + "then": "Des collations végétariens sont disponibles" }, "1": { - "then": "Graisse animale" - } - }, - "question": "Cette friteuse fonctionne-t-elle avec de la graisse animale ou végétale ?" - }, - "17": { - "mappings": { - "0": { - "then": "Vous pouvez apporter vos contenants pour votre commande, limitant l’usage de matériaux à usage unique et les déchets" - }, - "1": { - "then": "Apporter ses propres contenants n’est pas permis" + "then": "Quelques snacks végétariens seulement" }, "2": { - "then": "Il est obligatoire d’apporter ses propres contenants" + "then": "Pas d'en-cas végétariens disponibles" } }, - "question": "Est-il proposé d’utiliser ses propres contenants pour sa commande ?
" + "question": "Cette friterie est-elle équipée de snacks végétariens ?" } } }, @@ -913,10 +913,14 @@ } }, "tagRenderings": { - "0": { + "ghost-bike-explanation": { "render": "Un vélo fantôme est un monument commémoratif pour un cycliste décédé dans un accident de la route, sous la forme d'un vélo blanc placé en permanence près du lieu de l'accident." }, - "2": { + "ghost_bike-inscription": { + "question": "Quelle est l'inscription sur ce vélo fantôme ?", + "render": "{inscription}" + }, + "ghost_bike-name": { "mappings": { "0": { "then": "Aucun nom n'est marqué sur le vélo" @@ -925,15 +929,11 @@ "question": "À qui est dédié ce vélo fantôme ?
Veuillez respecter la vie privée – ajoutez le nom seulement s'il est largement publié ou marqué sur le vélo. Choisissez de ne pas indiquer le nom de famille
", "render": "En souvenir de {name}" }, - "3": { + "ghost_bike-source": { "question": "Sur quelle page web peut-on trouver plus d'informations sur le Vélo fantôme ou l'accident ?", "render": "
Plus d'informations sont disponibles" }, - "4": { - "question": "Quelle est l'inscription sur ce vélo fantôme ?", - "render": "{inscription}" - }, - "5": { + "ghost_bike-start_date": { "question": "Quand ce vélo fantôme a-t-il été installée ?", "render": "Placé le {start_date}" } @@ -968,16 +968,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Cette carte est basée sur OpenStreetMap" - } - }, - "question": "Sur quelles données cette carte est-elle basée ?", - "render": "Cette carte est basée sur {map_source}" - }, - "2": { + "map-attribution": { "mappings": { "0": { "then": "L’attribution est clairement inscrite ainsi que la licence ODBL" @@ -996,6 +987,15 @@ } }, "question": "L’attribution à OpenStreetMap est elle-présente ?" + }, + "map-map_source": { + "mappings": { + "0": { + "then": "Cette carte est basée sur OpenStreetMap" + } + }, + "question": "Sur quelles données cette carte est-elle basée ?", + "render": "Cette carte est basée sur {map_source}" } }, "title": { @@ -1004,7 +1004,11 @@ }, "nature_reserve": { "tagRenderings": { - "5": { + "Curator": { + "question": "Qui est en charge de la conservation de la réserve ?
À ne remplir seulement que si le nom est diffusé au public", + "render": "{curator} est en charge de la conservation de la réserve" + }, + "Dogs?": { "mappings": { "0": { "then": "Les chiens doivent être tenus en laisse" @@ -1018,23 +1022,19 @@ }, "question": "Les chiens sont-ils autorisés dans cette réserve naturelle ?" }, - "6": { - "question": "Sur quelle page web peut-on trouver plus d'informations sur cette réserve naturelle ?" - }, - "7": { - "question": "Qui est en charge de la conservation de la réserve ?
À ne remplir seulement que si le nom est diffusé au public", - "render": "{curator} est en charge de la conservation de la réserve" - }, - "8": { + "Email": { "question": "À quelle adresse courriel peut-on envoyer des questions et des problèmes concernant cette réserve naturelle ?
Respecter la vie privée – renseignez une adresse électronique personnelle seulement si celle-ci est largement publiée", "render": "{email}" }, - "9": { + "Surface area": { + "render": "Superficie : {_surface:ha} ha" + }, + "Website": { + "question": "Sur quelle page web peut-on trouver plus d'informations sur cette réserve naturelle ?" + }, + "phone": { "question": "Quel numéro de téléphone peut-on appeler pour poser des questions et résoudre des problèmes concernant cette réserve naturelle ?
Respecter la vie privée – renseignez un numéro de téléphone personnel seulement si celui-ci est largement publié", "render": "{phone}" - }, - "12": { - "render": "Superficie : {_surface:ha} ha" } } }, @@ -1047,7 +1047,7 @@ } }, "tagRenderings": { - "0": { + "picnic_table-material": { "mappings": { "0": { "then": "C’est une table en bois" @@ -1073,7 +1073,86 @@ } }, "tagRenderings": { - "1": { + "Playground-wheelchair": { + "mappings": { + "0": { + "then": "Entièrement accessible aux personnes en fauteuil roulant" + }, + "1": { + "then": "Accessibilité limitée pour les personnes en fauteuil roulant" + }, + "2": { + "then": "Non accessible aux personnes en fauteuil roulant" + } + }, + "question": "Ce terrain de jeux est-il accessible aux personnes en fauteuil roulant ?" + }, + "playground-access": { + "mappings": { + "0": { + "then": "Accessible au public" + }, + "1": { + "then": "Accessible au public" + }, + "2": { + "then": "Réservée aux clients" + }, + "3": { + "then": "Réservée aux élèves de l’école" + }, + "4": { + "then": "Non accessible" + } + }, + "question": "L’aire de jeu est-elle accessible au public ?" + }, + "playground-email": { + "question": "Quelle est l'adresse électronique du responsable de l'aire de jeux ?", + "render": "{email}" + }, + "playground-lit": { + "mappings": { + "0": { + "then": "L’aire de jeu est éclairée de nuit" + }, + "1": { + "then": "L’aire de jeu n’est pas éclairée de nuit" + } + }, + "question": "Ce terrain de jeux est-il éclairé la nuit ?" + }, + "playground-max_age": { + "question": "Quel est l’âge maximum autorisé pour utiliser l’aire de jeu ?", + "render": "Accessible aux enfants de {max_age} au maximum" + }, + "playground-min_age": { + "question": "Quel est l'âge minimal requis pour accéder à ce terrain de jeux ?", + "render": "Accessible aux enfants de plus de {min_age} ans" + }, + "playground-opening_hours": { + "mappings": { + "0": { + "then": "Accessible du lever au coucher du soleil" + }, + "1": { + "then": "Toujours accessible" + }, + "2": { + "then": "Toujours accessible" + } + }, + "question": "Quand ce terrain de jeux est-il accessible ?" + }, + "playground-operator": { + "question": "Qui est en charge de l’exploitation de l’aire de jeu ?", + "render": "Exploité par {operator}" + }, + "playground-phone": { + "question": "Quel est le numéro de téléphone du responsable du terrain de jeux ?", + "render": "{phone}" + }, + "playground-surface": { "mappings": { "0": { "then": "La surface est en gazon" @@ -1102,85 +1181,6 @@ }, "question": "De quelle matière est la surface de l’aire de jeu ?
Pour plusieurs matières, sélectionner la principale", "render": "La surface est en {surface}" - }, - "2": { - "mappings": { - "0": { - "then": "L’aire de jeu est éclairée de nuit" - }, - "1": { - "then": "L’aire de jeu n’est pas éclairée de nuit" - } - }, - "question": "Ce terrain de jeux est-il éclairé la nuit ?" - }, - "3": { - "question": "Quel est l'âge minimal requis pour accéder à ce terrain de jeux ?", - "render": "Accessible aux enfants de plus de {min_age} ans" - }, - "4": { - "question": "Quel est l’âge maximum autorisé pour utiliser l’aire de jeu ?", - "render": "Accessible aux enfants de {max_age} au maximum" - }, - "5": { - "question": "Qui est en charge de l’exploitation de l’aire de jeu ?", - "render": "Exploité par {operator}" - }, - "6": { - "mappings": { - "0": { - "then": "Accessible au public" - }, - "1": { - "then": "Accessible au public" - }, - "2": { - "then": "Réservée aux clients" - }, - "3": { - "then": "Réservée aux élèves de l’école" - }, - "4": { - "then": "Non accessible" - } - }, - "question": "L’aire de jeu est-elle accessible au public ?" - }, - "7": { - "question": "Quelle est l'adresse électronique du responsable de l'aire de jeux ?", - "render": "{email}" - }, - "8": { - "question": "Quel est le numéro de téléphone du responsable du terrain de jeux ?", - "render": "{phone}" - }, - "9": { - "mappings": { - "0": { - "then": "Entièrement accessible aux personnes en fauteuil roulant" - }, - "1": { - "then": "Accessibilité limitée pour les personnes en fauteuil roulant" - }, - "2": { - "then": "Non accessible aux personnes en fauteuil roulant" - } - }, - "question": "Ce terrain de jeux est-il accessible aux personnes en fauteuil roulant ?" - }, - "10": { - "mappings": { - "0": { - "then": "Accessible du lever au coucher du soleil" - }, - "1": { - "then": "Toujours accessible" - }, - "2": { - "then": "Toujours accessible" - } - }, - "question": "Quand ce terrain de jeux est-il accessible ?" } }, "title": { @@ -1201,20 +1201,7 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "Cette microbibliothèque n'a pas de nom" - } - }, - "question": "Quel est le nom de cette microbibliothèque ?", - "render": "Le nom de cette microbibliothèque est {name}" - }, - "3": { - "question": "Combien de livres peuvent entrer dans cette microbibliothèque ?", - "render": "{capacity} livres peuvent entrer dans cette microbibliothèque" - }, - "4": { + "bookcase-booktypes": { "mappings": { "0": { "then": "Livres pour enfants" @@ -1228,7 +1215,18 @@ }, "question": "Quel type de livres peut-on dans cette microbibliothèque ?" }, - "5": { + "bookcase-is-accessible": { + "mappings": { + "0": { + "then": "Accèssible au public" + }, + "1": { + "then": "Accèssible aux clients" + } + }, + "question": "Cette microbibliothèque est-elle librement accèssible ?" + }, + "bookcase-is-indoors": { "mappings": { "0": { "then": "Cette microbibliothèque est en intérieur" @@ -1242,22 +1240,7 @@ }, "question": "Cette microbiliothèque est-elle en extérieur ?" }, - "6": { - "mappings": { - "0": { - "then": "Accèssible au public" - }, - "1": { - "then": "Accèssible aux clients" - } - }, - "question": "Cette microbibliothèque est-elle librement accèssible ?" - }, - "7": { - "question": "Qui entretien cette microbibliothèque ?", - "render": "Entretenue par {operator}" - }, - "8": { + "public_bookcase-brand": { "mappings": { "0": { "then": "Fait partie du réseau Little Free Library" @@ -1269,7 +1252,24 @@ "question": "Cette microbibliothèque fait-elle partie d'un réseau/groupe ?", "render": "Cette microbibliothèque fait partie du groupe {brand}" }, - "9": { + "public_bookcase-capacity": { + "question": "Combien de livres peuvent entrer dans cette microbibliothèque ?", + "render": "{capacity} livres peuvent entrer dans cette microbibliothèque" + }, + "public_bookcase-name": { + "mappings": { + "0": { + "then": "Cette microbibliothèque n'a pas de nom" + } + }, + "question": "Quel est le nom de cette microbibliothèque ?", + "render": "Le nom de cette microbibliothèque est {name}" + }, + "public_bookcase-operator": { + "question": "Qui entretien cette microbibliothèque ?", + "render": "Entretenue par {operator}" + }, + "public_bookcase-ref": { "mappings": { "0": { "then": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe" @@ -1278,11 +1278,11 @@ "question": "Quelle est le numéro de référence de cette microbibliothèque ?", "render": "Cette microbibliothèque du réseau {brand} possède le numéro {ref}" }, - "10": { + "public_bookcase-start_date": { "question": "Quand a été installée cette microbibliothèque ?", "render": "Installée le {start_date}" }, - "11": { + "public_bookcase-website": { "question": "Y a-t-il un site web avec plus d'informations sur cette microbibliothèque ?", "render": "Plus d'infos sur le site web" } @@ -1298,7 +1298,7 @@ }, "slow_roads": { "tagRenderings": { - "2": { + "slow_roads-surface": { "mappings": { "0": { "then": "La surface est en herbe" @@ -1341,7 +1341,55 @@ } }, "tagRenderings": { - "1": { + "sport-pitch-access": { + "mappings": { + "0": { + "then": "Accessible au public" + }, + "1": { + "then": "Accès limité (par exemple uniquement sur réservation, à certains horaires…)" + }, + "2": { + "then": "Accessible uniquement aux membres du club" + }, + "3": { + "then": "Privé - Pas accessible au public" + } + }, + "question": "Est-ce que ce terrain de sport est accessible au public ?" + }, + "sport-pitch-reservation": { + "mappings": { + "0": { + "then": "Il est obligatoire de réserver pour utiliser ce terrain de sport" + }, + "1": { + "then": "Il est recommendé de réserver pour utiliser ce terrain de sport" + }, + "2": { + "then": "Il est possible de réserver, mais ce n'est pas nécéssaire pour utiliser ce terrain de sport" + }, + "3": { + "then": "On ne peut pas réserver" + } + }, + "question": "Doit-on réserver pour utiliser ce terrain de sport ?" + }, + "sport_pitch-email": { + "question": "Quelle est l'adresse courriel du gérant ?" + }, + "sport_pitch-opening_hours": { + "mappings": { + "1": { + "then": "Accessible en permanence" + } + }, + "question": "Quand ce terrain est-il accessible ?" + }, + "sport_pitch-phone": { + "question": "Quel est le numéro de téléphone du gérant ?" + }, + "sport_pitch-sport": { "mappings": { "0": { "then": "Ici, on joue au basketball" @@ -1365,7 +1413,7 @@ "question": "À quel sport peut-on jouer ici ?", "render": "Ici on joue au {sport}" }, - "2": { + "sport_pitch-surface": { "mappings": { "0": { "then": "La surface est de l'herbe" @@ -1385,54 +1433,6 @@ }, "question": "De quelle surface est fait ce terrain de sport ?", "render": "La surface est {surface}" - }, - "3": { - "mappings": { - "0": { - "then": "Accessible au public" - }, - "1": { - "then": "Accès limité (par exemple uniquement sur réservation, à certains horaires…)" - }, - "2": { - "then": "Accessible uniquement aux membres du club" - }, - "3": { - "then": "Privé - Pas accessible au public" - } - }, - "question": "Est-ce que ce terrain de sport est accessible au public ?" - }, - "4": { - "mappings": { - "0": { - "then": "Il est obligatoire de réserver pour utiliser ce terrain de sport" - }, - "1": { - "then": "Il est recommendé de réserver pour utiliser ce terrain de sport" - }, - "2": { - "then": "Il est possible de réserver, mais ce n'est pas nécéssaire pour utiliser ce terrain de sport" - }, - "3": { - "then": "On ne peut pas réserver" - } - }, - "question": "Doit-on réserver pour utiliser ce terrain de sport ?" - }, - "5": { - "question": "Quel est le numéro de téléphone du gérant ?" - }, - "6": { - "question": "Quelle est l'adresse courriel du gérant ?" - }, - "7": { - "mappings": { - "1": { - "then": "Accessible en permanence" - } - }, - "question": "Quand ce terrain est-il accessible ?" } }, "title": { @@ -1442,7 +1442,7 @@ "surveillance_camera": { "name": "Caméras de surveillance", "tagRenderings": { - "1": { + "Camera type: fixed; panning; dome": { "mappings": { "0": { "then": "Une caméra fixe (non mobile)" @@ -1456,34 +1456,7 @@ }, "question": "Quel genre de caméra est-ce ?" }, - "2": { - "mappings": { - "0": { - "then": "Filme dans une direction {direction}" - } - }, - "question": "Dans quelle direction géographique cette caméra filme-t-elle ?", - "render": "Filme dans une direction {camera:direction}" - }, - "3": { - "question": "Qui exploite ce système de vidéosurveillance ?", - "render": "Exploité par {operator}" - }, - "4": { - "mappings": { - "0": { - "then": "Une zone publique est surveillée, telle qu'une rue, un pont, une place, un parc, une gare, un couloir ou un tunnel public…" - }, - "1": { - "then": "Une zone extérieure, mais privée, est surveillée (par exemple, un parking, une station-service, une cour, une entrée, une allée privée, etc.)" - }, - "2": { - "then": "Une zone intérieure privée est surveillée, par exemple un magasin, un parking souterrain privé…" - } - }, - "question": "Quel genre de surveillance est cette caméra" - }, - "5": { + "Indoor camera? This isn't clear for 'public'-cameras": { "mappings": { "0": { "then": "Cette caméra est située à l'intérieur" @@ -1497,11 +1470,29 @@ }, "question": "L'espace public surveillé par cette caméra est-il un espace intérieur ou extérieur ?" }, - "6": { + "Level": { "question": "À quel niveau se trouve cette caméra ?", "render": "Situé au niveau {level}" }, - "7": { + "Operator": { + "question": "Qui exploite ce système de vidéosurveillance ?", + "render": "Exploité par {operator}" + }, + "Surveillance type: public, outdoor, indoor": { + "mappings": { + "0": { + "then": "Une zone publique est surveillée, telle qu'une rue, un pont, une place, un parc, une gare, un couloir ou un tunnel public…" + }, + "1": { + "then": "Une zone extérieure, mais privée, est surveillée (par exemple, un parking, une station-service, une cour, une entrée, une allée privée, etc.)" + }, + "2": { + "then": "Une zone intérieure privée est surveillée, par exemple un magasin, un parking souterrain privé…" + } + }, + "question": "Quel genre de surveillance est cette caméra" + }, + "Surveillance:zone": { "mappings": { "0": { "then": "Surveille un parking" @@ -1525,7 +1516,7 @@ "question": "Qu'est-ce qui est surveillé ici ?", "render": " Surveille un(e) {surveillance:zone}" }, - "8": { + "camera:mount": { "mappings": { "0": { "then": "Cette caméra est placée contre un mur" @@ -1539,6 +1530,15 @@ }, "question": "Comment cette caméra est-elle placée ?", "render": "Méthode de montage : {mount}" + }, + "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view": { + "mappings": { + "0": { + "then": "Filme dans une direction {direction}" + } + }, + "question": "Dans quelle direction géographique cette caméra filme-t-elle ?", + "render": "Filme dans une direction {camera:direction}" } }, "title": { @@ -1558,7 +1558,7 @@ } }, "tagRenderings": { - "1": { + "toilet-access": { "mappings": { "0": { "then": "Accès publique" @@ -1579,61 +1579,7 @@ "question": "Ces toilettes sont-elles accessibles au public ?", "render": "L'accès est {access}" }, - "2": { - "mappings": { - "0": { - "then": "Toilettes payantes" - }, - "1": { - "then": "Toilettes gratuites" - } - }, - "question": "Ces toilettes sont-elles payantes ?" - }, - "3": { - "question": "Quel est le prix d'accès de ces toilettes ?", - "render": "Le prix est {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "Il y a des toilettes réservées pour les personnes à mobilité réduite" - }, - "1": { - "then": "Non accessible aux personnes à mobilité réduite" - } - }, - "question": "Y a-t-il des toilettes réservées aux personnes en fauteuil roulant ?" - }, - "5": { - "mappings": { - "0": { - "then": "Il y a uniquement des sièges de toilettes" - }, - "1": { - "then": "Il y a uniquement des urinoirs" - }, - "2": { - "then": "Il y a uniquement des toilettes turques" - }, - "3": { - "then": "Il y a des sièges de toilettes et des urinoirs" - } - }, - "question": "De quel type sont ces toilettes ?" - }, - "6": { - "mappings": { - "0": { - "then": "Une table à langer est disponible" - }, - "1": { - "then": "Aucune table à langer" - } - }, - "question": "Ces toilettes disposent-elles d'une table à langer ?" - }, - "7": { + "toilet-changing_table:location": { "mappings": { "0": { "then": "La table à langer est dans les toilettes pour femmes. " @@ -1650,6 +1596,60 @@ }, "question": "Où se situe la table à langer ?", "render": "Emplacement de la table à langer : {changing_table:location}" + }, + "toilet-charge": { + "question": "Quel est le prix d'accès de ces toilettes ?", + "render": "Le prix est {charge}" + }, + "toilets-changing-table": { + "mappings": { + "0": { + "then": "Une table à langer est disponible" + }, + "1": { + "then": "Aucune table à langer" + } + }, + "question": "Ces toilettes disposent-elles d'une table à langer ?" + }, + "toilets-fee": { + "mappings": { + "0": { + "then": "Toilettes payantes" + }, + "1": { + "then": "Toilettes gratuites" + } + }, + "question": "Ces toilettes sont-elles payantes ?" + }, + "toilets-type": { + "mappings": { + "0": { + "then": "Il y a uniquement des sièges de toilettes" + }, + "1": { + "then": "Il y a uniquement des urinoirs" + }, + "2": { + "then": "Il y a uniquement des toilettes turques" + }, + "3": { + "then": "Il y a des sièges de toilettes et des urinoirs" + } + }, + "question": "De quel type sont ces toilettes ?" + }, + "toilets-wheelchair": { + "mappings": { + "0": { + "then": "Il y a des toilettes réservées pour les personnes à mobilité réduite" + }, + "1": { + "then": "Non accessible aux personnes à mobilité réduite" + } + }, + "question": "Y a-t-il des toilettes réservées aux personnes en fauteuil roulant ?" } }, "title": { @@ -1673,29 +1673,18 @@ } }, "tagRenderings": { - "1": { + "tree-decidouous": { "mappings": { "0": { - "then": "Hauteur : {height} m" - } - }, - "render": "Hauteur : {height}" - }, - "2": { - "mappings": { - "0": { - "then": "\"\"/ Feuillu" + "then": "Caduc : l’arbre perd son feuillage une partie de l’année." }, "1": { - "then": "\"\"/ Résineux" - }, - "2": { - "then": "\"\"/ Sans feuilles (Permanent)" + "then": "À feuilles persistantes." } }, - "question": "Cet arbre est-il un feuillu ou un résineux ?" + "question": "L’arbre est-il à feuillage persistant ou caduc ?" }, - "3": { + "tree-denotation": { "mappings": { "0": { "then": "L'arbre est remarquable en raison de sa taille ou de son emplacement proéminent. Il est utile pour la navigation." @@ -1724,27 +1713,15 @@ }, "question": "Quelle est l'importance de cet arbre ? Choisissez la première réponse qui s'applique." }, - "4": { + "tree-height": { "mappings": { "0": { - "then": "Caduc : l’arbre perd son feuillage une partie de l’année." - }, - "1": { - "then": "À feuilles persistantes." + "then": "Hauteur : {height} m" } }, - "question": "L’arbre est-il à feuillage persistant ou caduc ?" + "render": "Hauteur : {height}" }, - "5": { - "mappings": { - "0": { - "then": "L'arbre n'a pas de nom." - } - }, - "question": "L'arbre a-t-il un nom ?", - "render": "Nom : {name}" - }, - "6": { + "tree-heritage": { "mappings": { "0": { "then": "\"\"/ Fait partie du patrimoine par Onroerend Erfgoed" @@ -1764,11 +1741,34 @@ }, "question": "Cet arbre est-il inscrit au patrimoine ?" }, - "7": { + "tree-leaf_type": { + "mappings": { + "0": { + "then": "\"\"/ Feuillu" + }, + "1": { + "then": "\"\"/ Résineux" + }, + "2": { + "then": "\"\"/ Sans feuilles (Permanent)" + } + }, + "question": "Cet arbre est-il un feuillu ou un résineux ?" + }, + "tree_node-name": { + "mappings": { + "0": { + "then": "L'arbre n'a pas de nom." + } + }, + "question": "L'arbre a-t-il un nom ?", + "render": "Nom : {name}" + }, + "tree_node-ref:OnroerendErfgoed": { "question": "Quel est son identifiant donné par Onroerend Erfgoed ?", "render": "\"\"/ Identifiant Onroerend Erfgoed : {ref:OnroerendErfgoed}" }, - "8": { + "tree_node-wikidata": { "question": "Quel est l'identifiant Wikidata de cet arbre ?", "render": "\"\"/ Wikidata : {wikidata}" } @@ -1791,7 +1791,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Voulez-vous ajouter une description ?" } }, diff --git a/langs/layers/gl.json b/langs/layers/gl.json index 5a6d58c6d..44f1a21ba 100644 --- a/langs/layers/gl.json +++ b/langs/layers/gl.json @@ -7,11 +7,7 @@ } }, "tagRenderings": { - "1": { - "question": "Cal é o nome deste café de ciclistas?", - "render": "Este café de ciclistas chámase {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "Este café de ciclistas ofrece unha bomba de ar" @@ -22,18 +18,17 @@ }, "question": "Este café de ciclistas ofrece unha bomba de ar para que calquera persoa poida usala?" }, - "3": { - "mappings": { - "0": { - "then": "Hai ferramentas aquí para arranxar a túa propia bicicleta" - }, - "1": { - "then": "Non hai ferramentas aquí para arranxar a túa propia bicicleta" - } - }, - "question": "Hai ferramentas aquí para arranxar a túa propia bicicleta?" + "bike_cafe-email": { + "question": "Cal é o enderezo de correo electrónico de {name}?" }, - "4": { + "bike_cafe-name": { + "question": "Cal é o nome deste café de ciclistas?", + "render": "Este café de ciclistas chámase {name}" + }, + "bike_cafe-phone": { + "question": "Cal é o número de teléfono de {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "Este café de ciclistas arranxa bicicletas" @@ -44,14 +39,19 @@ }, "question": "Este café de ciclistas arranxa bicicletas?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "Hai ferramentas aquí para arranxar a túa propia bicicleta" + }, + "1": { + "then": "Non hai ferramentas aquí para arranxar a túa propia bicicleta" + } + }, + "question": "Hai ferramentas aquí para arranxar a túa propia bicicleta?" + }, + "bike_cafe-website": { "question": "Cal é a páxina web de {name}?" - }, - "6": { - "question": "Cal é o número de teléfono de {name}?" - }, - "7": { - "question": "Cal é o enderezo de correo electrónico de {name}?" } }, "title": { @@ -71,7 +71,7 @@ } }, "tagRenderings": { - "1": { + "Bicycle parking type": { "mappings": { "0": { "then": "De roda (Stands) " @@ -95,22 +95,15 @@ "question": "Que tipo de aparcadoiro de bicicletas é?", "render": "Este é un aparcadoiro de bicicletas do tipo: {bicycle_parking}" }, - "3": { - "mappings": { - "0": { - "then": "Este aparcadoiro está cuberto (ten un teito)" - }, - "1": { - "then": "Este aparcadoiro non está cuberto" - } - }, - "question": "Este aparcadoiro está cuberto? Tamén escolle \"cuberto\" para aparcadoiros interiores." - }, - "4": { + "Capacity": { "question": "Cantas bicicletas caben neste aparcadoiro de bicicletas (incluídas as posíbeis bicicletas de carga)?", "render": "Lugar para {capacity} bicicletas" }, - "6": { + "Cargo bike capacity?": { + "question": "Cantas bicicletas de carga caben neste aparcadoiro de bicicletas?", + "render": "Neste aparcadoiro caben {capacity:cargo_bike} bicicletas de carga" + }, + "Cargo bike spaces?": { "mappings": { "0": { "then": "Este aparcadoiro ten espazo para bicicletas de carga." @@ -124,9 +117,16 @@ }, "question": "Este aparcadoiro de bicicletas ten espazo para bicicletas de carga?" }, - "7": { - "question": "Cantas bicicletas de carga caben neste aparcadoiro de bicicletas?", - "render": "Neste aparcadoiro caben {capacity:cargo_bike} bicicletas de carga" + "Is covered?": { + "mappings": { + "0": { + "then": "Este aparcadoiro está cuberto (ten un teito)" + }, + "1": { + "then": "Este aparcadoiro non está cuberto" + } + }, + "question": "Este aparcadoiro está cuberto? Tamén escolle \"cuberto\" para aparcadoiros interiores." } }, "title": { @@ -147,7 +147,18 @@ } }, "tagRenderings": { - "1": { + "Operational status": { + "mappings": { + "0": { + "then": "A bomba de ar está estragada" + }, + "1": { + "then": "A bomba de ar está operativa" + } + }, + "question": "Segue a funcionar a bomba de ar?" + }, + "bike_repair_station-available-services": { "mappings": { "0": { "then": "Só hai unha bomba de ar presente" @@ -161,7 +172,7 @@ }, "question": "Que servizos están dispoñíbeis nesta estación de bicicletas?" }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "Hai unha ferramenta para a cadea" @@ -172,7 +183,7 @@ }, "question": "Esta estación de arranxo de bicicletas ten unha ferramenta especial para arranxar a cadea da túa bicicleta?" }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "Hai un guindastre ou soporte" @@ -183,18 +194,32 @@ }, "question": "Esta estación de bicicletas ten un guindastre para pendurar a túa bicicleta ou un soporte para elevala?" }, - "8": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { - "then": "A bomba de ar está estragada" + "then": "Bomba de ar manual" }, "1": { - "then": "A bomba de ar está operativa" + "then": "Bomba de ar eléctrica" } }, - "question": "Segue a funcionar a bomba de ar?" + "question": "Esta é unha bomba de ar eléctrica?" }, - "10": { + "bike_repair_station-manometer": { + "mappings": { + "0": { + "then": "Hai manómetro" + }, + "1": { + "then": "Non hai manómetro" + }, + "2": { + "then": "Hai manómetro pero está estragado" + } + }, + "question": "Ten a bomba de ar un indicador de presión ou un manómetro?" + }, + "bike_repair_station-valves": { "mappings": { "0": { "then": "Sclaverand (tamén coñecido como Presta)" @@ -208,31 +233,6 @@ }, "question": "Que válvulas son compatíbeis?", "render": "Esta bomba de ar admite as seguintes válvulas: {valves}" - }, - "11": { - "mappings": { - "0": { - "then": "Bomba de ar manual" - }, - "1": { - "then": "Bomba de ar eléctrica" - } - }, - "question": "Esta é unha bomba de ar eléctrica?" - }, - "12": { - "mappings": { - "0": { - "then": "Hai manómetro" - }, - "1": { - "then": "Non hai manómetro" - }, - "2": { - "then": "Hai manómetro pero está estragado" - } - }, - "question": "Ten a bomba de ar un indicador de presión ou un manómetro?" } }, "title": { @@ -264,31 +264,29 @@ } }, "tagRenderings": { - "2": { - "question": "Cal é o nome desta tenda de bicicletas?", - "render": "Esta tenda de bicicletas chámase {name}" - }, - "3": { - "question": "Cal é a páxina web de {name}?" - }, - "4": { - "question": "Cal é o número de teléfono de {name}?" - }, - "5": { - "question": "Cal é o enderezo de correo electrónico de {name}?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "Esta tenda vende bicicletas" + "then": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa" }, "1": { - "then": "Esta tenda non vende bicicletas" + "then": "Esta tenda non ofrece unha bomba de ar para uso de calquera persoa" } }, - "question": "Esta tenda vende bicicletas?" + "question": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa?" }, - "10": { + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "Esta tenda aluga bicicletas" + }, + "1": { + "then": "Esta tenda non aluga bicicletas" + } + }, + "question": "Esta tenda aluga bicicletas?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Esta tenda arranxa bicicletas" @@ -305,18 +303,7 @@ }, "question": "Esta tenda arranxa bicicletas?" }, - "11": { - "mappings": { - "0": { - "then": "Esta tenda aluga bicicletas" - }, - "1": { - "then": "Esta tenda non aluga bicicletas" - } - }, - "question": "Esta tenda aluga bicicletas?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "Esta tenda vende bicicletas de segunda man" @@ -330,18 +317,18 @@ }, "question": "Esta tenda vende bicicletas de segunda man?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa" + "then": "Esta tenda vende bicicletas" }, "1": { - "then": "Esta tenda non ofrece unha bomba de ar para uso de calquera persoa" + "then": "Esta tenda non vende bicicletas" } }, - "question": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa?" + "question": "Esta tenda vende bicicletas?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "0": { "then": "Hai ferramentas aquí para arranxar a túa propia bicicleta" @@ -351,6 +338,19 @@ } }, "question": "Hai ferramentas aquí para arranxar a túa propia bicicleta?" + }, + "bike_shop-email": { + "question": "Cal é o enderezo de correo electrónico de {name}?" + }, + "bike_shop-name": { + "question": "Cal é o nome desta tenda de bicicletas?", + "render": "Esta tenda de bicicletas chámase {name}" + }, + "bike_shop-phone": { + "question": "Cal é o número de teléfono de {name}?" + }, + "bike_shop-website": { + "question": "Cal é a páxina web de {name}?" } }, "title": { diff --git a/langs/layers/hu.json b/langs/layers/hu.json index 4ffbf2671..2842a2d33 100644 --- a/langs/layers/hu.json +++ b/langs/layers/hu.json @@ -7,7 +7,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Háttámla: Igen" @@ -19,39 +19,7 @@ "question": "Van háttámlája ennek a padnak?", "render": "Háttámla" }, - "2": { - "question": "Hány ülőhely van ezen a padon?", - "render": "{seats} ülőhely" - }, - "3": { - "mappings": { - "0": { - "then": "Anyag: fa" - }, - "1": { - "then": "Anyag: fém" - }, - "2": { - "then": "Anyag: kő" - }, - "3": { - "then": "Anyag: beton" - }, - "4": { - "then": "Anyag: műanyag" - }, - "5": { - "then": "Anyag: acél" - } - }, - "question": "Miből van a pad (ülő része)?", - "render": "Anyag: {material}" - }, - "4": { - "question": "Milyen irányba néz a pad?", - "render": "A pad {direction}° felé néz." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Szín: barna" @@ -80,6 +48,38 @@ }, "question": "Milyen színű a pad?", "render": "Szín: {colour}" + }, + "bench-direction": { + "question": "Milyen irányba néz a pad?", + "render": "A pad {direction}° felé néz." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Anyag: fa" + }, + "1": { + "then": "Anyag: fém" + }, + "2": { + "then": "Anyag: kő" + }, + "3": { + "then": "Anyag: beton" + }, + "4": { + "then": "Anyag: műanyag" + }, + "5": { + "then": "Anyag: acél" + } + }, + "question": "Miből van a pad (ülő része)?", + "render": "Anyag: {material}" + }, + "bench-seats": { + "question": "Hány ülőhely van ezen a padon?", + "render": "{seats} ülőhely" } }, "title": { @@ -89,7 +89,7 @@ "bench_at_pt": { "name": "Padok megállókban", "tagRenderings": { - "1": { + "bench_at_pt-name": { "render": "{name}" } }, @@ -108,7 +108,15 @@ "bicycle_library": { "description": "Létesítmény, ahonnan kerékpár kölcsönözhető hosszabb időre", "tagRenderings": { - "6": { + "bicycle-library-target-group": { + "mappings": { + "0": { + "then": "" + } + }, + "question": "Ki kölcsönözhet itt kerékpárt?" + }, + "bicycle_library-charge": { "mappings": { "0": { "then": "A kerékpárkölcsönzés ingyenes" @@ -116,20 +124,12 @@ }, "question": "Mennyibe kerül egy kerékpár kölcsönzése?", "render": "Egy kerékpár kölcsönzése {charge}" - }, - "7": { - "mappings": { - "0": { - "then": "" - } - }, - "question": "Ki kölcsönözhet itt kerékpárt?" } } }, "bicycle_tube_vending_machine": { "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Az automata működik" @@ -152,7 +152,7 @@ } }, "tagRenderings": { - "1": { + "Bicycle parking type": { "mappings": { "0": { "then": "\"U\" " @@ -170,7 +170,18 @@ "question": "Milyen típusú ez a kerékpáros parkoló?", "render": "Ez egy {bicycle_parking} típusú kerékpáros parkoló" }, - "2": { + "Is covered?": { + "mappings": { + "0": { + "then": "A parkoló fedett" + }, + "1": { + "then": "A parkoló nem fedett" + } + }, + "question": "Fedett ez a parkoló? (Beltéri parkoló esetén is válaszd a \"fedett\" opciót.)" + }, + "Underground?": { "mappings": { "2": { "then": "Felszíni parkoló" @@ -182,17 +193,6 @@ "then": "Tetőparkoló" } } - }, - "3": { - "mappings": { - "0": { - "then": "A parkoló fedett" - }, - "1": { - "then": "A parkoló nem fedett" - } - }, - "question": "Fedett ez a parkoló? (Beltéri parkoló esetén is válaszd a \"fedett\" opciót.)" } }, "title": { diff --git a/langs/layers/id.json b/langs/layers/id.json index d6990fce5..7aacdc7aa 100644 --- a/langs/layers/id.json +++ b/langs/layers/id.json @@ -7,7 +7,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Sandaran: Ya" @@ -19,11 +19,11 @@ "question": "Apakah bangku ini memiliki sandaran?", "render": "Sandaran" }, - "2": { - "render": "{seats} kursi" - }, - "5": { + "bench-colour": { "render": "Warna: {colour}" + }, + "bench-seats": { + "render": "{seats} kursi" } }, "title": { @@ -32,7 +32,7 @@ }, "bench_at_pt": { "tagRenderings": { - "1": { + "bench_at_pt-name": { "render": "{name}" } }, @@ -42,21 +42,21 @@ }, "bike_parking": { "tagRenderings": { - "5": { + "Access": { "render": "{access}" } } }, "bike_shop": { "tagRenderings": { - "3": { + "bike_shop-website": { "question": "URL {name} apa?" } } }, "defibrillator": { "tagRenderings": { - "13": { + "defibrillator-description": { "render": "Informasi tambahan: {description}" } } @@ -74,30 +74,30 @@ }, "ghost_bike": { "tagRenderings": { - "3": { - "render": "Informasi lanjut tersedia" - }, - "4": { + "ghost_bike-inscription": { "render": "{inscription}" + }, + "ghost_bike-source": { + "render": "Informasi lanjut tersedia" } } }, "nature_reserve": { "tagRenderings": { - "8": { + "Email": { "render": "{email}" }, - "9": { + "phone": { "render": "{phone}" } } }, "playground": { "tagRenderings": { - "7": { + "playground-email": { "render": "{email}" }, - "8": { + "playground-phone": { "render": "{phone}" } } @@ -109,7 +109,7 @@ } }, "tagRenderings": { - "5": { + "tree_node-name": { "render": "Nama: {name}" } }, @@ -129,7 +129,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Apakah Anda ingin menambahkan deskripsi?" } }, diff --git a/langs/layers/it.json b/langs/layers/it.json index 4b714e5c9..d5e8c4050 100644 --- a/langs/layers/it.json +++ b/langs/layers/it.json @@ -8,7 +8,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Schienale: Sì" @@ -20,39 +20,7 @@ "question": "Questa panchina ha lo schienale?", "render": "Schienale" }, - "2": { - "question": "Quanti posti ha questa panchina?", - "render": "{seats} posti" - }, - "3": { - "mappings": { - "0": { - "then": "Materiale: legno" - }, - "1": { - "then": "Materiale: metallo" - }, - "2": { - "then": "Materiale: pietra" - }, - "3": { - "then": "Materiale: cemento" - }, - "4": { - "then": "Materiale: plastica" - }, - "5": { - "then": "Materiale: acciaio" - } - }, - "question": "Di che materiale è fatta questa panchina?", - "render": "Materiale: {material}" - }, - "4": { - "question": "In che direzione si guarda quando si è seduti su questa panchina?", - "render": "Quando si è seduti su questa panchina, si guarda verso {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Colore: marrone" @@ -82,7 +50,39 @@ "question": "Di che colore è questa panchina?", "render": "Colore: {colour}" }, - "6": { + "bench-direction": { + "question": "In che direzione si guarda quando si è seduti su questa panchina?", + "render": "Quando si è seduti su questa panchina, si guarda verso {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Materiale: legno" + }, + "1": { + "then": "Materiale: metallo" + }, + "2": { + "then": "Materiale: pietra" + }, + "3": { + "then": "Materiale: cemento" + }, + "4": { + "then": "Materiale: plastica" + }, + "5": { + "then": "Materiale: acciaio" + } + }, + "question": "Di che materiale è fatta questa panchina?", + "render": "Materiale: {material}" + }, + "bench-seats": { + "question": "Quanti posti ha questa panchina?", + "render": "{seats} posti" + }, + "bench-survey:date": { "question": "Quando è stata verificata l’ultima volta questa panchina?", "render": "Questa panchina è stata controllata l’ultima volta in data {survey:date}" } @@ -94,11 +94,11 @@ "bench_at_pt": { "name": "Panchine alle fermate del trasporto pubblico", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "Panca in piedi" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -123,23 +123,7 @@ } }, "tagRenderings": { - "1": { - "question": "Qual è il nome di questo “bici in prestito”?", - "render": "Il “bici in prestito” è chiamato {name}" - }, - "6": { - "mappings": { - "0": { - "then": "Il prestito di una bicicletta è gratuito" - }, - "1": { - "then": "Il prestito di una bicicletta costa 20 €/anno più 20 € di garanzia" - } - }, - "question": "Quanto costa il prestito di una bicicletta?", - "render": "Il prestito di una bicicletta costa {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Sono disponibili biciclette per bambini" @@ -152,6 +136,22 @@ } }, "question": "Chi può prendere in prestito le biciclette qua?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "Il prestito di una bicicletta è gratuito" + }, + "1": { + "then": "Il prestito di una bicicletta costa 20 €/anno più 20 € di garanzia" + } + }, + "question": "Quanto costa il prestito di una bicicletta?", + "render": "Il prestito di una bicicletta costa {charge}" + }, + "bicycle_library-name": { + "question": "Qual è il nome di questo “bici in prestito”?", + "render": "Il “bici in prestito” è chiamato {name}" } }, "title": { @@ -166,7 +166,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Il distributore automatico funziona" @@ -194,11 +194,7 @@ } }, "tagRenderings": { - "1": { - "question": "Qual è il nome di questo caffè in bici?", - "render": "Questo caffè in bici è chiamato {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "Questo caffè in bici offre una pompa per bici liberamente utilizzabile" @@ -209,18 +205,20 @@ }, "question": "Questo caffè in bici offre una pompa per bici che chiunque può utilizzare?" }, - "3": { - "mappings": { - "0": { - "then": "Questo caffè in bici fornisce degli attrezzi per la riparazione fai-da-te" - }, - "1": { - "then": "Questo caffè in bici non fornisce degli attrezzi per la riparazione fai-da-te" - } - }, - "question": "Ci sono degli strumenti per riparare la propria bicicletta?" + "bike_cafe-email": { + "question": "Qual è l’indirizzo email di {name}?" }, - "4": { + "bike_cafe-name": { + "question": "Qual è il nome di questo caffè in bici?", + "render": "Questo caffè in bici è chiamato {name}" + }, + "bike_cafe-opening_hours": { + "question": "Quando è aperto questo caffè in bici?" + }, + "bike_cafe-phone": { + "question": "Qual è il numero di telefono di {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "Questo caffè in bici ripara le bici" @@ -231,17 +229,19 @@ }, "question": "Questo caffè in bici ripara le bici?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "Questo caffè in bici fornisce degli attrezzi per la riparazione fai-da-te" + }, + "1": { + "then": "Questo caffè in bici non fornisce degli attrezzi per la riparazione fai-da-te" + } + }, + "question": "Ci sono degli strumenti per riparare la propria bicicletta?" + }, + "bike_cafe-website": { "question": "Qual è il sito web di {name}?" - }, - "6": { - "question": "Qual è il numero di telefono di {name}?" - }, - "7": { - "question": "Qual è l’indirizzo email di {name}?" - }, - "8": { - "question": "Quando è aperto questo caffè in bici?" } }, "title": { @@ -277,7 +277,22 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "Accessibile pubblicamente" + }, + "1": { + "then": "Accesso destinato principalmente ai visitatori di un’attività" + }, + "2": { + "then": "Accesso limitato ai membri di una scuola, una compagnia o un’organizzazione" + } + }, + "question": "Chi può usare questo parcheggio bici?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "0": { "then": "Archetti " @@ -307,7 +322,40 @@ "question": "Di che tipo di parcheggio bici si tratta?", "render": "È un parcheggio bici del tipo: {bicycle_parking}" }, - "2": { + "Capacity": { + "question": "Quante biciclette entrano in questo parcheggio per bici (incluse le eventuali bici da trasporto)?", + "render": "Posti per {capacity} bici" + }, + "Cargo bike capacity?": { + "question": "Quante bici da trasporto entrano in questo parcheggio per bici?", + "render": "Questo parcheggio può contenere {capacity:cargo_bike} bici da trasporto" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "Questo parcheggio ha posto per bici da trasporto" + }, + "1": { + "then": "Questo parcheggio ha posti destinati (ufficialmente) alle bici da trasporto." + }, + "2": { + "then": "Il parcheggio delle bici da trasporto è proibito" + } + }, + "question": "Questo parcheggio dispone di posti specifici per le bici da trasporto?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "È un parcheggio coperto (ha un tetto)" + }, + "1": { + "then": "Non è un parcheggio coperto" + } + }, + "question": "È un parcheggio coperto? Indicare “coperto” per parcheggi all’interno." + }, + "Underground?": { "mappings": { "0": { "then": "Parcheggio sotterraneo" @@ -326,54 +374,6 @@ } }, "question": "Qual è la posizione relativa di questo parcheggio bici?" - }, - "3": { - "mappings": { - "0": { - "then": "È un parcheggio coperto (ha un tetto)" - }, - "1": { - "then": "Non è un parcheggio coperto" - } - }, - "question": "È un parcheggio coperto? Indicare “coperto” per parcheggi all’interno." - }, - "4": { - "question": "Quante biciclette entrano in questo parcheggio per bici (incluse le eventuali bici da trasporto)?", - "render": "Posti per {capacity} bici" - }, - "5": { - "mappings": { - "0": { - "then": "Accessibile pubblicamente" - }, - "1": { - "then": "Accesso destinato principalmente ai visitatori di un’attività" - }, - "2": { - "then": "Accesso limitato ai membri di una scuola, una compagnia o un’organizzazione" - } - }, - "question": "Chi può usare questo parcheggio bici?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "Questo parcheggio ha posto per bici da trasporto" - }, - "1": { - "then": "Questo parcheggio ha posti destinati (ufficialmente) alle bici da trasporto." - }, - "2": { - "then": "Il parcheggio delle bici da trasporto è proibito" - } - }, - "question": "Questo parcheggio dispone di posti specifici per le bici da trasporto?" - }, - "7": { - "question": "Quante bici da trasporto entrano in questo parcheggio per bici?", - "render": "Questo parcheggio può contenere {capacity:cargo_bike} bici da trasporto" } }, "title": { @@ -399,7 +399,18 @@ } }, "tagRenderings": { - "1": { + "Operational status": { + "mappings": { + "0": { + "then": "La pompa per bici è guasta" + }, + "1": { + "then": "La pompa per bici funziona" + } + }, + "question": "La pompa per bici è sempre funzionante?" + }, + "bike_repair_station-available-services": { "mappings": { "0": { "then": "C’è solamente una pompa presente" @@ -413,22 +424,7 @@ }, "question": "Quali servizi sono disponibili in questa stazione per bici?" }, - "2": { - "question": "Chi gestisce questa pompa per bici?", - "render": "Manutenuta da {operator}" - }, - "5": { - "mappings": { - "0": { - "then": "Sempre aperto" - }, - "1": { - "then": "Sempre aperto" - } - }, - "question": "Quando è aperto questo punto riparazione bici?" - }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "È presente un utensile per riparare la catena" @@ -439,7 +435,7 @@ }, "question": "Questa stazione di riparazione bici ha un attrezzo speciale per riparare la catena della bici?" }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "C’è un gancio o un supporto" @@ -450,18 +446,47 @@ }, "question": "Questa stazione bici ha un gancio per tenere sospesa la bici o un supporto per alzarla?" }, - "8": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { - "then": "La pompa per bici è guasta" + "then": "Pompa manuale" }, "1": { - "then": "La pompa per bici funziona" + "then": "Pompa elettrica" } }, - "question": "La pompa per bici è sempre funzionante?" + "question": "Questa pompa per bici è elettrica?" }, - "10": { + "bike_repair_station-manometer": { + "mappings": { + "0": { + "then": "C’è un manometro" + }, + "1": { + "then": "Non c’è un manometro" + }, + "2": { + "then": "C’è un manometro ma è rotto" + } + }, + "question": "Questa pompa ha l’indicatore della pressione o il manometro?" + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Sempre aperto" + }, + "1": { + "then": "Sempre aperto" + } + }, + "question": "Quando è aperto questo punto riparazione bici?" + }, + "bike_repair_station-operator": { + "question": "Chi gestisce questa pompa per bici?", + "render": "Manutenuta da {operator}" + }, + "bike_repair_station-valves": { "mappings": { "0": { "then": "Sclaverand (detta anche Presta)" @@ -475,31 +500,6 @@ }, "question": "Quali valvole sono supportate?", "render": "Questa pompa è compatibile con le seguenti valvole: {valves}" - }, - "11": { - "mappings": { - "0": { - "then": "Pompa manuale" - }, - "1": { - "then": "Pompa elettrica" - } - }, - "question": "Questa pompa per bici è elettrica?" - }, - "12": { - "mappings": { - "0": { - "then": "C’è un manometro" - }, - "1": { - "then": "Non c’è un manometro" - }, - "2": { - "then": "C’è un manometro ma è rotto" - } - }, - "question": "Questa pompa ha l’indicatore della pressione o il manometro?" } }, "title": { @@ -532,34 +532,46 @@ } }, "tagRenderings": { - "1": { - "render": "Questo negozio è specializzato nella vendita di {shop} ed effettua attività relative alle biciclette" - }, - "2": { - "question": "Qual è il nome di questo negozio di biciclette?", - "render": "Questo negozio di biciclette è chiamato {name}" - }, - "3": { - "question": "Qual è il sito web di {name}?" - }, - "4": { - "question": "Qual è il numero di telefono di {name}?" - }, - "5": { - "question": "Qual è l’indirizzo email di {name}?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "Questo negozio vende bici" + "then": "Questo negozio offre l’uso pubblico di una pompa per bici" }, "1": { - "then": "Questo negozio non vende bici" + "then": "Questo negozio non offre l’uso pubblico di una pompa per bici" + }, + "2": { + "then": "C’è una pompa per bici, è mostrata come punto separato " } }, - "question": "Questo negozio vende bici?" + "question": "Questo negozio offre l’uso a chiunque di una pompa per bici?" }, - "10": { + "bike_repair_bike-wash": { + "mappings": { + "0": { + "then": "Questo negozio lava le biciclette" + }, + "1": { + "then": "Questo negozio ha una struttura dove è possibile pulire la propria bici" + }, + "2": { + "then": "Questo negozio non offre la pulizia della bicicletta" + } + }, + "question": "Vengono lavate le bici qua?" + }, + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "Questo negozio noleggia le bici" + }, + "1": { + "then": "Questo negozio non noleggia le bici" + } + }, + "question": "Questo negozio noleggia le bici?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Questo negozio ripara bici" @@ -576,18 +588,7 @@ }, "question": "Questo negozio ripara bici?" }, - "11": { - "mappings": { - "0": { - "then": "Questo negozio noleggia le bici" - }, - "1": { - "then": "Questo negozio non noleggia le bici" - } - }, - "question": "Questo negozio noleggia le bici?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "Questo negozio vende bici usate" @@ -601,21 +602,18 @@ }, "question": "Questo negozio vende bici usate?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "Questo negozio offre l’uso pubblico di una pompa per bici" + "then": "Questo negozio vende bici" }, "1": { - "then": "Questo negozio non offre l’uso pubblico di una pompa per bici" - }, - "2": { - "then": "C’è una pompa per bici, è mostrata come punto separato " + "then": "Questo negozio non vende bici" } }, - "question": "Questo negozio offre l’uso a chiunque di una pompa per bici?" + "question": "Questo negozio vende bici?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "0": { "then": "Questo negozio offre degli attrezzi per la riparazione fai-da-te" @@ -629,19 +627,21 @@ }, "question": "Sono presenti degli attrezzi per riparare la propria bici?" }, - "15": { - "mappings": { - "0": { - "then": "Questo negozio lava le biciclette" - }, - "1": { - "then": "Questo negozio ha una struttura dove è possibile pulire la propria bici" - }, - "2": { - "then": "Questo negozio non offre la pulizia della bicicletta" - } - }, - "question": "Vengono lavate le bici qua?" + "bike_shop-email": { + "question": "Qual è l’indirizzo email di {name}?" + }, + "bike_shop-is-bicycle_shop": { + "render": "Questo negozio è specializzato nella vendita di {shop} ed effettua attività relative alle biciclette" + }, + "bike_shop-name": { + "question": "Qual è il nome di questo negozio di biciclette?", + "render": "Questo negozio di biciclette è chiamato {name}" + }, + "bike_shop-phone": { + "question": "Qual è il numero di telefono di {name}?" + }, + "bike_shop-website": { + "question": "Qual è il sito web di {name}?" } }, "title": { @@ -680,12 +680,12 @@ "description": "Una stazione di ricarica", "name": "Stazioni di ricarica", "tagRenderings": { - "57": { - "question": "Quali sono gli orari di apertura di questa stazione di ricarica?" - }, - "58": { + "Auth phone": { "question": "A quale rete appartiene questa stazione di ricarica?", "render": "{network}" + }, + "Authentication": { + "question": "Quali sono gli orari di apertura di questa stazione di ricarica?" } }, "title": { @@ -707,18 +707,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Questo defibrillatore si trova all’interno" - }, - "1": { - "then": "Questo defibrillatore si trova all’esterno" - } - }, - "question": "Questo defibrillatore si trova all’interno?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Pubblicamente accessibile" @@ -739,7 +728,7 @@ "question": "Questo defibrillatore è liberamente accessibile?", "render": "Accesso è {access}" }, - "3": { + "defibrillator-defibrillator": { "mappings": { "0": { "then": "Questo è un defibrillatore manuale per professionisti" @@ -751,7 +740,42 @@ "question": "Si tratta di un normale defibrillatore automatico o un defibrillatore manuale riservato ai professionisti?", "render": "Non vi sono informazioni riguardanti il tipo di questo dispositivo" }, - "4": { + "defibrillator-defibrillator:location": { + "question": "Indica più precisamente dove si trova il defibrillatore (in lingua locale)", + "render": "Informazioni supplementari circa la posizione (in lingua locale):
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:en": { + "question": "Indica più precisamente dove si trova il defibrillatore (in inglese)", + "render": "Informazioni supplementari circa la posizione (in inglese):
{defibrillator:location:en}" + }, + "defibrillator-defibrillator:location:fr": { + "question": "Indica più precisamente dove si trova il defibrillatore (in francese)", + "render": "Informazioni supplementari circa la posizione (in francese):
{defibrillator:location:fr}" + }, + "defibrillator-description": { + "question": "Vi sono altre informazioni utili agli utenti che non è stato possibile aggiungere prima? (lasciare vuoto in caso negativo)", + "render": "Informazioni supplementari: {description}" + }, + "defibrillator-email": { + "question": "Qual è l’indirizzo email per le domande riguardanti questo defibrillatore?", + "render": "Indirizzo email per le domande su questo defibrillatore:{email}" + }, + "defibrillator-fixme": { + "question": "C’è qualcosa di sbagliato riguardante come è stato mappato, che non si è potuto correggere qua? (lascia una nota agli esperti di OpenStreetMap)", + "render": "Informazioni supplementari per gli esperti di OpenStreetMap: {fixme}" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "Questo defibrillatore si trova all’interno" + }, + "1": { + "then": "Questo defibrillatore si trova all’esterno" + } + }, + "question": "Questo defibrillatore si trova all’interno?" + }, + "defibrillator-level": { "mappings": { "0": { "then": "Questo defibrillatore è al pian terreno" @@ -763,31 +787,7 @@ "question": "A che piano si trova questo defibrillatore?", "render": "Questo defibrillatore è al piano {level}" }, - "5": { - "question": "Indica più precisamente dove si trova il defibrillatore (in lingua locale)", - "render": "Informazioni supplementari circa la posizione (in lingua locale):
{defibrillator:location}" - }, - "6": { - "question": "Indica più precisamente dove si trova il defibrillatore (in inglese)", - "render": "Informazioni supplementari circa la posizione (in inglese):
{defibrillator:location:en}" - }, - "7": { - "question": "Indica più precisamente dove si trova il defibrillatore (in francese)", - "render": "Informazioni supplementari circa la posizione (in francese):
{defibrillator:location:fr}" - }, - "9": { - "question": "Qual è il numero identificativo ufficiale di questo dispositivo? (se visibile sul dispositivo)", - "render": "Numero identificativo ufficiale di questo dispositivo:{ref}" - }, - "10": { - "question": "Qual è l’indirizzo email per le domande riguardanti questo defibrillatore?", - "render": "Indirizzo email per le domande su questo defibrillatore:{email}" - }, - "11": { - "question": "Qual è il numero di telefono per le domande riguardanti questo defibrillatore?", - "render": "Numero di telefono per le domande su questo defibrillatore:{phone}" - }, - "12": { + "defibrillator-opening_hours": { "mappings": { "0": { "then": "Aperto 24/7 (festivi inclusi)" @@ -796,11 +796,15 @@ "question": "In quali orari è disponibile questo defibrillatore?", "render": "{opening_hours_table(opening_hours)}" }, - "13": { - "question": "Vi sono altre informazioni utili agli utenti che non è stato possibile aggiungere prima? (lasciare vuoto in caso negativo)", - "render": "Informazioni supplementari: {description}" + "defibrillator-phone": { + "question": "Qual è il numero di telefono per le domande riguardanti questo defibrillatore?", + "render": "Numero di telefono per le domande su questo defibrillatore:{phone}" }, - "14": { + "defibrillator-ref": { + "question": "Qual è il numero identificativo ufficiale di questo dispositivo? (se visibile sul dispositivo)", + "render": "Numero identificativo ufficiale di questo dispositivo:{ref}" + }, + "defibrillator-survey:date": { "mappings": { "0": { "then": "Verificato oggi!" @@ -808,10 +812,6 @@ }, "question": "Quando è stato verificato per l’ultima volta questo defibrillatore?", "render": "Questo defibrillatore è stato verificato per l‘ultima volta in data {survey:date}" - }, - "15": { - "question": "C’è qualcosa di sbagliato riguardante come è stato mappato, che non si è potuto correggere qua? (lascia una nota agli esperti di OpenStreetMap)", - "render": "Informazioni supplementari per gli esperti di OpenStreetMap: {fixme}" } }, "title": { @@ -830,7 +830,18 @@ } }, "tagRenderings": { - "1": { + "Bottle refill": { + "mappings": { + "0": { + "then": "È facile riempire d’acqua le bottiglie" + }, + "1": { + "then": "Le bottiglie d’acqua potrebbero non entrare" + } + }, + "question": "Quanto è facile riempire d’acqua le bottiglie?" + }, + "Still in use?": { "mappings": { "0": { "then": "La fontanella funziona" @@ -845,18 +856,7 @@ "question": "Questo punto di acqua potabile è sempre funzionante?", "render": "Lo stato operativo è {operational_status}" }, - "2": { - "mappings": { - "0": { - "then": "È facile riempire d’acqua le bottiglie" - }, - "1": { - "then": "Le bottiglie d’acqua potrebbero non entrare" - } - }, - "question": "Quanto è facile riempire d’acqua le bottiglie?" - }, - "3": { + "render-closest-drinking-water": { "render": "C’è un’altra fontanella a {_closest_other_drinking_water_distance} metri" } }, @@ -872,10 +872,14 @@ } }, "tagRenderings": { - "0": { + "ghost-bike-explanation": { "render": "Una bici fantasma è il memoriale di un ciclista che è morto in un incidente stradale e che ha la forma di una bicicletta bianca piazzata in maniera stabile vicino al luogo dell’incidente." }, - "2": { + "ghost_bike-inscription": { + "question": "Che cosa è scritto sulla bici fantasma?", + "render": "{inscription}" + }, + "ghost_bike-name": { "mappings": { "0": { "then": "Nessun nome scritto sulla bici" @@ -884,15 +888,11 @@ "question": "A chi è dedicata questa bici fantasma?
Rispetta la privacy (compila solo il nome se questo è stato ampiamente pubblicato o se è scritto sulla bici). Decidi se è il caso di non inserire il cognome.
", "render": "In ricordo di {name}" }, - "3": { + "ghost_bike-source": { "question": "In quale pagina web si possono trovare informazioni sulla bici fantasma o l’incidente?", "render": "Sono disponibili ulteriori informazioni" }, - "4": { - "question": "Che cosa è scritto sulla bici fantasma?", - "render": "{inscription}" - }, - "5": { + "ghost_bike-start_date": { "question": "Quando è stata installata questa bici fantasma?", "render": "Piazzata in data {start_date}" } @@ -927,16 +927,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Questa mappa si basa su OpenStreetMap" - } - }, - "question": "Su quali dati si basa questa mappa?", - "render": "Questa mappa si basa su {map_source}" - }, - "2": { + "map-attribution": { "mappings": { "0": { "then": "L’attribuzione a OpenStreetMap è chiaramente specificata, inclusa la licenza ODBL" @@ -955,6 +946,15 @@ } }, "question": "L’attribuzione a OpenStreetMap è presente?" + }, + "map-map_source": { + "mappings": { + "0": { + "then": "Questa mappa si basa su OpenStreetMap" + } + }, + "question": "Su quali dati si basa questa mappa?", + "render": "Questa mappa si basa su {map_source}" } }, "title": { @@ -963,7 +963,11 @@ }, "nature_reserve": { "tagRenderings": { - "5": { + "Curator": { + "question": "Chi è il curatore di questa riserva naturale?
Rispetta la privacy (scrivi il nome solo se questo è noto pubblicamente)", + "render": "{curator} è il curatore di questa riserva naturale" + }, + "Dogs?": { "mappings": { "0": { "then": "I cani devono essere tenuti al guinzaglio" @@ -977,23 +981,19 @@ }, "question": "I cani sono ammessi in questa riserva naturale?" }, - "6": { - "question": "In quale pagina web si possono trovare altre informazioni riguardanti questa riserva naturale?" - }, - "7": { - "question": "Chi è il curatore di questa riserva naturale?
Rispetta la privacy (scrivi il nome solo se questo è noto pubblicamente)", - "render": "{curator} è il curatore di questa riserva naturale" - }, - "8": { + "Email": { "question": "Qual è l’indirizzo email a cui scrivere per fare domande o segnalare problemi su questa riserva naturale?
Rispetta la privacy (compila l’indirizzo email personale solo se è stato reso pubblico)", "render": "{email}" }, - "9": { + "Surface area": { + "render": "Area: {_surface:ha} ha" + }, + "Website": { + "question": "In quale pagina web si possono trovare altre informazioni riguardanti questa riserva naturale?" + }, + "phone": { "question": "Quale numero di telefono comporre per fare domande o segnalare problemi riguardanti questa riserva naturale?br/>Rispetta la privacy (inserisci il numero di telefono privato solo se questo è noto pubblicamente)", "render": "{phone}" - }, - "12": { - "render": "Area: {_surface:ha} ha" } } }, @@ -1006,7 +1006,7 @@ } }, "tagRenderings": { - "0": { + "picnic_table-material": { "mappings": { "0": { "then": "È un tavolo da picnic in legno" @@ -1032,7 +1032,86 @@ } }, "tagRenderings": { - "1": { + "Playground-wheelchair": { + "mappings": { + "0": { + "then": "Completamente accessibile in sedia a rotelle" + }, + "1": { + "then": "Accesso limitato in sedia a rotelle" + }, + "2": { + "then": "Non accessibile in sedia a rotelle" + } + }, + "question": "Il campetto è accessibile a persone in sedia a rotelle?" + }, + "playground-access": { + "mappings": { + "0": { + "then": "Accessibile pubblicamente" + }, + "1": { + "then": "Accessibile pubblicamente" + }, + "2": { + "then": "Accessibile solamente ai clienti dell’attività che lo gestisce" + }, + "3": { + "then": "Accessibile solamente agli studenti della scuola" + }, + "4": { + "then": "Non accessibile" + } + }, + "question": "Questo parco giochi è pubblicamente accessibile?" + }, + "playground-email": { + "question": "Qual è l’indirizzo email del gestore di questo parco giochi?", + "render": "{email}" + }, + "playground-lit": { + "mappings": { + "0": { + "then": "Questo parco giochi è illuminato di notte" + }, + "1": { + "then": "Questo parco giochi non è illuminato di notte" + } + }, + "question": "È illuminato di notte questo parco giochi?" + }, + "playground-max_age": { + "question": "Qual è l’età massima per accedere a questo parco giochi?", + "render": "Accessibile ai bambini di età inferiore a {max_age}" + }, + "playground-min_age": { + "question": "Qual è l’età minima per accedere a questo parco giochi?", + "render": "Accessibile ai bambini di almeno {min_age} anni" + }, + "playground-opening_hours": { + "mappings": { + "0": { + "then": "Si può accedere dall'alba al tramonto" + }, + "1": { + "then": "Si può sempre accedere" + }, + "2": { + "then": "Si può sempre accedere" + } + }, + "question": "Quando si può accedere a questo campetto?" + }, + "playground-operator": { + "question": "Chi è il responsabile di questo parco giochi?", + "render": "Gestito da {operator}" + }, + "playground-phone": { + "question": "Qual è il numero di telefono del gestore del campetto?", + "render": "{phone}" + }, + "playground-surface": { "mappings": { "0": { "then": "La superficie è prato" @@ -1061,85 +1140,6 @@ }, "question": "Qual è la superficie di questo parco giochi?
Se ve ne è più di una, seleziona quella predominante", "render": "La superficie è {surface}" - }, - "2": { - "mappings": { - "0": { - "then": "Questo parco giochi è illuminato di notte" - }, - "1": { - "then": "Questo parco giochi non è illuminato di notte" - } - }, - "question": "È illuminato di notte questo parco giochi?" - }, - "3": { - "question": "Qual è l’età minima per accedere a questo parco giochi?", - "render": "Accessibile ai bambini di almeno {min_age} anni" - }, - "4": { - "question": "Qual è l’età massima per accedere a questo parco giochi?", - "render": "Accessibile ai bambini di età inferiore a {max_age}" - }, - "5": { - "question": "Chi è il responsabile di questo parco giochi?", - "render": "Gestito da {operator}" - }, - "6": { - "mappings": { - "0": { - "then": "Accessibile pubblicamente" - }, - "1": { - "then": "Accessibile pubblicamente" - }, - "2": { - "then": "Accessibile solamente ai clienti dell’attività che lo gestisce" - }, - "3": { - "then": "Accessibile solamente agli studenti della scuola" - }, - "4": { - "then": "Non accessibile" - } - }, - "question": "Questo parco giochi è pubblicamente accessibile?" - }, - "7": { - "question": "Qual è l’indirizzo email del gestore di questo parco giochi?", - "render": "{email}" - }, - "8": { - "question": "Qual è il numero di telefono del gestore del campetto?", - "render": "{phone}" - }, - "9": { - "mappings": { - "0": { - "then": "Completamente accessibile in sedia a rotelle" - }, - "1": { - "then": "Accesso limitato in sedia a rotelle" - }, - "2": { - "then": "Non accessibile in sedia a rotelle" - } - }, - "question": "Il campetto è accessibile a persone in sedia a rotelle?" - }, - "10": { - "mappings": { - "0": { - "then": "Si può accedere dall'alba al tramonto" - }, - "1": { - "then": "Si può sempre accedere" - }, - "2": { - "then": "Si può sempre accedere" - } - }, - "question": "Quando si può accedere a questo campetto?" } }, "title": { @@ -1160,20 +1160,7 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "Questa microbiblioteca non ha un nome proprio" - } - }, - "question": "Come si chiama questa microbiblioteca pubblica?", - "render": "Questa microbiblioteca si chiama {name}" - }, - "3": { - "question": "Quanti libri può contenere questa microbiblioteca?", - "render": "Questa microbiblioteca può contenere fino a {capacity} libri" - }, - "4": { + "bookcase-booktypes": { "mappings": { "0": { "then": "Principalmente libri per l'infanzia" @@ -1187,7 +1174,18 @@ }, "question": "Che tipo di libri si possono trovare in questa microbiblioteca?" }, - "5": { + "bookcase-is-accessible": { + "mappings": { + "0": { + "then": "È ad accesso libero" + }, + "1": { + "then": "L'accesso è riservato ai clienti" + } + }, + "question": "Questa microbiblioteca è ad accesso libero?" + }, + "bookcase-is-indoors": { "mappings": { "0": { "then": "Questa microbiblioteca si trova al chiuso" @@ -1201,22 +1199,7 @@ }, "question": "Questa microbiblioteca si trova all'aperto?" }, - "6": { - "mappings": { - "0": { - "then": "È ad accesso libero" - }, - "1": { - "then": "L'accesso è riservato ai clienti" - } - }, - "question": "Questa microbiblioteca è ad accesso libero?" - }, - "7": { - "question": "Chi mantiene questa microbiblioteca?", - "render": "È gestita da {operator}" - }, - "8": { + "public_bookcase-brand": { "mappings": { "0": { "then": "Fa parte della rete 'Little Free Library'" @@ -1228,7 +1211,24 @@ "question": "Questa microbiblioteca fa parte di una rete?", "render": "Questa microbiblioteca fa parte di {brand}" }, - "9": { + "public_bookcase-capacity": { + "question": "Quanti libri può contenere questa microbiblioteca?", + "render": "Questa microbiblioteca può contenere fino a {capacity} libri" + }, + "public_bookcase-name": { + "mappings": { + "0": { + "then": "Questa microbiblioteca non ha un nome proprio" + } + }, + "question": "Come si chiama questa microbiblioteca pubblica?", + "render": "Questa microbiblioteca si chiama {name}" + }, + "public_bookcase-operator": { + "question": "Chi mantiene questa microbiblioteca?", + "render": "È gestita da {operator}" + }, + "public_bookcase-ref": { "mappings": { "0": { "then": "Questa microbiblioteca non fa parte di una rete" @@ -1237,11 +1237,11 @@ "question": "Qual è il numero identificativo di questa microbiblioteca?", "render": "Il numero identificativo di questa microbiblioteca nella rete {brand} è {ref}" }, - "10": { + "public_bookcase-start_date": { "question": "Quando è stata inaugurata questa microbiblioteca?", "render": "È stata inaugurata il {start_date}" }, - "11": { + "public_bookcase-website": { "question": "C'è un sito web con maggiori informazioni su questa microbiblioteca?", "render": "Maggiori informazioni sul sito web" } @@ -1257,7 +1257,7 @@ }, "slow_roads": { "tagRenderings": { - "2": { + "slow_roads-surface": { "mappings": { "0": { "then": "La superficie è erba" @@ -1300,7 +1300,55 @@ } }, "tagRenderings": { - "1": { + "sport-pitch-access": { + "mappings": { + "0": { + "then": "Aperto al pubblico" + }, + "1": { + "then": "Accesso limitato (p.es. solo con prenotazione, in certi orari, ...)" + }, + "2": { + "then": "Accesso limitato ai membri dell'associazione" + }, + "3": { + "then": "Privato - non aperto al pubblico" + } + }, + "question": "Questo campo sportivo è aperto al pubblico?" + }, + "sport-pitch-reservation": { + "mappings": { + "0": { + "then": "La prenotazione è obbligatoria per usare questo campo sportivo" + }, + "1": { + "then": "La prenotazione è consigliata per usare questo campo sportivo" + }, + "2": { + "then": "La prenotazione è consentita, ma non è obbligatoria per usare questo campo sportivo" + }, + "3": { + "then": "Non è possibile prenotare" + } + }, + "question": "È necessario prenotarsi per usare questo campo sportivo?" + }, + "sport_pitch-email": { + "question": "Qual è l'indirizzo email del gestore?" + }, + "sport_pitch-opening_hours": { + "mappings": { + "1": { + "then": "Sempre aperto" + } + }, + "question": "Quando è aperto questo campo sportivo?" + }, + "sport_pitch-phone": { + "question": "Qual è il numero di telefono del gestore?" + }, + "sport_pitch-sport": { "mappings": { "0": { "then": "Qui si gioca a basket" @@ -1324,7 +1372,7 @@ "question": "Quale sport si gioca qui?", "render": "Qui si gioca a {sport}" }, - "2": { + "sport_pitch-surface": { "mappings": { "0": { "then": "La superficie è erba" @@ -1344,54 +1392,6 @@ }, "question": "Qual è la superficie di questo campo sportivo?", "render": "La superficie è {surface}" - }, - "3": { - "mappings": { - "0": { - "then": "Aperto al pubblico" - }, - "1": { - "then": "Accesso limitato (p.es. solo con prenotazione, in certi orari, ...)" - }, - "2": { - "then": "Accesso limitato ai membri dell'associazione" - }, - "3": { - "then": "Privato - non aperto al pubblico" - } - }, - "question": "Questo campo sportivo è aperto al pubblico?" - }, - "4": { - "mappings": { - "0": { - "then": "La prenotazione è obbligatoria per usare questo campo sportivo" - }, - "1": { - "then": "La prenotazione è consigliata per usare questo campo sportivo" - }, - "2": { - "then": "La prenotazione è consentita, ma non è obbligatoria per usare questo campo sportivo" - }, - "3": { - "then": "Non è possibile prenotare" - } - }, - "question": "È necessario prenotarsi per usare questo campo sportivo?" - }, - "5": { - "question": "Qual è il numero di telefono del gestore?" - }, - "6": { - "question": "Qual è l'indirizzo email del gestore?" - }, - "7": { - "mappings": { - "1": { - "then": "Sempre aperto" - } - }, - "question": "Quando è aperto questo campo sportivo?" } }, "title": { @@ -1401,7 +1401,7 @@ "surveillance_camera": { "name": "Videocamere di sorveglianza", "tagRenderings": { - "1": { + "Camera type: fixed; panning; dome": { "mappings": { "0": { "then": "Una videocamera fissa (non semovente)" @@ -1415,34 +1415,7 @@ }, "question": "Di che tipo di videocamera si tratta?" }, - "2": { - "mappings": { - "0": { - "then": "Punta in direzione {direction}" - } - }, - "question": "In quale direzione geografica punta questa videocamera?", - "render": "Punta in direzione {camera:direction}" - }, - "3": { - "question": "Chi gestisce questa videocamera a circuito chiuso?", - "render": "È gestita da {operator}" - }, - "4": { - "mappings": { - "0": { - "then": "Sorveglia un'area pubblica, come una strada, un ponte, una piazza, un parco, una stazione, un passaggio o un sottopasso pubblico, ..." - }, - "1": { - "then": "Sorveglia un'area esterna di proprietà privata (un parcheggio, una stazione di servizio, un cortile, un ingresso, un vialetto privato, ...)" - }, - "2": { - "then": "Sorveglia un ambiente interno di proprietà privata, per esempio un negozio, un parcheggio sotterraneo privato, ..." - } - }, - "question": "Che cosa sorveglia questa videocamera" - }, - "5": { + "Indoor camera? This isn't clear for 'public'-cameras": { "mappings": { "0": { "then": "Questa videocamera si trova al chiuso" @@ -1456,11 +1429,29 @@ }, "question": "Lo spazio pubblico sorvegliato da questa videocamera è all'aperto o al chiuso?" }, - "6": { + "Level": { "question": "A che piano si trova questa videocamera?", "render": "Si trova al piano {level}" }, - "7": { + "Operator": { + "question": "Chi gestisce questa videocamera a circuito chiuso?", + "render": "È gestita da {operator}" + }, + "Surveillance type: public, outdoor, indoor": { + "mappings": { + "0": { + "then": "Sorveglia un'area pubblica, come una strada, un ponte, una piazza, un parco, una stazione, un passaggio o un sottopasso pubblico, ..." + }, + "1": { + "then": "Sorveglia un'area esterna di proprietà privata (un parcheggio, una stazione di servizio, un cortile, un ingresso, un vialetto privato, ...)" + }, + "2": { + "then": "Sorveglia un ambiente interno di proprietà privata, per esempio un negozio, un parcheggio sotterraneo privato, ..." + } + }, + "question": "Che cosa sorveglia questa videocamera" + }, + "Surveillance:zone": { "mappings": { "0": { "then": "Sorveglia un parcheggio" @@ -1484,7 +1475,7 @@ "question": "Che cosa è sorvegliato qui?", "render": " Sorveglia una {surveillance:zone}" }, - "8": { + "camera:mount": { "mappings": { "0": { "then": "Questa telecamera è posizionata contro un muro" @@ -1498,6 +1489,15 @@ }, "question": "Com'è posizionata questa telecamera?", "render": "Metodo di montaggio: {mount}" + }, + "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view": { + "mappings": { + "0": { + "then": "Punta in direzione {direction}" + } + }, + "question": "In quale direzione geografica punta questa videocamera?", + "render": "Punta in direzione {camera:direction}" } }, "title": { @@ -1517,7 +1517,7 @@ } }, "tagRenderings": { - "1": { + "toilet-access": { "mappings": { "0": { "then": "Accesso pubblico" @@ -1538,61 +1538,7 @@ "question": "Questi servizi igienici sono aperti al pubblico?", "render": "L'accesso è {access}" }, - "2": { - "mappings": { - "0": { - "then": "Questi servizi igienici sono a pagamento" - }, - "1": { - "then": "Gratis" - } - }, - "question": "Questi servizi igienici sono gratuiti?" - }, - "3": { - "question": "Quanto costa l'accesso a questi servizi igienici?", - "render": "La tariffa è {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "C'è un WC riservato alle persone in sedia a rotelle" - }, - "1": { - "then": "Non accessibile in sedia a rotelle" - } - }, - "question": "C'è un WC riservato alle persone in sedia a rotelle" - }, - "5": { - "mappings": { - "0": { - "then": "Ci sono solo WC con sedile" - }, - "1": { - "then": "Ci sono solo urinali" - }, - "2": { - "then": "Ci sono solo turche" - }, - "3": { - "then": "Ci sono sia sedili, sia urinali" - } - }, - "question": "Di che tipo di servizi igienici si tratta?" - }, - "6": { - "mappings": { - "0": { - "then": "È disponibile un fasciatoio" - }, - "1": { - "then": "Non è disponibile un fasciatoio" - } - }, - "question": "È disponibile un fasciatoio (per cambiare i pannolini)?" - }, - "7": { + "toilet-changing_table:location": { "mappings": { "0": { "then": "Il fasciatoio è nei servizi igienici femminili. " @@ -1609,6 +1555,60 @@ }, "question": "Dove si trova il fasciatoio?", "render": "Il fasciatoio si trova presso {changing_table:location}" + }, + "toilet-charge": { + "question": "Quanto costa l'accesso a questi servizi igienici?", + "render": "La tariffa è {charge}" + }, + "toilets-changing-table": { + "mappings": { + "0": { + "then": "È disponibile un fasciatoio" + }, + "1": { + "then": "Non è disponibile un fasciatoio" + } + }, + "question": "È disponibile un fasciatoio (per cambiare i pannolini)?" + }, + "toilets-fee": { + "mappings": { + "0": { + "then": "Questi servizi igienici sono a pagamento" + }, + "1": { + "then": "Gratis" + } + }, + "question": "Questi servizi igienici sono gratuiti?" + }, + "toilets-type": { + "mappings": { + "0": { + "then": "Ci sono solo WC con sedile" + }, + "1": { + "then": "Ci sono solo urinali" + }, + "2": { + "then": "Ci sono solo turche" + }, + "3": { + "then": "Ci sono sia sedili, sia urinali" + } + }, + "question": "Di che tipo di servizi igienici si tratta?" + }, + "toilets-wheelchair": { + "mappings": { + "0": { + "then": "C'è un WC riservato alle persone in sedia a rotelle" + }, + "1": { + "then": "Non accessibile in sedia a rotelle" + } + }, + "question": "C'è un WC riservato alle persone in sedia a rotelle" } }, "title": { @@ -1632,29 +1632,18 @@ } }, "tagRenderings": { - "1": { + "tree-decidouous": { "mappings": { "0": { - "then": "Altezza: {height} m" - } - }, - "render": "Altezza: {height}" - }, - "2": { - "mappings": { - "0": { - "then": "\"\"/ Latifoglia" + "then": "Caduco: l’albero perde le sue foglie per un periodo dell’anno." }, "1": { - "then": "\"\"/ Aghifoglia" - }, - "2": { - "then": "\"\"/ Privo di foglie (permanente)" + "then": "Sempreverde." } }, - "question": "Si tratta di un albero latifoglia o aghifoglia?" + "question": "È un sempreverde o caduco?" }, - "3": { + "tree-denotation": { "mappings": { "0": { "then": "È un albero notevole per le sue dimensioni o per la posizione prominente. È utile alla navigazione." @@ -1683,27 +1672,15 @@ }, "question": "Quanto significativo è questo albero? Scegli la prima risposta che corrisponde." }, - "4": { + "tree-height": { "mappings": { "0": { - "then": "Caduco: l’albero perde le sue foglie per un periodo dell’anno." - }, - "1": { - "then": "Sempreverde." + "then": "Altezza: {height} m" } }, - "question": "È un sempreverde o caduco?" + "render": "Altezza: {height}" }, - "5": { - "mappings": { - "0": { - "then": "L’albero non ha un nome." - } - }, - "question": "L’albero ha un nome?", - "render": "Nome: {name}" - }, - "6": { + "tree-heritage": { "mappings": { "0": { "then": "\"\"/Registrato come patrimonio da Onroerend Erfgoed Flanders" @@ -1723,11 +1700,34 @@ }, "question": "Quest’albero è registrato come patrimonio?" }, - "7": { + "tree-leaf_type": { + "mappings": { + "0": { + "then": "\"\"/ Latifoglia" + }, + "1": { + "then": "\"\"/ Aghifoglia" + }, + "2": { + "then": "\"\"/ Privo di foglie (permanente)" + } + }, + "question": "Si tratta di un albero latifoglia o aghifoglia?" + }, + "tree_node-name": { + "mappings": { + "0": { + "then": "L’albero non ha un nome." + } + }, + "question": "L’albero ha un nome?", + "render": "Nome: {name}" + }, + "tree_node-ref:OnroerendErfgoed": { "question": "Qual è l’ID rilasciato da Onroerend Erfgoed Flanders?", "render": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}" }, - "8": { + "tree_node-wikidata": { "question": "Qual è l’ID Wikidata per questo albero?", "render": "\"\"/ Wikidata: {wikidata}" } @@ -1750,7 +1750,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Vuoi aggiungere una descrizione?" } }, diff --git a/langs/layers/ja.json b/langs/layers/ja.json index c3276aa50..28607d857 100644 --- a/langs/layers/ja.json +++ b/langs/layers/ja.json @@ -3,12 +3,12 @@ "description": "充電ステーション", "name": "充電ステーション", "tagRenderings": { - "57": { - "question": "この充電ステーションはいつオープンしますか?" - }, - "58": { + "Auth phone": { "question": "この充電ステーションの運営チェーンはどこですか?", "render": "{network}" + }, + "Authentication": { + "question": "この充電ステーションはいつオープンしますか?" } }, "title": { @@ -17,7 +17,7 @@ }, "food": { "tagRenderings": { - "17": { + "friture-take-your-container": { "mappings": { "0": { "then": "自分の容器を持ってきて、注文を受け取ることができ、使い捨ての梱包材を節約して、無駄を省くことができます" diff --git a/langs/layers/nb_NO.json b/langs/layers/nb_NO.json index d3cfb1b18..e22f10944 100644 --- a/langs/layers/nb_NO.json +++ b/langs/layers/nb_NO.json @@ -8,7 +8,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Rygglene: Ja" @@ -20,34 +20,7 @@ "question": "Har denne beken et rygglene?", "render": "Rygglene" }, - "2": { - "question": "Hvor mange sitteplasser har denne benken?", - "render": "{seats} seter" - }, - "3": { - "mappings": { - "0": { - "then": "Materiale: tre" - }, - "1": { - "then": "Materiale: metall" - }, - "2": { - "then": "Materiale: stein" - }, - "3": { - "then": "Materiale: betong" - }, - "4": { - "then": "Materiale: plastikk" - }, - "5": { - "then": "Materiale: stål" - } - }, - "render": "Materiale: {material}" - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Farge: brun" @@ -75,6 +48,33 @@ } }, "render": "Farge: {colour}" + }, + "bench-material": { + "mappings": { + "0": { + "then": "Materiale: tre" + }, + "1": { + "then": "Materiale: metall" + }, + "2": { + "then": "Materiale: stein" + }, + "3": { + "then": "Materiale: betong" + }, + "4": { + "then": "Materiale: plastikk" + }, + "5": { + "then": "Materiale: stål" + } + }, + "render": "Materiale: {material}" + }, + "bench-seats": { + "question": "Hvor mange sitteplasser har denne benken?", + "render": "{seats} seter" } }, "title": { @@ -89,11 +89,7 @@ }, "bicycle_library": { "tagRenderings": { - "1": { - "question": "Hva heter dette sykkelbiblioteket?", - "render": "Dette sykkelbiblioteket heter {name}" - }, - "6": { + "bicycle_library-charge": { "mappings": { "0": { "then": "Det er gratis å leie en sykkel" @@ -101,6 +97,10 @@ }, "question": "Hvor mye koster det å leie en sykkel?", "render": "Sykkelleie koster {charge}" + }, + "bicycle_library-name": { + "question": "Hva heter dette sykkelbiblioteket?", + "render": "Dette sykkelbiblioteket heter {name}" } } }, @@ -108,11 +108,11 @@ "description": "En ladestasjon", "name": "Ladestasjoner", "tagRenderings": { - "57": { - "question": "Når åpnet denne ladestasjonen?" - }, - "58": { + "Auth phone": { "render": "{network}" + }, + "Authentication": { + "question": "Når åpnet denne ladestasjonen?" } }, "title": { diff --git a/langs/layers/nl.json b/langs/layers/nl.json index e7c5886e9..e98497ecb 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -13,18 +13,7 @@ } }, "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "Een fietser kan hier langs." - }, - "1": { - "then": "Een fietser kan hier niet langs." - } - }, - "question": "Kan een fietser langs deze barrière?" - }, - "1": { + "Bollard type": { "mappings": { "0": { "then": "Verwijderbare paal" @@ -44,7 +33,7 @@ }, "question": "Wat voor soort paal is dit?" }, - "2": { + "Cycle barrier type": { "mappings": { "0": { "then": "Enkelvoudig, slechts twee hekjes met ruimte ertussen " @@ -61,20 +50,31 @@ }, "question": "Wat voor fietshekjes zijn dit?" }, - "3": { + "MaxWidth": { "question": "Hoe breed is de ruimte naast de barrière?", "render": "Maximumbreedte: {maxwidth:physical} m" }, - "4": { + "Overlap (cyclebarrier)": { + "question": "Hoeveel overlappen de barrières?" + }, + "Space between barrier (cyclebarrier)": { "question": "Hoeveel ruimte is er tussen de barrières (langs de lengte van de weg)?", "render": "Ruimte tussen barrières (langs de lengte van de weg): {width:separation} m" }, - "5": { + "Width of opening (cyclebarrier)": { "question": "Hoe breed is de smalste opening naast de barrières?", "render": "Breedte van de opening: {width:opening} m" }, - "6": { - "question": "Hoeveel overlappen de barrières?" + "bicycle=yes/no": { + "mappings": { + "0": { + "then": "Een fietser kan hier langs." + }, + "1": { + "then": "Een fietser kan hier niet langs." + } + }, + "question": "Kan een fietser langs deze barrière?" } }, "title": { @@ -98,7 +98,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Heeft een rugleuning" @@ -110,39 +110,7 @@ "question": "Heeft deze zitbank een rugleuning?", "render": "Rugleuning" }, - "2": { - "question": "Hoeveel zitplaatsen heeft deze bank?", - "render": "{seats} zitplaatsen" - }, - "3": { - "mappings": { - "0": { - "then": "Gemaakt uit hout" - }, - "1": { - "then": "Gemaakt uit metaal" - }, - "2": { - "then": "Gemaakt uit steen" - }, - "3": { - "then": "Gemaakt uit beton" - }, - "4": { - "then": "Gemaakt uit plastiek" - }, - "5": { - "then": "Gemaakt uit staal" - } - }, - "question": "Uit welk materiaal is het zitgedeelte van deze zitbank gemaakt?", - "render": "Gemaakt van {material}" - }, - "4": { - "question": "In welke richting kijk je wanneer je op deze zitbank zit?", - "render": "Wanneer je op deze bank zit, dan kijk je in {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "De kleur is bruin" @@ -172,7 +140,39 @@ "question": "Welke kleur heeft deze zitbank?", "render": "Kleur: {colour}" }, - "6": { + "bench-direction": { + "question": "In welke richting kijk je wanneer je op deze zitbank zit?", + "render": "Wanneer je op deze bank zit, dan kijk je in {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Gemaakt uit hout" + }, + "1": { + "then": "Gemaakt uit metaal" + }, + "2": { + "then": "Gemaakt uit steen" + }, + "3": { + "then": "Gemaakt uit beton" + }, + "4": { + "then": "Gemaakt uit plastiek" + }, + "5": { + "then": "Gemaakt uit staal" + } + }, + "question": "Uit welk materiaal is het zitgedeelte van deze zitbank gemaakt?", + "render": "Gemaakt van {material}" + }, + "bench-seats": { + "question": "Hoeveel zitplaatsen heeft deze bank?", + "render": "{seats} zitplaatsen" + }, + "bench-survey:date": { "question": "Wanneer is deze laatste bank laatst gesurveyed?", "render": "Deze bank is laatst gesurveyd op {survey:date}" } @@ -184,11 +184,11 @@ "bench_at_pt": { "name": "Zitbanken aan bushaltes", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "Leunbank" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -213,23 +213,7 @@ } }, "tagRenderings": { - "1": { - "question": "Wat is de naam van deze fietsbieb?", - "render": "Deze fietsbieb heet {name}" - }, - "6": { - "mappings": { - "0": { - "then": "Een fiets huren is gratis" - }, - "1": { - "then": "Een fiets huren kost €20/jaar en €20 waarborg" - } - }, - "question": "Hoeveel kost het huren van een fiets?", - "render": "Een fiets huren kost {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Aanbod voor kinderen" @@ -242,6 +226,22 @@ } }, "question": "Voor wie worden hier fietsen aangeboden?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "Een fiets huren is gratis" + }, + "1": { + "then": "Een fiets huren kost €20/jaar en €20 waarborg" + } + }, + "question": "Hoeveel kost het huren van een fiets?", + "render": "Een fiets huren kost {charge}" + }, + "bicycle_library-name": { + "question": "Wat is de naam van deze fietsbieb?", + "render": "Deze fietsbieb heet {name}" } }, "title": { @@ -256,7 +256,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Deze verkoopsautomaat werkt" @@ -284,11 +284,7 @@ } }, "tagRenderings": { - "1": { - "question": "Wat is de naam van dit fietscafé?", - "render": "Dit fietscafé heet {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "Dit fietscafé biedt een fietspomp aan voor eender wie" @@ -299,18 +295,20 @@ }, "question": "Biedt dit fietscafé een fietspomp aan voor iedereen?" }, - "3": { - "mappings": { - "0": { - "then": "Dit fietscafé biedt gereedschap aan om je fiets zelf te herstellen" - }, - "1": { - "then": "Dit fietscafé biedt geen gereedschap aan om je fiets zelf te herstellen" - } - }, - "question": "Biedt dit fietscafé gereedschap aan om je fiets zelf te herstellen?" + "bike_cafe-email": { + "question": "Wat is het email-adres van {name}?" }, - "4": { + "bike_cafe-name": { + "question": "Wat is de naam van dit fietscafé?", + "render": "Dit fietscafé heet {name}" + }, + "bike_cafe-opening_hours": { + "question": "Wanneer is dit fietscafé geopend?" + }, + "bike_cafe-phone": { + "question": "Wat is het telefoonnummer van {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "Dit fietscafé herstelt fietsen" @@ -321,17 +319,19 @@ }, "question": "Herstelt dit fietscafé fietsen?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "Dit fietscafé biedt gereedschap aan om je fiets zelf te herstellen" + }, + "1": { + "then": "Dit fietscafé biedt geen gereedschap aan om je fiets zelf te herstellen" + } + }, + "question": "Biedt dit fietscafé gereedschap aan om je fiets zelf te herstellen?" + }, + "bike_cafe-website": { "question": "Wat is de website van {name}?" - }, - "6": { - "question": "Wat is het telefoonnummer van {name}?" - }, - "7": { - "question": "Wat is het email-adres van {name}?" - }, - "8": { - "question": "Wanneer is dit fietscafé geopend?" } }, "title": { @@ -367,7 +367,22 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "Publiek toegankelijke fietsenstalling" + }, + "1": { + "then": "Klanten van de zaak of winkel" + }, + "2": { + "then": "Private fietsenstalling van een school, een bedrijf, ..." + } + }, + "question": "Wie mag er deze fietsenstalling gebruiken?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "0": { "then": "Nietjes " @@ -397,7 +412,40 @@ "question": "Van welk type is deze fietsparking?", "render": "Dit is een fietsparking van het type: {bicycle_parking}" }, - "2": { + "Capacity": { + "question": "Hoeveel fietsen kunnen in deze fietsparking (inclusief potentiëel bakfietsen)?", + "render": "Plaats voor {capacity} fietsen" + }, + "Cargo bike capacity?": { + "question": "Voor hoeveel bakfietsen heeft deze fietsparking plaats?", + "render": "Deze parking heeft plaats voor {capacity:cargo_bike} fietsen" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "Deze parking heeft plaats voor bakfietsen" + }, + "1": { + "then": "Er zijn speciale plaatsen voorzien voor bakfietsen" + }, + "2": { + "then": "Je mag hier geen bakfietsen parkeren" + } + }, + "question": "Heeft deze fietsparking plaats voor bakfietsen?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "Deze parking is overdekt (er is een afdak)" + }, + "1": { + "then": "Deze parking is niet overdekt" + } + }, + "question": "Is deze parking overdekt? Selecteer ook \"overdekt\" voor fietsparkings binnen een gebouw." + }, + "Underground?": { "mappings": { "0": { "then": "Ondergrondse parking" @@ -416,54 +464,6 @@ } }, "question": "Wat is de relatieve locatie van deze parking??" - }, - "3": { - "mappings": { - "0": { - "then": "Deze parking is overdekt (er is een afdak)" - }, - "1": { - "then": "Deze parking is niet overdekt" - } - }, - "question": "Is deze parking overdekt? Selecteer ook \"overdekt\" voor fietsparkings binnen een gebouw." - }, - "4": { - "question": "Hoeveel fietsen kunnen in deze fietsparking (inclusief potentiëel bakfietsen)?", - "render": "Plaats voor {capacity} fietsen" - }, - "5": { - "mappings": { - "0": { - "then": "Publiek toegankelijke fietsenstalling" - }, - "1": { - "then": "Klanten van de zaak of winkel" - }, - "2": { - "then": "Private fietsenstalling van een school, een bedrijf, ..." - } - }, - "question": "Wie mag er deze fietsenstalling gebruiken?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "Deze parking heeft plaats voor bakfietsen" - }, - "1": { - "then": "Er zijn speciale plaatsen voorzien voor bakfietsen" - }, - "2": { - "then": "Je mag hier geen bakfietsen parkeren" - } - }, - "question": "Heeft deze fietsparking plaats voor bakfietsen?" - }, - "7": { - "question": "Voor hoeveel bakfietsen heeft deze fietsparking plaats?", - "render": "Deze parking heeft plaats voor {capacity:cargo_bike} fietsen" } }, "title": { @@ -486,7 +486,21 @@ } }, "tagRenderings": { - "1": { + "Email maintainer": { + "render": "Rapporteer deze fietspomp als kapot" + }, + "Operational status": { + "mappings": { + "0": { + "then": "De fietspomp is kapot" + }, + "1": { + "then": "De fietspomp werkt nog" + } + }, + "question": "Werkt de fietspomp nog?" + }, + "bike_repair_station-available-services": { "mappings": { "0": { "then": "Er is enkel een pomp aanwezig" @@ -500,28 +514,7 @@ }, "question": "Welke functies biedt dit fietspunt?" }, - "2": { - "question": "Wie beheert deze fietspomp?", - "render": "Beheer door {operator}" - }, - "3": { - "question": "Wat is het email-adres van de beheerder?" - }, - "4": { - "question": "Wat is het telefoonnummer van de beheerder?" - }, - "5": { - "mappings": { - "0": { - "then": "Dag en nacht open" - }, - "1": { - "then": "Dag en nacht open" - } - }, - "question": "Wanneer is dit fietsherstelpunt open?" - }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "Er is een reparatieset voor je ketting" @@ -532,7 +525,7 @@ }, "question": "Heeft dit herstelpunt een speciale reparatieset voor je ketting?" }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "Er is een haak of standaard" @@ -543,21 +536,53 @@ }, "question": "Heeft dit herstelpunt een haak of standaard om je fiets op te hangen/zetten?" }, - "8": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { - "then": "De fietspomp is kapot" + "then": "Manuele pomp" }, "1": { - "then": "De fietspomp werkt nog" + "then": "Electrische pomp" } }, - "question": "Werkt de fietspomp nog?" + "question": "Is dit een electrische fietspomp?" }, - "9": { - "render": "Rapporteer deze fietspomp als kapot" + "bike_repair_station-email": { + "question": "Wat is het email-adres van de beheerder?" }, - "10": { + "bike_repair_station-manometer": { + "mappings": { + "0": { + "then": "Er is een luchtdrukmeter" + }, + "1": { + "then": "Er is geen luchtdrukmeter" + }, + "2": { + "then": "Er is een luchtdrukmeter maar die is momenteel defect" + } + }, + "question": "Heeft deze pomp een luchtdrukmeter?" + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Dag en nacht open" + }, + "1": { + "then": "Dag en nacht open" + } + }, + "question": "Wanneer is dit fietsherstelpunt open?" + }, + "bike_repair_station-operator": { + "question": "Wie beheert deze fietspomp?", + "render": "Beheer door {operator}" + }, + "bike_repair_station-phone": { + "question": "Wat is het telefoonnummer van de beheerder?" + }, + "bike_repair_station-valves": { "mappings": { "0": { "then": "Sclaverand (ook gekend als Presta)" @@ -571,31 +596,6 @@ }, "question": "Welke ventielen werken er met de pomp?", "render": "Deze pomp werkt met de volgende ventielen: {valves}" - }, - "11": { - "mappings": { - "0": { - "then": "Manuele pomp" - }, - "1": { - "then": "Electrische pomp" - } - }, - "question": "Is dit een electrische fietspomp?" - }, - "12": { - "mappings": { - "0": { - "then": "Er is een luchtdrukmeter" - }, - "1": { - "then": "Er is geen luchtdrukmeter" - }, - "2": { - "then": "Er is een luchtdrukmeter maar die is momenteel defect" - } - }, - "question": "Heeft deze pomp een luchtdrukmeter?" } }, "title": { @@ -628,34 +628,46 @@ } }, "tagRenderings": { - "1": { - "render": "Deze winkel verkoopt {shop} en heeft fiets-gerelateerde activiteiten." - }, - "2": { - "question": "Wat is de naam van deze fietszaak?", - "render": "Deze fietszaak heet {name}" - }, - "3": { - "question": "Wat is de website van {name}?" - }, - "4": { - "question": "Wat is het telefoonnummer van {name}?" - }, - "5": { - "question": "Wat is het email-adres van {name}?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "Deze winkel verkoopt fietsen" + "then": "Deze winkel biedt een fietspomp aan voor iedereen" }, "1": { - "then": "Deze winkel verkoopt geen fietsen" + "then": "Deze winkel biedt geen fietspomp aan voor eender wie" + }, + "2": { + "then": "Er is een fietspomp, deze is apart aangeduid" } }, - "question": "Verkoopt deze fietszaak fietsen?" + "question": "Biedt deze winkel een fietspomp aan voor iedereen?" }, - "10": { + "bike_repair_bike-wash": { + "mappings": { + "0": { + "then": "Deze winkel biedt fietsschoonmaak aan" + }, + "1": { + "then": "Deze winkel biedt een installatie aan om zelf je fiets schoon te maken" + }, + "2": { + "then": "Deze winkel biedt geen fietsschoonmaak aan" + } + }, + "question": "Biedt deze winkel een fietsschoonmaak aan?" + }, + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "Deze winkel verhuurt fietsen" + }, + "1": { + "then": "Deze winkel verhuurt geen fietsen" + } + }, + "question": "Verhuurt deze winkel fietsen?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Deze winkel herstelt fietsen" @@ -672,18 +684,7 @@ }, "question": "Herstelt deze winkel fietsen?" }, - "11": { - "mappings": { - "0": { - "then": "Deze winkel verhuurt fietsen" - }, - "1": { - "then": "Deze winkel verhuurt geen fietsen" - } - }, - "question": "Verhuurt deze winkel fietsen?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "Deze winkel verkoopt tweedehands fietsen" @@ -697,21 +698,18 @@ }, "question": "Verkoopt deze winkel tweedehands fietsen?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "Deze winkel biedt een fietspomp aan voor iedereen" + "then": "Deze winkel verkoopt fietsen" }, "1": { - "then": "Deze winkel biedt geen fietspomp aan voor eender wie" - }, - "2": { - "then": "Er is een fietspomp, deze is apart aangeduid" + "then": "Deze winkel verkoopt geen fietsen" } }, - "question": "Biedt deze winkel een fietspomp aan voor iedereen?" + "question": "Verkoopt deze fietszaak fietsen?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "0": { "then": "Deze winkel biedt gereedschap aan om je fiets zelf te herstellen" @@ -725,19 +723,21 @@ }, "question": "Biedt deze winkel gereedschap aan om je fiets zelf te herstellen?" }, - "15": { - "mappings": { - "0": { - "then": "Deze winkel biedt fietsschoonmaak aan" - }, - "1": { - "then": "Deze winkel biedt een installatie aan om zelf je fiets schoon te maken" - }, - "2": { - "then": "Deze winkel biedt geen fietsschoonmaak aan" - } - }, - "question": "Biedt deze winkel een fietsschoonmaak aan?" + "bike_shop-email": { + "question": "Wat is het email-adres van {name}?" + }, + "bike_shop-is-bicycle_shop": { + "render": "Deze winkel verkoopt {shop} en heeft fiets-gerelateerde activiteiten." + }, + "bike_shop-name": { + "question": "Wat is de naam van deze fietszaak?", + "render": "Deze fietszaak heet {name}" + }, + "bike_shop-phone": { + "question": "Wat is het telefoonnummer van {name}?" + }, + "bike_shop-website": { + "question": "Wat is de website van {name}?" } }, "title": { @@ -782,7 +782,7 @@ } }, "tagRenderings": { - "1": { + "binocular-charge": { "mappings": { "0": { "then": "Gratis te gebruiken" @@ -791,7 +791,7 @@ "question": "Hoeveel moet men betalen om deze verrekijker te gebruiken?", "render": "Deze verrekijker gebruiken kost {charge}" }, - "2": { + "binocular-direction": { "question": "Welke richting kijkt men uit als men door deze verrekijker kijkt?", "render": "Kijkt richting {direction}°" } @@ -842,7 +842,7 @@ "render": "3" }, "tagRenderings": { - "1": { + "bird-hide-shelter-or-wall": { "mappings": { "0": { "then": "Vogelkijkwand" @@ -859,7 +859,7 @@ }, "question": "Is dit een kijkwand of kijkhut?" }, - "2": { + "bird-hide-wheelchair": { "mappings": { "0": { "then": "Er zijn speciale voorzieningen voor rolstoelen" @@ -876,7 +876,7 @@ }, "question": "Is deze vogelkijkplaats rolstoeltoegankelijk?" }, - "3": { + "birdhide-operator": { "mappings": { "0": { "then": "Beheer door Natuurpunt" @@ -930,11 +930,7 @@ } }, "tagRenderings": { - "1": { - "question": "Wat is de naam van dit café?", - "render": "De naam van dit café is {name}" - }, - "2": { + "Classification": { "mappings": { "0": { "then": "Dit is een bruin café of een kroeg waar voornamelijk bier wordt gedronken. De inrichting is typisch gezellig met veel houtwerk " @@ -953,6 +949,10 @@ } }, "question": "Welk soort café is dit?" + }, + "Name": { + "question": "Wat is de naam van dit café?", + "render": "De naam van dit café is {name}" } }, "title": { @@ -1027,11 +1027,7 @@ } }, "tagRenderings": { - "3": { - "question": "Hoeveel voertuigen kunnen hier opgeladen worden?", - "render": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" - }, - "4": { + "Available_charging_stations (generated)": { "mappings": { "0": { "then": " Schuko stekker zonder aardingspin (CEE7/4 type F)" @@ -1113,535 +1109,7 @@ } } }, - "5": { - "question": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?", - "render": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" - }, - "6": { - "mappings": { - "0": { - "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" - } - }, - "question": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ", - "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" - }, - "7": { - "mappings": { - "0": { - "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" - } - }, - "question": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", - "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" - }, - "8": { - "mappings": { - "0": { - "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", - "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" - }, - "9": { - "question": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?", - "render": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" - }, - "10": { - "mappings": { - "0": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" - } - }, - "question": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ", - "render": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" - }, - "11": { - "mappings": { - "0": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" - } - }, - "question": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", - "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" - }, - "12": { - "mappings": { - "0": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" - }, - "1": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", - "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" - }, - "13": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "14": { - "mappings": { - "0": { - "then": " heeft een spanning van 500 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:chademo:voltage} volt" - }, - "15": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 120 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:chademo:current}A" - }, - "16": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:chademo:output}" - }, - "17": { - "question": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?", - "render": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" - }, - "18": { - "mappings": { - "0": { - "then": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" - }, - "1": { - "then": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" - } - }, - "question": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) ", - "render": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" - }, - "19": { - "mappings": { - "0": { - "then": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?", - "render": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" - }, - "20": { - "mappings": { - "0": { - "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" - }, - "1": { - "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?", - "render": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" - }, - "21": { - "question": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?", - "render": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" - }, - "22": { - "mappings": { - "0": { - "then": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" - }, - "1": { - "then": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" - } - }, - "question": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) ", - "render": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" - }, - "23": { - "mappings": { - "0": { - "then": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?", - "render": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" - }, - "24": { - "mappings": { - "0": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" - }, - "1": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" - }, - "2": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" - }, - "3": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?", - "render": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" - }, - "25": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "26": { - "mappings": { - "0": { - "then": " heeft een spanning van 400 volt" - }, - "1": { - "then": " heeft een spanning van 1000 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:type1_combo:voltage} volt" - }, - "27": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 50 A" - }, - "1": { - "then": " levert een stroom van maximaal 125 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:type1_combo:current}A" - }, - "28": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 62.5 kw" - }, - "2": { - "then": " levert een vermogen van maximaal 150 kw" - }, - "3": { - "then": " levert een vermogen van maximaal 350 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:type1_combo:output}" - }, - "29": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "30": { - "mappings": { - "0": { - "then": " heeft een spanning van 480 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" - }, - "31": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" - }, - "32": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 120 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 150 kw" - }, - "2": { - "then": " levert een vermogen van maximaal 250 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" - }, - "33": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "34": { - "mappings": { - "0": { - "then": " heeft een spanning van 230 volt" - }, - "1": { - "then": " heeft een spanning van 400 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:type2:voltage} volt" - }, - "35": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 16 A" - }, - "1": { - "then": " levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:type2:current}A" - }, - "36": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 11 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:type2:output}" - }, - "37": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "38": { - "mappings": { - "0": { - "then": " heeft een spanning van 500 volt" - }, - "1": { - "then": " heeft een spanning van 920 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:type2_combo:voltage} volt" - }, - "39": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:type2_combo:current}A" - }, - "40": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:type2_combo:output}" - }, - "41": { - "question": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?", - "render": "Hier zijn Type 2 met kabel (J1772) stekkers van het type Type 2 met kabel (J1772)" - }, - "42": { - "mappings": { - "0": { - "then": "Type 2 met kabel (J1772) heeft een spanning van 230 volt" - }, - "1": { - "then": "Type 2 met kabel (J1772) heeft een spanning van 400 volt" - } - }, - "question": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) ", - "render": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt" - }, - "43": { - "mappings": { - "0": { - "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 16 A" - }, - "1": { - "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?", - "render": "Type 2 met kabel (J1772) levert een stroom van maximaal {socket:type2_cable:current}A" - }, - "44": { - "mappings": { - "0": { - "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 11 kw" - }, - "1": { - "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?", - "render": "Type 2 met kabel (J1772) levert een vermogen van maximaal {socket:type2_cable:output}" - }, - "45": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "46": { - "mappings": { - "0": { - "then": " heeft een spanning van 500 volt" - }, - "1": { - "then": " heeft een spanning van 920 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" - }, - "47": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" - }, - "48": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" - }, - "49": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "50": { - "mappings": { - "0": { - "then": " heeft een spanning van 480 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" - }, - "51": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" - }, - "52": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 120 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 150 kw" - }, - "2": { - "then": " levert een vermogen van maximaal 250 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" - }, - "53": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "54": { - "mappings": { - "0": { - "then": " heeft een spanning van 230 volt" - }, - "1": { - "then": " heeft een spanning van 400 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" - }, - "55": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 16 A" - }, - "1": { - "then": " levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" - }, - "56": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 11 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" - }, - "60": { - "mappings": { - "0": { - "then": "Gratis te gebruiken" - } - }, - "question": "Hoeveel kost het gebruik van dit oplaadpunt?", - "render": "Dit oplaadpunt gebruiken kost {charge}" - }, - "61": { - "override": { - "mappings": { - "0": { - "then": "Betalen via een app van het netwerk" - } - }, - "mappings+": { - "0": { - "then": "Betalen via een app van het netwerk" - } - } - } - }, - "62": { - "mappings": { - "0": { - "then": "Geen maximum parkeertijd" - } - }, - "question": "Hoelang mag een voertuig hier blijven staan?", - "render": "De maximale parkeertijd hier is {canonical(maxstay)}" - }, - "70": { + "Operational status": { "mappings": { "0": { "then": "Dit oplaadpunt is kapot" @@ -1660,6 +1128,538 @@ } }, "question": "Is dit oplaadpunt operationeel?" + }, + "capacity": { + "question": "Hoeveel voertuigen kunnen hier opgeladen worden?", + "render": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" + }, + "current-0": { + "mappings": { + "0": { + "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" + } + }, + "question": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", + "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" + }, + "current-1": { + "mappings": { + "0": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" + } + }, + "question": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", + "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" + }, + "current-10": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" + }, + "current-11": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "current-12": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 16 A" + }, + "1": { + "then": " levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "current-2": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 120 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:chademo:current}A" + }, + "current-3": { + "mappings": { + "0": { + "then": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?", + "render": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" + }, + "current-4": { + "mappings": { + "0": { + "then": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?", + "render": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" + }, + "current-5": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 50 A" + }, + "1": { + "then": " levert een stroom van maximaal 125 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:type1_combo:current}A" + }, + "current-6": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" + }, + "current-7": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 16 A" + }, + "1": { + "then": " levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:type2:current}A" + }, + "current-8": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:type2_combo:current}A" + }, + "current-9": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 16 A" + }, + "1": { + "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?", + "render": "Type 2 met kabel (J1772) levert een stroom van maximaal {socket:type2_cable:current}A" + }, + "fee/charge": { + "mappings": { + "0": { + "then": "Gratis te gebruiken" + } + }, + "question": "Hoeveel kost het gebruik van dit oplaadpunt?", + "render": "Dit oplaadpunt gebruiken kost {charge}" + }, + "maxstay": { + "mappings": { + "0": { + "then": "Geen maximum parkeertijd" + } + }, + "question": "Hoelang mag een voertuig hier blijven staan?", + "render": "De maximale parkeertijd hier is {canonical(maxstay)}" + }, + "payment-options": { + "override": { + "mappings": { + "0": { + "then": "Betalen via een app van het netwerk" + } + }, + "mappings+": { + "0": { + "then": "Betalen via een app van het netwerk" + } + } + } + }, + "plugs-0": { + "question": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?", + "render": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" + }, + "plugs-1": { + "question": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?", + "render": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" + }, + "plugs-10": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-11": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-12": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-2": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-3": { + "question": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?", + "render": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" + }, + "plugs-4": { + "question": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?", + "render": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" + }, + "plugs-5": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-6": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-7": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-8": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-9": { + "question": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?", + "render": "Hier zijn Type 2 met kabel (J1772) stekkers van het type Type 2 met kabel (J1772)" + }, + "power-output-0": { + "mappings": { + "0": { + "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", + "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" + }, + "power-output-1": { + "mappings": { + "0": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" + }, + "1": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", + "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" + }, + "power-output-10": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" + }, + "power-output-11": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 120 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 150 kw" + }, + "2": { + "then": " levert een vermogen van maximaal 250 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "power-output-12": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "power-output-2": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:chademo:output}" + }, + "power-output-3": { + "mappings": { + "0": { + "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" + }, + "1": { + "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?", + "render": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" + }, + "power-output-4": { + "mappings": { + "0": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" + }, + "1": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" + }, + "2": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" + }, + "3": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?", + "render": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" + }, + "power-output-5": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 62.5 kw" + }, + "2": { + "then": " levert een vermogen van maximaal 150 kw" + }, + "3": { + "then": " levert een vermogen van maximaal 350 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:type1_combo:output}" + }, + "power-output-6": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 120 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 150 kw" + }, + "2": { + "then": " levert een vermogen van maximaal 250 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" + }, + "power-output-7": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:type2:output}" + }, + "power-output-8": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:type2_combo:output}" + }, + "power-output-9": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?", + "render": "Type 2 met kabel (J1772) levert een vermogen van maximaal {socket:type2_cable:output}" + }, + "voltage-0": { + "mappings": { + "0": { + "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" + } + }, + "question": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ", + "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" + }, + "voltage-1": { + "mappings": { + "0": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" + } + }, + "question": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ", + "render": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" + }, + "voltage-10": { + "mappings": { + "0": { + "then": " heeft een spanning van 500 volt" + }, + "1": { + "then": " heeft een spanning van 920 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" + }, + "voltage-11": { + "mappings": { + "0": { + "then": " heeft een spanning van 480 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "voltage-12": { + "mappings": { + "0": { + "then": " heeft een spanning van 230 volt" + }, + "1": { + "then": " heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "voltage-2": { + "mappings": { + "0": { + "then": " heeft een spanning van 500 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:chademo:voltage} volt" + }, + "voltage-3": { + "mappings": { + "0": { + "then": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" + }, + "1": { + "then": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" + } + }, + "question": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) ", + "render": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" + }, + "voltage-4": { + "mappings": { + "0": { + "then": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" + }, + "1": { + "then": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" + } + }, + "question": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) ", + "render": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" + }, + "voltage-5": { + "mappings": { + "0": { + "then": " heeft een spanning van 400 volt" + }, + "1": { + "then": " heeft een spanning van 1000 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:type1_combo:voltage} volt" + }, + "voltage-6": { + "mappings": { + "0": { + "then": " heeft een spanning van 480 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" + }, + "voltage-7": { + "mappings": { + "0": { + "then": " heeft een spanning van 230 volt" + }, + "1": { + "then": " heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:type2:voltage} volt" + }, + "voltage-8": { + "mappings": { + "0": { + "then": " heeft een spanning van 500 volt" + }, + "1": { + "then": " heeft een spanning van 920 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:type2_combo:voltage} volt" + }, + "voltage-9": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) heeft een spanning van 230 volt" + }, + "1": { + "then": "Type 2 met kabel (J1772) heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) ", + "render": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt" } }, "units": { @@ -1719,32 +1719,7 @@ } }, "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "Oversteekplaats, zonder verkeerslichten" - }, - "1": { - "then": "Oversteekplaats met verkeerslichten" - }, - "2": { - "then": "Zebrapad" - } - }, - "question": "Wat voor oversteekplaats is dit?" - }, - "1": { - "mappings": { - "0": { - "then": "Dit is een zebrapad" - }, - "1": { - "then": "Dit is geen zebrapad" - } - }, - "question": "Is dit een zebrapad?" - }, - "2": { + "crossing-bicycle-allowed": { "mappings": { "0": { "then": "Een fietser kan deze oversteekplaats gebruiken" @@ -1755,32 +1730,7 @@ }, "question": "Is deze oversteekplaats ook voor fietsers" }, - "3": { - "mappings": { - "0": { - "then": "Deze oversteekplaats heeft een verkeerseiland in het midden" - }, - "1": { - "then": "Deze oversteekplaats heeft geen verkeerseiland in het midden" - } - }, - "question": "Heeft deze oversteekplaats een verkeerseiland in het midden?" - }, - "4": { - "mappings": { - "0": { - "then": "Deze oversteekplaats heeft een geleidelijn" - }, - "1": { - "then": "Deze oversteekplaats heeft geen geleidelijn" - }, - "2": { - "then": "Deze oversteekplaats heeft een geleidelijn, die incorrect is." - } - }, - "question": "Heeft deze oversteekplaats een geleidelijn?" - }, - "5": { + "crossing-button": { "mappings": { "0": { "then": "Dit verkeerslicht heeft een knop voor groen licht" @@ -1791,7 +1741,43 @@ }, "question": "Heeft dit verkeerslicht een knop voor groen licht?" }, - "6": { + "crossing-continue-through-red": { + "mappings": { + "0": { + "then": "Een fietser mag wel rechtdoor gaan als het licht rood is " + }, + "1": { + "then": "Een fietser mag wel rechtdoor gaan als het licht rood is" + }, + "2": { + "then": "Een fietser mag niet rechtdoor gaan als het licht rood is" + } + }, + "question": "Mag een fietser rechtdoor gaan als het licht rood is?" + }, + "crossing-has-island": { + "mappings": { + "0": { + "then": "Deze oversteekplaats heeft een verkeerseiland in het midden" + }, + "1": { + "then": "Deze oversteekplaats heeft geen verkeerseiland in het midden" + } + }, + "question": "Heeft deze oversteekplaats een verkeerseiland in het midden?" + }, + "crossing-is-zebra": { + "mappings": { + "0": { + "then": "Dit is een zebrapad" + }, + "1": { + "then": "Dit is geen zebrapad" + } + }, + "question": "Is dit een zebrapad?" + }, + "crossing-right-turn-through-red": { "mappings": { "0": { "then": "Een fietser mag wel rechtsaf slaan als het licht rood is " @@ -1805,19 +1791,33 @@ }, "question": "Mag een fietser rechtsaf slaan als het licht rood is?" }, - "7": { + "crossing-tactile": { "mappings": { "0": { - "then": "Een fietser mag wel rechtdoor gaan als het licht rood is " + "then": "Deze oversteekplaats heeft een geleidelijn" }, "1": { - "then": "Een fietser mag wel rechtdoor gaan als het licht rood is" + "then": "Deze oversteekplaats heeft geen geleidelijn" }, "2": { - "then": "Een fietser mag niet rechtdoor gaan als het licht rood is" + "then": "Deze oversteekplaats heeft een geleidelijn, die incorrect is." } }, - "question": "Mag een fietser rechtdoor gaan als het licht rood is?" + "question": "Heeft deze oversteekplaats een geleidelijn?" + }, + "crossing-type": { + "mappings": { + "0": { + "then": "Oversteekplaats, zonder verkeerslichten" + }, + "1": { + "then": "Oversteekplaats met verkeerslichten" + }, + "2": { + "then": "Zebrapad" + } + }, + "question": "Wat voor oversteekplaats is dit?" } }, "title": { @@ -1835,7 +1835,7 @@ "cycleways_and_roads": { "name": "Fietspaden, straten en wegen", "tagRenderings": { - "0": { + "Cycleway type for a road": { "mappings": { "0": { "then": "Er is een fietssuggestiestrook" @@ -1858,59 +1858,36 @@ }, "question": "Wat voor fietspad is hier?" }, - "1": { + "Cycleway:smoothness": { "mappings": { "0": { - "then": "Deze weg is verlicht" + "then": "Geschikt voor fijne rollers: rollerblade, skateboard" }, "1": { - "then": "Deze weg is niet verlicht" + "then": "Geschikt voor fijne wielen: racefiets" }, "2": { - "then": "Deze weg is 's nachts verlicht" + "then": "Geschikt voor normale wielen: stadsfiets, rolstoel, scooter" }, "3": { - "then": "Deze weg is 24/7 verlicht" - } - }, - "question": "Is deze weg verlicht?" - }, - "2": { - "mappings": { - "0": { - "then": "Dit is een fietsstraat, en dus een 30km/h zone" - }, - "1": { - "then": "Dit is een fietsstraat" - }, - "2": { - "then": "Dit is geen fietsstraat" - } - }, - "question": "Is dit een fietsstraat?" - }, - "3": { - "mappings": { - "0": { - "then": "De maximumsnelheid is 20 km/u" - }, - "1": { - "then": "De maximumsnelheid is 30 km/u" - }, - "2": { - "then": "De maximumsnelheid is 50 km/u" - }, - "3": { - "then": "De maximumsnelheid is 70 km/u" + "then": "Geschikt voor brede wielen: trekfiets, auto, rickshaw" }, "4": { - "then": "De maximumsnelheid is 90 km/u" + "then": "Geschikt voor voertuigen met hoge banden: lichte terreinwagen" + }, + "5": { + "then": "Geschikt voor terreinwagens: zware terreinwagen" + }, + "6": { + "then": "Geschikt voor gespecialiseerde terreinwagens: tractor, alleterreinwagen" + }, + "7": { + "then": "Niet geschikt voor voertuigen met wielen" } }, - "question": "Wat is de maximumsnelheid in deze straat?", - "render": "De maximumsnelheid op deze weg is {maxspeed} km/u" + "question": "Wat is de kwaliteit van dit fietspad?" }, - "4": { + "Cycleway:surface": { "mappings": { "0": { "then": "Dit fietspad is onverhard" @@ -1955,36 +1932,42 @@ "question": "Waaruit is het oppervlak van het fietspad van gemaakt?", "render": "Dit fietspad is gemaakt van {cycleway:surface}" }, - "5": { + "Is this a cyclestreet? (For a road)": { "mappings": { "0": { - "then": "Geschikt voor fijne rollers: rollerblade, skateboard" + "then": "Dit is een fietsstraat, en dus een 30km/h zone" }, "1": { - "then": "Geschikt voor fijne wielen: racefiets" + "then": "Dit is een fietsstraat" }, "2": { - "then": "Geschikt voor normale wielen: stadsfiets, rolstoel, scooter" - }, - "3": { - "then": "Geschikt voor brede wielen: trekfiets, auto, rickshaw" - }, - "4": { - "then": "Geschikt voor voertuigen met hoge banden: lichte terreinwagen" - }, - "5": { - "then": "Geschikt voor terreinwagens: zware terreinwagen" - }, - "6": { - "then": "Geschikt voor gespecialiseerde terreinwagens: tractor, alleterreinwagen" - }, - "7": { - "then": "Niet geschikt voor voertuigen met wielen" + "then": "Dit is geen fietsstraat" } }, - "question": "Wat is de kwaliteit van dit fietspad?" + "question": "Is dit een fietsstraat?" }, - "6": { + "Maxspeed (for road)": { + "mappings": { + "0": { + "then": "De maximumsnelheid is 20 km/u" + }, + "1": { + "then": "De maximumsnelheid is 30 km/u" + }, + "2": { + "then": "De maximumsnelheid is 50 km/u" + }, + "3": { + "then": "De maximumsnelheid is 70 km/u" + }, + "4": { + "then": "De maximumsnelheid is 90 km/u" + } + }, + "question": "Wat is de maximumsnelheid in deze straat?", + "render": "De maximumsnelheid op deze weg is {maxspeed} km/u" + }, + "Surface of the road": { "mappings": { "0": { "then": "Dit fietspad is onverhard" @@ -2029,14 +2012,27 @@ "question": "Waaruit is het oppervlak van de straat gemaakt?", "render": "Deze weg is gemaakt van {surface}" }, - "7": { + "Surface of the street": { "question": "Wat is de kwaliteit van deze straat?" }, - "8": { - "question": "Hoe breed is de rijbaan in deze straat (in meters)?", - "render": "De breedte van deze rijbaan in deze straat is {width:carriageway}m" + "cyclelan-segregation": { + "mappings": { + "0": { + "then": "Dit fietspad is gescheiden van de weg met een onderbroken streep" + }, + "1": { + "then": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" + }, + "2": { + "then": "Dit fietspad is gescheiden van de weg met parkeervakken" + }, + "3": { + "then": "Dit fietspad is gescheiden van de weg met een stoeprand" + } + }, + "question": "Hoe is dit fietspad gescheiden van de weg?" }, - "9": { + "cycleway-lane-track-traffic-signs": { "mappings": { "0": { "then": "Verplicht fietspad " @@ -2056,7 +2052,24 @@ }, "question": "Welk verkeersbord heeft dit fietspad?" }, - "10": { + "cycleway-segregation": { + "mappings": { + "0": { + "then": "Dit fietspad is gescheiden van de weg met een onderbroken streep" + }, + "1": { + "then": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" + }, + "2": { + "then": "Dit fietspad is gescheiden van de weg met parkeervakken" + }, + "3": { + "then": "Dit fietspad is gescheiden van de weg met een stoeprand" + } + }, + "question": "Hoe is dit fietspad gescheiden van de weg?" + }, + "cycleway-traffic-signs": { "mappings": { "0": { "then": "Verplicht fietspad " @@ -2076,7 +2089,7 @@ }, "question": "Welk verkeersbord heeft dit fietspad?" }, - "11": { + "cycleway-traffic-signs-D7-supplementary": { "mappings": { "0": { "then": "" @@ -2102,7 +2115,7 @@ }, "question": "Heeft het verkeersbord D7 () een onderbord?" }, - "12": { + "cycleway-traffic-signs-supplementary": { "mappings": { "0": { "then": "" @@ -2128,43 +2141,30 @@ }, "question": "Heeft het verkeersbord D7 () een onderbord?" }, - "13": { + "cycleways_and_roads-cycleway:buffer": { "question": "Hoe breed is de ruimte tussen het fietspad en de weg?", "render": "De schrikafstand van dit fietspad is {cycleway:buffer} m" }, - "14": { + "is lit?": { "mappings": { "0": { - "then": "Dit fietspad is gescheiden van de weg met een onderbroken streep" + "then": "Deze weg is verlicht" }, "1": { - "then": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" + "then": "Deze weg is niet verlicht" }, "2": { - "then": "Dit fietspad is gescheiden van de weg met parkeervakken" + "then": "Deze weg is 's nachts verlicht" }, "3": { - "then": "Dit fietspad is gescheiden van de weg met een stoeprand" + "then": "Deze weg is 24/7 verlicht" } }, - "question": "Hoe is dit fietspad gescheiden van de weg?" + "question": "Is deze weg verlicht?" }, - "15": { - "mappings": { - "0": { - "then": "Dit fietspad is gescheiden van de weg met een onderbroken streep" - }, - "1": { - "then": "Dit fietspad is gescheiden van de weg met een doorgetrokken streep" - }, - "2": { - "then": "Dit fietspad is gescheiden van de weg met parkeervakken" - }, - "3": { - "then": "Dit fietspad is gescheiden van de weg met een stoeprand" - } - }, - "question": "Hoe is dit fietspad gescheiden van de weg?" + "width:carriageway": { + "question": "Hoe breed is de rijbaan in deze straat (in meters)?", + "render": "De breedte van deze rijbaan in deze straat is {width:carriageway}m" } }, "title": { @@ -2196,18 +2196,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Deze defibrillator bevindt zich in een gebouw" - }, - "1": { - "then": "Deze defibrillator hangt buiten" - } - }, - "question": "Hangt deze defibrillator binnen of buiten?" - }, - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Publiek toegankelijk" @@ -2228,7 +2217,7 @@ "question": "Is deze defibrillator vrij toegankelijk?", "render": "Toegankelijkheid is {access}" }, - "3": { + "defibrillator-defibrillator": { "mappings": { "0": { "then": "Dit is een manueel toestel enkel voor professionals" @@ -2240,7 +2229,42 @@ "question": "Is dit een gewone automatische defibrillator of een manueel toestel enkel voor professionals?", "render": "Er is geen info over het soort toestel" }, - "4": { + "defibrillator-defibrillator:location": { + "question": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in de plaatselijke taal)", + "render": "Meer informatie over de locatie (lokale taal):
{defibrillator:location}" + }, + "defibrillator-defibrillator:location:en": { + "question": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Engels)", + "render": "Meer informatie over de locatie (in het Engels):
{defibrillator:location:en}" + }, + "defibrillator-defibrillator:location:fr": { + "question": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Frans)", + "render": "Meer informatie over de locatie (in het Frans):
{defibrillator:location:fr}" + }, + "defibrillator-description": { + "question": "Is er nog iets bijzonder aan deze defibrillator dat je nog niet hebt kunnen meegeven? (laat leeg indien niet)", + "render": "Aanvullende info: {description}" + }, + "defibrillator-email": { + "question": "Wat is het email-adres voor vragen over deze defibrillator", + "render": "Email voor vragen over deze defibrillator: {email}" + }, + "defibrillator-fixme": { + "question": "Is er iets mis met de informatie over deze defibrillator dat je hier niet opgelost kreeg? (laat hier een berichtje achter voor OpenStreetMap experts)", + "render": "Extra informatie voor OpenStreetMap experts: {fixme}" + }, + "defibrillator-indoors": { + "mappings": { + "0": { + "then": "Deze defibrillator bevindt zich in een gebouw" + }, + "1": { + "then": "Deze defibrillator hangt buiten" + } + }, + "question": "Hangt deze defibrillator binnen of buiten?" + }, + "defibrillator-level": { "mappings": { "0": { "then": "Deze defibrillator bevindt zich gelijkvloers" @@ -2252,31 +2276,7 @@ "question": "Op welke verdieping bevindt deze defibrillator zich?", "render": "De defibrillator bevindt zicht op verdieping {level}" }, - "5": { - "question": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in de plaatselijke taal)", - "render": "Meer informatie over de locatie (lokale taal):
{defibrillator:location}" - }, - "6": { - "question": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Engels)", - "render": "Meer informatie over de locatie (in het Engels):
{defibrillator:location:en}" - }, - "7": { - "question": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator (in het Frans)", - "render": "Meer informatie over de locatie (in het Frans):
{defibrillator:location:fr}" - }, - "9": { - "question": "Wat is het officieel identificatienummer van het toestel? (indien zichtbaar op toestel)", - "render": "Officieel identificatienummer van het toestel: {ref}" - }, - "10": { - "question": "Wat is het email-adres voor vragen over deze defibrillator", - "render": "Email voor vragen over deze defibrillator: {email}" - }, - "11": { - "question": "Wat is het telefoonnummer voor vragen over deze defibrillator", - "render": "Telefoonnummer voor vragen over deze defibrillator: {phone}" - }, - "12": { + "defibrillator-opening_hours": { "mappings": { "0": { "then": "24/7 open (inclusief feestdagen)" @@ -2285,11 +2285,15 @@ "question": "Wanneer is deze defibrillator beschikbaar?", "render": "{opening_hours_table(opening_hours)}" }, - "13": { - "question": "Is er nog iets bijzonder aan deze defibrillator dat je nog niet hebt kunnen meegeven? (laat leeg indien niet)", - "render": "Aanvullende info: {description}" + "defibrillator-phone": { + "question": "Wat is het telefoonnummer voor vragen over deze defibrillator", + "render": "Telefoonnummer voor vragen over deze defibrillator: {phone}" }, - "14": { + "defibrillator-ref": { + "question": "Wat is het officieel identificatienummer van het toestel? (indien zichtbaar op toestel)", + "render": "Officieel identificatienummer van het toestel: {ref}" + }, + "defibrillator-survey:date": { "mappings": { "0": { "then": "Vandaag nagekeken!" @@ -2297,10 +2301,6 @@ }, "question": "Wanneer is deze defibrillator het laatst gecontroleerd in OpenStreetMap?", "render": "Deze defibrillator is nagekeken in OSM op {survey:date}" - }, - "15": { - "question": "Is er iets mis met de informatie over deze defibrillator dat je hier niet opgelost kreeg? (laat hier een berichtje achter voor OpenStreetMap experts)", - "render": "Extra informatie voor OpenStreetMap experts: {fixme}" } }, "title": { @@ -2319,7 +2319,18 @@ } }, "tagRenderings": { - "1": { + "Bottle refill": { + "mappings": { + "0": { + "then": "Een drinkbus bijvullen gaat makkelijk" + }, + "1": { + "then": "Een drinkbus past moeilijk" + } + }, + "question": "Hoe gemakkelijk is het om drinkbussen bij te vullen?" + }, + "Still in use?": { "mappings": { "0": { "then": "Deze drinkwaterfontein werkt" @@ -2334,18 +2345,7 @@ "question": "Is deze drinkwaterkraan nog steeds werkende?", "render": "Deze waterkraan-status is {operational_status}" }, - "2": { - "mappings": { - "0": { - "then": "Een drinkbus bijvullen gaat makkelijk" - }, - "1": { - "then": "Een drinkbus past moeilijk" - } - }, - "question": "Hoe gemakkelijk is het om drinkbussen bij te vullen?" - }, - "3": { + "render-closest-drinking-water": { "render": "Er bevindt zich een ander drinkwaterpunt op {_closest_other_drinking_water_distance} meter" } }, @@ -2400,22 +2400,7 @@ } }, "tagRenderings": { - "1": { - "question": "Wat is de naam van deze eetgelegenheid?", - "render": "De naam van deze eetgelegeheid is {name}" - }, - "2": { - "mappings": { - "0": { - "then": "Dit is een fastfood-zaak. De focus ligt op snelle bediening, zitplaatsen zijn vaak beperkt en functioneel" - }, - "1": { - "then": "Dit is een restaurant. De focus ligt op een aangename ervaring waar je aan tafel wordt bediend" - } - }, - "question": "Wat voor soort zaak is dit?" - }, - "9": { + "Cuisine": { "mappings": { "0": { "then": "Dit is een pizzeria" @@ -2466,7 +2451,22 @@ "question": "Welk soort gerechten worden hier geserveerd?", "render": "Deze plaats serveert vooral {cuisine}" }, - "10": { + "Fastfood vs restaurant": { + "mappings": { + "0": { + "then": "Dit is een fastfood-zaak. De focus ligt op snelle bediening, zitplaatsen zijn vaak beperkt en functioneel" + }, + "1": { + "then": "Dit is een restaurant. De focus ligt op een aangename ervaring waar je aan tafel wordt bediend" + } + }, + "question": "Wat voor soort zaak is dit?" + }, + "Name": { + "question": "Wat is de naam van deze eetgelegenheid?", + "render": "De naam van deze eetgelegeheid is {name}" + }, + "Takeaway": { "mappings": { "0": { "then": "Hier is enkel afhaal mogelijk" @@ -2480,24 +2480,7 @@ }, "question": "Biedt deze zaak een afhaalmogelijkheid aan?" }, - "11": { - "mappings": { - "0": { - "then": "Geen vegetarische opties beschikbaar" - }, - "1": { - "then": "Beperkte vegetarische opties zijn beschikbaar" - }, - "2": { - "then": "Vegetarische opties zijn beschikbaar" - }, - "3": { - "then": "Enkel vegetarische opties zijn beschikbaar" - } - }, - "question": "Heeft deze eetgelegenheid een vegetarische optie?" - }, - "12": { + "Vegan (no friture)": { "mappings": { "0": { "then": "Geen veganistische opties beschikbaar" @@ -2514,7 +2497,77 @@ }, "question": "Heeft deze eetgelegenheid een veganistische optie?" }, - "13": { + "Vegetarian (no friture)": { + "mappings": { + "0": { + "then": "Geen vegetarische opties beschikbaar" + }, + "1": { + "then": "Beperkte vegetarische opties zijn beschikbaar" + }, + "2": { + "then": "Vegetarische opties zijn beschikbaar" + }, + "3": { + "then": "Enkel vegetarische opties zijn beschikbaar" + } + }, + "question": "Heeft deze eetgelegenheid een vegetarische optie?" + }, + "friture-oil": { + "mappings": { + "0": { + "then": "Plantaardige olie" + }, + "1": { + "then": "Dierlijk vet" + } + }, + "question": "Bakt deze frituur met dierlijk vet of met plantaardige olie?" + }, + "friture-take-your-container": { + "mappings": { + "0": { + "then": "Je mag je eigen containers meenemen om je bestelling in mee te nemen en zo minder afval te maken" + }, + "1": { + "then": "Je mag geen eigen containers meenemen om je bestelling in mee te nemen" + }, + "2": { + "then": "Je moet je eigen containers meenemen om je bestelling in mee te nemen." + } + }, + "question": "Als je je eigen container (bv. kookpot of kleine potjes voor saus) meeneemt, gebruikt de frituur deze dan om je bestelling in te doen?" + }, + "friture-vegan": { + "mappings": { + "0": { + "then": "Er zijn veganistische snacks aanwezig" + }, + "1": { + "then": "Slechts enkele veganistische snacks" + }, + "2": { + "then": "Geen veganistische snacks beschikbaar" + } + }, + "question": "Heeft deze frituur veganistische snacks?" + }, + "friture-vegetarian": { + "mappings": { + "0": { + "then": "Er zijn vegetarische snacks aanwezig" + }, + "1": { + "then": "Slechts enkele vegetarische snacks" + }, + "2": { + "then": "Geen vegetarische snacks beschikbaar" + } + }, + "question": "Heeft deze frituur vegetarische snacks?" + }, + "halal (no friture)": { "mappings": { "0": { "then": "Er zijn geen halal opties aanwezig" @@ -2530,59 +2583,6 @@ } }, "question": "Heeft dit restaurant halal opties?" - }, - "14": { - "mappings": { - "0": { - "then": "Er zijn vegetarische snacks aanwezig" - }, - "1": { - "then": "Slechts enkele vegetarische snacks" - }, - "2": { - "then": "Geen vegetarische snacks beschikbaar" - } - }, - "question": "Heeft deze frituur vegetarische snacks?" - }, - "15": { - "mappings": { - "0": { - "then": "Er zijn veganistische snacks aanwezig" - }, - "1": { - "then": "Slechts enkele veganistische snacks" - }, - "2": { - "then": "Geen veganistische snacks beschikbaar" - } - }, - "question": "Heeft deze frituur veganistische snacks?" - }, - "16": { - "mappings": { - "0": { - "then": "Plantaardige olie" - }, - "1": { - "then": "Dierlijk vet" - } - }, - "question": "Bakt deze frituur met dierlijk vet of met plantaardige olie?" - }, - "17": { - "mappings": { - "0": { - "then": "Je mag je eigen containers meenemen om je bestelling in mee te nemen en zo minder afval te maken" - }, - "1": { - "then": "Je mag geen eigen containers meenemen om je bestelling in mee te nemen" - }, - "2": { - "then": "Je moet je eigen containers meenemen om je bestelling in mee te nemen." - } - }, - "question": "Als je je eigen container (bv. kookpot of kleine potjes voor saus) meeneemt, gebruikt de frituur deze dan om je bestelling in te doen?" } }, "title": { @@ -2605,10 +2605,14 @@ } }, "tagRenderings": { - "0": { + "ghost-bike-explanation": { "render": "Een Witte Fiets (of Spookfiets) is een aandenken aan een fietser die bij een verkeersongeval om het leven kwam. Het gaat over een witgeschilderde fiets die geplaatst werd in de buurt van het ongeval." }, - "2": { + "ghost_bike-inscription": { + "question": "Wat is het opschrift op deze witte fiets?", + "render": "{inscription}" + }, + "ghost_bike-name": { "mappings": { "0": { "then": "De naam is niet aangeduid op de fiets" @@ -2617,15 +2621,11 @@ "question": "Aan wie is deze witte fiets een eerbetoon?
Respecteer privacy - voeg enkel een naam toe indien die op de fiets staat of gepubliceerd is. Eventueel voeg je enkel de voornaam toe.
", "render": "Ter nagedachtenis van {name}" }, - "3": { + "ghost_bike-source": { "question": "Op welke website kan men meer informatie vinden over de Witte fiets of over het ongeval?", "render": "Meer informatie" }, - "4": { - "question": "Wat is het opschrift op deze witte fiets?", - "render": "{inscription}" - }, - "5": { + "ghost_bike-start_date": { "question": "Wanneer werd deze witte fiets geplaatst?", "render": "Geplaatst op {start_date}" } @@ -2671,16 +2671,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Deze kaart is gebaseerd op OpenStreetMap" - } - }, - "question": "Op welke data is deze kaart gebaseerd?", - "render": "Deze kaart is gebaseerd op {map_source}" - }, - "2": { + "map-attribution": { "mappings": { "0": { "then": "De OpenStreetMap-attributie is duidelijk aangegeven, zelf met vermelding van \"ODBL\" " @@ -2699,6 +2690,15 @@ } }, "question": "Is de attributie voor OpenStreetMap aanwezig?" + }, + "map-map_source": { + "mappings": { + "0": { + "then": "Deze kaart is gebaseerd op OpenStreetMap" + } + }, + "question": "Op welke data is deze kaart gebaseerd?", + "render": "Deze kaart is gebaseerd op {map_source}" } }, "title": { @@ -2737,7 +2737,7 @@ } }, "tagRenderings": { - "1": { + "Access tag": { "mappings": { "0": { "then": "Vrij toegankelijk" @@ -2761,7 +2761,48 @@ "question": "Is dit gebied toegankelijk?", "render": "De toegankelijkheid van dit gebied is: {access:description}" }, - "2": { + "Curator": { + "question": "Wie is de conservator van dit gebied?
Respecteer privacy - geef deze naam enkel als die duidelijk is gepubliceerd", + "render": "{curator} is de beheerder van dit gebied" + }, + "Dogs?": { + "mappings": { + "0": { + "then": "Honden moeten aan de leiband" + }, + "1": { + "then": "Honden zijn niet toegestaan" + }, + "2": { + "then": "Honden zijn welkom en mogen vrij rondlopen" + } + }, + "question": "Zijn honden toegelaten in dit gebied?" + }, + "Editable description {description:0}": { + "render": "Extra info: {description:0}" + }, + "Email": { + "question": "Waar kan men naartoe emailen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke emailadressen als deze elders zijn gepubliceerd", + "render": "{email}" + }, + "Name tag": { + "mappings": { + "0": { + "then": "Dit gebied heeft geen naam" + } + }, + "question": "Wat is de naam van dit gebied?", + "render": "Dit gebied heet {name}" + }, + "Name:nl-tag": { + "question": "Wat is de Nederlandstalige naam van dit gebied?", + "render": "Dit gebied heet {name:nl}" + }, + "Non-editable description {description}": { + "render": "Extra info: {description}" + }, + "Operator tag": { "mappings": { "0": { "then": "Dit gebied wordt beheerd door Natuurpunt" @@ -2776,56 +2817,15 @@ "question": "Wie beheert dit gebied?", "render": "Beheer door {operator}" }, - "3": { - "question": "Wat is de Nederlandstalige naam van dit gebied?", - "render": "Dit gebied heet {name:nl}" + "Surface area": { + "render": "Totale oppervlakte: {_surface:ha}Ha" }, - "4": { - "mappings": { - "0": { - "then": "Dit gebied heeft geen naam" - } - }, - "question": "Wat is de naam van dit gebied?", - "render": "Dit gebied heet {name}" - }, - "5": { - "mappings": { - "0": { - "then": "Honden moeten aan de leiband" - }, - "1": { - "then": "Honden zijn niet toegestaan" - }, - "2": { - "then": "Honden zijn welkom en mogen vrij rondlopen" - } - }, - "question": "Zijn honden toegelaten in dit gebied?" - }, - "6": { + "Website": { "question": "Op welke webpagina kan men meer informatie vinden over dit natuurgebied?" }, - "7": { - "question": "Wie is de conservator van dit gebied?
Respecteer privacy - geef deze naam enkel als die duidelijk is gepubliceerd", - "render": "{curator} is de beheerder van dit gebied" - }, - "8": { - "question": "Waar kan men naartoe emailen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke emailadressen als deze elders zijn gepubliceerd", - "render": "{email}" - }, - "9": { + "phone": { "question": "Waar kan men naartoe bellen voor vragen en meldingen van dit natuurgebied?
Respecteer privacy - geef enkel persoonlijke telefoonnummers als deze elders zijn gepubliceerd", "render": "{phone}" - }, - "10": { - "render": "Extra info: {description}" - }, - "11": { - "render": "Extra info: {description:0}" - }, - "12": { - "render": "Totale oppervlakte: {_surface:ha}Ha" } }, "title": { @@ -2850,24 +2850,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Deze toren heeft geen specifieke naam" - } - }, - "question": "Heeft deze toren een naam?", - "render": "Deze toren heet {name}" - }, - "2": { - "question": "Hoe hoog is deze toren?", - "render": "Deze toren is {height} hoog" - }, - "3": { - "question": "Wie onderhoudt deze toren?", - "render": "Wordt onderhouden door {operator}" - }, - "5": { + "Fee": { "mappings": { "0": { "then": "Gratis te bezoeken" @@ -2875,6 +2858,23 @@ }, "question": "Hoeveel moet men betalen om deze toren te bezoeken?", "render": "Deze toren bezoeken kost {charge}" + }, + "Height": { + "question": "Hoe hoog is deze toren?", + "render": "Deze toren is {height} hoog" + }, + "Operator": { + "question": "Wie onderhoudt deze toren?", + "render": "Wordt onderhouden door {operator}" + }, + "name": { + "mappings": { + "0": { + "then": "Deze toren heeft geen specifieke naam" + } + }, + "question": "Heeft deze toren een naam?", + "render": "Deze toren heet {name}" } }, "title": { @@ -2905,7 +2905,7 @@ } }, "tagRenderings": { - "1": { + "Access tag": { "mappings": { "0": { "then": "Vrij toegankelijk" @@ -2929,7 +2929,7 @@ "question": "Is dit gebied toegankelijk?", "render": "De toegankelijkheid van dit gebied is: {access:description}" }, - "2": { + "Operator tag": { "mappings": { "0": { "then": "Dit gebied wordt beheerd door Natuurpunt" @@ -2966,7 +2966,7 @@ } }, "tagRenderings": { - "0": { + "picnic_table-material": { "mappings": { "0": { "then": "Deze picnictafel is gemaakt uit hout" @@ -3007,7 +3007,86 @@ } }, "tagRenderings": { - "1": { + "Playground-wheelchair": { + "mappings": { + "0": { + "then": "Geheel toegankelijk voor rolstoelgebruikers" + }, + "1": { + "then": "Beperkt toegankelijk voor rolstoelgebruikers" + }, + "2": { + "then": "Niet toegankelijk voor rolstoelgebruikers" + } + }, + "question": "Is deze speeltuin toegankelijk voor rolstoelgebruikers?" + }, + "playground-access": { + "mappings": { + "0": { + "then": "Vrij toegankelijk voor het publiek" + }, + "1": { + "then": "Vrij toegankelijk voor het publiek" + }, + "2": { + "then": "Enkel toegankelijk voor klanten van de bijhorende zaak" + }, + "3": { + "then": "Vrij toegankelijk voor scholieren van de school" + }, + "4": { + "then": "Niet vrij toegankelijk" + } + }, + "question": "Is deze speeltuin vrij toegankelijk voor het publiek?" + }, + "playground-email": { + "question": "Wie kan men emailen indien er problemen zijn met de speeltuin?", + "render": "De bevoegde dienst kan bereikt worden via {email}" + }, + "playground-lit": { + "mappings": { + "0": { + "then": "Deze speeltuin is 's nachts verlicht" + }, + "1": { + "then": "Deze speeltuin is 's nachts niet verlicht" + } + }, + "question": "Is deze speeltuin 's nachts verlicht?" + }, + "playground-max_age": { + "question": "Wat is de maximaal toegestane leeftijd voor deze speeltuin?", + "render": "Toegankelijk tot {max_age}" + }, + "playground-min_age": { + "question": "Wat is de minimale leeftijd om op deze speeltuin te mogen?", + "render": "Toegankelijk vanaf {min_age} jaar oud" + }, + "playground-opening_hours": { + "mappings": { + "0": { + "then": "Van zonsopgang tot zonsondergang" + }, + "1": { + "then": "Dag en nacht toegankelijk" + }, + "2": { + "then": "Dag en nacht toegankelijk" + } + }, + "question": "Op welke uren is deze speeltuin toegankelijk?" + }, + "playground-operator": { + "question": "Wie beheert deze speeltuin?", + "render": "Beheer door {operator}" + }, + "playground-phone": { + "question": "Wie kan men bellen indien er problemen zijn met de speeltuin?", + "render": "De bevoegde dienst kan getelefoneerd worden via {phone}" + }, + "playground-surface": { "mappings": { "0": { "then": "De ondergrond is gras" @@ -3036,85 +3115,6 @@ }, "question": "Wat is de ondergrond van deze speeltuin?
Indien er verschillende ondergronden zijn, neem de meest voorkomende", "render": "De ondergrond is {surface}" - }, - "2": { - "mappings": { - "0": { - "then": "Deze speeltuin is 's nachts verlicht" - }, - "1": { - "then": "Deze speeltuin is 's nachts niet verlicht" - } - }, - "question": "Is deze speeltuin 's nachts verlicht?" - }, - "3": { - "question": "Wat is de minimale leeftijd om op deze speeltuin te mogen?", - "render": "Toegankelijk vanaf {min_age} jaar oud" - }, - "4": { - "question": "Wat is de maximaal toegestane leeftijd voor deze speeltuin?", - "render": "Toegankelijk tot {max_age}" - }, - "5": { - "question": "Wie beheert deze speeltuin?", - "render": "Beheer door {operator}" - }, - "6": { - "mappings": { - "0": { - "then": "Vrij toegankelijk voor het publiek" - }, - "1": { - "then": "Vrij toegankelijk voor het publiek" - }, - "2": { - "then": "Enkel toegankelijk voor klanten van de bijhorende zaak" - }, - "3": { - "then": "Vrij toegankelijk voor scholieren van de school" - }, - "4": { - "then": "Niet vrij toegankelijk" - } - }, - "question": "Is deze speeltuin vrij toegankelijk voor het publiek?" - }, - "7": { - "question": "Wie kan men emailen indien er problemen zijn met de speeltuin?", - "render": "De bevoegde dienst kan bereikt worden via {email}" - }, - "8": { - "question": "Wie kan men bellen indien er problemen zijn met de speeltuin?", - "render": "De bevoegde dienst kan getelefoneerd worden via {phone}" - }, - "9": { - "mappings": { - "0": { - "then": "Geheel toegankelijk voor rolstoelgebruikers" - }, - "1": { - "then": "Beperkt toegankelijk voor rolstoelgebruikers" - }, - "2": { - "then": "Niet toegankelijk voor rolstoelgebruikers" - } - }, - "question": "Is deze speeltuin toegankelijk voor rolstoelgebruikers?" - }, - "10": { - "mappings": { - "0": { - "then": "Van zonsopgang tot zonsondergang" - }, - "1": { - "then": "Dag en nacht toegankelijk" - }, - "2": { - "then": "Dag en nacht toegankelijk" - } - }, - "question": "Op welke uren is deze speeltuin toegankelijk?" } }, "title": { @@ -3135,20 +3135,7 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "Dit boekenruilkastje heeft geen naam" - } - }, - "question": "Wat is de naam van dit boekenuilkastje?", - "render": "De naam van dit boekenruilkastje is {name}" - }, - "3": { - "question": "Hoeveel boeken passen er in dit boekenruilkastje?", - "render": "Er passen {capacity} boeken" - }, - "4": { + "bookcase-booktypes": { "mappings": { "0": { "then": "Voornamelijk kinderboeken" @@ -3162,7 +3149,18 @@ }, "question": "Voor welke doelgroep zijn de meeste boeken in dit boekenruilkastje?" }, - "5": { + "bookcase-is-accessible": { + "mappings": { + "0": { + "then": "Publiek toegankelijk" + }, + "1": { + "then": "Enkel toegankelijk voor klanten" + } + }, + "question": "Is dit boekenruilkastje publiek toegankelijk?" + }, + "bookcase-is-indoors": { "mappings": { "0": { "then": "Dit boekenruilkastje staat binnen" @@ -3176,22 +3174,7 @@ }, "question": "Staat dit boekenruilkastje binnen of buiten?" }, - "6": { - "mappings": { - "0": { - "then": "Publiek toegankelijk" - }, - "1": { - "then": "Enkel toegankelijk voor klanten" - } - }, - "question": "Is dit boekenruilkastje publiek toegankelijk?" - }, - "7": { - "question": "Wie is verantwoordelijk voor dit boekenruilkastje?", - "render": "Onderhouden door {operator}" - }, - "8": { + "public_bookcase-brand": { "mappings": { "0": { "then": "Deel van het netwerk 'Little Free Library'" @@ -3203,7 +3186,24 @@ "question": "Is dit boekenruilkastje deel van een netwerk?", "render": "Dit boekenruilkastje is deel van het netwerk {brand}" }, - "9": { + "public_bookcase-capacity": { + "question": "Hoeveel boeken passen er in dit boekenruilkastje?", + "render": "Er passen {capacity} boeken" + }, + "public_bookcase-name": { + "mappings": { + "0": { + "then": "Dit boekenruilkastje heeft geen naam" + } + }, + "question": "Wat is de naam van dit boekenuilkastje?", + "render": "De naam van dit boekenruilkastje is {name}" + }, + "public_bookcase-operator": { + "question": "Wie is verantwoordelijk voor dit boekenruilkastje?", + "render": "Onderhouden door {operator}" + }, + "public_bookcase-ref": { "mappings": { "0": { "then": "Dit boekenruilkastje maakt geen deel uit van een netwerk" @@ -3212,11 +3212,11 @@ "question": "Wat is het referentienummer van dit boekenruilkastje?", "render": "Het referentienummer binnen {brand} is {ref}" }, - "10": { + "public_bookcase-start_date": { "question": "Op welke dag werd dit boekenruilkastje geinstalleerd?", "render": "Geplaatst op {start_date}" }, - "11": { + "public_bookcase-website": { "question": "Is er een website over dit boekenruilkastje?", "render": "Meer info op de website" } @@ -3233,7 +3233,7 @@ "slow_roads": { "name": "Paadjes, trage wegen en autoluwe straten", "tagRenderings": { - "1": { + "explanation": { "mappings": { "1": { "then": "Dit is een brede, autovrije straat" @@ -3252,7 +3252,7 @@ } } }, - "2": { + "slow_roads-surface": { "mappings": { "0": { "then": "De ondergrond is gras" @@ -3316,7 +3316,55 @@ } }, "tagRenderings": { - "1": { + "sport-pitch-access": { + "mappings": { + "0": { + "then": "Publiek toegankelijk" + }, + "1": { + "then": "Beperkt toegankelijk (enkel na reservatie, tijdens bepaalde uren, ...)" + }, + "2": { + "then": "Enkel toegankelijk voor leden van de bijhorende sportclub" + }, + "3": { + "then": "Privaat en niet toegankelijk" + } + }, + "question": "Is dit sportterrein publiek toegankelijk?" + }, + "sport-pitch-reservation": { + "mappings": { + "0": { + "then": "Reserveren is verplicht om gebruik te maken van dit sportterrein" + }, + "1": { + "then": "Reserveren is sterk aangeraden om gebruik te maken van dit sportterrein" + }, + "2": { + "then": "Reserveren is mogelijk, maar geen voorwaarde" + }, + "3": { + "then": "Reserveren is niet mogelijk" + } + }, + "question": "Moet men reserveren om gebruik te maken van dit sportveld?" + }, + "sport_pitch-email": { + "question": "Wat is het email-adres van de bevoegde dienst of uitbater?" + }, + "sport_pitch-opening_hours": { + "mappings": { + "1": { + "then": "24/7 toegankelijk" + } + }, + "question": "Wanneer is dit sportveld toegankelijk?" + }, + "sport_pitch-phone": { + "question": "Wat is het telefoonnummer van de bevoegde dienst of uitbater?" + }, + "sport_pitch-sport": { "mappings": { "0": { "then": "Hier kan men basketbal spelen" @@ -3340,7 +3388,7 @@ "question": "Welke sporten kan men hier beoefenen?", "render": "Hier kan men {sport} beoefenen" }, - "2": { + "sport_pitch-surface": { "mappings": { "0": { "then": "De ondergrond is gras" @@ -3360,54 +3408,6 @@ }, "question": "Wat is de ondergrond van dit sportveld?", "render": "De ondergrond is {surface}" - }, - "3": { - "mappings": { - "0": { - "then": "Publiek toegankelijk" - }, - "1": { - "then": "Beperkt toegankelijk (enkel na reservatie, tijdens bepaalde uren, ...)" - }, - "2": { - "then": "Enkel toegankelijk voor leden van de bijhorende sportclub" - }, - "3": { - "then": "Privaat en niet toegankelijk" - } - }, - "question": "Is dit sportterrein publiek toegankelijk?" - }, - "4": { - "mappings": { - "0": { - "then": "Reserveren is verplicht om gebruik te maken van dit sportterrein" - }, - "1": { - "then": "Reserveren is sterk aangeraden om gebruik te maken van dit sportterrein" - }, - "2": { - "then": "Reserveren is mogelijk, maar geen voorwaarde" - }, - "3": { - "then": "Reserveren is niet mogelijk" - } - }, - "question": "Moet men reserveren om gebruik te maken van dit sportveld?" - }, - "5": { - "question": "Wat is het telefoonnummer van de bevoegde dienst of uitbater?" - }, - "6": { - "question": "Wat is het email-adres van de bevoegde dienst of uitbater?" - }, - "7": { - "mappings": { - "1": { - "then": "24/7 toegankelijk" - } - }, - "question": "Wanneer is dit sportveld toegankelijk?" } }, "title": { @@ -3417,7 +3417,7 @@ "surveillance_camera": { "name": "Bewakingscamera's", "tagRenderings": { - "1": { + "Camera type: fixed; panning; dome": { "mappings": { "0": { "then": "Een vaste camera" @@ -3431,34 +3431,7 @@ }, "question": "Wat voor soort camera is dit?" }, - "2": { - "mappings": { - "0": { - "then": "Filmt in kompasrichting {direction}" - } - }, - "question": "In welke geografische richting filmt deze camera?", - "render": "Filmt in kompasrichting {camera:direction}" - }, - "3": { - "question": "Wie beheert deze bewakingscamera?", - "render": "Beheer door {operator}" - }, - "4": { - "mappings": { - "0": { - "then": "Bewaking van de publieke ruilmte, dus een straat, een brug, een park, een plein, een stationsgebouw, een publiek toegankelijke gang of tunnel..." - }, - "1": { - "then": "Een buitenruimte met privaat karakter (zoals een privé-oprit, een parking, tankstation, ...)" - }, - "2": { - "then": "Een private binnenruimte wordt bewaakt, bv. een winkel, een parkeergarage, ..." - } - }, - "question": "Wat soort bewaking wordt hier uitgevoerd?" - }, - "5": { + "Indoor camera? This isn't clear for 'public'-cameras": { "mappings": { "0": { "then": "Deze camera bevindt zich binnen" @@ -3472,11 +3445,29 @@ }, "question": "Bevindt de bewaakte publieke ruimte camera zich binnen of buiten?" }, - "6": { + "Level": { "question": "Op welke verdieping bevindt deze camera zich?", "render": "Bevindt zich op verdieping {level}" }, - "7": { + "Operator": { + "question": "Wie beheert deze bewakingscamera?", + "render": "Beheer door {operator}" + }, + "Surveillance type: public, outdoor, indoor": { + "mappings": { + "0": { + "then": "Bewaking van de publieke ruilmte, dus een straat, een brug, een park, een plein, een stationsgebouw, een publiek toegankelijke gang of tunnel..." + }, + "1": { + "then": "Een buitenruimte met privaat karakter (zoals een privé-oprit, een parking, tankstation, ...)" + }, + "2": { + "then": "Een private binnenruimte wordt bewaakt, bv. een winkel, een parkeergarage, ..." + } + }, + "question": "Wat soort bewaking wordt hier uitgevoerd?" + }, + "Surveillance:zone": { "mappings": { "0": { "then": "Bewaakt een parking" @@ -3500,7 +3491,7 @@ "question": "Wat wordt hier precies bewaakt?", "render": "Bewaakt een {surveillance:zone}" }, - "8": { + "camera:mount": { "mappings": { "0": { "then": "Deze camera hangt aan een muur" @@ -3514,6 +3505,15 @@ }, "question": "Hoe is deze camera geplaatst?", "render": "Montage: {camera:mount}" + }, + "direction. We don't ask this for a dome on a pole or ceiling as it has a 360° view": { + "mappings": { + "0": { + "then": "Filmt in kompasrichting {direction}" + } + }, + "question": "In welke geografische richting filmt deze camera?", + "render": "Filmt in kompasrichting {camera:direction}" } }, "title": { @@ -3533,7 +3533,7 @@ } }, "tagRenderings": { - "1": { + "toilet-access": { "mappings": { "0": { "then": "Publiek toegankelijk" @@ -3554,61 +3554,7 @@ "question": "Zijn deze toiletten publiek toegankelijk?", "render": "Toegankelijkheid is {access}" }, - "2": { - "mappings": { - "0": { - "then": "Men moet betalen om deze toiletten te gebruiken" - }, - "1": { - "then": "Gratis te gebruiken" - } - }, - "question": "Zijn deze toiletten gratis te gebruiken?" - }, - "3": { - "question": "Hoeveel moet men betalen om deze toiletten te gebruiken?", - "render": "De toiletten gebruiken kost {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "Er is een toilet voor rolstoelgebruikers" - }, - "1": { - "then": "Niet toegankelijk voor rolstoelgebruikers" - } - }, - "question": "Is er een rolstoeltoegankelijke toilet voorzien?" - }, - "5": { - "mappings": { - "0": { - "then": "Er zijn enkel WC's om op te zitten" - }, - "1": { - "then": "Er zijn enkel urinoirs" - }, - "2": { - "then": "Er zijn enkel hurktoiletten" - }, - "3": { - "then": "Er zijn zowel urinoirs als zittoiletten" - } - }, - "question": "Welke toiletten zijn dit?" - }, - "6": { - "mappings": { - "0": { - "then": "Er is een luiertafel" - }, - "1": { - "then": "Geen luiertafel" - } - }, - "question": "Is er een luiertafel beschikbaar?" - }, - "7": { + "toilet-changing_table:location": { "mappings": { "0": { "then": "De luiertafel bevindt zich in de vrouwentoiletten " @@ -3625,6 +3571,60 @@ }, "question": "Waar bevindt de luiertafel zich?", "render": "De luiertafel bevindt zich in {changing_table:location}" + }, + "toilet-charge": { + "question": "Hoeveel moet men betalen om deze toiletten te gebruiken?", + "render": "De toiletten gebruiken kost {charge}" + }, + "toilets-changing-table": { + "mappings": { + "0": { + "then": "Er is een luiertafel" + }, + "1": { + "then": "Geen luiertafel" + } + }, + "question": "Is er een luiertafel beschikbaar?" + }, + "toilets-fee": { + "mappings": { + "0": { + "then": "Men moet betalen om deze toiletten te gebruiken" + }, + "1": { + "then": "Gratis te gebruiken" + } + }, + "question": "Zijn deze toiletten gratis te gebruiken?" + }, + "toilets-type": { + "mappings": { + "0": { + "then": "Er zijn enkel WC's om op te zitten" + }, + "1": { + "then": "Er zijn enkel urinoirs" + }, + "2": { + "then": "Er zijn enkel hurktoiletten" + }, + "3": { + "then": "Er zijn zowel urinoirs als zittoiletten" + } + }, + "question": "Welke toiletten zijn dit?" + }, + "toilets-wheelchair": { + "mappings": { + "0": { + "then": "Er is een toilet voor rolstoelgebruikers" + }, + "1": { + "then": "Niet toegankelijk voor rolstoelgebruikers" + } + }, + "question": "Is er een rolstoeltoegankelijke toilet voorzien?" } }, "title": { @@ -3635,26 +3635,7 @@ "description": "Aangeduide wandeltochten", "name": "Wandeltochten", "tagRenderings": { - "1": { - "render": "Deze wandeling is {_length:km} kilometer lang" - }, - "2": { - "question": "Wat is de naam van deze wandeling?", - "render": "Deze wandeling heet {name}" - }, - "3": { - "mappings": { - "0": { - "then": "Dit gebied wordt beheerd door Natuurpunt" - }, - "1": { - "then": "Dit gebied wordt beheerd door {operator}" - } - }, - "question": "Wie beheert deze wandeltocht?", - "render": "Beheer door {operator}" - }, - "4": { + "Color": { "mappings": { "0": { "then": "Blauwe wandeling" @@ -3672,7 +3653,23 @@ "question": "Welke kleur heeft deze wandeling?", "render": "Deze wandeling heeft kleur {colour}" }, - "5": { + "Name": { + "question": "Wat is de naam van deze wandeling?", + "render": "Deze wandeling heet {name}" + }, + "Operator tag": { + "mappings": { + "0": { + "then": "Dit gebied wordt beheerd door Natuurpunt" + }, + "1": { + "then": "Dit gebied wordt beheerd door {operator}" + } + }, + "question": "Wie beheert deze wandeltocht?", + "render": "Beheer door {operator}" + }, + "Wheelchair access": { "mappings": { "0": { "then": "deze wandeltocht is toegankelijk met de rolstoel" @@ -3683,7 +3680,7 @@ }, "question": "Is deze wandeling toegankelijk met de rolstoel?" }, - "6": { + "pushchair access": { "mappings": { "0": { "then": "deze wandeltocht is toegankelijk met de buggy" @@ -3693,6 +3690,9 @@ } }, "question": "Is deze wandeltocht toegankelijk met de buggy?" + }, + "trail-length": { + "render": "Deze wandeling is {_length:km} kilometer lang" } }, "title": { @@ -3716,29 +3716,18 @@ } }, "tagRenderings": { - "1": { + "tree-decidouous": { "mappings": { "0": { - "then": "Hoogte: {height} m" - } - }, - "render": "Hoogte: {height}" - }, - "2": { - "mappings": { - "0": { - "then": "\"\"/ Loofboom" + "then": "Bladverliezend: de boom is een periode van het jaar kaal." }, "1": { - "then": "\"\"/ Naaldboom" - }, - "2": { - "then": "\"\"/ Permanent bladloos" + "then": "Groenblijvend." } }, - "question": "Is dit een naald- of loofboom?" + "question": "Is deze boom groenblijvend of bladverliezend?" }, - "3": { + "tree-denotation": { "mappings": { "0": { "then": "De boom valt op door zijn grootte of prominente locatie. Hij is nuttig voor navigatie." @@ -3767,27 +3756,15 @@ }, "question": "Hoe significant is deze boom? Kies het eerste antwoord dat van toepassing is." }, - "4": { + "tree-height": { "mappings": { "0": { - "then": "Bladverliezend: de boom is een periode van het jaar kaal." - }, - "1": { - "then": "Groenblijvend." + "then": "Hoogte: {height} m" } }, - "question": "Is deze boom groenblijvend of bladverliezend?" + "render": "Hoogte: {height}" }, - "5": { - "mappings": { - "0": { - "then": "De boom heeft geen naam." - } - }, - "question": "Heeft de boom een naam?", - "render": "Naam: {name}" - }, - "6": { + "tree-heritage": { "mappings": { "0": { "then": "\"\"/ Erkend als houtig erfgoed door Onroerend Erfgoed Vlaanderen" @@ -3807,11 +3784,34 @@ }, "question": "Is deze boom erkend als erfgoed?" }, - "7": { + "tree-leaf_type": { + "mappings": { + "0": { + "then": "\"\"/ Loofboom" + }, + "1": { + "then": "\"\"/ Naaldboom" + }, + "2": { + "then": "\"\"/ Permanent bladloos" + } + }, + "question": "Is dit een naald- of loofboom?" + }, + "tree_node-name": { + "mappings": { + "0": { + "then": "De boom heeft geen naam." + } + }, + "question": "Heeft de boom een naam?", + "render": "Naam: {name}" + }, + "tree_node-ref:OnroerendErfgoed": { "question": "Wat is het ID uitgegeven door Onroerend Erfgoed Vlaanderen?", "render": "\"\"/ Onroerend Erfgoed-ID: {ref:OnroerendErfgoed}" }, - "8": { + "tree_node-wikidata": { "question": "Wat is het Wikidata-ID van deze boom?", "render": "\"\"/ Wikidata: {wikidata}" } @@ -3834,7 +3834,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Zijn er bijzonderheden die je wilt toevoegen?" } }, @@ -3884,7 +3884,7 @@ } }, "tagRenderings": { - "0": { + "waste-basket-waste-types": { "mappings": { "0": { "then": "Een vuilnisbak voor zwerfvuil" @@ -3916,7 +3916,7 @@ "description": "Watermolens", "name": "watermolens", "tagRenderings": { - "1": { + "Access tag": { "mappings": { "0": { "then": "Vrij toegankelijk" @@ -3940,7 +3940,7 @@ "question": "Is dit gebied toegankelijk?", "render": "De toegankelijkheid van dit gebied is: {access:description}" }, - "2": { + "Operator tag": { "mappings": { "0": { "then": "Dit gebied wordt beheerd door Natuurpunt" diff --git a/langs/layers/pl.json b/langs/layers/pl.json index 302194fd9..7c91508bb 100644 --- a/langs/layers/pl.json +++ b/langs/layers/pl.json @@ -8,7 +8,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Oparcie: Tak" @@ -20,39 +20,7 @@ "question": "Czy ta ławka ma oparcie?", "render": "Oparcie" }, - "2": { - "question": "Ile siedzeń ma ta ławka?", - "render": "{seats} siedzeń" - }, - "3": { - "mappings": { - "0": { - "then": "Materiał: drewno" - }, - "1": { - "then": "Materiał: metal" - }, - "2": { - "then": "Materiał: kamień" - }, - "3": { - "then": "Materiał: beton" - }, - "4": { - "then": "Materiał: plastik" - }, - "5": { - "then": "Materiał: stal" - } - }, - "question": "Z czego wykonana jest ławka (siedzisko)?", - "render": "Materiał: {material}" - }, - "4": { - "question": "W jakim kierunku patrzysz siedząc na ławce?", - "render": "Siedząc na ławce, patrzy się w kierunku {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Kolor: brązowy" @@ -82,7 +50,39 @@ "question": "Jaki kolor ma ta ławka?", "render": "Kolor: {colour}" }, - "6": { + "bench-direction": { + "question": "W jakim kierunku patrzysz siedząc na ławce?", + "render": "Siedząc na ławce, patrzy się w kierunku {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Materiał: drewno" + }, + "1": { + "then": "Materiał: metal" + }, + "2": { + "then": "Materiał: kamień" + }, + "3": { + "then": "Materiał: beton" + }, + "4": { + "then": "Materiał: plastik" + }, + "5": { + "then": "Materiał: stal" + } + }, + "question": "Z czego wykonana jest ławka (siedzisko)?", + "render": "Materiał: {material}" + }, + "bench-seats": { + "question": "Ile siedzeń ma ta ławka?", + "render": "{seats} siedzeń" + }, + "bench-survey:date": { "question": "Kiedy ostatnio badano tę ławkę?", "render": "Ławka ta była ostatnio badana w dniu {survey:date}" } @@ -94,7 +94,7 @@ "bench_at_pt": { "name": "Ławki na przystankach komunikacji miejskiej", "tagRenderings": { - "1": { + "bench_at_pt-name": { "render": "{name}" } }, @@ -118,11 +118,11 @@ } }, "tagRenderings": { - "1": { + "Bicycle parking type": { "question": "Jaki jest typ tego parkingu dla rowerów?", "render": "Jest to parking rowerowy typu: {bicycle_parking}" }, - "2": { + "Underground?": { "question": "Jaka jest względna lokalizacja tego parkingu rowerowego?" } }, @@ -141,7 +141,7 @@ } }, "tagRenderings": { - "8": { + "Operational status": { "mappings": { "0": { "then": "Pompka rowerowa jest zepsuta" @@ -152,11 +152,7 @@ }, "question": "Czy pompka rowerowa jest nadal sprawna?" }, - "10": { - "question": "Jakie zawory są obsługiwane?", - "render": "Ta pompka obsługuje następujące zawory: {valves}" - }, - "11": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { "then": "Pompa ręczna" @@ -167,7 +163,7 @@ }, "question": "Czy jest to elektryczna pompka do roweru?" }, - "12": { + "bike_repair_station-manometer": { "mappings": { "0": { "then": "Jest manometr" @@ -180,6 +176,10 @@ } }, "question": "Czy pompka posiada wskaźnik ciśnienia lub manometr?" + }, + "bike_repair_station-valves": { + "question": "Jakie zawory są obsługiwane?", + "render": "Ta pompka obsługuje następujące zawory: {valves}" } } }, diff --git a/langs/layers/pt_BR.json b/langs/layers/pt_BR.json index 1c8e1de2a..602d1ea85 100644 --- a/langs/layers/pt_BR.json +++ b/langs/layers/pt_BR.json @@ -8,7 +8,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Encosto: Sim" @@ -20,39 +20,7 @@ "question": "Este assento tem um escosto?", "render": "Encosto" }, - "2": { - "question": "Quantos assentos este banco tem?", - "render": "{seats} assentos" - }, - "3": { - "mappings": { - "0": { - "then": "Material: madeira" - }, - "1": { - "then": "Material: metal" - }, - "2": { - "then": "Material: pedra" - }, - "3": { - "then": "Material: concreto" - }, - "4": { - "then": "Material: plástico" - }, - "5": { - "then": "Material: aço" - } - }, - "question": "De que é feito o banco (assento)?", - "render": "Material: {material}" - }, - "4": { - "question": "Em que direção você olha quando está sentado no banco?", - "render": "Ao sentar-se no banco, olha-se para {direction} °." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Cor: marrom" @@ -82,7 +50,39 @@ "question": "Qual a cor dessa bancada?", "render": "Cor: {colour}" }, - "6": { + "bench-direction": { + "question": "Em que direção você olha quando está sentado no banco?", + "render": "Ao sentar-se no banco, olha-se para {direction} °." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Material: madeira" + }, + "1": { + "then": "Material: metal" + }, + "2": { + "then": "Material: pedra" + }, + "3": { + "then": "Material: concreto" + }, + "4": { + "then": "Material: plástico" + }, + "5": { + "then": "Material: aço" + } + }, + "question": "De que é feito o banco (assento)?", + "render": "Material: {material}" + }, + "bench-seats": { + "question": "Quantos assentos este banco tem?", + "render": "{seats} assentos" + }, + "bench-survey:date": { "question": "Quando esta bancada foi pesquisada pela última vez?", "render": "Esta bancada foi pesquisada pela última vez em {survey:date}" } @@ -94,7 +94,7 @@ "bench_at_pt": { "name": "Bancos em pontos de transporte público", "tagRenderings": { - "1": { + "bench_at_pt-name": { "render": "{name}" } }, @@ -119,23 +119,7 @@ } }, "tagRenderings": { - "1": { - "question": "Qual o nome desta biblioteca de bicicleta?", - "render": "Esta biblioteca de bicicleta é chamada de {name}" - }, - "6": { - "mappings": { - "0": { - "then": "Emprestar uma bicicleta é grátis" - }, - "1": { - "then": "Emprestar uma bicicleta custa €20/ano e €20 de garantia" - } - }, - "question": "Quanto custa um empréstimo de bicicleta?", - "render": "Custos de empréstimo de bicicleta {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Bicicletas para crianças disponíveis" @@ -148,6 +132,22 @@ } }, "question": "Quem pode emprestar bicicletas aqui?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "Emprestar uma bicicleta é grátis" + }, + "1": { + "then": "Emprestar uma bicicleta custa €20/ano e €20 de garantia" + } + }, + "question": "Quanto custa um empréstimo de bicicleta?", + "render": "Custos de empréstimo de bicicleta {charge}" + }, + "bicycle_library-name": { + "question": "Qual o nome desta biblioteca de bicicleta?", + "render": "Esta biblioteca de bicicleta é chamada de {name}" } }, "title": { @@ -162,7 +162,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Esta máquina de venda automática funciona" @@ -190,22 +190,20 @@ } }, "tagRenderings": { - "1": { + "bike_cafe-email": { + "question": "Qual o endereço de email de {name}?" + }, + "bike_cafe-name": { "question": "Qual o nome deste café de bicicleta?", "render": "Este café de bicicleta se chama {name}" }, - "3": { - "mappings": { - "0": { - "then": "Este café de bicicleta oferece ferramentas de reparo faça você mesmo" - }, - "1": { - "then": "Este café de bicicleta não oferece ferramentas de reparo faça você mesmo" - } - }, - "question": "Há ferramentas aqui para consertar sua bicicleta?" + "bike_cafe-opening_hours": { + "question": "Quando este café de bicicleta abre?" }, - "4": { + "bike_cafe-phone": { + "question": "Qual o número de telefone de {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "Este café de bicicleta conserta bicicletas" @@ -216,17 +214,19 @@ }, "question": "Este café de bicicleta conserta bicicletas?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "Este café de bicicleta oferece ferramentas de reparo faça você mesmo" + }, + "1": { + "then": "Este café de bicicleta não oferece ferramentas de reparo faça você mesmo" + } + }, + "question": "Há ferramentas aqui para consertar sua bicicleta?" + }, + "bike_cafe-website": { "question": "Qual o website de {name}?" - }, - "6": { - "question": "Qual o número de telefone de {name}?" - }, - "7": { - "question": "Qual o endereço de email de {name}?" - }, - "8": { - "question": "Quando este café de bicicleta abre?" } }, "title": { @@ -262,11 +262,58 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "Acessível ao público" + }, + "1": { + "then": "Acesso é principalmente para visitantes de uma empresa" + }, + "2": { + "then": "Acesso é limitado aos membros de uma escola, companhia ou organização" + } + }, + "question": "Quem pode usar este estacionamento de bicicletas?", + "render": "{access}" + }, + "Bicycle parking type": { "question": "Qual o tipo deste estacionamento de bicicletas?", "render": "Este é um estacionamento de bicicletas do tipo: {bicycle_parking}" }, - "2": { + "Capacity": { + "render": "Lugar para {capacity} bicicletas" + }, + "Cargo bike capacity?": { + "question": "Quantas bicicletas de carga cabem neste estacionamento de bicicletas?", + "render": "Neste estacionamento cabem {capacity:cargo_bike} bicicletas de carga" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "Este estacionamento tem vagas para bicicletas de carga" + }, + "1": { + "then": "Este estacionamento tem vagas (oficiais) projetadas para bicicletas de carga." + }, + "2": { + "then": "Você não tem permissão para estacionar bicicletas de carga" + } + }, + "question": "O estacionamento de bicicletas tem vagas para bicicletas de carga?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "Este estacionamento é coberto (tem um telhado)" + }, + "1": { + "then": "Este estacionamento não é coberto" + } + }, + "question": "Este estacionamento é coberto? Também selecione \"coberto\" para estacionamentos internos." + }, + "Underground?": { "mappings": { "0": { "then": "Estacionamento subterrâneo" @@ -285,53 +332,6 @@ } }, "question": "Qual a localização relativa deste estacionamento de bicicletas?" - }, - "3": { - "mappings": { - "0": { - "then": "Este estacionamento é coberto (tem um telhado)" - }, - "1": { - "then": "Este estacionamento não é coberto" - } - }, - "question": "Este estacionamento é coberto? Também selecione \"coberto\" para estacionamentos internos." - }, - "4": { - "render": "Lugar para {capacity} bicicletas" - }, - "5": { - "mappings": { - "0": { - "then": "Acessível ao público" - }, - "1": { - "then": "Acesso é principalmente para visitantes de uma empresa" - }, - "2": { - "then": "Acesso é limitado aos membros de uma escola, companhia ou organização" - } - }, - "question": "Quem pode usar este estacionamento de bicicletas?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "Este estacionamento tem vagas para bicicletas de carga" - }, - "1": { - "then": "Este estacionamento tem vagas (oficiais) projetadas para bicicletas de carga." - }, - "2": { - "then": "Você não tem permissão para estacionar bicicletas de carga" - } - }, - "question": "O estacionamento de bicicletas tem vagas para bicicletas de carga?" - }, - "7": { - "question": "Quantas bicicletas de carga cabem neste estacionamento de bicicletas?", - "render": "Neste estacionamento cabem {capacity:cargo_bike} bicicletas de carga" } }, "title": { @@ -350,7 +350,7 @@ } }, "tagRenderings": { - "1": { + "bike_repair_station-available-services": { "mappings": { "0": { "then": "Há somente uma bomba presente" @@ -364,21 +364,7 @@ }, "question": "Quais serviços estão disponíveis nesta estação de bicicletas?" }, - "2": { - "question": "Quem faz a manutenção desta bomba de ciclo?", - "render": "Mantida por {operator}" - }, - "5": { - "mappings": { - "0": { - "then": "Sempre aberto" - }, - "1": { - "then": "Sempre aberto" - } - } - }, - "6": { + "bike_repair_station-bike-chain-tool": { "mappings": { "0": { "then": "Há uma ferramenta de corrente" @@ -388,7 +374,7 @@ } } }, - "7": { + "bike_repair_station-bike-stand": { "mappings": { "0": { "then": "Há um gancho ou um suporte" @@ -398,7 +384,7 @@ } } }, - "11": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { "then": "Bomba manual" @@ -408,7 +394,7 @@ } } }, - "12": { + "bike_repair_station-manometer": { "mappings": { "0": { "then": "Há um manômetro" @@ -420,6 +406,20 @@ "then": "Há um manômetro mas está quebrado" } } + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Sempre aberto" + }, + "1": { + "then": "Sempre aberto" + } + } + }, + "bike_repair_station-operator": { + "question": "Quem faz a manutenção desta bomba de ciclo?", + "render": "Mantida por {operator}" } }, "title": { @@ -447,34 +447,18 @@ "description": "Uma loja que vende especificamente bicicletas ou itens relacionados", "name": "Reparo/loja de bicicletas", "tagRenderings": { - "1": { - "render": "Esta loja é especializada em vender {shop} e faz atividades relacionadas à bicicletas" - }, - "2": { - "question": "Qual o nome desta loja de bicicletas?", - "render": "Esta loja de bicicletas se chama {nome}" - }, - "3": { - "question": "Qual o website de {name}?" - }, - "4": { - "question": "Qual o número de telefone de {name}?" - }, - "5": { - "question": "Qual o endereço de email de {name}?" - }, - "9": { + "bike_repair_rents-bikes": { "mappings": { "0": { - "then": "Esta loja vende bicicletas" + "then": "Esta loja aluga bicicletas" }, "1": { - "then": "Esta loja não vende bicicletas" + "then": "Esta loja não aluga bicicletas" } }, - "question": "Esta loja vende bicicletas?" + "question": "Esta loja aluga bicicletas?" }, - "10": { + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Esta loja conserta bicicletas" @@ -491,16 +475,32 @@ }, "question": "Esta loja conserta bicicletas?" }, - "11": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "Esta loja aluga bicicletas" + "then": "Esta loja vende bicicletas" }, "1": { - "then": "Esta loja não aluga bicicletas" + "then": "Esta loja não vende bicicletas" } }, - "question": "Esta loja aluga bicicletas?" + "question": "Esta loja vende bicicletas?" + }, + "bike_shop-email": { + "question": "Qual o endereço de email de {name}?" + }, + "bike_shop-is-bicycle_shop": { + "render": "Esta loja é especializada em vender {shop} e faz atividades relacionadas à bicicletas" + }, + "bike_shop-name": { + "question": "Qual o nome desta loja de bicicletas?", + "render": "Esta loja de bicicletas se chama {nome}" + }, + "bike_shop-phone": { + "question": "Qual o número de telefone de {name}?" + }, + "bike_shop-website": { + "question": "Qual o website de {name}?" } }, "title": { diff --git a/langs/layers/ru.json b/langs/layers/ru.json index 770366020..2c6485f51 100644 --- a/langs/layers/ru.json +++ b/langs/layers/ru.json @@ -8,7 +8,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "Со спинкой" @@ -20,39 +20,7 @@ "question": "Есть ли у этой скамейки спинка?", "render": "Спинка" }, - "2": { - "question": "Сколько мест на этой скамейке?", - "render": "{seats} мест" - }, - "3": { - "mappings": { - "0": { - "then": "Материал: дерево" - }, - "1": { - "then": "Материал: металл" - }, - "2": { - "then": "Материал: камень" - }, - "3": { - "then": "Материал: бетон" - }, - "4": { - "then": "Материал: пластик" - }, - "5": { - "then": "Материал: сталь" - } - }, - "question": "Из какого материала сделана скамейка?", - "render": "Материал: {material}" - }, - "4": { - "question": "В каком направлении вы смотрите, когда сидите на скамейке?", - "render": "Сидя на скамейке, вы смотрите в сторону {direction}°." - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "Цвет: коричневый" @@ -82,7 +50,39 @@ "question": "Какого цвета скамейка?", "render": "Цвет: {colour}" }, - "6": { + "bench-direction": { + "question": "В каком направлении вы смотрите, когда сидите на скамейке?", + "render": "Сидя на скамейке, вы смотрите в сторону {direction}°." + }, + "bench-material": { + "mappings": { + "0": { + "then": "Материал: дерево" + }, + "1": { + "then": "Материал: металл" + }, + "2": { + "then": "Материал: камень" + }, + "3": { + "then": "Материал: бетон" + }, + "4": { + "then": "Материал: пластик" + }, + "5": { + "then": "Материал: сталь" + } + }, + "question": "Из какого материала сделана скамейка?", + "render": "Материал: {material}" + }, + "bench-seats": { + "question": "Сколько мест на этой скамейке?", + "render": "{seats} мест" + }, + "bench-survey:date": { "question": "Когда последний раз обследовали эту скамейку?", "render": "Последний раз обследование этой скамейки проводилось {survey:date}" } @@ -94,11 +94,11 @@ "bench_at_pt": { "name": "Скамейки на остановках общественного транспорта", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "Встаньте на скамейке" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -123,23 +123,7 @@ } }, "tagRenderings": { - "1": { - "question": "Как называется эта велосипедная библиотека?", - "render": "Эта велосипедная библиотека называется {name}" - }, - "6": { - "mappings": { - "0": { - "then": "Прокат велосипедов бесплатен" - }, - "1": { - "then": "Прокат велосипеда стоит €20/год и €20 залог" - } - }, - "question": "Сколько стоит прокат велосипеда?", - "render": "Стоимость аренды велосипеда {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "Доступны детские велосипеды" @@ -152,6 +136,22 @@ } }, "question": "Кто здесь может арендовать велосипед?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "Прокат велосипедов бесплатен" + }, + "1": { + "then": "Прокат велосипеда стоит €20/год и €20 залог" + } + }, + "question": "Сколько стоит прокат велосипеда?", + "render": "Стоимость аренды велосипеда {charge}" + }, + "bicycle_library-name": { + "question": "Как называется эта велосипедная библиотека?", + "render": "Эта велосипедная библиотека называется {name}" } }, "title": { @@ -166,7 +166,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "Этот торговый автомат работает" @@ -194,11 +194,7 @@ } }, "tagRenderings": { - "1": { - "question": "Как называется это байк-кафе?", - "render": "Это велосипедное кафе называется {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "В этом велосипедном кафе есть велосипедный насос для всеобщего использования" @@ -209,18 +205,20 @@ }, "question": "Есть ли в этом велосипедном кафе велосипедный насос для всеобщего использования?" }, - "3": { - "mappings": { - "0": { - "then": "В этом велосипедном кафе есть инструменты для починки своего велосипеда" - }, - "1": { - "then": "В этом велосипедном кафе нет инструментов для починки своего велосипеда" - } - }, - "question": "Есть ли здесь инструменты для починки вашего велосипеда?" + "bike_cafe-email": { + "question": "Какой адрес электронной почты у {name}?" }, - "4": { + "bike_cafe-name": { + "question": "Как называется это байк-кафе?", + "render": "Это велосипедное кафе называется {name}" + }, + "bike_cafe-opening_hours": { + "question": "Каков режим работы этого велосипедного кафе?" + }, + "bike_cafe-phone": { + "question": "Какой номер телефона у {name}?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "В этом велосипедном кафе есть услуги ремонта велосипедов" @@ -231,17 +229,19 @@ }, "question": "Есть ли услуги ремонта велосипедов в этом велосипедном кафе?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "В этом велосипедном кафе есть инструменты для починки своего велосипеда" + }, + "1": { + "then": "В этом велосипедном кафе нет инструментов для починки своего велосипеда" + } + }, + "question": "Есть ли здесь инструменты для починки вашего велосипеда?" + }, + "bike_cafe-website": { "question": "Какой сайт у {name}?" - }, - "6": { - "question": "Какой номер телефона у {name}?" - }, - "7": { - "question": "Какой адрес электронной почты у {name}?" - }, - "8": { - "question": "Каков режим работы этого велосипедного кафе?" } }, "title": { @@ -261,7 +261,11 @@ } }, "tagRenderings": { - "1": { + "Access": { + "question": "Кто может пользоваться этой велопарковкой?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "3": { "then": "Стойка " @@ -276,7 +280,20 @@ "question": "К какому типу относится эта велопарковка?", "render": "Это велопарковка типа {bicycle_parking}" }, - "2": { + "Capacity": { + "render": "Место для {capacity} велосипеда(ов)" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "Это крытая парковка (есть крыша/навес)" + }, + "1": { + "then": "Это открытая парковка" + } + } + }, + "Underground?": { "mappings": { "0": { "then": "Подземная парковка" @@ -288,23 +305,6 @@ "then": "Парковка на крыше" } } - }, - "3": { - "mappings": { - "0": { - "then": "Это крытая парковка (есть крыша/навес)" - }, - "1": { - "then": "Это открытая парковка" - } - } - }, - "4": { - "render": "Место для {capacity} велосипеда(ов)" - }, - "5": { - "question": "Кто может пользоваться этой велопарковкой?", - "render": "{access}" } }, "title": { @@ -321,15 +321,7 @@ } }, "tagRenderings": { - "5": { - "mappings": { - "0": { - "then": "Всегда открыто" - } - }, - "question": "Когда работает эта точка обслуживания велосипедов?" - }, - "8": { + "Operational status": { "mappings": { "0": { "then": "Велосипедный насос сломан" @@ -340,18 +332,7 @@ }, "question": "Велосипедный насос все еще работает?" }, - "10": { - "mappings": { - "0": { - "then": "Клапан Presta (также известный как французский клапан)" - }, - "1": { - "then": "Клапан Dunlop" - } - }, - "render": "Этот насос поддерживает следующие клапаны: {valves}" - }, - "11": { + "bike_repair_station-electrical_pump": { "mappings": { "0": { "then": "Ручной насос" @@ -362,7 +343,7 @@ }, "question": "Это электрический велосипедный насос?" }, - "12": { + "bike_repair_station-manometer": { "mappings": { "0": { "then": "Есть манометр" @@ -374,6 +355,25 @@ "then": "Есть манометр, но он сломан" } } + }, + "bike_repair_station-opening_hours": { + "mappings": { + "0": { + "then": "Всегда открыто" + } + }, + "question": "Когда работает эта точка обслуживания велосипедов?" + }, + "bike_repair_station-valves": { + "mappings": { + "0": { + "then": "Клапан Presta (также известный как французский клапан)" + }, + "1": { + "then": "Клапан Dunlop" + } + }, + "render": "Этот насос поддерживает следующие клапаны: {valves}" } }, "title": { @@ -399,31 +399,40 @@ } }, "tagRenderings": { - "2": { - "question": "Как называется магазин велосипедов?", - "render": "Этот магазин велосипедов называется {name}" - }, - "3": { - "question": "Какой сайт у {name}?" - }, - "4": { - "question": "Какой номер телефона у {name}?" - }, - "5": { - "question": "Какой адрес электронной почты у {name}?" - }, - "9": { + "bike_repair_bike-pump-service": { "mappings": { "0": { - "then": "В этом магазине продаются велосипеды" + "then": "В этом магазине есть велосипедный насос для всеобщего пользования" }, "1": { - "then": "В этом магазине не продают велосипеды" + "then": "В этом магазине нет велосипедного насоса для всеобщего пользования" } }, - "question": "Продаются ли велосипеды в этом магазине?" + "question": "Предлагается ли в этом магазине велосипедный насос для всеобщего пользования?" }, - "10": { + "bike_repair_bike-wash": { + "mappings": { + "0": { + "then": "В этом магазине оказываются услуги мойки/чистки велосипедов" + }, + "2": { + "then": "В этом магазине нет услуг мойки/чистки велосипедов" + } + }, + "question": "Здесь моют велосипеды?" + }, + "bike_repair_rents-bikes": { + "mappings": { + "0": { + "then": "Этот магазин сдает велосипеды в аренду" + }, + "1": { + "then": "Этот магазин не сдает велосипеды напрокат" + } + }, + "question": "Этот магазин сдает велосипеды в аренду?" + }, + "bike_repair_repairs-bikes": { "mappings": { "0": { "then": "Этот магазин ремонтирует велосипеды" @@ -440,18 +449,7 @@ }, "question": "В этом магазине ремонтируют велосипеды?" }, - "11": { - "mappings": { - "0": { - "then": "Этот магазин сдает велосипеды в аренду" - }, - "1": { - "then": "Этот магазин не сдает велосипеды напрокат" - } - }, - "question": "Этот магазин сдает велосипеды в аренду?" - }, - "12": { + "bike_repair_second-hand-bikes": { "mappings": { "0": { "then": "В этом магазине продаются подержанные велосипеды" @@ -465,18 +463,18 @@ }, "question": "В этом магазине продаются подержанные велосипеды?" }, - "13": { + "bike_repair_sells-bikes": { "mappings": { "0": { - "then": "В этом магазине есть велосипедный насос для всеобщего пользования" + "then": "В этом магазине продаются велосипеды" }, "1": { - "then": "В этом магазине нет велосипедного насоса для всеобщего пользования" + "then": "В этом магазине не продают велосипеды" } }, - "question": "Предлагается ли в этом магазине велосипедный насос для всеобщего пользования?" + "question": "Продаются ли велосипеды в этом магазине?" }, - "14": { + "bike_repair_tools-service": { "mappings": { "2": { "then": "Инструменты для починки доступны только при покупке/аренде велосипеда в магазине" @@ -484,16 +482,18 @@ }, "question": "Есть ли здесь инструменты для починки собственного велосипеда?" }, - "15": { - "mappings": { - "0": { - "then": "В этом магазине оказываются услуги мойки/чистки велосипедов" - }, - "2": { - "then": "В этом магазине нет услуг мойки/чистки велосипедов" - } - }, - "question": "Здесь моют велосипеды?" + "bike_shop-email": { + "question": "Какой адрес электронной почты у {name}?" + }, + "bike_shop-name": { + "question": "Как называется магазин велосипедов?", + "render": "Этот магазин велосипедов называется {name}" + }, + "bike_shop-phone": { + "question": "Какой номер телефона у {name}?" + }, + "bike_shop-website": { + "question": "Какой сайт у {name}?" } }, "title": { @@ -518,12 +518,12 @@ "description": "Зарядная станция", "name": "Зарядные станции", "tagRenderings": { - "57": { - "question": "В какое время работает эта зарядная станция?" - }, - "58": { + "Auth phone": { "question": "К какой сети относится эта станция?", "render": "{network}" + }, + "Authentication": { + "question": "В какое время работает эта зарядная станция?" } }, "title": { @@ -545,7 +545,7 @@ } }, "tagRenderings": { - "2": { + "defibrillator-access": { "mappings": { "0": { "then": "Общедоступный" @@ -558,29 +558,29 @@ } } }, - "3": { + "defibrillator-defibrillator": { "mappings": { "1": { "then": "Это обычный автоматический дефибриллятор" } } }, - "12": { + "defibrillator-description": { + "render": "Дополнительная информация: {description}" + }, + "defibrillator-fixme": { + "render": "Дополнительная информация для экспертов OpenStreetMap: {fixme}" + }, + "defibrillator-opening_hours": { "question": "В какое время доступен этот дефибриллятор?", "render": "{opening_hours_table(opening_hours)}" }, - "13": { - "render": "Дополнительная информация: {description}" - }, - "14": { + "defibrillator-survey:date": { "mappings": { "0": { "then": "Проверено сегодня!" } } - }, - "15": { - "render": "Дополнительная информация для экспертов OpenStreetMap: {fixme}" } }, "title": { @@ -603,7 +603,7 @@ }, "food": { "tagRenderings": { - "17": { + "friture-take-your-container": { "mappings": { "1": { "then": "Приносить свою тару не разрешено" @@ -615,16 +615,16 @@ "ghost_bike": { "name": "Велосипед Ghost", "tagRenderings": { - "2": { - "render": "В знак памяти о {name}" - }, - "3": { - "render": "Доступна более подробная информация" - }, - "4": { + "ghost_bike-inscription": { "render": "{inscription}" }, - "5": { + "ghost_bike-name": { + "render": "В знак памяти о {name}" + }, + "ghost_bike-source": { + "render": "Доступна более подробная информация" + }, + "ghost_bike-start_date": { "render": "Установлен {start_date}" } }, @@ -651,7 +651,7 @@ } }, "tagRenderings": { - "1": { + "map-map_source": { "mappings": { "0": { "then": "Эта карта основана на OpenStreetMap" @@ -666,10 +666,10 @@ }, "nature_reserve": { "tagRenderings": { - "8": { + "Email": { "render": "{email}" }, - "9": { + "phone": { "render": "{phone}" } } @@ -683,7 +683,7 @@ } }, "tagRenderings": { - "0": { + "picnic_table-material": { "mappings": { "0": { "then": "Это деревянный стол для пикника" @@ -709,7 +709,66 @@ } }, "tagRenderings": { - "1": { + "Playground-wheelchair": { + "mappings": { + "0": { + "then": "Полностью доступна пользователям кресел-колясок" + }, + "1": { + "then": "Частично доступна пользователям кресел-колясок" + }, + "2": { + "then": "Недоступна пользователям кресел-колясок" + } + }, + "question": "Доступна ли детская площадка пользователям кресел-колясок?" + }, + "playground-access": { + "mappings": { + "4": { + "then": "Недоступно" + } + } + }, + "playground-email": { + "render": "{email}" + }, + "playground-lit": { + "mappings": { + "0": { + "then": "Эта детская площадка освещается ночью" + }, + "1": { + "then": "Эта детская площадка не освещается ночью" + } + }, + "question": "Эта игровая площадка освещается ночью?" + }, + "playground-max_age": { + "render": "Доступно детям до {max_age}" + }, + "playground-min_age": { + "question": "С какого возраста доступна эта детская площадка?", + "render": "Доступно для детей старше {min_age} лет" + }, + "playground-opening_hours": { + "mappings": { + "0": { + "then": "Открыто от рассвета до заката" + }, + "1": { + "then": "Всегда доступен" + }, + "2": { + "then": "Всегда доступен" + } + }, + "question": "Когда открыта эта игровая площадка?" + }, + "playground-phone": { + "render": "{phone}" + }, + "playground-surface": { "mappings": { "0": { "then": "Поверхность - трава" @@ -731,65 +790,6 @@ } }, "render": "Поверхность - {surface}" - }, - "2": { - "mappings": { - "0": { - "then": "Эта детская площадка освещается ночью" - }, - "1": { - "then": "Эта детская площадка не освещается ночью" - } - }, - "question": "Эта игровая площадка освещается ночью?" - }, - "3": { - "question": "С какого возраста доступна эта детская площадка?", - "render": "Доступно для детей старше {min_age} лет" - }, - "4": { - "render": "Доступно детям до {max_age}" - }, - "6": { - "mappings": { - "4": { - "then": "Недоступно" - } - } - }, - "7": { - "render": "{email}" - }, - "8": { - "render": "{phone}" - }, - "9": { - "mappings": { - "0": { - "then": "Полностью доступна пользователям кресел-колясок" - }, - "1": { - "then": "Частично доступна пользователям кресел-колясок" - }, - "2": { - "then": "Недоступна пользователям кресел-колясок" - } - }, - "question": "Доступна ли детская площадка пользователям кресел-колясок?" - }, - "10": { - "mappings": { - "0": { - "then": "Открыто от рассвета до заката" - }, - "1": { - "then": "Всегда доступен" - }, - "2": { - "then": "Всегда доступен" - } - }, - "question": "Когда открыта эта игровая площадка?" } }, "title": { @@ -810,20 +810,7 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "У этого книжного шкафа нет названия" - } - }, - "question": "Как называется этот общественный книжный шкаф?", - "render": "Название книжного шкафа — {name}" - }, - "3": { - "question": "Сколько книг помещается в этом общественном книжном шкафу?", - "render": "{capacity} книг помещается в этот книжный шкаф" - }, - "4": { + "bookcase-booktypes": { "mappings": { "0": { "then": "В основном детские книги" @@ -837,7 +824,7 @@ }, "question": "Какие книги можно найти в этом общественном книжном шкафу?" }, - "6": { + "bookcase-is-accessible": { "mappings": { "0": { "then": "Свободный доступ" @@ -845,11 +832,24 @@ }, "question": "Имеется ли свободный доступ к этому общественному книжному шкафу?" }, - "10": { + "public_bookcase-capacity": { + "question": "Сколько книг помещается в этом общественном книжном шкафу?", + "render": "{capacity} книг помещается в этот книжный шкаф" + }, + "public_bookcase-name": { + "mappings": { + "0": { + "then": "У этого книжного шкафа нет названия" + } + }, + "question": "Как называется этот общественный книжный шкаф?", + "render": "Название книжного шкафа — {name}" + }, + "public_bookcase-start_date": { "question": "Когда был установлен этот общественный книжный шкаф?", "render": "Установлен {start_date}" }, - "11": { + "public_bookcase-website": { "question": "Есть ли веб-сайт с более подробной информацией об этом общественном книжном шкафе?", "render": "Более подробная информация на сайте" } @@ -865,7 +865,7 @@ }, "slow_roads": { "tagRenderings": { - "2": { + "slow_roads-surface": { "mappings": { "0": { "then": "Поверхность - трава" @@ -902,7 +902,43 @@ } }, "tagRenderings": { - "1": { + "sport-pitch-access": { + "mappings": { + "0": { + "then": "Свободный доступ" + }, + "1": { + "then": "Ограниченный доступ (напр., только по записи, в определённые часы, ...)" + }, + "2": { + "then": "Доступ только членам клуба" + } + }, + "question": "Есть ли свободный доступ к этой спортивной площадке?" + }, + "sport-pitch-reservation": { + "mappings": { + "1": { + "then": "Желательна предварительная запись для доступа на эту спортивную площадку" + }, + "2": { + "then": "Предварительная запись для доступа на эту спортивную площадку возможна, но не обязательна" + }, + "3": { + "then": "Невозможна предварительная запись" + } + }, + "question": "Нужна ли предварительная запись для доступа на эту спортивную площадку?" + }, + "sport_pitch-opening_hours": { + "mappings": { + "1": { + "then": "Всегда доступен" + } + }, + "question": "В какое время доступна эта площадка?" + }, + "sport_pitch-sport": { "mappings": { "0": { "then": "Здесь можно играть в баскетбол" @@ -924,7 +960,7 @@ } } }, - "2": { + "sport_pitch-surface": { "mappings": { "0": { "then": "Поверхность - трава" @@ -944,42 +980,6 @@ }, "question": "Какое покрытие на этой спортивной площадке?", "render": "Поверхность - {surface}" - }, - "3": { - "mappings": { - "0": { - "then": "Свободный доступ" - }, - "1": { - "then": "Ограниченный доступ (напр., только по записи, в определённые часы, ...)" - }, - "2": { - "then": "Доступ только членам клуба" - } - }, - "question": "Есть ли свободный доступ к этой спортивной площадке?" - }, - "4": { - "mappings": { - "1": { - "then": "Желательна предварительная запись для доступа на эту спортивную площадку" - }, - "2": { - "then": "Предварительная запись для доступа на эту спортивную площадку возможна, но не обязательна" - }, - "3": { - "then": "Невозможна предварительная запись" - } - }, - "question": "Нужна ли предварительная запись для доступа на эту спортивную площадку?" - }, - "7": { - "mappings": { - "1": { - "then": "Всегда доступен" - } - }, - "question": "В какое время доступна эта площадка?" } }, "title": { @@ -989,7 +989,7 @@ "surveillance_camera": { "name": "Камеры наблюдения", "tagRenderings": { - "1": { + "Camera type: fixed; panning; dome": { "mappings": { "1": { "then": "Камера с поворотным механизмом" @@ -1000,7 +1000,7 @@ }, "question": "Какая это камера?" }, - "5": { + "Indoor camera? This isn't clear for 'public'-cameras": { "mappings": { "1": { "then": "Эта камера расположена снаружи" @@ -1010,7 +1010,7 @@ } } }, - "8": { + "camera:mount": { "question": "Как расположена эта камера?" } }, @@ -1030,7 +1030,7 @@ } }, "tagRenderings": { - "1": { + "toilet-access": { "mappings": { "0": { "then": "Свободный доступ" @@ -1044,26 +1044,26 @@ }, "question": "Есть ли свободный доступ к этим туалетам?" }, - "2": { + "toilet-charge": { + "question": "Сколько стоит посещение туалета?", + "render": "Стоимость {charge}" + }, + "toilets-fee": { "mappings": { "0": { "then": "Это платные туалеты" } } }, - "3": { - "question": "Сколько стоит посещение туалета?", - "render": "Стоимость {charge}" + "toilets-type": { + "question": "Какие это туалеты?" }, - "4": { + "toilets-wheelchair": { "mappings": { "1": { "then": "Недоступно пользователям кресел-колясок" } } - }, - "5": { - "question": "Какие это туалеты?" } }, "title": { @@ -1086,15 +1086,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Высота: {height} м" - } - }, - "render": "Высота: {height}" - }, - "4": { + "tree-decidouous": { "mappings": { "0": { "then": "Листопадное: у дерева опадают листья в определённое время года." @@ -1105,7 +1097,15 @@ }, "question": "Это дерево вечнозелёное или листопадное?" }, - "5": { + "tree-height": { + "mappings": { + "0": { + "then": "Высота: {height} м" + } + }, + "render": "Высота: {height}" + }, + "tree_node-name": { "mappings": { "0": { "then": "У этого дерева нет названия." @@ -1114,10 +1114,10 @@ "question": "Есть ли у этого дерева название?", "render": "Название: {name}" }, - "7": { + "tree_node-ref:OnroerendErfgoed": { "render": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}" }, - "8": { + "tree_node-wikidata": { "render": "\"\"/ Wikidata: {wikidata}" } }, @@ -1138,7 +1138,7 @@ } }, "tagRenderings": { - "1": { + "viewpoint-description": { "question": "Вы хотите добавить описание?" } }, diff --git a/langs/layers/zh_Hans.json b/langs/layers/zh_Hans.json index de1601cf5..90b74fe66 100644 --- a/langs/layers/zh_Hans.json +++ b/langs/layers/zh_Hans.json @@ -8,7 +8,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "靠背:有" @@ -20,38 +20,7 @@ "question": "这个长椅有靠背吗?", "render": "靠背" }, - "2": { - "question": "这个长椅有几个座位?" - }, - "3": { - "mappings": { - "0": { - "then": "材质:木" - }, - "1": { - "then": "材质:金属" - }, - "2": { - "then": "材质:石头" - }, - "3": { - "then": "材质:混凝土" - }, - "4": { - "then": "材质:塑料" - }, - "5": { - "then": "材质:不锈钢" - } - }, - "question": "这个长椅(或座椅)是用什么材料做的?", - "render": "材质: {material}" - }, - "4": { - "question": "坐在长椅上的时候你目视的方向是哪边?", - "render": "坐在长椅上的时候目视方向为 {direction}°方位。" - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "颜色:棕" @@ -81,7 +50,38 @@ "question": "这个长椅是什么颜色的?", "render": "颜色: {colour}" }, - "6": { + "bench-direction": { + "question": "坐在长椅上的时候你目视的方向是哪边?", + "render": "坐在长椅上的时候目视方向为 {direction}°方位。" + }, + "bench-material": { + "mappings": { + "0": { + "then": "材质:木" + }, + "1": { + "then": "材质:金属" + }, + "2": { + "then": "材质:石头" + }, + "3": { + "then": "材质:混凝土" + }, + "4": { + "then": "材质:塑料" + }, + "5": { + "then": "材质:不锈钢" + } + }, + "question": "这个长椅(或座椅)是用什么材料做的?", + "render": "材质: {material}" + }, + "bench-seats": { + "question": "这个长椅有几个座位?" + }, + "bench-survey:date": { "question": "上次对这个长椅实地调查是什么时候?", "render": "这个长椅于 {survey:date}最后一次实地调查" } @@ -93,11 +93,11 @@ "bench_at_pt": { "name": "在公交站点的长椅", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "站立长凳" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -114,14 +114,14 @@ }, "bicycle_library": { "tagRenderings": { - "7": { + "bicycle-library-target-group": { "question": "谁可以从这里借自行车?" } } }, "bicycle_tube_vending_machine": { "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "这个借还机正常工作" @@ -144,11 +144,7 @@ } }, "tagRenderings": { - "1": { - "question": "这个自行车咖啡的名字是什么?", - "render": "这家自行车咖啡叫做 {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "这家自行车咖啡为每个人提供打气筒" @@ -159,18 +155,20 @@ }, "question": "这家自行车咖啡为每个使用者提供打气筒吗?" }, - "3": { - "mappings": { - "0": { - "then": "这家自行车咖啡为DIY修理者提供工具" - }, - "1": { - "then": "这家自行车咖啡不为DIY修理者提供工具" - } - }, - "question": "这里有供你修车用的工具吗?" + "bike_cafe-email": { + "question": "{name}的电子邮箱是什么?" }, - "4": { + "bike_cafe-name": { + "question": "这个自行车咖啡的名字是什么?", + "render": "这家自行车咖啡叫做 {name}" + }, + "bike_cafe-opening_hours": { + "question": "这家自行车咖啡什么时候开门营业?" + }, + "bike_cafe-phone": { + "question": "{name}的电话号码是什么?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "这家自行车咖啡可以修车" @@ -181,17 +179,19 @@ }, "question": "这家自行车咖啡t提供修车服务吗?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "这家自行车咖啡为DIY修理者提供工具" + }, + "1": { + "then": "这家自行车咖啡不为DIY修理者提供工具" + } + }, + "question": "这里有供你修车用的工具吗?" + }, + "bike_cafe-website": { "question": "{name}的网站是什么?" - }, - "6": { - "question": "{name}的电话号码是什么?" - }, - "7": { - "question": "{name}的电子邮箱是什么?" - }, - "8": { - "question": "这家自行车咖啡什么时候开门营业?" } }, "title": { diff --git a/langs/layers/zh_Hant.json b/langs/layers/zh_Hant.json index 7591ee2dd..994ecb486 100644 --- a/langs/layers/zh_Hant.json +++ b/langs/layers/zh_Hant.json @@ -8,7 +8,7 @@ } }, "tagRenderings": { - "1": { + "bench-backrest": { "mappings": { "0": { "then": "靠背:有" @@ -20,39 +20,7 @@ "question": "這個長椅是否有靠背?", "render": "靠背" }, - "2": { - "question": "這個長椅有幾個位子?", - "render": "{seats} 座位數" - }, - "3": { - "mappings": { - "0": { - "then": "材質:木頭" - }, - "1": { - "then": "材質:金屬" - }, - "2": { - "then": "材質:石頭" - }, - "3": { - "then": "材質:水泥" - }, - "4": { - "then": "材質:塑膠" - }, - "5": { - "then": "材質:鋼鐵" - } - }, - "question": "這個長椅 (座位) 是什麼做的?", - "render": "材質:{material}" - }, - "4": { - "question": "坐在長椅時是面對那個方向?", - "render": "當坐在長椅時,那個人朝向 {direction}°。" - }, - "5": { + "bench-colour": { "mappings": { "0": { "then": "顏色:棕色" @@ -82,7 +50,39 @@ "question": "這個長椅是什麼顏色的?", "render": "顏色:{colour}" }, - "6": { + "bench-direction": { + "question": "坐在長椅時是面對那個方向?", + "render": "當坐在長椅時,那個人朝向 {direction}°。" + }, + "bench-material": { + "mappings": { + "0": { + "then": "材質:木頭" + }, + "1": { + "then": "材質:金屬" + }, + "2": { + "then": "材質:石頭" + }, + "3": { + "then": "材質:水泥" + }, + "4": { + "then": "材質:塑膠" + }, + "5": { + "then": "材質:鋼鐵" + } + }, + "question": "這個長椅 (座位) 是什麼做的?", + "render": "材質:{material}" + }, + "bench-seats": { + "question": "這個長椅有幾個位子?", + "render": "{seats} 座位數" + }, + "bench-survey:date": { "question": "上一次探察長椅是什麼時候?", "render": "這個長椅最後是在 {survey:date} 探查的" } @@ -94,11 +94,11 @@ "bench_at_pt": { "name": "大眾運輸站點的長椅", "tagRenderings": { - "1": { - "render": "{name}" - }, - "2": { + "bench_at_pt-bench": { "render": "站立長椅" + }, + "bench_at_pt-name": { + "render": "{name}" } }, "title": { @@ -123,23 +123,7 @@ } }, "tagRenderings": { - "1": { - "question": "這個單車圖書館的名稱是?", - "render": "這個單車圖書館叫做 {name}" - }, - "6": { - "mappings": { - "0": { - "then": "租借單車免費" - }, - "1": { - "then": "租借單車價錢 €20/year 與 €20 保證金" - } - }, - "question": "租用單車的費用多少?", - "render": "租借單車需要 {charge}" - }, - "7": { + "bicycle-library-target-group": { "mappings": { "0": { "then": "提供兒童單車" @@ -152,6 +136,22 @@ } }, "question": "誰可以在這裡租單車?" + }, + "bicycle_library-charge": { + "mappings": { + "0": { + "then": "租借單車免費" + }, + "1": { + "then": "租借單車價錢 €20/year 與 €20 保證金" + } + }, + "question": "租用單車的費用多少?", + "render": "租借單車需要 {charge}" + }, + "bicycle_library-name": { + "question": "這個單車圖書館的名稱是?", + "render": "這個單車圖書館叫做 {name}" } }, "title": { @@ -166,7 +166,7 @@ } }, "tagRenderings": { - "1": { + "Still in use?": { "mappings": { "0": { "then": "這個自動販賣機仍運作" @@ -194,11 +194,7 @@ } }, "tagRenderings": { - "1": { - "question": "這個單車咖啡廳的名稱是?", - "render": "這個單車咖啡廳叫做 {name}" - }, - "2": { + "bike_cafe-bike-pump": { "mappings": { "0": { "then": "這個單車咖啡廳有提供給任何人都能使用的單車打氣甬" @@ -209,18 +205,20 @@ }, "question": "這個單車咖啡廳有提供給任何人都能使用的單車打氣甬嗎?" }, - "3": { - "mappings": { - "0": { - "then": "這個單車咖啡廳提供工具讓你修理" - }, - "1": { - "then": "這個單車咖啡廳並沒有提供工具讓你修理" - } - }, - "question": "這裡是否有工具修理你的單車嗎?" + "bike_cafe-email": { + "question": "{name} 的電子郵件地址是?" }, - "4": { + "bike_cafe-name": { + "question": "這個單車咖啡廳的名稱是?", + "render": "這個單車咖啡廳叫做 {name}" + }, + "bike_cafe-opening_hours": { + "question": "何時這個單車咖啡廳營運?" + }, + "bike_cafe-phone": { + "question": "{name} 的電話號碼是?" + }, + "bike_cafe-repair-service": { "mappings": { "0": { "then": "這個單車咖啡廳修理單車" @@ -231,17 +229,19 @@ }, "question": "這個單車咖啡廳是否能修理單車?" }, - "5": { + "bike_cafe-repair-tools": { + "mappings": { + "0": { + "then": "這個單車咖啡廳提供工具讓你修理" + }, + "1": { + "then": "這個單車咖啡廳並沒有提供工具讓你修理" + } + }, + "question": "這裡是否有工具修理你的單車嗎?" + }, + "bike_cafe-website": { "question": "{name} 的網站是?" - }, - "6": { - "question": "{name} 的電話號碼是?" - }, - "7": { - "question": "{name} 的電子郵件地址是?" - }, - "8": { - "question": "何時這個單車咖啡廳營運?" } }, "title": { @@ -277,7 +277,22 @@ } }, "tagRenderings": { - "1": { + "Access": { + "mappings": { + "0": { + "then": "公開可用" + }, + "1": { + "then": "通行性主要是為了企業的顧客" + }, + "2": { + "then": "通行性僅限學校、公司或組織的成員" + } + }, + "question": "誰可以使用這個單車停車場?", + "render": "{access}" + }, + "Bicycle parking type": { "mappings": { "0": { "then": "單車架 " @@ -307,7 +322,33 @@ "question": "這是那種類型的單車停車場?", "render": "這個單車停車場的類型是:{bicycle_parking}" }, - "2": { + "Capacity": { + "question": "這個單車停車場能放幾台單車 (包括裝箱單車)?", + "render": "{capacity} 單車的地方" + }, + "Cargo bike spaces?": { + "mappings": { + "0": { + "then": "這個停車場有地方可以放裝箱單車" + }, + "1": { + "then": "這停車場有設計 (官方) 空間給裝箱的單車。" + } + }, + "question": "這個單車停車場有地方放裝箱的單車嗎?" + }, + "Is covered?": { + "mappings": { + "0": { + "then": "這個停車場有遮蔽 (有屋頂)" + }, + "1": { + "then": "這個停車場沒有遮蔽" + } + }, + "question": "這個停車場是否有車棚?如果是室內停車場也請選擇\"遮蔽\"。" + }, + "Underground?": { "mappings": { "0": { "then": "地下停車場" @@ -326,47 +367,6 @@ } }, "question": "這個單車停車場的相對位置是?" - }, - "3": { - "mappings": { - "0": { - "then": "這個停車場有遮蔽 (有屋頂)" - }, - "1": { - "then": "這個停車場沒有遮蔽" - } - }, - "question": "這個停車場是否有車棚?如果是室內停車場也請選擇\"遮蔽\"。" - }, - "4": { - "question": "這個單車停車場能放幾台單車 (包括裝箱單車)?", - "render": "{capacity} 單車的地方" - }, - "5": { - "mappings": { - "0": { - "then": "公開可用" - }, - "1": { - "then": "通行性主要是為了企業的顧客" - }, - "2": { - "then": "通行性僅限學校、公司或組織的成員" - } - }, - "question": "誰可以使用這個單車停車場?", - "render": "{access}" - }, - "6": { - "mappings": { - "0": { - "then": "這個停車場有地方可以放裝箱單車" - }, - "1": { - "then": "這停車場有設計 (官方) 空間給裝箱的單車。" - } - }, - "question": "這個單車停車場有地方放裝箱的單車嗎?" } }, "title": { @@ -377,12 +377,12 @@ "description": "充電站", "name": "充電站", "tagRenderings": { - "57": { - "question": "何時是充電站開放使用的時間?" - }, - "58": { + "Auth phone": { "question": "充電站所屬的網路是?", "render": "{network}" + }, + "Authentication": { + "question": "何時是充電站開放使用的時間?" } }, "title": { diff --git a/langs/layers/zh_Hanå¨s.json b/langs/layers/zh_Hanå¨s.json index 8a25d1e17..0efb21822 100644 --- a/langs/layers/zh_Hanå¨s.json +++ b/langs/layers/zh_Hanå¨s.json @@ -1,7 +1,7 @@ { "bench": { "tagRenderings": { - "3": { + "bench-material": { "render": "材质: {material}" } } diff --git a/langs/themes/ca.json b/langs/themes/ca.json index 6832bb590..a6cd62432 100644 --- a/langs/themes/ca.json +++ b/langs/themes/ca.json @@ -5,37 +5,37 @@ }, "climbing": { "layers": { - "0": { + "climbing": { "tagRenderings": { - "0": { + "name": { "render": "{name}" } } }, - "1": { + "climbing_club": { "tagRenderings": { - "3": { + "climbing_club-name": { "render": "{name}" } } }, - "2": { + "climbing_gym": { "tagRenderings": { - "3": { + "name": { "render": "{name}" } } }, - "3": { + "climbing_route": { "tagRenderings": { - "6": { + "Name": { "render": "{name}" } } }, - "4": { + "maybe_climbing": { "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" } } @@ -48,12 +48,12 @@ }, "shops": { "layers": { - "0": { + "shops": { "tagRenderings": { - "3": { + "shops-phone": { "render": "{phone}" }, - "4": { + "shops-website": { "render": "{website}" } } diff --git a/langs/themes/de.json b/langs/themes/de.json index 934363b63..f2a9971f4 100644 --- a/langs/themes/de.json +++ b/langs/themes/de.json @@ -6,7 +6,7 @@ "artwork": { "description": "Willkommen bei der Freien Kunstwerk-Karte, einer Karte von Statuen, Büsten, Grafitti, ... auf der ganzen Welt", "layers": { - "0": { + "artwork": { "description": "Verschiedene Kunstwerke", "name": "Kunstwerke", "presets": { @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Welcher Künstler hat das geschaffen?", + "render": "Erstellt von {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Architektur" @@ -57,15 +61,11 @@ "question": "Was ist die Art dieses Kunstwerks?", "render": "Dies ist ein {artwork_type}" }, - "2": { - "question": "Welcher Künstler hat das geschaffen?", - "render": "Erstellt von {artist_name}" - }, - "3": { + "artwork-website": { "question": "Gibt es eine Website mit weiteren Informationen über dieses Kunstwerk?", "render": "Weitere Informationen auf dieser Webseite" }, - "4": { + "artwork-wikidata": { "question": "Welcher Wikidata-Eintrag entspricht diesem Kunstwerk?", "render": "Entspricht {wikidata}" } @@ -98,81 +98,7 @@ "description": "Auf dieser Karte finden Sie verschiedene Klettermöglichkeiten wie Kletterhallen, Boulderhallen und Felsen in der Natur.", "descriptionTail": "

kletterspots.de wird betrieben von Christian Neumann. Bitte melden Sie sich, wenn Sie Feedback oder Fragen haben.

Das Projekt nutzt Daten des OpenStreetMap Projekts und basiert auf der freien Software MapComplete.

", "layers": { - "0": { - "description": "Ein Kletterverein oder eine Organisation", - "name": "Kletterverein", - "presets": { - "0": { - "description": "Ein Kletterverein", - "title": "Kletterverein" - }, - "1": { - "description": "Eine Organisation, welche sich mit dem Klettern beschäftigt", - "title": "Eine Kletter-Organisation" - } - }, - "tagRenderings": { - "0": { - "question": "Wie lautet der Name dieses Vereins oder Organisation?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Kletter-Organisation" - } - }, - "render": "Kletterverein" - } - }, - "1": { - "description": "Eine Kletterhalle", - "name": "Kletterhallen", - "tagRenderings": { - "3": { - "question": "Wie heißt diese Kletterhalle?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Kletterhalle {name}" - } - }, - "render": "Kletterhalle" - } - }, - "2": { - "name": "Kletterrouten", - "tagRenderings": { - "3": { - "mappings": { - "0": { - "then": "Diese Kletterroute hat keinen Namen" - } - }, - "question": "Wie heißt diese Kletterroute?", - "render": "{name}" - }, - "4": { - "render": "Diese Route ist {canonical(climbing:length)} lang" - }, - "5": { - "render": "Die Schwierigkeit ist {climbing:grade:french} entsprechend des französisch/belgischen Systems" - } - }, - "title": { - "mappings": { - "0": { - "then": "Kleterroute {name}" - } - }, - "render": "Kleterroute" - } - }, - "3": { + "climbing": { "description": "Eine Klettergelegenheit", "name": "Klettermöglichkeiten", "presets": { @@ -182,7 +108,7 @@ } }, "tagRenderings": { - "6": { + "name": { "mappings": { "0": { "then": "Diese Klettergelegenheit hat keinen Namen" @@ -196,14 +122,88 @@ "render": "Klettermöglichkeit" } }, - "4": { + "climbing_club": { + "description": "Ein Kletterverein oder eine Organisation", + "name": "Kletterverein", + "presets": { + "0": { + "description": "Ein Kletterverein", + "title": "Kletterverein" + }, + "1": { + "description": "Eine Organisation, welche sich mit dem Klettern beschäftigt", + "title": "Eine Kletter-Organisation" + } + }, + "tagRenderings": { + "climbing_club-name": { + "question": "Wie lautet der Name dieses Vereins oder Organisation?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Kletter-Organisation" + } + }, + "render": "Kletterverein" + } + }, + "climbing_gym": { + "description": "Eine Kletterhalle", + "name": "Kletterhallen", + "tagRenderings": { + "name": { + "question": "Wie heißt diese Kletterhalle?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Kletterhalle {name}" + } + }, + "render": "Kletterhalle" + } + }, + "climbing_route": { + "name": "Kletterrouten", + "tagRenderings": { + "Difficulty": { + "render": "Die Schwierigkeit ist {climbing:grade:french} entsprechend des französisch/belgischen Systems" + }, + "Length": { + "render": "Diese Route ist {canonical(climbing:length)} lang" + }, + "Name": { + "mappings": { + "0": { + "then": "Diese Kletterroute hat keinen Namen" + } + }, + "question": "Wie heißt diese Kletterroute?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Kleterroute {name}" + } + }, + "render": "Kleterroute" + } + }, + "maybe_climbing": { "description": "Eine Klettergelegenheit?", "name": "Klettermöglichkeiten?", "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" }, - "2": { + "climbing-possible": { "mappings": { "0": { "then": "Hier kann nicht geklettert werden" diff --git a/langs/themes/en.json b/langs/themes/en.json index b1e565d3a..c1477e31f 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -6,7 +6,7 @@ "artwork": { "description": "Welcome to Open Artwork Map, a map of statues, busts, grafittis and other artwork all over the world", "layers": { - "0": { + "artwork": { "description": "Diverse pieces of artwork", "name": "Artworks", "presets": { @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Which artist created this?", + "render": "Created by {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Architecture" @@ -57,15 +61,11 @@ "question": "What is the type of this artwork?", "render": "This is a {artwork_type}" }, - "2": { - "question": "Which artist created this?", - "render": "Created by {artist_name}" - }, - "3": { + "artwork-website": { "question": "Is there a website with more information about this artwork?", "render": "More information on this website" }, - "4": { + "artwork-wikidata": { "question": "Which Wikidata-entry corresponds with this artwork?", "render": "Corresponds with {wikidata}" } @@ -106,7 +106,7 @@ "campersite": { "description": "This site collects all official camper stopover places and places where you can dump grey and black water. You can add details about the services provided and the cost. Add pictures and reviews. This is a website and a webapp. The data is stored in OpenStreetMap, so it will be free forever and can be re-used by any app.", "layers": { - "0": { + "caravansites": { "description": "camper sites", "name": "Camper sites", "presets": { @@ -116,11 +116,19 @@ } }, "tagRenderings": { - "1": { - "question": "What is this place called?", - "render": "This place is called {name}" + "caravansites-capacity": { + "question": "How many campers can stay here? (skip if there is no obvious number of spaces or allowed vehicles)", + "render": "{capacity} campers can use this place at the same time" }, - "2": { + "caravansites-charge": { + "question": "How much does this place charge?", + "render": "This place charges {charge}" + }, + "caravansites-description": { + "question": "Would you like to add a general description of this place? (Do not repeat information previously asked or shown above. Please keep it objective - opinions go into the reviews)", + "render": "More details about this place: {description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "You need to pay for use" @@ -131,26 +139,7 @@ }, "question": "Does this place charge a fee?" }, - "3": { - "question": "How much does this place charge?", - "render": "This place charges {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "This place has a sanitary dump station" - }, - "1": { - "then": "This place does not have a sanitary dump station" - } - }, - "question": "Does this place have a sanitary dump station?" - }, - "5": { - "question": "How many campers can stay here? (skip if there is no obvious number of spaces or allowed vehicles)", - "render": "{capacity} campers can use this place at the same time" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "There is internet access" @@ -164,7 +153,7 @@ }, "question": "Does this place provide internet access?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "You need to pay extra for internet access" @@ -175,22 +164,7 @@ }, "question": "Do you have to pay for the internet access?" }, - "8": { - "mappings": { - "0": { - "then": "This place has toilets" - }, - "1": { - "then": "This place does not have toilets" - } - }, - "question": "Does this place have toilets?" - }, - "9": { - "question": "Does this place have a website?", - "render": "Official website: {website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "Yes, there are some spots for long term rental, but you can also stay on a daily basis" @@ -204,9 +178,35 @@ }, "question": "Does this place offer spots for long term rental?" }, - "11": { - "question": "Would you like to add a general description of this place? (Do not repeat information previously asked or shown above. Please keep it objective - opinions go into the reviews)", - "render": "More details about this place: {description}" + "caravansites-name": { + "question": "What is this place called?", + "render": "This place is called {name}" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "This place has a sanitary dump station" + }, + "1": { + "then": "This place does not have a sanitary dump station" + } + }, + "question": "Does this place have a sanitary dump station?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "This place has toilets" + }, + "1": { + "then": "This place does not have toilets" + } + }, + "question": "Does this place have toilets?" + }, + "caravansites-website": { + "question": "Does this place have a website?", + "render": "Official website: {website}" } }, "title": { @@ -218,7 +218,7 @@ "render": "Camper site {name}" } }, - "1": { + "dumpstations": { "description": "Sanitary dump stations", "name": "Sanitary dump stations", "presets": { @@ -228,55 +228,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "You need to pay for use" - }, - "1": { - "then": "Can be used for free" - } - }, - "question": "Does this place charge a fee?" - }, - "2": { - "question": "How much does this place charge?", - "render": "This place charges {charge}" - }, - "3": { - "mappings": { - "0": { - "then": "This place has a water point" - }, - "1": { - "then": "This place does not have a water point" - } - }, - "question": "Does this place have a water point?" - }, - "4": { - "mappings": { - "0": { - "then": "You can dispose of grey water here" - }, - "1": { - "then": "You cannot dispose of gray water here" - } - }, - "question": "Can you dispose of grey water here?" - }, - "5": { - "mappings": { - "0": { - "then": "You can dispose of chemical toilet waste here" - }, - "1": { - "then": "You cannot dispose of chemical toilet waste here" - } - }, - "question": "Can you dispose of chemical toilet waste here?" - }, - "6": { + "dumpstations-access": { "mappings": { "0": { "then": "You need a network key/code to use this" @@ -293,9 +245,57 @@ }, "question": "Who can use this dump station?" }, - "7": { + "dumpstations-charge": { + "question": "How much does this place charge?", + "render": "This place charges {charge}" + }, + "dumpstations-chemical-waste": { + "mappings": { + "0": { + "then": "You can dispose of chemical toilet waste here" + }, + "1": { + "then": "You cannot dispose of chemical toilet waste here" + } + }, + "question": "Can you dispose of chemical toilet waste here?" + }, + "dumpstations-fee": { + "mappings": { + "0": { + "then": "You need to pay for use" + }, + "1": { + "then": "Can be used for free" + } + }, + "question": "Does this place charge a fee?" + }, + "dumpstations-grey-water": { + "mappings": { + "0": { + "then": "You can dispose of grey water here" + }, + "1": { + "then": "You cannot dispose of gray water here" + } + }, + "question": "Can you dispose of grey water here?" + }, + "dumpstations-network": { "question": "What network is this place a part of? (skip if none)", "render": "This station is part of network {network}" + }, + "dumpstations-waterpoint": { + "mappings": { + "0": { + "then": "This place has a water point" + }, + "1": { + "then": "This place does not have a water point" + } + }, + "question": "Does this place have a water point?" } }, "title": { @@ -337,103 +337,7 @@ "description": "On this map you will find various climbing opportunities such as climbing gyms, bouldering halls and rocks in nature.", "descriptionTail": "The climbing map was originally made by Christian Neumann. Please get in touch if you have feedback or questions.

The project uses data of the OpenStreetMap project.

", "layers": { - "0": { - "description": "A climbing club or organisations", - "name": "Climbing club", - "presets": { - "0": { - "description": "A climbing club", - "title": "Climbing club" - }, - "1": { - "description": "A NGO working around climbing", - "title": "Climbing NGO" - } - }, - "tagRenderings": { - "0": { - "question": "What is the name of this climbing club or NGO?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Climbing NGO" - } - }, - "render": "Climbing club" - } - }, - "1": { - "description": "A climbing gym", - "name": "Climbing gyms", - "tagRenderings": { - "3": { - "question": "What is the name of this climbing gym?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Climbing gym {name}" - } - }, - "render": "Climbing gym" - } - }, - "2": { - "name": "Climbing routes", - "presets": { - "0": { - "title": "Climbing route" - } - }, - "tagRenderings": { - "3": { - "mappings": { - "0": { - "then": "This climbing route doesn't have a name" - } - }, - "question": "What is the name of this climbing route?", - "render": "{name}" - }, - "4": { - "question": "How long is this climbing route (in meters)?", - "render": "This route is {canonical(climbing:length)} long" - }, - "5": { - "question": "What is the difficulty of this climbing route according to the french/belgian system?", - "render": "The difficulty is {climbing:grade:french} according to the french/belgian system" - }, - "6": { - "mappings": { - "0": { - "then": "This route is not bolted" - }, - "1": { - "then": "This route is not bolted" - } - }, - "question": "How much bolts does this route have before reaching the moulinette?", - "render": "This route has {climbing:bolts} bolts" - }, - "8": { - "render": "The rock type is {_embedding_features_with_rock:rock} as stated on the surrounding crag" - } - }, - "title": { - "mappings": { - "0": { - "then": "Climbing route {name}" - } - }, - "render": "Climbing route" - } - }, - "3": { + "climbing": { "description": "A climbing opportunity", "name": "Climbing opportunities", "presets": { @@ -443,25 +347,25 @@ } }, "tagRenderings": { - "3": { - "render": "

Length overview

{histogram(_length_hist)}" - }, - "4": { - "render": "

Difficulties overview

{histogram(_difficulty_hist)}" - }, - "5": { + "Containe {_contained_climbing_routes_count} routes": { "render": "

Contains {_contained_climbing_routes_count} routes

    {_contained_climbing_routes}
" }, - "6": { + "Contained routes hist": { + "render": "

Difficulties overview

{histogram(_difficulty_hist)}" + }, + "Contained routes length hist": { + "render": "

Length overview

{histogram(_length_hist)}" + }, + "Rock type (crag/rock/cliff only)": { "mappings": { "0": { - "then": "This climbing opportunity doesn't have a name" + "then": "Limestone" } }, - "question": "What is the name of this climbing opportunity?", - "render": "{name}" + "question": "What is the rock type here?", + "render": "The rock type is {rock}" }, - "7": { + "Type": { "mappings": { "0": { "then": "A climbing boulder - a single rock or cliff with one or a few climbing routes which can be climbed safely without rope" @@ -471,14 +375,14 @@ } } }, - "8": { + "name": { "mappings": { "0": { - "then": "Limestone" + "then": "This climbing opportunity doesn't have a name" } }, - "question": "What is the rock type here?", - "render": "The rock type is {rock}" + "question": "What is the name of this climbing opportunity?", + "render": "{name}" } }, "title": { @@ -499,14 +403,110 @@ "render": "Climbing opportunity" } }, - "4": { + "climbing_club": { + "description": "A climbing club or organisations", + "name": "Climbing club", + "presets": { + "0": { + "description": "A climbing club", + "title": "Climbing club" + }, + "1": { + "description": "A NGO working around climbing", + "title": "Climbing NGO" + } + }, + "tagRenderings": { + "climbing_club-name": { + "question": "What is the name of this climbing club or NGO?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Climbing NGO" + } + }, + "render": "Climbing club" + } + }, + "climbing_gym": { + "description": "A climbing gym", + "name": "Climbing gyms", + "tagRenderings": { + "name": { + "question": "What is the name of this climbing gym?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Climbing gym {name}" + } + }, + "render": "Climbing gym" + } + }, + "climbing_route": { + "name": "Climbing routes", + "presets": { + "0": { + "title": "Climbing route" + } + }, + "tagRenderings": { + "Bolts": { + "mappings": { + "0": { + "then": "This route is not bolted" + }, + "1": { + "then": "This route is not bolted" + } + }, + "question": "How much bolts does this route have before reaching the moulinette?", + "render": "This route has {climbing:bolts} bolts" + }, + "Difficulty": { + "question": "What is the difficulty of this climbing route according to the french/belgian system?", + "render": "The difficulty is {climbing:grade:french} according to the french/belgian system" + }, + "Length": { + "question": "How long is this climbing route (in meters)?", + "render": "This route is {canonical(climbing:length)} long" + }, + "Name": { + "mappings": { + "0": { + "then": "This climbing route doesn't have a name" + } + }, + "question": "What is the name of this climbing route?", + "render": "{name}" + }, + "Rock type": { + "render": "The rock type is {_embedding_features_with_rock:rock} as stated on the surrounding crag" + } + }, + "title": { + "mappings": { + "0": { + "then": "Climbing route {name}" + } + }, + "render": "Climbing route" + } + }, + "maybe_climbing": { "description": "A climbing opportunity?", "name": "Climbing opportunities?", "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" }, - "2": { + "climbing-possible": { "mappings": { "0": { "then": "Climbing is not possible here" @@ -668,7 +668,7 @@ "cycle_highways": { "description": "This map shows cycle highways", "layers": { - "0": { + "cycle_highways": { "name": "cycle highways", "title": { "render": "cycle highway" @@ -685,11 +685,18 @@ "cyclestreets": { "description": "A cyclestreet is is a street where motorized traffic is not allowed to overtake cyclists. They are signposted by a special traffic sign. Cyclestreets can be found in the Netherlands and Belgium, but also in Germany and France. ", "layers": { - "0": { + "all_streets": { + "description": "Layer to mark any street as cyclestreet", + "name": "All streets", + "title": { + "render": "Street" + } + }, + "fietsstraat": { "description": "A cyclestreet is a street where motorized traffic is not allowed to overtake a cyclist", "name": "Cyclestreets" }, - "1": { + "toekomstige_fietsstraat": { "description": "This street will become a cyclestreet soon", "name": "Future cyclestreet", "title": { @@ -700,13 +707,6 @@ }, "render": "Future cyclestreet" } - }, - "2": { - "description": "Layer to mark any street as cyclestreet", - "name": "All streets", - "title": { - "render": "Street" - } } }, "roamingRenderings": { @@ -746,7 +746,7 @@ "facadegardens": { "description": "Facade gardens, green facades and trees in the city not only bring peace and quiet, but also a more beautiful city, greater biodiversity, a cooling effect and better air quality.
Klimaan VZW and Mechelen Klimaatneutraal want to map existing and new facade gardens as an example for people who want to build their own garden or for city walkers who love nature.
More info about the project at klimaan.be.", "layers": { - "0": { + "facadegardens": { "description": "Facade gardens", "name": "Facade gardens", "presets": { @@ -756,40 +756,15 @@ } }, "tagRenderings": { - "1": { + "facadegardens-description": { + "question": "Extra describing info about the garden (if needed and not yet described above)", + "render": "More details: {description}" + }, + "facadegardens-direction": { "question": "What is the orientation of the garden?", "render": "Orientation: {direction} (where 0=N and 90=O)" }, - "2": { - "mappings": { - "0": { - "then": "The garden is in full sun" - }, - "1": { - "then": "The garden is in partial shade" - }, - "2": { - "then": "The garden is in the shade" - } - }, - "question": "Is the garden shaded or sunny?" - }, - "3": { - "mappings": { - "0": { - "then": "There is a rain barrel" - }, - "1": { - "then": "There is no rain barrel" - } - }, - "question": "Is there a water barrel installed for the garden?" - }, - "4": { - "question": "When was the garden constructed? (a year is sufficient)", - "render": "Construction date of the garden: {start_date}" - }, - "5": { + "facadegardens-edible": { "mappings": { "0": { "then": "There are edible plants" @@ -800,7 +775,7 @@ }, "question": "Are there any edible plants?" }, - "6": { + "facadegardens-plants": { "mappings": { "0": { "then": "There are vines" @@ -817,9 +792,34 @@ }, "question": "What kinds of plants grow here?" }, - "7": { - "question": "Extra describing info about the garden (if needed and not yet described above)", - "render": "More details: {description}" + "facadegardens-rainbarrel": { + "mappings": { + "0": { + "then": "There is a rain barrel" + }, + "1": { + "then": "There is no rain barrel" + } + }, + "question": "Is there a water barrel installed for the garden?" + }, + "facadegardens-start_date": { + "question": "When was the garden constructed? (a year is sufficient)", + "render": "Construction date of the garden: {start_date}" + }, + "facadegardens-sunshine": { + "mappings": { + "0": { + "then": "The garden is in full sun" + }, + "1": { + "then": "The garden is in partial shade" + }, + "2": { + "then": "The garden is in the shade" + } + }, + "question": "Is the garden shaded or sunny?" } }, "title": { @@ -836,7 +836,7 @@ "fritures": { "layers": { "0": { - "override": { + "friture": { "name": "Fries shop" } } @@ -849,7 +849,7 @@ "hackerspaces": { "description": "On this map you can see hackerspaces, add a new hackerspace or update data directly", "layers": { - "0": { + "hackerspaces": { "description": "Hackerspace", "icon": { "mappings": { @@ -870,22 +870,11 @@ } }, "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "This is a makerspace" - }, - "1": { - "then": "This is a traditional (software oriented) hackerspace" - } - }, - "question": "Is this a hackerspace or a makerspace?" - }, - "1": { + "hackerspaces-name": { "question": "What is the name of this hackerspace?", "render": "This hackerspace is named {name}" }, - "5": { + "hackerspaces-opening_hours": { "mappings": { "0": { "then": "Opened 24/7" @@ -894,7 +883,11 @@ "question": "When is this hackerspace opened?", "render": "{opening_hours_table()}" }, - "7": { + "hackerspaces-start_date": { + "question": "When was this hackerspace founded?", + "render": "This hackerspace was founded at {start_date}" + }, + "hs-club-mate": { "mappings": { "0": { "then": "This hackerspace serves club mate" @@ -905,9 +898,16 @@ }, "question": "Does this hackerspace serve Club Mate?" }, - "8": { - "question": "When was this hackerspace founded?", - "render": "This hackerspace was founded at {start_date}" + "is_makerspace": { + "mappings": { + "0": { + "then": "This is a makerspace" + }, + "1": { + "then": "This is a traditional (software oriented) hackerspace" + } + }, + "question": "Is this a hackerspace or a makerspace?" } }, "title": { @@ -926,7 +926,137 @@ "hailhydrant": { "description": "On this map you can find and update hydrants, fire stations, ambulance stations, and extinguishers in your favorite neighborhoods. \n\nYou can track your precise location (mobile only) and select layers that are relevant for you in the bottom left corner. You can also use this tool to add or edit pins (points of interest) to the map and provide additional details by answering available questions. \n\nAll changes you make will automatically be saved in the global database of OpenStreetMap and can be freely re-used by others.", "layers": { - "0": { + "ambulancestation": { + "description": "An ambulance station is an area for storage of ambulance vehicles, medical equipment, personal protective equipment, and other medical supplies.", + "name": "Map of ambulance stations", + "presets": { + "0": { + "description": "Add an ambulance station to the map", + "title": "Ambulance station" + } + }, + "tagRenderings": { + "ambulance-agency": { + "question": "What agency operates this station?", + "render": "This station is operated by {operator}." + }, + "ambulance-name": { + "question": "What is the name of this ambulance station?", + "render": "This station is called {name}." + }, + "ambulance-operator-type": { + "mappings": { + "0": { + "then": "The station is operated by the government." + }, + "1": { + "then": "The station is operated by a community-based, or informal organization." + }, + "2": { + "then": "The station is operated by a formal group of volunteers." + }, + "3": { + "then": "The station is privately operated." + } + }, + "question": "How is the station operator classified?", + "render": "The operator is a(n) {operator:type} entity." + }, + "ambulance-place": { + "question": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", + "render": "This station is found within {addr:place}." + }, + "ambulance-street": { + "question": " What is the street name where the station located?", + "render": "This station is along a highway called {addr:street}." + } + }, + "title": { + "render": "Ambulance Station" + } + }, + "extinguisher": { + "description": "Map layer to show fire hydrants.", + "name": "Map of fire extinguishers.", + "presets": { + "0": { + "description": "A fire extinguisher is a small, portable device used to stop a fire", + "title": "Fire extinguisher" + } + }, + "tagRenderings": { + "extinguisher-location": { + "mappings": { + "0": { + "then": "Found indoors." + }, + "1": { + "then": "Found outdoors." + } + }, + "question": "Where is it positioned?", + "render": "Location: {location}" + } + }, + "title": { + "render": "Extinguishers" + } + }, + "fire_stations": { + "description": "Map layer to show fire stations.", + "name": "Map of fire stations", + "presets": { + "0": { + "description": "A fire station is a place where the fire trucks and firefighters are located when not in operation.", + "title": "Fire station" + } + }, + "tagRenderings": { + "station-agency": { + "mappings": { + "0": { + "then": "Bureau of Fire Protection" + } + }, + "question": "What agency operates this station?", + "render": "This station is operated by {operator}." + }, + "station-name": { + "question": "What is the name of this fire station?", + "render": "This station is called {name}." + }, + "station-operator": { + "mappings": { + "0": { + "then": "The station is operated by the government." + }, + "1": { + "then": "The station is operated by a community-based, or informal organization." + }, + "2": { + "then": "The station is operated by a formal group of volunteers." + }, + "3": { + "then": "The station is privately operated." + } + }, + "question": "How is the station operator classified?", + "render": "The operator is a(n) {operator:type} entity." + }, + "station-place": { + "question": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", + "render": "This station is found within {addr:place}." + }, + "station-street": { + "question": " What is the street name where the station located?", + "render": "This station is along a highway called {addr:street}." + } + }, + "title": { + "render": "Fire Station" + } + }, + "hydrants": { "description": "Map layer to show fire hydrants.", "name": "Map of hydrants", "presets": { @@ -936,7 +1066,7 @@ } }, "tagRenderings": { - "0": { + "hydrant-color": { "mappings": { "0": { "then": "The hydrant color is unknown." @@ -951,7 +1081,22 @@ "question": "What color is the hydrant?", "render": "The hydrant color is {colour}" }, - "1": { + "hydrant-state": { + "mappings": { + "0": { + "then": "The hydrant is (fully or partially) working." + }, + "1": { + "then": "The hydrant is unavailable." + }, + "2": { + "then": "The hydrant has been removed." + } + }, + "question": "Update the lifecycle status of the hydrant.", + "render": "Lifecycle status" + }, + "hydrant-type": { "mappings": { "0": { "then": "The hydrant type is unknown." @@ -971,156 +1116,11 @@ }, "question": "What type of hydrant is it?", "render": " Hydrant type: {fire_hydrant:type}" - }, - "2": { - "mappings": { - "0": { - "then": "The hydrant is (fully or partially) working." - }, - "1": { - "then": "The hydrant is unavailable." - }, - "2": { - "then": "The hydrant has been removed." - } - }, - "question": "Update the lifecycle status of the hydrant.", - "render": "Lifecycle status" } }, "title": { "render": "Hydrant" } - }, - "1": { - "description": "Map layer to show fire hydrants.", - "name": "Map of fire extinguishers.", - "presets": { - "0": { - "description": "A fire extinguisher is a small, portable device used to stop a fire", - "title": "Fire extinguisher" - } - }, - "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "Found indoors." - }, - "1": { - "then": "Found outdoors." - } - }, - "question": "Where is it positioned?", - "render": "Location: {location}" - } - }, - "title": { - "render": "Extinguishers" - } - }, - "2": { - "description": "Map layer to show fire stations.", - "name": "Map of fire stations", - "presets": { - "0": { - "description": "A fire station is a place where the fire trucks and firefighters are located when not in operation.", - "title": "Fire station" - } - }, - "tagRenderings": { - "0": { - "question": "What is the name of this fire station?", - "render": "This station is called {name}." - }, - "1": { - "question": " What is the street name where the station located?", - "render": "This station is along a highway called {addr:street}." - }, - "2": { - "question": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", - "render": "This station is found within {addr:place}." - }, - "3": { - "mappings": { - "0": { - "then": "Bureau of Fire Protection" - } - }, - "question": "What agency operates this station?", - "render": "This station is operated by {operator}." - }, - "4": { - "mappings": { - "0": { - "then": "The station is operated by the government." - }, - "1": { - "then": "The station is operated by a community-based, or informal organization." - }, - "2": { - "then": "The station is operated by a formal group of volunteers." - }, - "3": { - "then": "The station is privately operated." - } - }, - "question": "How is the station operator classified?", - "render": "The operator is a(n) {operator:type} entity." - } - }, - "title": { - "render": "Fire Station" - } - }, - "3": { - "description": "An ambulance station is an area for storage of ambulance vehicles, medical equipment, personal protective equipment, and other medical supplies.", - "name": "Map of ambulance stations", - "presets": { - "0": { - "description": "Add an ambulance station to the map", - "title": "Ambulance station" - } - }, - "tagRenderings": { - "0": { - "question": "What is the name of this ambulance station?", - "render": "This station is called {name}." - }, - "1": { - "question": " What is the street name where the station located?", - "render": "This station is along a highway called {addr:street}." - }, - "2": { - "question": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", - "render": "This station is found within {addr:place}." - }, - "3": { - "question": "What agency operates this station?", - "render": "This station is operated by {operator}." - }, - "4": { - "mappings": { - "0": { - "then": "The station is operated by the government." - }, - "1": { - "then": "The station is operated by a community-based, or informal organization." - }, - "2": { - "then": "The station is operated by a formal group of volunteers." - }, - "3": { - "then": "The station is privately operated." - } - }, - "question": "How is the station operator classified?", - "render": "The operator is a(n) {operator:type} entity." - } - }, - "title": { - "render": "Ambulance Station" - } } }, "shortDescription": "Map to show hydrants, extinguishers, fire stations, and ambulance stations.", @@ -1144,7 +1144,7 @@ "openwindpowermap": { "description": "A map for showing and editing wind turbines.", "layers": { - "0": { + "windturbine": { "name": "wind turbine", "presets": { "0": { @@ -1152,23 +1152,23 @@ } }, "tagRenderings": { - "0": { - "question": "What is the power output of this wind turbine? (e.g. 2.3 MW)", - "render": "The power output of this wind turbine is {generator:output:electricity}." - }, - "1": { - "question": "Who operates this wind turbine?", - "render": "This wind turbine is operated by {operator}." - }, - "2": { - "question": "What is the total height of this wind turbine (including rotor radius), in metres?", - "render": "The total height (including rotor radius) of this wind turbine is {height} metres." - }, - "3": { + "turbine-diameter": { "question": "What is the rotor diameter of this wind turbine, in metres?", "render": "The rotor diameter of this wind turbine is {rotor:diameter} metres." }, - "4": { + "turbine-height": { + "question": "What is the total height of this wind turbine (including rotor radius), in metres?", + "render": "The total height (including rotor radius) of this wind turbine is {height} metres." + }, + "turbine-operator": { + "question": "Who operates this wind turbine?", + "render": "This wind turbine is operated by {operator}." + }, + "turbine-output": { + "question": "What is the power output of this wind turbine? (e.g. 2.3 MW)", + "render": "The power output of this wind turbine is {generator:output:electricity}." + }, + "turbine-start-date": { "question": "When did this wind turbine go into operation?", "render": "This wind turbine went into operation on/in {start_date}." } @@ -1227,7 +1227,7 @@ "shops": { "description": "On this map, one can mark basic information about shops, add opening hours and phone numbers", "layers": { - "0": { + "shops": { "description": "A shop", "name": "Shop", "presets": { @@ -1237,10 +1237,22 @@ } }, "tagRenderings": { - "1": { + "shops-email": { + "question": "What is the email address of this shop?", + "render": "{email}" + }, + "shops-name": { "question": "What is the name of this shop?" }, - "2": { + "shops-opening_hours": { + "question": "What are the opening hours of this shop?", + "render": "{opening_hours_table(opening_hours)}" + }, + "shops-phone": { + "question": "What is the phone number?", + "render": "{phone}" + }, + "shops-shop": { "mappings": { "0": { "then": "Convenience store" @@ -1267,21 +1279,9 @@ "question": "What does this shop sell?", "render": "This shop sells {shop}" }, - "3": { - "question": "What is the phone number?", - "render": "{phone}" - }, - "4": { + "shops-website": { "question": "What is the website of this shop?", "render": "{website}" - }, - "5": { - "question": "What is the email address of this shop?", - "render": "{email}" - }, - "6": { - "question": "What are the opening hours of this shop?", - "render": "{opening_hours_table(opening_hours)}" } }, "title": { diff --git a/langs/themes/es.json b/langs/themes/es.json index 158b8b000..3b31ed8c4 100644 --- a/langs/themes/es.json +++ b/langs/themes/es.json @@ -6,7 +6,7 @@ "artwork": { "description": "Bienvenido a Open Artwork Map, un mapa de estatuas, bustos, grafitis y otras obras de arte de todo el mundo", "layers": { - "0": { + "artwork": { "description": "Diversas piezas de obras de arte", "name": "Obras de arte", "presets": { @@ -15,7 +15,7 @@ } }, "tagRenderings": { - "1": { + "artwork-artwork_type": { "question": "Cuál es el tipo de esta obra de arte?", "render": "Esta es un {artwork_type}" } diff --git a/langs/themes/fr.json b/langs/themes/fr.json index c30ac520b..83ab9d4ce 100644 --- a/langs/themes/fr.json +++ b/langs/themes/fr.json @@ -6,7 +6,7 @@ "artwork": { "description": "Bienvenue sur la carte ouverte des œuvres d'art, une carte des statues, fresques, ... du monde entier", "layers": { - "0": { + "artwork": { "description": "Diverses œuvres d'art", "name": "Œuvres d'art", "presets": { @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Quel artiste a créé cette œuvre ?", + "render": "Créé par {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Architecture" @@ -57,15 +61,11 @@ "question": "Quel est le type de cette œuvre d'art?", "render": "Type d'œuvre : {artwork_type}" }, - "2": { - "question": "Quel artiste a créé cette œuvre ?", - "render": "Créé par {artist_name}" - }, - "3": { + "artwork-website": { "question": "Existe-t-il un site web où trouver plus d'informations sur cette œuvre d'art ?", "render": "Plus d'info sûr ce site web" }, - "4": { + "artwork-wikidata": { "question": "Quelle entrée Wikidata correspond à cette œuvre d'art ?", "render": "Correspond à {wikidata}" } @@ -98,7 +98,7 @@ "campersite": { "description": "Ce site collecte les zones de camping officielles ainsi que les aires de vidange. Il est possible d’ajouter des détails à propos des services proposés ainsi que leurs coûts. Ajoutez vos images et avis. C’est un site et une application. Les données sont stockées sur OpenStreetMap, elles seront toujours gratuites et peuvent être réutilisées par n’importe quelle application.", "layers": { - "0": { + "caravansites": { "description": "campings", "name": "Campings", "presets": { @@ -108,11 +108,19 @@ } }, "tagRenderings": { - "1": { - "question": "Comment s'appelle cet endroit ?", - "render": "Cet endroit s'appelle {nom}" + "caravansites-capacity": { + "question": "Combien de personnes peuvent camper ici ? (Passez s’il n’y a pas de places délimitées)", + "render": "{capacity} personnes peuvent utiliser cet espace en même temps" }, - "2": { + "caravansites-charge": { + "question": "Combien coûte cet endroit ?", + "render": "Ce site fait payer {charge}" + }, + "caravansites-description": { + "question": "Souhaitez-vous ajouter une description générale du lieu ? (Ne pas répéter les informations précédentes et rester neutre, les opinions vont dans les avis)", + "render": "Plus de détails à propos du site : {description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "L’utilisation est payante" @@ -123,26 +131,7 @@ }, "question": "Cet endroit est-il payant ?" }, - "3": { - "question": "Combien coûte cet endroit ?", - "render": "Ce site fait payer {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "Cet endroit a une station de vidange sanitaire" - }, - "1": { - "then": "Ce site ne possède pas de lieu de vidange" - } - }, - "question": "Ce site possède-t’il un lieu de vidange ?" - }, - "5": { - "question": "Combien de personnes peuvent camper ici ? (Passez s’il n’y a pas de places délimitées)", - "render": "{capacity} personnes peuvent utiliser cet espace en même temps" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "Il y a un accès internet" @@ -156,7 +145,7 @@ }, "question": "Cet endroit offre-t-il un accès à Internet ?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "L’accès internet est en supplément" @@ -167,22 +156,7 @@ }, "question": "L’accès internet est-il payant ?" }, - "8": { - "mappings": { - "0": { - "then": "Ce site a des toilettes" - }, - "1": { - "then": "Ce site n’a pas de toilettes" - } - }, - "question": "Y-a-t’il des toilettes sur le site ?" - }, - "9": { - "question": "Ce lieu a-t’il un site internet ?", - "render": "Site officiel : {website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "Oui, mais il est possible d’y passer seulement une nuit" @@ -196,9 +170,35 @@ }, "question": "Ce site permet-il la location longue durée ?" }, - "11": { - "question": "Souhaitez-vous ajouter une description générale du lieu ? (Ne pas répéter les informations précédentes et rester neutre, les opinions vont dans les avis)", - "render": "Plus de détails à propos du site : {description}" + "caravansites-name": { + "question": "Comment s'appelle cet endroit ?", + "render": "Cet endroit s'appelle {nom}" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "Cet endroit a une station de vidange sanitaire" + }, + "1": { + "then": "Ce site ne possède pas de lieu de vidange" + } + }, + "question": "Ce site possède-t’il un lieu de vidange ?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "Ce site a des toilettes" + }, + "1": { + "then": "Ce site n’a pas de toilettes" + } + }, + "question": "Y-a-t’il des toilettes sur le site ?" + }, + "caravansites-website": { + "question": "Ce lieu a-t’il un site internet ?", + "render": "Site officiel : {website}" } }, "title": { @@ -210,7 +210,7 @@ "render": "Camping {name}" } }, - "1": { + "dumpstations": { "description": "Site de vidange", "name": "Site de vidange", "presets": { @@ -220,55 +220,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "Ce site demande un paiement" - }, - "1": { - "then": "Ce site ne demande pas de paiement" - } - }, - "question": "Ce site est-il payant ?" - }, - "2": { - "question": "Combien ce site demande t’il de payer ?", - "render": "Ce site fait payer {charge}" - }, - "3": { - "mappings": { - "0": { - "then": "Ce site a un point d’eau" - }, - "1": { - "then": "Ce site n’a pas de point d’eau" - } - }, - "question": "Ce site dispose-t’il d’un point d’eau ?" - }, - "4": { - "mappings": { - "0": { - "then": "Il est possible d’y vidanger ses eaux usées" - }, - "1": { - "then": "Il n’est pas possible d’y vidanger ses eaux usées" - } - }, - "question": "Est-il possible d’y faire sa vidange des eaux usées ?" - }, - "5": { - "mappings": { - "0": { - "then": "Il est possible d’y vidanger ses toilettes chimiques" - }, - "1": { - "then": "Il n’est pas possible d’y vidanger ses toilettes chimiques" - } - }, - "question": "Est-il possible d’y vidanger ses toilettes chimiques ?" - }, - "6": { + "dumpstations-access": { "mappings": { "0": { "then": "Un code est nécessaire" @@ -285,9 +237,57 @@ }, "question": "Qui peut utiliser le site de vidange ?" }, - "7": { + "dumpstations-charge": { + "question": "Combien ce site demande t’il de payer ?", + "render": "Ce site fait payer {charge}" + }, + "dumpstations-chemical-waste": { + "mappings": { + "0": { + "then": "Il est possible d’y vidanger ses toilettes chimiques" + }, + "1": { + "then": "Il n’est pas possible d’y vidanger ses toilettes chimiques" + } + }, + "question": "Est-il possible d’y vidanger ses toilettes chimiques ?" + }, + "dumpstations-fee": { + "mappings": { + "0": { + "then": "Ce site demande un paiement" + }, + "1": { + "then": "Ce site ne demande pas de paiement" + } + }, + "question": "Ce site est-il payant ?" + }, + "dumpstations-grey-water": { + "mappings": { + "0": { + "then": "Il est possible d’y vidanger ses eaux usées" + }, + "1": { + "then": "Il n’est pas possible d’y vidanger ses eaux usées" + } + }, + "question": "Est-il possible d’y faire sa vidange des eaux usées ?" + }, + "dumpstations-network": { "question": "De quel réseau fait-elle partie ? (Passer si aucun)", "render": "Cette station fait parte d’un réseau {network}" + }, + "dumpstations-waterpoint": { + "mappings": { + "0": { + "then": "Ce site a un point d’eau" + }, + "1": { + "then": "Ce site n’a pas de point d’eau" + } + }, + "question": "Ce site dispose-t’il d’un point d’eau ?" } }, "title": { @@ -324,103 +324,7 @@ "description": "Cette carte indique les sites d’escalades comme les salles d’escalade ou les sites naturels.", "descriptionTail": "La carte a été créée par Christian Neumann. Merci de le contacter pour des avis ou des questions.

Ce projet utilise les données OpenStreetMap.

", "layers": { - "0": { - "description": "Club ou association d’escalade", - "name": "Club d’escalade", - "presets": { - "0": { - "description": "Un club d’escalade", - "title": "Club d’escalade" - }, - "1": { - "description": "Une association d’escalade", - "title": "Association d’escalade" - } - }, - "tagRenderings": { - "0": { - "question": "Quel est le nom du club ou de l’association ?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Association d’escalade" - } - }, - "render": "Club d’escalade" - } - }, - "1": { - "description": "Une salle d’escalade", - "name": "Salle d’escalade", - "tagRenderings": { - "3": { - "question": "Quel est le nom de la salle d’escalade ?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Salle d’escalade {name}" - } - }, - "render": "Salle d’escalade" - } - }, - "2": { - "name": "Voies d’escalade", - "presets": { - "0": { - "title": "Voie d’escalade" - } - }, - "tagRenderings": { - "3": { - "mappings": { - "0": { - "then": "Cette voie n’a pas de nom" - } - }, - "question": "Quel est le nom de cette voie d’escalade ?", - "render": "{name}" - }, - "4": { - "question": "Quelle est la longueur de cette voie (en mètres) ?", - "render": "Cette voie fait {canonical(climbing:length)} de long" - }, - "5": { - "question": "Quelle est la difficulté de cette voie selon le système franco-belge ?", - "render": "Selon le système franco-belge, la difficulté de cette voie est de {climbing:grade:french}" - }, - "6": { - "mappings": { - "0": { - "then": "Cette voie n’a pas de prises" - }, - "1": { - "then": "Cette voie n’a pas de prises" - } - }, - "question": "Combien de prises cette voie possède avant d’atteindre la moulinette ?", - "render": "Cette voie a {climbing:bolts} prises" - }, - "8": { - "render": "Le type de roche est {_embedding_features_with_rock:rock} selon le mur" - } - }, - "title": { - "mappings": { - "0": { - "then": "Voie d’escalade {name}" - } - }, - "render": "Voie d’escalade" - } - }, - "3": { + "climbing": { "description": "Opportunité d’escalade", "name": "Opportunité d’escalade", "presets": { @@ -430,25 +334,25 @@ } }, "tagRenderings": { - "3": { - "render": "

Résumé de longueur

{histogram(_length_hist)}" - }, - "4": { - "render": "

Résumé des difficultés

{histogram(_difficulty_hist)}" - }, - "5": { + "Containe {_contained_climbing_routes_count} routes": { "render": "

Contient {_contained_climbing_routes_count} voies

    {_contained_climbing_routes}
" }, - "6": { + "Contained routes hist": { + "render": "

Résumé des difficultés

{histogram(_difficulty_hist)}" + }, + "Contained routes length hist": { + "render": "

Résumé de longueur

{histogram(_length_hist)}" + }, + "Rock type (crag/rock/cliff only)": { "mappings": { "0": { - "then": "Ce site n’a pas de nom" + "then": "Calcaire" } }, - "question": "Quel est le nom de ce site ?", - "render": "{name}" + "question": "Quel est le type de roche ?", + "render": "La roche est du {rock}" }, - "7": { + "Type": { "mappings": { "0": { "then": "Rocher d’escalade, rocher avec une ou peu de voie permettant d’escalader sans corde" @@ -458,14 +362,14 @@ } } }, - "8": { + "name": { "mappings": { "0": { - "then": "Calcaire" + "then": "Ce site n’a pas de nom" } }, - "question": "Quel est le type de roche ?", - "render": "La roche est du {rock}" + "question": "Quel est le nom de ce site ?", + "render": "{name}" } }, "title": { @@ -486,14 +390,110 @@ "render": "Opportunité d’escalade" } }, - "4": { + "climbing_club": { + "description": "Club ou association d’escalade", + "name": "Club d’escalade", + "presets": { + "0": { + "description": "Un club d’escalade", + "title": "Club d’escalade" + }, + "1": { + "description": "Une association d’escalade", + "title": "Association d’escalade" + } + }, + "tagRenderings": { + "climbing_club-name": { + "question": "Quel est le nom du club ou de l’association ?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Association d’escalade" + } + }, + "render": "Club d’escalade" + } + }, + "climbing_gym": { + "description": "Une salle d’escalade", + "name": "Salle d’escalade", + "tagRenderings": { + "name": { + "question": "Quel est le nom de la salle d’escalade ?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Salle d’escalade {name}" + } + }, + "render": "Salle d’escalade" + } + }, + "climbing_route": { + "name": "Voies d’escalade", + "presets": { + "0": { + "title": "Voie d’escalade" + } + }, + "tagRenderings": { + "Bolts": { + "mappings": { + "0": { + "then": "Cette voie n’a pas de prises" + }, + "1": { + "then": "Cette voie n’a pas de prises" + } + }, + "question": "Combien de prises cette voie possède avant d’atteindre la moulinette ?", + "render": "Cette voie a {climbing:bolts} prises" + }, + "Difficulty": { + "question": "Quelle est la difficulté de cette voie selon le système franco-belge ?", + "render": "Selon le système franco-belge, la difficulté de cette voie est de {climbing:grade:french}" + }, + "Length": { + "question": "Quelle est la longueur de cette voie (en mètres) ?", + "render": "Cette voie fait {canonical(climbing:length)} de long" + }, + "Name": { + "mappings": { + "0": { + "then": "Cette voie n’a pas de nom" + } + }, + "question": "Quel est le nom de cette voie d’escalade ?", + "render": "{name}" + }, + "Rock type": { + "render": "Le type de roche est {_embedding_features_with_rock:rock} selon le mur" + } + }, + "title": { + "mappings": { + "0": { + "then": "Voie d’escalade {name}" + } + }, + "render": "Voie d’escalade" + } + }, + "maybe_climbing": { "description": "Opportunité d’escalade ?", "name": "Opportunités d’escalade ?", "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" }, - "2": { + "climbing-possible": { "mappings": { "0": { "then": "Escalader n’est pas possible" @@ -621,7 +621,7 @@ "facadegardens": { "description": "Les jardins muraux en ville n’apportent pas seulement paix et tranquillité mais contribuent à embellir la ville, favoriser la biodiversité, régule la température et assainit l’air.
Klimaan VZW et Mechelen Klimaatneutraal veulent cartographier les jardins muraux comme exemple pour les personnes souhaitant en construire ainsi que celles aimant la nature.
Plus d’infos sur klimaan.be.", "layers": { - "0": { + "facadegardens": { "description": "Jardins muraux", "name": "Jardins muraux", "presets": { @@ -631,40 +631,15 @@ } }, "tagRenderings": { - "1": { + "facadegardens-description": { + "question": "Détails supplémentaires sur le jardin (si nécessaire et non décrit précédemment)", + "render": "Plus de détails : {description}" + }, + "facadegardens-direction": { "question": "Quelle est l’orientation du jardin ?", "render": "Orientation : {direction} (0 pour le Nord et 90 pour l’Ouest)" }, - "2": { - "mappings": { - "0": { - "then": "Le jardin est en plein soleil" - }, - "1": { - "then": "Le jardin est partiellement ensoleillé" - }, - "2": { - "then": "Le jardin est à l’ombre" - } - }, - "question": "Quel est l’ensoleillement du jardin ?" - }, - "3": { - "mappings": { - "0": { - "then": "Il y a des réserves" - }, - "1": { - "then": "Il n’y a pas de réserves" - } - }, - "question": "Des réserves d’eau ont-elles été installées pour le jardin ?" - }, - "4": { - "question": "Quand le jardin a-t’il été construit ? (L’année suffit)", - "render": "Date de construction du jardin : {start_date}" - }, - "5": { + "facadegardens-edible": { "mappings": { "0": { "then": "Il y a des plantes comestibles" @@ -675,7 +650,7 @@ }, "question": "Y-a-t’il des plantes comestibles ?" }, - "6": { + "facadegardens-plants": { "mappings": { "0": { "then": "Il y a des plantes grimpantes" @@ -692,9 +667,34 @@ }, "question": "Quel type de plantes pousse ici ?" }, - "7": { - "question": "Détails supplémentaires sur le jardin (si nécessaire et non décrit précédemment)", - "render": "Plus de détails : {description}" + "facadegardens-rainbarrel": { + "mappings": { + "0": { + "then": "Il y a des réserves" + }, + "1": { + "then": "Il n’y a pas de réserves" + } + }, + "question": "Des réserves d’eau ont-elles été installées pour le jardin ?" + }, + "facadegardens-start_date": { + "question": "Quand le jardin a-t’il été construit ? (L’année suffit)", + "render": "Date de construction du jardin : {start_date}" + }, + "facadegardens-sunshine": { + "mappings": { + "0": { + "then": "Le jardin est en plein soleil" + }, + "1": { + "then": "Le jardin est partiellement ensoleillé" + }, + "2": { + "then": "Le jardin est à l’ombre" + } + }, + "question": "Quel est l’ensoleillement du jardin ?" } }, "title": { @@ -708,7 +708,7 @@ "fritures": { "layers": { "0": { - "override": { + "friture": { "name": "Friteries" } } @@ -722,7 +722,137 @@ "hailhydrant": { "description": "Sur cette carte on trouve et met à jour les bornes incendies, extincteurs, casernes de pompiers et ambulanciers dans son quartier.
Les options en haut à gauche permettent de localiser sa position (sur téléphone) et de filtrer les éléments. Il est possible d’utiliser cet outil pour ajouter et éditer les points d’intérêt de la carte et d’y ajouter des détails en répondant aux questions.
Toutes les modifications sont automatiquement enregistrées dans la base de données OpenStreetMap et peuvent êtres librement réutilisées par d’autres.", "layers": { - "0": { + "ambulancestation": { + "description": "Une station d’ambulance est un lieu où sont stockés les véhicules d’urgence ainsi que de l’équipement médical.", + "name": "Couche des ambulances", + "presets": { + "0": { + "description": "Ajouter une station d’ambulances à la carte", + "title": "Station d’ambulances" + } + }, + "tagRenderings": { + "ambulance-agency": { + "question": "Quel est l’exploitant de la station ?", + "render": "Cette station est opérée par {operator}." + }, + "ambulance-name": { + "question": "Quel est le nom de cette station ?", + "render": "Cette station s’appelle {name}." + }, + "ambulance-operator-type": { + "mappings": { + "0": { + "then": "La station est opérée par le gouvernement." + }, + "1": { + "then": "La station est opérée par une organisation informelle." + }, + "2": { + "then": "La station est opérée par un groupe officiel de bénévoles." + }, + "3": { + "then": "La station est opérée par un groupe privé." + } + }, + "question": "Quel est le type d’exploitant ?", + "render": "L’exploitant est de type {operator:type}." + }, + "ambulance-place": { + "question": "Dans quelle localité la station est-elle située ?", + "render": "La station fait partie de {addr:place}." + }, + "ambulance-street": { + "question": " Quel est le nom de la rue où la station se situe ?", + "render": "La station fait partie de {addr:street}." + } + }, + "title": { + "render": "Station d’ambulances" + } + }, + "extinguisher": { + "description": "Couche des lances à incendie.", + "name": "Couche des extincteurs.", + "presets": { + "0": { + "description": "Un extincteur est un appareil portatif servant à éteindre un feu", + "title": "Extincteur" + } + }, + "tagRenderings": { + "extinguisher-location": { + "mappings": { + "0": { + "then": "Intérieur." + }, + "1": { + "then": "Extérieur." + } + }, + "question": "Où est-elle positionnée ?", + "render": "Emplacement : {location}" + } + }, + "title": { + "render": "Exctincteurs" + } + }, + "fire_stations": { + "description": "Couche des stations de pompiers.", + "name": "Couche des stations de pompiers", + "presets": { + "0": { + "description": "Une caserne de pompiers est un lieu où les pompiers et leur équipements sont situés en dehors des missions.", + "title": "Caserne de pompiers" + } + }, + "tagRenderings": { + "station-agency": { + "mappings": { + "0": { + "then": "Brigade de Protection du Feu" + } + }, + "question": "Quel est l’exploitant de la station ?", + "render": "Cette station est opérée par {operator}." + }, + "station-name": { + "question": "Quel est le nom de la station ?", + "render": "Cette station s’appelle {name}." + }, + "station-operator": { + "mappings": { + "0": { + "then": "La station est opérée par le gouvernement." + }, + "1": { + "then": "La station est opérée par une organisation informelle." + }, + "2": { + "then": "La station est opérée par un groupe officiel de bénévoles." + }, + "3": { + "then": "La station est opérée par un groupe privé." + } + }, + "question": "Quel est le type d’exploitant ?", + "render": "L’exploitant est de type {operator:type}." + }, + "station-place": { + "question": "Dans quelle localité la station est-elle située ?", + "render": "La station fait partie de {addr:place}." + }, + "station-street": { + "question": " Quel est le nom de la rue dans lequel elle se situe ?", + "render": "La station fait partie de la {addr:street}." + } + }, + "title": { + "render": "Station de pompiers" + } + }, + "hydrants": { "description": "Couche des bornes incendie.", "name": "Carte des bornes incendie", "presets": { @@ -732,7 +862,7 @@ } }, "tagRenderings": { - "0": { + "hydrant-color": { "mappings": { "0": { "then": "La borne est de couleur inconnue." @@ -747,7 +877,22 @@ "question": "Quelle est la couleur de la borne ?", "render": "La borne est {colour}" }, - "1": { + "hydrant-state": { + "mappings": { + "0": { + "then": "La borne est en état, ou partiellement en état, de fonctionner." + }, + "1": { + "then": "La borne est hors-service." + }, + "2": { + "then": "La borne a été retirée." + } + }, + "question": "Mettre à jour l’état de la borne.", + "render": "État" + }, + "hydrant-type": { "mappings": { "0": { "then": "La borne est de type inconnu." @@ -767,156 +912,11 @@ }, "question": "De quel type de borne s’agit-il ?", "render": " Type de borne : {fire_hydrant:type}" - }, - "2": { - "mappings": { - "0": { - "then": "La borne est en état, ou partiellement en état, de fonctionner." - }, - "1": { - "then": "La borne est hors-service." - }, - "2": { - "then": "La borne a été retirée." - } - }, - "question": "Mettre à jour l’état de la borne.", - "render": "État" } }, "title": { "render": "Bornes incendie" } - }, - "1": { - "description": "Couche des lances à incendie.", - "name": "Couche des extincteurs.", - "presets": { - "0": { - "description": "Un extincteur est un appareil portatif servant à éteindre un feu", - "title": "Extincteur" - } - }, - "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "Intérieur." - }, - "1": { - "then": "Extérieur." - } - }, - "question": "Où est-elle positionnée ?", - "render": "Emplacement : {location}" - } - }, - "title": { - "render": "Exctincteurs" - } - }, - "2": { - "description": "Couche des stations de pompiers.", - "name": "Couche des stations de pompiers", - "presets": { - "0": { - "description": "Une caserne de pompiers est un lieu où les pompiers et leur équipements sont situés en dehors des missions.", - "title": "Caserne de pompiers" - } - }, - "tagRenderings": { - "0": { - "question": "Quel est le nom de la station ?", - "render": "Cette station s’appelle {name}." - }, - "1": { - "question": " Quel est le nom de la rue dans lequel elle se situe ?", - "render": "La station fait partie de la {addr:street}." - }, - "2": { - "question": "Dans quelle localité la station est-elle située ?", - "render": "La station fait partie de {addr:place}." - }, - "3": { - "mappings": { - "0": { - "then": "Brigade de Protection du Feu" - } - }, - "question": "Quel est l’exploitant de la station ?", - "render": "Cette station est opérée par {operator}." - }, - "4": { - "mappings": { - "0": { - "then": "La station est opérée par le gouvernement." - }, - "1": { - "then": "La station est opérée par une organisation informelle." - }, - "2": { - "then": "La station est opérée par un groupe officiel de bénévoles." - }, - "3": { - "then": "La station est opérée par un groupe privé." - } - }, - "question": "Quel est le type d’exploitant ?", - "render": "L’exploitant est de type {operator:type}." - } - }, - "title": { - "render": "Station de pompiers" - } - }, - "3": { - "description": "Une station d’ambulance est un lieu où sont stockés les véhicules d’urgence ainsi que de l’équipement médical.", - "name": "Couche des ambulances", - "presets": { - "0": { - "description": "Ajouter une station d’ambulances à la carte", - "title": "Station d’ambulances" - } - }, - "tagRenderings": { - "0": { - "question": "Quel est le nom de cette station ?", - "render": "Cette station s’appelle {name}." - }, - "1": { - "question": " Quel est le nom de la rue où la station se situe ?", - "render": "La station fait partie de {addr:street}." - }, - "2": { - "question": "Dans quelle localité la station est-elle située ?", - "render": "La station fait partie de {addr:place}." - }, - "3": { - "question": "Quel est l’exploitant de la station ?", - "render": "Cette station est opérée par {operator}." - }, - "4": { - "mappings": { - "0": { - "then": "La station est opérée par le gouvernement." - }, - "1": { - "then": "La station est opérée par une organisation informelle." - }, - "2": { - "then": "La station est opérée par un groupe officiel de bénévoles." - }, - "3": { - "then": "La station est opérée par un groupe privé." - } - }, - "question": "Quel est le type d’exploitant ?", - "render": "L’exploitant est de type {operator:type}." - } - }, - "title": { - "render": "Station d’ambulances" - } } }, "shortDescription": "Carte indiquant les bornes incendies, extincteurs, casernes de pompiers et ambulanciers.", @@ -930,7 +930,7 @@ "openwindpowermap": { "description": "Une carte indiquant les éoliennes et permettant leur édition.", "layers": { - "0": { + "windturbine": { "name": "Éolienne", "presets": { "0": { @@ -938,23 +938,23 @@ } }, "tagRenderings": { - "0": { - "question": "Quel est la puissance générée par cette éolienne ?", - "render": "La puissance générée par cette éolienne est de {generator:output:electricity}." - }, - "1": { - "question": "Qui est l’exploitant de cette éolienne ?", - "render": "Cette éolienne est opérée par {operator}." - }, - "2": { - "question": "Quelle est la hauteur totale de l’éolienne en mètres, pales incluses ?", - "render": "La hauteur totale, incluant les pales, est de {height} mètres." - }, - "3": { + "turbine-diameter": { "question": "Quel est le diamètre du rotor en mètres ?", "render": "Le diamètre du rotor est de {rotor:diameter} mètres." }, - "4": { + "turbine-height": { + "question": "Quelle est la hauteur totale de l’éolienne en mètres, pales incluses ?", + "render": "La hauteur totale, incluant les pales, est de {height} mètres." + }, + "turbine-operator": { + "question": "Qui est l’exploitant de cette éolienne ?", + "render": "Cette éolienne est opérée par {operator}." + }, + "turbine-output": { + "question": "Quel est la puissance générée par cette éolienne ?", + "render": "La puissance générée par cette éolienne est de {generator:output:electricity}." + }, + "turbine-start-date": { "question": "Depuis quand l’éolienne est-elle en fonctionnement ?", "render": "L’éolienne est active depuis {start_date}." } @@ -1008,7 +1008,7 @@ "shops": { "description": "Sur cette carte, vous pouvez ajouter des informations sur les magasins, horaires d'ouverture et numéro de téléphone", "layers": { - "0": { + "shops": { "description": "Un magasin", "name": "Magasin", "presets": { @@ -1018,10 +1018,22 @@ } }, "tagRenderings": { - "1": { + "shops-email": { + "question": "Quelle est l'adresse électronique de ce magasin ?", + "render": "{email}" + }, + "shops-name": { "question": "Qu'est-ce que le nom de ce magasin?" }, - "2": { + "shops-opening_hours": { + "question": "Quels sont les horaires d'ouverture de ce magasin ?", + "render": "{opening_hours_table(opening_hours)}" + }, + "shops-phone": { + "question": "Quel est le numéro de téléphone ?", + "render": "{phone}" + }, + "shops-shop": { "mappings": { "0": { "then": "Épicerie/superette" @@ -1048,21 +1060,9 @@ "question": "Que vends ce magasin ?", "render": "Ce magasin vends {shop}" }, - "3": { - "question": "Quel est le numéro de téléphone ?", - "render": "{phone}" - }, - "4": { + "shops-website": { "question": "Quel est le site internet de ce magasin ?", "render": "{website}" - }, - "5": { - "question": "Quelle est l'adresse électronique de ce magasin ?", - "render": "{email}" - }, - "6": { - "question": "Quels sont les horaires d'ouverture de ce magasin ?", - "render": "{opening_hours_table(opening_hours)}" } }, "title": { diff --git a/langs/themes/id.json b/langs/themes/id.json index e95bb0454..0be2f3e01 100644 --- a/langs/themes/id.json +++ b/langs/themes/id.json @@ -6,10 +6,10 @@ "artwork": { "description": "Selamat datang di Open Artwork Map, peta untuk patung, grafiti, dan karya seni lain di seluruh dunia", "layers": { - "0": { + "artwork": { "name": "Karya seni", "tagRenderings": { - "3": { + "artwork-website": { "render": "Info lanjut tersedia di laman web ini." } }, @@ -27,19 +27,16 @@ }, "campersite": { "layers": { - "0": { + "caravansites": { "tagRenderings": { - "1": { - "question": "Apakah nama tempat ini?" - }, - "2": { + "caravansites-fee": { "mappings": { "1": { "then": "Boleh digunakan tanpa bayaran" } } }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "Akses Web tersedia" @@ -53,7 +50,10 @@ }, "question": "Tempat ini berbagi akses Web?" }, - "8": { + "caravansites-name": { + "question": "Apakah nama tempat ini?" + }, + "caravansites-toilets": { "mappings": { "0": { "then": "Tempat sini ada tandas" @@ -63,7 +63,7 @@ } } }, - "9": { + "caravansites-website": { "question": "Tempat sini terada situs web?", "render": "Situs resmi: {website}" } @@ -88,37 +88,37 @@ }, "climbing": { "layers": { - "0": { + "climbing": { "tagRenderings": { - "0": { + "name": { "render": "{name}" } } }, - "1": { + "climbing_club": { "tagRenderings": { - "3": { + "climbing_club-name": { "render": "{name}" } } }, - "2": { + "climbing_gym": { "tagRenderings": { - "3": { + "name": { "render": "{name}" } } }, - "3": { + "climbing_route": { "tagRenderings": { - "6": { + "Name": { "render": "{name}" } } }, - "4": { + "maybe_climbing": { "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" } } @@ -127,9 +127,9 @@ }, "hailhydrant": { "layers": { - "0": { + "hydrants": { "tagRenderings": { - "1": { + "hydrant-type": { "mappings": { "3": { "then": " Jenis dinding." @@ -142,16 +142,16 @@ }, "shops": { "layers": { - "0": { + "shops": { "tagRenderings": { - "3": { + "shops-email": { + "render": "{email}" + }, + "shops-phone": { "render": "{phone}" }, - "4": { + "shops-website": { "render": "{website}" - }, - "5": { - "render": "{email}" } } } diff --git a/langs/themes/it.json b/langs/themes/it.json index 8f7487108..fa17395bd 100644 --- a/langs/themes/it.json +++ b/langs/themes/it.json @@ -6,7 +6,7 @@ "artwork": { "description": "Benvenuto/a sulla mappa libera dell’arte, una mappa delle statue, i busti, i graffiti e le altre realizzazioni artistiche di tutto il mondo", "layers": { - "0": { + "artwork": { "description": "Diverse opere d’arte", "name": "Opere d’arte", "presets": { @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Quale artista ha creato quest’opera?", + "render": "Creato da {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Architettura" @@ -57,15 +61,11 @@ "question": "Che tipo di opera d’arte è questo?", "render": "Si tratta di un {artwork_type}" }, - "2": { - "question": "Quale artista ha creato quest’opera?", - "render": "Creato da {artist_name}" - }, - "3": { + "artwork-website": { "question": "Esiste un sito web con maggiori informazioni su quest’opera?", "render": "Ulteriori informazioni su questo sito web" }, - "4": { + "artwork-wikidata": { "question": "Quale elemento Wikidata corrisponde a quest’opera d’arte?", "render": "Corrisponde a {wikidata}" } @@ -98,7 +98,7 @@ "campersite": { "description": "Questo sito raccoglie tutti i luoghi ufficiali dove sostare con il camper e aree dove è possibile scaricare acque grigie e nere. Puoi aggiungere dettagli riguardanti i servizi forniti e il loro costo. Aggiungi foto e recensioni. Questo è al contempo un sito web e una web app. I dati sono memorizzati su OpenStreetMap in modo tale che siano per sempre liberi e riutilizzabili da qualsiasi app.", "layers": { - "0": { + "caravansites": { "description": "Aree camper", "name": "Aree camper", "presets": { @@ -108,11 +108,19 @@ } }, "tagRenderings": { - "1": { - "question": "Come viene chiamato questo luogo?", - "render": "Questo luogo è chiamato {name}" + "caravansites-capacity": { + "question": "Quanti camper possono stare qua? (non rispondere se non c’è un numero chario di spazi o veicoli ammessi)", + "render": "{capacity} camper possono usare questo luogo al contempo" }, - "2": { + "caravansites-charge": { + "question": "Quanto costa questo luogo?", + "render": "Questo luogo costa {charge}" + }, + "caravansites-description": { + "question": "Desideri aggiungere una descrizione del luogo? (Non vanno ripetute informazioni già richieste e mostrate precedentemente. Si prega di attenersi a dati oggettivi - le opinioni vanno nelle recensioni)", + "render": "Maggiori dettagli su questo luogo: {description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "Devi pagare per usarlo" @@ -123,26 +131,7 @@ }, "question": "Ha una tariffa questo luogo?" }, - "3": { - "question": "Quanto costa questo luogo?", - "render": "Questo luogo costa {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "Questo luogo ha una stazione per lo scarico delle acque" - }, - "1": { - "then": "Questo luogo non ha una stazione per lo scarico delle acque" - } - }, - "question": "Questo luogo ha una stazione per lo scarico delle acque?" - }, - "5": { - "question": "Quanti camper possono stare qua? (non rispondere se non c’è un numero chario di spazi o veicoli ammessi)", - "render": "{capacity} camper possono usare questo luogo al contempo" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "C’è l’accesso a internet" @@ -156,7 +145,7 @@ }, "question": "Questo luogo ha l’accesso a internet?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "Occorre pagare un extra per avere l’accesso a internet" @@ -167,22 +156,7 @@ }, "question": "Occorre pagare per avere l’accesso a internet?" }, - "8": { - "mappings": { - "0": { - "then": "Questo luogo ha i servizi igienici" - }, - "1": { - "then": "Questo luogo non ha i servizi igienici" - } - }, - "question": "Questo luogo dispone di servizi igienici?" - }, - "9": { - "question": "Questo luogo ha un sito web?", - "render": "Sito web ufficiale: {website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "Sì, ci sono spazi per il noleggio a lungo termine, ma puoi anche pagare per singola giornata" @@ -196,9 +170,35 @@ }, "question": "Questo luogo offre spazi per il noleggio a lungo termine?" }, - "11": { - "question": "Desideri aggiungere una descrizione del luogo? (Non vanno ripetute informazioni già richieste e mostrate precedentemente. Si prega di attenersi a dati oggettivi - le opinioni vanno nelle recensioni)", - "render": "Maggiori dettagli su questo luogo: {description}" + "caravansites-name": { + "question": "Come viene chiamato questo luogo?", + "render": "Questo luogo è chiamato {name}" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "Questo luogo ha una stazione per lo scarico delle acque" + }, + "1": { + "then": "Questo luogo non ha una stazione per lo scarico delle acque" + } + }, + "question": "Questo luogo ha una stazione per lo scarico delle acque?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "Questo luogo ha i servizi igienici" + }, + "1": { + "then": "Questo luogo non ha i servizi igienici" + } + }, + "question": "Questo luogo dispone di servizi igienici?" + }, + "caravansites-website": { + "question": "Questo luogo ha un sito web?", + "render": "Sito web ufficiale: {website}" } }, "title": { @@ -210,7 +210,7 @@ "render": "Area camper {name}" } }, - "1": { + "dumpstations": { "description": "Luoghi di sversamento delle acque reflue", "name": "Luoghi di sversamento delle acque reflue", "presets": { @@ -220,55 +220,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "A pagamento" - }, - "1": { - "then": "È gratuito" - } - }, - "question": "Questo luogo è a pagamento?" - }, - "2": { - "question": "Qual è la tariffa di questo luogo?", - "render": "Ha una tariffa di {charge}" - }, - "3": { - "mappings": { - "0": { - "then": "Questo luogo ha un punto per l'approvvigionamento di acqua" - }, - "1": { - "then": "Questo luogo non ha un punto per l'approvvigionamento di acqua" - } - }, - "question": "Questo luogo ha un punto per l'approvvigionamento di acqua?" - }, - "4": { - "mappings": { - "0": { - "then": "Si possono smaltire le acque grigie qui" - }, - "1": { - "then": "Non si possono smaltire le acque grigie qui" - } - }, - "question": "Si possono smaltire le acque grigie qui?" - }, - "5": { - "mappings": { - "0": { - "then": "È possibile smaltire le acque del WC chimico qui" - }, - "1": { - "then": "Non è possibile smaltire le acque del WC chimico qui" - } - }, - "question": "È possibile smaltire le acque del WC chimico qui?" - }, - "6": { + "dumpstations-access": { "mappings": { "0": { "then": "Servono una chiave o un codice di accesso" @@ -285,9 +237,57 @@ }, "question": "Chi può utilizzare questo luogo di sversamento?" }, - "7": { + "dumpstations-charge": { + "question": "Qual è la tariffa di questo luogo?", + "render": "Ha una tariffa di {charge}" + }, + "dumpstations-chemical-waste": { + "mappings": { + "0": { + "then": "È possibile smaltire le acque del WC chimico qui" + }, + "1": { + "then": "Non è possibile smaltire le acque del WC chimico qui" + } + }, + "question": "È possibile smaltire le acque del WC chimico qui?" + }, + "dumpstations-fee": { + "mappings": { + "0": { + "then": "A pagamento" + }, + "1": { + "then": "È gratuito" + } + }, + "question": "Questo luogo è a pagamento?" + }, + "dumpstations-grey-water": { + "mappings": { + "0": { + "then": "Si possono smaltire le acque grigie qui" + }, + "1": { + "then": "Non si possono smaltire le acque grigie qui" + } + }, + "question": "Si possono smaltire le acque grigie qui?" + }, + "dumpstations-network": { "question": "Di quale rete fa parte questo luogo? (se non fa parte di nessuna rete, salta)", "render": "Questo luogo è parte della rete {network}" + }, + "dumpstations-waterpoint": { + "mappings": { + "0": { + "then": "Questo luogo ha un punto per l'approvvigionamento di acqua" + }, + "1": { + "then": "Questo luogo non ha un punto per l'approvvigionamento di acqua" + } + }, + "question": "Questo luogo ha un punto per l'approvvigionamento di acqua?" } }, "title": { @@ -327,9 +327,17 @@ }, "climbing": { "layers": { - "2": { + "climbing_route": { "tagRenderings": { - "3": { + "Difficulty": { + "question": "Qual è la difficoltà di questa via di arrampicata nel sistema francese/belga?", + "render": "Il grado di difficoltà è {climbing:grade:french} nel sistema francese/belga" + }, + "Length": { + "question": "Quanto è lunga questa via di arrampicata (in metri)?", + "render": "Questo percorso è lungo {canonical(climbing:length)}" + }, + "Name": { "mappings": { "0": { "then": "Questa via di arrampicata non ha un nome" @@ -337,14 +345,6 @@ }, "question": "Come si chiama questa via di arrampicata?", "render": "{name}" - }, - "4": { - "question": "Quanto è lunga questa via di arrampicata (in metri)?", - "render": "Questo percorso è lungo {canonical(climbing:length)}" - }, - "5": { - "question": "Qual è la difficoltà di questa via di arrampicata nel sistema francese/belga?", - "render": "Il grado di difficoltà è {climbing:grade:french} nel sistema francese/belga" } }, "title": { @@ -361,11 +361,18 @@ }, "cyclestreets": { "layers": { - "0": { + "all_streets": { + "description": "Livello per contrassegnare tutte le strade come strade ciclabili", + "name": "Tutte le strade", + "title": { + "render": "Strada" + } + }, + "fietsstraat": { "description": "Una strada ciclabile è una strada in cui i veicoli a motore non possono sorpassare le persone in bicicletta", "name": "Strade ciclabili" }, - "1": { + "toekomstige_fietsstraat": { "description": "Questa strada diventerà presto una strada ciclabile", "name": "Futura strada ciclabile", "title": { @@ -376,13 +383,6 @@ }, "render": "Futura strada ciclabile" } - }, - "2": { - "description": "Livello per contrassegnare tutte le strade come strade ciclabili", - "name": "Tutte le strade", - "title": { - "render": "Strada" - } } }, "roamingRenderings": { @@ -409,7 +409,7 @@ }, "facadegardens": { "layers": { - "0": { + "facadegardens": { "presets": { "0": { "description": "Aggiungi un giardino verticale", @@ -417,35 +417,11 @@ } }, "tagRenderings": { - "2": { - "mappings": { - "0": { - "then": "Il giardino è completamente illuminato dal sole" - }, - "1": { - "then": "Il giardino è parzialmente in ombra" - }, - "2": { - "then": "Il giardino è in ombra" - } - }, - "question": "Il giardino è al sole o in ombra?" + "facadegardens-description": { + "question": "Altre informazioni per descrivere il giardino (se necessarie e non riportate qui sopra)", + "render": "Maggiori dettagli: {description}" }, - "3": { - "mappings": { - "0": { - "then": "C'è un contenitore per raccogliere la pioggia" - }, - "1": { - "then": "Non c'è un contenitore per raccogliere la pioggia" - } - } - }, - "4": { - "question": "Quando è stato realizzato il giardino? (è sufficiente l'anno)", - "render": "Data di realizzazione del giardino: {start_date}" - }, - "5": { + "facadegardens-edible": { "mappings": { "0": { "then": "Ci sono piante commestibili" @@ -456,7 +432,7 @@ }, "question": "Ci sono piante commestibili?" }, - "6": { + "facadegardens-plants": { "mappings": { "0": { "then": "Ci sono viti" @@ -473,9 +449,33 @@ }, "question": "Che tipi di piante sono presenti qui?" }, - "7": { - "question": "Altre informazioni per descrivere il giardino (se necessarie e non riportate qui sopra)", - "render": "Maggiori dettagli: {description}" + "facadegardens-rainbarrel": { + "mappings": { + "0": { + "then": "C'è un contenitore per raccogliere la pioggia" + }, + "1": { + "then": "Non c'è un contenitore per raccogliere la pioggia" + } + } + }, + "facadegardens-start_date": { + "question": "Quando è stato realizzato il giardino? (è sufficiente l'anno)", + "render": "Data di realizzazione del giardino: {start_date}" + }, + "facadegardens-sunshine": { + "mappings": { + "0": { + "then": "Il giardino è completamente illuminato dal sole" + }, + "1": { + "then": "Il giardino è parzialmente in ombra" + }, + "2": { + "then": "Il giardino è in ombra" + } + }, + "question": "Il giardino è al sole o in ombra?" } } } @@ -488,16 +488,32 @@ }, "hailhydrant": { "layers": { - "0": { + "fire_stations": { + "description": "Livello che mostra le caserme dei vigili del fuoco.", + "name": "Mappa delle caserme dei vigili del fuoco", "tagRenderings": { - "0": { + "station-name": { + "question": "Come si chiama questa caserma dei vigili del fuoco?", + "render": "Questa caserma si chiama {name}." + }, + "station-street": { + "question": " Qual è il nome della via in cui si trova la caserma?" + } + }, + "title": { + "render": "Caserma dei vigili del fuoco" + } + }, + "hydrants": { + "tagRenderings": { + "hydrant-color": { "mappings": { "2": { "then": "L'idrante è rosso." } } }, - "1": { + "hydrant-type": { "mappings": { "0": { "then": "Il tipo di idrante è sconosciuto." @@ -507,22 +523,6 @@ "render": " Tipo di idrante: {fire_hydrant:type}" } } - }, - "2": { - "description": "Livello che mostra le caserme dei vigili del fuoco.", - "name": "Mappa delle caserme dei vigili del fuoco", - "tagRenderings": { - "0": { - "question": "Come si chiama questa caserma dei vigili del fuoco?", - "render": "Questa caserma si chiama {name}." - }, - "1": { - "question": " Qual è il nome della via in cui si trova la caserma?" - } - }, - "title": { - "render": "Caserma dei vigili del fuoco" - } } } }, diff --git a/langs/themes/ja.json b/langs/themes/ja.json index d1b0cb22d..cb61f27de 100644 --- a/langs/themes/ja.json +++ b/langs/themes/ja.json @@ -6,7 +6,7 @@ "artwork": { "description": "オープン アートワーク マップへようこそ。世界中の銅像や胸像、壁の落書きなどのアートワークの地図です", "layers": { - "0": { + "artwork": { "description": "多様な作品", "name": "美術品", "presets": { @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "どのアーティストが作ったんですか?", + "render": "作成者:{artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "建物" @@ -57,15 +61,11 @@ "question": "この作品の種類は何ですか?", "render": "これは{artwork_type}です" }, - "2": { - "question": "どのアーティストが作ったんですか?", - "render": "作成者:{artist_name}" - }, - "3": { + "artwork-website": { "question": "この作品についての詳しい情報はどのウェブサイトにありますか?", "render": "Webサイトに詳細情報がある" }, - "4": { + "artwork-wikidata": { "question": "このアートワークに関するWikidataのエントリーはどれですか?", "render": "{wikidata}に関連する" } @@ -98,7 +98,7 @@ "campersite": { "description": "このWebサイトでは、すべてのキャンピングカーの公式停車場所と、汚水を捨てることができる場所を収集します。提供されるサービスとコストに関する詳細を追加できます。写真とレビューを追加します。これはウェブサイトとウェブアプリです。データはOpenStreetMapに保存されるので、永遠に無料で、どんなアプリからでも再利用できます。", "layers": { - "0": { + "caravansites": { "description": "キャンプサイト", "name": "キャンプサイト", "presets": { @@ -108,11 +108,19 @@ } }, "tagRenderings": { - "1": { - "question": "ここは何というところですか?", - "render": "この場所は {name} と呼ばれています" + "caravansites-capacity": { + "question": "ここには何人のキャンパーが泊まれますか?(許可された車両の数や駐車スペースが明らかでない場合は省略)", + "render": "{capacity} 人が同時に使用できます" }, - "2": { + "caravansites-charge": { + "question": "ここはいくらかかりますか?", + "render": "この場所は{charge} が必要" + }, + "caravansites-description": { + "question": "この場所の一般的な説明を追加しますか?(前に問い合わせた情報や上記の情報を繰り返し入力しないでください。客観的な意見はレビューに反映されます)", + "render": "この場所の詳細:{description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "使用料を支払う必要がある" @@ -123,26 +131,7 @@ }, "question": "ここは有料ですか?" }, - "3": { - "question": "ここはいくらかかりますか?", - "render": "この場所は{charge} が必要" - }, - "4": { - "mappings": { - "0": { - "then": "この場所には衛生的なゴミ捨て場がある" - }, - "1": { - "then": "この場所には衛生的なゴミ捨て場がない" - } - }, - "question": "この場所に衛生的なゴミ捨て場はありますか?" - }, - "5": { - "question": "ここには何人のキャンパーが泊まれますか?(許可された車両の数や駐車スペースが明らかでない場合は省略)", - "render": "{capacity} 人が同時に使用できます" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "インターネットアクセスがある" @@ -156,7 +145,7 @@ }, "question": "この場所はインターネットにアクセスできますか?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "インターネット接続には別途料金が必要です" @@ -167,22 +156,7 @@ }, "question": "インターネット接続にお金はかかりますか?" }, - "8": { - "mappings": { - "0": { - "then": "ここにはトイレがある" - }, - "1": { - "then": "ここにはトイレがない" - } - }, - "question": "ここにトイレはありますか?" - }, - "9": { - "question": "ここにはウェブサイトがありますか?", - "render": "公式Webサイト: {website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "はい、長期レンタルのスポットもあり、日常的に滞在することもできます" @@ -196,9 +170,35 @@ }, "question": "ここには長期レンタルのスポットがありますか?" }, - "11": { - "question": "この場所の一般的な説明を追加しますか?(前に問い合わせた情報や上記の情報を繰り返し入力しないでください。客観的な意見はレビューに反映されます)", - "render": "この場所の詳細:{description}" + "caravansites-name": { + "question": "ここは何というところですか?", + "render": "この場所は {name} と呼ばれています" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "この場所には衛生的なゴミ捨て場がある" + }, + "1": { + "then": "この場所には衛生的なゴミ捨て場がない" + } + }, + "question": "この場所に衛生的なゴミ捨て場はありますか?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "ここにはトイレがある" + }, + "1": { + "then": "ここにはトイレがない" + } + }, + "question": "ここにトイレはありますか?" + }, + "caravansites-website": { + "question": "ここにはウェブサイトがありますか?", + "render": "公式Webサイト: {website}" } }, "title": { @@ -210,7 +210,7 @@ "render": "キャンプサイト {name}" } }, - "1": { + "dumpstations": { "description": "衛生ゴミ捨て場", "name": "衛生ゴミ捨て場", "presets": { @@ -220,55 +220,7 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "使用料を支払う必要がある" - }, - "1": { - "then": "無料で使用可能" - } - }, - "question": "ここは有料ですか?" - }, - "2": { - "question": "ここはいくらかかりますか?", - "render": "この場所は{charge} が必要" - }, - "3": { - "mappings": { - "0": { - "then": "この場所には給水所がある" - }, - "1": { - "then": "この場所には給水所がない" - } - }, - "question": "この場所には給水所がありますか?" - }, - "4": { - "mappings": { - "0": { - "then": "ここで汚水(雑排水)を捨てることができます" - }, - "1": { - "then": "ここでは汚水(雑排水)を捨てることはできない" - } - }, - "question": "汚水(雑排水)はこちらで処分できますか?" - }, - "5": { - "mappings": { - "0": { - "then": "携帯トイレのゴミはここで処分できます" - }, - "1": { - "then": "ここでは携帯トイレの廃棄物を処分することはできません" - } - }, - "question": "携帯トイレのゴミはこちらで処分できますか?" - }, - "6": { + "dumpstations-access": { "mappings": { "0": { "then": "これを使用するには、ネットワークキー/コードが必要です" @@ -285,9 +237,57 @@ }, "question": "このゴミ捨て場は誰が使えるんですか?" }, - "7": { + "dumpstations-charge": { + "question": "ここはいくらかかりますか?", + "render": "この場所は{charge} が必要" + }, + "dumpstations-chemical-waste": { + "mappings": { + "0": { + "then": "携帯トイレのゴミはここで処分できます" + }, + "1": { + "then": "ここでは携帯トイレの廃棄物を処分することはできません" + } + }, + "question": "携帯トイレのゴミはこちらで処分できますか?" + }, + "dumpstations-fee": { + "mappings": { + "0": { + "then": "使用料を支払う必要がある" + }, + "1": { + "then": "無料で使用可能" + } + }, + "question": "ここは有料ですか?" + }, + "dumpstations-grey-water": { + "mappings": { + "0": { + "then": "ここで汚水(雑排水)を捨てることができます" + }, + "1": { + "then": "ここでは汚水(雑排水)を捨てることはできない" + } + }, + "question": "汚水(雑排水)はこちらで処分できますか?" + }, + "dumpstations-network": { "question": "ここは何のネットワークの一部ですか?(なければスキップ)", "render": "このステーションはネットワーク{network}の一部です" + }, + "dumpstations-waterpoint": { + "mappings": { + "0": { + "then": "この場所には給水所がある" + }, + "1": { + "then": "この場所には給水所がない" + } + }, + "question": "この場所には給水所がありますか?" } }, "title": { @@ -329,81 +329,7 @@ "description": "この地図には、自然の中のクライミングジム、ボルダリングホール、岩など、さまざまなクライミングの機会があります。", "descriptionTail": "登山地図はもともと Christian Neumann によって作成されたものです。フィードバックや質問がありましたら、ご連絡ください。

このプロジェクトでは、OpenStreetMapプロジェクトのデータを使用します。

", "layers": { - "0": { - "description": "クライミングクラブや団体", - "name": "クライミングクラブ", - "presets": { - "0": { - "description": "クライミングクラブ", - "title": "クライミングクラブ" - }, - "1": { - "description": "登山に関わるNGO", - "title": "クライミングNGO" - } - }, - "tagRenderings": { - "0": { - "question": "この登山クラブやNGOの名前は何ですか?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "クライミングNGO" - } - }, - "render": "クライミングクラブ" - } - }, - "1": { - "description": "クライミングジム", - "name": "クライミングジム", - "tagRenderings": { - "3": { - "question": "このクライミングジムは何という名前ですか?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "クライミングジム{name}" - } - }, - "render": "クライミングジム" - } - }, - "2": { - "name": "登坂ルート", - "tagRenderings": { - "3": { - "mappings": { - "0": { - "then": "この登坂ルートには名前がありません" - } - }, - "question": "この登坂ルートの名前は何ですか?", - "render": "{name}" - }, - "4": { - "render": "このルート長は、 {canonical(climbing:length)} メーターです" - }, - "5": { - "render": "フランス/ベルギーのランク評価システムによると、{climbing:grade:french}の困難度です" - } - }, - "title": { - "mappings": { - "0": { - "then": "登坂ルート{name}" - } - }, - "render": "登坂ルート" - } - }, - "3": { + "climbing": { "description": "登坂教室", "name": "登坂教室", "presets": { @@ -413,7 +339,7 @@ } }, "tagRenderings": { - "6": { + "name": { "mappings": { "0": { "then": "この登坂教室には名前がついていない" @@ -427,14 +353,88 @@ "render": "登坂教室" } }, - "4": { + "climbing_club": { + "description": "クライミングクラブや団体", + "name": "クライミングクラブ", + "presets": { + "0": { + "description": "クライミングクラブ", + "title": "クライミングクラブ" + }, + "1": { + "description": "登山に関わるNGO", + "title": "クライミングNGO" + } + }, + "tagRenderings": { + "climbing_club-name": { + "question": "この登山クラブやNGOの名前は何ですか?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "クライミングNGO" + } + }, + "render": "クライミングクラブ" + } + }, + "climbing_gym": { + "description": "クライミングジム", + "name": "クライミングジム", + "tagRenderings": { + "name": { + "question": "このクライミングジムは何という名前ですか?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "クライミングジム{name}" + } + }, + "render": "クライミングジム" + } + }, + "climbing_route": { + "name": "登坂ルート", + "tagRenderings": { + "Difficulty": { + "render": "フランス/ベルギーのランク評価システムによると、{climbing:grade:french}の困難度です" + }, + "Length": { + "render": "このルート長は、 {canonical(climbing:length)} メーターです" + }, + "Name": { + "mappings": { + "0": { + "then": "この登坂ルートには名前がありません" + } + }, + "question": "この登坂ルートの名前は何ですか?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "登坂ルート{name}" + } + }, + "render": "登坂ルート" + } + }, + "maybe_climbing": { "description": "登坂教室?", "name": "登坂教室?", "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" }, - "2": { + "climbing-possible": { "mappings": { "0": { "then": "ここでは登ることができない" @@ -549,11 +549,18 @@ "cyclestreets": { "description": "cyclestreetとは、自動車がサイクリストを追い越すことができない道です。専用の道路標識で表示されます。Cyclestreetsはオランダやベルギーにもありますが、ドイツやフランスにもあります。 ", "layers": { - "0": { + "all_streets": { + "description": "任意の道路をCycle Streetとしてマークするレイヤ", + "name": "すべての道路", + "title": { + "render": "ストリート" + } + }, + "fietsstraat": { "description": "cyclestreetとは、自動車による交通がサイクリストを追い越すことができない道路です", "name": "Cyclestreets" }, - "1": { + "toekomstige_fietsstraat": { "description": "この通りはまもなくcyclestreetになります", "name": "将来のcyclestreet", "title": { @@ -564,13 +571,6 @@ }, "render": "将来のcyclestreet" } - }, - "2": { - "description": "任意の道路をCycle Streetとしてマークするレイヤ", - "name": "すべての道路", - "title": { - "render": "ストリート" - } } }, "roamingRenderings": { @@ -610,7 +610,7 @@ "facadegardens": { "description": "ファサード庭園、都市の緑のファサードと樹木は、平和と静けさをもたらすだけでなく、より美しい都市、より大きな生物多様性、冷却効果、より良い大気質をもたらす。
KlimaanのVZWとMechelenのKlimaatneutraalは、自分で庭を作りたい人や自然を愛する都市の歩行者のために、既存のファサード庭園と新しいファサード庭園のマッピングしたいと考えています。
このプロジェクトに関する詳細情報はklimaanにあります。", "layers": { - "0": { + "facadegardens": { "description": "ファサード庭園", "name": "ファサード庭園", "presets": { @@ -620,40 +620,15 @@ } }, "tagRenderings": { - "1": { + "facadegardens-description": { + "question": "庭園に関する追加の説明情報(必要な場合でまだ上記に記載されていない場合)", + "render": "詳細情報: {description}" + }, + "facadegardens-direction": { "question": "庭の向きはどうなっていますか?", "render": "方向: {direction} (0=N で 90=O)" }, - "2": { - "mappings": { - "0": { - "then": "庭は日があたっている" - }, - "1": { - "then": "庭は部分的に日陰である" - }, - "2": { - "then": "庭は日陰である" - } - }, - "question": "庭は日陰ですか、日当たりがいいですか?" - }, - "3": { - "mappings": { - "0": { - "then": "雨樽がある" - }, - "1": { - "then": "雨樽はありません" - } - }, - "question": "庭に水桶が設置されているのですか?" - }, - "4": { - "question": "その庭園はいつ造られたのですか?(建設年で十分です)", - "render": "庭園の建設日: {start_date}" - }, - "5": { + "facadegardens-edible": { "mappings": { "0": { "then": "食用の植物がある" @@ -664,7 +639,7 @@ }, "question": "食用の植物はありますか?" }, - "6": { + "facadegardens-plants": { "mappings": { "0": { "then": "つるがある" @@ -681,9 +656,34 @@ }, "question": "ここではどんな植物が育つんですか?" }, - "7": { - "question": "庭園に関する追加の説明情報(必要な場合でまだ上記に記載されていない場合)", - "render": "詳細情報: {description}" + "facadegardens-rainbarrel": { + "mappings": { + "0": { + "then": "雨樽がある" + }, + "1": { + "then": "雨樽はありません" + } + }, + "question": "庭に水桶が設置されているのですか?" + }, + "facadegardens-start_date": { + "question": "その庭園はいつ造られたのですか?(建設年で十分です)", + "render": "庭園の建設日: {start_date}" + }, + "facadegardens-sunshine": { + "mappings": { + "0": { + "then": "庭は日があたっている" + }, + "1": { + "then": "庭は部分的に日陰である" + }, + "2": { + "then": "庭は日陰である" + } + }, + "question": "庭は日陰ですか、日当たりがいいですか?" } }, "title": { @@ -701,7 +701,137 @@ "hailhydrant": { "description": "このマップでは、お気に入りの近隣にある消火栓、消防署、救急ステーション、消火器を検索して更新できます。\n\n正確な位置を追跡し(モバイルのみ)、左下コーナーで関連するレイヤを選択できます。このツールを使用して、マップにピン(注視点)を追加または編集したり、利用可能な質問に答えることによって追加の詳細を提供することもできます。\n\nすべての変更は自動的にOpenStreetMapのグローバルデータベースに保存され、他のユーザが自由に再利用できます。", "layers": { - "0": { + "ambulancestation": { + "description": "救急ステーションは、救急車、医療機器、個人用保護具、およびその他の医療用品を保管する場所です。", + "name": "救急ステーションの地図", + "presets": { + "0": { + "description": "救急ステーション(消防署)をマップに追加する", + "title": "救急ステーション(消防署)" + } + }, + "tagRenderings": { + "ambulance-agency": { + "question": "このステーションを運営しているのはどこですか?", + "render": "このステーションは{operator}によって運営されています。" + }, + "ambulance-name": { + "question": "この救急ステーションの名前は何ですか?", + "render": "このステーションの名前は{name}です。" + }, + "ambulance-operator-type": { + "mappings": { + "0": { + "then": "ステーションは自治体が運営する。" + }, + "1": { + "then": "任意団体やコミュニティが運営しているステーションである。" + }, + "2": { + "then": "公益団体が運営しているステーションである。" + }, + "3": { + "then": "個人が運営しているステーションである。" + } + }, + "question": "ステーションの運営の分類は?", + "render": "運営者は、{operator:type} です。" + }, + "ambulance-place": { + "question": "このステーションの住所は?(例: 地区、村、または町の名称)", + "render": "このステーションは{addr:place}にあります。" + }, + "ambulance-street": { + "question": " 救急ステーションの所在地はどこですか?", + "render": "{addr:street} 沿いにあります。" + } + }, + "title": { + "render": "救急ステーション" + } + }, + "extinguisher": { + "description": "消火栓を表示するマップレイヤ。", + "name": "消火器の地図です。", + "presets": { + "0": { + "description": "消火器は、火災を止めるために使用される小型で携帯可能な装置である", + "title": "消火器" + } + }, + "tagRenderings": { + "extinguisher-location": { + "mappings": { + "0": { + "then": "屋内にある。" + }, + "1": { + "then": "屋外にある。" + } + }, + "question": "どこにあるんですか?", + "render": "場所:{location}" + } + }, + "title": { + "render": "消火器" + } + }, + "fire_stations": { + "description": "消防署を表示するためのマップレイヤ。", + "name": "消防署の地図", + "presets": { + "0": { + "description": "消防署は、運転していないときに消防車や消防士がいる場所です。", + "title": "消防署" + } + }, + "tagRenderings": { + "station-agency": { + "mappings": { + "0": { + "then": "消防局(消防庁)" + } + }, + "question": "このステーションを運営しているのはどこですか?", + "render": "このステーションは{operator}によって運営されています。" + }, + "station-name": { + "question": "この消防署の名前は何ですか?", + "render": "このステーションの名前は{name}です。" + }, + "station-operator": { + "mappings": { + "0": { + "then": "ステーションは自治体が運営する。" + }, + "1": { + "then": "任意団体やコミュニティが運営しているステーションである。" + }, + "2": { + "then": "公益団体が運営しているステーションである。" + }, + "3": { + "then": "個人が運営しているステーションである。" + } + }, + "question": "ステーションの運営の分類は?", + "render": "運営者は、{operator:type} です。" + }, + "station-place": { + "question": "このステーションの住所は?(例: 地区、村、または町の名称)", + "render": "このステーションは{addr:place}にあります。" + }, + "station-street": { + "question": " 救急ステーションの所在地はどこですか?", + "render": "{addr:street} 沿いにあります。" + } + }, + "title": { + "render": "消防署" + } + }, + "hydrants": { "description": "消火栓を表示するマップレイヤ。", "name": "消火栓の地図", "presets": { @@ -711,7 +841,7 @@ } }, "tagRenderings": { - "0": { + "hydrant-color": { "mappings": { "0": { "then": "消火栓の色は不明です。" @@ -726,7 +856,22 @@ "question": "消火栓の色は何色ですか?", "render": "消火栓の色は{color}です" }, - "1": { + "hydrant-state": { + "mappings": { + "0": { + "then": "消火栓は(完全にまたは部分的に)機能しています。" + }, + "1": { + "then": "消火栓は使用できません。" + }, + "2": { + "then": "消火栓が撤去されました。" + } + }, + "question": "消火栓のライフサイクルステータスを更新します。", + "render": "ライフサイクルステータス" + }, + "hydrant-type": { "mappings": { "0": { "then": "消火栓の種類は不明です。" @@ -746,156 +891,11 @@ }, "question": "どんな消火栓なんですか?", "render": " 消火栓のタイプ:{fire_hydrant:type}" - }, - "2": { - "mappings": { - "0": { - "then": "消火栓は(完全にまたは部分的に)機能しています。" - }, - "1": { - "then": "消火栓は使用できません。" - }, - "2": { - "then": "消火栓が撤去されました。" - } - }, - "question": "消火栓のライフサイクルステータスを更新します。", - "render": "ライフサイクルステータス" } }, "title": { "render": "消火栓" } - }, - "1": { - "description": "消火栓を表示するマップレイヤ。", - "name": "消火器の地図です。", - "presets": { - "0": { - "description": "消火器は、火災を止めるために使用される小型で携帯可能な装置である", - "title": "消火器" - } - }, - "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "屋内にある。" - }, - "1": { - "then": "屋外にある。" - } - }, - "question": "どこにあるんですか?", - "render": "場所:{location}" - } - }, - "title": { - "render": "消火器" - } - }, - "2": { - "description": "消防署を表示するためのマップレイヤ。", - "name": "消防署の地図", - "presets": { - "0": { - "description": "消防署は、運転していないときに消防車や消防士がいる場所です。", - "title": "消防署" - } - }, - "tagRenderings": { - "0": { - "question": "この消防署の名前は何ですか?", - "render": "このステーションの名前は{name}です。" - }, - "1": { - "question": " 救急ステーションの所在地はどこですか?", - "render": "{addr:street} 沿いにあります。" - }, - "2": { - "question": "このステーションの住所は?(例: 地区、村、または町の名称)", - "render": "このステーションは{addr:place}にあります。" - }, - "3": { - "mappings": { - "0": { - "then": "消防局(消防庁)" - } - }, - "question": "このステーションを運営しているのはどこですか?", - "render": "このステーションは{operator}によって運営されています。" - }, - "4": { - "mappings": { - "0": { - "then": "ステーションは自治体が運営する。" - }, - "1": { - "then": "任意団体やコミュニティが運営しているステーションである。" - }, - "2": { - "then": "公益団体が運営しているステーションである。" - }, - "3": { - "then": "個人が運営しているステーションである。" - } - }, - "question": "ステーションの運営の分類は?", - "render": "運営者は、{operator:type} です。" - } - }, - "title": { - "render": "消防署" - } - }, - "3": { - "description": "救急ステーションは、救急車、医療機器、個人用保護具、およびその他の医療用品を保管する場所です。", - "name": "救急ステーションの地図", - "presets": { - "0": { - "description": "救急ステーション(消防署)をマップに追加する", - "title": "救急ステーション(消防署)" - } - }, - "tagRenderings": { - "0": { - "question": "この救急ステーションの名前は何ですか?", - "render": "このステーションの名前は{name}です。" - }, - "1": { - "question": " 救急ステーションの所在地はどこですか?", - "render": "{addr:street} 沿いにあります。" - }, - "2": { - "question": "このステーションの住所は?(例: 地区、村、または町の名称)", - "render": "このステーションは{addr:place}にあります。" - }, - "3": { - "question": "このステーションを運営しているのはどこですか?", - "render": "このステーションは{operator}によって運営されています。" - }, - "4": { - "mappings": { - "0": { - "then": "ステーションは自治体が運営する。" - }, - "1": { - "then": "任意団体やコミュニティが運営しているステーションである。" - }, - "2": { - "then": "公益団体が運営しているステーションである。" - }, - "3": { - "then": "個人が運営しているステーションである。" - } - }, - "question": "ステーションの運営の分類は?", - "render": "運営者は、{operator:type} です。" - } - }, - "title": { - "render": "救急ステーション" - } } }, "shortDescription": "消火栓、消火器、消防署消火栓、消火器、消防署、および救急ステーションを表示します。", @@ -918,7 +918,7 @@ "shops": { "description": "この地図には店の基本情報を記入したり営業時間や電話番号を追加することができます", "layers": { - "0": { + "shops": { "description": "ショップ", "name": "店", "presets": { @@ -928,10 +928,22 @@ } }, "tagRenderings": { - "1": { + "shops-email": { + "question": "このお店のメールアドレスは何ですか?", + "render": "{email}" + }, + "shops-name": { "question": "このお店の名前は何ですか?" }, - "2": { + "shops-opening_hours": { + "question": "この店の営業時間は何時から何時までですか?", + "render": "{opening_hours_table(opening_hours)}" + }, + "shops-phone": { + "question": "電話番号は何番ですか?", + "render": "{phone}" + }, + "shops-shop": { "mappings": { "0": { "then": "コンビニエンスストア" @@ -958,21 +970,9 @@ "question": "このお店では何を売っていますか?", "render": "こちらのお店では{shop}を販売しております" }, - "3": { - "question": "電話番号は何番ですか?", - "render": "{phone}" - }, - "4": { + "shops-website": { "question": "このお店のホームページは何ですか?", "render": "{website}" - }, - "5": { - "question": "このお店のメールアドレスは何ですか?", - "render": "{email}" - }, - "6": { - "question": "この店の営業時間は何時から何時までですか?", - "render": "{opening_hours_table(opening_hours)}" } }, "title": { diff --git a/langs/themes/nb_NO.json b/langs/themes/nb_NO.json index 84792b812..35fb78455 100644 --- a/langs/themes/nb_NO.json +++ b/langs/themes/nb_NO.json @@ -4,7 +4,7 @@ }, "artwork": { "layers": { - "0": { + "artwork": { "name": "Kunstverk", "presets": { "0": { @@ -12,7 +12,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Hvilken artist lagde dette?", + "render": "Laget av {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Arkitektur" @@ -54,15 +58,11 @@ "question": "Hvilken type kunstverk er dette?", "render": "Dette er et kunstverk av typen {artwork_type}" }, - "2": { - "question": "Hvilken artist lagde dette?", - "render": "Laget av {artist_name}" - }, - "3": { + "artwork-website": { "question": "Finnes det en nettside med mer info om dette kunstverket?", "render": "Mer info er å finne på denne nettsiden" }, - "4": { + "artwork-wikidata": { "question": "Hvilken Wikipedia-oppføring samsvarer med dette kunstverket?", "render": "Samsvarer med {wikidata}" } @@ -82,20 +82,23 @@ }, "campersite": { "layers": { - "0": { + "caravansites": { "tagRenderings": { - "2": { + "caravansites-charge": { + "question": "pø", + "render": "Dette stedet tar {charge}" + }, + "caravansites-description": { + "render": "Flere detaljer om dette stedet: {description}" + }, + "caravansites-fee": { "mappings": { "1": { "then": "Kan brukes gratis" } } }, - "3": { - "question": "pø", - "render": "Dette stedet tar {charge}" - }, - "8": { + "caravansites-toilets": { "mappings": { "0": { "then": "Dette stedet har toalettfasiliteter" @@ -106,12 +109,9 @@ }, "question": "Har dette stedet toaletter?" }, - "9": { + "caravansites-website": { "question": "Har dette stedet en nettside?", "render": "Offisiell nettside: {website}" - }, - "11": { - "render": "Flere detaljer om dette stedet: {description}" } } } @@ -119,7 +119,19 @@ }, "climbing": { "layers": { - "0": { + "climbing": { + "description": "En klatremulighet", + "presets": { + "0": { + "description": "En klatremulighet", + "title": "Klatremulighet" + } + }, + "title": { + "render": "Klatremulighet" + } + }, + "climbing_club": { "description": "En klatreklubb eller organisasjoner", "name": "Klatreklubb", "presets": { @@ -132,10 +144,10 @@ "render": "Klatreklubb" } }, - "2": { + "climbing_route": { "name": "Klatreruter", "tagRenderings": { - "4": { + "Length": { "render": "Denne ruten er {canonical(climbing:length)} lang" } }, @@ -143,23 +155,11 @@ "render": "Klatrerute" } }, - "3": { - "description": "En klatremulighet", - "presets": { - "0": { - "description": "En klatremulighet", - "title": "Klatremulighet" - } - }, - "title": { - "render": "Klatremulighet" - } - }, - "4": { + "maybe_climbing": { "description": "En klatremulighet?", "name": "Klatremuligheter?", "tagRenderings": { - "2": { + "climbing-possible": { "mappings": { "0": { "then": "Klatring er ikke mulig her" @@ -196,15 +196,15 @@ }, "cyclestreets": { "layers": { - "1": { + "all_streets": { + "description": "Lag for å markere hvilken som helst gate som sykkelvei", + "name": "Alle gater" + }, + "toekomstige_fietsstraat": { "name": "Fremtidig sykkelvei", "title": { "render": "Fremtidig sykkelvei" } - }, - "2": { - "description": "Lag for å markere hvilken som helst gate som sykkelvei", - "name": "Alle gater" } }, "roamingRenderings": { @@ -230,9 +230,9 @@ }, "facadegardens": { "layers": { - "0": { + "facadegardens": { "tagRenderings": { - "2": { + "facadegardens-sunshine": { "mappings": { "1": { "then": "Denne hagen er i delvis skygge" @@ -248,25 +248,7 @@ }, "hailhydrant": { "layers": { - "0": { - "description": "Kartlag for å vise brannhydranter.", - "name": "Kart over brannhydranter", - "presets": { - "0": { - "title": "Brannhydrant" - } - }, - "tagRenderings": { - "0": { - "question": "Hvilken farge har brannhydranten?", - "render": "Brannhydranter er {colour}" - } - }, - "title": { - "render": "Brannhydrant" - } - }, - "1": { + "extinguisher": { "description": "Kartlag for å vise brannslokkere.", "name": "Kart over brannhydranter", "presets": { @@ -278,11 +260,29 @@ "render": "Brannslokkere" } }, - "2": { + "fire_stations": { "name": "Kart over brannstasjoner", "title": { "render": "Brannstasjon" } + }, + "hydrants": { + "description": "Kartlag for å vise brannhydranter.", + "name": "Kart over brannhydranter", + "presets": { + "0": { + "title": "Brannhydrant" + } + }, + "tagRenderings": { + "hydrant-color": { + "question": "Hvilken farge har brannhydranten?", + "render": "Brannhydranter er {colour}" + } + }, + "title": { + "render": "Brannhydrant" + } } } } diff --git a/langs/themes/nl.json b/langs/themes/nl.json index c35eab161..53bc832ea 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -10,7 +10,7 @@ "artwork": { "description": "Welkom op de open kunstwerken-kaart, een kaart van standbeelden, bustes, graffiti en andere kunstwerken over de hele wereld", "layers": { - "0": { + "artwork": { "description": "Verschillende soorten kunstwerken", "name": "Kunstwerken", "presets": { @@ -19,7 +19,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Welke kunstenaar creëerde dit kunstwerk?", + "render": "Gecreëerd door {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Architectuur" @@ -61,15 +65,11 @@ "question": "Wat voor soort kunstwerk is dit?", "render": "Dit is een {artwork_type}" }, - "2": { - "question": "Welke kunstenaar creëerde dit kunstwerk?", - "render": "Gecreëerd door {artist_name}" - }, - "3": { + "artwork-website": { "question": "Is er een website met meer informatie over dit kunstwerk?", "render": "Meer informatie op deze website" }, - "4": { + "artwork-wikidata": { "question": "Welk Wikidata-item beschrijft dit kunstwerk?", "render": "Komt overeen met {wikidata}" } @@ -108,7 +108,28 @@ "description": "logo-groenmeld je aan voor e-mailupdates.", "descriptionTail": "

Tips

  • Over groen ingekleurde gebieden weten we alles wat we willen weten.
  • Bij rood ingekleurde gebieden ontbreekt nog heel wat info: klik een gebied aan en beantwoord de vragen.
  • Je kan altijd een vraag overslaan als je het antwoord niet weet of niet zeker bent
  • Je kan altijd een foto toevoegen
  • Je kan ook zelf een gebied toevoegen door op de kaart te klikken
  • Open buurtnatuur.be op je smartphone om al wandelend foto's te maken en vragen te beantwoorden

De oorspronkelijke data komt van OpenStreetMap en je antwoorden worden daar bewaard.
Omdat iedereen vrij kan meewerken aan dit project, kunnen we niet garanderen dat er geen fouten opduiken.Kan je hier niet aanpassen wat je wilt, dan kan je dat zelf via OpenStreetMap.org doen. Groen kan geen enkele verantwoordelijkheid nemen over de kaart.

Je privacy is belangrijk. We tellen wel hoeveel gebruikers deze website bezoeken. We plaatsen een cookie waar geen persoonlijke informatie in bewaard wordt. Als je inlogt, komt er een tweede cookie bij met je inloggegevens.
", "layers": { - "0": { + "forest": { + "description": "Een bos is een verzameling bomen, al dan niet als productiehout.", + "name": "Bos", + "presets": { + "0": { + "description": "Voeg een ontbrekend bos toe aan de kaart", + "title": "Bos" + } + }, + "title": { + "mappings": { + "0": { + "then": "{name:nl}" + }, + "1": { + "then": "{name}" + } + }, + "render": "Bos" + } + }, + "nature_reserve_buurtnatuur": { "description": "Een natuurgebied is een gebied waar actief ruimte gemaakt word voor de natuur. Typisch zijn deze in beheer van Natuurpunt of het Agentschap Natuur en Bos of zijn deze erkend door de overheid.", "name": "Natuurgebied", "presets": { @@ -129,7 +150,7 @@ "render": "Natuurgebied" } }, - "1": { + "parks": { "description": "Een park is een publiek toegankelijke, groene ruimte binnen de stad. Ze is typisch ingericht voor recreatief gebruik, met (verharde) wandelpaden, zitbanken, vuilnisbakken, een gezellig vijvertje, ...", "name": "Park", "presets": { @@ -149,27 +170,6 @@ }, "render": "Park" } - }, - "2": { - "description": "Een bos is een verzameling bomen, al dan niet als productiehout.", - "name": "Bos", - "presets": { - "0": { - "description": "Voeg een ontbrekend bos toe aan de kaart", - "title": "Bos" - } - }, - "title": { - "mappings": { - "0": { - "then": "{name:nl}" - }, - "1": { - "then": "{name}" - } - }, - "render": "Bos" - } } }, "roamingRenderings": { @@ -245,15 +245,15 @@ "campersite": { "description": "Deze website verzamelt en toont alle officiële plaatsen waar een camper mag overnachten en afvalwater kan lozen. Ook jij kan extra gegevens toevoegen, zoals welke services er geboden worden en hoeveel dit kot, ook afbeeldingen en reviews kan je toevoegen. De data wordt op OpenStreetMap opgeslagen en is dus altijd gratis te hergebruiken, ook door andere applicaties.", "layers": { - "0": { + "caravansites": { "description": "camperplaatsen", "name": "Camperplaatsen", "tagRenderings": { - "1": { - "question": "Wat is de naam van deze plaats?", - "render": "Deze plaats heet {name}" + "caravansites-charge": { + "question": "Hoeveel kost deze plaats?", + "render": "Deze plaats vraagt {charge}" }, - "2": { + "caravansites-fee": { "mappings": { "0": { "then": "Gebruik is betalend" @@ -264,11 +264,11 @@ }, "question": "Moet men betalen om deze camperplaats te gebruiken?" }, - "3": { - "question": "Hoeveel kost deze plaats?", - "render": "Deze plaats vraagt {charge}" + "caravansites-name": { + "question": "Wat is de naam van deze plaats?", + "render": "Deze plaats heet {name}" }, - "9": { + "caravansites-website": { "render": "Officiële website: : {website}" } }, @@ -293,88 +293,7 @@ "description": "Op deze kaart vind je verschillende klimgelegenheden, zoals klimzalen, bolderzalen en klimmen in de natuur", "descriptionTail": "De klimkaart is oorspronkelijk gemaakt door Christian Neumann op kletterspots.de.", "layers": { - "0": { - "description": "Een klimclub of organisatie", - "name": "Klimclub", - "presets": { - "0": { - "description": "Een klimclub", - "title": "Klimclub" - }, - "1": { - "description": "Een VZW die werkt rond klimmen", - "title": "Een klimorganisatie" - } - }, - "tagRenderings": { - "0": { - "question": "Wat is de naam van deze klimclub?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Klimorganisatie" - } - }, - "render": "Klimclub" - } - }, - "1": { - "description": "Een klimzaal", - "name": "Klimzalen", - "tagRenderings": { - "3": { - "question": "Wat is de naam van dit Klimzaal?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Klimzaal {name}" - } - }, - "render": "Klimzaal" - } - }, - "2": { - "name": "Klimroute", - "presets": { - "0": { - "title": "Klimroute" - } - }, - "tagRenderings": { - "3": { - "mappings": { - "0": { - "then": "Deze klimroute heeft geen naam" - } - }, - "question": "Hoe heet deze klimroute?", - "render": "{name}" - }, - "4": { - "question": "Hoe lang is deze klimroute (in meters)?", - "render": "Deze klimroute is {canonical(climbing:length)} lang" - }, - "5": { - "question": "Hoe moeilijk is deze klimroute volgens het Franse/Belgische systeem?", - "render": "De klimmoeilijkheid is {climbing:grade:french} volgens het Franse/Belgische systeem" - } - }, - "title": { - "mappings": { - "0": { - "then": "Klimroute {name}" - } - }, - "render": "Klimroute" - } - }, - "3": { + "climbing": { "description": "Een klimgelegenheid", "name": "Klimgelegenheden", "presets": { @@ -384,7 +303,14 @@ } }, "tagRenderings": { - "6": { + "Rock type (crag/rock/cliff only)": { + "mappings": { + "0": { + "then": "Kalksteen" + } + } + }, + "name": { "mappings": { "0": { "then": "Dit Klimgelegenheid heeft geen naam" @@ -392,13 +318,6 @@ }, "question": "Wat is de naam van dit Klimgelegenheid?", "render": "{name}" - }, - "8": { - "mappings": { - "0": { - "then": "Kalksteen" - } - } } }, "title": { @@ -416,14 +335,95 @@ "render": "Klimgelegenheid" } }, - "4": { + "climbing_club": { + "description": "Een klimclub of organisatie", + "name": "Klimclub", + "presets": { + "0": { + "description": "Een klimclub", + "title": "Klimclub" + }, + "1": { + "description": "Een VZW die werkt rond klimmen", + "title": "Een klimorganisatie" + } + }, + "tagRenderings": { + "climbing_club-name": { + "question": "Wat is de naam van deze klimclub?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Klimorganisatie" + } + }, + "render": "Klimclub" + } + }, + "climbing_gym": { + "description": "Een klimzaal", + "name": "Klimzalen", + "tagRenderings": { + "name": { + "question": "Wat is de naam van dit Klimzaal?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Klimzaal {name}" + } + }, + "render": "Klimzaal" + } + }, + "climbing_route": { + "name": "Klimroute", + "presets": { + "0": { + "title": "Klimroute" + } + }, + "tagRenderings": { + "Difficulty": { + "question": "Hoe moeilijk is deze klimroute volgens het Franse/Belgische systeem?", + "render": "De klimmoeilijkheid is {climbing:grade:french} volgens het Franse/Belgische systeem" + }, + "Length": { + "question": "Hoe lang is deze klimroute (in meters)?", + "render": "Deze klimroute is {canonical(climbing:length)} lang" + }, + "Name": { + "mappings": { + "0": { + "then": "Deze klimroute heeft geen naam" + } + }, + "question": "Hoe heet deze klimroute?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Klimroute {name}" + } + }, + "render": "Klimroute" + } + }, + "maybe_climbing": { "description": "Een klimgelegenheid?", "name": "Klimgelegenheiden?", "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" }, - "2": { + "climbing-possible": { "mappings": { "0": { "then": "Klimmen is hier niet mogelijk" @@ -566,11 +566,18 @@ "cyclestreets": { "description": "Een fietsstraat is een straat waar
  • automobilisten geen fietsers mogen inhalen
  • Er een maximumsnelheid van 30km/u geldt
  • Fietsers gemotoriseerde voertuigen links mogen inhalen
  • Fietsers nog steeds voorrang aan rechts moeten verlenen - ook aan auto's en voetgangers op het zebrapad


Op deze open kaart kan je alle gekende fietsstraten zien en kan je ontbrekende fietsstraten aanduiden. Om de kaart aan te passen, moet je je aanmelden met OpenStreetMap en helemaal inzoomen tot straatniveau. ", "layers": { - "0": { + "all_streets": { + "description": "Laag waar je een straat als fietsstraat kan markeren", + "name": "Alle straten", + "title": { + "render": "Straat" + } + }, + "fietsstraat": { "description": "Een fietsstraat is een straat waar gemotoriseerd verkeer een fietser niet mag inhalen.", "name": "Fietsstraten" }, - "1": { + "toekomstige_fietsstraat": { "description": "Deze straat wordt binnenkort een fietsstraat", "name": "Toekomstige fietsstraat", "title": { @@ -581,13 +588,6 @@ }, "render": "Toekomstige fietsstraat" } - }, - "2": { - "description": "Laag waar je een straat als fietsstraat kan markeren", - "name": "Alle straten", - "title": { - "render": "Straat" - } } }, "roamingRenderings": { @@ -627,7 +627,7 @@ "facadegardens": { "description": "Ontharde voortuintjes, groene gevels en bomen ín de stad brengen naast rust ook een mooiere stad, een grotere biodiversiteit, een verkoelend effect en een betere luchtkwaliteit.
Klimaan VZW en 'Mechelen Klimaatneutraal' willen met het project Klim(t)aan je Gevel bestaande en nieuwe geveltuintjes in kaart brengen als voorbeeld voor mensen zelf een tuintje willen aanleggen of voor stadwandelaars die houden van de natuur.
Meer info over het project op klimaan.be.", "layers": { - "0": { + "facadegardens": { "description": "Geveltuintjes", "name": "Geveltuintjes", "presets": { @@ -637,40 +637,15 @@ } }, "tagRenderings": { - "1": { + "facadegardens-description": { + "question": "Aanvullende omschrijving van de tuin (indien nodig, en voor zover nog niet omschreven hierboven)", + "render": "Meer details: {description}" + }, + "facadegardens-direction": { "question": "Hoe is de tuin georiënteerd?", "render": "Oriëntatie: {direction} (waarbij 0=N en 90=O)" }, - "2": { - "mappings": { - "0": { - "then": "Het is een volle zon tuintje" - }, - "1": { - "then": "Het is een halfschaduw tuintje" - }, - "2": { - "then": "Het is een schaduw tuintje" - } - }, - "question": "Ligt de tuin in zon/half schaduw of schaduw?" - }, - "3": { - "mappings": { - "0": { - "then": "Er is een regenton" - }, - "1": { - "then": "Er is geen regenton" - } - }, - "question": "Is er een regenton voorzien bij het tuintje?" - }, - "4": { - "question": "Wanneer werd de tuin aangelegd? (vul gewoon een jaartal in)", - "render": "Aanlegdatum van de tuin: {start_date}" - }, - "5": { + "facadegardens-edible": { "mappings": { "0": { "then": "Er staan eetbare planten" @@ -681,7 +656,7 @@ }, "question": "Staan er eetbare planten?" }, - "6": { + "facadegardens-plants": { "mappings": { "0": { "then": "Er staat een klimplant" @@ -698,9 +673,34 @@ }, "question": "Wat voor planten staan hier?" }, - "7": { - "question": "Aanvullende omschrijving van de tuin (indien nodig, en voor zover nog niet omschreven hierboven)", - "render": "Meer details: {description}" + "facadegardens-rainbarrel": { + "mappings": { + "0": { + "then": "Er is een regenton" + }, + "1": { + "then": "Er is geen regenton" + } + }, + "question": "Is er een regenton voorzien bij het tuintje?" + }, + "facadegardens-start_date": { + "question": "Wanneer werd de tuin aangelegd? (vul gewoon een jaartal in)", + "render": "Aanlegdatum van de tuin: {start_date}" + }, + "facadegardens-sunshine": { + "mappings": { + "0": { + "then": "Het is een volle zon tuintje" + }, + "1": { + "then": "Het is een halfschaduw tuintje" + }, + "2": { + "then": "Het is een schaduw tuintje" + } + }, + "question": "Ligt de tuin in zon/half schaduw of schaduw?" } }, "title": { @@ -719,7 +719,7 @@ "description": "Op deze kaart vind je je favoriete frituur!", "layers": { "0": { - "override": { + "friture": { "name": "Frituren" } } @@ -729,19 +729,7 @@ "fruit_trees": { "description": "Op deze kaart vindt je boomgaarden en fruitbomen", "layers": { - "0": { - "name": "Boomgaarden", - "presets": { - "0": { - "description": "Voeg een boomgaard toe (als punt - omtrek nog te tekenen)", - "title": "Boomgaard" - } - }, - "title": { - "render": "Boomgaard" - } - }, - "1": { + "fruitboom": { "description": "Een boom", "name": "Boom", "presets": { @@ -751,26 +739,38 @@ } }, "tagRenderings": { - "0": { - "question": "Wat is de soort van deze boom (in het Nederlands)?", - "render": "De soort is {species:nl}" - }, - "1": { - "question": "Wat is het taxon (ras) van deze boom?", - "render": "Het ras (taxon) van deze boom is {taxon}" - }, - "2": { + "fruitboom-description": { "question": "Welke beschrijving past bij deze boom?", "render": "Beschrijving: {description}" }, - "3": { + "fruitboom-ref": { "question": "Is er een refernetienummer?", "render": "Referentienummer: {ref}" + }, + "fruitboom-species:nl": { + "question": "Wat is de soort van deze boom (in het Nederlands)?", + "render": "De soort is {species:nl}" + }, + "fruitboom-taxon": { + "question": "Wat is het taxon (ras) van deze boom?", + "render": "Het ras (taxon) van deze boom is {taxon}" } }, "title": { "render": "Boom" } + }, + "orchards": { + "name": "Boomgaarden", + "presets": { + "0": { + "description": "Voeg een boomgaard toe (als punt - omtrek nog te tekenen)", + "title": "Boomgaard" + } + }, + "title": { + "render": "Boomgaard" + } } }, "shortDescription": "Boomgaarden en fruitbomen", @@ -783,27 +783,11 @@ "grb": { "description": "GRB Fixup", "layers": { - "0": { + "grb-fixmes": { "description": "Dit gebouw heeft een foutmelding", "name": "Fixmes op gebouwen", "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "Geen huisnummer" - } - }, - "question": "Wat is het huisnummer?", - "render": "Het huisnummer is {addr:housenumber}" - }, - "1": { - "render": "De wooneenheid-aanduiding is {addr:unit} " - }, - "2": { - "question": "Wat is de straat?", - "render": "De straat is {addr:street}" - }, - "3": { + "grb-fixme": { "mappings": { "0": { "then": "Geen fixme" @@ -812,9 +796,25 @@ "question": "Wat zegt de fixme?", "render": "De fixme is {fixme}" }, - "4": { + "grb-housenumber": { + "mappings": { + "0": { + "then": "Geen huisnummer" + } + }, + "question": "Wat is het huisnummer?", + "render": "Het huisnummer is {addr:housenumber}" + }, + "grb-min-level": { "question": "Hoeveel verdiepingen ontbreken?", "render": "Dit gebouw begint maar op de {building:min_level} verdieping" + }, + "grb-street": { + "question": "Wat is de straat?", + "render": "De straat is {addr:street}" + }, + "grb-unit": { + "render": "De wooneenheid-aanduiding is {addr:unit} " } }, "title": { @@ -852,7 +852,7 @@ }, "openwindpowermap": { "layers": { - "0": { + "windturbine": { "name": "windturbine", "presets": { "0": { @@ -911,7 +911,7 @@ }, "shops": { "layers": { - "0": { + "shops": { "description": "Een winkel", "name": "Winkel", "presets": { @@ -921,10 +921,19 @@ } }, "tagRenderings": { - "1": { + "shops-email": { + "question": "Wat is het e-mailadres van deze winkel?" + }, + "shops-name": { "question": "Wat is de naam van deze winkel?" }, - "2": { + "shops-opening_hours": { + "question": "Wat zijn de openingsuren van deze winkel?" + }, + "shops-phone": { + "question": "Wat is het telefoonnummer?" + }, + "shops-shop": { "mappings": { "1": { "then": "Supermarkt" @@ -937,17 +946,8 @@ } } }, - "3": { - "question": "Wat is het telefoonnummer?" - }, - "4": { + "shops-website": { "question": "Wat is de website van deze winkel?" - }, - "5": { - "question": "Wat is het e-mailadres van deze winkel?" - }, - "6": { - "question": "Wat zijn de openingsuren van deze winkel?" } }, "title": { @@ -959,13 +959,23 @@ "speelplekken": { "description": "

Welkom bij de Groendoener!

De Zuidrand dat is spelen, ravotten, chillen, wandelen,… in het groen. Meer dan 200 grote en kleine speelplekken liggen er in parken, in bossen en op pleintjes te wachten om ontdekt te worden. De verschillende speelplekken werden getest én goedgekeurd door kinder- en jongerenreporters uit de Zuidrand. Met leuke challenges dagen de reporters jou uit om ook op ontdekking te gaan. Klik op een speelplek op de kaart, bekijk het filmpje en ga op verkenning!

Het project groendoener kadert binnen het strategisch project Beleefbare Open Ruimte in de Antwerpse Zuidrand en is een samenwerking tussen het departement Leefmilieu van provincie Antwerpen, Sportpret vzw, een OpenStreetMap-België Consultent en Createlli vzw. Het project kwam tot stand met steun van Departement Omgeving van de Vlaamse Overheid.
", "layers": { - "7": { + "walking_routes": { "name": "Wandelroutes van provincie Antwerpen", "tagRenderings": { - "0": { + "walk-description": { + "render": "

Korte beschrijving:

{description}" + }, + "walk-length": { "render": "Deze wandeling is {_length:km}km lang" }, - "1": { + "walk-operator": { + "question": "Wie beheert deze wandeling en plaatst dus de signalisatiebordjes?" + }, + "walk-operator-email": { + "question": "Naar wie kan men emailen bij problemen rond signalisatie?", + "render": "Bij problemen met signalisatie kan men emailen naar {operator:email}" + }, + "walk-type": { "mappings": { "0": { "then": "Dit is een internationale wandelroute" @@ -980,16 +990,6 @@ "then": "Dit is een lokale wandelroute" } } - }, - "2": { - "render": "

Korte beschrijving:

{description}" - }, - "3": { - "question": "Wie beheert deze wandeling en plaatst dus de signalisatiebordjes?" - }, - "4": { - "question": "Naar wie kan men emailen bij problemen rond signalisatie?", - "render": "Bij problemen met signalisatie kan men emailen naar {operator:email}" } } } diff --git a/langs/themes/pt_BR.json b/langs/themes/pt_BR.json index 1b202d8aa..cc97313f2 100644 --- a/langs/themes/pt_BR.json +++ b/langs/themes/pt_BR.json @@ -15,7 +15,7 @@ }, "campersite": { "layers": { - "0": { + "caravansites": { "description": "Locais de acampamento", "name": "Locais de acampamento", "presets": { @@ -24,11 +24,18 @@ } }, "tagRenderings": { - "1": { - "question": "Qual o nome deste lugar?", - "render": "Este lugar é chamado de {name}" + "caravansites-capacity": { + "question": "Quantos campistas podem ficar aqui? (pule se não houver um número óbvio de vagas ou veículos permitidos)", + "render": "{capacity} campistas podem usar este lugar ao mesmo tempo" }, - "2": { + "caravansites-charge": { + "question": "Quanto este lugar cobra?", + "render": "Este lugar cobra {charge}" + }, + "caravansites-description": { + "render": "Mais detalhes sobre este lugar: {description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "Você precisa pagar para usar" @@ -39,26 +46,7 @@ }, "question": "Este lugar cobra alguma taxa?" }, - "3": { - "question": "Quanto este lugar cobra?", - "render": "Este lugar cobra {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "Este local tem uma estação de aterro sanitário" - }, - "1": { - "then": "Este local não tem uma estação de aterro sanitário" - } - }, - "question": "Este local tem uma estação de aterro sanitário?" - }, - "5": { - "question": "Quantos campistas podem ficar aqui? (pule se não houver um número óbvio de vagas ou veículos permitidos)", - "render": "{capacity} campistas podem usar este lugar ao mesmo tempo" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "Há acesso à internet" @@ -72,7 +60,7 @@ }, "question": "Este lugar fornece acesso a internet?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "Você precisa pagar um extra pelo acesso à internet" @@ -83,22 +71,7 @@ }, "question": "Você tem que pagar pelo acesso à internet?" }, - "8": { - "mappings": { - "0": { - "then": "Este lugar tem banheiros" - }, - "1": { - "then": "Este lugar não tem banheiros" - } - }, - "question": "Este lugar tem banheiros?" - }, - "9": { - "question": "Este lugar tem um website?", - "render": "Site oficial: {website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "Sim, há alguns pontos para aluguel a longo prazo, mas você também pode ficar em uma base diária" @@ -109,8 +82,35 @@ }, "question": "Este lugar oferece vagas para aluguel a longo prazo?" }, - "11": { - "render": "Mais detalhes sobre este lugar: {description}" + "caravansites-name": { + "question": "Qual o nome deste lugar?", + "render": "Este lugar é chamado de {name}" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "Este local tem uma estação de aterro sanitário" + }, + "1": { + "then": "Este local não tem uma estação de aterro sanitário" + } + }, + "question": "Este local tem uma estação de aterro sanitário?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "Este lugar tem banheiros" + }, + "1": { + "then": "Este lugar não tem banheiros" + } + }, + "question": "Este lugar tem banheiros?" + }, + "caravansites-website": { + "question": "Este lugar tem um website?", + "render": "Site oficial: {website}" } }, "title": { @@ -122,11 +122,15 @@ "render": "Local de acampamento {name}" } }, - "1": { + "dumpstations": { "description": "Estações de despejo sanitário", "name": "Estações de despejo sanitário", "tagRenderings": { - "1": { + "dumpstations-charge": { + "question": "Quanto este lugar cobra?", + "render": "Este lugar cobra {charge}" + }, + "dumpstations-fee": { "mappings": { "0": { "then": "Você precisa pagar pelo uso" @@ -137,11 +141,7 @@ }, "question": "Este lugar cobra alguma taxa?" }, - "2": { - "question": "Quanto este lugar cobra?", - "render": "Este lugar cobra {charge}" - }, - "3": { + "dumpstations-waterpoint": { "mappings": { "0": { "then": "Este lugar tem um ponto de água" diff --git a/langs/themes/ru.json b/langs/themes/ru.json index e41b737a9..1c8f6076d 100644 --- a/langs/themes/ru.json +++ b/langs/themes/ru.json @@ -6,7 +6,7 @@ "artwork": { "description": "Добро пожаловать на Open Artwork Map, карту статуй, бюстов, граффити и других произведений искусства по всему миру", "layers": { - "0": { + "artwork": { "description": "Разнообразные произведения искусства", "name": "Произведения искусства", "presets": { @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "Какой художник создал это?", + "render": "Создано {artist_name}" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "Архитектура" @@ -57,15 +61,11 @@ "question": "К какому типу относится эта работа?", "render": "Это {artwork_type}" }, - "2": { - "question": "Какой художник создал это?", - "render": "Создано {artist_name}" - }, - "3": { + "artwork-website": { "question": "Есть ли сайт с более подробной информацией об этой работе?", "render": "Больше информации на этом сайте" }, - "4": { + "artwork-wikidata": { "question": "Какая запись в Wikidata соответсвует этой работе?", "render": "Запись об этой работе в wikidata: {wikidata}" } @@ -98,7 +98,7 @@ "campersite": { "description": "На этом сайте собраны все официальные места остановки кемперов и места, где можно сбросить серую и черную воду. Вы можете добавить подробную информацию о предоставляемых услугах и их стоимости. Добавлять фотографии и отзывы. Это веб-сайт и веб-приложение. Данные хранятся в OpenStreetMap, поэтому они будут бесплатными всегда и могут быть повторно использованы любым приложением.", "layers": { - "0": { + "caravansites": { "description": "площадки для кемпинга", "name": "Площадки для кемпинга", "presets": { @@ -108,11 +108,19 @@ } }, "tagRenderings": { - "1": { - "question": "Как называется это место?", - "render": "Это место называется {name}" + "caravansites-capacity": { + "question": "Сколько кемперов может здесь остановиться? (пропустите, если нет очевидного количества мест или разрешённых транспортных средств)", + "render": "{capacity} кемперов могут использовать это место одновременно" }, - "2": { + "caravansites-charge": { + "question": "Сколько это место взимает?", + "render": "Это место взимает {charge}" + }, + "caravansites-description": { + "question": "Хотели бы вы добавить общее описание этого места? (Не повторяйте информацию, которая уже написана выше или на которую вы уже ответили ранее. Пожалуйста, будьте объективны - мнения должны быть в отзывах)", + "render": "Более подробная информация об этом месте: {description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "За использование нужно платить" @@ -123,26 +131,7 @@ }, "question": "Взимается ли в этом месте плата?" }, - "3": { - "question": "Сколько это место взимает?", - "render": "Это место взимает {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "В этом кемпинге есть место для слива отходов из туалетных резервуаров" - }, - "1": { - "then": "В этом кемпинге нет места для слива отходов из туалетных резервуаров" - } - }, - "question": "В этом кемпинге есть место для слива отходов из туалетных резервуаров?" - }, - "5": { - "question": "Сколько кемперов может здесь остановиться? (пропустите, если нет очевидного количества мест или разрешённых транспортных средств)", - "render": "{capacity} кемперов могут использовать это место одновременно" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "Есть доступ в Интернет" @@ -156,7 +145,7 @@ }, "question": "Предоставляет ли это место доступ в Интернет?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "За доступ в Интернет нужно платить дополнительно" @@ -167,22 +156,7 @@ }, "question": "Нужно ли платить за доступ в Интернет?" }, - "8": { - "mappings": { - "0": { - "then": "В этом месте есть туалеты" - }, - "1": { - "then": "В этом месте нет туалетов" - } - }, - "question": "Здесь есть туалеты?" - }, - "9": { - "question": "Есть ли у этого места веб-сайт?", - "render": "Официальный сайт: {website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "Да, здесь есть места для долгосрочной аренды, но вы можете остановиться и на сутки" @@ -196,9 +170,35 @@ }, "question": "Предлагает ли эта площадка места для долгосрочной аренды?" }, - "11": { - "question": "Хотели бы вы добавить общее описание этого места? (Не повторяйте информацию, которая уже написана выше или на которую вы уже ответили ранее. Пожалуйста, будьте объективны - мнения должны быть в отзывах)", - "render": "Более подробная информация об этом месте: {description}" + "caravansites-name": { + "question": "Как называется это место?", + "render": "Это место называется {name}" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "В этом кемпинге есть место для слива отходов из туалетных резервуаров" + }, + "1": { + "then": "В этом кемпинге нет места для слива отходов из туалетных резервуаров" + } + }, + "question": "В этом кемпинге есть место для слива отходов из туалетных резервуаров?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "В этом месте есть туалеты" + }, + "1": { + "then": "В этом месте нет туалетов" + } + }, + "question": "Здесь есть туалеты?" + }, + "caravansites-website": { + "question": "Есть ли у этого места веб-сайт?", + "render": "Официальный сайт: {website}" } }, "title": { @@ -210,59 +210,11 @@ "render": "Место для кемпинга {name}" } }, - "1": { + "dumpstations": { "description": "Ассенизационные сливные станции", "name": "Места для слива отходов из туалетных резервуаров", "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "За использование нужно платить" - }, - "1": { - "then": "Можно использовать бесплатно" - } - }, - "question": "Взимается ли в этом месте плата?" - }, - "2": { - "question": "Сколько это место взимает?", - "render": "Это место взимает {charge}" - }, - "3": { - "mappings": { - "0": { - "then": "В этом месте есть водоснабжение" - }, - "1": { - "then": "В этом месте нет водоснабжения" - } - }, - "question": "Есть ли в этом месте водоснабжение?" - }, - "4": { - "mappings": { - "0": { - "then": "Вы можете утилизировать серую воду здесь" - }, - "1": { - "then": "Здесь нельзя утилизировать серую воду" - } - }, - "question": "Можно ли здесь утилизировать серую воду?" - }, - "5": { - "mappings": { - "0": { - "then": "Вы можете утилизировать отходы химических туалетов здесь" - }, - "1": { - "then": "Здесь нельзя утилизировать отходы химических туалетов" - } - }, - "question": "Можно ли здесь утилизировать отходы химических туалетов?" - }, - "6": { + "dumpstations-access": { "mappings": { "2": { "then": "Любой может воспользоваться этой станцией утилизации" @@ -273,9 +225,57 @@ }, "question": "Кто может использовать эту станцию утилизации?" }, - "7": { + "dumpstations-charge": { + "question": "Сколько это место взимает?", + "render": "Это место взимает {charge}" + }, + "dumpstations-chemical-waste": { + "mappings": { + "0": { + "then": "Вы можете утилизировать отходы химических туалетов здесь" + }, + "1": { + "then": "Здесь нельзя утилизировать отходы химических туалетов" + } + }, + "question": "Можно ли здесь утилизировать отходы химических туалетов?" + }, + "dumpstations-fee": { + "mappings": { + "0": { + "then": "За использование нужно платить" + }, + "1": { + "then": "Можно использовать бесплатно" + } + }, + "question": "Взимается ли в этом месте плата?" + }, + "dumpstations-grey-water": { + "mappings": { + "0": { + "then": "Вы можете утилизировать серую воду здесь" + }, + "1": { + "then": "Здесь нельзя утилизировать серую воду" + } + }, + "question": "Можно ли здесь утилизировать серую воду?" + }, + "dumpstations-network": { "question": "К какой сети относится эта станция? (пропустите, если неприменимо)", "render": "Эта станция - часть сети {network}" + }, + "dumpstations-waterpoint": { + "mappings": { + "0": { + "then": "В этом месте есть водоснабжение" + }, + "1": { + "then": "В этом месте нет водоснабжения" + } + }, + "question": "Есть ли в этом месте водоснабжение?" } }, "title": { @@ -298,7 +298,14 @@ "description": "На этой карте вы найдете различные возможности для скалолазания, такие как скалодромы, залы для боулдеринга и скалы на природе.", "descriptionTail": "Создатель карты скалолазания — Christian Neumann. Пожалуйста, пишите если у вас есть отзыв или вопросы.

Проект использует данные OpenStreetMap.

", "layers": { - "0": { + "climbing": { + "tagRenderings": { + "name": { + "render": "{name}" + } + } + }, + "climbing_club": { "name": "Клуб скалолазания", "presets": { "0": { @@ -307,7 +314,7 @@ } }, "tagRenderings": { - "0": { + "climbing_club-name": { "render": "{name}" } }, @@ -315,30 +322,23 @@ "render": "Клуб скалолазания" } }, - "1": { + "climbing_gym": { "tagRenderings": { - "3": { + "name": { "render": "{name}" } } }, - "2": { + "climbing_route": { "tagRenderings": { - "3": { + "Name": { "render": "{name}" } } }, - "3": { + "maybe_climbing": { "tagRenderings": { - "6": { - "render": "{name}" - } - } - }, - "4": { - "tagRenderings": { - "1": { + "climbing-opportunity-name": { "render": "{name}" } } @@ -370,7 +370,7 @@ }, "cyclestreets": { "layers": { - "2": { + "all_streets": { "name": "Все улицы", "title": { "render": "Улица" @@ -387,12 +387,16 @@ }, "facadegardens": { "layers": { - "0": { + "facadegardens": { "tagRenderings": { - "2": { - "question": "Сад расположен на солнечной стороне или в тени?" + "facadegardens-description": { + "question": "Дополнительная информация о саде (если требуется или еще не указана выше)", + "render": "Подробнее: {description}" }, - "3": { + "facadegardens-plants": { + "question": "Какие виды растений обитают здесь?" + }, + "facadegardens-rainbarrel": { "mappings": { "0": { "then": "Есть бочка с дождевой водой" @@ -402,15 +406,11 @@ } } }, - "4": { + "facadegardens-start_date": { "render": "Дата строительства сада: {start_date}" }, - "6": { - "question": "Какие виды растений обитают здесь?" - }, - "7": { - "question": "Дополнительная информация о саде (если требуется или еще не указана выше)", - "render": "Подробнее: {description}" + "facadegardens-sunshine": { + "question": "Сад расположен на солнечной стороне или в тени?" } } } @@ -421,58 +421,32 @@ }, "hailhydrant": { "layers": { - "0": { - "description": "Слой карты, отображающий пожарные гидранты.", - "name": "Карта пожарных гидрантов", + "ambulancestation": { + "name": "Карта станций скорой помощи", "presets": { "0": { - "title": "Пожарный гидрант" + "description": "Добавить станцию скорой помощи на карту", + "title": "Станция скорой помощи" } }, "tagRenderings": { - "0": { - "mappings": { - "0": { - "then": "Цвет гидранта не определён." - }, - "1": { - "then": "Гидрант жёлтого цвета." - }, - "2": { - "then": "Гидрант красного цвета." - } - }, - "question": "Какого цвета гидрант?", - "render": "Цвет гидранта {colour}" + "ambulance-name": { + "question": "Как называется эта станция скорой помощи?", + "render": "Эта станция называется {name}." }, - "1": { - "mappings": { - "0": { - "then": "Тип гидранта не определён." - }, - "3": { - "then": " Тип стены." - } - }, - "question": "К какому типу относится этот гидрант?", - "render": " Тип гидранта: {fire_hydrant:type}" + "ambulance-place": { + "question": "Где расположена станция? (напр., название населённого пункта)" }, - "2": { - "mappings": { - "0": { - "then": "Гидрант (полностью или частично) в рабочем состоянии." - }, - "2": { - "then": "Гидрант демонтирован." - } - } + "ambulance-street": { + "question": " По какому адресу расположена эта станция?", + "render": "Эта станция расположена вдоль шоссе {addr:street}." } }, "title": { - "render": "Гидрант" + "render": "Станция скорой помощи" } }, - "1": { + "extinguisher": { "description": "Слой карты, отображающий огнетушители.", "name": "Карта огнетушителей.", "presets": { @@ -482,7 +456,7 @@ } }, "tagRenderings": { - "0": { + "extinguisher-location": { "mappings": { "0": { "then": "Внутри." @@ -499,7 +473,7 @@ "render": "Огнетушители" } }, - "2": { + "fire_stations": { "description": "Слой карты, отображающий пожарные части.", "name": "Карта пожарных частей", "presets": { @@ -508,46 +482,72 @@ } }, "tagRenderings": { - "0": { + "station-name": { "question": "Как называется эта пожарная часть?", "render": "Эта часть называется {name}." }, - "1": { - "question": " По какому адресу расположена эта часть?", - "render": "Часть расположена вдоль шоссе {addr:street}." - }, - "2": { + "station-place": { "question": "Где расположена часть? (напр., название населённого пункта)", "render": "Эта часть расположена в {addr:place}." + }, + "station-street": { + "question": " По какому адресу расположена эта часть?", + "render": "Часть расположена вдоль шоссе {addr:street}." } }, "title": { "render": "Пожарная часть" } }, - "3": { - "name": "Карта станций скорой помощи", + "hydrants": { + "description": "Слой карты, отображающий пожарные гидранты.", + "name": "Карта пожарных гидрантов", "presets": { "0": { - "description": "Добавить станцию скорой помощи на карту", - "title": "Станция скорой помощи" + "title": "Пожарный гидрант" } }, "tagRenderings": { - "0": { - "question": "Как называется эта станция скорой помощи?", - "render": "Эта станция называется {name}." + "hydrant-color": { + "mappings": { + "0": { + "then": "Цвет гидранта не определён." + }, + "1": { + "then": "Гидрант жёлтого цвета." + }, + "2": { + "then": "Гидрант красного цвета." + } + }, + "question": "Какого цвета гидрант?", + "render": "Цвет гидранта {colour}" }, - "1": { - "question": " По какому адресу расположена эта станция?", - "render": "Эта станция расположена вдоль шоссе {addr:street}." + "hydrant-state": { + "mappings": { + "0": { + "then": "Гидрант (полностью или частично) в рабочем состоянии." + }, + "2": { + "then": "Гидрант демонтирован." + } + } }, - "2": { - "question": "Где расположена станция? (напр., название населённого пункта)" + "hydrant-type": { + "mappings": { + "0": { + "then": "Тип гидранта не определён." + }, + "3": { + "then": " Тип стены." + } + }, + "question": "К какому типу относится этот гидрант?", + "render": " Тип гидранта: {fire_hydrant:type}" } }, "title": { - "render": "Станция скорой помощи" + "render": "Гидрант" } } }, @@ -567,7 +567,7 @@ }, "shops": { "layers": { - "0": { + "shops": { "description": "Магазин", "name": "Магазин", "presets": { @@ -577,10 +577,22 @@ } }, "tagRenderings": { - "1": { + "shops-email": { + "question": "Каков адрес электронной почты этого магазина?", + "render": "{email}" + }, + "shops-name": { "question": "Как называется этот магазин?" }, - "2": { + "shops-opening_hours": { + "question": "Каковы часы работы этого магазина?", + "render": "{opening_hours_table(opening_hours)}" + }, + "shops-phone": { + "question": "Какой телефон?", + "render": "{phone}" + }, + "shops-shop": { "mappings": { "1": { "then": "Супермаркет" @@ -597,21 +609,9 @@ }, "question": "Что продаётся в этом магазине?" }, - "3": { - "question": "Какой телефон?", - "render": "{phone}" - }, - "4": { + "shops-website": { "question": "Какой веб-сайт у этого магазина?", "render": "{website}" - }, - "5": { - "question": "Каков адрес электронной почты этого магазина?", - "render": "{email}" - }, - "6": { - "question": "Каковы часы работы этого магазина?", - "render": "{opening_hours_table(opening_hours)}" } }, "title": { diff --git a/langs/themes/zh_Hant.json b/langs/themes/zh_Hant.json index 42e84b918..5dfff1615 100644 --- a/langs/themes/zh_Hant.json +++ b/langs/themes/zh_Hant.json @@ -6,7 +6,7 @@ "artwork": { "description": "歡迎來到開放藝術品地圖,這份地圖會顯示全世界的雕像、半身像、塗鴉以及其他類型的藝術品", "layers": { - "0": { + "artwork": { "description": "不同類型的藝術品", "name": "藝術品", "presets": { @@ -15,7 +15,11 @@ } }, "tagRenderings": { - "1": { + "artwork-artist_name": { + "question": "創造這個的藝術家是誰?", + "render": "{artist_name} 創作" + }, + "artwork-artwork_type": { "mappings": { "0": { "then": "建築物" @@ -57,15 +61,11 @@ "question": "這是什麼類型的藝術品?", "render": "這是 {artwork_type}" }, - "2": { - "question": "創造這個的藝術家是誰?", - "render": "{artist_name} 創作" - }, - "3": { + "artwork-website": { "question": "在那個網站能夠找到更多藝術品的資訊?", "render": "這個網站有更多資訊" }, - "4": { + "artwork-wikidata": { "question": "這個藝術品有那個對應的 Wikidata 項目?", "render": "與 {wikidata}對應" } @@ -98,7 +98,7 @@ "campersite": { "description": "這個網站收集所有官方露營地點,以及那邊能排放廢水。你可以加上詳細的服務項目與價格,加上圖片以及評價。這是網站與網路 app,資料則是存在開放街圖,因此會永遠免費,而且可以被所有 app 再利用。", "layers": { - "0": { + "caravansites": { "description": "露營地", "name": "露營地", "presets": { @@ -107,11 +107,19 @@ } }, "tagRenderings": { - "1": { - "question": "這個地方叫做什麼?", - "render": "這個地方叫做 {name}" + "caravansites-capacity": { + "question": "多少露營者能夠待在這裡?(如果沒有明顯的空間數字或是允許車輛則可以跳過)", + "render": "{capacity} 露營者能夠同時使用這個地方" }, - "2": { + "caravansites-charge": { + "question": "這個地方收多少費用?", + "render": "這個地方收費 {charge}" + }, + "caravansites-description": { + "question": "你想要為這個地方加一般的敘述嗎?(不要重覆加先前問過或提供的資訊,請保持敘述性-請將意見留在評價)", + "render": "這個地方更詳細的資訊: {description}" + }, + "caravansites-fee": { "mappings": { "0": { "then": "你要付費才能使用" @@ -122,26 +130,7 @@ }, "question": "這個地方收費嗎?" }, - "3": { - "question": "這個地方收多少費用?", - "render": "這個地方收費 {charge}" - }, - "4": { - "mappings": { - "0": { - "then": "這個地方有衛生設施" - }, - "1": { - "then": "這個地方沒有衛生設施" - } - }, - "question": "這個地方有衛生設施嗎?" - }, - "5": { - "question": "多少露營者能夠待在這裡?(如果沒有明顯的空間數字或是允許車輛則可以跳過)", - "render": "{capacity} 露營者能夠同時使用這個地方" - }, - "6": { + "caravansites-internet": { "mappings": { "0": { "then": "這裡有網路連線" @@ -155,7 +144,7 @@ }, "question": "這個地方有提網路連線嗎?" }, - "7": { + "caravansites-internet-fee": { "mappings": { "0": { "then": "你需要額外付費來使用網路連線" @@ -166,22 +155,7 @@ }, "question": "你需要為網路連線付費嗎?" }, - "8": { - "mappings": { - "0": { - "then": "這個地方有廁所" - }, - "1": { - "then": "這個地方並沒有廁所" - } - }, - "question": "這個地方有廁所嗎?" - }, - "9": { - "question": "這個地方有網站嗎?", - "render": "官方網站:{website}" - }, - "10": { + "caravansites-long-term": { "mappings": { "0": { "then": "有,這個地方有提供長期租用,但你也可以用天計算費用" @@ -195,9 +169,35 @@ }, "question": "這個地方有提供長期租用嗎?" }, - "11": { - "question": "你想要為這個地方加一般的敘述嗎?(不要重覆加先前問過或提供的資訊,請保持敘述性-請將意見留在評價)", - "render": "這個地方更詳細的資訊: {description}" + "caravansites-name": { + "question": "這個地方叫做什麼?", + "render": "這個地方叫做 {name}" + }, + "caravansites-sanitary-dump": { + "mappings": { + "0": { + "then": "這個地方有衛生設施" + }, + "1": { + "then": "這個地方沒有衛生設施" + } + }, + "question": "這個地方有衛生設施嗎?" + }, + "caravansites-toilets": { + "mappings": { + "0": { + "then": "這個地方有廁所" + }, + "1": { + "then": "這個地方並沒有廁所" + } + }, + "question": "這個地方有廁所嗎?" + }, + "caravansites-website": { + "question": "這個地方有網站嗎?", + "render": "官方網站:{website}" } }, "title": { @@ -209,9 +209,9 @@ "render": "露營地 {name}" } }, - "1": { + "dumpstations": { "tagRenderings": { - "5": { + "dumpstations-chemical-waste": { "mappings": { "0": { "then": "你可以在這邊丟棄廁所化學廢棄物" @@ -237,11 +237,11 @@ "description": "在這份地圖上你會發現能夠攀爬機會,像是攀岩體育館、抱石大廳以及大自然當中的巨石。", "descriptionTail": "攀爬地圖最初由 Christian Neumann 製作。如果你有回饋意見或問題請到Please 這邊反應

這專案使用來自開放街圖專案的資料。

", "layers": { - "0": { + "climbing_club": { "description": "攀岩社團或組織", "name": "攀岩社團", "tagRenderings": { - "0": { + "climbing_club-name": { "render": "{name}" } }, @@ -260,10 +260,10 @@ "cyclestreets": { "description": "單車街道是機動車輛受限制,只允許單車通行的道路。通常會有路標顯示特別的交通指標。單車街道通常在荷蘭、比利時看到,但德國與法國也有。 ", "layers": { - "0": { + "fietsstraat": { "name": "單車街道" }, - "1": { + "toekomstige_fietsstraat": { "name": "將來的單車街道" } }, @@ -280,7 +280,7 @@ }, "facadegardens": { "layers": { - "0": { + "facadegardens": { "description": "立面花園", "name": "立面花園", "title": { @@ -298,12 +298,12 @@ "hailhydrant": { "description": "在這份地圖上面你可以在你喜愛的社區尋找與更新消防栓、消防隊、急救站與滅火器。\n\n你可以追蹤確切位置 (只有行動版) 以及在左下角選擇與你相關的圖層。你也可以使用這工具新增或編輯地圖上的釘子 (興趣點),以及透過回答一些問題提供額外的資訊。\n\n所有你做出的變動都會自動存到開放街圖這個全球資料庫,而且能自由讓其他人取用。", "layers": { - "0": { + "extinguisher": { + "description": "顯示消防栓的地圖圖層。" + }, + "hydrants": { "description": "顯示消防栓的地圖圖層。", "name": "消防栓地圖" - }, - "1": { - "description": "顯示消防栓的地圖圖層。" } }, "shortDescription": "顯示消防栓、滅火器、消防隊與急救站的地圖。", diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index 3097abecf..58bba200d 100644 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -55,20 +55,27 @@ class TranslationPart { } const v = object[key] - - if(typeof key === "number" && v["id"] !== undefined){ - // We use the embedded id as key instead of the index as this is more stable - // key = v["id"] - if(typeof key !== "string"){ - throw "Panic: found a non-string ID at"+context - } - } - + if (v == null) { console.warn("Got a null value for key ", key) continue } + if (v["id"] !== undefined) { + // We use the embedded id as key instead of the index as this is more stable + // Note: indonesian is shortened as 'id' as well! + if (v["en"] !== undefined || v["nl"] !== undefined) { + // This is probably a translation already! + // pass + } else { + + key = v["id"] + if (typeof key !== "string") { + throw "Panic: found a non-string ID at" + context + } + } + } + if (typeof v !== "object") { continue; } @@ -230,6 +237,7 @@ function generateTranslationsObjectFrom(objects: { path: string, parsed: { id: s } let json = tr.toJson(lang) try { + json = JSON.stringify(JSON.parse(json), null, " "); } catch (e) { console.error(e) @@ -245,7 +253,7 @@ function MergeTranslation(source: any, target: any, language: string, context: s if (!source.hasOwnProperty(key)) { continue } - + const sourceV = source[key]; const targetV = target[key] if (typeof sourceV === "string") { @@ -305,9 +313,9 @@ function loadTranslationFilesFrom(target: string): Map { for (const translationFilePath of translationFilePaths) { let language = translationFilePath.substr(translationFilePath.lastIndexOf("/") + 1) language = language.substr(0, language.length - 5) - try{ + try { translationFiles.set(language, JSON.parse(readFileSync(translationFilePath, "utf8"))) - }catch(e){ + } catch (e) { console.error("Invalid JSON file or file does not exist", translationFilePath) throw e; } From c019650ee9fda24263ca250747fd700080348f72 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 20:58:10 +0200 Subject: [PATCH 26/65] Different translation rendering, which should be more stable in the face of updates --- langs/themes/ca.json | 24 +- langs/themes/de.json | 58 ++-- langs/themes/en.json | 494 ++++++++++++++++---------------- langs/themes/es.json | 2 +- langs/themes/fr.json | 472 +++++++++++++++--------------- langs/themes/id.json | 30 +- langs/themes/it.json | 62 ++-- langs/themes/ja.json | 346 +++++++++++----------- langs/themes/nb_NO.json | 84 +++--- langs/themes/nl.json | 272 +++++++++--------- langs/themes/pt_BR.json | 4 +- langs/themes/ru.json | 192 ++++++------- langs/themes/zh_Hant.json | 22 +- scripts/generateTranslations.ts | 27 +- 14 files changed, 1055 insertions(+), 1034 deletions(-) diff --git a/langs/themes/ca.json b/langs/themes/ca.json index a6cd62432..79eb7a4c2 100644 --- a/langs/themes/ca.json +++ b/langs/themes/ca.json @@ -5,35 +5,35 @@ }, "climbing": { "layers": { - "climbing": { - "tagRenderings": { - "name": { - "render": "{name}" - } - } - }, - "climbing_club": { + "0": { "tagRenderings": { "climbing_club-name": { "render": "{name}" } } }, - "climbing_gym": { + "1": { "tagRenderings": { "name": { "render": "{name}" } } }, - "climbing_route": { + "2": { "tagRenderings": { "Name": { "render": "{name}" } } }, - "maybe_climbing": { + "3": { + "tagRenderings": { + "name": { + "render": "{name}" + } + } + }, + "4": { "tagRenderings": { "climbing-opportunity-name": { "render": "{name}" @@ -48,7 +48,7 @@ }, "shops": { "layers": { - "shops": { + "0": { "tagRenderings": { "shops-phone": { "render": "{phone}" diff --git a/langs/themes/de.json b/langs/themes/de.json index f2a9971f4..300eacddc 100644 --- a/langs/themes/de.json +++ b/langs/themes/de.json @@ -6,7 +6,7 @@ "artwork": { "description": "Willkommen bei der Freien Kunstwerk-Karte, einer Karte von Statuen, Büsten, Grafitti, ... auf der ganzen Welt", "layers": { - "artwork": { + "0": { "description": "Verschiedene Kunstwerke", "name": "Kunstwerke", "presets": { @@ -98,31 +98,7 @@ "description": "Auf dieser Karte finden Sie verschiedene Klettermöglichkeiten wie Kletterhallen, Boulderhallen und Felsen in der Natur.", "descriptionTail": "

kletterspots.de wird betrieben von Christian Neumann. Bitte melden Sie sich, wenn Sie Feedback oder Fragen haben.

Das Projekt nutzt Daten des OpenStreetMap Projekts und basiert auf der freien Software MapComplete.

", "layers": { - "climbing": { - "description": "Eine Klettergelegenheit", - "name": "Klettermöglichkeiten", - "presets": { - "0": { - "description": "Eine Klettergelegenheit", - "title": "Klettermöglichkeit" - } - }, - "tagRenderings": { - "name": { - "mappings": { - "0": { - "then": "Diese Klettergelegenheit hat keinen Namen" - } - }, - "question": "Wie heißt diese Klettergelegenheit?", - "render": "{name}" - } - }, - "title": { - "render": "Klettermöglichkeit" - } - }, - "climbing_club": { + "0": { "description": "Ein Kletterverein oder eine Organisation", "name": "Kletterverein", "presets": { @@ -150,7 +126,7 @@ "render": "Kletterverein" } }, - "climbing_gym": { + "1": { "description": "Eine Kletterhalle", "name": "Kletterhallen", "tagRenderings": { @@ -168,7 +144,7 @@ "render": "Kletterhalle" } }, - "climbing_route": { + "2": { "name": "Kletterrouten", "tagRenderings": { "Difficulty": { @@ -196,7 +172,31 @@ "render": "Kleterroute" } }, - "maybe_climbing": { + "3": { + "description": "Eine Klettergelegenheit", + "name": "Klettermöglichkeiten", + "presets": { + "0": { + "description": "Eine Klettergelegenheit", + "title": "Klettermöglichkeit" + } + }, + "tagRenderings": { + "name": { + "mappings": { + "0": { + "then": "Diese Klettergelegenheit hat keinen Namen" + } + }, + "question": "Wie heißt diese Klettergelegenheit?", + "render": "{name}" + } + }, + "title": { + "render": "Klettermöglichkeit" + } + }, + "4": { "description": "Eine Klettergelegenheit?", "name": "Klettermöglichkeiten?", "tagRenderings": { diff --git a/langs/themes/en.json b/langs/themes/en.json index c1477e31f..cf9c49376 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -6,7 +6,7 @@ "artwork": { "description": "Welcome to Open Artwork Map, a map of statues, busts, grafittis and other artwork all over the world", "layers": { - "artwork": { + "0": { "description": "Diverse pieces of artwork", "name": "Artworks", "presets": { @@ -106,7 +106,7 @@ "campersite": { "description": "This site collects all official camper stopover places and places where you can dump grey and black water. You can add details about the services provided and the cost. Add pictures and reviews. This is a website and a webapp. The data is stored in OpenStreetMap, so it will be free forever and can be re-used by any app.", "layers": { - "caravansites": { + "0": { "description": "camper sites", "name": "Camper sites", "presets": { @@ -218,7 +218,7 @@ "render": "Camper site {name}" } }, - "dumpstations": { + "1": { "description": "Sanitary dump stations", "name": "Sanitary dump stations", "presets": { @@ -337,7 +337,103 @@ "description": "On this map you will find various climbing opportunities such as climbing gyms, bouldering halls and rocks in nature.", "descriptionTail": "The climbing map was originally made by Christian Neumann. Please get in touch if you have feedback or questions.

The project uses data of the OpenStreetMap project.

", "layers": { - "climbing": { + "0": { + "description": "A climbing club or organisations", + "name": "Climbing club", + "presets": { + "0": { + "description": "A climbing club", + "title": "Climbing club" + }, + "1": { + "description": "A NGO working around climbing", + "title": "Climbing NGO" + } + }, + "tagRenderings": { + "climbing_club-name": { + "question": "What is the name of this climbing club or NGO?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Climbing NGO" + } + }, + "render": "Climbing club" + } + }, + "1": { + "description": "A climbing gym", + "name": "Climbing gyms", + "tagRenderings": { + "name": { + "question": "What is the name of this climbing gym?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Climbing gym {name}" + } + }, + "render": "Climbing gym" + } + }, + "2": { + "name": "Climbing routes", + "presets": { + "0": { + "title": "Climbing route" + } + }, + "tagRenderings": { + "Bolts": { + "mappings": { + "0": { + "then": "This route is not bolted" + }, + "1": { + "then": "This route is not bolted" + } + }, + "question": "How much bolts does this route have before reaching the moulinette?", + "render": "This route has {climbing:bolts} bolts" + }, + "Difficulty": { + "question": "What is the difficulty of this climbing route according to the french/belgian system?", + "render": "The difficulty is {climbing:grade:french} according to the french/belgian system" + }, + "Length": { + "question": "How long is this climbing route (in meters)?", + "render": "This route is {canonical(climbing:length)} long" + }, + "Name": { + "mappings": { + "0": { + "then": "This climbing route doesn't have a name" + } + }, + "question": "What is the name of this climbing route?", + "render": "{name}" + }, + "Rock type": { + "render": "The rock type is {_embedding_features_with_rock:rock} as stated on the surrounding crag" + } + }, + "title": { + "mappings": { + "0": { + "then": "Climbing route {name}" + } + }, + "render": "Climbing route" + } + }, + "3": { "description": "A climbing opportunity", "name": "Climbing opportunities", "presets": { @@ -403,103 +499,7 @@ "render": "Climbing opportunity" } }, - "climbing_club": { - "description": "A climbing club or organisations", - "name": "Climbing club", - "presets": { - "0": { - "description": "A climbing club", - "title": "Climbing club" - }, - "1": { - "description": "A NGO working around climbing", - "title": "Climbing NGO" - } - }, - "tagRenderings": { - "climbing_club-name": { - "question": "What is the name of this climbing club or NGO?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Climbing NGO" - } - }, - "render": "Climbing club" - } - }, - "climbing_gym": { - "description": "A climbing gym", - "name": "Climbing gyms", - "tagRenderings": { - "name": { - "question": "What is the name of this climbing gym?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Climbing gym {name}" - } - }, - "render": "Climbing gym" - } - }, - "climbing_route": { - "name": "Climbing routes", - "presets": { - "0": { - "title": "Climbing route" - } - }, - "tagRenderings": { - "Bolts": { - "mappings": { - "0": { - "then": "This route is not bolted" - }, - "1": { - "then": "This route is not bolted" - } - }, - "question": "How much bolts does this route have before reaching the moulinette?", - "render": "This route has {climbing:bolts} bolts" - }, - "Difficulty": { - "question": "What is the difficulty of this climbing route according to the french/belgian system?", - "render": "The difficulty is {climbing:grade:french} according to the french/belgian system" - }, - "Length": { - "question": "How long is this climbing route (in meters)?", - "render": "This route is {canonical(climbing:length)} long" - }, - "Name": { - "mappings": { - "0": { - "then": "This climbing route doesn't have a name" - } - }, - "question": "What is the name of this climbing route?", - "render": "{name}" - }, - "Rock type": { - "render": "The rock type is {_embedding_features_with_rock:rock} as stated on the surrounding crag" - } - }, - "title": { - "mappings": { - "0": { - "then": "Climbing route {name}" - } - }, - "render": "Climbing route" - } - }, - "maybe_climbing": { + "4": { "description": "A climbing opportunity?", "name": "Climbing opportunities?", "tagRenderings": { @@ -668,7 +668,7 @@ "cycle_highways": { "description": "This map shows cycle highways", "layers": { - "cycle_highways": { + "0": { "name": "cycle highways", "title": { "render": "cycle highway" @@ -685,18 +685,11 @@ "cyclestreets": { "description": "A cyclestreet is is a street where motorized traffic is not allowed to overtake cyclists. They are signposted by a special traffic sign. Cyclestreets can be found in the Netherlands and Belgium, but also in Germany and France. ", "layers": { - "all_streets": { - "description": "Layer to mark any street as cyclestreet", - "name": "All streets", - "title": { - "render": "Street" - } - }, - "fietsstraat": { + "0": { "description": "A cyclestreet is a street where motorized traffic is not allowed to overtake a cyclist", "name": "Cyclestreets" }, - "toekomstige_fietsstraat": { + "1": { "description": "This street will become a cyclestreet soon", "name": "Future cyclestreet", "title": { @@ -707,6 +700,13 @@ }, "render": "Future cyclestreet" } + }, + "2": { + "description": "Layer to mark any street as cyclestreet", + "name": "All streets", + "title": { + "render": "Street" + } } }, "roamingRenderings": { @@ -746,7 +746,7 @@ "facadegardens": { "description": "Facade gardens, green facades and trees in the city not only bring peace and quiet, but also a more beautiful city, greater biodiversity, a cooling effect and better air quality.
Klimaan VZW and Mechelen Klimaatneutraal want to map existing and new facade gardens as an example for people who want to build their own garden or for city walkers who love nature.
More info about the project at klimaan.be.", "layers": { - "facadegardens": { + "0": { "description": "Facade gardens", "name": "Facade gardens", "presets": { @@ -836,7 +836,7 @@ "fritures": { "layers": { "0": { - "friture": { + "override": { "name": "Fries shop" } } @@ -849,7 +849,7 @@ "hackerspaces": { "description": "On this map you can see hackerspaces, add a new hackerspace or update data directly", "layers": { - "hackerspaces": { + "0": { "description": "Hackerspace", "icon": { "mappings": { @@ -926,137 +926,7 @@ "hailhydrant": { "description": "On this map you can find and update hydrants, fire stations, ambulance stations, and extinguishers in your favorite neighborhoods. \n\nYou can track your precise location (mobile only) and select layers that are relevant for you in the bottom left corner. You can also use this tool to add or edit pins (points of interest) to the map and provide additional details by answering available questions. \n\nAll changes you make will automatically be saved in the global database of OpenStreetMap and can be freely re-used by others.", "layers": { - "ambulancestation": { - "description": "An ambulance station is an area for storage of ambulance vehicles, medical equipment, personal protective equipment, and other medical supplies.", - "name": "Map of ambulance stations", - "presets": { - "0": { - "description": "Add an ambulance station to the map", - "title": "Ambulance station" - } - }, - "tagRenderings": { - "ambulance-agency": { - "question": "What agency operates this station?", - "render": "This station is operated by {operator}." - }, - "ambulance-name": { - "question": "What is the name of this ambulance station?", - "render": "This station is called {name}." - }, - "ambulance-operator-type": { - "mappings": { - "0": { - "then": "The station is operated by the government." - }, - "1": { - "then": "The station is operated by a community-based, or informal organization." - }, - "2": { - "then": "The station is operated by a formal group of volunteers." - }, - "3": { - "then": "The station is privately operated." - } - }, - "question": "How is the station operator classified?", - "render": "The operator is a(n) {operator:type} entity." - }, - "ambulance-place": { - "question": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", - "render": "This station is found within {addr:place}." - }, - "ambulance-street": { - "question": " What is the street name where the station located?", - "render": "This station is along a highway called {addr:street}." - } - }, - "title": { - "render": "Ambulance Station" - } - }, - "extinguisher": { - "description": "Map layer to show fire hydrants.", - "name": "Map of fire extinguishers.", - "presets": { - "0": { - "description": "A fire extinguisher is a small, portable device used to stop a fire", - "title": "Fire extinguisher" - } - }, - "tagRenderings": { - "extinguisher-location": { - "mappings": { - "0": { - "then": "Found indoors." - }, - "1": { - "then": "Found outdoors." - } - }, - "question": "Where is it positioned?", - "render": "Location: {location}" - } - }, - "title": { - "render": "Extinguishers" - } - }, - "fire_stations": { - "description": "Map layer to show fire stations.", - "name": "Map of fire stations", - "presets": { - "0": { - "description": "A fire station is a place where the fire trucks and firefighters are located when not in operation.", - "title": "Fire station" - } - }, - "tagRenderings": { - "station-agency": { - "mappings": { - "0": { - "then": "Bureau of Fire Protection" - } - }, - "question": "What agency operates this station?", - "render": "This station is operated by {operator}." - }, - "station-name": { - "question": "What is the name of this fire station?", - "render": "This station is called {name}." - }, - "station-operator": { - "mappings": { - "0": { - "then": "The station is operated by the government." - }, - "1": { - "then": "The station is operated by a community-based, or informal organization." - }, - "2": { - "then": "The station is operated by a formal group of volunteers." - }, - "3": { - "then": "The station is privately operated." - } - }, - "question": "How is the station operator classified?", - "render": "The operator is a(n) {operator:type} entity." - }, - "station-place": { - "question": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", - "render": "This station is found within {addr:place}." - }, - "station-street": { - "question": " What is the street name where the station located?", - "render": "This station is along a highway called {addr:street}." - } - }, - "title": { - "render": "Fire Station" - } - }, - "hydrants": { + "0": { "description": "Map layer to show fire hydrants.", "name": "Map of hydrants", "presets": { @@ -1121,6 +991,136 @@ "title": { "render": "Hydrant" } + }, + "1": { + "description": "Map layer to show fire hydrants.", + "name": "Map of fire extinguishers.", + "presets": { + "0": { + "description": "A fire extinguisher is a small, portable device used to stop a fire", + "title": "Fire extinguisher" + } + }, + "tagRenderings": { + "extinguisher-location": { + "mappings": { + "0": { + "then": "Found indoors." + }, + "1": { + "then": "Found outdoors." + } + }, + "question": "Where is it positioned?", + "render": "Location: {location}" + } + }, + "title": { + "render": "Extinguishers" + } + }, + "2": { + "description": "Map layer to show fire stations.", + "name": "Map of fire stations", + "presets": { + "0": { + "description": "A fire station is a place where the fire trucks and firefighters are located when not in operation.", + "title": "Fire station" + } + }, + "tagRenderings": { + "station-agency": { + "mappings": { + "0": { + "then": "Bureau of Fire Protection" + } + }, + "question": "What agency operates this station?", + "render": "This station is operated by {operator}." + }, + "station-name": { + "question": "What is the name of this fire station?", + "render": "This station is called {name}." + }, + "station-operator": { + "mappings": { + "0": { + "then": "The station is operated by the government." + }, + "1": { + "then": "The station is operated by a community-based, or informal organization." + }, + "2": { + "then": "The station is operated by a formal group of volunteers." + }, + "3": { + "then": "The station is privately operated." + } + }, + "question": "How is the station operator classified?", + "render": "The operator is a(n) {operator:type} entity." + }, + "station-place": { + "question": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", + "render": "This station is found within {addr:place}." + }, + "station-street": { + "question": " What is the street name where the station located?", + "render": "This station is along a highway called {addr:street}." + } + }, + "title": { + "render": "Fire Station" + } + }, + "3": { + "description": "An ambulance station is an area for storage of ambulance vehicles, medical equipment, personal protective equipment, and other medical supplies.", + "name": "Map of ambulance stations", + "presets": { + "0": { + "description": "Add an ambulance station to the map", + "title": "Ambulance station" + } + }, + "tagRenderings": { + "ambulance-agency": { + "question": "What agency operates this station?", + "render": "This station is operated by {operator}." + }, + "ambulance-name": { + "question": "What is the name of this ambulance station?", + "render": "This station is called {name}." + }, + "ambulance-operator-type": { + "mappings": { + "0": { + "then": "The station is operated by the government." + }, + "1": { + "then": "The station is operated by a community-based, or informal organization." + }, + "2": { + "then": "The station is operated by a formal group of volunteers." + }, + "3": { + "then": "The station is privately operated." + } + }, + "question": "How is the station operator classified?", + "render": "The operator is a(n) {operator:type} entity." + }, + "ambulance-place": { + "question": "Where is the station located? (e.g. name of neighborhood, villlage, or town)", + "render": "This station is found within {addr:place}." + }, + "ambulance-street": { + "question": " What is the street name where the station located?", + "render": "This station is along a highway called {addr:street}." + } + }, + "title": { + "render": "Ambulance Station" + } } }, "shortDescription": "Map to show hydrants, extinguishers, fire stations, and ambulance stations.", @@ -1144,7 +1144,7 @@ "openwindpowermap": { "description": "A map for showing and editing wind turbines.", "layers": { - "windturbine": { + "0": { "name": "wind turbine", "presets": { "0": { @@ -1227,7 +1227,7 @@ "shops": { "description": "On this map, one can mark basic information about shops, add opening hours and phone numbers", "layers": { - "shops": { + "0": { "description": "A shop", "name": "Shop", "presets": { diff --git a/langs/themes/es.json b/langs/themes/es.json index 3b31ed8c4..80196c809 100644 --- a/langs/themes/es.json +++ b/langs/themes/es.json @@ -6,7 +6,7 @@ "artwork": { "description": "Bienvenido a Open Artwork Map, un mapa de estatuas, bustos, grafitis y otras obras de arte de todo el mundo", "layers": { - "artwork": { + "0": { "description": "Diversas piezas de obras de arte", "name": "Obras de arte", "presets": { diff --git a/langs/themes/fr.json b/langs/themes/fr.json index 83ab9d4ce..530b9acb0 100644 --- a/langs/themes/fr.json +++ b/langs/themes/fr.json @@ -6,7 +6,7 @@ "artwork": { "description": "Bienvenue sur la carte ouverte des œuvres d'art, une carte des statues, fresques, ... du monde entier", "layers": { - "artwork": { + "0": { "description": "Diverses œuvres d'art", "name": "Œuvres d'art", "presets": { @@ -98,7 +98,7 @@ "campersite": { "description": "Ce site collecte les zones de camping officielles ainsi que les aires de vidange. Il est possible d’ajouter des détails à propos des services proposés ainsi que leurs coûts. Ajoutez vos images et avis. C’est un site et une application. Les données sont stockées sur OpenStreetMap, elles seront toujours gratuites et peuvent être réutilisées par n’importe quelle application.", "layers": { - "caravansites": { + "0": { "description": "campings", "name": "Campings", "presets": { @@ -210,7 +210,7 @@ "render": "Camping {name}" } }, - "dumpstations": { + "1": { "description": "Site de vidange", "name": "Site de vidange", "presets": { @@ -324,7 +324,103 @@ "description": "Cette carte indique les sites d’escalades comme les salles d’escalade ou les sites naturels.", "descriptionTail": "La carte a été créée par Christian Neumann. Merci de le contacter pour des avis ou des questions.

Ce projet utilise les données OpenStreetMap.

", "layers": { - "climbing": { + "0": { + "description": "Club ou association d’escalade", + "name": "Club d’escalade", + "presets": { + "0": { + "description": "Un club d’escalade", + "title": "Club d’escalade" + }, + "1": { + "description": "Une association d’escalade", + "title": "Association d’escalade" + } + }, + "tagRenderings": { + "climbing_club-name": { + "question": "Quel est le nom du club ou de l’association ?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Association d’escalade" + } + }, + "render": "Club d’escalade" + } + }, + "1": { + "description": "Une salle d’escalade", + "name": "Salle d’escalade", + "tagRenderings": { + "name": { + "question": "Quel est le nom de la salle d’escalade ?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Salle d’escalade {name}" + } + }, + "render": "Salle d’escalade" + } + }, + "2": { + "name": "Voies d’escalade", + "presets": { + "0": { + "title": "Voie d’escalade" + } + }, + "tagRenderings": { + "Bolts": { + "mappings": { + "0": { + "then": "Cette voie n’a pas de prises" + }, + "1": { + "then": "Cette voie n’a pas de prises" + } + }, + "question": "Combien de prises cette voie possède avant d’atteindre la moulinette ?", + "render": "Cette voie a {climbing:bolts} prises" + }, + "Difficulty": { + "question": "Quelle est la difficulté de cette voie selon le système franco-belge ?", + "render": "Selon le système franco-belge, la difficulté de cette voie est de {climbing:grade:french}" + }, + "Length": { + "question": "Quelle est la longueur de cette voie (en mètres) ?", + "render": "Cette voie fait {canonical(climbing:length)} de long" + }, + "Name": { + "mappings": { + "0": { + "then": "Cette voie n’a pas de nom" + } + }, + "question": "Quel est le nom de cette voie d’escalade ?", + "render": "{name}" + }, + "Rock type": { + "render": "Le type de roche est {_embedding_features_with_rock:rock} selon le mur" + } + }, + "title": { + "mappings": { + "0": { + "then": "Voie d’escalade {name}" + } + }, + "render": "Voie d’escalade" + } + }, + "3": { "description": "Opportunité d’escalade", "name": "Opportunité d’escalade", "presets": { @@ -390,103 +486,7 @@ "render": "Opportunité d’escalade" } }, - "climbing_club": { - "description": "Club ou association d’escalade", - "name": "Club d’escalade", - "presets": { - "0": { - "description": "Un club d’escalade", - "title": "Club d’escalade" - }, - "1": { - "description": "Une association d’escalade", - "title": "Association d’escalade" - } - }, - "tagRenderings": { - "climbing_club-name": { - "question": "Quel est le nom du club ou de l’association ?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Association d’escalade" - } - }, - "render": "Club d’escalade" - } - }, - "climbing_gym": { - "description": "Une salle d’escalade", - "name": "Salle d’escalade", - "tagRenderings": { - "name": { - "question": "Quel est le nom de la salle d’escalade ?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Salle d’escalade {name}" - } - }, - "render": "Salle d’escalade" - } - }, - "climbing_route": { - "name": "Voies d’escalade", - "presets": { - "0": { - "title": "Voie d’escalade" - } - }, - "tagRenderings": { - "Bolts": { - "mappings": { - "0": { - "then": "Cette voie n’a pas de prises" - }, - "1": { - "then": "Cette voie n’a pas de prises" - } - }, - "question": "Combien de prises cette voie possède avant d’atteindre la moulinette ?", - "render": "Cette voie a {climbing:bolts} prises" - }, - "Difficulty": { - "question": "Quelle est la difficulté de cette voie selon le système franco-belge ?", - "render": "Selon le système franco-belge, la difficulté de cette voie est de {climbing:grade:french}" - }, - "Length": { - "question": "Quelle est la longueur de cette voie (en mètres) ?", - "render": "Cette voie fait {canonical(climbing:length)} de long" - }, - "Name": { - "mappings": { - "0": { - "then": "Cette voie n’a pas de nom" - } - }, - "question": "Quel est le nom de cette voie d’escalade ?", - "render": "{name}" - }, - "Rock type": { - "render": "Le type de roche est {_embedding_features_with_rock:rock} selon le mur" - } - }, - "title": { - "mappings": { - "0": { - "then": "Voie d’escalade {name}" - } - }, - "render": "Voie d’escalade" - } - }, - "maybe_climbing": { + "4": { "description": "Opportunité d’escalade ?", "name": "Opportunités d’escalade ?", "tagRenderings": { @@ -621,7 +621,7 @@ "facadegardens": { "description": "Les jardins muraux en ville n’apportent pas seulement paix et tranquillité mais contribuent à embellir la ville, favoriser la biodiversité, régule la température et assainit l’air.
Klimaan VZW et Mechelen Klimaatneutraal veulent cartographier les jardins muraux comme exemple pour les personnes souhaitant en construire ainsi que celles aimant la nature.
Plus d’infos sur klimaan.be.", "layers": { - "facadegardens": { + "0": { "description": "Jardins muraux", "name": "Jardins muraux", "presets": { @@ -708,7 +708,7 @@ "fritures": { "layers": { "0": { - "friture": { + "override": { "name": "Friteries" } } @@ -722,137 +722,7 @@ "hailhydrant": { "description": "Sur cette carte on trouve et met à jour les bornes incendies, extincteurs, casernes de pompiers et ambulanciers dans son quartier.
Les options en haut à gauche permettent de localiser sa position (sur téléphone) et de filtrer les éléments. Il est possible d’utiliser cet outil pour ajouter et éditer les points d’intérêt de la carte et d’y ajouter des détails en répondant aux questions.
Toutes les modifications sont automatiquement enregistrées dans la base de données OpenStreetMap et peuvent êtres librement réutilisées par d’autres.", "layers": { - "ambulancestation": { - "description": "Une station d’ambulance est un lieu où sont stockés les véhicules d’urgence ainsi que de l’équipement médical.", - "name": "Couche des ambulances", - "presets": { - "0": { - "description": "Ajouter une station d’ambulances à la carte", - "title": "Station d’ambulances" - } - }, - "tagRenderings": { - "ambulance-agency": { - "question": "Quel est l’exploitant de la station ?", - "render": "Cette station est opérée par {operator}." - }, - "ambulance-name": { - "question": "Quel est le nom de cette station ?", - "render": "Cette station s’appelle {name}." - }, - "ambulance-operator-type": { - "mappings": { - "0": { - "then": "La station est opérée par le gouvernement." - }, - "1": { - "then": "La station est opérée par une organisation informelle." - }, - "2": { - "then": "La station est opérée par un groupe officiel de bénévoles." - }, - "3": { - "then": "La station est opérée par un groupe privé." - } - }, - "question": "Quel est le type d’exploitant ?", - "render": "L’exploitant est de type {operator:type}." - }, - "ambulance-place": { - "question": "Dans quelle localité la station est-elle située ?", - "render": "La station fait partie de {addr:place}." - }, - "ambulance-street": { - "question": " Quel est le nom de la rue où la station se situe ?", - "render": "La station fait partie de {addr:street}." - } - }, - "title": { - "render": "Station d’ambulances" - } - }, - "extinguisher": { - "description": "Couche des lances à incendie.", - "name": "Couche des extincteurs.", - "presets": { - "0": { - "description": "Un extincteur est un appareil portatif servant à éteindre un feu", - "title": "Extincteur" - } - }, - "tagRenderings": { - "extinguisher-location": { - "mappings": { - "0": { - "then": "Intérieur." - }, - "1": { - "then": "Extérieur." - } - }, - "question": "Où est-elle positionnée ?", - "render": "Emplacement : {location}" - } - }, - "title": { - "render": "Exctincteurs" - } - }, - "fire_stations": { - "description": "Couche des stations de pompiers.", - "name": "Couche des stations de pompiers", - "presets": { - "0": { - "description": "Une caserne de pompiers est un lieu où les pompiers et leur équipements sont situés en dehors des missions.", - "title": "Caserne de pompiers" - } - }, - "tagRenderings": { - "station-agency": { - "mappings": { - "0": { - "then": "Brigade de Protection du Feu" - } - }, - "question": "Quel est l’exploitant de la station ?", - "render": "Cette station est opérée par {operator}." - }, - "station-name": { - "question": "Quel est le nom de la station ?", - "render": "Cette station s’appelle {name}." - }, - "station-operator": { - "mappings": { - "0": { - "then": "La station est opérée par le gouvernement." - }, - "1": { - "then": "La station est opérée par une organisation informelle." - }, - "2": { - "then": "La station est opérée par un groupe officiel de bénévoles." - }, - "3": { - "then": "La station est opérée par un groupe privé." - } - }, - "question": "Quel est le type d’exploitant ?", - "render": "L’exploitant est de type {operator:type}." - }, - "station-place": { - "question": "Dans quelle localité la station est-elle située ?", - "render": "La station fait partie de {addr:place}." - }, - "station-street": { - "question": " Quel est le nom de la rue dans lequel elle se situe ?", - "render": "La station fait partie de la {addr:street}." - } - }, - "title": { - "render": "Station de pompiers" - } - }, - "hydrants": { + "0": { "description": "Couche des bornes incendie.", "name": "Carte des bornes incendie", "presets": { @@ -917,6 +787,136 @@ "title": { "render": "Bornes incendie" } + }, + "1": { + "description": "Couche des lances à incendie.", + "name": "Couche des extincteurs.", + "presets": { + "0": { + "description": "Un extincteur est un appareil portatif servant à éteindre un feu", + "title": "Extincteur" + } + }, + "tagRenderings": { + "extinguisher-location": { + "mappings": { + "0": { + "then": "Intérieur." + }, + "1": { + "then": "Extérieur." + } + }, + "question": "Où est-elle positionnée ?", + "render": "Emplacement : {location}" + } + }, + "title": { + "render": "Exctincteurs" + } + }, + "2": { + "description": "Couche des stations de pompiers.", + "name": "Couche des stations de pompiers", + "presets": { + "0": { + "description": "Une caserne de pompiers est un lieu où les pompiers et leur équipements sont situés en dehors des missions.", + "title": "Caserne de pompiers" + } + }, + "tagRenderings": { + "station-agency": { + "mappings": { + "0": { + "then": "Brigade de Protection du Feu" + } + }, + "question": "Quel est l’exploitant de la station ?", + "render": "Cette station est opérée par {operator}." + }, + "station-name": { + "question": "Quel est le nom de la station ?", + "render": "Cette station s’appelle {name}." + }, + "station-operator": { + "mappings": { + "0": { + "then": "La station est opérée par le gouvernement." + }, + "1": { + "then": "La station est opérée par une organisation informelle." + }, + "2": { + "then": "La station est opérée par un groupe officiel de bénévoles." + }, + "3": { + "then": "La station est opérée par un groupe privé." + } + }, + "question": "Quel est le type d’exploitant ?", + "render": "L’exploitant est de type {operator:type}." + }, + "station-place": { + "question": "Dans quelle localité la station est-elle située ?", + "render": "La station fait partie de {addr:place}." + }, + "station-street": { + "question": " Quel est le nom de la rue dans lequel elle se situe ?", + "render": "La station fait partie de la {addr:street}." + } + }, + "title": { + "render": "Station de pompiers" + } + }, + "3": { + "description": "Une station d’ambulance est un lieu où sont stockés les véhicules d’urgence ainsi que de l’équipement médical.", + "name": "Couche des ambulances", + "presets": { + "0": { + "description": "Ajouter une station d’ambulances à la carte", + "title": "Station d’ambulances" + } + }, + "tagRenderings": { + "ambulance-agency": { + "question": "Quel est l’exploitant de la station ?", + "render": "Cette station est opérée par {operator}." + }, + "ambulance-name": { + "question": "Quel est le nom de cette station ?", + "render": "Cette station s’appelle {name}." + }, + "ambulance-operator-type": { + "mappings": { + "0": { + "then": "La station est opérée par le gouvernement." + }, + "1": { + "then": "La station est opérée par une organisation informelle." + }, + "2": { + "then": "La station est opérée par un groupe officiel de bénévoles." + }, + "3": { + "then": "La station est opérée par un groupe privé." + } + }, + "question": "Quel est le type d’exploitant ?", + "render": "L’exploitant est de type {operator:type}." + }, + "ambulance-place": { + "question": "Dans quelle localité la station est-elle située ?", + "render": "La station fait partie de {addr:place}." + }, + "ambulance-street": { + "question": " Quel est le nom de la rue où la station se situe ?", + "render": "La station fait partie de {addr:street}." + } + }, + "title": { + "render": "Station d’ambulances" + } } }, "shortDescription": "Carte indiquant les bornes incendies, extincteurs, casernes de pompiers et ambulanciers.", @@ -930,7 +930,7 @@ "openwindpowermap": { "description": "Une carte indiquant les éoliennes et permettant leur édition.", "layers": { - "windturbine": { + "0": { "name": "Éolienne", "presets": { "0": { @@ -1008,7 +1008,7 @@ "shops": { "description": "Sur cette carte, vous pouvez ajouter des informations sur les magasins, horaires d'ouverture et numéro de téléphone", "layers": { - "shops": { + "0": { "description": "Un magasin", "name": "Magasin", "presets": { diff --git a/langs/themes/id.json b/langs/themes/id.json index 0be2f3e01..7412ded69 100644 --- a/langs/themes/id.json +++ b/langs/themes/id.json @@ -6,7 +6,7 @@ "artwork": { "description": "Selamat datang di Open Artwork Map, peta untuk patung, grafiti, dan karya seni lain di seluruh dunia", "layers": { - "artwork": { + "0": { "name": "Karya seni", "tagRenderings": { "artwork-website": { @@ -27,7 +27,7 @@ }, "campersite": { "layers": { - "caravansites": { + "0": { "tagRenderings": { "caravansites-fee": { "mappings": { @@ -88,35 +88,35 @@ }, "climbing": { "layers": { - "climbing": { - "tagRenderings": { - "name": { - "render": "{name}" - } - } - }, - "climbing_club": { + "0": { "tagRenderings": { "climbing_club-name": { "render": "{name}" } } }, - "climbing_gym": { + "1": { "tagRenderings": { "name": { "render": "{name}" } } }, - "climbing_route": { + "2": { "tagRenderings": { "Name": { "render": "{name}" } } }, - "maybe_climbing": { + "3": { + "tagRenderings": { + "name": { + "render": "{name}" + } + } + }, + "4": { "tagRenderings": { "climbing-opportunity-name": { "render": "{name}" @@ -127,7 +127,7 @@ }, "hailhydrant": { "layers": { - "hydrants": { + "0": { "tagRenderings": { "hydrant-type": { "mappings": { @@ -142,7 +142,7 @@ }, "shops": { "layers": { - "shops": { + "0": { "tagRenderings": { "shops-email": { "render": "{email}" diff --git a/langs/themes/it.json b/langs/themes/it.json index fa17395bd..ecac81814 100644 --- a/langs/themes/it.json +++ b/langs/themes/it.json @@ -6,7 +6,7 @@ "artwork": { "description": "Benvenuto/a sulla mappa libera dell’arte, una mappa delle statue, i busti, i graffiti e le altre realizzazioni artistiche di tutto il mondo", "layers": { - "artwork": { + "0": { "description": "Diverse opere d’arte", "name": "Opere d’arte", "presets": { @@ -98,7 +98,7 @@ "campersite": { "description": "Questo sito raccoglie tutti i luoghi ufficiali dove sostare con il camper e aree dove è possibile scaricare acque grigie e nere. Puoi aggiungere dettagli riguardanti i servizi forniti e il loro costo. Aggiungi foto e recensioni. Questo è al contempo un sito web e una web app. I dati sono memorizzati su OpenStreetMap in modo tale che siano per sempre liberi e riutilizzabili da qualsiasi app.", "layers": { - "caravansites": { + "0": { "description": "Aree camper", "name": "Aree camper", "presets": { @@ -210,7 +210,7 @@ "render": "Area camper {name}" } }, - "dumpstations": { + "1": { "description": "Luoghi di sversamento delle acque reflue", "name": "Luoghi di sversamento delle acque reflue", "presets": { @@ -327,7 +327,7 @@ }, "climbing": { "layers": { - "climbing_route": { + "2": { "tagRenderings": { "Difficulty": { "question": "Qual è la difficoltà di questa via di arrampicata nel sistema francese/belga?", @@ -361,18 +361,11 @@ }, "cyclestreets": { "layers": { - "all_streets": { - "description": "Livello per contrassegnare tutte le strade come strade ciclabili", - "name": "Tutte le strade", - "title": { - "render": "Strada" - } - }, - "fietsstraat": { + "0": { "description": "Una strada ciclabile è una strada in cui i veicoli a motore non possono sorpassare le persone in bicicletta", "name": "Strade ciclabili" }, - "toekomstige_fietsstraat": { + "1": { "description": "Questa strada diventerà presto una strada ciclabile", "name": "Futura strada ciclabile", "title": { @@ -383,6 +376,13 @@ }, "render": "Futura strada ciclabile" } + }, + "2": { + "description": "Livello per contrassegnare tutte le strade come strade ciclabili", + "name": "Tutte le strade", + "title": { + "render": "Strada" + } } }, "roamingRenderings": { @@ -409,7 +409,7 @@ }, "facadegardens": { "layers": { - "facadegardens": { + "0": { "presets": { "0": { "description": "Aggiungi un giardino verticale", @@ -488,23 +488,7 @@ }, "hailhydrant": { "layers": { - "fire_stations": { - "description": "Livello che mostra le caserme dei vigili del fuoco.", - "name": "Mappa delle caserme dei vigili del fuoco", - "tagRenderings": { - "station-name": { - "question": "Come si chiama questa caserma dei vigili del fuoco?", - "render": "Questa caserma si chiama {name}." - }, - "station-street": { - "question": " Qual è il nome della via in cui si trova la caserma?" - } - }, - "title": { - "render": "Caserma dei vigili del fuoco" - } - }, - "hydrants": { + "0": { "tagRenderings": { "hydrant-color": { "mappings": { @@ -523,6 +507,22 @@ "render": " Tipo di idrante: {fire_hydrant:type}" } } + }, + "2": { + "description": "Livello che mostra le caserme dei vigili del fuoco.", + "name": "Mappa delle caserme dei vigili del fuoco", + "tagRenderings": { + "station-name": { + "question": "Come si chiama questa caserma dei vigili del fuoco?", + "render": "Questa caserma si chiama {name}." + }, + "station-street": { + "question": " Qual è il nome della via in cui si trova la caserma?" + } + }, + "title": { + "render": "Caserma dei vigili del fuoco" + } } } }, diff --git a/langs/themes/ja.json b/langs/themes/ja.json index cb61f27de..5f12ec6cf 100644 --- a/langs/themes/ja.json +++ b/langs/themes/ja.json @@ -6,7 +6,7 @@ "artwork": { "description": "オープン アートワーク マップへようこそ。世界中の銅像や胸像、壁の落書きなどのアートワークの地図です", "layers": { - "artwork": { + "0": { "description": "多様な作品", "name": "美術品", "presets": { @@ -98,7 +98,7 @@ "campersite": { "description": "このWebサイトでは、すべてのキャンピングカーの公式停車場所と、汚水を捨てることができる場所を収集します。提供されるサービスとコストに関する詳細を追加できます。写真とレビューを追加します。これはウェブサイトとウェブアプリです。データはOpenStreetMapに保存されるので、永遠に無料で、どんなアプリからでも再利用できます。", "layers": { - "caravansites": { + "0": { "description": "キャンプサイト", "name": "キャンプサイト", "presets": { @@ -210,7 +210,7 @@ "render": "キャンプサイト {name}" } }, - "dumpstations": { + "1": { "description": "衛生ゴミ捨て場", "name": "衛生ゴミ捨て場", "presets": { @@ -329,31 +329,7 @@ "description": "この地図には、自然の中のクライミングジム、ボルダリングホール、岩など、さまざまなクライミングの機会があります。", "descriptionTail": "登山地図はもともと Christian Neumann によって作成されたものです。フィードバックや質問がありましたら、ご連絡ください。

このプロジェクトでは、OpenStreetMapプロジェクトのデータを使用します。

", "layers": { - "climbing": { - "description": "登坂教室", - "name": "登坂教室", - "presets": { - "0": { - "description": "登坂教室", - "title": "登坂教室" - } - }, - "tagRenderings": { - "name": { - "mappings": { - "0": { - "then": "この登坂教室には名前がついていない" - } - }, - "question": "この登坂教室の名前は何ですか?", - "render": "{name}" - } - }, - "title": { - "render": "登坂教室" - } - }, - "climbing_club": { + "0": { "description": "クライミングクラブや団体", "name": "クライミングクラブ", "presets": { @@ -381,7 +357,7 @@ "render": "クライミングクラブ" } }, - "climbing_gym": { + "1": { "description": "クライミングジム", "name": "クライミングジム", "tagRenderings": { @@ -399,7 +375,7 @@ "render": "クライミングジム" } }, - "climbing_route": { + "2": { "name": "登坂ルート", "tagRenderings": { "Difficulty": { @@ -427,7 +403,31 @@ "render": "登坂ルート" } }, - "maybe_climbing": { + "3": { + "description": "登坂教室", + "name": "登坂教室", + "presets": { + "0": { + "description": "登坂教室", + "title": "登坂教室" + } + }, + "tagRenderings": { + "name": { + "mappings": { + "0": { + "then": "この登坂教室には名前がついていない" + } + }, + "question": "この登坂教室の名前は何ですか?", + "render": "{name}" + } + }, + "title": { + "render": "登坂教室" + } + }, + "4": { "description": "登坂教室?", "name": "登坂教室?", "tagRenderings": { @@ -549,18 +549,11 @@ "cyclestreets": { "description": "cyclestreetとは、自動車がサイクリストを追い越すことができない道です。専用の道路標識で表示されます。Cyclestreetsはオランダやベルギーにもありますが、ドイツやフランスにもあります。 ", "layers": { - "all_streets": { - "description": "任意の道路をCycle Streetとしてマークするレイヤ", - "name": "すべての道路", - "title": { - "render": "ストリート" - } - }, - "fietsstraat": { + "0": { "description": "cyclestreetとは、自動車による交通がサイクリストを追い越すことができない道路です", "name": "Cyclestreets" }, - "toekomstige_fietsstraat": { + "1": { "description": "この通りはまもなくcyclestreetになります", "name": "将来のcyclestreet", "title": { @@ -571,6 +564,13 @@ }, "render": "将来のcyclestreet" } + }, + "2": { + "description": "任意の道路をCycle Streetとしてマークするレイヤ", + "name": "すべての道路", + "title": { + "render": "ストリート" + } } }, "roamingRenderings": { @@ -610,7 +610,7 @@ "facadegardens": { "description": "ファサード庭園、都市の緑のファサードと樹木は、平和と静けさをもたらすだけでなく、より美しい都市、より大きな生物多様性、冷却効果、より良い大気質をもたらす。
KlimaanのVZWとMechelenのKlimaatneutraalは、自分で庭を作りたい人や自然を愛する都市の歩行者のために、既存のファサード庭園と新しいファサード庭園のマッピングしたいと考えています。
このプロジェクトに関する詳細情報はklimaanにあります。", "layers": { - "facadegardens": { + "0": { "description": "ファサード庭園", "name": "ファサード庭園", "presets": { @@ -701,137 +701,7 @@ "hailhydrant": { "description": "このマップでは、お気に入りの近隣にある消火栓、消防署、救急ステーション、消火器を検索して更新できます。\n\n正確な位置を追跡し(モバイルのみ)、左下コーナーで関連するレイヤを選択できます。このツールを使用して、マップにピン(注視点)を追加または編集したり、利用可能な質問に答えることによって追加の詳細を提供することもできます。\n\nすべての変更は自動的にOpenStreetMapのグローバルデータベースに保存され、他のユーザが自由に再利用できます。", "layers": { - "ambulancestation": { - "description": "救急ステーションは、救急車、医療機器、個人用保護具、およびその他の医療用品を保管する場所です。", - "name": "救急ステーションの地図", - "presets": { - "0": { - "description": "救急ステーション(消防署)をマップに追加する", - "title": "救急ステーション(消防署)" - } - }, - "tagRenderings": { - "ambulance-agency": { - "question": "このステーションを運営しているのはどこですか?", - "render": "このステーションは{operator}によって運営されています。" - }, - "ambulance-name": { - "question": "この救急ステーションの名前は何ですか?", - "render": "このステーションの名前は{name}です。" - }, - "ambulance-operator-type": { - "mappings": { - "0": { - "then": "ステーションは自治体が運営する。" - }, - "1": { - "then": "任意団体やコミュニティが運営しているステーションである。" - }, - "2": { - "then": "公益団体が運営しているステーションである。" - }, - "3": { - "then": "個人が運営しているステーションである。" - } - }, - "question": "ステーションの運営の分類は?", - "render": "運営者は、{operator:type} です。" - }, - "ambulance-place": { - "question": "このステーションの住所は?(例: 地区、村、または町の名称)", - "render": "このステーションは{addr:place}にあります。" - }, - "ambulance-street": { - "question": " 救急ステーションの所在地はどこですか?", - "render": "{addr:street} 沿いにあります。" - } - }, - "title": { - "render": "救急ステーション" - } - }, - "extinguisher": { - "description": "消火栓を表示するマップレイヤ。", - "name": "消火器の地図です。", - "presets": { - "0": { - "description": "消火器は、火災を止めるために使用される小型で携帯可能な装置である", - "title": "消火器" - } - }, - "tagRenderings": { - "extinguisher-location": { - "mappings": { - "0": { - "then": "屋内にある。" - }, - "1": { - "then": "屋外にある。" - } - }, - "question": "どこにあるんですか?", - "render": "場所:{location}" - } - }, - "title": { - "render": "消火器" - } - }, - "fire_stations": { - "description": "消防署を表示するためのマップレイヤ。", - "name": "消防署の地図", - "presets": { - "0": { - "description": "消防署は、運転していないときに消防車や消防士がいる場所です。", - "title": "消防署" - } - }, - "tagRenderings": { - "station-agency": { - "mappings": { - "0": { - "then": "消防局(消防庁)" - } - }, - "question": "このステーションを運営しているのはどこですか?", - "render": "このステーションは{operator}によって運営されています。" - }, - "station-name": { - "question": "この消防署の名前は何ですか?", - "render": "このステーションの名前は{name}です。" - }, - "station-operator": { - "mappings": { - "0": { - "then": "ステーションは自治体が運営する。" - }, - "1": { - "then": "任意団体やコミュニティが運営しているステーションである。" - }, - "2": { - "then": "公益団体が運営しているステーションである。" - }, - "3": { - "then": "個人が運営しているステーションである。" - } - }, - "question": "ステーションの運営の分類は?", - "render": "運営者は、{operator:type} です。" - }, - "station-place": { - "question": "このステーションの住所は?(例: 地区、村、または町の名称)", - "render": "このステーションは{addr:place}にあります。" - }, - "station-street": { - "question": " 救急ステーションの所在地はどこですか?", - "render": "{addr:street} 沿いにあります。" - } - }, - "title": { - "render": "消防署" - } - }, - "hydrants": { + "0": { "description": "消火栓を表示するマップレイヤ。", "name": "消火栓の地図", "presets": { @@ -896,6 +766,136 @@ "title": { "render": "消火栓" } + }, + "1": { + "description": "消火栓を表示するマップレイヤ。", + "name": "消火器の地図です。", + "presets": { + "0": { + "description": "消火器は、火災を止めるために使用される小型で携帯可能な装置である", + "title": "消火器" + } + }, + "tagRenderings": { + "extinguisher-location": { + "mappings": { + "0": { + "then": "屋内にある。" + }, + "1": { + "then": "屋外にある。" + } + }, + "question": "どこにあるんですか?", + "render": "場所:{location}" + } + }, + "title": { + "render": "消火器" + } + }, + "2": { + "description": "消防署を表示するためのマップレイヤ。", + "name": "消防署の地図", + "presets": { + "0": { + "description": "消防署は、運転していないときに消防車や消防士がいる場所です。", + "title": "消防署" + } + }, + "tagRenderings": { + "station-agency": { + "mappings": { + "0": { + "then": "消防局(消防庁)" + } + }, + "question": "このステーションを運営しているのはどこですか?", + "render": "このステーションは{operator}によって運営されています。" + }, + "station-name": { + "question": "この消防署の名前は何ですか?", + "render": "このステーションの名前は{name}です。" + }, + "station-operator": { + "mappings": { + "0": { + "then": "ステーションは自治体が運営する。" + }, + "1": { + "then": "任意団体やコミュニティが運営しているステーションである。" + }, + "2": { + "then": "公益団体が運営しているステーションである。" + }, + "3": { + "then": "個人が運営しているステーションである。" + } + }, + "question": "ステーションの運営の分類は?", + "render": "運営者は、{operator:type} です。" + }, + "station-place": { + "question": "このステーションの住所は?(例: 地区、村、または町の名称)", + "render": "このステーションは{addr:place}にあります。" + }, + "station-street": { + "question": " 救急ステーションの所在地はどこですか?", + "render": "{addr:street} 沿いにあります。" + } + }, + "title": { + "render": "消防署" + } + }, + "3": { + "description": "救急ステーションは、救急車、医療機器、個人用保護具、およびその他の医療用品を保管する場所です。", + "name": "救急ステーションの地図", + "presets": { + "0": { + "description": "救急ステーション(消防署)をマップに追加する", + "title": "救急ステーション(消防署)" + } + }, + "tagRenderings": { + "ambulance-agency": { + "question": "このステーションを運営しているのはどこですか?", + "render": "このステーションは{operator}によって運営されています。" + }, + "ambulance-name": { + "question": "この救急ステーションの名前は何ですか?", + "render": "このステーションの名前は{name}です。" + }, + "ambulance-operator-type": { + "mappings": { + "0": { + "then": "ステーションは自治体が運営する。" + }, + "1": { + "then": "任意団体やコミュニティが運営しているステーションである。" + }, + "2": { + "then": "公益団体が運営しているステーションである。" + }, + "3": { + "then": "個人が運営しているステーションである。" + } + }, + "question": "ステーションの運営の分類は?", + "render": "運営者は、{operator:type} です。" + }, + "ambulance-place": { + "question": "このステーションの住所は?(例: 地区、村、または町の名称)", + "render": "このステーションは{addr:place}にあります。" + }, + "ambulance-street": { + "question": " 救急ステーションの所在地はどこですか?", + "render": "{addr:street} 沿いにあります。" + } + }, + "title": { + "render": "救急ステーション" + } } }, "shortDescription": "消火栓、消火器、消防署消火栓、消火器、消防署、および救急ステーションを表示します。", @@ -918,7 +918,7 @@ "shops": { "description": "この地図には店の基本情報を記入したり営業時間や電話番号を追加することができます", "layers": { - "shops": { + "0": { "description": "ショップ", "name": "店", "presets": { diff --git a/langs/themes/nb_NO.json b/langs/themes/nb_NO.json index 35fb78455..f42affa6a 100644 --- a/langs/themes/nb_NO.json +++ b/langs/themes/nb_NO.json @@ -4,7 +4,7 @@ }, "artwork": { "layers": { - "artwork": { + "0": { "name": "Kunstverk", "presets": { "0": { @@ -82,7 +82,7 @@ }, "campersite": { "layers": { - "caravansites": { + "0": { "tagRenderings": { "caravansites-charge": { "question": "pø", @@ -119,19 +119,7 @@ }, "climbing": { "layers": { - "climbing": { - "description": "En klatremulighet", - "presets": { - "0": { - "description": "En klatremulighet", - "title": "Klatremulighet" - } - }, - "title": { - "render": "Klatremulighet" - } - }, - "climbing_club": { + "0": { "description": "En klatreklubb eller organisasjoner", "name": "Klatreklubb", "presets": { @@ -144,7 +132,7 @@ "render": "Klatreklubb" } }, - "climbing_route": { + "2": { "name": "Klatreruter", "tagRenderings": { "Length": { @@ -155,7 +143,19 @@ "render": "Klatrerute" } }, - "maybe_climbing": { + "3": { + "description": "En klatremulighet", + "presets": { + "0": { + "description": "En klatremulighet", + "title": "Klatremulighet" + } + }, + "title": { + "render": "Klatremulighet" + } + }, + "4": { "description": "En klatremulighet?", "name": "Klatremuligheter?", "tagRenderings": { @@ -196,15 +196,15 @@ }, "cyclestreets": { "layers": { - "all_streets": { - "description": "Lag for å markere hvilken som helst gate som sykkelvei", - "name": "Alle gater" - }, - "toekomstige_fietsstraat": { + "1": { "name": "Fremtidig sykkelvei", "title": { "render": "Fremtidig sykkelvei" } + }, + "2": { + "description": "Lag for å markere hvilken som helst gate som sykkelvei", + "name": "Alle gater" } }, "roamingRenderings": { @@ -230,7 +230,7 @@ }, "facadegardens": { "layers": { - "facadegardens": { + "0": { "tagRenderings": { "facadegardens-sunshine": { "mappings": { @@ -248,25 +248,7 @@ }, "hailhydrant": { "layers": { - "extinguisher": { - "description": "Kartlag for å vise brannslokkere.", - "name": "Kart over brannhydranter", - "presets": { - "0": { - "title": "Brannslukker" - } - }, - "title": { - "render": "Brannslokkere" - } - }, - "fire_stations": { - "name": "Kart over brannstasjoner", - "title": { - "render": "Brannstasjon" - } - }, - "hydrants": { + "0": { "description": "Kartlag for å vise brannhydranter.", "name": "Kart over brannhydranter", "presets": { @@ -283,6 +265,24 @@ "title": { "render": "Brannhydrant" } + }, + "1": { + "description": "Kartlag for å vise brannslokkere.", + "name": "Kart over brannhydranter", + "presets": { + "0": { + "title": "Brannslukker" + } + }, + "title": { + "render": "Brannslokkere" + } + }, + "2": { + "name": "Kart over brannstasjoner", + "title": { + "render": "Brannstasjon" + } } } } diff --git a/langs/themes/nl.json b/langs/themes/nl.json index 53bc832ea..a1e3dee82 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -10,7 +10,7 @@ "artwork": { "description": "Welkom op de open kunstwerken-kaart, een kaart van standbeelden, bustes, graffiti en andere kunstwerken over de hele wereld", "layers": { - "artwork": { + "0": { "description": "Verschillende soorten kunstwerken", "name": "Kunstwerken", "presets": { @@ -108,28 +108,7 @@ "description": "logo-groenmeld je aan voor e-mailupdates.", "descriptionTail": "

Tips

  • Over groen ingekleurde gebieden weten we alles wat we willen weten.
  • Bij rood ingekleurde gebieden ontbreekt nog heel wat info: klik een gebied aan en beantwoord de vragen.
  • Je kan altijd een vraag overslaan als je het antwoord niet weet of niet zeker bent
  • Je kan altijd een foto toevoegen
  • Je kan ook zelf een gebied toevoegen door op de kaart te klikken
  • Open buurtnatuur.be op je smartphone om al wandelend foto's te maken en vragen te beantwoorden

De oorspronkelijke data komt van OpenStreetMap en je antwoorden worden daar bewaard.
Omdat iedereen vrij kan meewerken aan dit project, kunnen we niet garanderen dat er geen fouten opduiken.Kan je hier niet aanpassen wat je wilt, dan kan je dat zelf via OpenStreetMap.org doen. Groen kan geen enkele verantwoordelijkheid nemen over de kaart.

Je privacy is belangrijk. We tellen wel hoeveel gebruikers deze website bezoeken. We plaatsen een cookie waar geen persoonlijke informatie in bewaard wordt. Als je inlogt, komt er een tweede cookie bij met je inloggegevens.
", "layers": { - "forest": { - "description": "Een bos is een verzameling bomen, al dan niet als productiehout.", - "name": "Bos", - "presets": { - "0": { - "description": "Voeg een ontbrekend bos toe aan de kaart", - "title": "Bos" - } - }, - "title": { - "mappings": { - "0": { - "then": "{name:nl}" - }, - "1": { - "then": "{name}" - } - }, - "render": "Bos" - } - }, - "nature_reserve_buurtnatuur": { + "0": { "description": "Een natuurgebied is een gebied waar actief ruimte gemaakt word voor de natuur. Typisch zijn deze in beheer van Natuurpunt of het Agentschap Natuur en Bos of zijn deze erkend door de overheid.", "name": "Natuurgebied", "presets": { @@ -150,7 +129,7 @@ "render": "Natuurgebied" } }, - "parks": { + "1": { "description": "Een park is een publiek toegankelijke, groene ruimte binnen de stad. Ze is typisch ingericht voor recreatief gebruik, met (verharde) wandelpaden, zitbanken, vuilnisbakken, een gezellig vijvertje, ...", "name": "Park", "presets": { @@ -170,6 +149,27 @@ }, "render": "Park" } + }, + "2": { + "description": "Een bos is een verzameling bomen, al dan niet als productiehout.", + "name": "Bos", + "presets": { + "0": { + "description": "Voeg een ontbrekend bos toe aan de kaart", + "title": "Bos" + } + }, + "title": { + "mappings": { + "0": { + "then": "{name:nl}" + }, + "1": { + "then": "{name}" + } + }, + "render": "Bos" + } } }, "roamingRenderings": { @@ -245,7 +245,7 @@ "campersite": { "description": "Deze website verzamelt en toont alle officiële plaatsen waar een camper mag overnachten en afvalwater kan lozen. Ook jij kan extra gegevens toevoegen, zoals welke services er geboden worden en hoeveel dit kot, ook afbeeldingen en reviews kan je toevoegen. De data wordt op OpenStreetMap opgeslagen en is dus altijd gratis te hergebruiken, ook door andere applicaties.", "layers": { - "caravansites": { + "0": { "description": "camperplaatsen", "name": "Camperplaatsen", "tagRenderings": { @@ -293,7 +293,88 @@ "description": "Op deze kaart vind je verschillende klimgelegenheden, zoals klimzalen, bolderzalen en klimmen in de natuur", "descriptionTail": "De klimkaart is oorspronkelijk gemaakt door Christian Neumann op kletterspots.de.", "layers": { - "climbing": { + "0": { + "description": "Een klimclub of organisatie", + "name": "Klimclub", + "presets": { + "0": { + "description": "Een klimclub", + "title": "Klimclub" + }, + "1": { + "description": "Een VZW die werkt rond klimmen", + "title": "Een klimorganisatie" + } + }, + "tagRenderings": { + "climbing_club-name": { + "question": "Wat is de naam van deze klimclub?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Klimorganisatie" + } + }, + "render": "Klimclub" + } + }, + "1": { + "description": "Een klimzaal", + "name": "Klimzalen", + "tagRenderings": { + "name": { + "question": "Wat is de naam van dit Klimzaal?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Klimzaal {name}" + } + }, + "render": "Klimzaal" + } + }, + "2": { + "name": "Klimroute", + "presets": { + "0": { + "title": "Klimroute" + } + }, + "tagRenderings": { + "Difficulty": { + "question": "Hoe moeilijk is deze klimroute volgens het Franse/Belgische systeem?", + "render": "De klimmoeilijkheid is {climbing:grade:french} volgens het Franse/Belgische systeem" + }, + "Length": { + "question": "Hoe lang is deze klimroute (in meters)?", + "render": "Deze klimroute is {canonical(climbing:length)} lang" + }, + "Name": { + "mappings": { + "0": { + "then": "Deze klimroute heeft geen naam" + } + }, + "question": "Hoe heet deze klimroute?", + "render": "{name}" + } + }, + "title": { + "mappings": { + "0": { + "then": "Klimroute {name}" + } + }, + "render": "Klimroute" + } + }, + "3": { "description": "Een klimgelegenheid", "name": "Klimgelegenheden", "presets": { @@ -335,88 +416,7 @@ "render": "Klimgelegenheid" } }, - "climbing_club": { - "description": "Een klimclub of organisatie", - "name": "Klimclub", - "presets": { - "0": { - "description": "Een klimclub", - "title": "Klimclub" - }, - "1": { - "description": "Een VZW die werkt rond klimmen", - "title": "Een klimorganisatie" - } - }, - "tagRenderings": { - "climbing_club-name": { - "question": "Wat is de naam van deze klimclub?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Klimorganisatie" - } - }, - "render": "Klimclub" - } - }, - "climbing_gym": { - "description": "Een klimzaal", - "name": "Klimzalen", - "tagRenderings": { - "name": { - "question": "Wat is de naam van dit Klimzaal?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Klimzaal {name}" - } - }, - "render": "Klimzaal" - } - }, - "climbing_route": { - "name": "Klimroute", - "presets": { - "0": { - "title": "Klimroute" - } - }, - "tagRenderings": { - "Difficulty": { - "question": "Hoe moeilijk is deze klimroute volgens het Franse/Belgische systeem?", - "render": "De klimmoeilijkheid is {climbing:grade:french} volgens het Franse/Belgische systeem" - }, - "Length": { - "question": "Hoe lang is deze klimroute (in meters)?", - "render": "Deze klimroute is {canonical(climbing:length)} lang" - }, - "Name": { - "mappings": { - "0": { - "then": "Deze klimroute heeft geen naam" - } - }, - "question": "Hoe heet deze klimroute?", - "render": "{name}" - } - }, - "title": { - "mappings": { - "0": { - "then": "Klimroute {name}" - } - }, - "render": "Klimroute" - } - }, - "maybe_climbing": { + "4": { "description": "Een klimgelegenheid?", "name": "Klimgelegenheiden?", "tagRenderings": { @@ -566,18 +566,11 @@ "cyclestreets": { "description": "Een fietsstraat is een straat waar
  • automobilisten geen fietsers mogen inhalen
  • Er een maximumsnelheid van 30km/u geldt
  • Fietsers gemotoriseerde voertuigen links mogen inhalen
  • Fietsers nog steeds voorrang aan rechts moeten verlenen - ook aan auto's en voetgangers op het zebrapad


Op deze open kaart kan je alle gekende fietsstraten zien en kan je ontbrekende fietsstraten aanduiden. Om de kaart aan te passen, moet je je aanmelden met OpenStreetMap en helemaal inzoomen tot straatniveau. ", "layers": { - "all_streets": { - "description": "Laag waar je een straat als fietsstraat kan markeren", - "name": "Alle straten", - "title": { - "render": "Straat" - } - }, - "fietsstraat": { + "0": { "description": "Een fietsstraat is een straat waar gemotoriseerd verkeer een fietser niet mag inhalen.", "name": "Fietsstraten" }, - "toekomstige_fietsstraat": { + "1": { "description": "Deze straat wordt binnenkort een fietsstraat", "name": "Toekomstige fietsstraat", "title": { @@ -588,6 +581,13 @@ }, "render": "Toekomstige fietsstraat" } + }, + "2": { + "description": "Laag waar je een straat als fietsstraat kan markeren", + "name": "Alle straten", + "title": { + "render": "Straat" + } } }, "roamingRenderings": { @@ -627,7 +627,7 @@ "facadegardens": { "description": "Ontharde voortuintjes, groene gevels en bomen ín de stad brengen naast rust ook een mooiere stad, een grotere biodiversiteit, een verkoelend effect en een betere luchtkwaliteit.
Klimaan VZW en 'Mechelen Klimaatneutraal' willen met het project Klim(t)aan je Gevel bestaande en nieuwe geveltuintjes in kaart brengen als voorbeeld voor mensen zelf een tuintje willen aanleggen of voor stadwandelaars die houden van de natuur.
Meer info over het project op klimaan.be.", "layers": { - "facadegardens": { + "0": { "description": "Geveltuintjes", "name": "Geveltuintjes", "presets": { @@ -719,7 +719,7 @@ "description": "Op deze kaart vind je je favoriete frituur!", "layers": { "0": { - "friture": { + "override": { "name": "Frituren" } } @@ -729,7 +729,19 @@ "fruit_trees": { "description": "Op deze kaart vindt je boomgaarden en fruitbomen", "layers": { - "fruitboom": { + "0": { + "name": "Boomgaarden", + "presets": { + "0": { + "description": "Voeg een boomgaard toe (als punt - omtrek nog te tekenen)", + "title": "Boomgaard" + } + }, + "title": { + "render": "Boomgaard" + } + }, + "1": { "description": "Een boom", "name": "Boom", "presets": { @@ -759,18 +771,6 @@ "title": { "render": "Boom" } - }, - "orchards": { - "name": "Boomgaarden", - "presets": { - "0": { - "description": "Voeg een boomgaard toe (als punt - omtrek nog te tekenen)", - "title": "Boomgaard" - } - }, - "title": { - "render": "Boomgaard" - } } }, "shortDescription": "Boomgaarden en fruitbomen", @@ -783,7 +783,7 @@ "grb": { "description": "GRB Fixup", "layers": { - "grb-fixmes": { + "0": { "description": "Dit gebouw heeft een foutmelding", "name": "Fixmes op gebouwen", "tagRenderings": { @@ -852,7 +852,7 @@ }, "openwindpowermap": { "layers": { - "windturbine": { + "0": { "name": "windturbine", "presets": { "0": { @@ -911,7 +911,7 @@ }, "shops": { "layers": { - "shops": { + "0": { "description": "Een winkel", "name": "Winkel", "presets": { @@ -959,7 +959,7 @@ "speelplekken": { "description": "

Welkom bij de Groendoener!

De Zuidrand dat is spelen, ravotten, chillen, wandelen,… in het groen. Meer dan 200 grote en kleine speelplekken liggen er in parken, in bossen en op pleintjes te wachten om ontdekt te worden. De verschillende speelplekken werden getest én goedgekeurd door kinder- en jongerenreporters uit de Zuidrand. Met leuke challenges dagen de reporters jou uit om ook op ontdekking te gaan. Klik op een speelplek op de kaart, bekijk het filmpje en ga op verkenning!

Het project groendoener kadert binnen het strategisch project Beleefbare Open Ruimte in de Antwerpse Zuidrand en is een samenwerking tussen het departement Leefmilieu van provincie Antwerpen, Sportpret vzw, een OpenStreetMap-België Consultent en Createlli vzw. Het project kwam tot stand met steun van Departement Omgeving van de Vlaamse Overheid.
", "layers": { - "walking_routes": { + "7": { "name": "Wandelroutes van provincie Antwerpen", "tagRenderings": { "walk-description": { diff --git a/langs/themes/pt_BR.json b/langs/themes/pt_BR.json index cc97313f2..6c7de8bfd 100644 --- a/langs/themes/pt_BR.json +++ b/langs/themes/pt_BR.json @@ -15,7 +15,7 @@ }, "campersite": { "layers": { - "caravansites": { + "0": { "description": "Locais de acampamento", "name": "Locais de acampamento", "presets": { @@ -122,7 +122,7 @@ "render": "Local de acampamento {name}" } }, - "dumpstations": { + "1": { "description": "Estações de despejo sanitário", "name": "Estações de despejo sanitário", "tagRenderings": { diff --git a/langs/themes/ru.json b/langs/themes/ru.json index 1c8f6076d..d03cdc427 100644 --- a/langs/themes/ru.json +++ b/langs/themes/ru.json @@ -6,7 +6,7 @@ "artwork": { "description": "Добро пожаловать на Open Artwork Map, карту статуй, бюстов, граффити и других произведений искусства по всему миру", "layers": { - "artwork": { + "0": { "description": "Разнообразные произведения искусства", "name": "Произведения искусства", "presets": { @@ -98,7 +98,7 @@ "campersite": { "description": "На этом сайте собраны все официальные места остановки кемперов и места, где можно сбросить серую и черную воду. Вы можете добавить подробную информацию о предоставляемых услугах и их стоимости. Добавлять фотографии и отзывы. Это веб-сайт и веб-приложение. Данные хранятся в OpenStreetMap, поэтому они будут бесплатными всегда и могут быть повторно использованы любым приложением.", "layers": { - "caravansites": { + "0": { "description": "площадки для кемпинга", "name": "Площадки для кемпинга", "presets": { @@ -210,7 +210,7 @@ "render": "Место для кемпинга {name}" } }, - "dumpstations": { + "1": { "description": "Ассенизационные сливные станции", "name": "Места для слива отходов из туалетных резервуаров", "tagRenderings": { @@ -298,14 +298,7 @@ "description": "На этой карте вы найдете различные возможности для скалолазания, такие как скалодромы, залы для боулдеринга и скалы на природе.", "descriptionTail": "Создатель карты скалолазания — Christian Neumann. Пожалуйста, пишите если у вас есть отзыв или вопросы.

Проект использует данные OpenStreetMap.

", "layers": { - "climbing": { - "tagRenderings": { - "name": { - "render": "{name}" - } - } - }, - "climbing_club": { + "0": { "name": "Клуб скалолазания", "presets": { "0": { @@ -322,21 +315,28 @@ "render": "Клуб скалолазания" } }, - "climbing_gym": { + "1": { "tagRenderings": { "name": { "render": "{name}" } } }, - "climbing_route": { + "2": { "tagRenderings": { "Name": { "render": "{name}" } } }, - "maybe_climbing": { + "3": { + "tagRenderings": { + "name": { + "render": "{name}" + } + } + }, + "4": { "tagRenderings": { "climbing-opportunity-name": { "render": "{name}" @@ -370,7 +370,7 @@ }, "cyclestreets": { "layers": { - "all_streets": { + "2": { "name": "Все улицы", "title": { "render": "Улица" @@ -387,7 +387,7 @@ }, "facadegardens": { "layers": { - "facadegardens": { + "0": { "tagRenderings": { "facadegardens-description": { "question": "Дополнительная информация о саде (если требуется или еще не указана выше)", @@ -421,85 +421,7 @@ }, "hailhydrant": { "layers": { - "ambulancestation": { - "name": "Карта станций скорой помощи", - "presets": { - "0": { - "description": "Добавить станцию скорой помощи на карту", - "title": "Станция скорой помощи" - } - }, - "tagRenderings": { - "ambulance-name": { - "question": "Как называется эта станция скорой помощи?", - "render": "Эта станция называется {name}." - }, - "ambulance-place": { - "question": "Где расположена станция? (напр., название населённого пункта)" - }, - "ambulance-street": { - "question": " По какому адресу расположена эта станция?", - "render": "Эта станция расположена вдоль шоссе {addr:street}." - } - }, - "title": { - "render": "Станция скорой помощи" - } - }, - "extinguisher": { - "description": "Слой карты, отображающий огнетушители.", - "name": "Карта огнетушителей.", - "presets": { - "0": { - "description": "Огнетушитель - небольшое переносное устройство для тушения огня", - "title": "Огнетушитель" - } - }, - "tagRenderings": { - "extinguisher-location": { - "mappings": { - "0": { - "then": "Внутри." - }, - "1": { - "then": "Снаружи." - } - }, - "question": "Где это расположено?", - "render": "Местоположение: {location}" - } - }, - "title": { - "render": "Огнетушители" - } - }, - "fire_stations": { - "description": "Слой карты, отображающий пожарные части.", - "name": "Карта пожарных частей", - "presets": { - "0": { - "title": "Пожарная часть" - } - }, - "tagRenderings": { - "station-name": { - "question": "Как называется эта пожарная часть?", - "render": "Эта часть называется {name}." - }, - "station-place": { - "question": "Где расположена часть? (напр., название населённого пункта)", - "render": "Эта часть расположена в {addr:place}." - }, - "station-street": { - "question": " По какому адресу расположена эта часть?", - "render": "Часть расположена вдоль шоссе {addr:street}." - } - }, - "title": { - "render": "Пожарная часть" - } - }, - "hydrants": { + "0": { "description": "Слой карты, отображающий пожарные гидранты.", "name": "Карта пожарных гидрантов", "presets": { @@ -549,6 +471,84 @@ "title": { "render": "Гидрант" } + }, + "1": { + "description": "Слой карты, отображающий огнетушители.", + "name": "Карта огнетушителей.", + "presets": { + "0": { + "description": "Огнетушитель - небольшое переносное устройство для тушения огня", + "title": "Огнетушитель" + } + }, + "tagRenderings": { + "extinguisher-location": { + "mappings": { + "0": { + "then": "Внутри." + }, + "1": { + "then": "Снаружи." + } + }, + "question": "Где это расположено?", + "render": "Местоположение: {location}" + } + }, + "title": { + "render": "Огнетушители" + } + }, + "2": { + "description": "Слой карты, отображающий пожарные части.", + "name": "Карта пожарных частей", + "presets": { + "0": { + "title": "Пожарная часть" + } + }, + "tagRenderings": { + "station-name": { + "question": "Как называется эта пожарная часть?", + "render": "Эта часть называется {name}." + }, + "station-place": { + "question": "Где расположена часть? (напр., название населённого пункта)", + "render": "Эта часть расположена в {addr:place}." + }, + "station-street": { + "question": " По какому адресу расположена эта часть?", + "render": "Часть расположена вдоль шоссе {addr:street}." + } + }, + "title": { + "render": "Пожарная часть" + } + }, + "3": { + "name": "Карта станций скорой помощи", + "presets": { + "0": { + "description": "Добавить станцию скорой помощи на карту", + "title": "Станция скорой помощи" + } + }, + "tagRenderings": { + "ambulance-name": { + "question": "Как называется эта станция скорой помощи?", + "render": "Эта станция называется {name}." + }, + "ambulance-place": { + "question": "Где расположена станция? (напр., название населённого пункта)" + }, + "ambulance-street": { + "question": " По какому адресу расположена эта станция?", + "render": "Эта станция расположена вдоль шоссе {addr:street}." + } + }, + "title": { + "render": "Станция скорой помощи" + } } }, "shortDescription": "Карта пожарных гидрантов, огнетушителей, пожарных станций и станций скорой помощи.", @@ -567,7 +567,7 @@ }, "shops": { "layers": { - "shops": { + "0": { "description": "Магазин", "name": "Магазин", "presets": { diff --git a/langs/themes/zh_Hant.json b/langs/themes/zh_Hant.json index 5dfff1615..4464b762f 100644 --- a/langs/themes/zh_Hant.json +++ b/langs/themes/zh_Hant.json @@ -6,7 +6,7 @@ "artwork": { "description": "歡迎來到開放藝術品地圖,這份地圖會顯示全世界的雕像、半身像、塗鴉以及其他類型的藝術品", "layers": { - "artwork": { + "0": { "description": "不同類型的藝術品", "name": "藝術品", "presets": { @@ -98,7 +98,7 @@ "campersite": { "description": "這個網站收集所有官方露營地點,以及那邊能排放廢水。你可以加上詳細的服務項目與價格,加上圖片以及評價。這是網站與網路 app,資料則是存在開放街圖,因此會永遠免費,而且可以被所有 app 再利用。", "layers": { - "caravansites": { + "0": { "description": "露營地", "name": "露營地", "presets": { @@ -209,7 +209,7 @@ "render": "露營地 {name}" } }, - "dumpstations": { + "1": { "tagRenderings": { "dumpstations-chemical-waste": { "mappings": { @@ -237,7 +237,7 @@ "description": "在這份地圖上你會發現能夠攀爬機會,像是攀岩體育館、抱石大廳以及大自然當中的巨石。", "descriptionTail": "攀爬地圖最初由 Christian Neumann 製作。如果你有回饋意見或問題請到Please 這邊反應

這專案使用來自開放街圖專案的資料。

", "layers": { - "climbing_club": { + "0": { "description": "攀岩社團或組織", "name": "攀岩社團", "tagRenderings": { @@ -260,10 +260,10 @@ "cyclestreets": { "description": "單車街道是機動車輛受限制,只允許單車通行的道路。通常會有路標顯示特別的交通指標。單車街道通常在荷蘭、比利時看到,但德國與法國也有。 ", "layers": { - "fietsstraat": { + "0": { "name": "單車街道" }, - "toekomstige_fietsstraat": { + "1": { "name": "將來的單車街道" } }, @@ -280,7 +280,7 @@ }, "facadegardens": { "layers": { - "facadegardens": { + "0": { "description": "立面花園", "name": "立面花園", "title": { @@ -298,12 +298,12 @@ "hailhydrant": { "description": "在這份地圖上面你可以在你喜愛的社區尋找與更新消防栓、消防隊、急救站與滅火器。\n\n你可以追蹤確切位置 (只有行動版) 以及在左下角選擇與你相關的圖層。你也可以使用這工具新增或編輯地圖上的釘子 (興趣點),以及透過回答一些問題提供額外的資訊。\n\n所有你做出的變動都會自動存到開放街圖這個全球資料庫,而且能自由讓其他人取用。", "layers": { - "extinguisher": { - "description": "顯示消防栓的地圖圖層。" - }, - "hydrants": { + "0": { "description": "顯示消防栓的地圖圖層。", "name": "消防栓地圖" + }, + "1": { + "description": "顯示消防栓的地圖圖層。" } }, "shortDescription": "顯示消防栓、滅火器、消防隊與急救站的地圖。", diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index 58bba200d..27b2482ac 100644 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -61,14 +61,14 @@ class TranslationPart { continue } - if (v["id"] !== undefined) { + if (v["id"] !== undefined && context.endsWith("tagRenderings")) { // We use the embedded id as key instead of the index as this is more stable // Note: indonesian is shortened as 'id' as well! if (v["en"] !== undefined || v["nl"] !== undefined) { // This is probably a translation already! // pass } else { - + key = v["id"] if (typeof key !== "string") { throw "Panic: found a non-string ID at" + context @@ -247,16 +247,34 @@ function generateTranslationsObjectFrom(objects: { path: string, parsed: { id: s } } +/** + * Merge two objects together + * @param source: where the tranlations come from + * @param target: the object in which the translations should be merged + * @param language: the language code + * @param context: context for error handling + * @constructor + */ function MergeTranslation(source: any, target: any, language: string, context: string = "") { + let keyRemapping: Map = undefined + if (context.endsWith(".tagRenderings")) { + keyRemapping = new Map() + for (const key in target) { + keyRemapping.set(target[key].id, key) + } + } + for (const key in source) { if (!source.hasOwnProperty(key)) { continue } const sourceV = source[key]; - const targetV = target[key] + const targetV = target[keyRemapping?.get(key) ?? key] + if (typeof sourceV === "string") { + // Add the translation if (targetV === undefined) { if (typeof target === "string") { throw "Trying to merge a translation into a fixed string at " + context + " for key " + key; @@ -335,6 +353,9 @@ function mergeLayerTranslations() { } } +/** + * Load the translations into the theme files + */ function mergeThemeTranslations() { const themeFiles = ScriptUtils.getThemeFiles(); for (const themeFile of themeFiles) { From b58c6620993d5959d22f168b0d460f001b9ca154 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 21:06:37 +0200 Subject: [PATCH 27/65] Fix charging_station generation with new ids --- .../charging_station/charging_station.json | 308 ++--- .../charging_station.protojson | 36 +- assets/layers/charging_station/csvToJson.ts | 18 +- langs/layers/en.json | 1204 +++++++++-------- langs/layers/it.json | 8 +- langs/layers/ja.json | 8 +- langs/layers/nb_NO.json | 8 +- langs/layers/nl.json | 1066 ++++++++------- langs/layers/ru.json | 8 +- langs/layers/zh_Hant.json | 8 +- 10 files changed, 1342 insertions(+), 1330 deletions(-) diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json index 729a74fb3..62ac38176 100644 --- a/assets/layers/charging_station/charging_station.json +++ b/assets/layers/charging_station/charging_station.json @@ -43,6 +43,7 @@ "tagRenderings": [ "images", { + "#": "Type", "question": { "en": "Which vehicles are allowed to charge here?" }, @@ -89,10 +90,10 @@ "en": "Buses can be charged here" } } - ], - "id": "Type" + ] }, { + "#": "access", "question": { "en": "Who is allowed to use this charging station?" }, @@ -128,10 +129,10 @@ "if": "access=private", "then": "Not accessible to the general public (e.g. only accessible to the owners, employees, ...)" } - ], - "id": "access" + ] }, { + "#": "capacity", "render": { "en": "{capacity} vehicles can be charged here at the same time", "nl": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" @@ -143,10 +144,10 @@ "freeform": { "key": "capacity", "type": "pnat" - }, - "id": "capacity" + } }, { + "#": "Available_charging_stations (generated)", "question": { "en": "Which charging stations are available here?" }, @@ -447,10 +448,10 @@ }, "hideInAnswer": true } - ], - "id": "Available_charging_stations (generated)" + ] }, { + "#": "plugs-0", "question": { "en": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", "nl": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?" @@ -468,10 +469,10 @@ "socket:schuko~*", "socket:schuko!=0" ] - }, - "id": "plugs-0" + } }, { + "#": "voltage-0", "question": { "en": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", "nl": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) " @@ -498,10 +499,10 @@ "socket:schuko~*", "socket:schuko!=0" ] - }, - "id": "voltage-0" + } }, { + "#": "current-0", "question": { "en": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", "nl": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" @@ -528,10 +529,10 @@ "socket:schuko~*", "socket:schuko!=0" ] - }, - "id": "current-0" + } }, { + "#": "power-output-0", "question": { "en": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", "nl": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" @@ -558,10 +559,10 @@ "socket:schuko~*", "socket:schuko!=0" ] - }, - "id": "power-output-0" + } }, { + "#": "plugs-1", "question": { "en": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", "nl": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?" @@ -579,10 +580,10 @@ "socket:typee~*", "socket:typee!=0" ] - }, - "id": "plugs-1" + } }, { + "#": "voltage-1", "question": { "en": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", "nl": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) " @@ -609,10 +610,10 @@ "socket:typee~*", "socket:typee!=0" ] - }, - "id": "voltage-1" + } }, { + "#": "current-1", "question": { "en": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", "nl": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" @@ -639,10 +640,10 @@ "socket:typee~*", "socket:typee!=0" ] - }, - "id": "current-1" + } }, { + "#": "power-output-1", "question": { "en": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", "nl": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" @@ -676,10 +677,10 @@ "socket:typee~*", "socket:typee!=0" ] - }, - "id": "power-output-1" + } }, { + "#": "plugs-2", "question": { "en": "How much plugs of type Chademo are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -697,10 +698,10 @@ "socket:chademo~*", "socket:chademo!=0" ] - }, - "id": "plugs-2" + } }, { + "#": "voltage-2", "question": { "en": "What voltage do the plugs with Chademo offer?", "nl": "Welke spanning levert de stekker van type " @@ -727,10 +728,10 @@ "socket:chademo~*", "socket:chademo!=0" ] - }, - "id": "voltage-2" + } }, { + "#": "current-2", "question": { "en": "What current do the plugs with Chademo offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -757,10 +758,10 @@ "socket:chademo~*", "socket:chademo!=0" ] - }, - "id": "current-2" + } }, { + "#": "power-output-2", "question": { "en": "What power output does a single plug of type Chademo offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -787,10 +788,10 @@ "socket:chademo~*", "socket:chademo!=0" ] - }, - "id": "power-output-2" + } }, { + "#": "plugs-3", "question": { "en": "How much plugs of type Type 1 with cable (J1772) are available here?", "nl": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?" @@ -808,10 +809,10 @@ "socket:type1_cable~*", "socket:type1_cable!=0" ] - }, - "id": "plugs-3" + } }, { + "#": "voltage-3", "question": { "en": "What voltage do the plugs with Type 1 with cable (J1772) offer?", "nl": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) " @@ -845,10 +846,10 @@ "socket:type1_cable~*", "socket:type1_cable!=0" ] - }, - "id": "voltage-3" + } }, { + "#": "current-3", "question": { "en": "What current do the plugs with Type 1 with cable (J1772) offer?", "nl": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?" @@ -875,10 +876,10 @@ "socket:type1_cable~*", "socket:type1_cable!=0" ] - }, - "id": "current-3" + } }, { + "#": "power-output-3", "question": { "en": "What power output does a single plug of type Type 1 with cable (J1772) offer?", "nl": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?" @@ -912,10 +913,10 @@ "socket:type1_cable~*", "socket:type1_cable!=0" ] - }, - "id": "power-output-3" + } }, { + "#": "plugs-4", "question": { "en": "How much plugs of type Type 1 without cable (J1772) are available here?", "nl": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?" @@ -933,10 +934,10 @@ "socket:type1~*", "socket:type1!=0" ] - }, - "id": "plugs-4" + } }, { + "#": "voltage-4", "question": { "en": "What voltage do the plugs with Type 1 without cable (J1772) offer?", "nl": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) " @@ -970,10 +971,10 @@ "socket:type1~*", "socket:type1!=0" ] - }, - "id": "voltage-4" + } }, { + "#": "current-4", "question": { "en": "What current do the plugs with Type 1 without cable (J1772) offer?", "nl": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?" @@ -1000,10 +1001,10 @@ "socket:type1~*", "socket:type1!=0" ] - }, - "id": "current-4" + } }, { + "#": "power-output-4", "question": { "en": "What power output does a single plug of type Type 1 without cable (J1772) offer?", "nl": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?" @@ -1051,10 +1052,10 @@ "socket:type1~*", "socket:type1!=0" ] - }, - "id": "power-output-4" + } }, { + "#": "plugs-5", "question": { "en": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1072,10 +1073,10 @@ "socket:type1_combo~*", "socket:type1_combo!=0" ] - }, - "id": "plugs-5" + } }, { + "#": "voltage-5", "question": { "en": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", "nl": "Welke spanning levert de stekker van type " @@ -1109,10 +1110,10 @@ "socket:type1_combo~*", "socket:type1_combo!=0" ] - }, - "id": "voltage-5" + } }, { + "#": "current-5", "question": { "en": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1146,10 +1147,10 @@ "socket:type1_combo~*", "socket:type1_combo!=0" ] - }, - "id": "current-5" + } }, { + "#": "power-output-5", "question": { "en": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1197,10 +1198,10 @@ "socket:type1_combo~*", "socket:type1_combo!=0" ] - }, - "id": "power-output-5" + } }, { + "#": "plugs-6", "question": { "en": "How much plugs of type Tesla Supercharger are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1218,10 +1219,10 @@ "socket:tesla_supercharger~*", "socket:tesla_supercharger!=0" ] - }, - "id": "plugs-6" + } }, { + "#": "voltage-6", "question": { "en": "What voltage do the plugs with Tesla Supercharger offer?", "nl": "Welke spanning levert de stekker van type " @@ -1248,10 +1249,10 @@ "socket:tesla_supercharger~*", "socket:tesla_supercharger!=0" ] - }, - "id": "voltage-6" + } }, { + "#": "current-6", "question": { "en": "What current do the plugs with Tesla Supercharger offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1285,10 +1286,10 @@ "socket:tesla_supercharger~*", "socket:tesla_supercharger!=0" ] - }, - "id": "current-6" + } }, { + "#": "power-output-6", "question": { "en": "What power output does a single plug of type Tesla Supercharger offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1329,10 +1330,10 @@ "socket:tesla_supercharger~*", "socket:tesla_supercharger!=0" ] - }, - "id": "power-output-6" + } }, { + "#": "plugs-7", "question": { "en": "How much plugs of type Type 2 (mennekes) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1350,10 +1351,10 @@ "socket:type2~*", "socket:type2!=0" ] - }, - "id": "plugs-7" + } }, { + "#": "voltage-7", "question": { "en": "What voltage do the plugs with Type 2 (mennekes) offer?", "nl": "Welke spanning levert de stekker van type " @@ -1387,10 +1388,10 @@ "socket:type2~*", "socket:type2!=0" ] - }, - "id": "voltage-7" + } }, { + "#": "current-7", "question": { "en": "What current do the plugs with Type 2 (mennekes) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1424,10 +1425,10 @@ "socket:type2~*", "socket:type2!=0" ] - }, - "id": "current-7" + } }, { + "#": "power-output-7", "question": { "en": "What power output does a single plug of type Type 2 (mennekes) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1461,10 +1462,10 @@ "socket:type2~*", "socket:type2!=0" ] - }, - "id": "power-output-7" + } }, { + "#": "plugs-8", "question": { "en": "How much plugs of type Type 2 CCS (mennekes) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1482,10 +1483,10 @@ "socket:type2_combo~*", "socket:type2_combo!=0" ] - }, - "id": "plugs-8" + } }, { + "#": "voltage-8", "question": { "en": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", "nl": "Welke spanning levert de stekker van type " @@ -1519,10 +1520,10 @@ "socket:type2_combo~*", "socket:type2_combo!=0" ] - }, - "id": "voltage-8" + } }, { + "#": "current-8", "question": { "en": "What current do the plugs with Type 2 CCS (mennekes) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1556,10 +1557,10 @@ "socket:type2_combo~*", "socket:type2_combo!=0" ] - }, - "id": "current-8" + } }, { + "#": "power-output-8", "question": { "en": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1586,10 +1587,10 @@ "socket:type2_combo~*", "socket:type2_combo!=0" ] - }, - "id": "power-output-8" + } }, { + "#": "plugs-9", "question": { "en": "How much plugs of type Type 2 with cable (mennekes) are available here?", "nl": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?" @@ -1607,10 +1608,10 @@ "socket:type2_cable~*", "socket:type2_cable!=0" ] - }, - "id": "plugs-9" + } }, { + "#": "voltage-9", "question": { "en": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", "nl": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) " @@ -1644,10 +1645,10 @@ "socket:type2_cable~*", "socket:type2_cable!=0" ] - }, - "id": "voltage-9" + } }, { + "#": "current-9", "question": { "en": "What current do the plugs with Type 2 with cable (mennekes) offer?", "nl": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?" @@ -1681,10 +1682,10 @@ "socket:type2_cable~*", "socket:type2_cable!=0" ] - }, - "id": "current-9" + } }, { + "#": "power-output-9", "question": { "en": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", "nl": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?" @@ -1718,10 +1719,10 @@ "socket:type2_cable~*", "socket:type2_cable!=0" ] - }, - "id": "power-output-9" + } }, { + "#": "plugs-10", "question": { "en": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1739,10 +1740,10 @@ "socket:tesla_supercharger_ccs~*", "socket:tesla_supercharger_ccs!=0" ] - }, - "id": "plugs-10" + } }, { + "#": "voltage-10", "question": { "en": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", "nl": "Welke spanning levert de stekker van type " @@ -1776,10 +1777,10 @@ "socket:tesla_supercharger_ccs~*", "socket:tesla_supercharger_ccs!=0" ] - }, - "id": "voltage-10" + } }, { + "#": "current-10", "question": { "en": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1813,10 +1814,10 @@ "socket:tesla_supercharger_ccs~*", "socket:tesla_supercharger_ccs!=0" ] - }, - "id": "current-10" + } }, { + "#": "power-output-10", "question": { "en": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1843,10 +1844,10 @@ "socket:tesla_supercharger_ccs~*", "socket:tesla_supercharger_ccs!=0" ] - }, - "id": "power-output-10" + } }, { + "#": "plugs-11", "question": { "en": "How much plugs of type Tesla Supercharger (destination) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1864,10 +1865,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - }, - "id": "plugs-11" + } }, { + "#": "voltage-11", "question": { "en": "What voltage do the plugs with Tesla Supercharger (destination) offer?", "nl": "Welke spanning levert de stekker van type " @@ -1894,10 +1895,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - }, - "id": "voltage-11" + } }, { + "#": "current-11", "question": { "en": "What current do the plugs with Tesla Supercharger (destination) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -1931,10 +1932,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - }, - "id": "current-11" + } }, { + "#": "power-output-11", "question": { "en": "What power output does a single plug of type Tesla Supercharger (destination) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -1975,10 +1976,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - }, - "id": "power-output-11" + } }, { + "#": "plugs-12", "question": { "en": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" @@ -1996,10 +1997,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - }, - "id": "plugs-12" + } }, { + "#": "voltage-12", "question": { "en": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", "nl": "Welke spanning levert de stekker van type " @@ -2033,10 +2034,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - }, - "id": "voltage-12" + } }, { + "#": "current-12", "question": { "en": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", "nl": "Welke stroom levert de stekker van type ?" @@ -2070,10 +2071,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - }, - "id": "current-12" + } }, { + "#": "power-output-12", "question": { "en": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", "nl": "Welk vermogen levert een enkele stekker van type ?" @@ -2107,10 +2108,10 @@ "socket:tesla_destination~*", "socket:tesla_destination!=0" ] - }, - "id": "power-output-12" + } }, { + "#": "Authentication", "question": { "en": "What kind of authentication is available at the charging station?", "it": "Quali sono gli orari di apertura di questa stazione di ricarica?", @@ -2177,10 +2178,10 @@ "en": "No authentication is needed" } } - ], - "id": "Authentication" + ] }, { + "#": "Auth phone", "render": { "en": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}", "it": "{network}", @@ -2225,10 +2226,10 @@ "0": { "then": "不屬於大型網路" } - }, - "id": "Auth phone" + } }, { + "#": "OH", "render": "{opening_hours_table(opening_hours)}", "freeform": { "key": "opening_hours", @@ -2244,10 +2245,10 @@ "en": "24/7 opened (including holidays)" } } - ], - "id": "OH" + ] }, { + "#": "fee/charge", "question": { "en": "How much does one have to pay to use this charging station?", "nl": "Hoeveel kost het gebruik van dit oplaadpunt?" @@ -2275,10 +2276,10 @@ "en": "Free to use" } } - ], - "id": "fee/charge" + ] }, { + "#": "payment-options", "builtin": "payment-options", "override": { "condition": { @@ -2295,22 +2296,20 @@ "en": "Payment is done using a dedicated app", "nl": "Betalen via een app van het netwerk" } - } - ], - "mappings": [ + }, { - "if": "payment:app=yes", - "ifnot": "payment:app=no", + "if": "payment:membership_card=yes", + "ifnot": "payment:membership_card=no", "then": { - "en": "Payment is done using a dedicated app", - "nl": "Betalen via een app van het netwerk" + "en": "Payment is done using a membership card", + "nl": "Betalen via een lidkaart van het netwerk" } } ] - }, - "id": "payment-options" + } }, { + "#": "maxstay", "question": { "en": "What is the maximum amount of time one is allowed to stay here?", "nl": "Hoelang mag een voertuig hier blijven staan?" @@ -2330,10 +2329,10 @@ "nl": "Geen maximum parkeertijd" } } - ], - "id": "maxstay" + ] }, { + "#": "Network", "render": { "en": "Part of the network {network}" }, @@ -2369,12 +2368,16 @@ "if": "network=eVgo", "then": "eVgo" } - ], - "id": "Network" + ] }, { - "question": "Who is the operator of this charging station?", - "render": "This charging station is operated by {operator}", + "#": "Operator", + "question": { + "en": "Who is the operator of this charging station?" + }, + "render": { + "en": "This charging station is operated by {operator}" + }, "freeform": { "key": "operator" }, @@ -2385,16 +2388,18 @@ "network:={operator}" ] }, - "then": "Actually, {operator} is the network", + "then": { + "en": "Actually, {operator} is the network" + }, "addExtraTags": [ "operator=" ], "hideInAnswer": "operator=" } - ], - "id": "Operator" + ] }, { + "#": "phone", "question": { "en": "What number can one call if there is a problem with this charging station?" }, @@ -2404,10 +2409,10 @@ "freeform": { "key": "phone", "type": "phone" - }, - "id": "phone" + } }, { + "#": "email", "question": { "en": "What is the email address of the operator?" }, @@ -2417,10 +2422,10 @@ "freeform": { "key": "email", "type": "email" - }, - "id": "email" + } }, { + "#": "website", "question": { "en": "What is the website of the operator?" }, @@ -2430,21 +2435,23 @@ "freeform": { "key": "website", "type": "url" - }, - "id": "website" + } }, "level", { + "#": "ref", "question": { "en": "What is the reference number of this charging station?" }, - "render": "Reference number is {ref}", + "render": { + "en": "Reference number is {ref}" + }, "freeform": { "key": "ref" - }, - "id": "ref" + } }, { + "#": "Operational status", "question": { "en": "Is this charging point in use?", "nl": "Is dit oplaadpunt operationeel?" @@ -2500,10 +2507,10 @@ "nl": "Dit oplaadpunt werkt" } } - ], - "id": "Operational status" + ] }, { + "#": "Parking:fee", "question": { "en": "Does one have to pay a parking fee while charging?" }, @@ -2520,8 +2527,7 @@ "en": "An additional parking fee should be paid while charging" } } - ], - "id": "Parking:fee" + ] } ], "icon": { diff --git a/assets/layers/charging_station/charging_station.protojson b/assets/layers/charging_station/charging_station.protojson index 39714ef8a..e76636ba7 100644 --- a/assets/layers/charging_station/charging_station.protojson +++ b/assets/layers/charging_station/charging_station.protojson @@ -43,7 +43,7 @@ "tagRenderings": [ "images", { - "#": "Type", + "id": "Type", "question": { "en": "Which vehicles are allowed to charge here?" }, @@ -93,7 +93,7 @@ ] }, { - "#": "access", + "id": "access", "question": { "en": "Who is allowed to use this charging station?" }, @@ -132,7 +132,7 @@ ] }, { - "#": "capacity", + "id": "capacity", "render": { "en": "{capacity} vehicles can be charged here at the same time", "nl": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" @@ -146,9 +146,9 @@ "type": "pnat" } }, - {"#": "$$$"}, + {"id": "$$$"}, { - "#": "Authentication", + "id": "Authentication", "question": { "en": "What kind of authentication is available at the charging station?", "it": "Quali sono gli orari di apertura di questa stazione di ricarica?", @@ -218,7 +218,7 @@ ] }, { - "#": "Auth phone", + "id": "Auth phone", "render": { "en": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}", "it": "{network}", @@ -266,7 +266,7 @@ } }, { - "#": "OH", + "id": "OH", "render": "{opening_hours_table(opening_hours)}", "freeform": { "key": "opening_hours", @@ -285,7 +285,7 @@ ] }, { - "#": "fee/charge", + "id": "fee/charge", "question": { "en": "How much does one have to pay to use this charging station?", "nl": "Hoeveel kost het gebruik van dit oplaadpunt?" @@ -316,7 +316,7 @@ ] }, { - "#": "payment-options", + "id": "payment-options", "builtin": "payment-options", "override": { "condition": { @@ -346,7 +346,7 @@ } }, { - "#": "maxstay", + "id": "maxstay", "question": { "en": "What is the maximum amount of time one is allowed to stay here?", "nl": "Hoelang mag een voertuig hier blijven staan?" @@ -369,7 +369,7 @@ ] }, { - "#": "Network", + "id": "Network", "render": { "en": "Part of the network {network}" }, @@ -408,7 +408,7 @@ ] }, { - "#": "Operator", + "id": "Operator", "question": { "en": "Who is the operator of this charging station?" }, @@ -436,7 +436,7 @@ ] }, { - "#": "phone", + "id": "phone", "question": { "en": "What number can one call if there is a problem with this charging station?" }, @@ -449,7 +449,7 @@ } }, { - "#": "email", + "id": "email", "question": { "en": "What is the email address of the operator?" }, @@ -462,7 +462,7 @@ } }, { - "#": "website", + "id": "website", "question": { "en": "What is the website of the operator?" }, @@ -476,7 +476,7 @@ }, "level", { - "#": "ref", + "id": "ref", "question": { "en": "What is the reference number of this charging station?" }, @@ -488,7 +488,7 @@ } }, { - "#": "Operational status", + "id": "Operational status", "question": { "en": "Is this charging point in use?", "nl": "Is dit oplaadpunt operationeel?" @@ -547,7 +547,7 @@ ] }, { - "#": "Parking:fee", + "id": "Parking:fee", "question": { "en": "Does one have to pay a parking fee while charging?" }, diff --git a/assets/layers/charging_station/csvToJson.ts b/assets/layers/charging_station/csvToJson.ts index f02033f59..2a1dfdb0b 100644 --- a/assets/layers/charging_station/csvToJson.ts +++ b/assets/layers/charging_station/csvToJson.ts @@ -53,7 +53,7 @@ function loadCsv(file): { function run(file, protojson) { const overview_question_answers = [] - const questions: (TagRenderingConfigJson & {"#": string})[] = [] + const questions: (TagRenderingConfigJson & {"id": string})[] = [] const filterOptions: { question: any, osmTags?: string } [] = [ { question: { @@ -103,7 +103,7 @@ function run(file, protojson) { const descrWithImage_nl = `${e.description.get("nl")} ` questions.push({ - "#":"plugs-"+i, + "id":"plugs-"+i, question: { en: `How much plugs of type ${descrWithImage_en} are available here?`, nl: `Hoeveel stekkers van type ${descrWithImage_nl} heeft dit oplaadpunt?`, @@ -122,7 +122,7 @@ function run(file, protojson) { }) questions.push({ - "#":"voltage-"+i, + "id":"voltage-"+i, question: { en: `What voltage do the plugs with ${descrWithImage_en} offer?`, nl: `Welke spanning levert de stekker van type ${descrWithImage_nl}` @@ -151,7 +151,7 @@ function run(file, protojson) { questions.push({ - "#":"current-"+i, + "id":"current-"+i, question: { en: `What current do the plugs with ${descrWithImage_en} offer?`, nl: `Welke stroom levert de stekker van type ${descrWithImage_nl}?`, @@ -180,7 +180,7 @@ function run(file, protojson) { questions.push({ - "#":"power-output-"+i, + "id":"power-output-"+i, question: { en: `What power output does a single plug of type ${descrWithImage_en} offer?`, nl: `Welk vermogen levert een enkele stekker van type ${descrWithImage_nl}?`, @@ -217,7 +217,7 @@ function run(file, protojson) { } const toggles = { - "#":"Available_charging_stations (generated)", + "id":"Available_charging_stations (generated)", "question": { "en": "Which charging stations are available here?" }, @@ -235,7 +235,7 @@ function run(file, protojson) { if(typeof tr === "string"){ return; } - if(tr["#"] === undefined || typeof tr["#"] !== "string"){ + if(tr["id"] === undefined || typeof tr["id"] !== "string"){ console.error(tr) throw "Every tagrendering should have an id, acting as comment" } @@ -348,11 +348,11 @@ function mergeTranslations(origPath, newConfig: LayerConfigJson){ for (const oldRendering of renderingsOld) { - const oldRenderingName = oldRendering["#"] + const oldRenderingName = oldRendering["id"] if(oldRenderingName === undefined){ continue } - const applicable = newRenderings.filter(r => r["#"] === oldRenderingName)[0] + const applicable = newRenderings.filter(r => r["id"] === oldRenderingName)[0] if(applicable === undefined){ continue; } diff --git a/langs/layers/en.json b/langs/layers/en.json index 79b62a672..c03b50f65 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -931,40 +931,35 @@ } }, "tagRenderings": { - "Auth phone": { - "question": "What's the phone number for authentication call or SMS?", - "render": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}" - }, - "Authentication": { + "1": { "mappings": { "0": { - "then": "Authentication by a membership card" + "then": "bicycles can be charged here" }, "1": { - "then": "Authentication by an app" + "then": "Cars can be charged here" }, "2": { - "then": "Authentication via phone call is available" + "then": "Scooters can be charged here" }, "3": { - "then": "Authentication via phone call is available" + "then": "Heavy good vehicles (such as trucks) can be charged here" }, "4": { - "then": "Authentication via NFC is available" - }, - "5": { - "then": "Authentication via Money Card is available" - }, - "6": { - "then": "Authentication via debit card is available" - }, - "7": { - "then": "No authentication is needed" + "then": "Buses can be charged here" } }, - "question": "What kind of authentication is available at the charging station?" + "question": "Which vehicles are allowed to charge here?" }, - "Available_charging_stations (generated)": { + "2": { + "question": "Who is allowed to use this charging station?", + "render": "Access is {access}" + }, + "3": { + "question": "How much vehicles can be charged here at the same time?", + "render": "{capacity} vehicles can be charged here at the same time" + }, + "4": { "mappings": { "0": { "then": " Schuko wall plug without ground pin (CEE7/4 type F)" @@ -1047,7 +1042,574 @@ }, "question": "Which charging stations are available here?" }, - "Network": { + "5": { + "question": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", + "render": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here" + }, + "6": { + "mappings": { + "0": { + "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt" + } + }, + "question": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt" + }, + "7": { + "mappings": { + "0": { + "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A" + } + }, + "question": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:current}A" + }, + "8": { + "mappings": { + "0": { + "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw" + } + }, + "question": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}" + }, + "9": { + "question": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", + "render": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here" + }, + "10": { + "mappings": { + "0": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt" + } + }, + "question": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "render": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt" + }, + "11": { + "mappings": { + "0": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A" + } + }, + "question": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A" + }, + "12": { + "mappings": { + "0": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw" + }, + "1": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", + "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}" + }, + "13": { + "question": "How much plugs of type Chademo are available here?", + "render": "There are Chademo plugs of type Chademo available here" + }, + "14": { + "mappings": { + "0": { + "then": "Chademo outputs 500 volt" + } + }, + "question": "What voltage do the plugs with Chademo offer?", + "render": "Chademo outputs {socket:chademo:voltage} volt" + }, + "15": { + "mappings": { + "0": { + "then": "Chademo outputs at most 120 A" + } + }, + "question": "What current do the plugs with Chademo offer?", + "render": "Chademo outputs at most {socket:chademo:current}A" + }, + "16": { + "mappings": { + "0": { + "then": "Chademo outputs at most 50 kw" + } + }, + "question": "What power output does a single plug of type Chademo offer?", + "render": "Chademo outputs at most {socket:chademo:output}" + }, + "17": { + "question": "How much plugs of type Type 1 with cable (J1772) are available here?", + "render": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here" + }, + "18": { + "mappings": { + "0": { + "then": "Type 1 with cable (J1772) outputs 200 volt" + }, + "1": { + "then": "Type 1 with cable (J1772) outputs 240 volt" + } + }, + "question": "What voltage do the plugs with Type 1 with cable (J1772) offer?", + "render": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt" + }, + "19": { + "mappings": { + "0": { + "then": "Type 1 with cable (J1772) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 1 with cable (J1772) offer?", + "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A" + }, + "20": { + "mappings": { + "0": { + "then": "Type 1 with cable (J1772) outputs at most 3.7 kw" + }, + "1": { + "then": "Type 1 with cable (J1772) outputs at most 7 kw" + } + }, + "question": "What power output does a single plug of type Type 1 with cable (J1772) offer?", + "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}" + }, + "21": { + "question": "How much plugs of type Type 1 without cable (J1772) are available here?", + "render": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here" + }, + "22": { + "mappings": { + "0": { + "then": "Type 1 without cable (J1772) outputs 200 volt" + }, + "1": { + "then": "Type 1 without cable (J1772) outputs 240 volt" + } + }, + "question": "What voltage do the plugs with Type 1 without cable (J1772) offer?", + "render": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt" + }, + "23": { + "mappings": { + "0": { + "then": "Type 1 without cable (J1772) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 1 without cable (J1772) offer?", + "render": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A" + }, + "24": { + "mappings": { + "0": { + "then": "Type 1 without cable (J1772) outputs at most 3.7 kw" + }, + "1": { + "then": "Type 1 without cable (J1772) outputs at most 6.6 kw" + }, + "2": { + "then": "Type 1 without cable (J1772) outputs at most 7 kw" + }, + "3": { + "then": "Type 1 without cable (J1772) outputs at most 7.2 kw" + } + }, + "question": "What power output does a single plug of type Type 1 without cable (J1772) offer?", + "render": "Type 1 without cable (J1772) outputs at most {socket:type1:output}" + }, + "25": { + "question": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", + "render": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here" + }, + "26": { + "mappings": { + "0": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt" + }, + "1": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt" + } + }, + "question": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "render": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt" + }, + "27": { + "mappings": { + "0": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A" + }, + "1": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A" + } + }, + "question": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A" + }, + "28": { + "mappings": { + "0": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw" + }, + "1": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw" + }, + "2": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw" + }, + "3": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw" + } + }, + "question": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", + "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}" + }, + "29": { + "question": "How much plugs of type Tesla Supercharger are available here?", + "render": "There are Tesla Supercharger plugs of type Tesla Supercharger available here" + }, + "30": { + "mappings": { + "0": { + "then": "Tesla Supercharger outputs 480 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger offer?", + "render": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt" + }, + "31": { + "mappings": { + "0": { + "then": "Tesla Supercharger outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger offer?", + "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A" + }, + "32": { + "mappings": { + "0": { + "then": "Tesla Supercharger outputs at most 120 kw" + }, + "1": { + "then": "Tesla Supercharger outputs at most 150 kw" + }, + "2": { + "then": "Tesla Supercharger outputs at most 250 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger offer?", + "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}" + }, + "33": { + "question": "How much plugs of type Type 2 (mennekes) are available here?", + "render": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here" + }, + "34": { + "mappings": { + "0": { + "then": "Type 2 (mennekes) outputs 230 volt" + }, + "1": { + "then": "Type 2 (mennekes) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Type 2 (mennekes) offer?", + "render": "Type 2 (mennekes) outputs {socket:type2:voltage} volt" + }, + "35": { + "mappings": { + "0": { + "then": "Type 2 (mennekes) outputs at most 16 A" + }, + "1": { + "then": "Type 2 (mennekes) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 2 (mennekes) offer?", + "render": "Type 2 (mennekes) outputs at most {socket:type2:current}A" + }, + "36": { + "mappings": { + "0": { + "then": "Type 2 (mennekes) outputs at most 11 kw" + }, + "1": { + "then": "Type 2 (mennekes) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Type 2 (mennekes) offer?", + "render": "Type 2 (mennekes) outputs at most {socket:type2:output}" + }, + "37": { + "question": "How much plugs of type Type 2 CCS (mennekes) are available here?", + "render": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here" + }, + "38": { + "mappings": { + "0": { + "then": "Type 2 CCS (mennekes) outputs 500 volt" + }, + "1": { + "then": "Type 2 CCS (mennekes) outputs 920 volt" + } + }, + "question": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", + "render": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt" + }, + "39": { + "mappings": { + "0": { + "then": "Type 2 CCS (mennekes) outputs at most 125 A" + }, + "1": { + "then": "Type 2 CCS (mennekes) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Type 2 CCS (mennekes) offer?", + "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A" + }, + "40": { + "mappings": { + "0": { + "then": "Type 2 CCS (mennekes) outputs at most 50 kw" + } + }, + "question": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", + "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}" + }, + "41": { + "question": "How much plugs of type Type 2 with cable (mennekes) are available here?", + "render": "There are Type 2 with cable (mennekes) plugs of type Type 2 with cable (mennekes) available here" + }, + "42": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs 230 volt" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs {socket:type2_cable:voltage} volt" + }, + "43": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs at most 16 A" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:current}A" + }, + "44": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs at most 11 kw" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:output}" + }, + "45": { + "question": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", + "render": "There are Tesla Supercharger CCS (a branded type2_css) plugs of type Tesla Supercharger CCS (a branded type2_css) available here" + }, + "46": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt" + }, + "1": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs 920 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt" + }, + "47": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A" + }, + "48": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 50 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:output}" + }, + "49": { + "question": "How much plugs of type Tesla Supercharger (destination) are available here?", + "render": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here" + }, + "50": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs 480 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt" + }, + "51": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger (destination) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A" + }, + "52": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs at most 120 kw" + }, + "1": { + "then": "Tesla Supercharger (destination) outputs at most 150 kw" + }, + "2": { + "then": "Tesla Supercharger (destination) outputs at most 250 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:output}" + }, + "53": { + "question": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", + "render": "There are Tesla supercharger (destination (A Type 2 with cable branded as tesla) plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) available here" + }, + "54": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt" + }, + "55": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 16 A" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:current}A" + }, + "56": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 11 kw" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:output}" + }, + "57": { + "mappings": { + "0": { + "then": "Authentication by a membership card" + }, + "1": { + "then": "Authentication by an app" + }, + "2": { + "then": "Authentication via phone call is available" + }, + "3": { + "then": "Authentication via phone call is available" + }, + "4": { + "then": "Authentication via NFC is available" + }, + "5": { + "then": "Authentication via Money Card is available" + }, + "6": { + "then": "Authentication via debit card is available" + }, + "7": { + "then": "No authentication is needed" + } + }, + "question": "What kind of authentication is available at the charging station?" + }, + "58": { + "question": "What's the phone number for authentication call or SMS?", + "render": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}" + }, + "59": { + "mappings": { + "0": { + "then": "24/7 opened (including holidays)" + } + }, + "question": "When is this charging station opened?" + }, + "60": { + "mappings": { + "0": { + "then": "Free to use" + } + }, + "question": "How much does one have to pay to use this charging station?", + "render": "Using this charging station costs {charge}" + }, + "61": { + "override": { + "mappings+": { + "0": { + "then": "Payment is done using a dedicated app" + }, + "1": { + "then": "Payment is done using a membership card" + } + } + } + }, + "62": { + "mappings": { + "0": { + "then": "No timelimit on leaving your vehicle here" + } + }, + "question": "What is the maximum amount of time one is allowed to stay here?", + "render": "One can stay at most {canonical(maxstay)}" + }, + "63": { "mappings": { "0": { "then": "Not part of a bigger network" @@ -1059,15 +1621,32 @@ "question": "Is this charging station part of a network?", "render": "Part of the network {network}" }, - "OH": { + "64": { "mappings": { "0": { - "then": "24/7 opened (including holidays)" + "then": "Actually, {operator} is the network" } }, - "question": "When is this charging station opened?" + "question": "Who is the operator of this charging station?", + "render": "This charging station is operated by {operator}" }, - "Operational status": { + "65": { + "question": "What number can one call if there is a problem with this charging station?", + "render": "In case of problems, call {phone}" + }, + "66": { + "question": "What is the email address of the operator?", + "render": "In case of problems, send an email to {email}" + }, + "67": { + "question": "What is the website of the operator?", + "render": "More info on {website}" + }, + "69": { + "question": "What is the reference number of this charging station?", + "render": "Reference number is {ref}" + }, + "70": { "mappings": { "0": { "then": "This charging station is broken" @@ -1087,7 +1666,7 @@ }, "question": "Is this charging point in use?" }, - "Parking:fee": { + "71": { "mappings": { "0": { "then": "No additional parking cost while charging" @@ -1097,577 +1676,6 @@ } }, "question": "Does one have to pay a parking fee while charging?" - }, - "Type": { - "mappings": { - "0": { - "then": "bicycles can be charged here" - }, - "1": { - "then": "Cars can be charged here" - }, - "2": { - "then": "Scooters can be charged here" - }, - "3": { - "then": "Heavy good vehicles (such as trucks) can be charged here" - }, - "4": { - "then": "Buses can be charged here" - } - }, - "question": "Which vehicles are allowed to charge here?" - }, - "access": { - "question": "Who is allowed to use this charging station?", - "render": "Access is {access}" - }, - "capacity": { - "question": "How much vehicles can be charged here at the same time?", - "render": "{capacity} vehicles can be charged here at the same time" - }, - "current-0": { - "mappings": { - "0": { - "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A" - } - }, - "question": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:current}A" - }, - "current-1": { - "mappings": { - "0": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A" - } - }, - "question": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A" - }, - "current-10": { - "mappings": { - "0": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A" - }, - "1": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A" - } - }, - "question": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", - "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A" - }, - "current-11": { - "mappings": { - "0": { - "then": "Tesla Supercharger (destination) outputs at most 125 A" - }, - "1": { - "then": "Tesla Supercharger (destination) outputs at most 350 A" - } - }, - "question": "What current do the plugs with Tesla Supercharger (destination) offer?", - "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A" - }, - "current-12": { - "mappings": { - "0": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 16 A" - }, - "1": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:current}A" - }, - "current-2": { - "mappings": { - "0": { - "then": "Chademo outputs at most 120 A" - } - }, - "question": "What current do the plugs with Chademo offer?", - "render": "Chademo outputs at most {socket:chademo:current}A" - }, - "current-3": { - "mappings": { - "0": { - "then": "Type 1 with cable (J1772) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 1 with cable (J1772) offer?", - "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A" - }, - "current-4": { - "mappings": { - "0": { - "then": "Type 1 without cable (J1772) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 1 without cable (J1772) offer?", - "render": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A" - }, - "current-5": { - "mappings": { - "0": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A" - }, - "1": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A" - } - }, - "question": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A" - }, - "current-6": { - "mappings": { - "0": { - "then": "Tesla Supercharger outputs at most 125 A" - }, - "1": { - "then": "Tesla Supercharger outputs at most 350 A" - } - }, - "question": "What current do the plugs with Tesla Supercharger offer?", - "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A" - }, - "current-7": { - "mappings": { - "0": { - "then": "Type 2 (mennekes) outputs at most 16 A" - }, - "1": { - "then": "Type 2 (mennekes) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 2 (mennekes) offer?", - "render": "Type 2 (mennekes) outputs at most {socket:type2:current}A" - }, - "current-8": { - "mappings": { - "0": { - "then": "Type 2 CCS (mennekes) outputs at most 125 A" - }, - "1": { - "then": "Type 2 CCS (mennekes) outputs at most 350 A" - } - }, - "question": "What current do the plugs with Type 2 CCS (mennekes) offer?", - "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A" - }, - "current-9": { - "mappings": { - "0": { - "then": "Type 2 with cable (mennekes) outputs at most 16 A" - }, - "1": { - "then": "Type 2 with cable (mennekes) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 2 with cable (mennekes) offer?", - "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:current}A" - }, - "email": { - "question": "What is the email address of the operator?", - "render": "In case of problems, send an email to {email}" - }, - "fee/charge": { - "mappings": { - "0": { - "then": "Free to use" - } - }, - "question": "How much does one have to pay to use this charging station?", - "render": "Using this charging station costs {charge}" - }, - "maxstay": { - "mappings": { - "0": { - "then": "No timelimit on leaving your vehicle here" - } - }, - "question": "What is the maximum amount of time one is allowed to stay here?", - "render": "One can stay at most {canonical(maxstay)}" - }, - "payment-options": { - "override": { - "mappings": { - "0": { - "then": "Payment is done using a dedicated app" - } - }, - "mappings+": { - "0": { - "then": "Payment is done using a dedicated app" - } - } - } - }, - "phone": { - "question": "What number can one call if there is a problem with this charging station?", - "render": "In case of problems, call {phone}" - }, - "plugs-0": { - "question": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", - "render": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here" - }, - "plugs-1": { - "question": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", - "render": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here" - }, - "plugs-10": { - "question": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", - "render": "There are Tesla Supercharger CCS (a branded type2_css) plugs of type Tesla Supercharger CCS (a branded type2_css) available here" - }, - "plugs-11": { - "question": "How much plugs of type Tesla Supercharger (destination) are available here?", - "render": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here" - }, - "plugs-12": { - "question": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", - "render": "There are Tesla supercharger (destination (A Type 2 with cable branded as tesla) plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) available here" - }, - "plugs-2": { - "question": "How much plugs of type Chademo are available here?", - "render": "There are Chademo plugs of type Chademo available here" - }, - "plugs-3": { - "question": "How much plugs of type Type 1 with cable (J1772) are available here?", - "render": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here" - }, - "plugs-4": { - "question": "How much plugs of type Type 1 without cable (J1772) are available here?", - "render": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here" - }, - "plugs-5": { - "question": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", - "render": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here" - }, - "plugs-6": { - "question": "How much plugs of type Tesla Supercharger are available here?", - "render": "There are Tesla Supercharger plugs of type Tesla Supercharger available here" - }, - "plugs-7": { - "question": "How much plugs of type Type 2 (mennekes) are available here?", - "render": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here" - }, - "plugs-8": { - "question": "How much plugs of type Type 2 CCS (mennekes) are available here?", - "render": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here" - }, - "plugs-9": { - "question": "How much plugs of type Type 2 with cable (mennekes) are available here?", - "render": "There are Type 2 with cable (mennekes) plugs of type Type 2 with cable (mennekes) available here" - }, - "power-output-0": { - "mappings": { - "0": { - "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw" - } - }, - "question": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}" - }, - "power-output-1": { - "mappings": { - "0": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw" - }, - "1": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", - "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}" - }, - "power-output-10": { - "mappings": { - "0": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 50 kw" - } - }, - "question": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", - "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:output}" - }, - "power-output-11": { - "mappings": { - "0": { - "then": "Tesla Supercharger (destination) outputs at most 120 kw" - }, - "1": { - "then": "Tesla Supercharger (destination) outputs at most 150 kw" - }, - "2": { - "then": "Tesla Supercharger (destination) outputs at most 250 kw" - } - }, - "question": "What power output does a single plug of type Tesla Supercharger (destination) offer?", - "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:output}" - }, - "power-output-12": { - "mappings": { - "0": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 11 kw" - }, - "1": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:output}" - }, - "power-output-2": { - "mappings": { - "0": { - "then": "Chademo outputs at most 50 kw" - } - }, - "question": "What power output does a single plug of type Chademo offer?", - "render": "Chademo outputs at most {socket:chademo:output}" - }, - "power-output-3": { - "mappings": { - "0": { - "then": "Type 1 with cable (J1772) outputs at most 3.7 kw" - }, - "1": { - "then": "Type 1 with cable (J1772) outputs at most 7 kw" - } - }, - "question": "What power output does a single plug of type Type 1 with cable (J1772) offer?", - "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}" - }, - "power-output-4": { - "mappings": { - "0": { - "then": "Type 1 without cable (J1772) outputs at most 3.7 kw" - }, - "1": { - "then": "Type 1 without cable (J1772) outputs at most 6.6 kw" - }, - "2": { - "then": "Type 1 without cable (J1772) outputs at most 7 kw" - }, - "3": { - "then": "Type 1 without cable (J1772) outputs at most 7.2 kw" - } - }, - "question": "What power output does a single plug of type Type 1 without cable (J1772) offer?", - "render": "Type 1 without cable (J1772) outputs at most {socket:type1:output}" - }, - "power-output-5": { - "mappings": { - "0": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw" - }, - "1": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw" - }, - "2": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw" - }, - "3": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw" - } - }, - "question": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", - "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}" - }, - "power-output-6": { - "mappings": { - "0": { - "then": "Tesla Supercharger outputs at most 120 kw" - }, - "1": { - "then": "Tesla Supercharger outputs at most 150 kw" - }, - "2": { - "then": "Tesla Supercharger outputs at most 250 kw" - } - }, - "question": "What power output does a single plug of type Tesla Supercharger offer?", - "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}" - }, - "power-output-7": { - "mappings": { - "0": { - "then": "Type 2 (mennekes) outputs at most 11 kw" - }, - "1": { - "then": "Type 2 (mennekes) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type Type 2 (mennekes) offer?", - "render": "Type 2 (mennekes) outputs at most {socket:type2:output}" - }, - "power-output-8": { - "mappings": { - "0": { - "then": "Type 2 CCS (mennekes) outputs at most 50 kw" - } - }, - "question": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", - "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}" - }, - "power-output-9": { - "mappings": { - "0": { - "then": "Type 2 with cable (mennekes) outputs at most 11 kw" - }, - "1": { - "then": "Type 2 with cable (mennekes) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", - "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:output}" - }, - "ref": { - "question": "What is the reference number of this charging station?" - }, - "voltage-0": { - "mappings": { - "0": { - "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt" - } - }, - "question": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt" - }, - "voltage-1": { - "mappings": { - "0": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt" - } - }, - "question": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "render": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt" - }, - "voltage-10": { - "mappings": { - "0": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt" - }, - "1": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs 920 volt" - } - }, - "question": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", - "render": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt" - }, - "voltage-11": { - "mappings": { - "0": { - "then": "Tesla Supercharger (destination) outputs 480 volt" - } - }, - "question": "What voltage do the plugs with Tesla Supercharger (destination) offer?", - "render": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt" - }, - "voltage-12": { - "mappings": { - "0": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt" - }, - "1": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt" - } - }, - "question": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt" - }, - "voltage-2": { - "mappings": { - "0": { - "then": "Chademo outputs 500 volt" - } - }, - "question": "What voltage do the plugs with Chademo offer?", - "render": "Chademo outputs {socket:chademo:voltage} volt" - }, - "voltage-3": { - "mappings": { - "0": { - "then": "Type 1 with cable (J1772) outputs 200 volt" - }, - "1": { - "then": "Type 1 with cable (J1772) outputs 240 volt" - } - }, - "question": "What voltage do the plugs with Type 1 with cable (J1772) offer?", - "render": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt" - }, - "voltage-4": { - "mappings": { - "0": { - "then": "Type 1 without cable (J1772) outputs 200 volt" - }, - "1": { - "then": "Type 1 without cable (J1772) outputs 240 volt" - } - }, - "question": "What voltage do the plugs with Type 1 without cable (J1772) offer?", - "render": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt" - }, - "voltage-5": { - "mappings": { - "0": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt" - }, - "1": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt" - } - }, - "question": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "render": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt" - }, - "voltage-6": { - "mappings": { - "0": { - "then": "Tesla Supercharger outputs 480 volt" - } - }, - "question": "What voltage do the plugs with Tesla Supercharger offer?", - "render": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt" - }, - "voltage-7": { - "mappings": { - "0": { - "then": "Type 2 (mennekes) outputs 230 volt" - }, - "1": { - "then": "Type 2 (mennekes) outputs 400 volt" - } - }, - "question": "What voltage do the plugs with Type 2 (mennekes) offer?", - "render": "Type 2 (mennekes) outputs {socket:type2:voltage} volt" - }, - "voltage-8": { - "mappings": { - "0": { - "then": "Type 2 CCS (mennekes) outputs 500 volt" - }, - "1": { - "then": "Type 2 CCS (mennekes) outputs 920 volt" - } - }, - "question": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", - "render": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt" - }, - "voltage-9": { - "mappings": { - "0": { - "then": "Type 2 with cable (mennekes) outputs 230 volt" - }, - "1": { - "then": "Type 2 with cable (mennekes) outputs 400 volt" - } - }, - "question": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", - "render": "Type 2 with cable (mennekes) outputs {socket:type2_cable:voltage} volt" - }, - "website": { - "question": "What is the website of the operator?", - "render": "More info on {website}" } }, "title": { diff --git a/langs/layers/it.json b/langs/layers/it.json index d5e8c4050..d51148992 100644 --- a/langs/layers/it.json +++ b/langs/layers/it.json @@ -680,12 +680,12 @@ "description": "Una stazione di ricarica", "name": "Stazioni di ricarica", "tagRenderings": { - "Auth phone": { + "57": { + "question": "Quali sono gli orari di apertura di questa stazione di ricarica?" + }, + "58": { "question": "A quale rete appartiene questa stazione di ricarica?", "render": "{network}" - }, - "Authentication": { - "question": "Quali sono gli orari di apertura di questa stazione di ricarica?" } }, "title": { diff --git a/langs/layers/ja.json b/langs/layers/ja.json index 28607d857..c016f416b 100644 --- a/langs/layers/ja.json +++ b/langs/layers/ja.json @@ -3,12 +3,12 @@ "description": "充電ステーション", "name": "充電ステーション", "tagRenderings": { - "Auth phone": { + "57": { + "question": "この充電ステーションはいつオープンしますか?" + }, + "58": { "question": "この充電ステーションの運営チェーンはどこですか?", "render": "{network}" - }, - "Authentication": { - "question": "この充電ステーションはいつオープンしますか?" } }, "title": { diff --git a/langs/layers/nb_NO.json b/langs/layers/nb_NO.json index e22f10944..03de4cfd0 100644 --- a/langs/layers/nb_NO.json +++ b/langs/layers/nb_NO.json @@ -108,11 +108,11 @@ "description": "En ladestasjon", "name": "Ladestasjoner", "tagRenderings": { - "Auth phone": { - "render": "{network}" - }, - "Authentication": { + "57": { "question": "Når åpnet denne ladestasjonen?" + }, + "58": { + "render": "{network}" } }, "title": { diff --git a/langs/layers/nl.json b/langs/layers/nl.json index e98497ecb..86e800600 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -1027,7 +1027,11 @@ } }, "tagRenderings": { - "Available_charging_stations (generated)": { + "3": { + "question": "Hoeveel voertuigen kunnen hier opgeladen worden?", + "render": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" + }, + "4": { "mappings": { "0": { "then": " Schuko stekker zonder aardingspin (CEE7/4 type F)" @@ -1109,7 +1113,533 @@ } } }, - "Operational status": { + "5": { + "question": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?", + "render": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" + }, + "6": { + "mappings": { + "0": { + "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" + } + }, + "question": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ", + "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" + }, + "7": { + "mappings": { + "0": { + "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" + } + }, + "question": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", + "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" + }, + "8": { + "mappings": { + "0": { + "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", + "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" + }, + "9": { + "question": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?", + "render": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" + }, + "10": { + "mappings": { + "0": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" + } + }, + "question": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ", + "render": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" + }, + "11": { + "mappings": { + "0": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" + } + }, + "question": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", + "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" + }, + "12": { + "mappings": { + "0": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" + }, + "1": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", + "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" + }, + "13": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "14": { + "mappings": { + "0": { + "then": " heeft een spanning van 500 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:chademo:voltage} volt" + }, + "15": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 120 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:chademo:current}A" + }, + "16": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:chademo:output}" + }, + "17": { + "question": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?", + "render": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" + }, + "18": { + "mappings": { + "0": { + "then": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" + }, + "1": { + "then": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" + } + }, + "question": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) ", + "render": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" + }, + "19": { + "mappings": { + "0": { + "then": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?", + "render": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" + }, + "20": { + "mappings": { + "0": { + "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" + }, + "1": { + "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?", + "render": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" + }, + "21": { + "question": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?", + "render": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" + }, + "22": { + "mappings": { + "0": { + "then": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" + }, + "1": { + "then": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" + } + }, + "question": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) ", + "render": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" + }, + "23": { + "mappings": { + "0": { + "then": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?", + "render": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" + }, + "24": { + "mappings": { + "0": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" + }, + "1": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" + }, + "2": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" + }, + "3": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?", + "render": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" + }, + "25": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "26": { + "mappings": { + "0": { + "then": " heeft een spanning van 400 volt" + }, + "1": { + "then": " heeft een spanning van 1000 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:type1_combo:voltage} volt" + }, + "27": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 50 A" + }, + "1": { + "then": " levert een stroom van maximaal 125 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:type1_combo:current}A" + }, + "28": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 62.5 kw" + }, + "2": { + "then": " levert een vermogen van maximaal 150 kw" + }, + "3": { + "then": " levert een vermogen van maximaal 350 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:type1_combo:output}" + }, + "29": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "30": { + "mappings": { + "0": { + "then": " heeft een spanning van 480 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" + }, + "31": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" + }, + "32": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 120 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 150 kw" + }, + "2": { + "then": " levert een vermogen van maximaal 250 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" + }, + "33": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "34": { + "mappings": { + "0": { + "then": " heeft een spanning van 230 volt" + }, + "1": { + "then": " heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:type2:voltage} volt" + }, + "35": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 16 A" + }, + "1": { + "then": " levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:type2:current}A" + }, + "36": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:type2:output}" + }, + "37": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "38": { + "mappings": { + "0": { + "then": " heeft een spanning van 500 volt" + }, + "1": { + "then": " heeft een spanning van 920 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:type2_combo:voltage} volt" + }, + "39": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:type2_combo:current}A" + }, + "40": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:type2_combo:output}" + }, + "41": { + "question": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?", + "render": "Hier zijn Type 2 met kabel (J1772) stekkers van het type Type 2 met kabel (J1772)" + }, + "42": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) heeft een spanning van 230 volt" + }, + "1": { + "then": "Type 2 met kabel (J1772) heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) ", + "render": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt" + }, + "43": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 16 A" + }, + "1": { + "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?", + "render": "Type 2 met kabel (J1772) levert een stroom van maximaal {socket:type2_cable:current}A" + }, + "44": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?", + "render": "Type 2 met kabel (J1772) levert een vermogen van maximaal {socket:type2_cable:output}" + }, + "45": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "46": { + "mappings": { + "0": { + "then": " heeft een spanning van 500 volt" + }, + "1": { + "then": " heeft een spanning van 920 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" + }, + "47": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" + }, + "48": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" + }, + "49": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "50": { + "mappings": { + "0": { + "then": " heeft een spanning van 480 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "51": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "52": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 120 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 150 kw" + }, + "2": { + "then": " levert een vermogen van maximaal 250 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "53": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "54": { + "mappings": { + "0": { + "then": " heeft een spanning van 230 volt" + }, + "1": { + "then": " heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "55": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 16 A" + }, + "1": { + "then": " levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "56": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "60": { + "mappings": { + "0": { + "then": "Gratis te gebruiken" + } + }, + "question": "Hoeveel kost het gebruik van dit oplaadpunt?", + "render": "Dit oplaadpunt gebruiken kost {charge}" + }, + "61": { + "override": { + "mappings+": { + "0": { + "then": "Betalen via een app van het netwerk" + }, + "1": { + "then": "Betalen via een lidkaart van het netwerk" + } + } + } + }, + "62": { + "mappings": { + "0": { + "then": "Geen maximum parkeertijd" + } + }, + "question": "Hoelang mag een voertuig hier blijven staan?", + "render": "De maximale parkeertijd hier is {canonical(maxstay)}" + }, + "70": { "mappings": { "0": { "then": "Dit oplaadpunt is kapot" @@ -1128,538 +1658,6 @@ } }, "question": "Is dit oplaadpunt operationeel?" - }, - "capacity": { - "question": "Hoeveel voertuigen kunnen hier opgeladen worden?", - "render": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" - }, - "current-0": { - "mappings": { - "0": { - "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" - } - }, - "question": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", - "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" - }, - "current-1": { - "mappings": { - "0": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" - } - }, - "question": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", - "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" - }, - "current-10": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" - }, - "current-11": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" - }, - "current-12": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 16 A" - }, - "1": { - "then": " levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" - }, - "current-2": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 120 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:chademo:current}A" - }, - "current-3": { - "mappings": { - "0": { - "then": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?", - "render": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" - }, - "current-4": { - "mappings": { - "0": { - "then": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?", - "render": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" - }, - "current-5": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 50 A" - }, - "1": { - "then": " levert een stroom van maximaal 125 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:type1_combo:current}A" - }, - "current-6": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" - }, - "current-7": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 16 A" - }, - "1": { - "then": " levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:type2:current}A" - }, - "current-8": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:type2_combo:current}A" - }, - "current-9": { - "mappings": { - "0": { - "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 16 A" - }, - "1": { - "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?", - "render": "Type 2 met kabel (J1772) levert een stroom van maximaal {socket:type2_cable:current}A" - }, - "fee/charge": { - "mappings": { - "0": { - "then": "Gratis te gebruiken" - } - }, - "question": "Hoeveel kost het gebruik van dit oplaadpunt?", - "render": "Dit oplaadpunt gebruiken kost {charge}" - }, - "maxstay": { - "mappings": { - "0": { - "then": "Geen maximum parkeertijd" - } - }, - "question": "Hoelang mag een voertuig hier blijven staan?", - "render": "De maximale parkeertijd hier is {canonical(maxstay)}" - }, - "payment-options": { - "override": { - "mappings": { - "0": { - "then": "Betalen via een app van het netwerk" - } - }, - "mappings+": { - "0": { - "then": "Betalen via een app van het netwerk" - } - } - } - }, - "plugs-0": { - "question": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?", - "render": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" - }, - "plugs-1": { - "question": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?", - "render": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" - }, - "plugs-10": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "plugs-11": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "plugs-12": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "plugs-2": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "plugs-3": { - "question": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?", - "render": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" - }, - "plugs-4": { - "question": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?", - "render": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" - }, - "plugs-5": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "plugs-6": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "plugs-7": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "plugs-8": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "plugs-9": { - "question": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?", - "render": "Hier zijn Type 2 met kabel (J1772) stekkers van het type Type 2 met kabel (J1772)" - }, - "power-output-0": { - "mappings": { - "0": { - "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", - "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" - }, - "power-output-1": { - "mappings": { - "0": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" - }, - "1": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", - "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" - }, - "power-output-10": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" - }, - "power-output-11": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 120 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 150 kw" - }, - "2": { - "then": " levert een vermogen van maximaal 250 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" - }, - "power-output-12": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 11 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" - }, - "power-output-2": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:chademo:output}" - }, - "power-output-3": { - "mappings": { - "0": { - "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" - }, - "1": { - "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?", - "render": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" - }, - "power-output-4": { - "mappings": { - "0": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" - }, - "1": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" - }, - "2": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" - }, - "3": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?", - "render": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" - }, - "power-output-5": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 62.5 kw" - }, - "2": { - "then": " levert een vermogen van maximaal 150 kw" - }, - "3": { - "then": " levert een vermogen van maximaal 350 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:type1_combo:output}" - }, - "power-output-6": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 120 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 150 kw" - }, - "2": { - "then": " levert een vermogen van maximaal 250 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" - }, - "power-output-7": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 11 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:type2:output}" - }, - "power-output-8": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:type2_combo:output}" - }, - "power-output-9": { - "mappings": { - "0": { - "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 11 kw" - }, - "1": { - "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?", - "render": "Type 2 met kabel (J1772) levert een vermogen van maximaal {socket:type2_cable:output}" - }, - "voltage-0": { - "mappings": { - "0": { - "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" - } - }, - "question": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ", - "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" - }, - "voltage-1": { - "mappings": { - "0": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" - } - }, - "question": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ", - "render": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" - }, - "voltage-10": { - "mappings": { - "0": { - "then": " heeft een spanning van 500 volt" - }, - "1": { - "then": " heeft een spanning van 920 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" - }, - "voltage-11": { - "mappings": { - "0": { - "then": " heeft een spanning van 480 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" - }, - "voltage-12": { - "mappings": { - "0": { - "then": " heeft een spanning van 230 volt" - }, - "1": { - "then": " heeft een spanning van 400 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" - }, - "voltage-2": { - "mappings": { - "0": { - "then": " heeft een spanning van 500 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:chademo:voltage} volt" - }, - "voltage-3": { - "mappings": { - "0": { - "then": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" - }, - "1": { - "then": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" - } - }, - "question": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) ", - "render": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" - }, - "voltage-4": { - "mappings": { - "0": { - "then": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" - }, - "1": { - "then": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" - } - }, - "question": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) ", - "render": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" - }, - "voltage-5": { - "mappings": { - "0": { - "then": " heeft een spanning van 400 volt" - }, - "1": { - "then": " heeft een spanning van 1000 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:type1_combo:voltage} volt" - }, - "voltage-6": { - "mappings": { - "0": { - "then": " heeft een spanning van 480 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" - }, - "voltage-7": { - "mappings": { - "0": { - "then": " heeft een spanning van 230 volt" - }, - "1": { - "then": " heeft een spanning van 400 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:type2:voltage} volt" - }, - "voltage-8": { - "mappings": { - "0": { - "then": " heeft een spanning van 500 volt" - }, - "1": { - "then": " heeft een spanning van 920 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:type2_combo:voltage} volt" - }, - "voltage-9": { - "mappings": { - "0": { - "then": "Type 2 met kabel (J1772) heeft een spanning van 230 volt" - }, - "1": { - "then": "Type 2 met kabel (J1772) heeft een spanning van 400 volt" - } - }, - "question": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) ", - "render": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt" } }, "units": { diff --git a/langs/layers/ru.json b/langs/layers/ru.json index 2c6485f51..a13c15188 100644 --- a/langs/layers/ru.json +++ b/langs/layers/ru.json @@ -518,12 +518,12 @@ "description": "Зарядная станция", "name": "Зарядные станции", "tagRenderings": { - "Auth phone": { + "57": { + "question": "В какое время работает эта зарядная станция?" + }, + "58": { "question": "К какой сети относится эта станция?", "render": "{network}" - }, - "Authentication": { - "question": "В какое время работает эта зарядная станция?" } }, "title": { diff --git a/langs/layers/zh_Hant.json b/langs/layers/zh_Hant.json index 994ecb486..c6e41067c 100644 --- a/langs/layers/zh_Hant.json +++ b/langs/layers/zh_Hant.json @@ -377,12 +377,12 @@ "description": "充電站", "name": "充電站", "tagRenderings": { - "Auth phone": { + "57": { + "question": "何時是充電站開放使用的時間?" + }, + "58": { "question": "充電站所屬的網路是?", "render": "{network}" - }, - "Authentication": { - "question": "何時是充電站開放使用的時間?" } }, "title": { From 4f4d592fc9550af50ba8dbcafeb5e9edee267443 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 21:10:08 +0200 Subject: [PATCH 28/65] Fix charging station layers --- .../charging_station/charging_station.json | 1997 +---------------- 1 file changed, 18 insertions(+), 1979 deletions(-) diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json index 62ac38176..bed272a4a 100644 --- a/assets/layers/charging_station/charging_station.json +++ b/assets/layers/charging_station/charging_station.json @@ -43,7 +43,7 @@ "tagRenderings": [ "images", { - "#": "Type", + "id": "Type", "question": { "en": "Which vehicles are allowed to charge here?" }, @@ -93,7 +93,7 @@ ] }, { - "#": "access", + "id": "access", "question": { "en": "Who is allowed to use this charging station?" }, @@ -132,7 +132,7 @@ ] }, { - "#": "capacity", + "id": "capacity", "render": { "en": "{capacity} vehicles can be charged here at the same time", "nl": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" @@ -147,1971 +147,10 @@ } }, { - "#": "Available_charging_stations (generated)", - "question": { - "en": "Which charging stations are available here?" - }, - "multiAnswer": true, - "mappings": [ - { - "if": "socket:schuko=1", - "ifnot": "socket:schuko=", - "then": { - "en": " Schuko wall plug without ground pin (CEE7/4 type F)", - "nl": " Schuko stekker zonder aardingspin (CEE7/4 type F)" - }, - "hideInAnswer": { - "or": [ - "_country!=be", - "_country!=fr", - "_country!=ma", - "_country!=tn", - "_country!=pl", - "_country!=cs", - "_country!=sk", - "_country!=mo" - ] - } - }, - { - "if": { - "and": [ - "socket:schuko~*", - "socket:schuko!=1" - ] - }, - "then": { - "en": " Schuko wall plug without ground pin (CEE7/4 type F)", - "nl": " Schuko stekker zonder aardingspin (CEE7/4 type F)" - }, - "hideInAnswer": true - }, - { - "if": "socket:typee=1", - "ifnot": "socket:typee=", - "then": { - "en": " European wall plug with ground pin (CEE7/4 type E)", - "nl": " Europese stekker met aardingspin (CEE7/4 type E)" - } - }, - { - "if": { - "and": [ - "socket:typee~*", - "socket:typee!=1" - ] - }, - "then": { - "en": " European wall plug with ground pin (CEE7/4 type E)", - "nl": " Europese stekker met aardingspin (CEE7/4 type E)" - }, - "hideInAnswer": true - }, - { - "if": "socket:chademo=1", - "ifnot": "socket:chademo=", - "then": { - "en": " Chademo", - "nl": " " - } - }, - { - "if": { - "and": [ - "socket:chademo~*", - "socket:chademo!=1" - ] - }, - "then": { - "en": " Chademo", - "nl": " " - }, - "hideInAnswer": true - }, - { - "if": "socket:type1_cable=1", - "ifnot": "socket:type1_cable=", - "then": { - "en": " Type 1 with cable (J1772)", - "nl": " Type 1 met kabel (J1772)" - } - }, - { - "if": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=1" - ] - }, - "then": { - "en": " Type 1 with cable (J1772)", - "nl": " Type 1 met kabel (J1772)" - }, - "hideInAnswer": true - }, - { - "if": "socket:type1=1", - "ifnot": "socket:type1=", - "then": { - "en": " Type 1 without cable (J1772)", - "nl": " Type 1 zonder kabel (J1772)" - } - }, - { - "if": { - "and": [ - "socket:type1~*", - "socket:type1!=1" - ] - }, - "then": { - "en": " Type 1 without cable (J1772)", - "nl": " Type 1 zonder kabel (J1772)" - }, - "hideInAnswer": true - }, - { - "if": "socket:type1_combo=1", - "ifnot": "socket:type1_combo=", - "then": { - "en": " Type 1 CCS (aka Type 1 Combo)", - "nl": " " - } - }, - { - "if": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=1" - ] - }, - "then": { - "en": " Type 1 CCS (aka Type 1 Combo)", - "nl": " " - }, - "hideInAnswer": true - }, - { - "if": "socket:tesla_supercharger=1", - "ifnot": "socket:tesla_supercharger=", - "then": { - "en": " Tesla Supercharger", - "nl": " " - } - }, - { - "if": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=1" - ] - }, - "then": { - "en": " Tesla Supercharger", - "nl": " " - }, - "hideInAnswer": true - }, - { - "if": "socket:type2=1", - "ifnot": "socket:type2=", - "then": { - "en": " Type 2 (mennekes)", - "nl": " " - } - }, - { - "if": { - "and": [ - "socket:type2~*", - "socket:type2!=1" - ] - }, - "then": { - "en": " Type 2 (mennekes)", - "nl": " " - }, - "hideInAnswer": true - }, - { - "if": "socket:type2_combo=1", - "ifnot": "socket:type2_combo=", - "then": { - "en": " Type 2 CCS (mennekes)", - "nl": " " - } - }, - { - "if": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=1" - ] - }, - "then": { - "en": " Type 2 CCS (mennekes)", - "nl": " " - }, - "hideInAnswer": true - }, - { - "if": "socket:type2_cable=1", - "ifnot": "socket:type2_cable=", - "then": { - "en": " Type 2 with cable (mennekes)", - "nl": " Type 2 met kabel (J1772)" - } - }, - { - "if": { - "and": [ - "socket:type2_cable~*", - "socket:type2_cable!=1" - ] - }, - "then": { - "en": " Type 2 with cable (mennekes)", - "nl": " Type 2 met kabel (J1772)" - }, - "hideInAnswer": true - }, - { - "if": "socket:tesla_supercharger_ccs=1", - "ifnot": "socket:tesla_supercharger_ccs=", - "then": { - "en": " Tesla Supercharger CCS (a branded type2_css)", - "nl": " " - } - }, - { - "if": { - "and": [ - "socket:tesla_supercharger_ccs~*", - "socket:tesla_supercharger_ccs!=1" - ] - }, - "then": { - "en": " Tesla Supercharger CCS (a branded type2_css)", - "nl": " " - }, - "hideInAnswer": true - }, - { - "if": "socket:tesla_destination=1", - "ifnot": "socket:tesla_destination=", - "then": { - "en": " Tesla Supercharger (destination)", - "nl": " " - }, - "hideInAnswer": { - "or": [ - "_country!=us" - ] - } - }, - { - "if": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=1" - ] - }, - "then": { - "en": " Tesla Supercharger (destination)", - "nl": " " - }, - "hideInAnswer": true - }, - { - "if": "socket:tesla_destination=1", - "ifnot": "socket:tesla_destination=", - "then": { - "en": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)", - "nl": " " - }, - "hideInAnswer": { - "or": [ - "_country=us" - ] - } - }, - { - "if": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=1" - ] - }, - "then": { - "en": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)", - "nl": " " - }, - "hideInAnswer": true - } - ] + "id": "$$$" }, { - "#": "plugs-0", - "question": { - "en": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", - "nl": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here", - "nl": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" - }, - "freeform": { - "key": "socket:schuko", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "#": "voltage-0", - "question": { - "en": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "nl": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) " - }, - "render": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" - }, - "freeform": { - "key": "socket:schuko:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:schuko:voltage=230 V", - "then": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" - } - } - ], - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "#": "current-0", - "question": { - "en": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "nl": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" - }, - "render": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:current}A", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" - }, - "freeform": { - "key": "socket:schuko:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:schuko:current=16 A", - "then": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" - } - } - ], - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "#": "power-output-0", - "question": { - "en": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" - }, - "render": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" - }, - "freeform": { - "key": "socket:schuko:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:schuko:output=3.6 kw", - "then": { - "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw", - "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" - } - } - ], - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "#": "plugs-1", - "question": { - "en": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", - "nl": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?" - }, - "render": { - "en": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here", - "nl": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" - }, - "freeform": { - "key": "socket:typee", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "#": "voltage-1", - "question": { - "en": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "nl": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) " - }, - "render": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" - }, - "freeform": { - "key": "socket:typee:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:typee:voltage=230 V", - "then": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" - } - } - ], - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "#": "current-1", - "question": { - "en": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "nl": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" - }, - "render": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" - }, - "freeform": { - "key": "socket:typee:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:typee:current=16 A", - "then": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" - } - } - ], - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "#": "power-output-1", - "question": { - "en": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" - }, - "render": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" - }, - "freeform": { - "key": "socket:typee:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:typee:output=3 kw", - "then": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" - } - }, - { - "if": "socket:socket:typee:output=22 kw", - "then": { - "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw", - "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" - } - } - ], - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "#": "plugs-2", - "question": { - "en": "How much plugs of type Chademo are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Chademo plugs of type Chademo available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:chademo", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "#": "voltage-2", - "question": { - "en": "What voltage do the plugs with Chademo offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Chademo outputs {socket:chademo:voltage} volt", - "nl": " heeft een spanning van {socket:chademo:voltage} volt" - }, - "freeform": { - "key": "socket:chademo:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:chademo:voltage=500 V", - "then": { - "en": "Chademo outputs 500 volt", - "nl": " heeft een spanning van 500 volt" - } - } - ], - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "#": "current-2", - "question": { - "en": "What current do the plugs with Chademo offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Chademo outputs at most {socket:chademo:current}A", - "nl": " levert een stroom van maximaal {socket:chademo:current}A" - }, - "freeform": { - "key": "socket:chademo:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:chademo:current=120 A", - "then": { - "en": "Chademo outputs at most 120 A", - "nl": " levert een stroom van maximaal 120 A" - } - } - ], - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "#": "power-output-2", - "question": { - "en": "What power output does a single plug of type Chademo offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Chademo outputs at most {socket:chademo:output}", - "nl": " levert een vermogen van maximaal {socket:chademo:output}" - }, - "freeform": { - "key": "socket:chademo:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:chademo:output=50 kw", - "then": { - "en": "Chademo outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" - } - } - ], - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "#": "plugs-3", - "question": { - "en": "How much plugs of type Type 1 with cable (J1772) are available here?", - "nl": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here", - "nl": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" - }, - "freeform": { - "key": "socket:type1_cable", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "#": "voltage-3", - "question": { - "en": "What voltage do the plugs with Type 1 with cable (J1772) offer?", - "nl": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) " - }, - "render": { - "en": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt", - "nl": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" - }, - "freeform": { - "key": "socket:type1_cable:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_cable:voltage=200 V", - "then": { - "en": "Type 1 with cable (J1772) outputs 200 volt", - "nl": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" - } - }, - { - "if": "socket:socket:type1_cable:voltage=240 V", - "then": { - "en": "Type 1 with cable (J1772) outputs 240 volt", - "nl": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" - } - } - ], - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "#": "current-3", - "question": { - "en": "What current do the plugs with Type 1 with cable (J1772) offer?", - "nl": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?" - }, - "render": { - "en": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A", - "nl": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" - }, - "freeform": { - "key": "socket:type1_cable:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_cable:current=32 A", - "then": { - "en": "Type 1 with cable (J1772) outputs at most 32 A", - "nl": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "#": "power-output-3", - "question": { - "en": "What power output does a single plug of type Type 1 with cable (J1772) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?" - }, - "render": { - "en": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}", - "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" - }, - "freeform": { - "key": "socket:type1_cable:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_cable:output=3.7 kw", - "then": { - "en": "Type 1 with cable (J1772) outputs at most 3.7 kw", - "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" - } - }, - { - "if": "socket:socket:type1_cable:output=7 kw", - "then": { - "en": "Type 1 with cable (J1772) outputs at most 7 kw", - "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" - } - } - ], - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "#": "plugs-4", - "question": { - "en": "How much plugs of type Type 1 without cable (J1772) are available here?", - "nl": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here", - "nl": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" - }, - "freeform": { - "key": "socket:type1", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "#": "voltage-4", - "question": { - "en": "What voltage do the plugs with Type 1 without cable (J1772) offer?", - "nl": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) " - }, - "render": { - "en": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt", - "nl": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" - }, - "freeform": { - "key": "socket:type1:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1:voltage=200 V", - "then": { - "en": "Type 1 without cable (J1772) outputs 200 volt", - "nl": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" - } - }, - { - "if": "socket:socket:type1:voltage=240 V", - "then": { - "en": "Type 1 without cable (J1772) outputs 240 volt", - "nl": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" - } - } - ], - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "#": "current-4", - "question": { - "en": "What current do the plugs with Type 1 without cable (J1772) offer?", - "nl": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?" - }, - "render": { - "en": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A", - "nl": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" - }, - "freeform": { - "key": "socket:type1:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1:current=32 A", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 32 A", - "nl": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "#": "power-output-4", - "question": { - "en": "What power output does a single plug of type Type 1 without cable (J1772) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?" - }, - "render": { - "en": "Type 1 without cable (J1772) outputs at most {socket:type1:output}", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" - }, - "freeform": { - "key": "socket:type1:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1:output=3.7 kw", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 3.7 kw", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" - } - }, - { - "if": "socket:socket:type1:output=6.6 kw", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 6.6 kw", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" - } - }, - { - "if": "socket:socket:type1:output=7 kw", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 7 kw", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" - } - }, - { - "if": "socket:socket:type1:output=7.2 kw", - "then": { - "en": "Type 1 without cable (J1772) outputs at most 7.2 kw", - "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" - } - } - ], - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "#": "plugs-5", - "question": { - "en": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:type1_combo", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "#": "voltage-5", - "question": { - "en": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt", - "nl": " heeft een spanning van {socket:type1_combo:voltage} volt" - }, - "freeform": { - "key": "socket:type1_combo:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_combo:voltage=400 V", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt", - "nl": " heeft een spanning van 400 volt" - } - }, - { - "if": "socket:socket:type1_combo:voltage=1000 V", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt", - "nl": " heeft een spanning van 1000 volt" - } - } - ], - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "#": "current-5", - "question": { - "en": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A", - "nl": " levert een stroom van maximaal {socket:type1_combo:current}A" - }, - "freeform": { - "key": "socket:type1_combo:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_combo:current=50 A", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A", - "nl": " levert een stroom van maximaal 50 A" - } - }, - { - "if": "socket:socket:type1_combo:current=125 A", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" - } - } - ], - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "#": "power-output-5", - "question": { - "en": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}", - "nl": " levert een vermogen van maximaal {socket:type1_combo:output}" - }, - "freeform": { - "key": "socket:type1_combo:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_combo:output=50 kw", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" - } - }, - { - "if": "socket:socket:type1_combo:output=62.5 kw", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw", - "nl": " levert een vermogen van maximaal 62.5 kw" - } - }, - { - "if": "socket:socket:type1_combo:output=150 kw", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw", - "nl": " levert een vermogen van maximaal 150 kw" - } - }, - { - "if": "socket:socket:type1_combo:output=350 kw", - "then": { - "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw", - "nl": " levert een vermogen van maximaal 350 kw" - } - } - ], - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "#": "plugs-6", - "question": { - "en": "How much plugs of type Tesla Supercharger are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Tesla Supercharger plugs of type Tesla Supercharger available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:tesla_supercharger", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "#": "voltage-6", - "question": { - "en": "What voltage do the plugs with Tesla Supercharger offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt", - "nl": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" - }, - "freeform": { - "key": "socket:tesla_supercharger:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger:voltage=480 V", - "then": { - "en": "Tesla Supercharger outputs 480 volt", - "nl": " heeft een spanning van 480 volt" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "#": "current-6", - "question": { - "en": "What current do the plugs with Tesla Supercharger offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A", - "nl": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" - }, - "freeform": { - "key": "socket:tesla_supercharger:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger:current=125 A", - "then": { - "en": "Tesla Supercharger outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" - } - }, - { - "if": "socket:socket:tesla_supercharger:current=350 A", - "then": { - "en": "Tesla Supercharger outputs at most 350 A", - "nl": " levert een stroom van maximaal 350 A" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "#": "power-output-6", - "question": { - "en": "What power output does a single plug of type Tesla Supercharger offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}", - "nl": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" - }, - "freeform": { - "key": "socket:tesla_supercharger:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger:output=120 kw", - "then": { - "en": "Tesla Supercharger outputs at most 120 kw", - "nl": " levert een vermogen van maximaal 120 kw" - } - }, - { - "if": "socket:socket:tesla_supercharger:output=150 kw", - "then": { - "en": "Tesla Supercharger outputs at most 150 kw", - "nl": " levert een vermogen van maximaal 150 kw" - } - }, - { - "if": "socket:socket:tesla_supercharger:output=250 kw", - "then": { - "en": "Tesla Supercharger outputs at most 250 kw", - "nl": " levert een vermogen van maximaal 250 kw" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "#": "plugs-7", - "question": { - "en": "How much plugs of type Type 2 (mennekes) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:type2", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "#": "voltage-7", - "question": { - "en": "What voltage do the plugs with Type 2 (mennekes) offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Type 2 (mennekes) outputs {socket:type2:voltage} volt", - "nl": " heeft een spanning van {socket:type2:voltage} volt" - }, - "freeform": { - "key": "socket:type2:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2:voltage=230 V", - "then": { - "en": "Type 2 (mennekes) outputs 230 volt", - "nl": " heeft een spanning van 230 volt" - } - }, - { - "if": "socket:socket:type2:voltage=400 V", - "then": { - "en": "Type 2 (mennekes) outputs 400 volt", - "nl": " heeft een spanning van 400 volt" - } - } - ], - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "#": "current-7", - "question": { - "en": "What current do the plugs with Type 2 (mennekes) offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Type 2 (mennekes) outputs at most {socket:type2:current}A", - "nl": " levert een stroom van maximaal {socket:type2:current}A" - }, - "freeform": { - "key": "socket:type2:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2:current=16 A", - "then": { - "en": "Type 2 (mennekes) outputs at most 16 A", - "nl": " levert een stroom van maximaal 16 A" - } - }, - { - "if": "socket:socket:type2:current=32 A", - "then": { - "en": "Type 2 (mennekes) outputs at most 32 A", - "nl": " levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "#": "power-output-7", - "question": { - "en": "What power output does a single plug of type Type 2 (mennekes) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Type 2 (mennekes) outputs at most {socket:type2:output}", - "nl": " levert een vermogen van maximaal {socket:type2:output}" - }, - "freeform": { - "key": "socket:type2:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2:output=11 kw", - "then": { - "en": "Type 2 (mennekes) outputs at most 11 kw", - "nl": " levert een vermogen van maximaal 11 kw" - } - }, - { - "if": "socket:socket:type2:output=22 kw", - "then": { - "en": "Type 2 (mennekes) outputs at most 22 kw", - "nl": " levert een vermogen van maximaal 22 kw" - } - } - ], - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "#": "plugs-8", - "question": { - "en": "How much plugs of type Type 2 CCS (mennekes) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:type2_combo", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "#": "voltage-8", - "question": { - "en": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt", - "nl": " heeft een spanning van {socket:type2_combo:voltage} volt" - }, - "freeform": { - "key": "socket:type2_combo:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_combo:voltage=500 V", - "then": { - "en": "Type 2 CCS (mennekes) outputs 500 volt", - "nl": " heeft een spanning van 500 volt" - } - }, - { - "if": "socket:socket:type2_combo:voltage=920 V", - "then": { - "en": "Type 2 CCS (mennekes) outputs 920 volt", - "nl": " heeft een spanning van 920 volt" - } - } - ], - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "#": "current-8", - "question": { - "en": "What current do the plugs with Type 2 CCS (mennekes) offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A", - "nl": " levert een stroom van maximaal {socket:type2_combo:current}A" - }, - "freeform": { - "key": "socket:type2_combo:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_combo:current=125 A", - "then": { - "en": "Type 2 CCS (mennekes) outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" - } - }, - { - "if": "socket:socket:type2_combo:current=350 A", - "then": { - "en": "Type 2 CCS (mennekes) outputs at most 350 A", - "nl": " levert een stroom van maximaal 350 A" - } - } - ], - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "#": "power-output-8", - "question": { - "en": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}", - "nl": " levert een vermogen van maximaal {socket:type2_combo:output}" - }, - "freeform": { - "key": "socket:type2_combo:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_combo:output=50 kw", - "then": { - "en": "Type 2 CCS (mennekes) outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" - } - } - ], - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "#": "plugs-9", - "question": { - "en": "How much plugs of type Type 2 with cable (mennekes) are available here?", - "nl": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Type 2 with cable (mennekes) plugs of type Type 2 with cable (mennekes) available here", - "nl": "Hier zijn Type 2 met kabel (J1772) stekkers van het type Type 2 met kabel (J1772)" - }, - "freeform": { - "key": "socket:type2_cable", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type2_cable~*", - "socket:type2_cable!=0" - ] - } - }, - { - "#": "voltage-9", - "question": { - "en": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", - "nl": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) " - }, - "render": { - "en": "Type 2 with cable (mennekes) outputs {socket:type2_cable:voltage} volt", - "nl": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt" - }, - "freeform": { - "key": "socket:type2_cable:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_cable:voltage=230 V", - "then": { - "en": "Type 2 with cable (mennekes) outputs 230 volt", - "nl": "Type 2 met kabel (J1772) heeft een spanning van 230 volt" - } - }, - { - "if": "socket:socket:type2_cable:voltage=400 V", - "then": { - "en": "Type 2 with cable (mennekes) outputs 400 volt", - "nl": "Type 2 met kabel (J1772) heeft een spanning van 400 volt" - } - } - ], - "condition": { - "and": [ - "socket:type2_cable~*", - "socket:type2_cable!=0" - ] - } - }, - { - "#": "current-9", - "question": { - "en": "What current do the plugs with Type 2 with cable (mennekes) offer?", - "nl": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?" - }, - "render": { - "en": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:current}A", - "nl": "Type 2 met kabel (J1772) levert een stroom van maximaal {socket:type2_cable:current}A" - }, - "freeform": { - "key": "socket:type2_cable:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_cable:current=16 A", - "then": { - "en": "Type 2 with cable (mennekes) outputs at most 16 A", - "nl": "Type 2 met kabel (J1772) levert een stroom van maximaal 16 A" - } - }, - { - "if": "socket:socket:type2_cable:current=32 A", - "then": { - "en": "Type 2 with cable (mennekes) outputs at most 32 A", - "nl": "Type 2 met kabel (J1772) levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type2_cable~*", - "socket:type2_cable!=0" - ] - } - }, - { - "#": "power-output-9", - "question": { - "en": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", - "nl": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?" - }, - "render": { - "en": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:output}", - "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal {socket:type2_cable:output}" - }, - "freeform": { - "key": "socket:type2_cable:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_cable:output=11 kw", - "then": { - "en": "Type 2 with cable (mennekes) outputs at most 11 kw", - "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal 11 kw" - } - }, - { - "if": "socket:socket:type2_cable:output=22 kw", - "then": { - "en": "Type 2 with cable (mennekes) outputs at most 22 kw", - "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal 22 kw" - } - } - ], - "condition": { - "and": [ - "socket:type2_cable~*", - "socket:type2_cable!=0" - ] - } - }, - { - "#": "plugs-10", - "question": { - "en": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Tesla Supercharger CCS (a branded type2_css) plugs of type Tesla Supercharger CCS (a branded type2_css) available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:tesla_supercharger_ccs", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:tesla_supercharger_ccs~*", - "socket:tesla_supercharger_ccs!=0" - ] - } - }, - { - "#": "voltage-10", - "question": { - "en": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt", - "nl": " heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" - }, - "freeform": { - "key": "socket:tesla_supercharger_ccs:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger_ccs:voltage=500 V", - "then": { - "en": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt", - "nl": " heeft een spanning van 500 volt" - } - }, - { - "if": "socket:socket:tesla_supercharger_ccs:voltage=920 V", - "then": { - "en": "Tesla Supercharger CCS (a branded type2_css) outputs 920 volt", - "nl": " heeft een spanning van 920 volt" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger_ccs~*", - "socket:tesla_supercharger_ccs!=0" - ] - } - }, - { - "#": "current-10", - "question": { - "en": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A", - "nl": " levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" - }, - "freeform": { - "key": "socket:tesla_supercharger_ccs:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger_ccs:current=125 A", - "then": { - "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" - } - }, - { - "if": "socket:socket:tesla_supercharger_ccs:current=350 A", - "then": { - "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A", - "nl": " levert een stroom van maximaal 350 A" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger_ccs~*", - "socket:tesla_supercharger_ccs!=0" - ] - } - }, - { - "#": "power-output-10", - "question": { - "en": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:output}", - "nl": " levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" - }, - "freeform": { - "key": "socket:tesla_supercharger_ccs:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger_ccs:output=50 kw", - "then": { - "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger_ccs~*", - "socket:tesla_supercharger_ccs!=0" - ] - } - }, - { - "#": "plugs-11", - "question": { - "en": "How much plugs of type Tesla Supercharger (destination) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:tesla_destination", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "#": "voltage-11", - "question": { - "en": "What voltage do the plugs with Tesla Supercharger (destination) offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt", - "nl": " heeft een spanning van {socket:tesla_destination:voltage} volt" - }, - "freeform": { - "key": "socket:tesla_destination:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_destination:voltage=480 V", - "then": { - "en": "Tesla Supercharger (destination) outputs 480 volt", - "nl": " heeft een spanning van 480 volt" - } - } - ], - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "#": "current-11", - "question": { - "en": "What current do the plugs with Tesla Supercharger (destination) offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A", - "nl": " levert een stroom van maximaal {socket:tesla_destination:current}A" - }, - "freeform": { - "key": "socket:tesla_destination:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_destination:current=125 A", - "then": { - "en": "Tesla Supercharger (destination) outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" - } - }, - { - "if": "socket:socket:tesla_destination:current=350 A", - "then": { - "en": "Tesla Supercharger (destination) outputs at most 350 A", - "nl": " levert een stroom van maximaal 350 A" - } - } - ], - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "#": "power-output-11", - "question": { - "en": "What power output does a single plug of type Tesla Supercharger (destination) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:output}", - "nl": " levert een vermogen van maximaal {socket:tesla_destination:output}" - }, - "freeform": { - "key": "socket:tesla_destination:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_destination:output=120 kw", - "then": { - "en": "Tesla Supercharger (destination) outputs at most 120 kw", - "nl": " levert een vermogen van maximaal 120 kw" - } - }, - { - "if": "socket:socket:tesla_destination:output=150 kw", - "then": { - "en": "Tesla Supercharger (destination) outputs at most 150 kw", - "nl": " levert een vermogen van maximaal 150 kw" - } - }, - { - "if": "socket:socket:tesla_destination:output=250 kw", - "then": { - "en": "Tesla Supercharger (destination) outputs at most 250 kw", - "nl": " levert een vermogen van maximaal 250 kw" - } - } - ], - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "#": "plugs-12", - "question": { - "en": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" - }, - "render": { - "en": "There are Tesla supercharger (destination (A Type 2 with cable branded as tesla) plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) available here", - "nl": "Hier zijn stekkers van het type " - }, - "freeform": { - "key": "socket:tesla_destination", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "#": "voltage-12", - "question": { - "en": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "nl": "Welke spanning levert de stekker van type " - }, - "render": { - "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt", - "nl": " heeft een spanning van {socket:tesla_destination:voltage} volt" - }, - "freeform": { - "key": "socket:tesla_destination:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_destination:voltage=230 V", - "then": { - "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt", - "nl": " heeft een spanning van 230 volt" - } - }, - { - "if": "socket:socket:tesla_destination:voltage=400 V", - "then": { - "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt", - "nl": " heeft een spanning van 400 volt" - } - } - ], - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "#": "current-12", - "question": { - "en": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "nl": "Welke stroom levert de stekker van type ?" - }, - "render": { - "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:current}A", - "nl": " levert een stroom van maximaal {socket:tesla_destination:current}A" - }, - "freeform": { - "key": "socket:tesla_destination:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_destination:current=16 A", - "then": { - "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 16 A", - "nl": " levert een stroom van maximaal 16 A" - } - }, - { - "if": "socket:socket:tesla_destination:current=32 A", - "then": { - "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 32 A", - "nl": " levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "#": "power-output-12", - "question": { - "en": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" - }, - "render": { - "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:output}", - "nl": " levert een vermogen van maximaal {socket:tesla_destination:output}" - }, - "freeform": { - "key": "socket:tesla_destination:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_destination:output=11 kw", - "then": { - "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 11 kw", - "nl": " levert een vermogen van maximaal 11 kw" - } - }, - { - "if": "socket:socket:tesla_destination:output=22 kw", - "then": { - "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 22 kw", - "nl": " levert een vermogen van maximaal 22 kw" - } - } - ], - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "#": "Authentication", + "id": "Authentication", "question": { "en": "What kind of authentication is available at the charging station?", "it": "Quali sono gli orari di apertura di questa stazione di ricarica?", @@ -2181,7 +220,7 @@ ] }, { - "#": "Auth phone", + "id": "Auth phone", "render": { "en": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}", "it": "{network}", @@ -2229,7 +268,7 @@ } }, { - "#": "OH", + "id": "OH", "render": "{opening_hours_table(opening_hours)}", "freeform": { "key": "opening_hours", @@ -2248,7 +287,7 @@ ] }, { - "#": "fee/charge", + "id": "fee/charge", "question": { "en": "How much does one have to pay to use this charging station?", "nl": "Hoeveel kost het gebruik van dit oplaadpunt?" @@ -2279,7 +318,7 @@ ] }, { - "#": "payment-options", + "id": "payment-options", "builtin": "payment-options", "override": { "condition": { @@ -2309,7 +348,7 @@ } }, { - "#": "maxstay", + "id": "maxstay", "question": { "en": "What is the maximum amount of time one is allowed to stay here?", "nl": "Hoelang mag een voertuig hier blijven staan?" @@ -2332,7 +371,7 @@ ] }, { - "#": "Network", + "id": "Network", "render": { "en": "Part of the network {network}" }, @@ -2371,7 +410,7 @@ ] }, { - "#": "Operator", + "id": "Operator", "question": { "en": "Who is the operator of this charging station?" }, @@ -2399,7 +438,7 @@ ] }, { - "#": "phone", + "id": "phone", "question": { "en": "What number can one call if there is a problem with this charging station?" }, @@ -2412,7 +451,7 @@ } }, { - "#": "email", + "id": "email", "question": { "en": "What is the email address of the operator?" }, @@ -2425,7 +464,7 @@ } }, { - "#": "website", + "id": "website", "question": { "en": "What is the website of the operator?" }, @@ -2439,7 +478,7 @@ }, "level", { - "#": "ref", + "id": "ref", "question": { "en": "What is the reference number of this charging station?" }, @@ -2451,7 +490,7 @@ } }, { - "#": "Operational status", + "id": "Operational status", "question": { "en": "Is this charging point in use?", "nl": "Is dit oplaadpunt operationeel?" @@ -2510,7 +549,7 @@ ] }, { - "#": "Parking:fee", + "id": "Parking:fee", "question": { "en": "Does one have to pay a parking fee while charging?" }, From 2240c0ab7c537fc3e6421f736e99b086ff65040a Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 21:14:48 +0200 Subject: [PATCH 29/65] Reset translations --- .../charging_station/charging_station.json | 18 + langs/layers/en.json | 773 +++--------------- langs/layers/it.json | 8 +- langs/layers/ja.json | 8 +- langs/layers/nb_NO.json | 8 +- langs/layers/nl.json | 656 +-------------- langs/layers/ru.json | 8 +- langs/layers/zh_Hant.json | 8 +- 8 files changed, 182 insertions(+), 1305 deletions(-) diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json index bed272a4a..94ef686e0 100644 --- a/assets/layers/charging_station/charging_station.json +++ b/assets/layers/charging_station/charging_station.json @@ -344,6 +344,24 @@ "nl": "Betalen via een lidkaart van het netwerk" } } + ], + "mappings": [ + { + "if": "payment:app=yes", + "ifnot": "payment:app=no", + "then": { + "en": "Payment is done using a dedicated app", + "nl": "Betalen via een app van het netwerk" + } + }, + { + "if": "payment:membership_card=yes", + "ifnot": "payment:membership_card=no", + "then": { + "en": "Payment is done using a membership card", + "nl": "Betalen via een lidkaart van het netwerk" + } + } ] } }, diff --git a/langs/layers/en.json b/langs/layers/en.json index c03b50f65..8e8c8bde5 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -931,614 +931,11 @@ } }, "tagRenderings": { - "1": { - "mappings": { - "0": { - "then": "bicycles can be charged here" - }, - "1": { - "then": "Cars can be charged here" - }, - "2": { - "then": "Scooters can be charged here" - }, - "3": { - "then": "Heavy good vehicles (such as trucks) can be charged here" - }, - "4": { - "then": "Buses can be charged here" - } - }, - "question": "Which vehicles are allowed to charge here?" + "Auth phone": { + "question": "What's the phone number for authentication call or SMS?", + "render": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}" }, - "2": { - "question": "Who is allowed to use this charging station?", - "render": "Access is {access}" - }, - "3": { - "question": "How much vehicles can be charged here at the same time?", - "render": "{capacity} vehicles can be charged here at the same time" - }, - "4": { - "mappings": { - "0": { - "then": " Schuko wall plug without ground pin (CEE7/4 type F)" - }, - "1": { - "then": " Schuko wall plug without ground pin (CEE7/4 type F)" - }, - "2": { - "then": " European wall plug with ground pin (CEE7/4 type E)" - }, - "3": { - "then": " European wall plug with ground pin (CEE7/4 type E)" - }, - "4": { - "then": " Chademo" - }, - "5": { - "then": " Chademo" - }, - "6": { - "then": " Type 1 with cable (J1772)" - }, - "7": { - "then": " Type 1 with cable (J1772)" - }, - "8": { - "then": " Type 1 without cable (J1772)" - }, - "9": { - "then": " Type 1 without cable (J1772)" - }, - "10": { - "then": " Type 1 CCS (aka Type 1 Combo)" - }, - "11": { - "then": " Type 1 CCS (aka Type 1 Combo)" - }, - "12": { - "then": " Tesla Supercharger" - }, - "13": { - "then": " Tesla Supercharger" - }, - "14": { - "then": " Type 2 (mennekes)" - }, - "15": { - "then": " Type 2 (mennekes)" - }, - "16": { - "then": " Type 2 CCS (mennekes)" - }, - "17": { - "then": " Type 2 CCS (mennekes)" - }, - "18": { - "then": " Type 2 with cable (mennekes)" - }, - "19": { - "then": " Type 2 with cable (mennekes)" - }, - "20": { - "then": " Tesla Supercharger CCS (a branded type2_css)" - }, - "21": { - "then": " Tesla Supercharger CCS (a branded type2_css)" - }, - "22": { - "then": " Tesla Supercharger (destination)" - }, - "23": { - "then": " Tesla Supercharger (destination)" - }, - "24": { - "then": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)" - }, - "25": { - "then": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)" - } - }, - "question": "Which charging stations are available here?" - }, - "5": { - "question": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", - "render": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here" - }, - "6": { - "mappings": { - "0": { - "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt" - } - }, - "question": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt" - }, - "7": { - "mappings": { - "0": { - "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A" - } - }, - "question": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:current}A" - }, - "8": { - "mappings": { - "0": { - "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw" - } - }, - "question": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", - "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}" - }, - "9": { - "question": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", - "render": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here" - }, - "10": { - "mappings": { - "0": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt" - } - }, - "question": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "render": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt" - }, - "11": { - "mappings": { - "0": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A" - } - }, - "question": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", - "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A" - }, - "12": { - "mappings": { - "0": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw" - }, - "1": { - "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", - "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}" - }, - "13": { - "question": "How much plugs of type Chademo are available here?", - "render": "There are Chademo plugs of type Chademo available here" - }, - "14": { - "mappings": { - "0": { - "then": "Chademo outputs 500 volt" - } - }, - "question": "What voltage do the plugs with Chademo offer?", - "render": "Chademo outputs {socket:chademo:voltage} volt" - }, - "15": { - "mappings": { - "0": { - "then": "Chademo outputs at most 120 A" - } - }, - "question": "What current do the plugs with Chademo offer?", - "render": "Chademo outputs at most {socket:chademo:current}A" - }, - "16": { - "mappings": { - "0": { - "then": "Chademo outputs at most 50 kw" - } - }, - "question": "What power output does a single plug of type Chademo offer?", - "render": "Chademo outputs at most {socket:chademo:output}" - }, - "17": { - "question": "How much plugs of type Type 1 with cable (J1772) are available here?", - "render": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here" - }, - "18": { - "mappings": { - "0": { - "then": "Type 1 with cable (J1772) outputs 200 volt" - }, - "1": { - "then": "Type 1 with cable (J1772) outputs 240 volt" - } - }, - "question": "What voltage do the plugs with Type 1 with cable (J1772) offer?", - "render": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt" - }, - "19": { - "mappings": { - "0": { - "then": "Type 1 with cable (J1772) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 1 with cable (J1772) offer?", - "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A" - }, - "20": { - "mappings": { - "0": { - "then": "Type 1 with cable (J1772) outputs at most 3.7 kw" - }, - "1": { - "then": "Type 1 with cable (J1772) outputs at most 7 kw" - } - }, - "question": "What power output does a single plug of type Type 1 with cable (J1772) offer?", - "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}" - }, - "21": { - "question": "How much plugs of type Type 1 without cable (J1772) are available here?", - "render": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here" - }, - "22": { - "mappings": { - "0": { - "then": "Type 1 without cable (J1772) outputs 200 volt" - }, - "1": { - "then": "Type 1 without cable (J1772) outputs 240 volt" - } - }, - "question": "What voltage do the plugs with Type 1 without cable (J1772) offer?", - "render": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt" - }, - "23": { - "mappings": { - "0": { - "then": "Type 1 without cable (J1772) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 1 without cable (J1772) offer?", - "render": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A" - }, - "24": { - "mappings": { - "0": { - "then": "Type 1 without cable (J1772) outputs at most 3.7 kw" - }, - "1": { - "then": "Type 1 without cable (J1772) outputs at most 6.6 kw" - }, - "2": { - "then": "Type 1 without cable (J1772) outputs at most 7 kw" - }, - "3": { - "then": "Type 1 without cable (J1772) outputs at most 7.2 kw" - } - }, - "question": "What power output does a single plug of type Type 1 without cable (J1772) offer?", - "render": "Type 1 without cable (J1772) outputs at most {socket:type1:output}" - }, - "25": { - "question": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", - "render": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here" - }, - "26": { - "mappings": { - "0": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt" - }, - "1": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt" - } - }, - "question": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "render": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt" - }, - "27": { - "mappings": { - "0": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A" - }, - "1": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A" - } - }, - "question": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A" - }, - "28": { - "mappings": { - "0": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw" - }, - "1": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw" - }, - "2": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw" - }, - "3": { - "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw" - } - }, - "question": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", - "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}" - }, - "29": { - "question": "How much plugs of type Tesla Supercharger are available here?", - "render": "There are Tesla Supercharger plugs of type Tesla Supercharger available here" - }, - "30": { - "mappings": { - "0": { - "then": "Tesla Supercharger outputs 480 volt" - } - }, - "question": "What voltage do the plugs with Tesla Supercharger offer?", - "render": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt" - }, - "31": { - "mappings": { - "0": { - "then": "Tesla Supercharger outputs at most 125 A" - }, - "1": { - "then": "Tesla Supercharger outputs at most 350 A" - } - }, - "question": "What current do the plugs with Tesla Supercharger offer?", - "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A" - }, - "32": { - "mappings": { - "0": { - "then": "Tesla Supercharger outputs at most 120 kw" - }, - "1": { - "then": "Tesla Supercharger outputs at most 150 kw" - }, - "2": { - "then": "Tesla Supercharger outputs at most 250 kw" - } - }, - "question": "What power output does a single plug of type Tesla Supercharger offer?", - "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}" - }, - "33": { - "question": "How much plugs of type Type 2 (mennekes) are available here?", - "render": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here" - }, - "34": { - "mappings": { - "0": { - "then": "Type 2 (mennekes) outputs 230 volt" - }, - "1": { - "then": "Type 2 (mennekes) outputs 400 volt" - } - }, - "question": "What voltage do the plugs with Type 2 (mennekes) offer?", - "render": "Type 2 (mennekes) outputs {socket:type2:voltage} volt" - }, - "35": { - "mappings": { - "0": { - "then": "Type 2 (mennekes) outputs at most 16 A" - }, - "1": { - "then": "Type 2 (mennekes) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 2 (mennekes) offer?", - "render": "Type 2 (mennekes) outputs at most {socket:type2:current}A" - }, - "36": { - "mappings": { - "0": { - "then": "Type 2 (mennekes) outputs at most 11 kw" - }, - "1": { - "then": "Type 2 (mennekes) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type Type 2 (mennekes) offer?", - "render": "Type 2 (mennekes) outputs at most {socket:type2:output}" - }, - "37": { - "question": "How much plugs of type Type 2 CCS (mennekes) are available here?", - "render": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here" - }, - "38": { - "mappings": { - "0": { - "then": "Type 2 CCS (mennekes) outputs 500 volt" - }, - "1": { - "then": "Type 2 CCS (mennekes) outputs 920 volt" - } - }, - "question": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", - "render": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt" - }, - "39": { - "mappings": { - "0": { - "then": "Type 2 CCS (mennekes) outputs at most 125 A" - }, - "1": { - "then": "Type 2 CCS (mennekes) outputs at most 350 A" - } - }, - "question": "What current do the plugs with Type 2 CCS (mennekes) offer?", - "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A" - }, - "40": { - "mappings": { - "0": { - "then": "Type 2 CCS (mennekes) outputs at most 50 kw" - } - }, - "question": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", - "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}" - }, - "41": { - "question": "How much plugs of type Type 2 with cable (mennekes) are available here?", - "render": "There are Type 2 with cable (mennekes) plugs of type Type 2 with cable (mennekes) available here" - }, - "42": { - "mappings": { - "0": { - "then": "Type 2 with cable (mennekes) outputs 230 volt" - }, - "1": { - "then": "Type 2 with cable (mennekes) outputs 400 volt" - } - }, - "question": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", - "render": "Type 2 with cable (mennekes) outputs {socket:type2_cable:voltage} volt" - }, - "43": { - "mappings": { - "0": { - "then": "Type 2 with cable (mennekes) outputs at most 16 A" - }, - "1": { - "then": "Type 2 with cable (mennekes) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Type 2 with cable (mennekes) offer?", - "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:current}A" - }, - "44": { - "mappings": { - "0": { - "then": "Type 2 with cable (mennekes) outputs at most 11 kw" - }, - "1": { - "then": "Type 2 with cable (mennekes) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", - "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:output}" - }, - "45": { - "question": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", - "render": "There are Tesla Supercharger CCS (a branded type2_css) plugs of type Tesla Supercharger CCS (a branded type2_css) available here" - }, - "46": { - "mappings": { - "0": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt" - }, - "1": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs 920 volt" - } - }, - "question": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", - "render": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt" - }, - "47": { - "mappings": { - "0": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A" - }, - "1": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A" - } - }, - "question": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", - "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A" - }, - "48": { - "mappings": { - "0": { - "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 50 kw" - } - }, - "question": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", - "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:output}" - }, - "49": { - "question": "How much plugs of type Tesla Supercharger (destination) are available here?", - "render": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here" - }, - "50": { - "mappings": { - "0": { - "then": "Tesla Supercharger (destination) outputs 480 volt" - } - }, - "question": "What voltage do the plugs with Tesla Supercharger (destination) offer?", - "render": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt" - }, - "51": { - "mappings": { - "0": { - "then": "Tesla Supercharger (destination) outputs at most 125 A" - }, - "1": { - "then": "Tesla Supercharger (destination) outputs at most 350 A" - } - }, - "question": "What current do the plugs with Tesla Supercharger (destination) offer?", - "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A" - }, - "52": { - "mappings": { - "0": { - "then": "Tesla Supercharger (destination) outputs at most 120 kw" - }, - "1": { - "then": "Tesla Supercharger (destination) outputs at most 150 kw" - }, - "2": { - "then": "Tesla Supercharger (destination) outputs at most 250 kw" - } - }, - "question": "What power output does a single plug of type Tesla Supercharger (destination) offer?", - "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:output}" - }, - "53": { - "question": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", - "render": "There are Tesla supercharger (destination (A Type 2 with cable branded as tesla) plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) available here" - }, - "54": { - "mappings": { - "0": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt" - }, - "1": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt" - } - }, - "question": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt" - }, - "55": { - "mappings": { - "0": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 16 A" - }, - "1": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 32 A" - } - }, - "question": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:current}A" - }, - "56": { - "mappings": { - "0": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 11 kw" - }, - "1": { - "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 22 kw" - } - }, - "question": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:output}" - }, - "57": { + "Authentication": { "mappings": { "0": { "then": "Authentication by a membership card" @@ -1567,49 +964,7 @@ }, "question": "What kind of authentication is available at the charging station?" }, - "58": { - "question": "What's the phone number for authentication call or SMS?", - "render": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}" - }, - "59": { - "mappings": { - "0": { - "then": "24/7 opened (including holidays)" - } - }, - "question": "When is this charging station opened?" - }, - "60": { - "mappings": { - "0": { - "then": "Free to use" - } - }, - "question": "How much does one have to pay to use this charging station?", - "render": "Using this charging station costs {charge}" - }, - "61": { - "override": { - "mappings+": { - "0": { - "then": "Payment is done using a dedicated app" - }, - "1": { - "then": "Payment is done using a membership card" - } - } - } - }, - "62": { - "mappings": { - "0": { - "then": "No timelimit on leaving your vehicle here" - } - }, - "question": "What is the maximum amount of time one is allowed to stay here?", - "render": "One can stay at most {canonical(maxstay)}" - }, - "63": { + "Network": { "mappings": { "0": { "then": "Not part of a bigger network" @@ -1621,32 +976,15 @@ "question": "Is this charging station part of a network?", "render": "Part of the network {network}" }, - "64": { + "OH": { "mappings": { "0": { - "then": "Actually, {operator} is the network" + "then": "24/7 opened (including holidays)" } }, - "question": "Who is the operator of this charging station?", - "render": "This charging station is operated by {operator}" + "question": "When is this charging station opened?" }, - "65": { - "question": "What number can one call if there is a problem with this charging station?", - "render": "In case of problems, call {phone}" - }, - "66": { - "question": "What is the email address of the operator?", - "render": "In case of problems, send an email to {email}" - }, - "67": { - "question": "What is the website of the operator?", - "render": "More info on {website}" - }, - "69": { - "question": "What is the reference number of this charging station?", - "render": "Reference number is {ref}" - }, - "70": { + "Operational status": { "mappings": { "0": { "then": "This charging station is broken" @@ -1666,7 +1004,16 @@ }, "question": "Is this charging point in use?" }, - "71": { + "Operator": { + "mappings": { + "0": { + "then": "Actually, {operator} is the network" + } + }, + "question": "Who is the operator of this charging station?", + "render": "This charging station is operated by {operator}" + }, + "Parking:fee": { "mappings": { "0": { "then": "No additional parking cost while charging" @@ -1676,6 +1023,88 @@ } }, "question": "Does one have to pay a parking fee while charging?" + }, + "Type": { + "mappings": { + "0": { + "then": "bicycles can be charged here" + }, + "1": { + "then": "Cars can be charged here" + }, + "2": { + "then": "Scooters can be charged here" + }, + "3": { + "then": "Heavy good vehicles (such as trucks) can be charged here" + }, + "4": { + "then": "Buses can be charged here" + } + }, + "question": "Which vehicles are allowed to charge here?" + }, + "access": { + "question": "Who is allowed to use this charging station?", + "render": "Access is {access}" + }, + "capacity": { + "question": "How much vehicles can be charged here at the same time?", + "render": "{capacity} vehicles can be charged here at the same time" + }, + "email": { + "question": "What is the email address of the operator?", + "render": "In case of problems, send an email to {email}" + }, + "fee/charge": { + "mappings": { + "0": { + "then": "Free to use" + } + }, + "question": "How much does one have to pay to use this charging station?", + "render": "Using this charging station costs {charge}" + }, + "maxstay": { + "mappings": { + "0": { + "then": "No timelimit on leaving your vehicle here" + } + }, + "question": "What is the maximum amount of time one is allowed to stay here?", + "render": "One can stay at most {canonical(maxstay)}" + }, + "payment-options": { + "override": { + "mappings": { + "0": { + "then": "Payment is done using a dedicated app" + }, + "1": { + "then": "Payment is done using a membership card" + } + }, + "mappings+": { + "0": { + "then": "Payment is done using a dedicated app" + }, + "1": { + "then": "Payment is done using a membership card" + } + } + } + }, + "phone": { + "question": "What number can one call if there is a problem with this charging station?", + "render": "In case of problems, call {phone}" + }, + "ref": { + "question": "What is the reference number of this charging station?", + "render": "Reference number is {ref}" + }, + "website": { + "question": "What is the website of the operator?", + "render": "More info on {website}" } }, "title": { diff --git a/langs/layers/it.json b/langs/layers/it.json index d51148992..d5e8c4050 100644 --- a/langs/layers/it.json +++ b/langs/layers/it.json @@ -680,12 +680,12 @@ "description": "Una stazione di ricarica", "name": "Stazioni di ricarica", "tagRenderings": { - "57": { - "question": "Quali sono gli orari di apertura di questa stazione di ricarica?" - }, - "58": { + "Auth phone": { "question": "A quale rete appartiene questa stazione di ricarica?", "render": "{network}" + }, + "Authentication": { + "question": "Quali sono gli orari di apertura di questa stazione di ricarica?" } }, "title": { diff --git a/langs/layers/ja.json b/langs/layers/ja.json index c016f416b..28607d857 100644 --- a/langs/layers/ja.json +++ b/langs/layers/ja.json @@ -3,12 +3,12 @@ "description": "充電ステーション", "name": "充電ステーション", "tagRenderings": { - "57": { - "question": "この充電ステーションはいつオープンしますか?" - }, - "58": { + "Auth phone": { "question": "この充電ステーションの運営チェーンはどこですか?", "render": "{network}" + }, + "Authentication": { + "question": "この充電ステーションはいつオープンしますか?" } }, "title": { diff --git a/langs/layers/nb_NO.json b/langs/layers/nb_NO.json index 03de4cfd0..e22f10944 100644 --- a/langs/layers/nb_NO.json +++ b/langs/layers/nb_NO.json @@ -108,11 +108,11 @@ "description": "En ladestasjon", "name": "Ladestasjoner", "tagRenderings": { - "57": { - "question": "Når åpnet denne ladestasjonen?" - }, - "58": { + "Auth phone": { "render": "{network}" + }, + "Authentication": { + "question": "Når åpnet denne ladestasjonen?" } }, "title": { diff --git a/langs/layers/nl.json b/langs/layers/nl.json index 86e800600..a894e10c1 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -1027,619 +1027,7 @@ } }, "tagRenderings": { - "3": { - "question": "Hoeveel voertuigen kunnen hier opgeladen worden?", - "render": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" - }, - "4": { - "mappings": { - "0": { - "then": " Schuko stekker zonder aardingspin (CEE7/4 type F)" - }, - "1": { - "then": " Schuko stekker zonder aardingspin (CEE7/4 type F)" - }, - "2": { - "then": " Europese stekker met aardingspin (CEE7/4 type E)" - }, - "3": { - "then": " Europese stekker met aardingspin (CEE7/4 type E)" - }, - "4": { - "then": " " - }, - "5": { - "then": " " - }, - "6": { - "then": " Type 1 met kabel (J1772)" - }, - "7": { - "then": " Type 1 met kabel (J1772)" - }, - "8": { - "then": " Type 1 zonder kabel (J1772)" - }, - "9": { - "then": " Type 1 zonder kabel (J1772)" - }, - "10": { - "then": " " - }, - "11": { - "then": " " - }, - "12": { - "then": " " - }, - "13": { - "then": " " - }, - "14": { - "then": " " - }, - "15": { - "then": " " - }, - "16": { - "then": " " - }, - "17": { - "then": " " - }, - "18": { - "then": " Type 2 met kabel (J1772)" - }, - "19": { - "then": " Type 2 met kabel (J1772)" - }, - "20": { - "then": " " - }, - "21": { - "then": " " - }, - "22": { - "then": " " - }, - "23": { - "then": " " - }, - "24": { - "then": " " - }, - "25": { - "then": " " - } - } - }, - "5": { - "question": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?", - "render": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" - }, - "6": { - "mappings": { - "0": { - "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" - } - }, - "question": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ", - "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" - }, - "7": { - "mappings": { - "0": { - "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" - } - }, - "question": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", - "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" - }, - "8": { - "mappings": { - "0": { - "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", - "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" - }, - "9": { - "question": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?", - "render": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" - }, - "10": { - "mappings": { - "0": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" - } - }, - "question": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ", - "render": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" - }, - "11": { - "mappings": { - "0": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" - } - }, - "question": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", - "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" - }, - "12": { - "mappings": { - "0": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" - }, - "1": { - "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", - "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" - }, - "13": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "14": { - "mappings": { - "0": { - "then": " heeft een spanning van 500 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:chademo:voltage} volt" - }, - "15": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 120 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:chademo:current}A" - }, - "16": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:chademo:output}" - }, - "17": { - "question": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?", - "render": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" - }, - "18": { - "mappings": { - "0": { - "then": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" - }, - "1": { - "then": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" - } - }, - "question": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) ", - "render": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" - }, - "19": { - "mappings": { - "0": { - "then": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?", - "render": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" - }, - "20": { - "mappings": { - "0": { - "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" - }, - "1": { - "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?", - "render": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" - }, - "21": { - "question": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?", - "render": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" - }, - "22": { - "mappings": { - "0": { - "then": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" - }, - "1": { - "then": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" - } - }, - "question": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) ", - "render": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" - }, - "23": { - "mappings": { - "0": { - "then": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?", - "render": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" - }, - "24": { - "mappings": { - "0": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" - }, - "1": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" - }, - "2": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" - }, - "3": { - "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?", - "render": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" - }, - "25": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "26": { - "mappings": { - "0": { - "then": " heeft een spanning van 400 volt" - }, - "1": { - "then": " heeft een spanning van 1000 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:type1_combo:voltage} volt" - }, - "27": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 50 A" - }, - "1": { - "then": " levert een stroom van maximaal 125 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:type1_combo:current}A" - }, - "28": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 62.5 kw" - }, - "2": { - "then": " levert een vermogen van maximaal 150 kw" - }, - "3": { - "then": " levert een vermogen van maximaal 350 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:type1_combo:output}" - }, - "29": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "30": { - "mappings": { - "0": { - "then": " heeft een spanning van 480 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" - }, - "31": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" - }, - "32": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 120 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 150 kw" - }, - "2": { - "then": " levert een vermogen van maximaal 250 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" - }, - "33": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "34": { - "mappings": { - "0": { - "then": " heeft een spanning van 230 volt" - }, - "1": { - "then": " heeft een spanning van 400 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:type2:voltage} volt" - }, - "35": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 16 A" - }, - "1": { - "then": " levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:type2:current}A" - }, - "36": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 11 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:type2:output}" - }, - "37": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "38": { - "mappings": { - "0": { - "then": " heeft een spanning van 500 volt" - }, - "1": { - "then": " heeft een spanning van 920 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:type2_combo:voltage} volt" - }, - "39": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:type2_combo:current}A" - }, - "40": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:type2_combo:output}" - }, - "41": { - "question": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?", - "render": "Hier zijn Type 2 met kabel (J1772) stekkers van het type Type 2 met kabel (J1772)" - }, - "42": { - "mappings": { - "0": { - "then": "Type 2 met kabel (J1772) heeft een spanning van 230 volt" - }, - "1": { - "then": "Type 2 met kabel (J1772) heeft een spanning van 400 volt" - } - }, - "question": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) ", - "render": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt" - }, - "43": { - "mappings": { - "0": { - "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 16 A" - }, - "1": { - "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?", - "render": "Type 2 met kabel (J1772) levert een stroom van maximaal {socket:type2_cable:current}A" - }, - "44": { - "mappings": { - "0": { - "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 11 kw" - }, - "1": { - "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?", - "render": "Type 2 met kabel (J1772) levert een vermogen van maximaal {socket:type2_cable:output}" - }, - "45": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "46": { - "mappings": { - "0": { - "then": " heeft een spanning van 500 volt" - }, - "1": { - "then": " heeft een spanning van 920 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" - }, - "47": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" - }, - "48": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 50 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" - }, - "49": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "50": { - "mappings": { - "0": { - "then": " heeft een spanning van 480 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" - }, - "51": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 125 A" - }, - "1": { - "then": " levert een stroom van maximaal 350 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" - }, - "52": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 120 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 150 kw" - }, - "2": { - "then": " levert een vermogen van maximaal 250 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" - }, - "53": { - "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", - "render": "Hier zijn stekkers van het type " - }, - "54": { - "mappings": { - "0": { - "then": " heeft een spanning van 230 volt" - }, - "1": { - "then": " heeft een spanning van 400 volt" - } - }, - "question": "Welke spanning levert de stekker van type ", - "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" - }, - "55": { - "mappings": { - "0": { - "then": " levert een stroom van maximaal 16 A" - }, - "1": { - "then": " levert een stroom van maximaal 32 A" - } - }, - "question": "Welke stroom levert de stekker van type ?", - "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" - }, - "56": { - "mappings": { - "0": { - "then": " levert een vermogen van maximaal 11 kw" - }, - "1": { - "then": " levert een vermogen van maximaal 22 kw" - } - }, - "question": "Welk vermogen levert een enkele stekker van type ?", - "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" - }, - "60": { - "mappings": { - "0": { - "then": "Gratis te gebruiken" - } - }, - "question": "Hoeveel kost het gebruik van dit oplaadpunt?", - "render": "Dit oplaadpunt gebruiken kost {charge}" - }, - "61": { - "override": { - "mappings+": { - "0": { - "then": "Betalen via een app van het netwerk" - }, - "1": { - "then": "Betalen via een lidkaart van het netwerk" - } - } - } - }, - "62": { - "mappings": { - "0": { - "then": "Geen maximum parkeertijd" - } - }, - "question": "Hoelang mag een voertuig hier blijven staan?", - "render": "De maximale parkeertijd hier is {canonical(maxstay)}" - }, - "70": { + "Operational status": { "mappings": { "0": { "then": "Dit oplaadpunt is kapot" @@ -1658,6 +1046,48 @@ } }, "question": "Is dit oplaadpunt operationeel?" + }, + "capacity": { + "question": "Hoeveel voertuigen kunnen hier opgeladen worden?", + "render": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" + }, + "fee/charge": { + "mappings": { + "0": { + "then": "Gratis te gebruiken" + } + }, + "question": "Hoeveel kost het gebruik van dit oplaadpunt?", + "render": "Dit oplaadpunt gebruiken kost {charge}" + }, + "maxstay": { + "mappings": { + "0": { + "then": "Geen maximum parkeertijd" + } + }, + "question": "Hoelang mag een voertuig hier blijven staan?", + "render": "De maximale parkeertijd hier is {canonical(maxstay)}" + }, + "payment-options": { + "override": { + "mappings": { + "0": { + "then": "Betalen via een app van het netwerk" + }, + "1": { + "then": "Betalen via een lidkaart van het netwerk" + } + }, + "mappings+": { + "0": { + "then": "Betalen via een app van het netwerk" + }, + "1": { + "then": "Betalen via een lidkaart van het netwerk" + } + } + } } }, "units": { diff --git a/langs/layers/ru.json b/langs/layers/ru.json index a13c15188..2c6485f51 100644 --- a/langs/layers/ru.json +++ b/langs/layers/ru.json @@ -518,12 +518,12 @@ "description": "Зарядная станция", "name": "Зарядные станции", "tagRenderings": { - "57": { - "question": "В какое время работает эта зарядная станция?" - }, - "58": { + "Auth phone": { "question": "К какой сети относится эта станция?", "render": "{network}" + }, + "Authentication": { + "question": "В какое время работает эта зарядная станция?" } }, "title": { diff --git a/langs/layers/zh_Hant.json b/langs/layers/zh_Hant.json index c6e41067c..994ecb486 100644 --- a/langs/layers/zh_Hant.json +++ b/langs/layers/zh_Hant.json @@ -377,12 +377,12 @@ "description": "充電站", "name": "充電站", "tagRenderings": { - "57": { - "question": "何時是充電站開放使用的時間?" - }, - "58": { + "Auth phone": { "question": "充電站所屬的網路是?", "render": "{network}" + }, + "Authentication": { + "question": "何時是充電站開放使用的時間?" } }, "title": { From 8b5c0c64cd6ba881cc4f98f54196651e2cd50f39 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 21:25:34 +0200 Subject: [PATCH 30/65] Fix charging stations theme --- .../charging_station/charging_station.json | 1963 ++++++++++++++++- assets/layers/charging_station/csvToJson.ts | 2 +- langs/layers/en.json | 579 +++++ langs/layers/nl.json | 578 +++++ 4 files changed, 3120 insertions(+), 2 deletions(-) diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json index 94ef686e0..ae3a12b1d 100644 --- a/assets/layers/charging_station/charging_station.json +++ b/assets/layers/charging_station/charging_station.json @@ -147,7 +147,1968 @@ } }, { - "id": "$$$" + "id": "Available_charging_stations (generated)", + "question": { + "en": "Which charging stations are available here?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "socket:schuko=1", + "ifnot": "socket:schuko=", + "then": { + "en": " Schuko wall plug without ground pin (CEE7/4 type F)", + "nl": " Schuko stekker zonder aardingspin (CEE7/4 type F)" + }, + "hideInAnswer": { + "or": [ + "_country!=be", + "_country!=fr", + "_country!=ma", + "_country!=tn", + "_country!=pl", + "_country!=cs", + "_country!=sk", + "_country!=mo" + ] + } + }, + { + "if": { + "and": [ + "socket:schuko~*", + "socket:schuko!=1" + ] + }, + "then": { + "en": " Schuko wall plug without ground pin (CEE7/4 type F)", + "nl": " Schuko stekker zonder aardingspin (CEE7/4 type F)" + }, + "hideInAnswer": true + }, + { + "if": "socket:typee=1", + "ifnot": "socket:typee=", + "then": { + "en": " European wall plug with ground pin (CEE7/4 type E)", + "nl": " Europese stekker met aardingspin (CEE7/4 type E)" + } + }, + { + "if": { + "and": [ + "socket:typee~*", + "socket:typee!=1" + ] + }, + "then": { + "en": " European wall plug with ground pin (CEE7/4 type E)", + "nl": " Europese stekker met aardingspin (CEE7/4 type E)" + }, + "hideInAnswer": true + }, + { + "if": "socket:chademo=1", + "ifnot": "socket:chademo=", + "then": { + "en": " Chademo", + "nl": " " + } + }, + { + "if": { + "and": [ + "socket:chademo~*", + "socket:chademo!=1" + ] + }, + "then": { + "en": " Chademo", + "nl": " " + }, + "hideInAnswer": true + }, + { + "if": "socket:type1_cable=1", + "ifnot": "socket:type1_cable=", + "then": { + "en": " Type 1 with cable (J1772)", + "nl": " Type 1 met kabel (J1772)" + } + }, + { + "if": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=1" + ] + }, + "then": { + "en": " Type 1 with cable (J1772)", + "nl": " Type 1 met kabel (J1772)" + }, + "hideInAnswer": true + }, + { + "if": "socket:type1=1", + "ifnot": "socket:type1=", + "then": { + "en": " Type 1 without cable (J1772)", + "nl": " Type 1 zonder kabel (J1772)" + } + }, + { + "if": { + "and": [ + "socket:type1~*", + "socket:type1!=1" + ] + }, + "then": { + "en": " Type 1 without cable (J1772)", + "nl": " Type 1 zonder kabel (J1772)" + }, + "hideInAnswer": true + }, + { + "if": "socket:type1_combo=1", + "ifnot": "socket:type1_combo=", + "then": { + "en": " Type 1 CCS (aka Type 1 Combo)", + "nl": " " + } + }, + { + "if": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=1" + ] + }, + "then": { + "en": " Type 1 CCS (aka Type 1 Combo)", + "nl": " " + }, + "hideInAnswer": true + }, + { + "if": "socket:tesla_supercharger=1", + "ifnot": "socket:tesla_supercharger=", + "then": { + "en": " Tesla Supercharger", + "nl": " " + } + }, + { + "if": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=1" + ] + }, + "then": { + "en": " Tesla Supercharger", + "nl": " " + }, + "hideInAnswer": true + }, + { + "if": "socket:type2=1", + "ifnot": "socket:type2=", + "then": { + "en": " Type 2 (mennekes)", + "nl": " " + } + }, + { + "if": { + "and": [ + "socket:type2~*", + "socket:type2!=1" + ] + }, + "then": { + "en": " Type 2 (mennekes)", + "nl": " " + }, + "hideInAnswer": true + }, + { + "if": "socket:type2_combo=1", + "ifnot": "socket:type2_combo=", + "then": { + "en": " Type 2 CCS (mennekes)", + "nl": " " + } + }, + { + "if": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=1" + ] + }, + "then": { + "en": " Type 2 CCS (mennekes)", + "nl": " " + }, + "hideInAnswer": true + }, + { + "if": "socket:type2_cable=1", + "ifnot": "socket:type2_cable=", + "then": { + "en": " Type 2 with cable (mennekes)", + "nl": " Type 2 met kabel (J1772)" + } + }, + { + "if": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=1" + ] + }, + "then": { + "en": " Type 2 with cable (mennekes)", + "nl": " Type 2 met kabel (J1772)" + }, + "hideInAnswer": true + }, + { + "if": "socket:tesla_supercharger_ccs=1", + "ifnot": "socket:tesla_supercharger_ccs=", + "then": { + "en": " Tesla Supercharger CCS (a branded type2_css)", + "nl": " " + } + }, + { + "if": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=1" + ] + }, + "then": { + "en": " Tesla Supercharger CCS (a branded type2_css)", + "nl": " " + }, + "hideInAnswer": true + }, + { + "if": "socket:tesla_destination=1", + "ifnot": "socket:tesla_destination=", + "then": { + "en": " Tesla Supercharger (destination)", + "nl": " " + }, + "hideInAnswer": { + "or": [ + "_country!=us" + ] + } + }, + { + "if": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=1" + ] + }, + "then": { + "en": " Tesla Supercharger (destination)", + "nl": " " + }, + "hideInAnswer": true + }, + { + "if": "socket:tesla_destination=1", + "ifnot": "socket:tesla_destination=", + "then": { + "en": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)", + "nl": " " + }, + "hideInAnswer": { + "or": [ + "_country=us" + ] + } + }, + { + "if": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=1" + ] + }, + "then": { + "en": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)", + "nl": " " + }, + "hideInAnswer": true + } + ] + }, + { + "id": "plugs-0", + "question": { + "en": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", + "nl": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here", + "nl": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" + }, + "freeform": { + "key": "socket:schuko", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "id": "voltage-0", + "question": { + "en": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "nl": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) " + }, + "render": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" + }, + "freeform": { + "key": "socket:schuko:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:schuko:voltage=230 V", + "then": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" + } + } + ], + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "id": "current-0", + "question": { + "en": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "nl": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" + }, + "render": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:current}A", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" + }, + "freeform": { + "key": "socket:schuko:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:schuko:current=16 A", + "then": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" + } + } + ], + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "id": "power-output-0", + "question": { + "en": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?" + }, + "render": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" + }, + "freeform": { + "key": "socket:schuko:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:schuko:output=3.6 kw", + "then": { + "en": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw", + "nl": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" + } + } + ], + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "id": "plugs-1", + "question": { + "en": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", + "nl": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here", + "nl": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" + }, + "freeform": { + "key": "socket:typee", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "id": "voltage-1", + "question": { + "en": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "nl": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) " + }, + "render": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" + }, + "freeform": { + "key": "socket:typee:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:typee:voltage=230 V", + "then": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" + } + } + ], + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "id": "current-1", + "question": { + "en": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "nl": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" + }, + "render": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" + }, + "freeform": { + "key": "socket:typee:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:typee:current=16 A", + "then": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" + } + } + ], + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "id": "power-output-1", + "question": { + "en": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?" + }, + "render": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" + }, + "freeform": { + "key": "socket:typee:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:typee:output=3 kw", + "then": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" + } + }, + { + "if": "socket:socket:typee:output=22 kw", + "then": { + "en": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw", + "nl": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "id": "plugs-2", + "question": { + "en": "How much plugs of type Chademo are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Chademo plugs of type Chademo available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:chademo", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "id": "voltage-2", + "question": { + "en": "What voltage do the plugs with Chademo offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Chademo outputs {socket:chademo:voltage} volt", + "nl": " heeft een spanning van {socket:chademo:voltage} volt" + }, + "freeform": { + "key": "socket:chademo:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:chademo:voltage=500 V", + "then": { + "en": "Chademo outputs 500 volt", + "nl": " heeft een spanning van 500 volt" + } + } + ], + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "id": "current-2", + "question": { + "en": "What current do the plugs with Chademo offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Chademo outputs at most {socket:chademo:current}A", + "nl": " levert een stroom van maximaal {socket:chademo:current}A" + }, + "freeform": { + "key": "socket:chademo:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:chademo:current=120 A", + "then": { + "en": "Chademo outputs at most 120 A", + "nl": " levert een stroom van maximaal 120 A" + } + } + ], + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "id": "power-output-2", + "question": { + "en": "What power output does a single plug of type Chademo offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Chademo outputs at most {socket:chademo:output}", + "nl": " levert een vermogen van maximaal {socket:chademo:output}" + }, + "freeform": { + "key": "socket:chademo:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:chademo:output=50 kw", + "then": { + "en": "Chademo outputs at most 50 kw", + "nl": " levert een vermogen van maximaal 50 kw" + } + } + ], + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "id": "plugs-3", + "question": { + "en": "How much plugs of type Type 1 with cable (J1772) are available here?", + "nl": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here", + "nl": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" + }, + "freeform": { + "key": "socket:type1_cable", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "id": "voltage-3", + "question": { + "en": "What voltage do the plugs with Type 1 with cable (J1772) offer?", + "nl": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) " + }, + "render": { + "en": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt", + "nl": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" + }, + "freeform": { + "key": "socket:type1_cable:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_cable:voltage=200 V", + "then": { + "en": "Type 1 with cable (J1772) outputs 200 volt", + "nl": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" + } + }, + { + "if": "socket:socket:type1_cable:voltage=240 V", + "then": { + "en": "Type 1 with cable (J1772) outputs 240 volt", + "nl": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" + } + } + ], + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "id": "current-3", + "question": { + "en": "What current do the plugs with Type 1 with cable (J1772) offer?", + "nl": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?" + }, + "render": { + "en": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A", + "nl": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" + }, + "freeform": { + "key": "socket:type1_cable:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_cable:current=32 A", + "then": { + "en": "Type 1 with cable (J1772) outputs at most 32 A", + "nl": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "id": "power-output-3", + "question": { + "en": "What power output does a single plug of type Type 1 with cable (J1772) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?" + }, + "render": { + "en": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}", + "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" + }, + "freeform": { + "key": "socket:type1_cable:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_cable:output=3.7 kw", + "then": { + "en": "Type 1 with cable (J1772) outputs at most 3.7 kw", + "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" + } + }, + { + "if": "socket:socket:type1_cable:output=7 kw", + "then": { + "en": "Type 1 with cable (J1772) outputs at most 7 kw", + "nl": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" + } + } + ], + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "id": "plugs-4", + "question": { + "en": "How much plugs of type Type 1 without cable (J1772) are available here?", + "nl": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here", + "nl": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" + }, + "freeform": { + "key": "socket:type1", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "id": "voltage-4", + "question": { + "en": "What voltage do the plugs with Type 1 without cable (J1772) offer?", + "nl": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) " + }, + "render": { + "en": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt", + "nl": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" + }, + "freeform": { + "key": "socket:type1:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1:voltage=200 V", + "then": { + "en": "Type 1 without cable (J1772) outputs 200 volt", + "nl": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" + } + }, + { + "if": "socket:socket:type1:voltage=240 V", + "then": { + "en": "Type 1 without cable (J1772) outputs 240 volt", + "nl": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" + } + } + ], + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "id": "current-4", + "question": { + "en": "What current do the plugs with Type 1 without cable (J1772) offer?", + "nl": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?" + }, + "render": { + "en": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A", + "nl": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" + }, + "freeform": { + "key": "socket:type1:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1:current=32 A", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 32 A", + "nl": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "id": "power-output-4", + "question": { + "en": "What power output does a single plug of type Type 1 without cable (J1772) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?" + }, + "render": { + "en": "Type 1 without cable (J1772) outputs at most {socket:type1:output}", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" + }, + "freeform": { + "key": "socket:type1:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1:output=3.7 kw", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 3.7 kw", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" + } + }, + { + "if": "socket:socket:type1:output=6.6 kw", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 6.6 kw", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" + } + }, + { + "if": "socket:socket:type1:output=7 kw", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 7 kw", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" + } + }, + { + "if": "socket:socket:type1:output=7.2 kw", + "then": { + "en": "Type 1 without cable (J1772) outputs at most 7.2 kw", + "nl": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" + } + } + ], + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "id": "plugs-5", + "question": { + "en": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:type1_combo", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "id": "voltage-5", + "question": { + "en": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt", + "nl": " heeft een spanning van {socket:type1_combo:voltage} volt" + }, + "freeform": { + "key": "socket:type1_combo:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_combo:voltage=400 V", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt", + "nl": " heeft een spanning van 400 volt" + } + }, + { + "if": "socket:socket:type1_combo:voltage=1000 V", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt", + "nl": " heeft een spanning van 1000 volt" + } + } + ], + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "id": "current-5", + "question": { + "en": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A", + "nl": " levert een stroom van maximaal {socket:type1_combo:current}A" + }, + "freeform": { + "key": "socket:type1_combo:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_combo:current=50 A", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A", + "nl": " levert een stroom van maximaal 50 A" + } + }, + { + "if": "socket:socket:type1_combo:current=125 A", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A", + "nl": " levert een stroom van maximaal 125 A" + } + } + ], + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "id": "power-output-5", + "question": { + "en": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}", + "nl": " levert een vermogen van maximaal {socket:type1_combo:output}" + }, + "freeform": { + "key": "socket:type1_combo:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_combo:output=50 kw", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw", + "nl": " levert een vermogen van maximaal 50 kw" + } + }, + { + "if": "socket:socket:type1_combo:output=62.5 kw", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw", + "nl": " levert een vermogen van maximaal 62.5 kw" + } + }, + { + "if": "socket:socket:type1_combo:output=150 kw", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw", + "nl": " levert een vermogen van maximaal 150 kw" + } + }, + { + "if": "socket:socket:type1_combo:output=350 kw", + "then": { + "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw", + "nl": " levert een vermogen van maximaal 350 kw" + } + } + ], + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "id": "plugs-6", + "question": { + "en": "How much plugs of type Tesla Supercharger are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Tesla Supercharger plugs of type Tesla Supercharger available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:tesla_supercharger", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "id": "voltage-6", + "question": { + "en": "What voltage do the plugs with Tesla Supercharger offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt", + "nl": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_supercharger:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger:voltage=480 V", + "then": { + "en": "Tesla Supercharger outputs 480 volt", + "nl": " heeft een spanning van 480 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "id": "current-6", + "question": { + "en": "What current do the plugs with Tesla Supercharger offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A", + "nl": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" + }, + "freeform": { + "key": "socket:tesla_supercharger:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger:current=125 A", + "then": { + "en": "Tesla Supercharger outputs at most 125 A", + "nl": " levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:tesla_supercharger:current=350 A", + "then": { + "en": "Tesla Supercharger outputs at most 350 A", + "nl": " levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "id": "power-output-6", + "question": { + "en": "What power output does a single plug of type Tesla Supercharger offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}", + "nl": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" + }, + "freeform": { + "key": "socket:tesla_supercharger:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger:output=120 kw", + "then": { + "en": "Tesla Supercharger outputs at most 120 kw", + "nl": " levert een vermogen van maximaal 120 kw" + } + }, + { + "if": "socket:socket:tesla_supercharger:output=150 kw", + "then": { + "en": "Tesla Supercharger outputs at most 150 kw", + "nl": " levert een vermogen van maximaal 150 kw" + } + }, + { + "if": "socket:socket:tesla_supercharger:output=250 kw", + "then": { + "en": "Tesla Supercharger outputs at most 250 kw", + "nl": " levert een vermogen van maximaal 250 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "id": "plugs-7", + "question": { + "en": "How much plugs of type Type 2 (mennekes) are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:type2", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "id": "voltage-7", + "question": { + "en": "What voltage do the plugs with Type 2 (mennekes) offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Type 2 (mennekes) outputs {socket:type2:voltage} volt", + "nl": " heeft een spanning van {socket:type2:voltage} volt" + }, + "freeform": { + "key": "socket:type2:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2:voltage=230 V", + "then": { + "en": "Type 2 (mennekes) outputs 230 volt", + "nl": " heeft een spanning van 230 volt" + } + }, + { + "if": "socket:socket:type2:voltage=400 V", + "then": { + "en": "Type 2 (mennekes) outputs 400 volt", + "nl": " heeft een spanning van 400 volt" + } + } + ], + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "id": "current-7", + "question": { + "en": "What current do the plugs with Type 2 (mennekes) offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Type 2 (mennekes) outputs at most {socket:type2:current}A", + "nl": " levert een stroom van maximaal {socket:type2:current}A" + }, + "freeform": { + "key": "socket:type2:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2:current=16 A", + "then": { + "en": "Type 2 (mennekes) outputs at most 16 A", + "nl": " levert een stroom van maximaal 16 A" + } + }, + { + "if": "socket:socket:type2:current=32 A", + "then": { + "en": "Type 2 (mennekes) outputs at most 32 A", + "nl": " levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "id": "power-output-7", + "question": { + "en": "What power output does a single plug of type Type 2 (mennekes) offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Type 2 (mennekes) outputs at most {socket:type2:output}", + "nl": " levert een vermogen van maximaal {socket:type2:output}" + }, + "freeform": { + "key": "socket:type2:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2:output=11 kw", + "then": { + "en": "Type 2 (mennekes) outputs at most 11 kw", + "nl": " levert een vermogen van maximaal 11 kw" + } + }, + { + "if": "socket:socket:type2:output=22 kw", + "then": { + "en": "Type 2 (mennekes) outputs at most 22 kw", + "nl": " levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "id": "plugs-8", + "question": { + "en": "How much plugs of type Type 2 CCS (mennekes) are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:type2_combo", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "id": "voltage-8", + "question": { + "en": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt", + "nl": " heeft een spanning van {socket:type2_combo:voltage} volt" + }, + "freeform": { + "key": "socket:type2_combo:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_combo:voltage=500 V", + "then": { + "en": "Type 2 CCS (mennekes) outputs 500 volt", + "nl": " heeft een spanning van 500 volt" + } + }, + { + "if": "socket:socket:type2_combo:voltage=920 V", + "then": { + "en": "Type 2 CCS (mennekes) outputs 920 volt", + "nl": " heeft een spanning van 920 volt" + } + } + ], + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "id": "current-8", + "question": { + "en": "What current do the plugs with Type 2 CCS (mennekes) offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A", + "nl": " levert een stroom van maximaal {socket:type2_combo:current}A" + }, + "freeform": { + "key": "socket:type2_combo:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_combo:current=125 A", + "then": { + "en": "Type 2 CCS (mennekes) outputs at most 125 A", + "nl": " levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:type2_combo:current=350 A", + "then": { + "en": "Type 2 CCS (mennekes) outputs at most 350 A", + "nl": " levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "id": "power-output-8", + "question": { + "en": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}", + "nl": " levert een vermogen van maximaal {socket:type2_combo:output}" + }, + "freeform": { + "key": "socket:type2_combo:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_combo:output=50 kw", + "then": { + "en": "Type 2 CCS (mennekes) outputs at most 50 kw", + "nl": " levert een vermogen van maximaal 50 kw" + } + } + ], + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "id": "plugs-9", + "question": { + "en": "How much plugs of type Type 2 with cable (mennekes) are available here?", + "nl": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Type 2 with cable (mennekes) plugs of type Type 2 with cable (mennekes) available here", + "nl": "Hier zijn Type 2 met kabel (J1772) stekkers van het type Type 2 met kabel (J1772)" + }, + "freeform": { + "key": "socket:type2_cable", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "id": "voltage-9", + "question": { + "en": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", + "nl": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) " + }, + "render": { + "en": "Type 2 with cable (mennekes) outputs {socket:type2_cable:voltage} volt", + "nl": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt" + }, + "freeform": { + "key": "socket:type2_cable:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_cable:voltage=230 V", + "then": { + "en": "Type 2 with cable (mennekes) outputs 230 volt", + "nl": "Type 2 met kabel (J1772) heeft een spanning van 230 volt" + } + }, + { + "if": "socket:socket:type2_cable:voltage=400 V", + "then": { + "en": "Type 2 with cable (mennekes) outputs 400 volt", + "nl": "Type 2 met kabel (J1772) heeft een spanning van 400 volt" + } + } + ], + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "id": "current-9", + "question": { + "en": "What current do the plugs with Type 2 with cable (mennekes) offer?", + "nl": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?" + }, + "render": { + "en": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:current}A", + "nl": "Type 2 met kabel (J1772) levert een stroom van maximaal {socket:type2_cable:current}A" + }, + "freeform": { + "key": "socket:type2_cable:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_cable:current=16 A", + "then": { + "en": "Type 2 with cable (mennekes) outputs at most 16 A", + "nl": "Type 2 met kabel (J1772) levert een stroom van maximaal 16 A" + } + }, + { + "if": "socket:socket:type2_cable:current=32 A", + "then": { + "en": "Type 2 with cable (mennekes) outputs at most 32 A", + "nl": "Type 2 met kabel (J1772) levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "id": "power-output-9", + "question": { + "en": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", + "nl": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?" + }, + "render": { + "en": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:output}", + "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal {socket:type2_cable:output}" + }, + "freeform": { + "key": "socket:type2_cable:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_cable:output=11 kw", + "then": { + "en": "Type 2 with cable (mennekes) outputs at most 11 kw", + "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal 11 kw" + } + }, + { + "if": "socket:socket:type2_cable:output=22 kw", + "then": { + "en": "Type 2 with cable (mennekes) outputs at most 22 kw", + "nl": "Type 2 met kabel (J1772) levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "id": "plugs-10", + "question": { + "en": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Tesla Supercharger CCS (a branded type2_css) plugs of type Tesla Supercharger CCS (a branded type2_css) available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "id": "voltage-10", + "question": { + "en": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt", + "nl": " heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger_ccs:voltage=500 V", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt", + "nl": " heeft een spanning van 500 volt" + } + }, + { + "if": "socket:socket:tesla_supercharger_ccs:voltage=920 V", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs 920 volt", + "nl": " heeft een spanning van 920 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "id": "current-10", + "question": { + "en": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A", + "nl": " levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger_ccs:current=125 A", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A", + "nl": " levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:tesla_supercharger_ccs:current=350 A", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A", + "nl": " levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "id": "power-output-10", + "question": { + "en": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:output}", + "nl": " levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger_ccs:output=50 kw", + "then": { + "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 50 kw", + "nl": " levert een vermogen van maximaal 50 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "id": "plugs-11", + "question": { + "en": "How much plugs of type Tesla Supercharger (destination) are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:tesla_destination", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "voltage-11", + "question": { + "en": "What voltage do the plugs with Tesla Supercharger (destination) offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt", + "nl": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_destination:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:voltage=480 V", + "then": { + "en": "Tesla Supercharger (destination) outputs 480 volt", + "nl": " heeft een spanning van 480 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "current-11", + "question": { + "en": "What current do the plugs with Tesla Supercharger (destination) offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A", + "nl": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "freeform": { + "key": "socket:tesla_destination:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:current=125 A", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 125 A", + "nl": " levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:tesla_destination:current=350 A", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 350 A", + "nl": " levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "power-output-11", + "question": { + "en": "What power output does a single plug of type Tesla Supercharger (destination) offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:output}", + "nl": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "freeform": { + "key": "socket:tesla_destination:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:output=120 kw", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 120 kw", + "nl": " levert een vermogen van maximaal 120 kw" + } + }, + { + "if": "socket:socket:tesla_destination:output=150 kw", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 150 kw", + "nl": " levert een vermogen van maximaal 150 kw" + } + }, + { + "if": "socket:socket:tesla_destination:output=250 kw", + "then": { + "en": "Tesla Supercharger (destination) outputs at most 250 kw", + "nl": " levert een vermogen van maximaal 250 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "plugs-12", + "question": { + "en": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", + "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + }, + "render": { + "en": "There are Tesla supercharger (destination (A Type 2 with cable branded as tesla) plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) available here", + "nl": "Hier zijn stekkers van het type " + }, + "freeform": { + "key": "socket:tesla_destination", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "voltage-12", + "question": { + "en": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "nl": "Welke spanning levert de stekker van type " + }, + "render": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt", + "nl": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_destination:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:voltage=230 V", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt", + "nl": " heeft een spanning van 230 volt" + } + }, + { + "if": "socket:socket:tesla_destination:voltage=400 V", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt", + "nl": " heeft een spanning van 400 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "current-12", + "question": { + "en": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "nl": "Welke stroom levert de stekker van type ?" + }, + "render": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:current}A", + "nl": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "freeform": { + "key": "socket:tesla_destination:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:current=16 A", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 16 A", + "nl": " levert een stroom van maximaal 16 A" + } + }, + { + "if": "socket:socket:tesla_destination:current=32 A", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 32 A", + "nl": " levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "power-output-12", + "question": { + "en": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "nl": "Welk vermogen levert een enkele stekker van type ?" + }, + "render": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:output}", + "nl": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "freeform": { + "key": "socket:tesla_destination:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:output=11 kw", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 11 kw", + "nl": " levert een vermogen van maximaal 11 kw" + } + }, + { + "if": "socket:socket:tesla_destination:output=22 kw", + "then": { + "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 22 kw", + "nl": " levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } }, { "id": "Authentication", diff --git a/assets/layers/charging_station/csvToJson.ts b/assets/layers/charging_station/csvToJson.ts index 2a1dfdb0b..08e33a229 100644 --- a/assets/layers/charging_station/csvToJson.ts +++ b/assets/layers/charging_station/csvToJson.ts @@ -229,7 +229,7 @@ function run(file, protojson) { const stringified = questions.map(q => JSON.stringify(q, null, " ")) let protoString = readFileSync(protojson, "utf8") - protoString = protoString.replace("{\"#\": \"$$$\"}", stringified.join(",\n")) + protoString = protoString.replace("{\"id\": \"$$$\"}", stringified.join(",\n")) const proto = JSON.parse(protoString) proto.tagRenderings.forEach(tr => { if(typeof tr === "string"){ diff --git a/langs/layers/en.json b/langs/layers/en.json index 8e8c8bde5..8908ed7ec 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -964,6 +964,89 @@ }, "question": "What kind of authentication is available at the charging station?" }, + "Available_charging_stations (generated)": { + "mappings": { + "0": { + "then": " Schuko wall plug without ground pin (CEE7/4 type F)" + }, + "1": { + "then": " Schuko wall plug without ground pin (CEE7/4 type F)" + }, + "2": { + "then": " European wall plug with ground pin (CEE7/4 type E)" + }, + "3": { + "then": " European wall plug with ground pin (CEE7/4 type E)" + }, + "4": { + "then": " Chademo" + }, + "5": { + "then": " Chademo" + }, + "6": { + "then": " Type 1 with cable (J1772)" + }, + "7": { + "then": " Type 1 with cable (J1772)" + }, + "8": { + "then": " Type 1 without cable (J1772)" + }, + "9": { + "then": " Type 1 without cable (J1772)" + }, + "10": { + "then": " Type 1 CCS (aka Type 1 Combo)" + }, + "11": { + "then": " Type 1 CCS (aka Type 1 Combo)" + }, + "12": { + "then": " Tesla Supercharger" + }, + "13": { + "then": " Tesla Supercharger" + }, + "14": { + "then": " Type 2 (mennekes)" + }, + "15": { + "then": " Type 2 (mennekes)" + }, + "16": { + "then": " Type 2 CCS (mennekes)" + }, + "17": { + "then": " Type 2 CCS (mennekes)" + }, + "18": { + "then": " Type 2 with cable (mennekes)" + }, + "19": { + "then": " Type 2 with cable (mennekes)" + }, + "20": { + "then": " Tesla Supercharger CCS (a branded type2_css)" + }, + "21": { + "then": " Tesla Supercharger CCS (a branded type2_css)" + }, + "22": { + "then": " Tesla Supercharger (destination)" + }, + "23": { + "then": " Tesla Supercharger (destination)" + }, + "24": { + "then": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)" + }, + "25": { + "then": " Tesla supercharger (destination (A Type 2 with cable branded as tesla)" + } + }, + "question": "Which charging stations are available here?" + }, "Network": { "mappings": { "0": { @@ -1052,6 +1135,147 @@ "question": "How much vehicles can be charged here at the same time?", "render": "{capacity} vehicles can be charged here at the same time" }, + "current-0": { + "mappings": { + "0": { + "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A" + } + }, + "question": "What current do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:current}A" + }, + "current-1": { + "mappings": { + "0": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A" + } + }, + "question": "What current do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:current}A" + }, + "current-10": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A" + }, + "current-11": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger (destination) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A" + }, + "current-12": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 16 A" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:current}A" + }, + "current-2": { + "mappings": { + "0": { + "then": "Chademo outputs at most 120 A" + } + }, + "question": "What current do the plugs with Chademo offer?", + "render": "Chademo outputs at most {socket:chademo:current}A" + }, + "current-3": { + "mappings": { + "0": { + "then": "Type 1 with cable (J1772) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 1 with cable (J1772) offer?", + "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:current}A" + }, + "current-4": { + "mappings": { + "0": { + "then": "Type 1 without cable (J1772) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 1 without cable (J1772) offer?", + "render": "Type 1 without cable (J1772) outputs at most {socket:type1:current}A" + }, + "current-5": { + "mappings": { + "0": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A" + }, + "1": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A" + } + }, + "question": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A" + }, + "current-6": { + "mappings": { + "0": { + "then": "Tesla Supercharger outputs at most 125 A" + }, + "1": { + "then": "Tesla Supercharger outputs at most 350 A" + } + }, + "question": "What current do the plugs with Tesla Supercharger offer?", + "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A" + }, + "current-7": { + "mappings": { + "0": { + "then": "Type 2 (mennekes) outputs at most 16 A" + }, + "1": { + "then": "Type 2 (mennekes) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 2 (mennekes) offer?", + "render": "Type 2 (mennekes) outputs at most {socket:type2:current}A" + }, + "current-8": { + "mappings": { + "0": { + "then": "Type 2 CCS (mennekes) outputs at most 125 A" + }, + "1": { + "then": "Type 2 CCS (mennekes) outputs at most 350 A" + } + }, + "question": "What current do the plugs with Type 2 CCS (mennekes) offer?", + "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A" + }, + "current-9": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs at most 16 A" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs at most 32 A" + } + }, + "question": "What current do the plugs with Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:current}A" + }, "email": { "question": "What is the email address of the operator?", "render": "In case of problems, send an email to {email}" @@ -1098,10 +1322,365 @@ "question": "What number can one call if there is a problem with this charging station?", "render": "In case of problems, call {phone}" }, + "plugs-0": { + "question": "How much plugs of type Schuko wall plug without ground pin (CEE7/4 type F) are available here?", + "render": "There are Schuko wall plug without ground pin (CEE7/4 type F) plugs of type Schuko wall plug without ground pin (CEE7/4 type F) available here" + }, + "plugs-1": { + "question": "How much plugs of type European wall plug with ground pin (CEE7/4 type E) are available here?", + "render": "There are European wall plug with ground pin (CEE7/4 type E) plugs of type European wall plug with ground pin (CEE7/4 type E) available here" + }, + "plugs-10": { + "question": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", + "render": "There are Tesla Supercharger CCS (a branded type2_css) plugs of type Tesla Supercharger CCS (a branded type2_css) available here" + }, + "plugs-11": { + "question": "How much plugs of type Tesla Supercharger (destination) are available here?", + "render": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here" + }, + "plugs-12": { + "question": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", + "render": "There are Tesla supercharger (destination (A Type 2 with cable branded as tesla) plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) available here" + }, + "plugs-2": { + "question": "How much plugs of type Chademo are available here?", + "render": "There are Chademo plugs of type Chademo available here" + }, + "plugs-3": { + "question": "How much plugs of type Type 1 with cable (J1772) are available here?", + "render": "There are Type 1 with cable (J1772) plugs of type Type 1 with cable (J1772) available here" + }, + "plugs-4": { + "question": "How much plugs of type Type 1 without cable (J1772) are available here?", + "render": "There are Type 1 without cable (J1772) plugs of type Type 1 without cable (J1772) available here" + }, + "plugs-5": { + "question": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", + "render": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here" + }, + "plugs-6": { + "question": "How much plugs of type Tesla Supercharger are available here?", + "render": "There are Tesla Supercharger plugs of type Tesla Supercharger available here" + }, + "plugs-7": { + "question": "How much plugs of type Type 2 (mennekes) are available here?", + "render": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here" + }, + "plugs-8": { + "question": "How much plugs of type Type 2 CCS (mennekes) are available here?", + "render": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here" + }, + "plugs-9": { + "question": "How much plugs of type Type 2 with cable (mennekes) are available here?", + "render": "There are Type 2 with cable (mennekes) plugs of type Type 2 with cable (mennekes) available here" + }, + "power-output-0": { + "mappings": { + "0": { + "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw" + } + }, + "question": "What power output does a single plug of type Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs at most {socket:schuko:output}" + }, + "power-output-1": { + "mappings": { + "0": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw" + }, + "1": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type European wall plug with ground pin (CEE7/4 type E) offer?", + "render": "European wall plug with ground pin (CEE7/4 type E) outputs at most {socket:typee:output}" + }, + "power-output-10": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs at most 50 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:output}" + }, + "power-output-11": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs at most 120 kw" + }, + "1": { + "then": "Tesla Supercharger (destination) outputs at most 150 kw" + }, + "2": { + "then": "Tesla Supercharger (destination) outputs at most 250 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:output}" + }, + "power-output-12": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 11 kw" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:output}" + }, + "power-output-2": { + "mappings": { + "0": { + "then": "Chademo outputs at most 50 kw" + } + }, + "question": "What power output does a single plug of type Chademo offer?", + "render": "Chademo outputs at most {socket:chademo:output}" + }, + "power-output-3": { + "mappings": { + "0": { + "then": "Type 1 with cable (J1772) outputs at most 3.7 kw" + }, + "1": { + "then": "Type 1 with cable (J1772) outputs at most 7 kw" + } + }, + "question": "What power output does a single plug of type Type 1 with cable (J1772) offer?", + "render": "Type 1 with cable (J1772) outputs at most {socket:type1_cable:output}" + }, + "power-output-4": { + "mappings": { + "0": { + "then": "Type 1 without cable (J1772) outputs at most 3.7 kw" + }, + "1": { + "then": "Type 1 without cable (J1772) outputs at most 6.6 kw" + }, + "2": { + "then": "Type 1 without cable (J1772) outputs at most 7 kw" + }, + "3": { + "then": "Type 1 without cable (J1772) outputs at most 7.2 kw" + } + }, + "question": "What power output does a single plug of type Type 1 without cable (J1772) offer?", + "render": "Type 1 without cable (J1772) outputs at most {socket:type1:output}" + }, + "power-output-5": { + "mappings": { + "0": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw" + }, + "1": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw" + }, + "2": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw" + }, + "3": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw" + } + }, + "question": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", + "render": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}" + }, + "power-output-6": { + "mappings": { + "0": { + "then": "Tesla Supercharger outputs at most 120 kw" + }, + "1": { + "then": "Tesla Supercharger outputs at most 150 kw" + }, + "2": { + "then": "Tesla Supercharger outputs at most 250 kw" + } + }, + "question": "What power output does a single plug of type Tesla Supercharger offer?", + "render": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}" + }, + "power-output-7": { + "mappings": { + "0": { + "then": "Type 2 (mennekes) outputs at most 11 kw" + }, + "1": { + "then": "Type 2 (mennekes) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Type 2 (mennekes) offer?", + "render": "Type 2 (mennekes) outputs at most {socket:type2:output}" + }, + "power-output-8": { + "mappings": { + "0": { + "then": "Type 2 CCS (mennekes) outputs at most 50 kw" + } + }, + "question": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", + "render": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}" + }, + "power-output-9": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs at most 11 kw" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs at most 22 kw" + } + }, + "question": "What power output does a single plug of type Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs at most {socket:type2_cable:output}" + }, "ref": { "question": "What is the reference number of this charging station?", "render": "Reference number is {ref}" }, + "voltage-0": { + "mappings": { + "0": { + "then": "Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt" + } + }, + "question": "What voltage do the plugs with Schuko wall plug without ground pin (CEE7/4 type F) offer?", + "render": "Schuko wall plug without ground pin (CEE7/4 type F) outputs {socket:schuko:voltage} volt" + }, + "voltage-1": { + "mappings": { + "0": { + "then": "European wall plug with ground pin (CEE7/4 type E) outputs 230 volt" + } + }, + "question": "What voltage do the plugs with European wall plug with ground pin (CEE7/4 type E) offer?", + "render": "European wall plug with ground pin (CEE7/4 type E) outputs {socket:typee:voltage} volt" + }, + "voltage-10": { + "mappings": { + "0": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt" + }, + "1": { + "then": "Tesla Supercharger CCS (a branded type2_css) outputs 920 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", + "render": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt" + }, + "voltage-11": { + "mappings": { + "0": { + "then": "Tesla Supercharger (destination) outputs 480 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger (destination) offer?", + "render": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt" + }, + "voltage-12": { + "mappings": { + "0": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt" + }, + "1": { + "then": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", + "render": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt" + }, + "voltage-2": { + "mappings": { + "0": { + "then": "Chademo outputs 500 volt" + } + }, + "question": "What voltage do the plugs with Chademo offer?", + "render": "Chademo outputs {socket:chademo:voltage} volt" + }, + "voltage-3": { + "mappings": { + "0": { + "then": "Type 1 with cable (J1772) outputs 200 volt" + }, + "1": { + "then": "Type 1 with cable (J1772) outputs 240 volt" + } + }, + "question": "What voltage do the plugs with Type 1 with cable (J1772) offer?", + "render": "Type 1 with cable (J1772) outputs {socket:type1_cable:voltage} volt" + }, + "voltage-4": { + "mappings": { + "0": { + "then": "Type 1 without cable (J1772) outputs 200 volt" + }, + "1": { + "then": "Type 1 without cable (J1772) outputs 240 volt" + } + }, + "question": "What voltage do the plugs with Type 1 without cable (J1772) offer?", + "render": "Type 1 without cable (J1772) outputs {socket:type1:voltage} volt" + }, + "voltage-5": { + "mappings": { + "0": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt" + }, + "1": { + "then": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt" + } + }, + "question": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", + "render": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt" + }, + "voltage-6": { + "mappings": { + "0": { + "then": "Tesla Supercharger outputs 480 volt" + } + }, + "question": "What voltage do the plugs with Tesla Supercharger offer?", + "render": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt" + }, + "voltage-7": { + "mappings": { + "0": { + "then": "Type 2 (mennekes) outputs 230 volt" + }, + "1": { + "then": "Type 2 (mennekes) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Type 2 (mennekes) offer?", + "render": "Type 2 (mennekes) outputs {socket:type2:voltage} volt" + }, + "voltage-8": { + "mappings": { + "0": { + "then": "Type 2 CCS (mennekes) outputs 500 volt" + }, + "1": { + "then": "Type 2 CCS (mennekes) outputs 920 volt" + } + }, + "question": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", + "render": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt" + }, + "voltage-9": { + "mappings": { + "0": { + "then": "Type 2 with cable (mennekes) outputs 230 volt" + }, + "1": { + "then": "Type 2 with cable (mennekes) outputs 400 volt" + } + }, + "question": "What voltage do the plugs with Type 2 with cable (mennekes) offer?", + "render": "Type 2 with cable (mennekes) outputs {socket:type2_cable:voltage} volt" + }, "website": { "question": "What is the website of the operator?", "render": "More info on {website}" diff --git a/langs/layers/nl.json b/langs/layers/nl.json index a894e10c1..8b133247b 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -1027,6 +1027,88 @@ } }, "tagRenderings": { + "Available_charging_stations (generated)": { + "mappings": { + "0": { + "then": " Schuko stekker zonder aardingspin (CEE7/4 type F)" + }, + "1": { + "then": " Schuko stekker zonder aardingspin (CEE7/4 type F)" + }, + "2": { + "then": " Europese stekker met aardingspin (CEE7/4 type E)" + }, + "3": { + "then": " Europese stekker met aardingspin (CEE7/4 type E)" + }, + "4": { + "then": " " + }, + "5": { + "then": " " + }, + "6": { + "then": " Type 1 met kabel (J1772)" + }, + "7": { + "then": " Type 1 met kabel (J1772)" + }, + "8": { + "then": " Type 1 zonder kabel (J1772)" + }, + "9": { + "then": " Type 1 zonder kabel (J1772)" + }, + "10": { + "then": " " + }, + "11": { + "then": " " + }, + "12": { + "then": " " + }, + "13": { + "then": " " + }, + "14": { + "then": " " + }, + "15": { + "then": " " + }, + "16": { + "then": " " + }, + "17": { + "then": " " + }, + "18": { + "then": " Type 2 met kabel (J1772)" + }, + "19": { + "then": " Type 2 met kabel (J1772)" + }, + "20": { + "then": " " + }, + "21": { + "then": " " + }, + "22": { + "then": " " + }, + "23": { + "then": " " + }, + "24": { + "then": " " + }, + "25": { + "then": " " + } + } + }, "Operational status": { "mappings": { "0": { @@ -1051,6 +1133,147 @@ "question": "Hoeveel voertuigen kunnen hier opgeladen worden?", "render": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" }, + "current-0": { + "mappings": { + "0": { + "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal 16 A" + } + }, + "question": "Welke stroom levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", + "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een stroom van maximaal {socket:schuko:current}A" + }, + "current-1": { + "mappings": { + "0": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal 16 A" + } + }, + "question": "Welke stroom levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", + "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een stroom van maximaal {socket:typee:current}A" + }, + "current-10": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" + }, + "current-11": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "current-12": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 16 A" + }, + "1": { + "then": " levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "current-2": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 120 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:chademo:current}A" + }, + "current-3": { + "mappings": { + "0": { + "then": "Type 1 met kabel (J1772) levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type Type 1 met kabel (J1772) ?", + "render": "Type 1 met kabel (J1772) levert een stroom van maximaal {socket:type1_cable:current}A" + }, + "current-4": { + "mappings": { + "0": { + "then": "Type 1 zonder kabel (J1772) levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type Type 1 zonder kabel (J1772) ?", + "render": "Type 1 zonder kabel (J1772) levert een stroom van maximaal {socket:type1:current}A" + }, + "current-5": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 50 A" + }, + "1": { + "then": " levert een stroom van maximaal 125 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:type1_combo:current}A" + }, + "current-6": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" + }, + "current-7": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 16 A" + }, + "1": { + "then": " levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:type2:current}A" + }, + "current-8": { + "mappings": { + "0": { + "then": " levert een stroom van maximaal 125 A" + }, + "1": { + "then": " levert een stroom van maximaal 350 A" + } + }, + "question": "Welke stroom levert de stekker van type ?", + "render": " levert een stroom van maximaal {socket:type2_combo:current}A" + }, + "current-9": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 16 A" + }, + "1": { + "then": "Type 2 met kabel (J1772) levert een stroom van maximaal 32 A" + } + }, + "question": "Welke stroom levert de stekker van type Type 2 met kabel (J1772) ?", + "render": "Type 2 met kabel (J1772) levert een stroom van maximaal {socket:type2_cable:current}A" + }, "fee/charge": { "mappings": { "0": { @@ -1088,6 +1311,361 @@ } } } + }, + "plugs-0": { + "question": "Hoeveel stekkers van type Schuko stekker zonder aardingspin (CEE7/4 type F) heeft dit oplaadpunt?", + "render": "Hier zijn Schuko stekker zonder aardingspin (CEE7/4 type F) stekkers van het type Schuko stekker zonder aardingspin (CEE7/4 type F)" + }, + "plugs-1": { + "question": "Hoeveel stekkers van type Europese stekker met aardingspin (CEE7/4 type E) heeft dit oplaadpunt?", + "render": "Hier zijn Europese stekker met aardingspin (CEE7/4 type E) stekkers van het type Europese stekker met aardingspin (CEE7/4 type E)" + }, + "plugs-10": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-11": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-12": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-2": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-3": { + "question": "Hoeveel stekkers van type Type 1 met kabel (J1772) heeft dit oplaadpunt?", + "render": "Hier zijn Type 1 met kabel (J1772) stekkers van het type Type 1 met kabel (J1772)" + }, + "plugs-4": { + "question": "Hoeveel stekkers van type Type 1 zonder kabel (J1772) heeft dit oplaadpunt?", + "render": "Hier zijn Type 1 zonder kabel (J1772) stekkers van het type Type 1 zonder kabel (J1772)" + }, + "plugs-5": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-6": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-7": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-8": { + "question": "Hoeveel stekkers van type heeft dit oplaadpunt?", + "render": "Hier zijn stekkers van het type " + }, + "plugs-9": { + "question": "Hoeveel stekkers van type Type 2 met kabel (J1772) heeft dit oplaadpunt?", + "render": "Hier zijn Type 2 met kabel (J1772) stekkers van het type Type 2 met kabel (J1772)" + }, + "power-output-0": { + "mappings": { + "0": { + "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal 3.6 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ?", + "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) levert een vermogen van maximaal {socket:schuko:output}" + }, + "power-output-1": { + "mappings": { + "0": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 3 kw" + }, + "1": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Europese stekker met aardingspin (CEE7/4 type E) ?", + "render": "Europese stekker met aardingspin (CEE7/4 type E) levert een vermogen van maximaal {socket:typee:output}" + }, + "power-output-10": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" + }, + "power-output-11": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 120 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 150 kw" + }, + "2": { + "then": " levert een vermogen van maximaal 250 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "power-output-12": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "power-output-2": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:chademo:output}" + }, + "power-output-3": { + "mappings": { + "0": { + "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 3.7 kw" + }, + "1": { + "then": "Type 1 met kabel (J1772) levert een vermogen van maximaal 7 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Type 1 met kabel (J1772) ?", + "render": "Type 1 met kabel (J1772) levert een vermogen van maximaal {socket:type1_cable:output}" + }, + "power-output-4": { + "mappings": { + "0": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 3.7 kw" + }, + "1": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 6.6 kw" + }, + "2": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7 kw" + }, + "3": { + "then": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal 7.2 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Type 1 zonder kabel (J1772) ?", + "render": "Type 1 zonder kabel (J1772) levert een vermogen van maximaal {socket:type1:output}" + }, + "power-output-5": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 62.5 kw" + }, + "2": { + "then": " levert een vermogen van maximaal 150 kw" + }, + "3": { + "then": " levert een vermogen van maximaal 350 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:type1_combo:output}" + }, + "power-output-6": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 120 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 150 kw" + }, + "2": { + "then": " levert een vermogen van maximaal 250 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" + }, + "power-output-7": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": " levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:type2:output}" + }, + "power-output-8": { + "mappings": { + "0": { + "then": " levert een vermogen van maximaal 50 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type ?", + "render": " levert een vermogen van maximaal {socket:type2_combo:output}" + }, + "power-output-9": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 11 kw" + }, + "1": { + "then": "Type 2 met kabel (J1772) levert een vermogen van maximaal 22 kw" + } + }, + "question": "Welk vermogen levert een enkele stekker van type Type 2 met kabel (J1772) ?", + "render": "Type 2 met kabel (J1772) levert een vermogen van maximaal {socket:type2_cable:output}" + }, + "voltage-0": { + "mappings": { + "0": { + "then": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van 230 volt" + } + }, + "question": "Welke spanning levert de stekker van type Schuko stekker zonder aardingspin (CEE7/4 type F) ", + "render": "Schuko stekker zonder aardingspin (CEE7/4 type F) heeft een spanning van {socket:schuko:voltage} volt" + }, + "voltage-1": { + "mappings": { + "0": { + "then": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van 230 volt" + } + }, + "question": "Welke spanning levert de stekker van type Europese stekker met aardingspin (CEE7/4 type E) ", + "render": "Europese stekker met aardingspin (CEE7/4 type E) heeft een spanning van {socket:typee:voltage} volt" + }, + "voltage-10": { + "mappings": { + "0": { + "then": " heeft een spanning van 500 volt" + }, + "1": { + "then": " heeft een spanning van 920 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" + }, + "voltage-11": { + "mappings": { + "0": { + "then": " heeft een spanning van 480 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "voltage-12": { + "mappings": { + "0": { + "then": " heeft een spanning van 230 volt" + }, + "1": { + "then": " heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "voltage-2": { + "mappings": { + "0": { + "then": " heeft een spanning van 500 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:chademo:voltage} volt" + }, + "voltage-3": { + "mappings": { + "0": { + "then": "Type 1 met kabel (J1772) heeft een spanning van 200 volt" + }, + "1": { + "then": "Type 1 met kabel (J1772) heeft een spanning van 240 volt" + } + }, + "question": "Welke spanning levert de stekker van type Type 1 met kabel (J1772) ", + "render": "Type 1 met kabel (J1772) heeft een spanning van {socket:type1_cable:voltage} volt" + }, + "voltage-4": { + "mappings": { + "0": { + "then": "Type 1 zonder kabel (J1772) heeft een spanning van 200 volt" + }, + "1": { + "then": "Type 1 zonder kabel (J1772) heeft een spanning van 240 volt" + } + }, + "question": "Welke spanning levert de stekker van type Type 1 zonder kabel (J1772) ", + "render": "Type 1 zonder kabel (J1772) heeft een spanning van {socket:type1:voltage} volt" + }, + "voltage-5": { + "mappings": { + "0": { + "then": " heeft een spanning van 400 volt" + }, + "1": { + "then": " heeft een spanning van 1000 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:type1_combo:voltage} volt" + }, + "voltage-6": { + "mappings": { + "0": { + "then": " heeft een spanning van 480 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" + }, + "voltage-7": { + "mappings": { + "0": { + "then": " heeft een spanning van 230 volt" + }, + "1": { + "then": " heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:type2:voltage} volt" + }, + "voltage-8": { + "mappings": { + "0": { + "then": " heeft een spanning van 500 volt" + }, + "1": { + "then": " heeft een spanning van 920 volt" + } + }, + "question": "Welke spanning levert de stekker van type ", + "render": " heeft een spanning van {socket:type2_combo:voltage} volt" + }, + "voltage-9": { + "mappings": { + "0": { + "then": "Type 2 met kabel (J1772) heeft een spanning van 230 volt" + }, + "1": { + "then": "Type 2 met kabel (J1772) heeft een spanning van 400 volt" + } + }, + "question": "Welke spanning levert de stekker van type Type 2 met kabel (J1772) ", + "render": "Type 2 met kabel (J1772) heeft een spanning van {socket:type2_cable:voltage} volt" } }, "units": { From a3c16d62977c9bc59c932c33140f73fc19176556 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 26 Sep 2021 23:35:26 +0200 Subject: [PATCH 31/65] Stabilize adding new points --- Logic/Actors/OverpassFeatureSource.ts | 2 - .../NewGeometryFromChangesFeatureSource.ts | 4 + Logic/Osm/Changes.ts | 89 ++--- Logic/Osm/ChangesetHandler.ts | 354 +++++++++--------- Logic/Osm/OsmConnection.ts | 13 +- Logic/Osm/OsmObject.ts | 17 - State.ts | 11 +- UI/BigComponents/SimpleAddUI.ts | 1 - assets/themes/uk_addresses/uk_addresses.json | 6 + langs/en.json | 3 +- langs/themes/en.json | 6 +- 11 files changed, 249 insertions(+), 257 deletions(-) diff --git a/Logic/Actors/OverpassFeatureSource.ts b/Logic/Actors/OverpassFeatureSource.ts index 7ddafacd8..20181fc14 100644 --- a/Logic/Actors/OverpassFeatureSource.ts +++ b/Logic/Actors/OverpassFeatureSource.ts @@ -56,8 +56,6 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour readonly overpassTimeout: UIEventSource; readonly overpassMaxZoom: UIEventSource }) { - console.trace("Initializing an overpass FS") - this.state = state this.relationsTracker = new RelationsTracker() diff --git a/Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource.ts b/Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource.ts index f4619b2aa..0a1c67f41 100644 --- a/Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource.ts +++ b/Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource.ts @@ -3,6 +3,7 @@ import {OsmNode, OsmRelation, OsmWay} from "../../Osm/OsmObject"; import FeatureSource from "../FeatureSource"; import {UIEventSource} from "../../UIEventSource"; import {ChangeDescription} from "../../Osm/Actions/ChangeDescription"; +import State from "../../../State"; export class NewGeometryFromChangesFeatureSource implements FeatureSource { // This class name truly puts the 'Java' into 'Javascript' @@ -54,6 +55,9 @@ export class NewGeometryFromChangesFeatureSource implements FeatureSource { tags[kv.k] = kv.v } tags["id"] = change.type+"/"+change.id + + tags["_backend"] = State.state.osmConnection._oauth_config.url + switch (change.type) { case "node": const n = new OsmNode(change.id) diff --git a/Logic/Osm/Changes.ts b/Logic/Osm/Changes.ts index 83545b30a..828ba7d78 100644 --- a/Logic/Osm/Changes.ts +++ b/Logic/Osm/Changes.ts @@ -14,7 +14,7 @@ import {LocalStorageSource} from "../Web/LocalStorageSource"; export class Changes { - private _nextId : number = -1; // Newly assigned ID's are negative + private _nextId: number = -1; // Newly assigned ID's are negative public readonly name = "Newly added features" /** * All the newly created features as featureSource + all the modified features @@ -31,7 +31,10 @@ export class Changes { // We keep track of all changes just as well this.allChanges.setData([...this.pendingChanges.data]) // If a pending change contains a negative ID, we save that - this._nextId = Math.min(-1, ...this.pendingChanges.data?.map(pch => pch.id) ?? []) + this._nextId = Math.min(-1, ...this.pendingChanges.data?.map(pch => pch.id) ?? []) + + // Note: a changeset might be reused which was opened just before and might have already used some ids + // This doesn't matter however, as the '-1' is per piecewise upload, not global per changeset } private static createChangesetFor(csId: string, @@ -90,62 +93,58 @@ export class Changes { if (this.pendingChanges.data.length === 0) { return; } - if (this.isUploading.data) { console.log("Is already uploading... Abort") return; } - - this.isUploading.setData(true) + this.flushChangesAsync(flushreason) + .then(_ => { + this.isUploading.setData(false) + console.log("Changes flushed!"); + }) + .catch(e => { + this.isUploading.setData(false) + console.error("Flushing changes failed due to", e); + }) + } + + private async flushChangesAsync(flushreason: string = undefined): Promise { console.log("Beginning upload... " + flushreason ?? ""); // At last, we build the changeset and upload const self = this; const pending = self.pendingChanges.data; const neededIds = Changes.GetNeededIds(pending) - console.log("Needed ids", neededIds) - OsmObject.DownloadAll(neededIds, true).addCallbackAndRunD(osmObjects => { - console.log("Got the fresh objects!", osmObjects, "pending: ", pending) - try { - - - const changes: { - newObjects: OsmObject[], - modifiedObjects: OsmObject[] - deletedObjects: OsmObject[] - - } = self.CreateChangesetObjects(pending, osmObjects) - if (changes.newObjects.length + changes.deletedObjects.length + changes.modifiedObjects.length === 0) { - console.log("No changes to be made") - self.pendingChanges.setData([]) - self.isUploading.setData(false) - return true; // Unregister the callback - } - - - State.state.osmConnection.UploadChangeset( - State.state.layoutToUse.data, - State.state.allElements, - (csId) => Changes.createChangesetFor(csId, changes), - () => { - console.log("Upload successfull!") - self.pendingChanges.setData([]); - self.isUploading.setData(false) - }, - () => { - console.log("Upload failed - trying again later") - return self.isUploading.setData(false); - } // Failed - mark to try again - ) - } catch (e) { - console.error("Could not handle changes - probably an old, pending changeset in localstorage with an invalid format; erasing those", e) + const osmObjects = await Promise.all(neededIds.map(id => OsmObject.DownloadObjectAsync(id))); + console.log("Got the fresh objects!", osmObjects, "pending: ", pending) + try { + const changes: { + newObjects: OsmObject[], + modifiedObjects: OsmObject[] + deletedObjects: OsmObject[] + } = self.CreateChangesetObjects(pending, osmObjects) + if (changes.newObjects.length + changes.deletedObjects.length + changes.modifiedObjects.length === 0) { + console.log("No changes to be made") self.pendingChanges.setData([]) self.isUploading.setData(false) } - return true; - }); + await State.state.osmConnection.UploadChangeset( + State.state.layoutToUse.data, + State.state.allElements, + (csId) => Changes.createChangesetFor(csId, changes), + ) + + console.log("Upload successfull!") + this.pendingChanges.setData([]); + this.isUploading.setData(false) + + } catch (e) { + console.error("Could not handle changes - probably an old, pending changeset in localstorage with an invalid format; erasing those", e) + self.pendingChanges.setData([]) + self.isUploading.setData(false) + } } @@ -311,4 +310,8 @@ export class Changes { return result } + + public registerIdRewrites(mappings: Map): void { + + } } \ No newline at end of file diff --git a/Logic/Osm/ChangesetHandler.ts b/Logic/Osm/ChangesetHandler.ts index dcf0d135a..aae51d4ee 100644 --- a/Logic/Osm/ChangesetHandler.ts +++ b/Logic/Osm/ChangesetHandler.ts @@ -8,15 +8,23 @@ import Locale from "../../UI/i18n/Locale"; import Constants from "../../Models/Constants"; import {OsmObject} from "./OsmObject"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; +import {Changes} from "./Changes"; export class ChangesetHandler { public readonly currentChangeset: UIEventSource; + private readonly allElements: ElementStorage; + private readonly changes: Changes; private readonly _dryRun: boolean; private readonly userDetails: UIEventSource; private readonly auth: any; - constructor(layoutName: string, dryRun: boolean, osmConnection: OsmConnection, auth) { + constructor(layoutName: string, dryRun: boolean, osmConnection: OsmConnection, + allElements: ElementStorage, + changes: Changes, + auth) { + this.allElements = allElements; + this.changes = changes; this._dryRun = dryRun; this.userDetails = osmConnection.userDetails; this.auth = auth; @@ -27,35 +35,55 @@ export class ChangesetHandler { } } - private static parseUploadChangesetResponse(response: XMLDocument, allElements: ElementStorage): void { + private handleIdRewrite(node: any, type: string): [string, string] { + const oldId = parseInt(node.attributes.old_id.value); + if (node.attributes.new_id === undefined) { + // We just removed this point! + const element =this. allElements.getEventSourceById("node/" + oldId); + element.data._deleted = "yes" + element.ping(); + return; + } + + const newId = parseInt(node.attributes.new_id.value); + const result: [string, string] = [type + "/" + oldId, type + "/" + newId] + if (!(oldId !== undefined && newId !== undefined && + !isNaN(oldId) && !isNaN(newId))) { + return undefined; + } + if (oldId == newId) { + return undefined; + } + console.log("Rewriting id: ", type + "/" + oldId, "-->", type + "/" + newId); + const element = this.allElements.getEventSourceById("node/" + oldId); + element.data.id = type + "/" + newId; + this.allElements.addElementById(type + "/" + newId, element); + this.allElements.ContainingFeatures.set(type + "/" + newId, this.allElements.ContainingFeatures.get(type + "/" + oldId)) + element.ping(); + return result; + } + + private parseUploadChangesetResponse(response: XMLDocument): void { const nodes = response.getElementsByTagName("node"); + const mappings = new Map() // @ts-ignore for (const node of nodes) { - const oldId = parseInt(node.attributes.old_id.value); - if (node.attributes.new_id === undefined) { - // We just removed this point! - const element = allElements.getEventSourceById("node/" + oldId); - element.data._deleted = "yes" - element.ping(); - continue; + const mapping = this.handleIdRewrite(node, "node") + if (mapping !== undefined) { + mappings.set(mapping[0], mapping[1]) } - - const newId = parseInt(node.attributes.new_id.value); - if (oldId !== undefined && newId !== undefined && - !isNaN(oldId) && !isNaN(newId)) { - if (oldId == newId) { - continue; - } - console.log("Rewriting id: ", oldId, "-->", newId); - const element = allElements.getEventSourceById("node/" + oldId); - element.data.id = "node/" + newId; - allElements.addElementById("node/" + newId, element); - element.ping(); - - } - - } + + const ways = response.getElementsByTagName("way"); + // @ts-ignore + for (const way of ways) { + const mapping = this.handleIdRewrite(way, "way") + if (mapping !== undefined) { + mappings.set(mapping[0], mapping[1]) + } + } + this.changes.registerIdRewrites(mappings) + } /** @@ -68,13 +96,9 @@ export class ChangesetHandler { * If 'dryrun' is specified, the changeset XML will be printed to console instead of being uploaded * */ - public UploadChangeset( + public async UploadChangeset( layout: LayoutConfig, - allElements: ElementStorage, - generateChangeXML: (csid: string) => string, - whenDone: (csId: string) => void, - onFail: () => void) { - + generateChangeXML: (csid: string) => string): Promise { if (this.userDetails.data.csCount == 0) { // The user became a contributor! this.userDetails.data.csCount = 1; @@ -84,46 +108,36 @@ export class ChangesetHandler { if (this._dryRun) { const changesetXML = generateChangeXML("123456"); console.log(changesetXML); - whenDone("123456") return; } - const self = this; - if (this.currentChangeset.data === undefined || this.currentChangeset.data === "") { // We have to open a new changeset - this.OpenChangeset(layout, (csId) => { + try { + const csId = await this.OpenChangeset(layout) this.currentChangeset.setData(csId); const changeset = generateChangeXML(csId); - console.log(changeset); - self.AddChange(csId, changeset, - allElements, - whenDone, - (e) => { - console.error("UPLOADING FAILED!", e) - onFail() - } - ) - }, { - onFail: onFail - }) + console.log("Current changeset is:", changeset); + await this.AddChange(csId, changeset) + } catch (e) { + console.error("Could not open/upload changeset due to ", e) + this.currentChangeset.setData("") + } } else { // There still exists an open changeset (or at least we hope so) const csId = this.currentChangeset.data; - self.AddChange( - csId, - generateChangeXML(csId), - allElements, - whenDone, - (e) => { - console.warn("Could not upload, changeset is probably closed: ", e); - // Mark the CS as closed... - this.currentChangeset.setData(""); - // ... and try again. As the cs is closed, no recursive loop can exist - self.UploadChangeset(layout, allElements, generateChangeXML, whenDone, onFail); - } - ) + try { + await this.AddChange( + csId, + generateChangeXML(csId)) + } catch (e) { + console.warn("Could not upload, changeset is probably closed: ", e); + // Mark the CS as closed... + this.currentChangeset.setData(""); + // ... and try again. As the cs is closed, no recursive loop can exist + await this.UploadChangeset(layout, generateChangeXML) + } } } @@ -143,6 +157,13 @@ export class ChangesetHandler { reason: string, allElements: ElementStorage, continuation: () => void) { + return this.DeleteElementAsync(object, layout, reason, allElements).then(continuation) + } + + public async DeleteElementAsync(object: OsmObject, + layout: LayoutConfig, + reason: string, + allElements: ElementStorage): Promise { function generateChangeXML(csId: string) { let [lat, lon] = object.centerpoint(); @@ -151,9 +172,7 @@ export class ChangesetHandler { changes += `<${object.type} id="${object.id}" version="${object.version}" changeset="${csId}" lat="${lat}" lon="${lon}" />`; changes += ""; - continuation() return changes; - } @@ -163,143 +182,122 @@ export class ChangesetHandler { return; } - const self = this; - this.OpenChangeset(layout, (csId: string) => { - - // The cs is open - let us actually upload! - const changes = generateChangeXML(csId) - - self.AddChange(csId, changes, allElements, (csId) => { - console.log("Successfully deleted ", object.id) - self.CloseChangeset(csId, continuation) - }, (csId) => { - alert("Deletion failed... Should not happend") - // FAILED - self.CloseChangeset(csId, continuation) - }) - }, { - isDeletionCS: true, - deletionReason: reason - } - ) + const csId = await this.OpenChangeset(layout, { + isDeletionCS: true, + deletionReason: reason + }) + // The cs is open - let us actually upload! + const changes = generateChangeXML(csId) + await this.AddChange(csId, changes) + await this.CloseChangeset(csId) } - private CloseChangeset(changesetId: string = undefined, continuation: (() => void) = () => { - }) { - if (changesetId === undefined) { - changesetId = this.currentChangeset.data; - } - if (changesetId === undefined) { - return; - } - console.log("closing changeset", changesetId); - this.currentChangeset.setData(""); - this.auth.xhr({ - method: 'PUT', - path: '/api/0.6/changeset/' + changesetId + '/close', - }, function (err, response) { - if (response == null) { - - console.log("err", err); + private async CloseChangeset(changesetId: string = undefined): Promise { + const self = this + return new Promise(function (resolve, reject) { + if (changesetId === undefined) { + changesetId = self.currentChangeset.data; } - console.log("Closed changeset ", changesetId) - - if (continuation !== undefined) { - continuation(); + if (changesetId === undefined) { + return; } - }); + console.log("closing changeset", changesetId); + self.currentChangeset.setData(""); + self.auth.xhr({ + method: 'PUT', + path: '/api/0.6/changeset/' + changesetId + '/close', + }, function (err, response) { + if (response == null) { + + console.log("err", err); + } + console.log("Closed changeset ", changesetId) + resolve() + }); + }) } private OpenChangeset( layout: LayoutConfig, - continuation: (changesetId: string) => void, options?: { isDeletionCS?: boolean, deletionReason?: string, - onFail?: () => void } - ) { - options = options ?? {} - options.isDeletionCS = options.isDeletionCS ?? false - const commentExtra = layout.changesetmessage !== undefined ? " - " + layout.changesetmessage : ""; - let comment = `Adding data with #MapComplete for theme #${layout.id}${commentExtra}` - if (options.isDeletionCS) { - comment = `Deleting a point with #MapComplete for theme #${layout.id}${commentExtra}` - if (options.deletionReason) { - comment += ": " + options.deletionReason; - } - } - - let path = window.location.pathname; - path = path.substr(1, path.lastIndexOf("/")); - const metadata = [ - ["created_by", `MapComplete ${Constants.vNumber}`], - ["comment", comment], - ["deletion", options.isDeletionCS ? "yes" : undefined], - ["theme", layout.id], - ["language", Locale.language.data], - ["host", window.location.host], - ["path", path], - ["source", State.state.currentGPSLocation.data !== undefined ? "survey" : undefined], - ["imagery", State.state.backgroundLayer.data.id], - ["theme-creator", layout.maintainer] - ] - .filter(kv => (kv[1] ?? "") !== "") - .map(kv => ``) - .join("\n") - - this.auth.xhr({ - method: 'PUT', - path: '/api/0.6/changeset/create', - options: {header: {'Content-Type': 'text/xml'}}, - content: [``, - metadata, - ``].join("") - }, function (err, response) { - if (response === undefined) { - console.log("err", err); - if (options.onFail) { - options.onFail() + ): Promise { + const self = this; + return new Promise(function (resolve, reject) { + options = options ?? {} + options.isDeletionCS = options.isDeletionCS ?? false + const commentExtra = layout.changesetmessage !== undefined ? " - " + layout.changesetmessage : ""; + let comment = `Adding data with #MapComplete for theme #${layout.id}${commentExtra}` + if (options.isDeletionCS) { + comment = `Deleting a point with #MapComplete for theme #${layout.id}${commentExtra}` + if (options.deletionReason) { + comment += ": " + options.deletionReason; } - return; - } else { - continuation(response); } - }); + + let path = window.location.pathname; + path = path.substr(1, path.lastIndexOf("/")); + const metadata = [ + ["created_by", `MapComplete ${Constants.vNumber}`], + ["comment", comment], + ["deletion", options.isDeletionCS ? "yes" : undefined], + ["theme", layout.id], + ["language", Locale.language.data], + ["host", window.location.host], + ["path", path], + ["source", State.state.currentGPSLocation.data !== undefined ? "survey" : undefined], + ["imagery", State.state.backgroundLayer.data.id], + ["theme-creator", layout.maintainer] + ] + .filter(kv => (kv[1] ?? "") !== "") + .map(kv => ``) + .join("\n") + + + self.auth.xhr({ + method: 'PUT', + path: '/api/0.6/changeset/create', + options: {header: {'Content-Type': 'text/xml'}}, + content: [``, + metadata, + ``].join("") + }, function (err, response) { + if (response === undefined) { + console.log("err", err); + reject(err) + } else { + resolve(response); + } + }); + }) + } /** * Upload a changesetXML - * @param changesetId - * @param changesetXML - * @param allElements - * @param continuation - * @param onFail - * @constructor - * @private */ private AddChange(changesetId: string, - changesetXML: string, - allElements: ElementStorage, - continuation: ((changesetId: string) => void), - onFail: ((changesetId: string, reason: string) => void) = undefined) { - this.auth.xhr({ - method: 'POST', - options: {header: {'Content-Type': 'text/xml'}}, - path: '/api/0.6/changeset/' + changesetId + '/upload', - content: changesetXML - }, function (err, response) { - if (response == null) { - console.log("err", err); - if (onFail) { - onFail(changesetId, err); + changesetXML: string): Promise { + const self = this; + return new Promise(function (resolve, reject) { + self.auth.xhr({ + method: 'POST', + options: {header: {'Content-Type': 'text/xml'}}, + path: '/api/0.6/changeset/' + changesetId + '/upload', + content: changesetXML + }, function (err, response) { + if (response == null) { + console.log("err", err); + reject(err); } - return; - } - ChangesetHandler.parseUploadChangesetResponse(response, allElements); - console.log("Uploaded changeset ", changesetId); - continuation(changesetId); - }); + self.parseUploadChangesetResponse(response); + console.log("Uploaded changeset ", changesetId); + resolve(changesetId); + }); + }) + } diff --git a/Logic/Osm/OsmConnection.ts b/Logic/Osm/OsmConnection.ts index 5a5e82612..5d955eb04 100644 --- a/Logic/Osm/OsmConnection.ts +++ b/Logic/Osm/OsmConnection.ts @@ -9,6 +9,7 @@ import Img from "../../UI/Base/Img"; import {Utils} from "../../Utils"; import {OsmObject} from "./OsmObject"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; +import {Changes} from "./Changes"; export default class UserDetails { @@ -54,7 +55,7 @@ export class OsmConnection { private _onLoggedIn: ((userDetails: UserDetails) => void)[] = []; private readonly _iframeMode: Boolean | boolean; private readonly _singlePage: boolean; - private readonly _oauth_config: { + public readonly _oauth_config: { oauth_consumer_key: string, oauth_secret: string, url: string @@ -63,6 +64,8 @@ export class OsmConnection { constructor(dryRun: boolean, fakeUser: boolean, + allElements: ElementStorage, + changes: Changes, oauth_token: UIEventSource, // Used to keep multiple changesets open and to write to the correct changeset layoutName: string, @@ -101,7 +104,7 @@ export class OsmConnection { this.preferencesHandler = new OsmPreferences(this.auth, this); - this.changesetHandler = new ChangesetHandler(layoutName, dryRun, this, this.auth); + this.changesetHandler = new ChangesetHandler(layoutName, dryRun, this, allElements, changes, this.auth); if (oauth_token.data !== undefined) { console.log(oauth_token.data) const self = this; @@ -124,10 +127,8 @@ export class OsmConnection { public UploadChangeset( layout: LayoutConfig, allElements: ElementStorage, - generateChangeXML: (csid: string) => string, - whenDone: (csId: string) => void, - onFail: () => {}) { - this.changesetHandler.UploadChangeset(layout, allElements, generateChangeXML, whenDone, onFail); + generateChangeXML: (csid: string) => string): Promise { + return this.changesetHandler.UploadChangeset(layout, generateChangeXML); } public GetPreference(key: string, prefix: string = "mapcomplete-"): UIEventSource { diff --git a/Logic/Osm/OsmObject.ts b/Logic/Osm/OsmObject.ts index 8027a18d9..d95e0fa49 100644 --- a/Logic/Osm/OsmObject.ts +++ b/Logic/Osm/OsmObject.ts @@ -157,23 +157,6 @@ export abstract class OsmObject { const elements: any[] = data.elements; return OsmObject.ParseObjects(elements); } - - public static DownloadAll(neededIds, forceRefresh = true): UIEventSource { - // local function which downloads all the objects one by one - // this is one big loop, running one download, then rerunning the entire function - - const allSources: UIEventSource [] = neededIds.map(id => OsmObject.DownloadObject(id, forceRefresh)) - const allCompleted = new UIEventSource(undefined).map(_ => { - return !allSources.some(uiEventSource => uiEventSource.data === undefined) - }, allSources) - return allCompleted.map(completed => { - if (completed) { - return allSources.map(src => src.data) - } - return undefined - }); - } - protected static isPolygon(tags: any): boolean { for (const tagsKey in tags) { if (!tags.hasOwnProperty(tagsKey)) { diff --git a/State.ts b/State.ts index 105e7ef05..04b9728b3 100644 --- a/State.ts +++ b/State.ts @@ -32,11 +32,11 @@ export default class State { /** The mapping from id -> UIEventSource */ - public allElements: ElementStorage; + public allElements: ElementStorage = new ElementStorage(); /** THe change handler */ - public changes: Changes; + public changes: Changes = new Changes(); /** The leaflet instance of the big basemap */ @@ -155,7 +155,6 @@ export default class State { constructor(layoutToUse: LayoutConfig) { const self = this; - this.layoutToUse.setData(layoutToUse); // -- Location control initialization @@ -376,6 +375,8 @@ export default class State { this.osmConnection = new OsmConnection( this.featureSwitchIsTesting.data, this.featureSwitchFakeUser.data, + this.allElements, + this.changes, QueryParameters.GetQueryParameter( "oauth_token", undefined, @@ -387,9 +388,7 @@ export default class State { this.featureSwitchApiURL.data ); - this.allElements = new ElementStorage(); - this.changes = new Changes(); - + new ChangeToElementsActor(this.changes, this.allElements) new PendingChangesUploader(this.changes, this.selectedElement); diff --git a/UI/BigComponents/SimpleAddUI.ts b/UI/BigComponents/SimpleAddUI.ts index 57f651e9a..fb2c93a0a 100644 --- a/UI/BigComponents/SimpleAddUI.ts +++ b/UI/BigComponents/SimpleAddUI.ts @@ -57,7 +57,6 @@ export default class SimpleAddUI extends Toggle { function createNewPoint(tags: any[], location: { lat: number, lon: number }, snapOntoWay?: OsmWay) { - console.trace("Creating a new point") const newElementAction = new CreateNewNodeAction(tags, location.lat, location.lon, {snapOnto: snapOntoWay}) State.state.changes.applyAction(newElementAction) selectedPreset.setData(undefined) diff --git a/assets/themes/uk_addresses/uk_addresses.json b/assets/themes/uk_addresses/uk_addresses.json index 7de4c3a36..d4708deac 100644 --- a/assets/themes/uk_addresses/uk_addresses.json +++ b/assets/themes/uk_addresses/uk_addresses.json @@ -54,13 +54,16 @@ }, "tagRenderings": [ { + "id": "uk_addresses_explanation", "render": "There probably is an address here" }, { + "id": "uk_addresses_embedding_outline", "render": "An outline embedding this point with an address already exists in OpenStreetMap.
This object has address {_embedding_object:addr:street} {_embedding_object:addr:housenumber}", "condition": "_embedding_object:id~*" }, { + "id": "uk_addresses_import_button", "render": "{import_button(ref:inspireid=$inspireid, Add this address, ./assets/themes/uk_addresses/housenumber_add.svg)}" }, "all_tags" @@ -109,11 +112,13 @@ }, "tagRenderings": [ { + "id": "uk_addresses_explanation_osm", "render": { "en": "This address is saved in OpenStreetMap" } }, { + "id": "uk_addresses_housenumber", "render": { "en": "The housenumber is {addr:housenumber}" }, @@ -137,6 +142,7 @@ ] }, { + "id": "uk_addresses_street", "render": { "en": "This address is in street {addr:street}" }, diff --git a/langs/en.json b/langs/en.json index fdfc46fe5..9687f11a9 100644 --- a/langs/en.json +++ b/langs/en.json @@ -13,7 +13,8 @@ "uploadDone": "Your picture has been added. Thanks for helping out!", "dontDelete": "Cancel", "doDelete": "Remove image", - "isDeleted": "Deleted" + "isDeleted": "Deleted", + "hasBeenImported": "This feature has been imported" }, "centerMessage": { "loadingData": "Loading data…", diff --git a/langs/themes/en.json b/langs/themes/en.json index 8fed7dd34..e2b1d6591 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -1326,10 +1326,10 @@ "description": "Addresses", "name": "Known addresses in OSM", "tagRenderings": { - "0": { + "uk_addresses_explanation_osm": { "render": "This address is saved in OpenStreetMap" }, - "1": { + "uk_addresses_housenumber": { "mappings": { "0": { "then": "This building has no house number" @@ -1338,7 +1338,7 @@ "question": "What is the number of this house?", "render": "The housenumber is {addr:housenumber}" }, - "2": { + "uk_addresses_street": { "question": "What street is this address located in?", "render": "This address is in street {addr:street}" } From 215aebce1983ebd2f027327547678f9ba5fd68fc Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 27 Sep 2021 14:45:48 +0200 Subject: [PATCH 32/65] More work on clustering, more or less finished --- InitUiElements.ts | 74 ++++-- Logic/FeatureSource/FeaturePipeline.ts | 32 ++- Models/ThemeConfig/Json/LayoutConfigJson.ts | 4 +- Models/ThemeConfig/LayoutConfig.ts | 9 +- UI/ShowDataLayer/PerTileCountAggregator.ts | 258 ++++++++++++-------- UI/ShowDataLayer/ShowDataLayer.ts | 77 +++--- assets/layers/tree_node/tree_node.json | 2 +- assets/themes/trees/trees.json | 5 +- 8 files changed, 276 insertions(+), 185 deletions(-) diff --git a/InitUiElements.ts b/InitUiElements.ts index 0bc6506d1..c3e57766a 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -39,7 +39,8 @@ import Combine from "./UI/Base/Combine"; import {SubtleButton} from "./UI/Base/SubtleButton"; import ShowTileInfo from "./UI/ShowDataLayer/ShowTileInfo"; import {Tiles} from "./Models/TileRange"; -import PerTileCountAggregator from "./UI/ShowDataLayer/PerTileCountAggregator"; +import {TileHierarchyAggregator} from "./UI/ShowDataLayer/PerTileCountAggregator"; +import {BBox} from "./Logic/GeoOperations"; export class InitUiElements { static InitAll( @@ -430,48 +431,67 @@ export class InitUiElements { return flayers; }); - const clusterCounter = new PerTileCountAggregator(State.state.locationControl.map(l => { - const z = l.zoom + 1 - if(z < 7){ - return 7 - } - return z - })) - const clusterShow = Math.min(...State.state.layoutToUse.data.layers.map(layer => layer.minzoomVisible ?? layer.minzoom)) + const layers = State.state.layoutToUse.data.layers + const clusterShow = Math.min(...layers.map(layer => layer.minzoom)) + + + const clusterCounter = TileHierarchyAggregator.createHierarchy() new ShowDataLayer({ - features: clusterCounter, + features: clusterCounter.getCountsForZoom(State.state.locationControl, State.state.layoutToUse.data.clustering.minNeededElements), leafletMap: State.state.leafletMap, layerToShow: ShowTileInfo.styling, - doShowLayer: State.state.locationControl.map(l => l.zoom < clusterShow) + doShowLayer: layers.length === 1 ? undefined : State.state.locationControl.map(l => l.zoom < clusterShow) }) + State.state.featurePipeline = new FeaturePipeline( source => { + + clusterCounter.addTile(source) + const clustering = State.state.layoutToUse.data.clustering const doShowFeatures = source.features.map( f => { const z = State.state.locationControl.data.zoom - if(z >= clustering.maxZoom){ - return true - } - if(z < source.layer.layerDef.minzoom){ + + if (z < source.layer.layerDef.minzoom) { + // Layer is always hidden for this zoom level return false; } - if(f.length > clustering.minNeededElements){ - console.log("Activating clustering for tile ", Tiles.tile_from_index(source.tileIndex)," as it has ", f.length, "features (clustering starts at)", clustering.minNeededElements) + + if (z >= clustering.maxZoom) { + return true + } + + if (f.length > clustering.minNeededElements) { + // This tile alone has too much features return false } - + + let [tileZ, tileX, tileY] = Tiles.tile_from_index(source.tileIndex); + if (tileZ >= z) { + + while (tileZ > z) { + tileZ-- + tileX = Math.floor(tileX / 2) + tileY = Math.floor(tileY / 2) + } + + if (clusterCounter.getTile(Tiles.tile_index(tileZ, tileX, tileY))?.totalValue > clustering.minNeededElements) { + return false + } + } + + + const bounds = State.state.currentBounds.data + const tilebbox = BBox.fromTileIndex(source.tileIndex) + if (!tilebbox.overlapsWith(bounds)) { + return false + } + return true - }, [State.state.locationControl] + }, [State.state.locationControl, State.state.currentBounds] ) - clusterCounter.addTile(source, doShowFeatures.map(b => !b)) - - /* - new ShowTileInfo({source: source, - leafletMap: State.state.leafletMap, - layer: source.layer.layerDef, - doShowLayer: doShowFeatures.map(b => !b) - })*/ + new ShowDataLayer( { features: source, diff --git a/Logic/FeatureSource/FeaturePipeline.ts b/Logic/FeatureSource/FeaturePipeline.ts index 1e033dad7..a24d6f516 100644 --- a/Logic/FeatureSource/FeaturePipeline.ts +++ b/Logic/FeatureSource/FeaturePipeline.ts @@ -134,6 +134,8 @@ export default class FeaturePipeline implements FeatureSourceState { layer: source.layer, minZoomLevel: 14, dontEnforceMinZoom: true, + maxFeatureCount: state.layoutToUse.data.clustering.minNeededElements, + maxZoomLevel: state.layoutToUse.data.clustering.maxZoom, registerTile: (tile) => { // We save the tile data for the given layer to local storage new SaveTileToLocalStorageActor(tile, tile.tileIndex) @@ -171,20 +173,26 @@ export default class FeaturePipeline implements FeatureSourceState { private applyMetaTags(src: FeatureSourceForLayer){ const self = this - console.log("Applying metatagging onto ", src.name) - MetaTagging.addMetatags( - src.features.data, - { - memberships: this.relationTracker, - getFeaturesWithin: (layerId, bbox: BBox) => self.GetFeaturesWithin(layerId, bbox) + console.debug("Applying metatagging onto ", src.name) + window.setTimeout( + () => { + MetaTagging.addMetatags( + src.features.data, + { + memberships: this.relationTracker, + getFeaturesWithin: (layerId, bbox: BBox) => self.GetFeaturesWithin(layerId, bbox) + }, + src.layer.layerDef, + { + includeDates: true, + // We assume that the non-dated metatags are already set by the cache generator + includeNonDates: !src.layer.layerDef.source.isOsmCacheLayer + } + ) }, - src.layer.layerDef, - { - includeDates: true, - // We assume that the non-dated metatags are already set by the cache generator - includeNonDates: !src.layer.layerDef.source.isOsmCacheLayer - } + 15 ) + } private updateAllMetaTagging() { diff --git a/Models/ThemeConfig/Json/LayoutConfigJson.ts b/Models/ThemeConfig/Json/LayoutConfigJson.ts index 856ab2736..887649fc4 100644 --- a/Models/ThemeConfig/Json/LayoutConfigJson.ts +++ b/Models/ThemeConfig/Json/LayoutConfigJson.ts @@ -228,8 +228,8 @@ export interface LayoutConfigJson { */ maxZoom?: number, /** - * The number of elements that should be showed (in total) before clustering starts to happen. - * If clustering is defined, defaults to 0 + * The number of elements per tile needed to start clustering + * If clustering is defined, defaults to 25 */ minNeededElements?: number }, diff --git a/Models/ThemeConfig/LayoutConfig.ts b/Models/ThemeConfig/LayoutConfig.ts index b632d8a29..9e6325039 100644 --- a/Models/ThemeConfig/LayoutConfig.ts +++ b/Models/ThemeConfig/LayoutConfig.ts @@ -129,17 +129,12 @@ export default class LayoutConfig { this.clustering = { maxZoom: 16, - minNeededElements: 500 + minNeededElements: 25 }; if (json.clustering) { this.clustering = { maxZoom: json.clustering.maxZoom ?? 18, - minNeededElements: json.clustering.minNeededElements ?? 1 - } - for (const layer of this.layers) { - if (layer.wayHandling !== LayerConfig.WAYHANDLING_CENTER_ONLY) { - console.debug("WARNING: In order to allow clustering, every layer must be set to CENTER_ONLY. Layer", layer.id, "does not respect this for layout", this.id); - } + minNeededElements: json.clustering.minNeededElements ?? 25 } } diff --git a/UI/ShowDataLayer/PerTileCountAggregator.ts b/UI/ShowDataLayer/PerTileCountAggregator.ts index 82e247f74..e4085f2cd 100644 --- a/UI/ShowDataLayer/PerTileCountAggregator.ts +++ b/UI/ShowDataLayer/PerTileCountAggregator.ts @@ -3,120 +3,178 @@ import {BBox} from "../../Logic/GeoOperations"; import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; import {UIEventSource} from "../../Logic/UIEventSource"; import {Tiles} from "../../Models/TileRange"; +import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"; +export class TileHierarchyAggregator implements FeatureSource { + private _parent: TileHierarchyAggregator; + private _root: TileHierarchyAggregator; + private _z: number; + private _x: number; + private _y: number; + private _tileIndex: number + private _counter: SingleTileCounter -/** - * A feature source containing meta features. - * It will contain exactly one point for every tile of the specified (dynamic) zoom level - */ -export default class PerTileCountAggregator implements FeatureSource { - public readonly features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); - public readonly name: string = "PerTileCountAggregator" + private _subtiles: [TileHierarchyAggregator, TileHierarchyAggregator, TileHierarchyAggregator, TileHierarchyAggregator] = [undefined, undefined, undefined, undefined] + public totalValue: number = 0 - private readonly perTile: Map = new Map() - private readonly _requestedZoomLevel: UIEventSource; + private static readonly empty = [] + public readonly features = new UIEventSource<{ feature: any, freshness: Date }[]>(TileHierarchyAggregator.empty) + public readonly name; - constructor(requestedZoomLevel: UIEventSource) { - this._requestedZoomLevel = requestedZoomLevel; - const self = this; - this._requestedZoomLevel.addCallbackAndRun(_ => self.update()) + private readonly featuresStatic = [] + private readonly featureProperties: { count: number, tileId: number }; + + private constructor(parent: TileHierarchyAggregator, z: number, x: number, y: number) { + this._parent = parent; + this._root = parent?._root ?? this + this._z = z; + this._x = x; + this._y = y; + this._tileIndex = Tiles.tile_index(z, x, y) + this.name = "Count(" + this._tileIndex + ")" + + const totals = { + tileId: this._tileIndex, + count: 0 + } + this.featureProperties = totals + + const now = new Date() + const feature = { + "type": "Feature", + "properties": totals, + "geometry": { + "type": "Point", + "coordinates": Tiles.centerPointOf(z, x, y) + } + } + this.featuresStatic.push({feature: feature, freshness: now}) + + const bbox = BBox.fromTile(z, x, y) + const box = { + "type": "Feature", + "properties": totals, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [bbox.minLon, bbox.minLat], + [bbox.minLon, bbox.maxLat], + [bbox.maxLon, bbox.maxLat], + [bbox.maxLon, bbox.minLat], + [bbox.minLon, bbox.minLat] + ] + ] + } + } + this.featuresStatic.push({feature: box, freshness: now}) + } + + public getTile(tileIndex): TileHierarchyAggregator { + if (tileIndex === this._tileIndex) { + return this; + } + let [tileZ, tileX, tileY] = Tiles.tile_from_index(tileIndex) + while (tileZ - 1 > this._z) { + tileX = Math.floor(tileX / 2) + tileY = Math.floor(tileY / 2) + tileZ-- + } + const xDiff = tileX - (2 * this._x) + const yDiff = tileY - (2 * this._y) + const subtileIndex = yDiff * 2 + xDiff; + return this._subtiles[subtileIndex]?.getTile(tileIndex) } private update() { - const now = new Date() - const allCountsAsFeatures : {feature: any, freshness: Date}[] = [] - const aggregate = this.calculatePerTileCount() - aggregate.forEach((totalsPerLayer, tileIndex) => { - const totals = {} - let totalCount = 0 - totalsPerLayer.forEach((total, layerId) => { - totals[layerId] = total - totalCount += total - }) - totals["tileId"] = tileIndex - totals["count"] = totalCount - const feature = { - "type": "Feature", - "properties": totals, - "geometry": { - "type": "Point", - "coordinates": Tiles.centerPointOf(...Tiles.tile_from_index(tileIndex)) - } - } - allCountsAsFeatures.push({feature: feature, freshness: now}) - - const bbox= BBox.fromTileIndex(tileIndex) - const box = { - "type": "Feature", - "properties":totals, - "geometry": { - "type": "Polygon", - "coordinates": [ - [ - [bbox.minLon, bbox.minLat], - [bbox.minLon, bbox.maxLat], - [bbox.maxLon, bbox.maxLat], - [bbox.maxLon, bbox.minLat], - [bbox.minLon, bbox.minLat] - ] - ] - } - } - allCountsAsFeatures.push({feature:box, freshness: now}) + const newMap = new Map() + let total = 0 + this?._counter?.countsPerLayer?.data?.forEach((count, layerId) => { + newMap.set(layerId, count) + total += count }) - this.features.setData(allCountsAsFeatures) - } - /** - * Calculates an aggregate count per tile and per subtile - * @private - */ - private calculatePerTileCount() { - const perTileCount = new Map>() - const targetZoom = this._requestedZoomLevel.data; - // We only search for tiles of the same zoomlevel or a higher zoomlevel, which is embedded - for (const singleTileCounter of Array.from(this.perTile.values())) { - - let tileZ = singleTileCounter.z - let tileX = singleTileCounter.x - let tileY = singleTileCounter.y - if (tileZ < targetZoom) { + for (const tile of this._subtiles) { + if (tile === undefined) { continue; } + total += tile.totalValue + } + this.totalValue = total + this._parent?.update() + + if (total === 0) { + this.features.setData(TileHierarchyAggregator.empty) + } else { + this.featureProperties.count = total; + this.features.data = this.featuresStatic + this.features.ping() + } + } - while (tileZ > targetZoom) { + public addTile(source: FeatureSourceForLayer & Tiled) { + const self = this; + if (source.tileIndex === this._tileIndex) { + if (this._counter === undefined) { + this._counter = new SingleTileCounter(this._tileIndex) + this._counter.countsPerLayer.addCallbackAndRun(_ => self.update()) + } + this._counter.addTileCount(source) + } else { + + // We have to give it to one of the subtiles + let [tileZ, tileX, tileY] = Tiles.tile_from_index(source.tileIndex) + while (tileZ - 1 > this._z) { tileX = Math.floor(tileX / 2) tileY = Math.floor(tileY / 2) tileZ-- } - const tileI = Tiles.tile_index(tileZ, tileX, tileY) - let counts = perTileCount.get(tileI) - if (counts === undefined) { - counts = new Map() - perTileCount.set(tileI, counts) + const xDiff = tileX - (2 * this._x) + const yDiff = tileY - (2 * this._y) + + const subtileIndex = yDiff * 2 + xDiff; + if (this._subtiles[subtileIndex] === undefined) { + this._subtiles[subtileIndex] = new TileHierarchyAggregator(this, tileZ, tileX, tileY) } - singleTileCounter.countsPerLayer.data.forEach((count, layerId) => { - if (counts.has(layerId)) { - counts.set(layerId, count + counts.get(layerId)) - } else { - counts.set(layerId, count) - } + this._subtiles[subtileIndex].addTile(source) + } + + } + + public static createHierarchy() { + return new TileHierarchyAggregator(undefined, 0, 0, 0) + } + + + private visitSubTiles(f : (aggr: TileHierarchyAggregator) => boolean){ + const visitFurther = f(this) + if(visitFurther){ + this._subtiles.forEach(tile => tile?.visitSubTiles(f)) + } + } + + getCountsForZoom(locationControl: UIEventSource<{ zoom : number }>, cutoff: number) : FeatureSource{ + const self = this + return new StaticFeatureSource( + locationControl.map(loc => { + const features = [] + const targetZoom = loc.zoom + self.visitSubTiles(aggr => { + if(aggr.totalValue < cutoff) { + return false + } + if(aggr._z === targetZoom){ + features.push(...aggr.features.data) + return false + } + return aggr._z <= targetZoom; + + }) + + return features }) - } - return perTileCount; + , true); } - - public addTile(tile: FeatureSourceForLayer & Tiled, shouldBeCounted: UIEventSource) { - let counter = this.perTile.get(tile.tileIndex) - if (counter === undefined) { - counter = new SingleTileCounter(tile.tileIndex) - this.perTile.set(tile.tileIndex, counter) - // We do **NOT** add a callback on the perTile index, even though we could! It'll update just fine without it - } - counter.addTileCount(tile, shouldBeCounted) - } - - } /** @@ -131,6 +189,7 @@ class SingleTileCounter implements Tiled { public readonly x: number public readonly y: number + constructor(tileIndex: number) { this.tileIndex = tileIndex this.bbox = BBox.fromTileIndex(tileIndex) @@ -140,17 +199,16 @@ class SingleTileCounter implements Tiled { this.y = y } - public addTileCount(source: FeatureSourceForLayer, shouldBeCounted: UIEventSource) { + public addTileCount(source: FeatureSourceForLayer) { const layer = source.layer.layerDef this.registeredLayers.set(layer.id, layer) const self = this + source.features.map(f => { - /*if (!shouldBeCounted.data) { - return; - }*/ self.countsPerLayer.data.set(layer.id, f.length) self.countsPerLayer.ping() - }, [shouldBeCounted]) + }) + } } \ No newline at end of file diff --git a/UI/ShowDataLayer/ShowDataLayer.ts b/UI/ShowDataLayer/ShowDataLayer.ts index 278ea3597..0d02bcd4e 100644 --- a/UI/ShowDataLayer/ShowDataLayer.ts +++ b/UI/ShowDataLayer/ShowDataLayer.ts @@ -17,6 +17,7 @@ export default class ShowDataLayer { // Used to generate a fresh ID when needed private _cleanCount = 0; private geoLayer = undefined; + private isDirty = false; /** * If the selected element triggers, this is used to lookup the correct layer and to open the popup @@ -37,9 +38,30 @@ export default class ShowDataLayer { this._layerToShow = options.layerToShow; const self = this; + options.leafletMap.addCallbackAndRunD(_ => { + self.update(options) + } + ); + features.addCallback(_ => self.update(options)); - options.leafletMap.addCallback(_ => self.update(options)); - this.update(options); + options.doShowLayer?.addCallbackAndRun(doShow => { + const mp = options.leafletMap.data; + if (mp == undefined) { + return; + } + if (doShow) { + if (self.isDirty) { + self.update(options) + } else { + mp.addLayer(this.geoLayer) + } + } else { + if(this.geoLayer !== undefined){ + mp.removeLayer(this.geoLayer) + } + } + + }) State.state.selectedElement.addCallbackAndRunD(selected => { if (self._leafletMap.data === undefined) { @@ -68,26 +90,16 @@ export default class ShowDataLayer { } }) - options.doShowLayer?.addCallbackAndRun(doShow => { - const mp = options.leafletMap.data; - if (this.geoLayer == undefined || mp == undefined) { - return; - } - if (doShow) { - mp.addLayer(this.geoLayer) - } else { - mp.removeLayer(this.geoLayer) - } - - - }) - } - private update(options) { + private update(options: ShowDataLayerOptions) { if (this._features.data === undefined) { return; } + this.isDirty = true; + if (options?.doShowLayer?.data === false) { + return; + } const mp = options.leafletMap.data; if (mp === undefined) { @@ -99,7 +111,18 @@ export default class ShowDataLayer { mp.removeLayer(this.geoLayer); } - this.geoLayer = this.CreateGeojsonLayer() + const self = this; + const data = { + type: "FeatureCollection", + features: [] + } + // @ts-ignore + this.geoLayer = L.geoJSON(data, { + style: feature => self.createStyleFor(feature), + pointToLayer: (feature, latLng) => self.pointToLayer(feature, latLng), + onEachFeature: (feature, leafletLayer) => self.postProcessFeature(feature, leafletLayer) + }); + const allFeats = this._features.data; for (const feat of allFeats) { if (feat === undefined) { @@ -123,6 +146,7 @@ export default class ShowDataLayer { if (options.doShowLayer?.data ?? true) { mp.addLayer(this.geoLayer) } + this.isDirty = false; } @@ -143,7 +167,7 @@ export default class ShowDataLayer { return; } - const tagSource = feature.properties.id === undefined ? new UIEventSource(feature.properties) : + const tagSource = feature.properties.id === undefined ? new UIEventSource(feature.properties) : State.state.allElements.getEventSourceById(feature.properties.id) const clickable = !(layer.title === undefined && (layer.tagRenderings ?? []).length === 0) const style = layer.GenerateLeafletStyle(tagSource, clickable); @@ -218,19 +242,4 @@ export default class ShowDataLayer { } - private CreateGeojsonLayer(): L.Layer { - const self = this; - const data = { - type: "FeatureCollection", - features: [] - } - // @ts-ignore - return L.geoJSON(data, { - style: feature => self.createStyleFor(feature), - pointToLayer: (feature, latLng) => self.pointToLayer(feature, latLng), - onEachFeature: (feature, leafletLayer) => self.postProcessFeature(feature, leafletLayer) - }); - - } - } \ No newline at end of file diff --git a/assets/layers/tree_node/tree_node.json b/assets/layers/tree_node/tree_node.json index bba09af12..59c1d03c1 100644 --- a/assets/layers/tree_node/tree_node.json +++ b/assets/layers/tree_node/tree_node.json @@ -7,7 +7,7 @@ "ru": "Дерево", "fr": "Arbre" }, - "minzoom": 14, + "minzoom": 16, "source": { "osmTags": { "and": [ diff --git a/assets/themes/trees/trees.json b/assets/themes/trees/trees.json index 52961293a..c609a43f1 100644 --- a/assets/themes/trees/trees.json +++ b/assets/themes/trees/trees.json @@ -45,10 +45,11 @@ "startLat": 50.642, "startLon": 4.482, "startZoom": 8, - "widenFactor": 1.5, + "widenFactor": 1.01, "socialImage": "./assets/themes/trees/logo.svg", "clustering": { - "maxZoom": 18 + "maxZoom": 19, + "minNeededElements": 25 }, "layers": [ "tree_node" From 38037014b08cc0675ffa491606bcbdafb641d891 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 27 Sep 2021 15:38:12 +0200 Subject: [PATCH 33/65] Fix bug in bounds calculation for negative lats/lons --- InitUiElements.ts | 7 ++--- Logic/GeoOperations.ts | 27 ++++++++++++++--- Logic/SimpleMetaTagger.ts | 3 ++ UI/Base/Minimap.ts | 4 ++- test.ts | 61 ++++++++++++++------------------------ test/GeoOperations.spec.ts | 14 +++++++-- 6 files changed, 65 insertions(+), 51 deletions(-) diff --git a/InitUiElements.ts b/InitUiElements.ts index c3e57766a..19f1e3340 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -41,6 +41,7 @@ import ShowTileInfo from "./UI/ShowDataLayer/ShowTileInfo"; import {Tiles} from "./Models/TileRange"; import {TileHierarchyAggregator} from "./UI/ShowDataLayer/PerTileCountAggregator"; import {BBox} from "./Logic/GeoOperations"; +import StaticFeatureSource from "./Logic/FeatureSource/Sources/StaticFeatureSource"; export class InitUiElements { static InitAll( @@ -421,9 +422,6 @@ export class InitUiElements { const flayer = { isDisplayed: isDisplayed, layerDef: layer, - isSufficientlyZoomed: state.locationControl.map(l => { - return l.zoom >= (layer.minzoomVisible ?? layer.minzoom) - }), appliedFilters: new UIEventSource(undefined), }; flayers.push(flayer); @@ -491,7 +489,7 @@ export class InitUiElements { return true }, [State.state.locationControl, State.state.currentBounds] ) - + new ShowDataLayer( { features: source, @@ -502,7 +500,6 @@ export class InitUiElements { ); }, state ); - } private static setupAllLayerElements() { diff --git a/Logic/GeoOperations.ts b/Logic/GeoOperations.ts index dd806ded4..cfef09e5d 100644 --- a/Logic/GeoOperations.ts +++ b/Logic/GeoOperations.ts @@ -388,10 +388,10 @@ export class BBox { static global: BBox = new BBox([[-180, -90], [180, 90]]); constructor(coordinates) { - this.maxLat = Number.MIN_VALUE; - this.maxLon = Number.MIN_VALUE; - this.minLat = Number.MAX_VALUE; - this.minLon = Number.MAX_VALUE; + this.maxLat = -90; + this.maxLon = -180; + this.minLat = 90; + this.minLon = 180; for (const coordinate of coordinates) { @@ -491,4 +491,23 @@ export class BBox { toLeaflet() { return [[this.minLat, this.minLon], [this.maxLat, this.maxLon]] } + + asGeoJson(properties: any) : any{ + return { + type:"Feature", + properties: properties, + geometry:{ + type:"Polygon", + coordinates:[[ + + [this.minLon, this.minLat], + [this.maxLon, this.minLat], + [this.maxLon, this.maxLat], + [this.minLon, this.maxLat], + [this.minLon, this.minLat], + + ]] + } + } + } } \ No newline at end of file diff --git a/Logic/SimpleMetaTagger.ts b/Logic/SimpleMetaTagger.ts index b74f0f542..a938e9c72 100644 --- a/Logic/SimpleMetaTagger.ts +++ b/Logic/SimpleMetaTagger.ts @@ -97,6 +97,9 @@ export default class SimpleMetaTagger { continue; } for (const unit of units) { + if(unit === undefined){ + continue + } if (unit.appliesToKeys === undefined) { console.error("The unit ", unit, "has no appliesToKey defined") continue diff --git a/UI/Base/Minimap.ts b/UI/Base/Minimap.ts index 963d39db1..e276c8281 100644 --- a/UI/Base/Minimap.ts +++ b/UI/Base/Minimap.ts @@ -30,6 +30,8 @@ export default class Minimap { /** * Construct a minimap */ - public static createMiniMap: (options: MinimapOptions) => (BaseUIElement & MinimapObj) + public static createMiniMap: (options: MinimapOptions) => (BaseUIElement & MinimapObj) = (_) => { + throw "CreateMinimap hasn't been initialized yet. Please call MinimapImplementation.initialize()" + } } \ No newline at end of file diff --git a/test.ts b/test.ts index 86a1c8f6e..c70e45da5 100644 --- a/test.ts +++ b/test.ts @@ -5,46 +5,29 @@ import MinimapImplementation from "./UI/Base/MinimapImplementation"; import {UIEventSource} from "./Logic/UIEventSource"; import FilteredLayer from "./Models/FilteredLayer"; import {And} from "./Logic/Tags/And"; +import ShowDataLayer from "./UI/ShowDataLayer/ShowDataLayer"; +import ShowTileInfo from "./UI/ShowDataLayer/ShowTileInfo"; +import StaticFeatureSource from "./Logic/FeatureSource/Sources/StaticFeatureSource"; +import {BBox} from "./Logic/GeoOperations"; +import Minimap from "./UI/Base/Minimap"; -const layout = AllKnownLayouts.allKnownLayouts.get("cyclestreets") -State.state = new State(layout) +State.state = new State(undefined) + +const leafletMap = new UIEventSource(undefined) MinimapImplementation.initialize() -const feature = { - "type": "Feature", - "properties": { - id: "way/1234", - "highway":"residential", - "cyclestreet":"yes" - }, - "geometry": { - "type": "LineString", - "coordinates": [ - [ - 3.2207107543945312, - 51.21978729870313 - ], - [ - 3.2198524475097656, - 51.21899435057332 - ], - [ - 3.2155394554138184, - 51.21617188199714 - ] - ] - } -} +Minimap.createMiniMap({ + leafletMap: leafletMap, +}).SetStyle("height: 600px; width: 600px") + .AttachTo("maindiv") -State.state.allElements.addOrGetElement(feature) -State.state.filteredLayers = new UIEventSource( - layout.layers.map( l => ({ - layerDef :l, - appliedFilters: new UIEventSource(undefined), - isDisplayed: new UIEventSource(undefined) - })) -) +const bbox = BBox.fromTile(16,32754,21785).asGeoJson({ + count: 42, + tileId: 42 +}) -const splitroad = new SplitRoadWizard("way/1234") - splitroad.AttachTo("maindiv") - -splitroad.dialogIsOpened.setData(true) +console.log(bbox) +new ShowDataLayer({ + layerToShow: ShowTileInfo.styling, + leafletMap: leafletMap, + features: new StaticFeatureSource([ bbox], false) +}) \ No newline at end of file diff --git a/test/GeoOperations.spec.ts b/test/GeoOperations.spec.ts index 7a556b20d..49447afd5 100644 --- a/test/GeoOperations.spec.ts +++ b/test/GeoOperations.spec.ts @@ -1,7 +1,8 @@ import {Utils} from "../Utils"; import * as Assert from "assert"; import T from "./TestHelper"; -import {GeoOperations} from "../Logic/GeoOperations"; +import {BBox, GeoOperations} from "../Logic/GeoOperations"; +import {equal} from "assert"; Utils.runningFromConsole = true; @@ -176,7 +177,16 @@ export default class GeoOperationsSpec extends T { const overlap = GeoOperations.calculateOverlap(point, [GeoOperationsSpec.polygon]); Assert.equal(1, overlap.length) - }] + }], + ["bbox bounds test", + () => { + const bbox = BBox.fromTile(16, 32754, 21785) + equal(-0.0714111328125, bbox.minLon) + equal(-0.076904296875, bbox.maxLon) + equal(51.53266860674158, bbox.minLat) + equal(51.5292513551899, bbox.maxLat) + } + ] ] ) From 0a9e7c0b36ce7609a9fd7eec5ab64f24084e5b0c Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 27 Sep 2021 18:35:32 +0200 Subject: [PATCH 34/65] Fix bbox bug, add ids to filters, add filter state to the URL --- InitUiElements.ts | 37 +++++++-- .../Sources/FilteringFeatureSource.ts | 18 ++-- Logic/MetaTagging.ts | 1 + Models/Constants.ts | 2 +- Models/FilteredLayer.ts | 3 +- Models/ThemeConfig/FilterConfig.ts | 12 ++- Models/ThemeConfig/Json/FilterConfigJson.ts | 4 + UI/BigComponents/FilterView.ts | 83 +++++++++++++------ UI/BigComponents/SimpleAddUI.ts | 4 +- assets/layers/birdhide/birdhide.json | 2 + assets/layers/cafe_pub/cafe_pub.json | 1 + .../charging_station/charging_station.json | 3 + .../charging_station.protojson | 2 + assets/layers/charging_station/csvToJson.ts | 1 + assets/layers/food/food.json | 4 + .../layers/nature_reserve/nature_reserve.json | 2 + .../public_bookcase/public_bookcase.json | 3 + assets/layers/toilet/toilet.json | 3 + .../themes/cycle_highways/cycle_highways.json | 6 ++ .../housenumber_unknown_small.svg | 60 ++++++++++++++ assets/themes/uk_addresses/license_info.json | 8 ++ assets/themes/uk_addresses/uk_addresses.json | 40 ++++++--- test/GeoOperations.spec.ts | 8 +- 23 files changed, 248 insertions(+), 59 deletions(-) create mode 100644 assets/themes/uk_addresses/housenumber_unknown_small.svg diff --git a/InitUiElements.ts b/InitUiElements.ts index 19f1e3340..f3593556f 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -42,6 +42,8 @@ import {Tiles} from "./Models/TileRange"; import {TileHierarchyAggregator} from "./UI/ShowDataLayer/PerTileCountAggregator"; import {BBox} from "./Logic/GeoOperations"; import StaticFeatureSource from "./Logic/FeatureSource/Sources/StaticFeatureSource"; +import FilterConfig from "./Models/ThemeConfig/FilterConfig"; +import FilteredLayer from "./Models/FilteredLayer"; export class InitUiElements { static InitAll( @@ -406,8 +408,10 @@ export class InitUiElements { private static InitLayers(): void { const state = State.state; + const empty = [] + state.filteredLayers = state.layoutToUse.map((layoutToUse) => { - const flayers = []; + const flayers: FilteredLayer[] = []; for (const layer of layoutToUse.layers) { const isDisplayed = QueryParameters.GetQueryParameter( @@ -422,30 +426,47 @@ export class InitUiElements { const flayer = { isDisplayed: isDisplayed, layerDef: layer, - appliedFilters: new UIEventSource(undefined), + appliedFilters: new UIEventSource<{ filter: FilterConfig, selected: number }[]>([]), }; + + if (layer.filters.length > 0) { + const filtersPerName = new Map() + layer.filters.forEach(f => filtersPerName.set(f.id, f)) + const qp = QueryParameters.GetQueryParameter("filter-" + layer.id, "","Filtering state for a layer") + flayer.appliedFilters.map(filters => { + filters = filters ?? [] + return filters.map(f => f.filter.id + "." + f.selected).join(",") + }, [], textual => { + if(textual.length === 0){ + return empty + } + return textual.split(",").map(part => { + const [filterId, selected] = part.split("."); + return {filter: filtersPerName.get(filterId), selected: Number(selected)} + }).filter(f => f.filter !== undefined && !isNaN(f.selected)) + }).syncWith(qp, true) + } + flayers.push(flayer); } return flayers; }); + const layers = State.state.layoutToUse.data.layers - const clusterShow = Math.min(...layers.map(layer => layer.minzoom)) - - + const clusterCounter = TileHierarchyAggregator.createHierarchy() new ShowDataLayer({ features: clusterCounter.getCountsForZoom(State.state.locationControl, State.state.layoutToUse.data.clustering.minNeededElements), leafletMap: State.state.leafletMap, layerToShow: ShowTileInfo.styling, - doShowLayer: layers.length === 1 ? undefined : State.state.locationControl.map(l => l.zoom < clusterShow) }) State.state.featurePipeline = new FeaturePipeline( source => { clusterCounter.addTile(source) - + const clustering = State.state.layoutToUse.data.clustering const doShowFeatures = source.features.map( f => { @@ -489,7 +510,7 @@ export class InitUiElements { return true }, [State.state.locationControl, State.state.currentBounds] ) - + new ShowDataLayer( { features: source, diff --git a/Logic/FeatureSource/Sources/FilteringFeatureSource.ts b/Logic/FeatureSource/Sources/FilteringFeatureSource.ts index 70d5a566c..65c6df0ec 100644 --- a/Logic/FeatureSource/Sources/FilteringFeatureSource.ts +++ b/Logic/FeatureSource/Sources/FilteringFeatureSource.ts @@ -5,13 +5,14 @@ import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; import Hash from "../../Web/Hash"; import {BBox} from "../../GeoOperations"; -export default class FilteringFeatureSource implements FeatureSourceForLayer , Tiled { +export default class FilteringFeatureSource implements FeatureSourceForLayer, Tiled { public features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); public readonly name; public readonly layer: FilteredLayer; -public readonly tileIndex : number - public readonly bbox : BBox + public readonly tileIndex: number + public readonly bbox: BBox + constructor( state: { locationControl: UIEventSource<{ zoom: number }>, @@ -21,7 +22,7 @@ public readonly tileIndex : number upstream: FeatureSourceForLayer ) { const self = this; - this.name = "FilteringFeatureSource("+upstream.name+")" + this.name = "FilteringFeatureSource(" + upstream.name + ")" this.tileIndex = tileIndex this.bbox = BBox.fromTileIndex(tileIndex) @@ -50,12 +51,15 @@ public readonly tileIndex : number } const tagsFilter = layer.appliedFilters.data; - if (tagsFilter) { - if (!tagsFilter.matchesProperties(f.feature.properties)) { + for (const filter of tagsFilter ?? []) { + const neededTags = filter.filter.options[filter.selected].osmTags + if (!neededTags.matchesProperties(f.feature.properties)) { // Hidden by the filter on the layer itself - we want to hide it no matter wat return false; } } + + if (!layer.isDisplayed) { // The layer itself is either disabled or hidden due to zoom constraints // We should return true, but it might still match some other layer @@ -80,7 +84,7 @@ public readonly tileIndex : number }); layer.appliedFilters.addCallback(_ => { - if(!layer.isDisplayed.data){ + if (!layer.isDisplayed.data) { // Currently not shown. // Note that a change in 'isSHown' will trigger an update as well, so we don't have to watch it another time return; diff --git a/Logic/MetaTagging.ts b/Logic/MetaTagging.ts index c02ed04e4..2a85e6292 100644 --- a/Logic/MetaTagging.ts +++ b/Logic/MetaTagging.ts @@ -150,6 +150,7 @@ export default class MetaTagging { for (const f of functions) { f(params, feature); } + State.state.allElements.getEventSourceById(feature.properties.id).ping(); } catch (e) { console.error("While calculating a tag value: ", e) } diff --git a/Models/Constants.ts b/Models/Constants.ts index 7f1b0c8de..91c9e0015 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.10.0-alpha-2"; + public static vNumber = "0.10.0-alpha-3"; public static ImgurApiKey = '7070e7167f0a25a' // The user journey states thresholds when a new feature gets unlocked diff --git a/Models/FilteredLayer.ts b/Models/FilteredLayer.ts index 6c387270f..68ffb4483 100644 --- a/Models/FilteredLayer.ts +++ b/Models/FilteredLayer.ts @@ -1,9 +1,10 @@ import {UIEventSource} from "../Logic/UIEventSource"; import LayerConfig from "./ThemeConfig/LayerConfig"; import {And} from "../Logic/Tags/And"; +import FilterConfig from "./ThemeConfig/FilterConfig"; export default interface FilteredLayer { readonly isDisplayed: UIEventSource; - readonly appliedFilters: UIEventSource; + readonly appliedFilters: UIEventSource<{filter: FilterConfig, selected: number}[]>; readonly layerDef: LayerConfig; } \ No newline at end of file diff --git a/Models/ThemeConfig/FilterConfig.ts b/Models/ThemeConfig/FilterConfig.ts index 464919d76..2dd9f69d6 100644 --- a/Models/ThemeConfig/FilterConfig.ts +++ b/Models/ThemeConfig/FilterConfig.ts @@ -5,7 +5,8 @@ import Translations from "../../UI/i18n/Translations"; import {TagUtils} from "../../Logic/Tags/TagUtils"; export default class FilterConfig { - readonly options: { + public readonly id: string + public readonly options: { question: Translation; osmTags: TagsFilter; }[]; @@ -14,11 +15,18 @@ export default class FilterConfig { if (json.options === undefined) { throw `A filter without options was given at ${context}` } + if (json.id === undefined) { + throw `A filter without id was found at ${context}` + } + if(json.id.match(/^[a-zA-Z0-9_-]*$/) === null){ + throw `A filter with invalid id was found at ${context}. Ids should only contain letters, numbers or - _` + + } if (json.options.map === undefined) { throw `A filter was given where the options aren't a list at ${context}` } - + this.id = json.id; this.options = json.options.map((option, i) => { const question = Translations.T( option.question, diff --git a/Models/ThemeConfig/Json/FilterConfigJson.ts b/Models/ThemeConfig/Json/FilterConfigJson.ts index c49f9f3eb..7151e3854 100644 --- a/Models/ThemeConfig/Json/FilterConfigJson.ts +++ b/Models/ThemeConfig/Json/FilterConfigJson.ts @@ -1,6 +1,10 @@ import {AndOrTagConfigJson} from "./TagConfigJson"; export default interface FilterConfigJson { + /** + * An id/name for this filter, used to set the URL parameters + */ + id: string, /** * The options for a filter * If there are multiple options these will be a list of radio buttons diff --git a/UI/BigComponents/FilterView.ts b/UI/BigComponents/FilterView.ts index 6e3fae5f7..249b3dacb 100644 --- a/UI/BigComponents/FilterView.ts +++ b/UI/BigComponents/FilterView.ts @@ -7,8 +7,6 @@ import Combine from "../Base/Combine"; import Translations from "../i18n/Translations"; import {Translation} from "../i18n/Translation"; import Svg from "../../Svg"; -import {TagsFilter} from "../../Logic/Tags/TagsFilter"; -import {And} from "../../Logic/Tags/And"; import {UIEventSource} from "../../Logic/UIEventSource"; import BaseUIElement from "../BaseUIElement"; import State from "../../State"; @@ -16,11 +14,6 @@ import FilteredLayer from "../../Models/FilteredLayer"; import BackgroundSelector from "./BackgroundSelector"; import FilterConfig from "../../Models/ThemeConfig/FilterConfig"; - -/** - * Shows the filter - */ - export default class FilterView extends VariableUiElement { constructor(filteredLayer: UIEventSource) { const backgroundSelector = new Toggle( @@ -101,26 +94,52 @@ export default class FilterView extends VariableUiElement { return undefined; } - let listFilterElements: [BaseUIElement, UIEventSource][] = layer.filters.map( + const filterIndexes = new Map() + layer.filters.forEach((f, i) => filterIndexes.set(f.id, i)) + + let listFilterElements: [BaseUIElement, UIEventSource<{ filter: FilterConfig, selected: number }>][] = layer.filters.map( FilterView.createFilter ); - const update = () => { - let listTagsFilters = Utils.NoNull( - listFilterElements.map((input) => input[1].data) - ); - flayer.appliedFilters.setData(new And(listTagsFilters)); - }; + listFilterElements.forEach((inputElement, i) => + inputElement[1].addCallback((changed) => { + const oldValue = flayer.appliedFilters.data + + if(changed === undefined){ + // Lets figure out which filter should be removed + // We know this inputElement corresponds with layer.filters[i] + // SO, if there is a value in 'oldValue' with this filter, we have to recalculated + if(!oldValue.some(f => f.filter === layer.filters[i])){ + // The filter to remove is already gone, we can stop + return; + } + }else if(oldValue.some(f => f.filter === changed.filter && f.selected === changed.selected)){ + // The changed value is already there + return; + } + const listTagsFilters = Utils.NoNull( + listFilterElements.map((input) => input[1].data) + ); - listFilterElements.forEach((inputElement) => - inputElement[1].addCallback((_) => update()) + console.log(listTagsFilters, oldValue) + flayer.appliedFilters.setData(listTagsFilters); + }) ); flayer.appliedFilters.addCallbackAndRun(appliedFilters => { - if (appliedFilters === undefined || appliedFilters.and.length === 0) { - listFilterElements.forEach(filter => filter[1].setData(undefined)) - return + for (let i = 0; i < layer.filters.length; i++){ + const filter = layer.filters[i]; + let foundMatch = undefined + for (const appliedFilter of appliedFilters) { + if(appliedFilter.filter === filter){ + foundMatch = appliedFilter + break; + } + } + + listFilterElements[i][1].setData(foundMatch) } + }) return new Combine(listFilterElements.map(input => input[0].SetClass("mt-3"))) @@ -128,7 +147,7 @@ export default class FilterView extends VariableUiElement { } - private static createFilter(filterConfig: FilterConfig): [BaseUIElement, UIEventSource] { + private static createFilter(filterConfig: FilterConfig): [BaseUIElement, UIEventSource<{ filter: FilterConfig, selected: number }>] { if (filterConfig.options.length === 1) { let option = filterConfig.options[0]; @@ -142,20 +161,36 @@ export default class FilterView extends VariableUiElement { .ToggleOnClick() .SetClass("block m-1") - return [toggle, toggle.isEnabled.map(enabled => enabled ? option.osmTags : undefined, [], tags => tags !== undefined)] + const selected = { + filter: filterConfig, + selected: 0 + } + return [toggle, toggle.isEnabled.map(enabled => enabled ? selected : undefined, [], + f => f?.filter === filterConfig && f?.selected === 0) + ] } let options = filterConfig.options; + const values = options.map((f, i) => ({ + filter: filterConfig, selected: i + })) const radio = new RadioButton( options.map( - (option) => - new FixedInputElement(option.question.Clone(), option.osmTags) + (option, i) => + new FixedInputElement(option.question.Clone(), i) ), { dontStyle: true } ); - return [radio, radio.GetValue()] + return [radio, + radio.GetValue().map( + i => values[i], + [], + selected => { + return selected?.selected + } + )] } } diff --git a/UI/BigComponents/SimpleAddUI.ts b/UI/BigComponents/SimpleAddUI.ts index fb2c93a0a..5dca2cfc2 100644 --- a/UI/BigComponents/SimpleAddUI.ts +++ b/UI/BigComponents/SimpleAddUI.ts @@ -223,14 +223,14 @@ export default class SimpleAddUI extends Toggle { ] ).SetClass("flex flex-col") ).onClick(() => { - preset.layerToAddTo.appliedFilters.setData(new And([])) + preset.layerToAddTo.appliedFilters.setData([]) cancel() }) const disableFiltersOrConfirm = new Toggle( openLayerOrConfirm, disableFilter, - preset.layerToAddTo.appliedFilters.map(filters => filters === undefined || filters.normalize().and.length === 0) + preset.layerToAddTo.appliedFilters.map(filters => filters === undefined || filters.length === 0) ) diff --git a/assets/layers/birdhide/birdhide.json b/assets/layers/birdhide/birdhide.json index 01e2853f9..1a581b8a0 100644 --- a/assets/layers/birdhide/birdhide.json +++ b/assets/layers/birdhide/birdhide.json @@ -258,6 +258,7 @@ "wayHandling": 1, "filter": [ { + "id": "wheelchair", "options": [ { "question": { @@ -275,6 +276,7 @@ ] }, { + "id": "shelter", "options": [ { "question": { diff --git a/assets/layers/cafe_pub/cafe_pub.json b/assets/layers/cafe_pub/cafe_pub.json index 803d39ffa..e5977e8bb 100644 --- a/assets/layers/cafe_pub/cafe_pub.json +++ b/assets/layers/cafe_pub/cafe_pub.json @@ -170,6 +170,7 @@ ], "filter": [ { + "id": "opened-now", "options": [ { "question": { diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json index ae3a12b1d..f3caa2321 100644 --- a/assets/layers/charging_station/charging_station.json +++ b/assets/layers/charging_station/charging_station.json @@ -2627,6 +2627,7 @@ "wayHandling": 1, "filter": [ { + "id": "vehicle-type", "options": [ { "question": { @@ -2656,6 +2657,7 @@ ] }, { + "id": "working", "options": [ { "question": { @@ -2671,6 +2673,7 @@ ] }, { + "id": "connection_type", "options": [ { "question": { diff --git a/assets/layers/charging_station/charging_station.protojson b/assets/layers/charging_station/charging_station.protojson index 111afe533..73aced6ad 100644 --- a/assets/layers/charging_station/charging_station.protojson +++ b/assets/layers/charging_station/charging_station.protojson @@ -648,6 +648,7 @@ "wayHandling": 1, "filter": [ { + "id": "vehicle-type", "options": [ { "question": { @@ -677,6 +678,7 @@ ] }, { + "id": "working", "options": [ { "question": { diff --git a/assets/layers/charging_station/csvToJson.ts b/assets/layers/charging_station/csvToJson.ts index 08e33a229..4a5b04f53 100644 --- a/assets/layers/charging_station/csvToJson.ts +++ b/assets/layers/charging_station/csvToJson.ts @@ -242,6 +242,7 @@ function run(file, protojson) { }) proto["filter"].push({ + id:"connection_type", options: filterOptions }) diff --git a/assets/layers/food/food.json b/assets/layers/food/food.json index c05bb6453..1bac9814d 100644 --- a/assets/layers/food/food.json +++ b/assets/layers/food/food.json @@ -560,6 +560,7 @@ ], "filter": [ { + "id": "opened-now", "options": [ { "question": { @@ -571,6 +572,7 @@ ] }, { + "id": "vegetarian", "options": [ { "question": { @@ -589,6 +591,7 @@ ] }, { + "id": "vegan", "options": [ { "question": { @@ -605,6 +608,7 @@ ] }, { + "id": "halal", "options": [ { "question": { diff --git a/assets/layers/nature_reserve/nature_reserve.json b/assets/layers/nature_reserve/nature_reserve.json index 5a3551d52..dab52299c 100644 --- a/assets/layers/nature_reserve/nature_reserve.json +++ b/assets/layers/nature_reserve/nature_reserve.json @@ -423,6 +423,7 @@ ], "filter": [ { + "id": "access", "options": [ { "question": { @@ -433,6 +434,7 @@ ] }, { + "id": "dogs", "options": [ { "question": { diff --git a/assets/layers/public_bookcase/public_bookcase.json b/assets/layers/public_bookcase/public_bookcase.json index d5576a1b8..cc21f23f8 100644 --- a/assets/layers/public_bookcase/public_bookcase.json +++ b/assets/layers/public_bookcase/public_bookcase.json @@ -444,6 +444,7 @@ }, "filter": [ { + "id": "kid-books", "options": [ { "question": "Kinderboeken aanwezig?", @@ -452,6 +453,7 @@ ] }, { + "id": "adult-books", "options": [ { "question": "Boeken voor volwassenen aanwezig?", @@ -460,6 +462,7 @@ ] }, { + "id": "inside", "options": [ { "question": "Binnen of buiten", diff --git a/assets/layers/toilet/toilet.json b/assets/layers/toilet/toilet.json index 9f7fedf32..c8ee81894 100644 --- a/assets/layers/toilet/toilet.json +++ b/assets/layers/toilet/toilet.json @@ -411,6 +411,7 @@ ], "filter": [ { + "id": "wheelchair", "options": [ { "question": { @@ -421,6 +422,7 @@ ] }, { + "id": "changing_table", "options": [ { "question": { @@ -431,6 +433,7 @@ ] }, { + "id": "free", "options": [ { "question": { diff --git a/assets/themes/cycle_highways/cycle_highways.json b/assets/themes/cycle_highways/cycle_highways.json index 9cea92fde..53dea9cc8 100644 --- a/assets/themes/cycle_highways/cycle_highways.json +++ b/assets/themes/cycle_highways/cycle_highways.json @@ -143,6 +143,7 @@ }, "filter": [ { + "id": "name-alt", "options": [ { "question": "Name contains 'alt'", @@ -151,6 +152,7 @@ ] }, { + "id": "name-wenslijn", "options": [ { "question": "Name contains 'wenslijn'", @@ -159,6 +161,7 @@ ] }, { + "id": "name-omleiding", "options": [ { "question": "Name contains 'omleiding'", @@ -167,6 +170,7 @@ ] }, { + "id":"ref-alt", "options": [ { "question": "Reference contains 'alt'", @@ -175,6 +179,7 @@ ] }, { + "id": "missing_link", "options": [ { "question": "No filter" @@ -194,6 +199,7 @@ ] }, { + "id": "proposed", "options": [ { "question": "No filter" diff --git a/assets/themes/uk_addresses/housenumber_unknown_small.svg b/assets/themes/uk_addresses/housenumber_unknown_small.svg new file mode 100644 index 000000000..398ce8f72 --- /dev/null +++ b/assets/themes/uk_addresses/housenumber_unknown_small.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/assets/themes/uk_addresses/license_info.json b/assets/themes/uk_addresses/license_info.json index 0c6fb0715..7d805cee4 100644 --- a/assets/themes/uk_addresses/license_info.json +++ b/assets/themes/uk_addresses/license_info.json @@ -39,5 +39,13 @@ "https://github.com/streetcomplete/StreetComplete/tree/master/res/graphics", "https://f-droid.org/packages/de.westnordost.streetcomplete/" ] + }, + { + "path": "housenumber_unknown_small.svg", + "license": "CC0", + "authors": [ + "Pieter Vander Vennet" + ], + "sources": [] } ] \ No newline at end of file diff --git a/assets/themes/uk_addresses/uk_addresses.json b/assets/themes/uk_addresses/uk_addresses.json index d4708deac..8dd07bf47 100644 --- a/assets/themes/uk_addresses/uk_addresses.json +++ b/assets/themes/uk_addresses/uk_addresses.json @@ -15,11 +15,15 @@ "maintainer": "Pieter Vander Vennet, Rob Nickerson, Russ Garrett", "icon": "./assets/themes/uk_addresses/housenumber_unknown.svg", "version": "2021-09-17", - "startLat": -0.08528530407, - "startLon": 51.52103754846, - "startZoom": 18, - "widenFactor": 1.5, + "startLat": -0.08706, + "startLon": 51.52224, + "startZoom": 17, + "widenFactor": 1.01, "socialImage": "", + "clustering": { + "minNeededFeatures": 25, + "maxZoom": 17 + }, "layers": [ { "id": "to_import", @@ -34,21 +38,21 @@ "minzoom": 12, "wayHandling": 1, "icon": { - "render": "./assets/themes/uk_addresses/housenumber_unknown.svg" - }, - "iconSize": { - "render": "40,40,center", + "render": "./assets/themes/uk_addresses/housenumber_unknown.svg", "mappings": [ { "if": "_embedding_object:id~*", - "then": "15,15,center" + "then": "./assets/themes/uk_addresses/housenumber_unknown_small.svg" }, { "if": "_imported=yes", - "then": "8,8,center" + "then": "./assets/themes/uk_addresses/housenumber_unknown_small.svg" } ] }, + "iconSize": { + "render": "40,40,center" + }, "title": { "render": "Address to be determined" }, @@ -73,6 +77,22 @@ "_embedding_object:addr:housenumber=JSON.parse(feat.properties._embedding_object)?.['addr:housenumber']", "_embedding_object:addr:street=JSON.parse(feat.properties._embedding_object)?.['addr:street']", "_embedding_object:id=JSON.parse(feat.properties._embedding_object)?.id" + ], + "filter": [ + { + "id": "to_handle", + "options": [ + { + "question": "Only show non-matched objects", + "osmTags": { + "and": [ + "_imported=", + "_embedding_object:id=" + ] + } + } + ] + } ] }, { diff --git a/test/GeoOperations.spec.ts b/test/GeoOperations.spec.ts index 49447afd5..372402648 100644 --- a/test/GeoOperations.spec.ts +++ b/test/GeoOperations.spec.ts @@ -181,10 +181,10 @@ export default class GeoOperationsSpec extends T { ["bbox bounds test", () => { const bbox = BBox.fromTile(16, 32754, 21785) - equal(-0.0714111328125, bbox.minLon) - equal(-0.076904296875, bbox.maxLon) - equal(51.53266860674158, bbox.minLat) - equal(51.5292513551899, bbox.maxLat) + equal(-0.076904296875, bbox.minLon) + equal(-0.0714111328125, bbox.maxLon) + equal(51.5292513551899, bbox.minLat) + equal(51.53266860674158, bbox.maxLat) } ] ] From 41a2a79fe9aafca32f03c0e6fd12ab7588dd269a Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Tue, 28 Sep 2021 17:30:48 +0200 Subject: [PATCH 35/65] More refactoring of the featurepipeline, introduction of fetching data from the OSM-API directly per tile, personal theme refactoring --- Customizations/AllKnownLayouts.ts | 21 +++ InitUiElements.ts | 112 ++++++------- Logic/Actors/OverpassFeatureSource.ts | 92 +++++----- Logic/BBox.ts | 158 ++++++++++++++++++ Logic/ContributorCount.ts | 2 +- Logic/ExtraFunction.ts | 3 +- Logic/FeatureSource/FeaturePipeline.ts | 146 +++++++++++++--- Logic/FeatureSource/FeatureSource.ts | 2 +- .../PerLayerFeatureSourceSplitter.ts | 3 +- .../Sources/FeatureSourceMerger.ts | 2 +- .../Sources/FilteringFeatureSource.ts | 2 +- Logic/FeatureSource/Sources/GeoJsonSource.ts | 2 +- .../Sources/RememberingSource.ts | 2 +- .../Sources/SimpleFeatureSource.ts | 8 +- .../TiledFeatureSource/OsmFeatureSource.ts | 112 +++++++++++++ .../TiledFeatureSource/TileHierarchy.ts | 2 +- .../TiledFeatureSource/TileHierarchyMerger.ts | 2 +- .../TiledFeatureSource/TiledFeatureSource.ts | 18 +- .../TiledFromLocalStorageSource.ts | 16 +- Logic/GeoOperations.ts | 135 +-------------- Logic/Osm/OsmConnection.ts | 32 ++-- Logic/Osm/OsmObject.ts | 2 +- Logic/Osm/Overpass.ts | 15 +- Models/TileRange.ts | 2 +- State.ts | 28 ++-- UI/Base/Minimap.ts | 2 +- UI/Base/MinimapImplementation.ts | 2 +- UI/BigComponents/Attribution.ts | 2 +- UI/BigComponents/DownloadPanel.ts | 3 +- UI/BigComponents/FullWelcomePaneWithTabs.ts | 6 +- UI/BigComponents/LeftControls.ts | 2 +- UI/BigComponents/PersonalLayersPanel.ts | 120 ------------- UI/BigComponents/SimpleAddUI.ts | 2 +- UI/ExportPDF.ts | 2 +- UI/Input/LocationInput.ts | 3 +- UI/Popup/SplitRoadWizard.ts | 3 +- UI/ShowDataLayer/PerTileCountAggregator.ts | 2 +- Utils.ts | 21 +-- assets/layers/bike_shop/bike_shop.json | 9 +- assets/layers/toilet/toilet.json | 2 +- assets/layers/toilet/wheelchair.svg | 123 +++++++------- assets/themes/bicyclelib/bicyclelib.json | 8 +- assets/themes/personal/personal.json | 7 +- .../toerisme_vlaanderen.json | 2 +- preferences.ts | 18 +- test.ts | 58 +++---- test/GeoOperations.spec.ts | 3 +- test/OsmConnection.spec.ts | 17 +- 48 files changed, 746 insertions(+), 590 deletions(-) create mode 100644 Logic/BBox.ts create mode 100644 Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts delete mode 100644 UI/BigComponents/PersonalLayersPanel.ts diff --git a/Customizations/AllKnownLayouts.ts b/Customizations/AllKnownLayouts.ts index 35cfb010c..57dbbf0ba 100644 --- a/Customizations/AllKnownLayouts.ts +++ b/Customizations/AllKnownLayouts.ts @@ -1,6 +1,7 @@ import AllKnownLayers from "./AllKnownLayers"; import * as known_themes from "../assets/generated/known_layers_and_themes.json" import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"; +import LayerConfig from "../Models/ThemeConfig/LayerConfig"; export class AllKnownLayouts { @@ -8,6 +9,26 @@ export class AllKnownLayouts { public static allKnownLayouts: Map = AllKnownLayouts.AllLayouts(); public static layoutsList: LayoutConfig[] = AllKnownLayouts.GenerateOrderedList(AllKnownLayouts.allKnownLayouts); + public static AllPublicLayers(){ + const allLayers : LayerConfig[] = [] + const seendIds = new Set() + const publicLayouts = AllKnownLayouts.layoutsList.filter(l => !l.hideFromOverview) + for (const layout of publicLayouts) { + if(layout.hideFromOverview){ + continue + } + for (const layer of layout.layers) { + if(seendIds.has(layer.id)){ + continue + } + seendIds.add(layer.id) + allLayers.push(layer) + } + + } + return allLayers + } + private static GenerateOrderedList(allKnownLayouts: Map): LayoutConfig[] { const keys = ["personal", "cyclofix", "hailhydrant", "bookcases", "toilets", "aed"] const list = [] diff --git a/InitUiElements.ts b/InitUiElements.ts index f3593556f..202e64149 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -27,7 +27,6 @@ import MapControlButton from "./UI/MapControlButton"; import LZString from "lz-string"; import AllKnownLayers from "./Customizations/AllKnownLayers"; import AvailableBaseLayers from "./Logic/Actors/AvailableBaseLayers"; -import {TagsFilter} from "./Logic/Tags/TagsFilter"; import LeftControls from "./UI/BigComponents/LeftControls"; import RightControls from "./UI/BigComponents/RightControls"; import {LayoutConfigJson} from "./Models/ThemeConfig/Json/LayoutConfigJson"; @@ -40,10 +39,10 @@ import {SubtleButton} from "./UI/Base/SubtleButton"; import ShowTileInfo from "./UI/ShowDataLayer/ShowTileInfo"; import {Tiles} from "./Models/TileRange"; import {TileHierarchyAggregator} from "./UI/ShowDataLayer/PerTileCountAggregator"; -import {BBox} from "./Logic/GeoOperations"; -import StaticFeatureSource from "./Logic/FeatureSource/Sources/StaticFeatureSource"; import FilterConfig from "./Models/ThemeConfig/FilterConfig"; import FilteredLayer from "./Models/FilteredLayer"; +import {BBox} from "./Logic/BBox"; +import {AllKnownLayouts} from "./Customizations/AllKnownLayouts"; export class InitUiElements { static InitAll( @@ -70,10 +69,24 @@ export class InitUiElements { "LayoutFromBase64 is ", layoutFromBase64 ); + + if(layoutToUse.id === personal.id){ + layoutToUse.layers = AllKnownLayouts.AllPublicLayers() + for (const layer of layoutToUse.layers) { + layer.minzoomVisible = Math.max(layer.minzoomVisible, layer.minzoom) + layer.minzoom = Math.max(16, layer.minzoom) + } + } State.state = new State(layoutToUse); - // This 'leaks' the global state via the window object, useful for debugging + if(layoutToUse.id === personal.id) { + // Disable overpass all together + State.state.overpassMaxZoom.setData(0) + + } + + // This 'leaks' the global state via the window object, useful for debugging // @ts-ignore window.mapcomplete_state = State.state; @@ -102,45 +115,6 @@ export class InitUiElements { } } - function updateFavs() { - // This is purely for the personal theme to load the layers there - const favs = State.state.favouriteLayers.data ?? []; - - const neededLayers = new Set(); - - console.log("Favourites are: ", favs); - layoutToUse.layers.splice(0, layoutToUse.layers.length); - let somethingChanged = false; - for (const fav of favs) { - if (AllKnownLayers.sharedLayers.has(fav)) { - const layer = AllKnownLayers.sharedLayers.get(fav); - if (!neededLayers.has(layer)) { - neededLayers.add(layer); - somethingChanged = true; - } - } - - for (const layouts of State.state.installedThemes.data) { - for (const layer of layouts.layout.layers) { - if (typeof layer === "string") { - continue; - } - if (layer.id === fav) { - if (!neededLayers.has(layer)) { - neededLayers.add(layer); - somethingChanged = true; - } - } - } - } - } - if (somethingChanged) { - State.state.layoutToUse.data.layers = Array.from(neededLayers); - State.state.layoutToUse.ping(); - State.state.featurePipeline?.ForceRefresh(); - } - } - if (layoutToUse.customCss !== undefined) { Utils.LoadCustomCss(layoutToUse.customCss); } @@ -206,18 +180,9 @@ export class InitUiElements { .addCallbackAndRunD(_ => addHomeMarker()); State.state.leafletMap.addCallbackAndRunD(_ => addHomeMarker()) - if (layoutToUse.id === personal.id) { - updateFavs(); - } InitUiElements.setupAllLayerElements(); - - if (layoutToUse.id === personal.id) { - State.state.favouriteLayers.addCallback(updateFavs); - State.state.installedThemes.addCallback(updateFavs); - } else { State.state.locationControl.ping(); - } new SelectedFeatureHandler(Hash.hash, State.state) @@ -414,15 +379,29 @@ export class InitUiElements { const flayers: FilteredLayer[] = []; for (const layer of layoutToUse.layers) { - const isDisplayed = QueryParameters.GetQueryParameter( - "layer-" + layer.id, - "true", - "Wether or not layer " + layer.id + " is shown" - ).map( - (str) => str !== "false", - [], - (b) => b.toString() - ); + let defaultShown = "true" + if(layoutToUse.id === personal.id){ + defaultShown = "false" + } + + let isDisplayed: UIEventSource + if(layoutToUse.id === personal.id){ + isDisplayed = State.state.osmConnection.GetPreference("personal-theme-layer-" + layer.id + "-enabled") + .map(value => value === "yes", [], enabled => { + return enabled ? "yes" : ""; + }) + isDisplayed.addCallbackAndRun(d =>console.log("IsDisplayed for layer", layer.id, "is currently", d) ) + }else{ + isDisplayed = QueryParameters.GetQueryParameter( + "layer-" + layer.id, + defaultShown, + "Wether or not layer " + layer.id + " is shown" + ).map( + (str) => str !== "false", + [], + (b) => b.toString() + ); + } const flayer = { isDisplayed: isDisplayed, layerDef: layer, @@ -453,8 +432,6 @@ export class InitUiElements { }); - const layers = State.state.layoutToUse.data.layers - const clusterCounter = TileHierarchyAggregator.createHierarchy() new ShowDataLayer({ features: clusterCounter.getCountsForZoom(State.state.locationControl, State.state.layoutToUse.data.clustering.minNeededElements), @@ -471,6 +448,10 @@ export class InitUiElements { const doShowFeatures = source.features.map( f => { const z = State.state.locationControl.data.zoom + + if(!source.layer.isDisplayed.data){ + return false; + } if (z < source.layer.layerDef.minzoom) { // Layer is always hidden for this zoom level @@ -482,7 +463,7 @@ export class InitUiElements { } if (f.length > clustering.minNeededElements) { - // This tile alone has too much features + // This tile alone already has too much features return false } @@ -504,11 +485,12 @@ export class InitUiElements { const bounds = State.state.currentBounds.data const tilebbox = BBox.fromTileIndex(source.tileIndex) if (!tilebbox.overlapsWith(bounds)) { + // Not within range return false } return true - }, [State.state.locationControl, State.state.currentBounds] + }, [State.state.currentBounds] ) new ShowDataLayer( diff --git a/Logic/Actors/OverpassFeatureSource.ts b/Logic/Actors/OverpassFeatureSource.ts index 20181fc14..d77f326e5 100644 --- a/Logic/Actors/OverpassFeatureSource.ts +++ b/Logic/Actors/OverpassFeatureSource.ts @@ -9,9 +9,10 @@ import {TagsFilter} from "../Tags/TagsFilter"; import SimpleMetaTagger from "../SimpleMetaTagger"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import RelationsTracker from "../Osm/RelationsTracker"; +import {BBox} from "../BBox"; -export default class OverpassFeatureSource implements FeatureSource, FeatureSourceState { +export default class OverpassFeatureSource implements FeatureSource { public readonly name = "OverpassFeatureSource" @@ -21,7 +22,6 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour public readonly features: UIEventSource<{ feature: any, freshness: Date }[]> = new UIEventSource(undefined); - public readonly sufficientlyZoomed: UIEventSource; public readonly runningQuery: UIEventSource = new UIEventSource(false); public readonly timeout: UIEventSource = new UIEventSource(0); @@ -40,10 +40,12 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour private readonly state: { readonly locationControl: UIEventSource, readonly layoutToUse: UIEventSource, - readonly leafletMap: any, readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; + readonly currentBounds :UIEventSource } + private readonly _isActive: UIEventSource; + private _onUpdated?: (bbox: BBox, dataFreshness: Date) => void; /** * The most important layer should go first, as that one gets first pick for the questions */ @@ -51,33 +53,24 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour state: { readonly locationControl: UIEventSource, readonly layoutToUse: UIEventSource, - readonly leafletMap: any, readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; - readonly overpassMaxZoom: UIEventSource - }) { + readonly overpassMaxZoom: UIEventSource, + readonly currentBounds :UIEventSource + }, + + options?: { + isActive?: UIEventSource, + onUpdated?: (bbox: BBox, freshness: Date) => void, + relationTracker: RelationsTracker}) { this.state = state - this.relationsTracker = new RelationsTracker() + this._isActive = options.isActive; + this._onUpdated =options. onUpdated; + this.relationsTracker = options.relationTracker const location = state.locationControl const self = this; - this.sufficientlyZoomed = location.map(location => { - if (location?.zoom === undefined) { - return false; - } - let minzoom = Math.min(...state.layoutToUse.data.layers.map(layer => layer.minzoom ?? 18)); - if (location.zoom < minzoom) { - return false; - } - const maxZoom = state.overpassMaxZoom.data - if (maxZoom !== undefined && location.zoom > maxZoom) { - return false; - } - - return true; - }, [state.layoutToUse] - ); for (let i = 0; i < 25; i++) { // This update removes all data on all layers -> erase the map on lower levels too this._previousBounds.set(i, []); @@ -89,16 +82,11 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour location.addCallback(() => { self.update() }); - state.leafletMap.addCallbackAndRunD(_ => { - self.update(); + + state.currentBounds.addCallback(_ => { + self.update() }) - } - - public ForceRefresh() { - for (let i = 0; i < 25; i++) { - this._previousBounds.set(i, []); - } - this.update(); + } private GetFilter(): Overpass { @@ -152,24 +140,34 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour } private update() { - this.updateAsync().then(_ => { + if(!this._isActive.data){ + return; + } + const self = this + this.updateAsync().then(bboxAndDate => { + if(bboxAndDate === undefined || self._onUpdated === undefined){ + return; + } + const [bbox, date] = bboxAndDate + self._onUpdated(bbox, date); }) } - private async updateAsync(): Promise { + private async updateAsync(): Promise<[BBox, Date]> { if (this.runningQuery.data) { console.log("Still running a query, not updating"); - return; + return undefined; } if (this.timeout.data > 0) { console.log("Still in timeout - not updating") - return; + return undefined; } - const bounds = this.state.leafletMap.data?.getBounds()?.pad(this.state.layoutToUse.data.widenFactor); + const bounds = this.state.currentBounds.data?.pad(this.state.layoutToUse.data.widenFactor)?.expandToTileBounds(14); + if (bounds === undefined) { - return; + return undefined; } const n = Math.min(90, bounds.getNorth()); @@ -178,13 +176,12 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour const w = Math.max(-180, bounds.getWest()); const queryBounds = {north: n, east: e, south: s, west: w}; - const z = Math.floor(this.state.locationControl.data.zoom ?? 0); const self = this; const overpass = this.GetFilter(); if (overpass === undefined) { - return; + return undefined; } this.runningQuery.setData(true); @@ -195,15 +192,14 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour try { [data, date] = await overpass.queryGeoJson(queryBounds) + console.log("Querying overpass is done", data) } catch (e) { - console.error(`QUERY FAILED (retrying in ${5 * self.retries.data} sec) due to`, e); - self.retries.data++; self.retries.ping(); + console.error(`QUERY FAILED (retrying in ${5 * self.retries.data} sec) due to`, e); self.timeout.setData(self.retries.data * 5); - self.runningQuery.setData(false); - + while (self.timeout.data > 0) { await Utils.waitFor(1000) self.timeout.data-- @@ -212,16 +208,20 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour } } while (data === undefined); + const z = Math.floor(this.state.locationControl.data.zoom ?? 0); self._previousBounds.get(z).push(queryBounds); self.retries.setData(0); try { data.features.forEach(feature => SimpleMetaTagger.objectMetaInfo.applyMetaTagsOnFeature(feature, date)); self.features.setData(data.features.map(f => ({feature: f, freshness: date}))); + return [bounds, date]; } catch (e) { console.error("Got the overpass response, but could not process it: ", e, e.stack) + }finally { + self.runningQuery.setData(false); } - self.runningQuery.setData(false); + } @@ -231,7 +231,7 @@ export default class OverpassFeatureSource implements FeatureSource, FeatureSour return false; } - const b = this.state.leafletMap.data.getBounds(); + const b = this.state.currentBounds.data; return b.getSouth() >= bounds.south && b.getNorth() <= bounds.north && b.getEast() <= bounds.east && diff --git a/Logic/BBox.ts b/Logic/BBox.ts new file mode 100644 index 000000000..e642c6ce3 --- /dev/null +++ b/Logic/BBox.ts @@ -0,0 +1,158 @@ +import * as turf from "@turf/turf"; +import {TileRange, Tiles} from "../Models/TileRange"; + +export class BBox { + + readonly maxLat: number; + readonly maxLon: number; + readonly minLat: number; + readonly minLon: number; + static global: BBox = new BBox([[-180, -90], [180, 90]]); + + constructor(coordinates) { + this.maxLat = -90; + this.maxLon = -180; + this.minLat = 90; + this.minLon = 180; + + + for (const coordinate of coordinates) { + this.maxLon = Math.max(this.maxLon, coordinate[0]); + this.maxLat = Math.max(this.maxLat, coordinate[1]); + this.minLon = Math.min(this.minLon, coordinate[0]); + this.minLat = Math.min(this.minLat, coordinate[1]); + } + this.check(); + } + + static fromLeafletBounds(bounds) { + return new BBox([[bounds.getWest(), bounds.getNorth()], [bounds.getEast(), bounds.getSouth()]]) + } + + static get(feature): BBox { + if (feature.bbox?.overlapsWith === undefined) { + const turfBbox: number[] = turf.bbox(feature) + feature.bbox = new BBox([[turfBbox[0], turfBbox[1]], [turfBbox[2], turfBbox[3]]]); + } + return feature.bbox; + } + + /** + * Constructs a tilerange which fully contains this bbox (thus might be a bit larger) + * @param zoomlevel + */ + public containingTileRange(zoomlevel): TileRange{ + return Tiles.TileRangeBetween(zoomlevel, this.minLat, this.minLon, this.maxLat, this.maxLon) + } + + public overlapsWith(other: BBox) { + if (this.maxLon < other.minLon) { + return false; + } + if (this.maxLat < other.minLat) { + return false; + } + if (this.minLon > other.maxLon) { + return false; + } + return this.minLat <= other.maxLat; + + } + + public isContainedIn(other: BBox) { + if (this.maxLon > other.maxLon) { + return false; + } + if (this.maxLat > other.maxLat) { + return false; + } + if (this.minLon < other.minLon) { + return false; + } + if (this.minLat < other.minLat) { + return false + } + return true; + } + + private check() { + if (isNaN(this.maxLon) || isNaN(this.maxLat) || isNaN(this.minLon) || isNaN(this.minLat)) { + console.log(this); + throw "BBOX has NAN"; + } + } + + static fromTile(z: number, x: number, y: number): BBox { + return new BBox(Tiles.tile_bounds_lon_lat(z, x, y)) + } + + static fromTileIndex(i: number): BBox { + if (i === 0) { + return BBox.global + } + return BBox.fromTile(...Tiles.tile_from_index(i)) + } + + getEast() { + return this.maxLon + } + + getNorth() { + return this.maxLat + } + + getWest() { + return this.minLon + } + + getSouth() { + return this.minLat + } + + pad(factor: number): BBox { + const latDiff = this.maxLat - this.minLat + const lat = (this.maxLat + this.minLat) / 2 + const lonDiff = this.maxLon - this.minLon + const lon = (this.maxLon + this.minLon) / 2 + return new BBox([[ + lon - lonDiff * factor, + lat - latDiff * factor + ], [lon + lonDiff * factor, + lat + latDiff * factor]]) + } + + toLeaflet() { + return [[this.minLat, this.minLon], [this.maxLat, this.maxLon]] + } + + asGeoJson(properties: any): any { + return { + type: "Feature", + properties: properties, + geometry: { + type: "Polygon", + coordinates: [[ + + [this.minLon, this.minLat], + [this.maxLon, this.minLat], + [this.maxLon, this.maxLat], + [this.minLon, this.maxLat], + [this.minLon, this.minLat], + + ]] + } + } + } + + /** + * Expands the BBOx so that it contains complete tiles for the given zoomlevel + * @param zoomlevel + */ + expandToTileBounds(zoomlevel: number) : BBox{ + const ul = Tiles.embedded_tile(this.minLat, this.minLon, zoomlevel) + const lr = Tiles.embedded_tile(this.maxLat, this.maxLon, zoomlevel) + const boundsul = Tiles.tile_bounds_lon_lat(ul.z, ul.x, ul.y) + const boundslr = Tiles.tile_bounds_lon_lat(lr.z, lr.x, lr.y) + return new BBox([].concat(boundsul, boundslr)) + } +} \ No newline at end of file diff --git a/Logic/ContributorCount.ts b/Logic/ContributorCount.ts index 2dcd8450f..f39d1106f 100644 --- a/Logic/ContributorCount.ts +++ b/Logic/ContributorCount.ts @@ -2,7 +2,7 @@ import {UIEventSource} from "./UIEventSource"; import FeaturePipeline from "./FeatureSource/FeaturePipeline"; import Loc from "../Models/Loc"; -import {BBox} from "./GeoOperations"; +import {BBox} from "./BBox"; export default class ContributorCount { diff --git a/Logic/ExtraFunction.ts b/Logic/ExtraFunction.ts index 5839fca08..76c28c5a9 100644 --- a/Logic/ExtraFunction.ts +++ b/Logic/ExtraFunction.ts @@ -1,4 +1,4 @@ -import {BBox, GeoOperations} from "./GeoOperations"; +import {GeoOperations} from "./GeoOperations"; import Combine from "../UI/Base/Combine"; import RelationsTracker from "./Osm/RelationsTracker"; import State from "../State"; @@ -7,6 +7,7 @@ import List from "../UI/Base/List"; import Title from "../UI/Base/Title"; import {UIEventSourceTools} from "./UIEventSource"; import AspectedRouting from "./Osm/aspectedRouting"; +import {BBox} from "./BBox"; export interface ExtraFuncParams { /** diff --git a/Logic/FeatureSource/FeaturePipeline.ts b/Logic/FeatureSource/FeaturePipeline.ts index a24d6f516..fab051aa5 100644 --- a/Logic/FeatureSource/FeaturePipeline.ts +++ b/Logic/FeatureSource/FeaturePipeline.ts @@ -17,18 +17,23 @@ import RegisteringAllFromFeatureSourceActor from "./Actors/RegisteringAllFromFea import TiledFromLocalStorageSource from "./TiledFeatureSource/TiledFromLocalStorageSource"; import SaveTileToLocalStorageActor from "./Actors/SaveTileToLocalStorageActor"; import DynamicGeoJsonTileSource from "./TiledFeatureSource/DynamicGeoJsonTileSource"; -import {BBox} from "../GeoOperations"; import {TileHierarchyMerger} from "./TiledFeatureSource/TileHierarchyMerger"; import RelationsTracker from "../Osm/RelationsTracker"; import {NewGeometryFromChangesFeatureSource} from "./Sources/NewGeometryFromChangesFeatureSource"; import ChangeGeometryApplicator from "./Sources/ChangeGeometryApplicator"; +import {BBox} from "../BBox"; +import OsmFeatureSource from "./TiledFeatureSource/OsmFeatureSource"; +import {OsmConnection} from "../Osm/OsmConnection"; +import {Tiles} from "../../Models/TileRange"; -export default class FeaturePipeline implements FeatureSourceState { +export default class FeaturePipeline { public readonly sufficientlyZoomed: UIEventSource; + public readonly runningQuery: UIEventSource; public readonly timeout: UIEventSource; + public readonly somethingLoaded: UIEventSource = new UIEventSource(false) public readonly newDataLoadedSignal: UIEventSource = new UIEventSource(undefined) @@ -39,27 +44,59 @@ export default class FeaturePipeline implements FeatureSourceState { constructor( handleFeatureSource: (source: FeatureSourceForLayer & Tiled) => void, state: { - filteredLayers: UIEventSource, - locationControl: UIEventSource, - selectedElement: UIEventSource, - changes: Changes, - layoutToUse: UIEventSource, - leafletMap: any, + readonly filteredLayers: UIEventSource, + readonly locationControl: UIEventSource, + readonly selectedElement: UIEventSource, + readonly changes: Changes, + readonly layoutToUse: UIEventSource, + readonly leafletMap: any, readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; readonly overpassMaxZoom: UIEventSource; + readonly osmConnection: OsmConnection + readonly currentBounds: UIEventSource }) { const self = this - const updater = new OverpassFeatureSource(state); + + /** + * Maps tileid onto last download moment + */ + const tileFreshnesses = new Map() + const osmSourceZoomLevel = 14 + const useOsmApi = state.locationControl.map(l => l.zoom > (state.overpassMaxZoom.data ?? 12)) + this.relationTracker = new RelationsTracker() + + const updater = new OverpassFeatureSource(state, + { + relationTracker: this.relationTracker, + isActive: useOsmApi.map(b => !b), + onUpdated: (bbox, freshness) => { + // This callback contains metadata of the overpass call + const range = bbox.containingTileRange(osmSourceZoomLevel) + Tiles.MapRange(range, (x, y) => { + tileFreshnesses.set(Tiles.tile_index(osmSourceZoomLevel, x, y), freshness) + }) + + } + }); + this.overpassUpdater = updater; - this.sufficientlyZoomed = updater.sufficientlyZoomed - this.runningQuery = updater.runningQuery + this.sufficientlyZoomed = state.locationControl.map(location => { + if (location?.zoom === undefined) { + return false; + } + let minzoom = Math.min(...state.layoutToUse.data.layers.map(layer => layer.minzoom ?? 18)); + return location.zoom >= minzoom; + } + ); + this.timeout = updater.timeout - this.relationTracker = updater.relationsTracker + + // Register everything in the state' 'AllElements' new RegisteringAllFromFeatureSourceActor(updater) - + const perLayerHierarchy = new Map() this.perLayerHierarchy = perLayerHierarchy @@ -72,7 +109,7 @@ export default class FeaturePipeline implements FeatureSourceState { new ChangeGeometryApplicator(src, state.changes) ) ) - + handleFeatureSource(srcFiltered) self.somethingLoaded.setData(true) }; @@ -81,6 +118,7 @@ export default class FeaturePipeline implements FeatureSourceState { perLayerHierarchy.get(layerId).registerTile(src) } + for (const filteredLayer of state.filteredLayers.data) { const hierarchy = new TileHierarchyMerger(filteredLayer, (tile, _) => patchedHandleFeatureSource(tile)) const id = filteredLayer.layerDef.id @@ -91,12 +129,25 @@ export default class FeaturePipeline implements FeatureSourceState { // This is an OSM layer // We load the cached values and register them // Getting data from upstream happens a bit lower - new TiledFromLocalStorageSource(filteredLayer, + const localStorage = new TiledFromLocalStorageSource(filteredLayer, (src) => { new RegisteringAllFromFeatureSourceActor(src) hierarchy.registerTile(src); src.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(src)) }, state) + + localStorage.tileFreshness.forEach((value, key) => { + if (tileFreshnesses.has(key)) { + const previous = tileFreshnesses.get(key) + if (value < previous) { + tileFreshnesses.set(key, value) + } + } else { + tileFreshnesses.set(key, value) + } + }) + + continue } @@ -106,7 +157,7 @@ export default class FeaturePipeline implements FeatureSourceState { const src = new GeoJsonSource(filteredLayer) TiledFeatureSource.createHierarchy(src, { layer: src.layer, - minZoomLevel:14, + minZoomLevel: 14, dontEnforceMinZoom: true, registerTile: (tile) => { new RegisteringAllFromFeatureSourceActor(tile) @@ -118,16 +169,54 @@ export default class FeaturePipeline implements FeatureSourceState { new DynamicGeoJsonTileSource( filteredLayer, tile => { - new RegisteringAllFromFeatureSourceActor(tile) - addToHierarchy(tile, id) - tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) - }, + new RegisteringAllFromFeatureSourceActor(tile) + addToHierarchy(tile, id) + tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) + }, state ) } - } + console.log("Tilefreshnesses are", tileFreshnesses) + const oldestAllowedDate = new Date(new Date().getTime() - (60 * 60 * 24 * 30 * 1000)); + + const neededTilesFromOsm = state.currentBounds.map(bbox => { + if (bbox === undefined) { + return + } + const range = bbox.containingTileRange(osmSourceZoomLevel) + const tileIndexes = [] + if (range.total > 100) { + // Too much tiles! + return [] + } + Tiles.MapRange(range, (x, y) => { + const i = Tiles.tile_index(osmSourceZoomLevel, x, y); + if (tileFreshnesses.get(i) > oldestAllowedDate) { + console.debug("Skipping tile", osmSourceZoomLevel, x, y, "as a decently fresh one is available") + // The cached tiles contain decently fresh data + return; + } + tileIndexes.push(i) + }) + return tileIndexes + }) + + const osmFeatureSource = new OsmFeatureSource({ + isActive: useOsmApi, + neededTiles: neededTilesFromOsm, + handleTile: tile => { + new RegisteringAllFromFeatureSourceActor(tile) + new SaveTileToLocalStorageActor(tile, tile.tileIndex) + addToHierarchy(tile, tile.layer.layerDef.id), + tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) + + }, + state: state + }) + + // Actually load data from the overpass source new PerLayerFeatureSourceSplitter(state.filteredLayers, (source) => TiledFeatureSource.createHierarchy(source, { @@ -169,9 +258,15 @@ export default class FeaturePipeline implements FeatureSourceState { self.updateAllMetaTagging() }) + + this.runningQuery = updater.runningQuery.map( + overpass => overpass || osmFeatureSource.isRunning.data, [osmFeatureSource.isRunning] + ) + + } - - private applyMetaTags(src: FeatureSourceForLayer){ + + private applyMetaTags(src: FeatureSourceForLayer) { const self = this console.debug("Applying metatagging onto ", src.name) window.setTimeout( @@ -192,7 +287,7 @@ export default class FeaturePipeline implements FeatureSourceState { }, 15 ) - + } private updateAllMetaTagging() { @@ -231,7 +326,4 @@ export default class FeaturePipeline implements FeatureSourceState { }) } - public ForceRefresh() { - this.overpassUpdater.ForceRefresh() - } } \ No newline at end of file diff --git a/Logic/FeatureSource/FeatureSource.ts b/Logic/FeatureSource/FeatureSource.ts index 791882e11..7d603d1f6 100644 --- a/Logic/FeatureSource/FeatureSource.ts +++ b/Logic/FeatureSource/FeatureSource.ts @@ -1,7 +1,7 @@ import {UIEventSource} from "../UIEventSource"; import {Utils} from "../../Utils"; import FilteredLayer from "../../Models/FilteredLayer"; -import {BBox} from "../GeoOperations"; +import {BBox} from "../BBox"; export default interface FeatureSource { features: UIEventSource<{ feature: any, freshness: Date }[]>; diff --git a/Logic/FeatureSource/PerLayerFeatureSourceSplitter.ts b/Logic/FeatureSource/PerLayerFeatureSourceSplitter.ts index d16e2c558..f9a0cbe1a 100644 --- a/Logic/FeatureSource/PerLayerFeatureSourceSplitter.ts +++ b/Logic/FeatureSource/PerLayerFeatureSourceSplitter.ts @@ -15,6 +15,7 @@ export default class PerLayerFeatureSourceSplitter { handleLayerData: (source: FeatureSourceForLayer & Tiled) => void, upstream: FeatureSource, options?:{ + tileIndex?: number, handleLeftovers?: (featuresWithoutLayer: any[]) => void }) { @@ -71,7 +72,7 @@ export default class PerLayerFeatureSourceSplitter { let featureSource = knownLayers.get(id) if (featureSource === undefined) { // Not yet initialized - now is a good time - featureSource = new SimpleFeatureSource(layer) + featureSource = new SimpleFeatureSource(layer, options?.tileIndex) featureSource.features.setData(features) knownLayers.set(id, featureSource) handleLayerData(featureSource) diff --git a/Logic/FeatureSource/Sources/FeatureSourceMerger.ts b/Logic/FeatureSource/Sources/FeatureSourceMerger.ts index 44ae28543..b1797d0ae 100644 --- a/Logic/FeatureSource/Sources/FeatureSourceMerger.ts +++ b/Logic/FeatureSource/Sources/FeatureSourceMerger.ts @@ -5,9 +5,9 @@ import {UIEventSource} from "../../UIEventSource"; import FeatureSource, {FeatureSourceForLayer, IndexedFeatureSource, Tiled} from "../FeatureSource"; import FilteredLayer from "../../../Models/FilteredLayer"; -import {BBox} from "../../GeoOperations"; import {Utils} from "../../../Utils"; import {Tiles} from "../../../Models/TileRange"; +import {BBox} from "../../BBox"; export default class FeatureSourceMerger implements FeatureSourceForLayer, Tiled, IndexedFeatureSource { diff --git a/Logic/FeatureSource/Sources/FilteringFeatureSource.ts b/Logic/FeatureSource/Sources/FilteringFeatureSource.ts index 65c6df0ec..6b433f88d 100644 --- a/Logic/FeatureSource/Sources/FilteringFeatureSource.ts +++ b/Logic/FeatureSource/Sources/FilteringFeatureSource.ts @@ -3,7 +3,7 @@ import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"; import FilteredLayer from "../../../Models/FilteredLayer"; import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; import Hash from "../../Web/Hash"; -import {BBox} from "../../GeoOperations"; +import {BBox} from "../../BBox"; export default class FilteringFeatureSource implements FeatureSourceForLayer, Tiled { public features: UIEventSource<{ feature: any; freshness: Date }[]> = diff --git a/Logic/FeatureSource/Sources/GeoJsonSource.ts b/Logic/FeatureSource/Sources/GeoJsonSource.ts index 6222fc729..301f1bc55 100644 --- a/Logic/FeatureSource/Sources/GeoJsonSource.ts +++ b/Logic/FeatureSource/Sources/GeoJsonSource.ts @@ -5,8 +5,8 @@ import {UIEventSource} from "../../UIEventSource"; import FilteredLayer from "../../../Models/FilteredLayer"; import {Utils} from "../../../Utils"; import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; -import {BBox} from "../../GeoOperations"; import {Tiles} from "../../../Models/TileRange"; +import {BBox} from "../../BBox"; export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { diff --git a/Logic/FeatureSource/Sources/RememberingSource.ts b/Logic/FeatureSource/Sources/RememberingSource.ts index b31097061..683576736 100644 --- a/Logic/FeatureSource/Sources/RememberingSource.ts +++ b/Logic/FeatureSource/Sources/RememberingSource.ts @@ -4,7 +4,7 @@ */ import FeatureSource, {Tiled} from "../FeatureSource"; import {UIEventSource} from "../../UIEventSource"; -import {BBox} from "../../GeoOperations"; +import {BBox} from "../../BBox"; export default class RememberingSource implements FeatureSource , Tiled{ diff --git a/Logic/FeatureSource/Sources/SimpleFeatureSource.ts b/Logic/FeatureSource/Sources/SimpleFeatureSource.ts index b3a476f5f..b06aae6d2 100644 --- a/Logic/FeatureSource/Sources/SimpleFeatureSource.ts +++ b/Logic/FeatureSource/Sources/SimpleFeatureSource.ts @@ -1,20 +1,22 @@ import {UIEventSource} from "../../UIEventSource"; import FilteredLayer from "../../../Models/FilteredLayer"; import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; -import {BBox} from "../../GeoOperations"; import {Utils} from "../../../Utils"; import {Tiles} from "../../../Models/TileRange"; +import {BBox} from "../../BBox"; export default class SimpleFeatureSource implements FeatureSourceForLayer, Tiled { public readonly features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); public readonly name: string = "SimpleFeatureSource"; public readonly layer: FilteredLayer; public readonly bbox: BBox = BBox.global; - public readonly tileIndex: number = Tiles.tile_index(0, 0, 0); + public readonly tileIndex: number; - constructor(layer: FilteredLayer) { + constructor(layer: FilteredLayer, tileIndex: number) { this.name = "SimpleFeatureSource(" + layer.layerDef.id + ")" this.layer = layer + this.tileIndex = tileIndex ?? 0; + this.bbox = BBox.fromTileIndex(this.tileIndex) } } \ No newline at end of file diff --git a/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts b/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts new file mode 100644 index 000000000..2bed33298 --- /dev/null +++ b/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts @@ -0,0 +1,112 @@ +import {Utils} from "../../../Utils"; +import * as OsmToGeoJson from "osmtogeojson"; +import StaticFeatureSource from "../Sources/StaticFeatureSource"; +import PerLayerFeatureSourceSplitter from "../PerLayerFeatureSourceSplitter"; +import {UIEventSource} from "../../UIEventSource"; +import FilteredLayer from "../../../Models/FilteredLayer"; +import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; +import {Tiles} from "../../../Models/TileRange"; +import {BBox} from "../../BBox"; +import {OsmConnection} from "../../Osm/OsmConnection"; + +export default class OsmFeatureSource { + private readonly _backend: string; + + public readonly isRunning: UIEventSource = new UIEventSource(false) + private readonly filteredLayers: UIEventSource; + private readonly handleTile: (fs: (FeatureSourceForLayer & Tiled)) => void; + private isActive: UIEventSource; + private options: { + handleTile: (tile: FeatureSourceForLayer & Tiled) => void; + isActive: UIEventSource, + neededTiles: UIEventSource, + state: { + readonly osmConnection: OsmConnection; + }; + }; + private readonly downloadedTiles = new Set() + + constructor(options: { + handleTile: (tile: FeatureSourceForLayer & Tiled) => void; + isActive: UIEventSource, + neededTiles: UIEventSource, + state: { + readonly filteredLayers: UIEventSource; + readonly osmConnection: OsmConnection; + }; + }) { + this.options = options; + this._backend = options.state.osmConnection._oauth_config.url; + this.filteredLayers = options.state.filteredLayers.map(layers => layers.filter(layer => layer.layerDef.source.geojsonSource === undefined)) + this.handleTile = options.handleTile + this.isActive = options.isActive + const self = this + options.neededTiles.addCallbackAndRunD(neededTiles => { + if (options.isActive?.data === false) { + return; + } + + self.isRunning.setData(true) + try { + + for (const neededTile of neededTiles) { + if (self.downloadedTiles.has(neededTile)) { + return; + } + self.downloadedTiles.add(neededTile) + Promise.resolve(self.LoadTile(...Tiles.tile_from_index(neededTile)).then(_ => { + })) + } + } catch (e) { + console.error(e) + } + self.isRunning.setData(false) + }) + } + + private async LoadTile(z, x, y): Promise { + if (z > 18) { + throw "This is an absurd high zoom level" + } + + const bbox = BBox.fromTile(z, x, y) + const url = `${this._backend}/api/0.6/map?bbox=${bbox.minLon},${bbox.minLat},${bbox.maxLon},${bbox.maxLat}` + try { + + console.log("Attempting to get tile", z, x, y, "from the osm api") + const osmXml = await Utils.download(url, {"accept": "application/xml"}) + try { + const parsed = new DOMParser().parseFromString(osmXml, "text/xml"); + console.log("Got tile", z, x, y, "from the osm api") + const geojson = OsmToGeoJson.default(parsed, + // @ts-ignore + { + flatProperties: true + }); + console.log("Tile geojson:", z, x, y, "is", geojson) + new PerLayerFeatureSourceSplitter(this.filteredLayers, + this.handleTile, + new StaticFeatureSource(geojson.features, false), + { + tileIndex: Tiles.tile_index(z, x, y) + } + ); + } catch (e) { + console.error("Weird error: ", e) + } + } catch (e) { + console.error("Could not download tile", z, x, y, "due to", e, "; retrying with smaller bounds") + if (e === "rate limited") { + return; + } + await this.LoadTile(z + 1, x * 2, y * 2) + await this.LoadTile(z + 1, 1 + x * 2, y * 2) + await this.LoadTile(z + 1, x * 2, 1 + y * 2) + await this.LoadTile(z + 1, 1 + x * 2, 1 + y * 2) + return; + } + + + } + +} \ No newline at end of file diff --git a/Logic/FeatureSource/TiledFeatureSource/TileHierarchy.ts b/Logic/FeatureSource/TiledFeatureSource/TileHierarchy.ts index d905d2f65..f2e43069d 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TileHierarchy.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TileHierarchy.ts @@ -1,5 +1,5 @@ import FeatureSource, {Tiled} from "../FeatureSource"; -import {BBox} from "../../GeoOperations"; +import {BBox} from "../../BBox"; export default interface TileHierarchy { diff --git a/Logic/FeatureSource/TiledFeatureSource/TileHierarchyMerger.ts b/Logic/FeatureSource/TiledFeatureSource/TileHierarchyMerger.ts index d8ab294ce..844754854 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TileHierarchyMerger.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TileHierarchyMerger.ts @@ -3,9 +3,9 @@ import {UIEventSource} from "../../UIEventSource"; import FeatureSource, {FeatureSourceForLayer, IndexedFeatureSource, Tiled} from "../FeatureSource"; import FilteredLayer from "../../../Models/FilteredLayer"; import {Utils} from "../../../Utils"; -import {BBox} from "../../GeoOperations"; import FeatureSourceMerger from "../Sources/FeatureSourceMerger"; import {Tiles} from "../../../Models/TileRange"; +import {BBox} from "../../BBox"; export class TileHierarchyMerger implements TileHierarchy { public readonly loadedTiles: Map = new Map(); diff --git a/Logic/FeatureSource/TiledFeatureSource/TiledFeatureSource.ts b/Logic/FeatureSource/TiledFeatureSource/TiledFeatureSource.ts index 2dcf3e6d2..4950ea328 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TiledFeatureSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TiledFeatureSource.ts @@ -1,10 +1,10 @@ import FeatureSource, {FeatureSourceForLayer, IndexedFeatureSource, Tiled} from "../FeatureSource"; import {UIEventSource} from "../../UIEventSource"; import {Utils} from "../../../Utils"; -import {BBox} from "../../GeoOperations"; import FilteredLayer from "../../../Models/FilteredLayer"; import TileHierarchy from "./TileHierarchy"; import {Tiles} from "../../../Models/TileRange"; +import {BBox} from "../../BBox"; /** * Contains all features in a tiled fashion. @@ -109,7 +109,6 @@ export default class TiledFeatureSource implements Tiled, IndexedFeatureSource, // To much features - we split return featureCount > this.maxFeatureCount - } /*** @@ -143,7 +142,20 @@ export default class TiledFeatureSource implements Tiled, IndexedFeatureSource, for (const feature of features) { const bbox = BBox.get(feature.feature) - if (this.options.dontEnforceMinZoom || this.options.minZoomLevel === undefined) { + + if (this.options.dontEnforceMinZoom) { + if (bbox.overlapsWith(this.upper_left.bbox)) { + ulf.push(feature) + } else if (bbox.overlapsWith(this.upper_right.bbox)) { + urf.push(feature) + } else if (bbox.overlapsWith(this.lower_left.bbox)) { + llf.push(feature) + } else if (bbox.overlapsWith(this.lower_right.bbox)) { + lrf.push(feature) + } else { + overlapsboundary.push(feature) + } + }else if (this.options.minZoomLevel === undefined) { if (bbox.isContainedIn(this.upper_left.bbox)) { ulf.push(feature) } else if (bbox.isContainedIn(this.upper_right.bbox)) { diff --git a/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts b/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts index 3e879bd4a..4b578b7da 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts @@ -5,12 +5,13 @@ import Loc from "../../../Models/Loc"; import TileHierarchy from "./TileHierarchy"; import {Utils} from "../../../Utils"; import SaveTileToLocalStorageActor from "../Actors/SaveTileToLocalStorageActor"; -import {BBox} from "../../GeoOperations"; import {Tiles} from "../../../Models/TileRange"; +import {BBox} from "../../BBox"; export default class TiledFromLocalStorageSource implements TileHierarchy { public loadedTiles: Map = new Map(); - +public tileFreshness : Map = new Map() + constructor(layer: FilteredLayer, handleFeatureSource: (src: FeatureSourceForLayer & Tiled, index: number) => void, state: { @@ -29,7 +30,14 @@ export default class TiledFromLocalStorageSource implements TileHierarchy Tiles.tile_from_index(i).join("/")).join(", ")) + console.debug("Layer", layer.layerDef.id, "has following tiles in available in localstorage", indexes.map(i => Tiles.tile_from_index(i).join("/")).join(", ")) + for (const index of indexes) { + const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layer.layerDef.id + "-" +index+"-time"; + const data = Number(localStorage.getItem(prefix)) + const freshness = new Date() + freshness.setTime(data) + this.tileFreshness.set(index, freshness) + } const zLevels = indexes.map(i => i % 100) const indexesSet = new Set(indexes) @@ -72,7 +80,7 @@ export default class TiledFromLocalStorageSource implements TileHierarchy console.log("Tiles to load from localstorage:", t)) + neededTiles.addCallbackAndRun(t => console.debug("Tiles to load from localstorage:", t)) neededTiles.addCallbackAndRunD(neededIndexes => { for (const neededIndex of neededIndexes) { diff --git a/Logic/GeoOperations.ts b/Logic/GeoOperations.ts index cfef09e5d..3fa10f7a2 100644 --- a/Logic/GeoOperations.ts +++ b/Logic/GeoOperations.ts @@ -1,6 +1,5 @@ import * as turf from '@turf/turf' -import {Utils} from "../Utils"; -import {Tiles} from "../Models/TileRange"; +import {BBox} from "./BBox"; export class GeoOperations { @@ -379,135 +378,3 @@ export class GeoOperations { } -export class BBox { - - readonly maxLat: number; - readonly maxLon: number; - readonly minLat: number; - readonly minLon: number; - static global: BBox = new BBox([[-180, -90], [180, 90]]); - - constructor(coordinates) { - this.maxLat = -90; - this.maxLon = -180; - this.minLat = 90; - this.minLon = 180; - - - for (const coordinate of coordinates) { - this.maxLon = Math.max(this.maxLon, coordinate[0]); - this.maxLat = Math.max(this.maxLat, coordinate[1]); - this.minLon = Math.min(this.minLon, coordinate[0]); - this.minLat = Math.min(this.minLat, coordinate[1]); - } - this.check(); - } - - static fromLeafletBounds(bounds) { - return new BBox([[bounds.getWest(), bounds.getNorth()], [bounds.getEast(), bounds.getSouth()]]) - } - - static get(feature): BBox { - if (feature.bbox?.overlapsWith === undefined) { - const turfBbox: number[] = turf.bbox(feature) - feature.bbox = new BBox([[turfBbox[0], turfBbox[1]], [turfBbox[2], turfBbox[3]]]); - } - return feature.bbox; - } - - public overlapsWith(other: BBox) { - if (this.maxLon < other.minLon) { - return false; - } - if (this.maxLat < other.minLat) { - return false; - } - if (this.minLon > other.maxLon) { - return false; - } - return this.minLat <= other.maxLat; - - } - - public isContainedIn(other: BBox) { - if (this.maxLon > other.maxLon) { - return false; - } - if (this.maxLat > other.maxLat) { - return false; - } - if (this.minLon < other.minLon) { - return false; - } - if (this.minLat < other.minLat) { - return false - } - return true; - } - - private check() { - if (isNaN(this.maxLon) || isNaN(this.maxLat) || isNaN(this.minLon) || isNaN(this.minLat)) { - console.log(this); - throw "BBOX has NAN"; - } - } - - static fromTile(z: number, x: number, y: number): BBox { - return new BBox(Tiles.tile_bounds_lon_lat(z, x, y)) - } - - static fromTileIndex(i: number): BBox { - return BBox.fromTile(...Tiles.tile_from_index(i)) - } - - getEast() { - return this.maxLon - } - - getNorth() { - return this.maxLat - } - - getWest() { - return this.minLon - } - - getSouth() { - return this.minLat - } - - pad(factor: number) : BBox { - const latDiff = this.maxLat - this.minLat - const lat = (this.maxLat + this.minLat) / 2 - const lonDiff = this.maxLon - this.minLon - const lon = (this.maxLon + this.minLon) / 2 - return new BBox([[ - lon - lonDiff * factor, - lat - latDiff * factor - ], [lon + lonDiff * factor, - lat + latDiff * factor]]) - } - - toLeaflet() { - return [[this.minLat, this.minLon], [this.maxLat, this.maxLon]] - } - - asGeoJson(properties: any) : any{ - return { - type:"Feature", - properties: properties, - geometry:{ - type:"Polygon", - coordinates:[[ - - [this.minLon, this.minLat], - [this.maxLon, this.minLat], - [this.maxLon, this.maxLat], - [this.minLon, this.maxLat], - [this.minLon, this.minLat], - - ]] - } - } - } -} \ No newline at end of file diff --git a/Logic/Osm/OsmConnection.ts b/Logic/Osm/OsmConnection.ts index 5d955eb04..4e1a9297a 100644 --- a/Logic/Osm/OsmConnection.ts +++ b/Logic/Osm/OsmConnection.ts @@ -62,26 +62,26 @@ export class OsmConnection { }; private isChecking = false; - constructor(dryRun: boolean, - fakeUser: boolean, + constructor(options:{dryRun?: false | boolean, + fakeUser?: false | boolean, allElements: ElementStorage, changes: Changes, - oauth_token: UIEventSource, + oauth_token?: UIEventSource, // Used to keep multiple changesets open and to write to the correct changeset layoutName: string, - singlePage: boolean = true, - osmConfiguration: "osm" | "osm-test" = 'osm' + singlePage?: boolean, + osmConfiguration?: "osm" | "osm-test" } ) { - this.fakeUser = fakeUser; - this._singlePage = singlePage; - this._oauth_config = OsmConnection.oauth_configs[osmConfiguration] ?? OsmConnection.oauth_configs.osm; + this.fakeUser = options.fakeUser ?? false; + this._singlePage = options.singlePage ?? true; + this._oauth_config = OsmConnection.oauth_configs[options.osmConfiguration ?? 'osm'] ?? OsmConnection.oauth_configs.osm; console.debug("Using backend", this._oauth_config.url) OsmObject.SetBackendUrl(this._oauth_config.url + "/") this._iframeMode = Utils.runningFromConsole ? false : window !== window.top; this.userDetails = new UIEventSource(new UserDetails(this._oauth_config.url), "userDetails"); - this.userDetails.data.dryRun = dryRun || fakeUser; - if (fakeUser) { + this.userDetails.data.dryRun = (options.dryRun ?? false) || (options.fakeUser ?? false) ; + if (options.fakeUser) { const ud = this.userDetails.data; ud.csCount = 5678 ud.loggedIn = true; @@ -98,23 +98,23 @@ export class OsmConnection { } }); this.isLoggedIn.addCallbackAndRunD(li => console.log("User is logged in!", li)) - this._dryRun = dryRun; + this._dryRun = options.dryRun; this.updateAuthObject(); this.preferencesHandler = new OsmPreferences(this.auth, this); - this.changesetHandler = new ChangesetHandler(layoutName, dryRun, this, allElements, changes, this.auth); - if (oauth_token.data !== undefined) { - console.log(oauth_token.data) + this.changesetHandler = new ChangesetHandler(options.layoutName, options.dryRun, this, options.allElements, options.changes, this.auth); + if (options.oauth_token?.data !== undefined) { + console.log(options.oauth_token.data) const self = this; - this.auth.bootstrapToken(oauth_token.data, + this.auth.bootstrapToken(options.oauth_token.data, (x) => { console.log("Called back: ", x) self.AttemptLogin(); }, this.auth); - oauth_token.setData(undefined); + options. oauth_token.setData(undefined); } if (this.auth.authenticated()) { diff --git a/Logic/Osm/OsmObject.ts b/Logic/Osm/OsmObject.ts index d95e0fa49..4538622d1 100644 --- a/Logic/Osm/OsmObject.ts +++ b/Logic/Osm/OsmObject.ts @@ -1,7 +1,7 @@ import {Utils} from "../../Utils"; import * as polygon_features from "../../assets/polygon-features.json"; import {UIEventSource} from "../UIEventSource"; -import {BBox} from "../GeoOperations"; +import {BBox} from "../BBox"; export abstract class OsmObject { diff --git a/Logic/Osm/Overpass.ts b/Logic/Osm/Overpass.ts index de6b65287..2bf1b4e70 100644 --- a/Logic/Osm/Overpass.ts +++ b/Logic/Osm/Overpass.ts @@ -16,8 +16,8 @@ export class Overpass { private readonly _extraScripts: string[]; private _includeMeta: boolean; private _relationTracker: RelationsTracker; - - + + constructor(filter: TagsFilter, extraScripts: string[], interpreterUrl: UIEventSource, timeout: UIEventSource, @@ -41,10 +41,13 @@ export class Overpass { } const self = this; const json = await Utils.downloadJson(query) - - if (json.elements === [] && ((json.remarks ?? json.remark).indexOf("runtime error") >= 0)) { - console.log("Timeout or other runtime error"); - throw("Runtime error (timeout)") + console.log("Got json!", json) + if (json.elements.length === 0 && json.remark !== undefined) { + console.warn("Timeout or other runtime error while querying overpass", json.remark); + throw `Runtime error (timeout or similar)${json.remark}` + } + if(json.elements.length === 0){ + console.warn("No features for" ,json) } self._relationTracker.RegisterRelations(json) diff --git a/Models/TileRange.ts b/Models/TileRange.ts index 215d5a76f..b61f192a0 100644 --- a/Models/TileRange.ts +++ b/Models/TileRange.ts @@ -86,7 +86,7 @@ export class Tiles { static embedded_tile(lat: number, lon: number, z: number): { x: number, y: number, z: number } { return {x: Tiles.lon2tile(lon, z), y: Tiles.lat2tile(lat, z), z: z} } - + static TileRangeBetween(zoomlevel: number, lat0: number, lon0: number, lat1: number, lon1: number): TileRange { const t0 = Tiles.embedded_tile(lat0, lon0, zoomlevel) const t1 = Tiles.embedded_tile(lat1, lon1, zoomlevel) diff --git a/State.ts b/State.ts index 04b9728b3..85dfc9cfd 100644 --- a/State.ts +++ b/State.ts @@ -17,7 +17,7 @@ import FeaturePipeline from "./Logic/FeatureSource/FeaturePipeline"; import FilteredLayer from "./Models/FilteredLayer"; import ChangeToElementsActor from "./Logic/Actors/ChangeToElementsActor"; import LayoutConfig from "./Models/ThemeConfig/LayoutConfig"; -import {BBox} from "./Logic/GeoOperations"; +import {BBox} from "./Logic/BBox"; /** * Contains the global state: a bunch of UI-event sources @@ -83,7 +83,7 @@ export default class State { public readonly featureSwitchExportAsPdf: UIEventSource; public readonly overpassUrl: UIEventSource; public readonly overpassTimeout: UIEventSource; - public readonly overpassMaxZoom: UIEventSource = new UIEventSource(undefined); + public readonly overpassMaxZoom: UIEventSource = new UIEventSource(20); public featurePipeline: FeaturePipeline; @@ -97,7 +97,7 @@ export default class State { * The current visible extent of the screen */ public readonly currentBounds = new UIEventSource(undefined) - + public backgroundLayer; public readonly backgroundLayerId: UIEventSource; @@ -372,23 +372,21 @@ export default class State { return; } - this.osmConnection = new OsmConnection( - this.featureSwitchIsTesting.data, - this.featureSwitchFakeUser.data, - this.allElements, - this.changes, - QueryParameters.GetQueryParameter( + this.osmConnection = new OsmConnection({ + changes: this.changes, + dryRun: this.featureSwitchIsTesting.data, + fakeUser: this.featureSwitchFakeUser.data, + allElements: this.allElements, + oauth_token: QueryParameters.GetQueryParameter( "oauth_token", undefined, "Used to complete the login" ), - layoutToUse?.id, - true, - // @ts-ignore - this.featureSwitchApiURL.data - ); + layoutName: layoutToUse?.id, + osmConfiguration: <'osm' | 'osm-test'>this.featureSwitchApiURL.data + }) + - new ChangeToElementsActor(this.changes, this.allElements) new PendingChangesUploader(this.changes, this.selectedElement); diff --git a/UI/Base/Minimap.ts b/UI/Base/Minimap.ts index e276c8281..32cdadbd6 100644 --- a/UI/Base/Minimap.ts +++ b/UI/Base/Minimap.ts @@ -1,8 +1,8 @@ import BaseUIElement from "../BaseUIElement"; import Loc from "../../Models/Loc"; import BaseLayer from "../../Models/BaseLayer"; -import {BBox} from "../../Logic/GeoOperations"; import {UIEventSource} from "../../Logic/UIEventSource"; +import {BBox} from "../../Logic/BBox"; export interface MinimapOptions { background?: UIEventSource, diff --git a/UI/Base/MinimapImplementation.ts b/UI/Base/MinimapImplementation.ts index 1761d1ada..110235437 100644 --- a/UI/Base/MinimapImplementation.ts +++ b/UI/Base/MinimapImplementation.ts @@ -4,10 +4,10 @@ import {UIEventSource} from "../../Logic/UIEventSource"; import Loc from "../../Models/Loc"; import BaseLayer from "../../Models/BaseLayer"; import AvailableBaseLayers from "../../Logic/Actors/AvailableBaseLayers"; -import {BBox} from "../../Logic/GeoOperations"; import * as L from "leaflet"; import {Map} from "leaflet"; import Minimap, {MinimapObj, MinimapOptions} from "./Minimap"; +import {BBox} from "../../Logic/BBox"; export default class MinimapImplementation extends BaseUIElement implements MinimapObj { private static _nextId = 0; diff --git a/UI/BigComponents/Attribution.ts b/UI/BigComponents/Attribution.ts index 7e70fa367..9b1ddb013 100644 --- a/UI/BigComponents/Attribution.ts +++ b/UI/BigComponents/Attribution.ts @@ -7,7 +7,7 @@ import Constants from "../../Models/Constants"; import Loc from "../../Models/Loc"; import {VariableUiElement} from "../Base/VariableUIElement"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; -import {BBox} from "../../Logic/GeoOperations"; +import {BBox} from "../../Logic/BBox"; /** * The bottom right attribution panel in the leaflet map diff --git a/UI/BigComponents/DownloadPanel.ts b/UI/BigComponents/DownloadPanel.ts index 746715826..500d28e19 100644 --- a/UI/BigComponents/DownloadPanel.ts +++ b/UI/BigComponents/DownloadPanel.ts @@ -5,7 +5,7 @@ import State from "../../State"; import {Utils} from "../../Utils"; import Combine from "../Base/Combine"; import CheckBoxes from "../Input/Checkboxes"; -import {BBox, GeoOperations} from "../../Logic/GeoOperations"; +import {GeoOperations} from "../../Logic/GeoOperations"; import Toggle from "../Input/Toggle"; import Title from "../Base/Title"; import FeaturePipeline from "../../Logic/FeatureSource/FeaturePipeline"; @@ -13,6 +13,7 @@ import {UIEventSource} from "../../Logic/UIEventSource"; import SimpleMetaTagger from "../../Logic/SimpleMetaTagger"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import {meta} from "@turf/turf"; +import {BBox} from "../../Logic/BBox"; export class DownloadPanel extends Toggle { diff --git a/UI/BigComponents/FullWelcomePaneWithTabs.ts b/UI/BigComponents/FullWelcomePaneWithTabs.ts index a4a3e826a..f6574f04b 100644 --- a/UI/BigComponents/FullWelcomePaneWithTabs.ts +++ b/UI/BigComponents/FullWelcomePaneWithTabs.ts @@ -1,7 +1,5 @@ import State from "../../State"; import ThemeIntroductionPanel from "./ThemeIntroductionPanel"; -import * as personal from "../../assets/themes/personal/personal.json"; -import PersonalLayersPanel from "./PersonalLayersPanel"; import Svg from "../../Svg"; import Translations from "../i18n/Translations"; import ShareScreen from "./ShareScreen"; @@ -32,9 +30,7 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen { private static ConstructBaseTabs(layoutToUse: LayoutConfig, isShown: UIEventSource): { header: string | BaseUIElement; content: BaseUIElement }[] { let welcome: BaseUIElement = new ThemeIntroductionPanel(isShown); - if (layoutToUse.id === personal.id) { - welcome = new PersonalLayersPanel(); - } + const tabs: { header: string | BaseUIElement, content: BaseUIElement }[] = [ {header: ``, content: welcome}, { diff --git a/UI/BigComponents/LeftControls.ts b/UI/BigComponents/LeftControls.ts index b3e848d4d..7ee2a74e6 100644 --- a/UI/BigComponents/LeftControls.ts +++ b/UI/BigComponents/LeftControls.ts @@ -11,8 +11,8 @@ import AllDownloads from "./AllDownloads"; import FilterView from "./FilterView"; import {UIEventSource} from "../../Logic/UIEventSource"; import FeaturePipeline from "../../Logic/FeatureSource/FeaturePipeline"; -import {BBox} from "../../Logic/GeoOperations"; import Loc from "../../Models/Loc"; +import {BBox} from "../../Logic/BBox"; export default class LeftControls extends Combine { diff --git a/UI/BigComponents/PersonalLayersPanel.ts b/UI/BigComponents/PersonalLayersPanel.ts deleted file mode 100644 index e5a41b733..000000000 --- a/UI/BigComponents/PersonalLayersPanel.ts +++ /dev/null @@ -1,120 +0,0 @@ -import {AllKnownLayouts} from "../../Customizations/AllKnownLayouts"; -import Svg from "../../Svg"; -import State from "../../State"; -import Combine from "../Base/Combine"; -import Toggle from "../Input/Toggle"; -import {SubtleButton} from "../Base/SubtleButton"; -import Translations from "../i18n/Translations"; -import BaseUIElement from "../BaseUIElement"; -import {VariableUiElement} from "../Base/VariableUIElement"; -import {UIEventSource} from "../../Logic/UIEventSource"; -import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; - -export default class PersonalLayersPanel extends VariableUiElement { - - constructor() { - super( - State.state.installedThemes.map(installedThemes => { - const t = Translations.t.favourite; - - // Lets get all the layers - const allThemes = AllKnownLayouts.layoutsList.concat(installedThemes.map(layout => layout.layout)) - .filter(theme => !theme.hideFromOverview) - - const allLayers = [] - { - const seenLayers = new Set() - for (const layers of allThemes.map(theme => theme.layers)) { - for (const layer of layers) { - if (seenLayers.has(layer.id)) { - continue - } - seenLayers.add(layer.id) - allLayers.push(layer) - } - } - } - - // Time to create a panel based on them! - const panel: BaseUIElement = new Combine(allLayers.map(PersonalLayersPanel.CreateLayerToggle)); - - - return new Toggle( - new Combine([ - t.panelIntro.Clone(), - panel - ]).SetClass("flex flex-col"), - new SubtleButton( - Svg.osm_logo_ui(), - t.loginNeeded.Clone().SetClass("text-center") - ).onClick(() => State.state.osmConnection.AttemptLogin()), - State.state.osmConnection.isLoggedIn - ) - }) - ) - } - - /*** - * Creates a toggle for the given layer, which'll update State.state.favouriteLayers right away - * @param layer - * @constructor - * @private - */ - private static CreateLayerToggle(layer: LayerConfig): Toggle { - let icon: BaseUIElement = new Combine([layer.GenerateLeafletStyle( - new UIEventSource({id: "node/-1"}), - false - ).icon.html]).SetClass("relative") - let iconUnset = new Combine([layer.GenerateLeafletStyle( - new UIEventSource({id: "node/-1"}), - false - ).icon.html]).SetClass("relative") - - iconUnset.SetStyle("opacity:0.1") - - let name = layer.name; - if (name === undefined) { - return undefined; - } - const content = new Combine([ - Translations.WT(name).Clone().SetClass("font-bold"), - Translations.WT(layer.description)?.Clone() - ]).SetClass("flex flex-col") - - const contentUnselected = new Combine([ - Translations.WT(name).Clone().SetClass("font-bold"), - Translations.WT(layer.description)?.Clone() - ]).SetClass("flex flex-col line-through") - - return new Toggle( - new SubtleButton( - icon, - content), - new SubtleButton( - iconUnset, - contentUnselected - ), - State.state.favouriteLayers.map(favLayers => { - return favLayers.indexOf(layer.id) >= 0 - }, [], (selected, current) => { - if (!selected && current.indexOf(layer.id) <= 0) { - // Not selected and not contained: nothing to change: we return current as is - return current; - } - if (selected && current.indexOf(layer.id) >= 0) { - // Selected and contained: this is fine! - return current; - } - const clone = [...current] - if (selected) { - clone.push(layer.id) - } else { - clone.splice(clone.indexOf(layer.id), 1) - } - return clone - }) - ).ToggleOnClick(); - } - - -} \ No newline at end of file diff --git a/UI/BigComponents/SimpleAddUI.ts b/UI/BigComponents/SimpleAddUI.ts index 5dca2cfc2..ca758ab80 100644 --- a/UI/BigComponents/SimpleAddUI.ts +++ b/UI/BigComponents/SimpleAddUI.ts @@ -20,7 +20,7 @@ import {OsmObject, OsmWay} from "../../Logic/Osm/OsmObject"; import PresetConfig from "../../Models/ThemeConfig/PresetConfig"; import FilteredLayer from "../../Models/FilteredLayer"; import {And} from "../../Logic/Tags/And"; -import {BBox} from "../../Logic/GeoOperations"; +import {BBox} from "../../Logic/BBox"; /* * The SimpleAddUI is a single panel, which can have multiple states: diff --git a/UI/ExportPDF.ts b/UI/ExportPDF.ts index f1a113daa..54879b9b2 100644 --- a/UI/ExportPDF.ts +++ b/UI/ExportPDF.ts @@ -5,7 +5,6 @@ import {SimpleMapScreenshoter} from "leaflet-simple-map-screenshoter"; import {UIEventSource} from "../Logic/UIEventSource"; import Minimap from "./Base/Minimap"; import Loc from "../Models/Loc"; -import {BBox} from "../Logic/GeoOperations"; import BaseLayer from "../Models/BaseLayer"; import {FixedUiElement} from "./Base/FixedUiElement"; import Translations from "./i18n/Translations"; @@ -14,6 +13,7 @@ import Constants from "../Models/Constants"; import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"; import FeaturePipeline from "../Logic/FeatureSource/FeaturePipeline"; import ShowDataLayer from "./ShowDataLayer/ShowDataLayer"; +import {BBox} from "../Logic/BBox"; /** * Creates screenshoter to take png screenshot * Creates jspdf and downloads it diff --git a/UI/Input/LocationInput.ts b/UI/Input/LocationInput.ts index 0621eccc8..262d9a7db 100644 --- a/UI/Input/LocationInput.ts +++ b/UI/Input/LocationInput.ts @@ -7,11 +7,12 @@ import Combine from "../Base/Combine"; import Svg from "../../Svg"; import State from "../../State"; import AvailableBaseLayers from "../../Logic/Actors/AvailableBaseLayers"; -import {BBox, GeoOperations} from "../../Logic/GeoOperations"; +import {GeoOperations} from "../../Logic/GeoOperations"; import ShowDataLayer from "../ShowDataLayer/ShowDataLayer"; import ShowDataMultiLayer from "../ShowDataLayer/ShowDataMultiLayer"; import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"; import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; +import {BBox} from "../../Logic/BBox"; export default class LocationInput extends InputElement { diff --git a/UI/Popup/SplitRoadWizard.ts b/UI/Popup/SplitRoadWizard.ts index b1df0a5fa..17e1bd013 100644 --- a/UI/Popup/SplitRoadWizard.ts +++ b/UI/Popup/SplitRoadWizard.ts @@ -5,7 +5,7 @@ import {SubtleButton} from "../Base/SubtleButton"; import Minimap from "../Base/Minimap"; import State from "../../State"; import ShowDataLayer from "../ShowDataLayer/ShowDataLayer"; -import {BBox, GeoOperations} from "../../Logic/GeoOperations"; +import {GeoOperations} from "../../Logic/GeoOperations"; import {LeafletMouseEvent} from "leaflet"; import Combine from "../Base/Combine"; import {Button} from "../Base/Button"; @@ -15,6 +15,7 @@ import Title from "../Base/Title"; import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"; import ShowDataMultiLayer from "../ShowDataLayer/ShowDataMultiLayer"; import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; +import {BBox} from "../../Logic/BBox"; export default class SplitRoadWizard extends Toggle { private static splitLayerStyling = new LayerConfig({ diff --git a/UI/ShowDataLayer/PerTileCountAggregator.ts b/UI/ShowDataLayer/PerTileCountAggregator.ts index e4085f2cd..f313e741f 100644 --- a/UI/ShowDataLayer/PerTileCountAggregator.ts +++ b/UI/ShowDataLayer/PerTileCountAggregator.ts @@ -1,9 +1,9 @@ import FeatureSource, {FeatureSourceForLayer, Tiled} from "../../Logic/FeatureSource/FeatureSource"; -import {BBox} from "../../Logic/GeoOperations"; import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; import {UIEventSource} from "../../Logic/UIEventSource"; import {Tiles} from "../../Models/TileRange"; import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"; +import {BBox} from "../../Logic/BBox"; export class TileHierarchyAggregator implements FeatureSource { private _parent: TileHierarchyAggregator; diff --git a/Utils.ts b/Utils.ts index 477598f79..aced008ad 100644 --- a/Utils.ts +++ b/Utils.ts @@ -192,11 +192,12 @@ export class Utils { } /** - * Copies all key-value pairs of the source into the target. + * Copies all key-value pairs of the source into the target. This will change the target * If the key starts with a '+', the values of the list will be appended to the target instead of overwritten * @param source * @param target * @constructor + * @return the second parameter as is */ static Merge(source: any, target: any) { for (const key in source) { @@ -288,15 +289,13 @@ export class Utils { } - private static injectedDownloads = {} public static injectJsonDownloadForTests(url: string, data) { Utils.injectedDownloads[url] = data } - public static downloadJson(url: string, headers?: any): Promise { - + public static download(url: string, headers?: any): Promise { const injected = Utils.injectedDownloads[url] if (injected !== undefined) { console.log("Using injected resource for test for URL", url) @@ -311,17 +310,14 @@ export class Utils { const xhr = new XMLHttpRequest(); xhr.onload = () => { if (xhr.status == 200) { - try { - resolve(JSON.parse(xhr.response)) - } catch (e) { - reject("Not a valid json: " + xhr.response) - } + resolve(xhr.response) + } else if (xhr.status === 509 || xhr.status === 429){ + reject("rate limited") } else { reject(xhr.statusText) } }; xhr.open('GET', url); - xhr.setRequestHeader("accept", "application/json") if (headers !== undefined) { for (const key in headers) { @@ -334,6 +330,11 @@ export class Utils { ) } + public static async downloadJson(url: string, headers?: any): Promise { + const data = await Utils.download(url, Utils.Merge({"accept": "application/json"}, headers ?? {})) + return JSON.parse(data) + } + /** * Triggers a 'download file' popup which will download the contents */ diff --git a/assets/layers/bike_shop/bike_shop.json b/assets/layers/bike_shop/bike_shop.json index 571ff46e2..d7930f854 100644 --- a/assets/layers/bike_shop/bike_shop.json +++ b/assets/layers/bike_shop/bike_shop.json @@ -24,7 +24,7 @@ ] }, { - "#": "if sport is defined and is not bicycle, it is retrackted; if bicycle retail/repair is marked as 'no', it is retracted too.", + "#": "if sport is defined and is not bicycle, it is not matched; if bicycle retail/repair is marked as 'no', it is not shown to too.", "##": "There will be a few false-positives with this. They will get filtered out by people marking both 'not selling bikes' and 'not repairing bikes'. Furthermore, the OSMers will add a sports-subcategory on it", "and": [ "shop=sports", @@ -38,13 +38,6 @@ ] } ] - }, - { - "#": "Any shop with any bicycle service", - "and": [ - "shop~*", - "service:bicycle:.*~~.*" - ] } ] } diff --git a/assets/layers/toilet/toilet.json b/assets/layers/toilet/toilet.json index c8ee81894..da9b3ae90 100644 --- a/assets/layers/toilet/toilet.json +++ b/assets/layers/toilet/toilet.json @@ -27,7 +27,7 @@ "mappings": [ { "if": "wheelchair=yes", - "then": "./assets/layers/toilet/wheelchair.svg" + "then": "circle:white;./assets/layers/toilet/wheelchair.svg" }, { "if": { diff --git a/assets/layers/toilet/wheelchair.svg b/assets/layers/toilet/wheelchair.svg index 929ea6c40..d113492ad 100644 --- a/assets/layers/toilet/wheelchair.svg +++ b/assets/layers/toilet/wheelchair.svg @@ -2,76 +2,71 @@ image/svg+xml + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + id="defs9" /> + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="999" + id="namedview7" + showgrid="false" + inkscape:zoom="0.8559553" + inkscape:cx="-16.568588" + inkscape:cy="292.29436" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="layer2" /> - + inkscape:groupmode="layer" + id="layer2" + inkscape:label="background"> + + inkscape:groupmode="layer" + id="layer1" + inkscape:label="wheelchair"> \ No newline at end of file + inkscape:connector-curvature="0" + style="clip-rule:evenodd;fill:#000000;fill-rule:evenodd;stroke-width:0.66635805" + d="m 310.84431,395.24795 c -20.28873,40.10642 -62.75413,66.52908 -108.0502,66.52908 -66.52908,0 -120.790412,-54.26133 -120.790412,-120.79041 0,-46.71209 28.310452,-90.1207 70.555212,-109.36341 l 2.73376,35.67521 c -24.98647,15.74498 -40.3895,44.15435 -40.3895,73.93288 0,48.26215 39.36263,87.62413 87.62413,87.62413 44.15407,0 81.80523,-33.88535 86.93958,-77.35545 z" + id="path4" /> \ No newline at end of file diff --git a/assets/themes/bicyclelib/bicyclelib.json b/assets/themes/bicyclelib/bicyclelib.json index 3a8fb3e8e..c0c85b13b 100644 --- a/assets/themes/bicyclelib/bicyclelib.json +++ b/assets/themes/bicyclelib/bicyclelib.json @@ -43,6 +43,12 @@ "widenFactor": 1.5, "roamingRenderings": [], "layers": [ - "bicycle_library" + { + "builtin": "bicycle_library", + "override": { + "minZoom": 0 + } + }, + ] } \ No newline at end of file diff --git a/assets/themes/personal/personal.json b/assets/themes/personal/personal.json index d9df14a7b..88296088d 100644 --- a/assets/themes/personal/personal.json +++ b/assets/themes/personal/personal.json @@ -12,7 +12,7 @@ "zh_Hant": "個人化主題" }, "description": { - "en": "Create a personal theme based on all the available layers of all themes", + "en": "Create a personal theme based on all the available layers of all themes. Open the layer selection to select one or more layers.", "nl": "Stel je eigen thema samen door lagen te combineren van alle andere themas", "es": "Crea una interficie basada en todas las capas disponibles de todas las interficies", "ca": "Crea una interfície basada en totes les capes disponibles de totes les interfícies", @@ -37,11 +37,14 @@ ], "maintainer": "MapComplete", "icon": "./assets/svg/addSmall.svg", + "clustering": { + "maxZoom": 19 + }, "version": "0", "startLat": 0, "startLon": 0, "startZoom": 16, - "widenFactor": 3, + "widenFactor": 1.2, "layers": [], "roamingRenderings": [] } \ No newline at end of file diff --git a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json index c09b548e8..7bef2f129 100644 --- a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json +++ b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json @@ -20,7 +20,7 @@ "startZoom": 8, "startLat": 50.8536, "startLon": 4.433, - "widenFactor": 2, + "widenFactor": 1.5, "layers": [ { "builtin": [ diff --git a/preferences.ts b/preferences.ts index 310892003..c96912b5d 100644 --- a/preferences.ts +++ b/preferences.ts @@ -10,9 +10,17 @@ import LZString from "lz-string"; import BaseUIElement from "./UI/BaseUIElement"; import Table from "./UI/Base/Table"; import {LayoutConfigJson} from "./Models/ThemeConfig/Json/LayoutConfigJson"; +import {Changes} from "./Logic/Osm/Changes"; +import {ElementStorage} from "./Logic/ElementStorage"; -const connection = new OsmConnection(false, false, new UIEventSource(undefined), ""); +const connection = new OsmConnection({ + osmConfiguration: 'osm', + changes: new Changes(), + layoutName: '', + allElements: new ElementStorage() +}); + let rendered = false; @@ -20,6 +28,7 @@ function salvageThemes(preferences: any) { const knownThemeNames = new Set(); const correctThemeNames = [] for (const key in preferences) { + try{ if (!(typeof key === "string")) { continue; } @@ -36,7 +45,7 @@ function salvageThemes(preferences: any) { } else { knownThemeNames.add(theme); } - } + }catch(e){console.error(e)}} for (const correctThemeName of correctThemeNames) { knownThemeNames.delete(correctThemeName); @@ -65,8 +74,13 @@ function salvageThemes(preferences: any) { try { jsonObject = JSON.parse(atob(combined)); } catch (e) { + try{ + // We try to decode with lz-string jsonObject = JSON.parse(Utils.UnMinify(LZString.decompressFromBase64(combined))) as LayoutConfigJson; + }catch(e0){ + console.log("Could not salvage theme. Initial parsing failed due to:", e,"\nWith LZ failed due ", e0) + } } diff --git a/test.ts b/test.ts index c70e45da5..e758de8cd 100644 --- a/test.ts +++ b/test.ts @@ -1,33 +1,35 @@ -import SplitRoadWizard from "./UI/Popup/SplitRoadWizard"; -import State from "./State"; +import {Tiles} from "./Models/TileRange"; +import OsmFeatureSource from "./Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource"; +import {Utils} from "./Utils"; import {AllKnownLayouts} from "./Customizations/AllKnownLayouts"; -import MinimapImplementation from "./UI/Base/MinimapImplementation"; -import {UIEventSource} from "./Logic/UIEventSource"; -import FilteredLayer from "./Models/FilteredLayer"; -import {And} from "./Logic/Tags/And"; -import ShowDataLayer from "./UI/ShowDataLayer/ShowDataLayer"; -import ShowTileInfo from "./UI/ShowDataLayer/ShowTileInfo"; -import StaticFeatureSource from "./Logic/FeatureSource/Sources/StaticFeatureSource"; -import {BBox} from "./Logic/GeoOperations"; -import Minimap from "./UI/Base/Minimap"; +import LayerConfig from "./Models/ThemeConfig/LayerConfig"; -State.state = new State(undefined) +const allLayers: LayerConfig[] = [] +const seenIds = new Set() +for (const layoutConfig of AllKnownLayouts.layoutsList) { + if (layoutConfig.hideFromOverview) { + continue + } + for (const layer of layoutConfig.layers) { + if (seenIds.has(layer.id)) { + continue + } + seenIds.add(layer.id) + allLayers.push(layer) + } +} -const leafletMap = new UIEventSource(undefined) -MinimapImplementation.initialize() -Minimap.createMiniMap({ - leafletMap: leafletMap, -}).SetStyle("height: 600px; width: 600px") - .AttachTo("maindiv") +console.log("All layer ids", allLayers.map(l => l.id)) -const bbox = BBox.fromTile(16,32754,21785).asGeoJson({ - count: 42, - tileId: 42 +const src = new OsmFeatureSource({ + backend: "https://www.openstreetmap.org", + handleTile: tile => console.log("Got tile", tile), + allLayers: allLayers }) - -console.log(bbox) -new ShowDataLayer({ - layerToShow: ShowTileInfo.styling, - leafletMap: leafletMap, - features: new StaticFeatureSource([ bbox], false) -}) \ No newline at end of file +src.LoadTile(16, 33354, 21875).then(geojson => { + console.log("Got geojson", geojson); + Utils.offerContentsAsDownloadableFile(JSON.stringify(geojson), "test.geojson", { + mimetype: "application/vnd.geo+json" + }) +}) +//*/ \ No newline at end of file diff --git a/test/GeoOperations.spec.ts b/test/GeoOperations.spec.ts index 372402648..56e07acaf 100644 --- a/test/GeoOperations.spec.ts +++ b/test/GeoOperations.spec.ts @@ -1,8 +1,9 @@ import {Utils} from "../Utils"; import * as Assert from "assert"; import T from "./TestHelper"; -import {BBox, GeoOperations} from "../Logic/GeoOperations"; +import {GeoOperations} from "../Logic/GeoOperations"; import {equal} from "assert"; +import {BBox} from "../Logic/BBox"; Utils.runningFromConsole = true; diff --git a/test/OsmConnection.spec.ts b/test/OsmConnection.spec.ts index 0b6cf3b47..9d7b114f5 100644 --- a/test/OsmConnection.spec.ts +++ b/test/OsmConnection.spec.ts @@ -2,6 +2,9 @@ import T from "./TestHelper"; import UserDetails, {OsmConnection} from "../Logic/Osm/OsmConnection"; import {UIEventSource} from "../Logic/UIEventSource"; import ScriptUtils from "../scripts/ScriptUtils"; +import {AllKnownLayouts} from "../Customizations/AllKnownLayouts"; +import {ElementStorage} from "../Logic/ElementStorage"; +import {Changes} from "../Logic/Osm/Changes"; export default class OsmConnectionSpec extends T { @@ -15,12 +18,14 @@ export default class OsmConnectionSpec extends T { super("osmconnection", [ ["login on dev", () => { - const osmConn = new OsmConnection(false, false, - new UIEventSource(undefined), - "Unit test", - true, - "osm-test" - ) + const osmConn = new OsmConnection({ + osmConfiguration: "osm-test", + layoutName: "Unit test", + allElements: new ElementStorage(), + changes: new Changes(), + oauth_token: new UIEventSource(OsmConnectionSpec._osm_token) + } + ); osmConn.userDetails.map((userdetails: UserDetails) => { if (userdetails.loggedIn) { From a78d33112bfb7d801f3c561943a376b18fe350e6 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Tue, 28 Sep 2021 18:00:44 +0200 Subject: [PATCH 36/65] Refactoring: LayoutToUse is a simple value now --- InitUiElements.ts | 116 +++++++++--------- Logic/Actors/BackgroundLayerResetter.ts | 6 +- Logic/Actors/OverpassFeatureSource.ts | 13 +- Logic/Actors/TitleHandler.ts | 12 +- Logic/FeatureSource/FeaturePipeline.ts | 10 +- .../TiledFeatureSource/OsmFeatureSource.ts | 2 +- Logic/Osm/Actions/DeleteAction.ts | 2 +- Logic/Osm/Changes.ts | 2 +- Logic/SimpleMetaTagger.ts | 2 +- State.ts | 46 +++---- UI/BigComponents/Attribution.ts | 4 +- UI/BigComponents/AttributionPanel.ts | 8 +- UI/BigComponents/DownloadPanel.ts | 2 +- UI/BigComponents/FullWelcomePaneWithTabs.ts | 2 +- UI/BigComponents/MoreScreen.ts | 2 +- UI/BigComponents/ShareScreen.ts | 2 +- UI/BigComponents/ThemeIntroductionPanel.ts | 15 +-- UI/BigComponents/UserBadge.ts | 2 +- UI/Image/ImageUploadFlow.ts | 2 +- UI/Input/DropDown.ts | 2 +- UI/Input/LocationInput.ts | 21 ++-- UI/SpecialVisualizations.ts | 13 +- 22 files changed, 133 insertions(+), 153 deletions(-) diff --git a/InitUiElements.ts b/InitUiElements.ts index 202e64149..40932dfd2 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -323,9 +323,7 @@ export class InitUiElements { State.state.backgroundLayer, State.state.locationControl, State.state.availableBackgroundLayers, - State.state.layoutToUse.map( - (layout: LayoutConfig) => layout.defaultBackgroundId - ) + State.state.layoutToUse.defaultBackgroundId ); const attr = new Attribution( @@ -345,7 +343,7 @@ export class InitUiElements { }).SetClass("w-full h-full") .AttachTo("leafletDiv") - const layout = State.state.layoutToUse.data; + const layout = State.state.layoutToUse; if (layout.lockLocation) { if (layout.lockLocation === true) { const tile = Tiles.embedded_tile( @@ -375,66 +373,66 @@ export class InitUiElements { const state = State.state; const empty = [] - state.filteredLayers = state.layoutToUse.map((layoutToUse) => { - const flayers: FilteredLayer[] = []; + const flayers: FilteredLayer[] = []; - for (const layer of layoutToUse.layers) { - let defaultShown = "true" - if(layoutToUse.id === personal.id){ - defaultShown = "false" - } - - let isDisplayed: UIEventSource - if(layoutToUse.id === personal.id){ - isDisplayed = State.state.osmConnection.GetPreference("personal-theme-layer-" + layer.id + "-enabled") - .map(value => value === "yes", [], enabled => { - return enabled ? "yes" : ""; - }) - isDisplayed.addCallbackAndRun(d =>console.log("IsDisplayed for layer", layer.id, "is currently", d) ) - }else{ - isDisplayed = QueryParameters.GetQueryParameter( - "layer-" + layer.id, - defaultShown, - "Wether or not layer " + layer.id + " is shown" - ).map( - (str) => str !== "false", - [], - (b) => b.toString() - ); - } - const flayer = { - isDisplayed: isDisplayed, - layerDef: layer, - appliedFilters: new UIEventSource<{ filter: FilterConfig, selected: number }[]>([]), - }; - - if (layer.filters.length > 0) { - const filtersPerName = new Map() - layer.filters.forEach(f => filtersPerName.set(f.id, f)) - const qp = QueryParameters.GetQueryParameter("filter-" + layer.id, "","Filtering state for a layer") - flayer.appliedFilters.map(filters => { - filters = filters ?? [] - return filters.map(f => f.filter.id + "." + f.selected).join(",") - }, [], textual => { - if(textual.length === 0){ - return empty - } - return textual.split(",").map(part => { - const [filterId, selected] = part.split("."); - return {filter: filtersPerName.get(filterId), selected: Number(selected)} - }).filter(f => f.filter !== undefined && !isNaN(f.selected)) - }).syncWith(qp, true) - } - - flayers.push(flayer); + for (const layer of state.layoutToUse.layers) { + let defaultShown = "true" + if(state.layoutToUse.id === personal.id){ + defaultShown = "false" } - return flayers; - }); + + let isDisplayed: UIEventSource + if(state.layoutToUse.id === personal.id){ + isDisplayed = State.state.osmConnection.GetPreference("personal-theme-layer-" + layer.id + "-enabled") + .map(value => value === "yes", [], enabled => { + return enabled ? "yes" : ""; + }) + isDisplayed.addCallbackAndRun(d =>console.log("IsDisplayed for layer", layer.id, "is currently", d) ) + }else{ + isDisplayed = QueryParameters.GetQueryParameter( + "layer-" + layer.id, + defaultShown, + "Wether or not layer " + layer.id + " is shown" + ).map( + (str) => str !== "false", + [], + (b) => b.toString() + ); + } + const flayer = { + isDisplayed: isDisplayed, + layerDef: layer, + appliedFilters: new UIEventSource<{ filter: FilterConfig, selected: number }[]>([]), + }; + + if (layer.filters.length > 0) { + const filtersPerName = new Map() + layer.filters.forEach(f => filtersPerName.set(f.id, f)) + const qp = QueryParameters.GetQueryParameter("filter-" + layer.id, "","Filtering state for a layer") + flayer.appliedFilters.map(filters => { + filters = filters ?? [] + return filters.map(f => f.filter.id + "." + f.selected).join(",") + }, [], textual => { + if(textual.length === 0){ + return empty + } + return textual.split(",").map(part => { + const [filterId, selected] = part.split("."); + return {filter: filtersPerName.get(filterId), selected: Number(selected)} + }).filter(f => f.filter !== undefined && !isNaN(f.selected)) + }).syncWith(qp, true) + } + + flayers.push(flayer); + } + state.filteredLayers = new UIEventSource(flayers); + + const clusterCounter = TileHierarchyAggregator.createHierarchy() new ShowDataLayer({ - features: clusterCounter.getCountsForZoom(State.state.locationControl, State.state.layoutToUse.data.clustering.minNeededElements), + features: clusterCounter.getCountsForZoom(State.state.locationControl, State.state.layoutToUse.clustering.minNeededElements), leafletMap: State.state.leafletMap, layerToShow: ShowTileInfo.styling, }) @@ -444,7 +442,7 @@ export class InitUiElements { clusterCounter.addTile(source) - const clustering = State.state.layoutToUse.data.clustering + const clustering = State.state.layoutToUse.clustering const doShowFeatures = source.features.map( f => { const z = State.state.locationControl.data.zoom diff --git a/Logic/Actors/BackgroundLayerResetter.ts b/Logic/Actors/BackgroundLayerResetter.ts index 96c43bda3..d193d8132 100644 --- a/Logic/Actors/BackgroundLayerResetter.ts +++ b/Logic/Actors/BackgroundLayerResetter.ts @@ -11,8 +11,8 @@ export default class BackgroundLayerResetter { constructor(currentBackgroundLayer: UIEventSource, location: UIEventSource, availableLayers: UIEventSource, - defaultLayerId: UIEventSource = undefined) { - defaultLayerId = defaultLayerId ?? new UIEventSource(AvailableBaseLayers.osmCarto.id); + defaultLayerId: string = undefined) { + defaultLayerId = defaultLayerId ?? AvailableBaseLayers.osmCarto.id; // Change the baselayer back to OSM if we go out of the current range of the layer availableLayers.addCallbackAndRun(availableLayers => { @@ -28,7 +28,7 @@ export default class BackgroundLayerResetter { if (availableLayer.min_zoom > location.data.zoom) { break; } - if (availableLayer.id === defaultLayerId.data) { + if (availableLayer.id === defaultLayerId) { defaultLayer = availableLayer; } return; // All good - the current layer still works! diff --git a/Logic/Actors/OverpassFeatureSource.ts b/Logic/Actors/OverpassFeatureSource.ts index d77f326e5..248703954 100644 --- a/Logic/Actors/OverpassFeatureSource.ts +++ b/Logic/Actors/OverpassFeatureSource.ts @@ -3,7 +3,7 @@ import Loc from "../../Models/Loc"; import {Or} from "../Tags/Or"; import {Overpass} from "../Osm/Overpass"; import Bounds from "../../Models/Bounds"; -import FeatureSource, {FeatureSourceState} from "../FeatureSource/FeatureSource"; +import FeatureSource from "../FeatureSource/FeatureSource"; import {Utils} from "../../Utils"; import {TagsFilter} from "../Tags/TagsFilter"; import SimpleMetaTagger from "../SimpleMetaTagger"; @@ -39,7 +39,7 @@ export default class OverpassFeatureSource implements FeatureSource { private readonly _previousBounds: Map = new Map(); private readonly state: { readonly locationControl: UIEventSource, - readonly layoutToUse: UIEventSource, + readonly layoutToUse: LayoutConfig, readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; readonly currentBounds :UIEventSource @@ -52,7 +52,7 @@ export default class OverpassFeatureSource implements FeatureSource { constructor( state: { readonly locationControl: UIEventSource, - readonly layoutToUse: UIEventSource, + readonly layoutToUse: LayoutConfig, readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; readonly overpassMaxZoom: UIEventSource, @@ -76,9 +76,6 @@ export default class OverpassFeatureSource implements FeatureSource { this._previousBounds.set(i, []); } - state.layoutToUse.addCallback(() => { - self.update() - }); location.addCallback(() => { self.update() }); @@ -92,7 +89,7 @@ export default class OverpassFeatureSource implements FeatureSource { private GetFilter(): Overpass { let filters: TagsFilter[] = []; let extraScripts: string[] = []; - for (const layer of this.state.layoutToUse.data.layers) { + for (const layer of this.state.layoutToUse.layers) { if (typeof (layer) === "string") { throw "A layer was not expanded!" } @@ -164,7 +161,7 @@ export default class OverpassFeatureSource implements FeatureSource { return undefined; } - const bounds = this.state.currentBounds.data?.pad(this.state.layoutToUse.data.widenFactor)?.expandToTileBounds(14); + const bounds = this.state.currentBounds.data?.pad(this.state.layoutToUse.widenFactor)?.expandToTileBounds(14); if (bounds === undefined) { return undefined; diff --git a/Logic/Actors/TitleHandler.ts b/Logic/Actors/TitleHandler.ts index 49661f289..699a33aa8 100644 --- a/Logic/Actors/TitleHandler.ts +++ b/Logic/Actors/TitleHandler.ts @@ -3,12 +3,18 @@ import Translations from "../../UI/i18n/Translations"; import Locale from "../../UI/i18n/Locale"; import TagRenderingAnswer from "../../UI/Popup/TagRenderingAnswer"; import Combine from "../../UI/Base/Combine"; +import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; +import {ElementStorage} from "../ElementStorage"; export default class TitleHandler { - constructor(state) { + constructor(state : { + selectedElement: UIEventSource, + layoutToUse: LayoutConfig, + allElements: ElementStorage + }) { const currentTitle: UIEventSource = state.selectedElement.map( selected => { - const layout = state.layoutToUse.data + const layout = state.layoutToUse const defaultTitle = Translations.WT(layout?.title)?.txt ?? "MapComplete" if (selected === undefined) { @@ -27,7 +33,7 @@ export default class TitleHandler { } } return defaultTitle - }, [Locale.language, state.layoutToUse] + }, [Locale.language] ) diff --git a/Logic/FeatureSource/FeaturePipeline.ts b/Logic/FeatureSource/FeaturePipeline.ts index fab051aa5..d65771da2 100644 --- a/Logic/FeatureSource/FeaturePipeline.ts +++ b/Logic/FeatureSource/FeaturePipeline.ts @@ -1,7 +1,7 @@ import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import FilteringFeatureSource from "./Sources/FilteringFeatureSource"; import PerLayerFeatureSourceSplitter from "./PerLayerFeatureSourceSplitter"; -import FeatureSource, {FeatureSourceForLayer, FeatureSourceState, IndexedFeatureSource, Tiled} from "./FeatureSource"; +import FeatureSource, {FeatureSourceForLayer, IndexedFeatureSource, Tiled} from "./FeatureSource"; import TiledFeatureSource from "./TiledFeatureSource/TiledFeatureSource"; import {UIEventSource} from "../UIEventSource"; import {TileHierarchyTools} from "./TiledFeatureSource/TileHierarchy"; @@ -48,7 +48,7 @@ export default class FeaturePipeline { readonly locationControl: UIEventSource, readonly selectedElement: UIEventSource, readonly changes: Changes, - readonly layoutToUse: UIEventSource, + readonly layoutToUse: LayoutConfig, readonly leafletMap: any, readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; @@ -86,7 +86,7 @@ export default class FeaturePipeline { if (location?.zoom === undefined) { return false; } - let minzoom = Math.min(...state.layoutToUse.data.layers.map(layer => layer.minzoom ?? 18)); + let minzoom = Math.min(...state.layoutToUse.layers.map(layer => layer.minzoom ?? 18)); return location.zoom >= minzoom; } ); @@ -223,8 +223,8 @@ export default class FeaturePipeline { layer: source.layer, minZoomLevel: 14, dontEnforceMinZoom: true, - maxFeatureCount: state.layoutToUse.data.clustering.minNeededElements, - maxZoomLevel: state.layoutToUse.data.clustering.maxZoom, + maxFeatureCount: state.layoutToUse.clustering.minNeededElements, + maxZoomLevel: state.layoutToUse.clustering.maxZoom, registerTile: (tile) => { // We save the tile data for the given layer to local storage new SaveTileToLocalStorageActor(tile, tile.tileIndex) diff --git a/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts b/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts index 2bed33298..a7485facf 100644 --- a/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts @@ -65,7 +65,7 @@ export default class OsmFeatureSource { } private async LoadTile(z, x, y): Promise { - if (z > 18) { + if (z > 20) { throw "This is an absurd high zoom level" } diff --git a/Logic/Osm/Actions/DeleteAction.ts b/Logic/Osm/Actions/DeleteAction.ts index 25542bf18..68919bd12 100644 --- a/Logic/Osm/Actions/DeleteAction.ts +++ b/Logic/Osm/Actions/DeleteAction.ts @@ -62,7 +62,7 @@ export default class DeleteAction { } State.state.osmConnection.changesetHandler.DeleteElement( obj, - State.state.layoutToUse.data, + State.state.layoutToUse, reason, State.state.allElements, () => { diff --git a/Logic/Osm/Changes.ts b/Logic/Osm/Changes.ts index 828ba7d78..b4bf3b4ec 100644 --- a/Logic/Osm/Changes.ts +++ b/Logic/Osm/Changes.ts @@ -131,7 +131,7 @@ export class Changes { } await State.state.osmConnection.UploadChangeset( - State.state.layoutToUse.data, + State.state.layoutToUse, State.state.allElements, (csId) => Changes.createChangesetFor(csId, changes), ) diff --git a/Logic/SimpleMetaTagger.ts b/Logic/SimpleMetaTagger.ts index a938e9c72..4b047fc7d 100644 --- a/Logic/SimpleMetaTagger.ts +++ b/Logic/SimpleMetaTagger.ts @@ -87,7 +87,7 @@ export default class SimpleMetaTagger { }, (feature => { - const units = Utils.NoNull([].concat(...State.state?.layoutToUse?.data?.layers?.map(layer => layer.units ?? []))); + const units = Utils.NoNull([].concat(...State.state?.layoutToUse?.layers?.map(layer => layer.units ?? []))); if (units.length == 0) { return; } diff --git a/State.ts b/State.ts index 85dfc9cfd..0af8e5a64 100644 --- a/State.ts +++ b/State.ts @@ -27,7 +27,7 @@ export default class State { // The singleton of the global state public static state: State; - public readonly layoutToUse = new UIEventSource(undefined, "layoutToUse"); + public readonly layoutToUse : LayoutConfig; /** The mapping from id -> UIEventSource @@ -83,7 +83,9 @@ export default class State { public readonly featureSwitchExportAsPdf: UIEventSource; public readonly overpassUrl: UIEventSource; public readonly overpassTimeout: UIEventSource; - public readonly overpassMaxZoom: UIEventSource = new UIEventSource(20); + + + public readonly overpassMaxZoom: UIEventSource = new UIEventSource(17, "overpass-max-zoom: point to switch between OSM-api and overpass"); public featurePipeline: FeaturePipeline; @@ -155,7 +157,7 @@ export default class State { constructor(layoutToUse: LayoutConfig) { const self = this; - this.layoutToUse.setData(layoutToUse); + this.layoutToUse = layoutToUse; // -- Location control initialization { @@ -192,14 +194,7 @@ export default class State { lat.setData(latlonz.lat); lon.setData(latlonz.lon); }); - - this.layoutToUse.addCallback((layoutToUse) => { - const lcd = self.locationControl.data; - lcd.zoom = lcd.zoom ?? layoutToUse?.startZoom; - lcd.lat = lcd.lat ?? layoutToUse?.startLat; - lcd.lon = lcd.lon ?? layoutToUse?.startLon; - self.locationControl.ping(); - }); + } // Helper function to initialize feature switches @@ -208,28 +203,19 @@ export default class State { deflt: (layout: LayoutConfig) => boolean, documentation: string ): UIEventSource { - const queryParameterSource = QueryParameters.GetQueryParameter( + + const defaultValue = deflt(self.layoutToUse); + const queryParam = QueryParameters.GetQueryParameter( key, - undefined, + "" + defaultValue, documentation ); - // I'm so sorry about someone trying to decipher this // It takes the current layout, extracts the default value for this query parameter. A query parameter event source is then retrieved and flattened - return UIEventSource.flatten( - self.layoutToUse.map((layout) => { - const defaultValue = deflt(layout); - const queryParam = QueryParameters.GetQueryParameter( - key, - "" + defaultValue, - documentation - ); - return queryParam.map((str) => - str === undefined ? defaultValue : str !== "false" - ); - }), - [queryParameterSource] - ); + return queryParam.map((str) => + str === undefined ? defaultValue : str !== "false" + ) + } // Feature switch initialization - not as a function as the UIEventSources are readonly @@ -412,11 +398,11 @@ export default class State { Locale.language .addCallback((currentLanguage) => { - const layoutToUse = self.layoutToUse.data; + const layoutToUse = self.layoutToUse; if (layoutToUse === undefined) { return; } - if (this.layoutToUse.data.language.indexOf(currentLanguage) < 0) { + if (this.layoutToUse.language.indexOf(currentLanguage) < 0) { console.log( "Resetting language to", layoutToUse.language[0], diff --git a/UI/BigComponents/Attribution.ts b/UI/BigComponents/Attribution.ts index 9b1ddb013..471556798 100644 --- a/UI/BigComponents/Attribution.ts +++ b/UI/BigComponents/Attribution.ts @@ -16,13 +16,13 @@ export default class Attribution extends Combine { constructor(location: UIEventSource, userDetails: UIEventSource, - layoutToUse: UIEventSource, + layoutToUse: LayoutConfig, currentBounds: UIEventSource) { const mapComplete = new Link(`Mapcomplete ${Constants.vNumber}`, 'https://github.com/pietervdvn/MapComplete', true); const reportBug = new Link(Svg.bug_ui().SetClass("small-image"), "https://github.com/pietervdvn/MapComplete/issues", true); - const layoutId = layoutToUse?.data?.id; + const layoutId = layoutToUse?.id; const now = new Date() // Note: getMonth is zero-index, we want 1-index but with one substracted, so it checks out! const startDate = now.getFullYear() + "-" + now.getMonth() + "-" + now.getDate() diff --git a/UI/BigComponents/AttributionPanel.ts b/UI/BigComponents/AttributionPanel.ts index 542326314..c18c8d287 100644 --- a/UI/BigComponents/AttributionPanel.ts +++ b/UI/BigComponents/AttributionPanel.ts @@ -20,11 +20,11 @@ export default class AttributionPanel extends Combine { private static LicenseObject = AttributionPanel.GenerateLicenses(); - constructor(layoutToUse: UIEventSource, contributions: UIEventSource>) { + constructor(layoutToUse: LayoutConfig, contributions: UIEventSource>) { super([ Translations.t.general.attribution.attributionContent, - ((layoutToUse.data.maintainer ?? "") == "") ? "" : Translations.t.general.attribution.themeBy.Subs({author: layoutToUse.data.maintainer}), - layoutToUse.data.credits, + ((layoutToUse.maintainer ?? "") == "") ? "" : Translations.t.general.attribution.themeBy.Subs({author: layoutToUse.maintainer}), + layoutToUse.credits, "
", new Attribution(State.state.locationControl, State.state.osmConnection.userDetails, State.state.layoutToUse, State.state.currentBounds), "
", @@ -65,7 +65,7 @@ export default class AttributionPanel extends Combine { "
", AttributionPanel.CodeContributors(), "

", Translations.t.general.attribution.iconAttribution.title.Clone().SetClass("pt-6 pb-3"), "

", - ...Utils.NoNull(Array.from(layoutToUse.data.ExtractImages())) + ...Utils.NoNull(Array.from(layoutToUse.ExtractImages())) .map(AttributionPanel.IconAttribution) ]); this.SetClass("flex flex-col link-underline overflow-hidden") diff --git a/UI/BigComponents/DownloadPanel.ts b/UI/BigComponents/DownloadPanel.ts index 500d28e19..f23d98747 100644 --- a/UI/BigComponents/DownloadPanel.ts +++ b/UI/BigComponents/DownloadPanel.ts @@ -26,7 +26,7 @@ export class DownloadPanel extends Toggle { const t = Translations.t.general.download - const name = State.state.layoutToUse.data.id; + const name = State.state.layoutToUse.id; const includeMetaToggle = new CheckBoxes([t.includeMetaData.Clone()]) const metaisIncluded = includeMetaToggle.GetValue().map(selected => selected.length > 0) diff --git a/UI/BigComponents/FullWelcomePaneWithTabs.ts b/UI/BigComponents/FullWelcomePaneWithTabs.ts index f6574f04b..8ee36ecec 100644 --- a/UI/BigComponents/FullWelcomePaneWithTabs.ts +++ b/UI/BigComponents/FullWelcomePaneWithTabs.ts @@ -19,7 +19,7 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen { constructor(isShown: UIEventSource) { - const layoutToUse = State.state.layoutToUse.data; + const layoutToUse = State.state.layoutToUse; super( () => layoutToUse.title.Clone(), () => FullWelcomePaneWithTabs.GenerateContents(layoutToUse, State.state.osmConnection.userDetails, isShown), diff --git a/UI/BigComponents/MoreScreen.ts b/UI/BigComponents/MoreScreen.ts index 9d8fa44f9..01e4b9f95 100644 --- a/UI/BigComponents/MoreScreen.ts +++ b/UI/BigComponents/MoreScreen.ts @@ -126,7 +126,7 @@ export default class MoreScreen extends Combine { if (layout.hideFromOverview) { return undefined; } - if (layout.id === State.state.layoutToUse.data?.id) { + if (layout.id === State.state.layoutToUse?.id) { return undefined; } diff --git a/UI/BigComponents/ShareScreen.ts b/UI/BigComponents/ShareScreen.ts index 9b97ef441..32e1b0ce0 100644 --- a/UI/BigComponents/ShareScreen.ts +++ b/UI/BigComponents/ShareScreen.ts @@ -17,7 +17,7 @@ import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; export default class ShareScreen extends Combine { constructor(layout: LayoutConfig = undefined, layoutDefinition: string = undefined) { - layout = layout ?? State.state?.layoutToUse?.data; + layout = layout ?? State.state?.layoutToUse; layoutDefinition = layoutDefinition ?? State.state?.layoutDefinition; const tr = Translations.t.general.sharescreen; diff --git a/UI/BigComponents/ThemeIntroductionPanel.ts b/UI/BigComponents/ThemeIntroductionPanel.ts index 8c4add4d9..75c5b6f55 100644 --- a/UI/BigComponents/ThemeIntroductionPanel.ts +++ b/UI/BigComponents/ThemeIntroductionPanel.ts @@ -2,21 +2,17 @@ import State from "../../State"; import Combine from "../Base/Combine"; import LanguagePicker from "../LanguagePicker"; import Translations from "../i18n/Translations"; -import {VariableUiElement} from "../Base/VariableUIElement"; import Toggle from "../Input/Toggle"; import {SubtleButton} from "../Base/SubtleButton"; import Svg from "../../Svg"; import {UIEventSource} from "../../Logic/UIEventSource"; -export default class ThemeIntroductionPanel extends VariableUiElement { +export default class ThemeIntroductionPanel extends Combine { constructor(isShown: UIEventSource) { + const layout = State.state.layoutToUse - const languagePicker = - new VariableUiElement( - State.state.layoutToUse.map(layout => LanguagePicker.CreateLanguagePicker(layout.language, Translations.t.general.pickLanguage.Clone())) - ) - ; + const languagePicker = LanguagePicker.CreateLanguagePicker(layout.language, Translations.t.general.pickLanguage.Clone()) const toTheMap = new SubtleButton( undefined, @@ -53,8 +49,7 @@ export default class ThemeIntroductionPanel extends VariableUiElement { State.state.featureSwitchUserbadge ) - - super(State.state.layoutToUse.map(layout => new Combine([ + super([ layout.description.Clone(), "

", toTheMap, @@ -63,7 +58,7 @@ export default class ThemeIntroductionPanel extends VariableUiElement { "
", languagePicker, ...layout.CustomCodeSnippets() - ]))) + ]) this.SetClass("link-underline") } diff --git a/UI/BigComponents/UserBadge.ts b/UI/BigComponents/UserBadge.ts index 62f74e0ae..006b1823a 100644 --- a/UI/BigComponents/UserBadge.ts +++ b/UI/BigComponents/UserBadge.ts @@ -47,7 +47,7 @@ export default class UserBadge extends Toggle { }); const linkStyle = "flex items-baseline" - const languagePicker = (LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.data.language) ?? new FixedUiElement("")) + const languagePicker = (LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.language) ?? new FixedUiElement("")) .SetStyle("width:min-content;"); let messageSpan = diff --git a/UI/Image/ImageUploadFlow.ts b/UI/Image/ImageUploadFlow.ts index 2a8053523..432541395 100644 --- a/UI/Image/ImageUploadFlow.ts +++ b/UI/Image/ImageUploadFlow.ts @@ -55,7 +55,7 @@ export class ImageUploadFlow extends Toggle { const tags = tagsSource.data; - const layout = State.state?.layoutToUse?.data + const layout = State.state?.layoutToUse let matchingLayer: LayerConfig = undefined for (const layer of layout?.layers ?? []) { if (layer.source.osmTags.matchesProperties(tags)) { diff --git a/UI/Input/DropDown.ts b/UI/Input/DropDown.ts index fe8f8bc98..147ad0f50 100644 --- a/UI/Input/DropDown.ts +++ b/UI/Input/DropDown.ts @@ -47,7 +47,7 @@ export class DropDown extends InputElement { } options = options ?? {} - options.select_class = options.select_class ?? 'bg-indigo-100 p-1 rounded hover:bg-indigo-200' + options.select_class = options.select_class ?? 'bg-indigo-100 p-1 rounded hover:bg-indigo-200 w-full' { diff --git a/UI/Input/LocationInput.ts b/UI/Input/LocationInput.ts index 262d9a7db..e826773ab 100644 --- a/UI/Input/LocationInput.ts +++ b/UI/Input/LocationInput.ts @@ -39,7 +39,7 @@ export default class LocationInput extends InputElement { private readonly _maxSnapDistance: number private readonly _snappedPointTags: any; private readonly _bounds: UIEventSource; - public readonly _matching_layer: UIEventSource; + public readonly _matching_layer: LayerConfig; constructor(options: { mapBackground?: UIEventSource, @@ -63,18 +63,17 @@ export default class LocationInput extends InputElement { if (self._snappedPointTags !== undefined) { - this._matching_layer = State.state.layoutToUse.map(layout => { + const layout = State.state.layoutToUse - for (const layer of layout.layers) { - if (layer.source.osmTags.matchesProperties(self._snappedPointTags)) { - return layer - } + let matchingLayer = LocationInput.matchLayer + for (const layer of layout.layers) { + if (layer.source.osmTags.matchesProperties(self._snappedPointTags)) { + matchingLayer = layer } - console.error("No matching layer found for tags ", self._snappedPointTags) - return LocationInput.matchLayer - }) + } + this._matching_layer = matchingLayer; } else { - this._matching_layer = new UIEventSource(LocationInput.matchLayer) + this._matching_layer = LocationInput.matchLayer } this._snappedPoint = options.centerLocation.map(loc => { @@ -176,7 +175,7 @@ export default class LocationInput extends InputElement { enablePopups: false, zoomToFeatures: false, leafletMap: map.leafletMap, - layerToShow: this._matching_layer.data + layerToShow: this._matching_layer }) } diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 7814cbbdc..5b15cfdaa 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -316,10 +316,10 @@ export default class SpecialVisualizations { const generateShareData = () => { - const title = state?.layoutToUse?.data?.title?.txt ?? "MapComplete"; + const title = state?.layoutToUse?.title?.txt ?? "MapComplete"; let matchingLayer: LayerConfig = undefined; - for (const layer of (state?.layoutToUse?.data?.layers ?? [])) { + for (const layer of (state?.layoutToUse?.layers ?? [])) { if (layer.source.osmTags.matchesProperties(tagSource?.data)) { matchingLayer = layer } @@ -337,7 +337,7 @@ export default class SpecialVisualizations { return { title: name, url: url, - text: state?.layoutToUse?.data?.shortDescription?.txt ?? "MapComplete" + text: state?.layoutToUse?.shortDescription?.txt ?? "MapComplete" } } @@ -363,15 +363,14 @@ export default class SpecialVisualizations { if (value === undefined) { return undefined } - const allUnits = [].concat(...state.layoutToUse.data.layers.map(lyr => lyr.units)) + const allUnits = [].concat(...state.layoutToUse.layers.map(lyr => lyr.units)) const unit = allUnits.filter(unit => unit.isApplicableToKey(key))[0] if (unit === undefined) { return value; } return unit.asHumanLongValue(value); - }, - [state.layoutToUse]) + }) ) } }, @@ -410,7 +409,7 @@ There are also some technicalities in your theme to keep in mind: A reference number to the original dataset is an excellen way to do this `, constr: (state, tagSource, args) => { - if (!state.layoutToUse.data.official && !state.featureSwitchIsTesting.data) { + if (!state.layoutToUse.official && !state.featureSwitchIsTesting.data) { return new Combine([new FixedUiElement("The import button is disabled for unofficial themes to prevent accidents.").SetClass("alert"), new FixedUiElement("To test, add 'test=true' to the URL. The changeset will be printed in the console. Please open a PR to officialize this theme to actually enable the import button.")]) } From c34f558c67582bb3f2aea88d4f5b7996ddcf6013 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Tue, 28 Sep 2021 18:40:45 +0200 Subject: [PATCH 37/65] Move json data injection to approppriate place, fixes tests --- Utils.ts | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Utils.ts b/Utils.ts index aced008ad..424784205 100644 --- a/Utils.ts +++ b/Utils.ts @@ -296,12 +296,6 @@ export class Utils { } public static download(url: string, headers?: any): Promise { - const injected = Utils.injectedDownloads[url] - if (injected !== undefined) { - console.log("Using injected resource for test for URL", url) - return new Promise((resolve, _) => resolve(injected)) - } - if (this.externalDownloadFunction !== undefined) { return this.externalDownloadFunction(url, headers) } @@ -311,8 +305,8 @@ export class Utils { xhr.onload = () => { if (xhr.status == 200) { resolve(xhr.response) - } else if (xhr.status === 509 || xhr.status === 429){ - reject("rate limited") + } else if (xhr.status === 509 || xhr.status === 429) { + reject("rate limited") } else { reject(xhr.statusText) } @@ -331,8 +325,18 @@ export class Utils { } public static async downloadJson(url: string, headers?: any): Promise { + const injected = Utils.injectedDownloads[url] + if (injected !== undefined) { + console.log("Using injected resource for test for URL", url) + return new Promise((resolve, _) => resolve(injected)) + } const data = await Utils.download(url, Utils.Merge({"accept": "application/json"}, headers ?? {})) - return JSON.parse(data) + try { + return JSON.parse(data) + } catch (e) { + console.error("Could not parse ", data, "due to", e, "\n", e.stack) + throw e; + } } /** From e9aa8d347f250c0110011781b8479c90f1c54f30 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Tue, 28 Sep 2021 18:41:08 +0200 Subject: [PATCH 38/65] Small, experimental fixes to the themes --- assets/themes/bicyclelib/bicyclelib.json | 3 +-- assets/themes/cycle_highways/cycle_highways.json | 2 +- assets/themes/personal/personal.json | 2 +- assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json | 4 ++++ langs/themes/en.json | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/assets/themes/bicyclelib/bicyclelib.json b/assets/themes/bicyclelib/bicyclelib.json index c0c85b13b..bc251907b 100644 --- a/assets/themes/bicyclelib/bicyclelib.json +++ b/assets/themes/bicyclelib/bicyclelib.json @@ -48,7 +48,6 @@ "override": { "minZoom": 0 } - }, - + } ] } \ No newline at end of file diff --git a/assets/themes/cycle_highways/cycle_highways.json b/assets/themes/cycle_highways/cycle_highways.json index 53dea9cc8..08b7c8556 100644 --- a/assets/themes/cycle_highways/cycle_highways.json +++ b/assets/themes/cycle_highways/cycle_highways.json @@ -170,7 +170,7 @@ ] }, { - "id":"ref-alt", + "id": "ref-alt", "options": [ { "question": "Reference contains 'alt'", diff --git a/assets/themes/personal/personal.json b/assets/themes/personal/personal.json index 88296088d..2896e5fbc 100644 --- a/assets/themes/personal/personal.json +++ b/assets/themes/personal/personal.json @@ -12,7 +12,7 @@ "zh_Hant": "個人化主題" }, "description": { - "en": "Create a personal theme based on all the available layers of all themes. Open the layer selection to select one or more layers.", + "en": "Create a personal theme based on all the available layers of all themes. In order to show some data, open layer selection", "nl": "Stel je eigen thema samen door lagen te combineren van alle andere themas", "es": "Crea una interficie basada en todas las capas disponibles de todas las interficies", "ca": "Crea una interfície basada en totes les capes disponibles de totes les interfícies", diff --git a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json index 7bef2f129..aeea7f806 100644 --- a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json +++ b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json @@ -39,5 +39,9 @@ "binocular", "observation_tower" ], + "overiddeAll": { + "minZoomVisible": 0 + }, + "hideFromOverview": true } \ No newline at end of file diff --git a/langs/themes/en.json b/langs/themes/en.json index e2b1d6591..b62768bef 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -1216,7 +1216,7 @@ "title": "Parking" }, "personal": { - "description": "Create a personal theme based on all the available layers of all themes", + "description": "Create a personal theme based on all the available layers of all themes. In order to show some data, open layer selection", "title": "Personal theme" }, "playgrounds": { From e723427b99b77744af49c831c916bf098a812f94 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Tue, 28 Sep 2021 22:33:09 +0200 Subject: [PATCH 39/65] Fix #477 --- scripts/generateWikiPage.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/generateWikiPage.ts b/scripts/generateWikiPage.ts index ca03e3fb5..688dfd2fe 100644 --- a/scripts/generateWikiPage.ts +++ b/scripts/generateWikiPage.ts @@ -20,8 +20,8 @@ function generateWikiEntry(layout: LayoutConfig) { |name= [https://mapcomplete.osm.be/${layout.id} ${layout.id}] |region= Worldwide |lang= ${languages} -|descr= A MapComplete theme: ${Translations.W(layout.description) - .InnerRenderAsString() +|descr= A MapComplete theme: ${Translations.WT(layout.description) + .textFor("en") .replace(".*<\/a>/, "]]") } From 231f4f2c971f9713781a22f4b9c51884d09d50d6 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 01:10:25 +0200 Subject: [PATCH 40/65] New wikipage --- Docs/wikiIndex.txt | 280 +++++++++++++++++++++++++++++++-------------- 1 file changed, 196 insertions(+), 84 deletions(-) diff --git a/Docs/wikiIndex.txt b/Docs/wikiIndex.txt index f9d8ab6da..4bd9edfad 100644 --- a/Docs/wikiIndex.txt +++ b/Docs/wikiIndex.txt @@ -4,8 +4,8 @@ {{service_item |name= [https://mapcomplete.osm.be/personal personal] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:es|en}}, {{#language:ca|en}}, {{#language:gl|en}}, {{#language:de|en}} -|descr= A MapComplete theme: Create a personal theme based on all the available layers of all themes +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:es|en}}, {{#language:ca|en}}, {{#language:gl|en}}, {{#language:fr|en}}, {{#language:de|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:ru|en}} +|descr= A MapComplete theme: Create a personal theme based on all the available layers of all themes. In order to show some data, open [[#filter]] |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png |genre= POI, editor, personal @@ -13,25 +13,29 @@ {{service_item |name= [https://mapcomplete.osm.be/cyclofix cyclofix] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:gl|en}}, {{#language:de|en}} +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:gl|en}}, {{#language:de|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:it|en}} |descr= A MapComplete theme: The goal of this map is to present cyclists with an easy-to-use solution to find the appropriate infrastructure for their needs.

You can track your precise location (mobile only) and select layers that are relevant for you in the bottom left corner. You can also use this tool to add or edit pins (points of interest) to the map and provide more data by answering the questions.

All changes you make will automatically be saved in the global database of OpenStreetMap and can be freely re-used by others.

For more information about the cyclofix project, go to [[https://cyclofix.osm.be/]]. |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png |genre= POI, editor, cyclofix }} {{service_item -|name= [https://mapcomplete.osm.be/aed aed] +|name= [https://mapcomplete.osm.be/hailhydrant hailhydrant] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:ca|en}}, {{#language:es|en}}, {{#language:fr|en}}, {{#language:nl|en}}, {{#language:de|en}} -|descr= A MapComplete theme: On this map, one can find and mark nearby defibrillators -|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|lang= {{#language:en|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:ru|en}}, {{#language:fr|en}}, {{#language:nb_NO|en}}, {{#language:it|en}}, {{#language:id|en}} +|descr= A MapComplete theme: On this map you can find and update hydrants, fire stations, ambulance stations, and extinguishers in your favorite neighborhoods. + +You can track your precise location (mobile only) and select layers that are relevant for you in the bottom left corner. You can also use this tool to add or edit pins (points of interest) to the map and provide additional details by answering available questions. + +All changes you make will automatically be saved in the global database of OpenStreetMap and can be freely re-used by others. +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Erwin Olario;]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, aed +|genre= POI, editor, hailhydrant }} {{service_item |name= [https://mapcomplete.osm.be/bookcases bookcases] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:fr|en}} +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:fr|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:it|en}}, {{#language:pt_BR|en}} |descr= A MapComplete theme: A public bookcase is a small streetside cabinet, box, old phone boot or some other objects where books are stored. Everyone can place or take a book. This map aims to collect all these bookcases. You can discover new bookcases nearby and, with a free OpenStreetMap account, quickly add your favourite bookcases. |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png @@ -40,47 +44,173 @@ {{service_item |name= [https://mapcomplete.osm.be/toilets toilets] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:de|en}}, {{#language:fr|en}} +|lang= {{#language:en|en}}, {{#language:de|en}}, {{#language:fr|en}}, {{#language:nl|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:pl|en}} |descr= A MapComplete theme: A map of public toilets |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png |genre= POI, editor, toilets }} {{service_item -|name= [https://mapcomplete.osm.be/artworks artworks] +|name= [https://mapcomplete.osm.be/aed aed] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:de|en}} -|descr= A MapComplete theme: Welcome to Open Artwork Map, a map of statues, busts, grafittis, ... all over the world +|lang= {{#language:en|en}}, {{#language:ca|en}}, {{#language:es|en}}, {{#language:fr|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:hu|en}}, {{#language:id|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:nb_NO|en}}, {{#language:sv|en}}, {{#language:pl|en}}, {{#language:pt_BR|en}} +|descr= A MapComplete theme: On this map, one can find and mark nearby defibrillators |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, artworks +|genre= POI, editor, aed +}} +{{service_item +|name= [https://mapcomplete.osm.be/artwork artwork] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:de|en}}, {{#language:hu|en}}, {{#language:id|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:sv|en}}, {{#language:pl|en}}, {{#language:es|en}}, {{#language:nb_NO|en}} +|descr= A MapComplete theme: Welcome to Open Artwork Map, a map of statues, busts, grafittis and other artwork all over the world +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, artwork +}} +{{service_item +|name= [https://mapcomplete.osm.be/benches benches] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:de|en}}, {{#language:fr|en}}, {{#language:nl|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:nb_NO|en}}, {{#language:pt_BR|en}} +|descr= A MapComplete theme: This map shows all benches that are recorded in OpenStreetMap: Individual benches, and benches belonging to public transport stops or shelters. With an OpenStreetMap account, you can map new benches or edit details of existing benches. +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Florian Edelmann;]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, benches +}} +{{service_item +|name= [https://mapcomplete.osm.be/bicyclelib bicyclelib] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:fr|en}}, {{#language:zh_Hant|en}}, {{#language:nb_NO|en}}, {{#language:de|en}}, {{#language:pt_BR|en}} +|descr= A MapComplete theme: A bicycle library is a place where bicycles can be lent, often for a small yearly fee. A notable use case are bicycle libraries for kids, which allows them to change for a bigger bike when they've outgrown their current bike +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, bicyclelib +}} +{{service_item +|name= [https://mapcomplete.osm.be/binoculars binoculars] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:nl|en}} +|descr= A MapComplete theme: A map with binoculars fixed in place with a pole. It can typically be found on touristic locations, viewpoints, on top of panoramic towers or occasionally on a nature reserve. +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, binoculars +}} +{{service_item +|name= [https://mapcomplete.osm.be/cafes_and_pubs cafes_and_pubs] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:fr|en}}, {{#language:en|en}} +|descr= A MapComplete theme: Cafés, kroegen en drinkgelegenheden +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, cafes_and_pubs +}} +{{service_item +|name= [https://mapcomplete.osm.be/campersite campersite] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:fr|en}}, {{#language:zh_Hant|en}}, {{#language:pt_BR|en}}, {{#language:id|en}}, {{#language:nb_NO|en}} +|descr= A MapComplete theme: This site collects all official camper stopover places and places where you can dump grey and black water. You can add details about the services provided and the cost. Add pictures and reviews. This is a website and a webapp. The data is stored in OpenStreetMap, so it will be free forever and can be re-used by any app. +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by joost schouppe;]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, campersite +}} +{{service_item +|name= [https://mapcomplete.osm.be/charging_stations charging_stations] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:id|en}}, {{#language:it|en}}, {{#language:ja|en}}, {{#language:ru|en}}, {{#language:zh_Hant|en}}, {{#language:it|en}}, {{#language:nl|en}}, {{#language:nb_NO|en}} +|descr= A MapComplete theme: On this open map, one can find and mark information about charging stations +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, charging_stations +}} +{{service_item +|name= [https://mapcomplete.osm.be/climbing climbing] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:de|en}}, {{#language:en|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:nb_NO|en}}, {{#language:it|en}}, {{#language:ca|en}}, {{#language:fr|en}}, {{#language:id|en}} +|descr= A MapComplete theme: On this map you will find various climbing opportunities such as climbing gyms, bouldering halls and rocks in nature. +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Christian Neumann ;]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, climbing +}} +{{service_item +|name= [https://mapcomplete.osm.be/cycle_infra cycle_infra] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:nl|en}} +|descr= A MapComplete theme: A map where you can view and edit things related to the bicycle infrastructure. Made during #osoc21. +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, cycle_infra +}} +{{service_item +|name= [https://mapcomplete.osm.be/cyclestreets cyclestreets] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:en|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:nb_NO|en}}, {{#language:it|en}}, {{#language:ru|en}} +|descr= A MapComplete theme: A cyclestreet is is a street where motorized traffic is not allowed to overtake cyclists. They are signposted by a special traffic sign. Cyclestreets can be found in the Netherlands and Belgium, but also in Germany and France. +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, cyclestreets +}} +{{service_item +|name= [https://mapcomplete.osm.be/drinking_water drinking_water] +|region= Worldwide +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:it|en}} +|descr= A MapComplete theme: On this map, publicly accessible drinking water spots are shown and can be easily added +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, drinking_water +}} +{{service_item +|name= [https://mapcomplete.osm.be/facadegardens facadegardens] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:en|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:it|en}}, {{#language:fr|en}}, {{#language:nb_NO|en}}, {{#language:ru|en}} +|descr= A MapComplete theme: [[https://nl.wikipedia.org/wiki/Geveltuin' target=_blank>Facade gardens
, green facades and trees in the city not only bring peace and quiet, but also a more beautiful city, greater biodiversity, a cooling effect and better air quality.
Klimaan VZW and Mechelen Klimaatneutraal want to map existing and new facade gardens as an example for people who want to build their own garden or for city walkers who love nature.
More info about the project at klimaan.be. +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by joost schouppe; stla;]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, facadegardens +}} +{{service_item +|name= [https://mapcomplete.osm.be/food food] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:fr|en}}, {{#language:en|en}} +|descr= A MapComplete theme: Restaurants en fast food +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, food +}} +{{service_item +|name= [https://mapcomplete.osm.be/fritures fritures] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:fr|en}}, {{#language:en|en}}, {{#language:ja|en}}, {{#language:ca|en}}, {{#language:id|en}}, {{#language:ru|en}}, {{#language:it|en}}, {{#language:nb_NO|en}} +|descr= A MapComplete theme: Op deze kaart vind je je favoriete frituur! +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, fritures }} {{service_item |name= [https://mapcomplete.osm.be/ghostbikes ghostbikes] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}} +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:ja|en}}, {{#language:nb_NO|en}}, {{#language:zh_Hant|en}}, {{#language:fr|en}}, {{#language:eo|en}}, {{#language:es|en}}, {{#language:fi|en}}, {{#language:gl|en}}, {{#language:hu|en}}, {{#language:it|en}}, {{#language:pl|en}}, {{#language:pt_BR|en}}, {{#language:ru|en}}, {{#language:sv|en}} |descr= A MapComplete theme: A ghost bike is a memorial for a cyclist who died in a traffic accident, in the form of a white bicycle placed permanently near the accident location.

On this map, one can see all the ghost bikes which are known by OpenStreetMap. Is a ghost bike missing? Everyone can add or update information here - you only need to have a (free) OpenStreetMap account. |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png |genre= POI, editor, ghostbikes }} {{service_item -|name= [https://mapcomplete.osm.be/shops shops] +|name= [https://mapcomplete.osm.be/hackerspaces hackerspaces] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:fr|en}} -|descr= A MapComplete theme: On this map, one can mark basic information about shops, add opening hours and phone numbers +|lang= {{#language:en|en}} +|descr= A MapComplete theme: On this map you can see hackerspaces, add a new hackerspace or update data directly |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, shops +|genre= POI, editor, hackerspaces }} {{service_item -|name= [https://mapcomplete.osm.be/drinking_water drinking_water] +|name= [https://mapcomplete.osm.be/maps maps] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}} -|descr= A MapComplete theme: On this map, publicly accessible drinkging water spots are shown and can be easily added +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:ru|en}} +|descr= A MapComplete theme: On this map you can find all maps OpenStreetMap knows - typically a big map on an information board showing the area, city or region, e.g. a tourist map on the back of a billboard, a map of a nature reserve, a map of cycling networks in the region, ...)

If a map is missing, you can easily map this map on OpenStreetMap. |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, drinking_water +|genre= POI, editor, maps }} {{service_item |name= [https://mapcomplete.osm.be/nature nature] @@ -92,111 +222,93 @@ |genre= POI, editor, nature }} {{service_item -|name= [https://mapcomplete.osm.be/fietsstraten fietsstraten] -|region= Worldwide -|lang= {{#language:nl|en}} -|descr= A MapComplete theme: Een fietsstraat is een straat waar
  • automobilisten geen fietsers mogen inhalen
  • Er een maximumsnelheid van 30km/u geldt
  • Fietsers gemotoriseerde voortuigen links mogen inhalen
  • Fietsers nog steeds voorrang aan rechts moeten verlenen - ook aan auto's en voetgangers op het zebrapad


Op deze open kaart kan je alle gekende fietsstraten zien en kan je ontbrekende fietsstraten aanduiden. Om de kaart aan te passen, moet je je aanmelden met OpenStreetMap en helemaal inzoomen tot straatniveau. -|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} -|image= MapComplete_Screenshot.png -|genre= POI, editor, fietsstraten -}} -{{service_item -|name= [https://mapcomplete.osm.be/bicyclelib bicyclelib] +|name= [https://mapcomplete.osm.be/observation_towers observation_towers] |region= Worldwide |lang= {{#language:en|en}}, {{#language:nl|en}} -|descr= A MapComplete theme: A bicycle library is a place where bicycles can be lent, often for a small yearly fee. A notable use case are bicycle libraries for kids, which allows them to change for a bigger bike when they've outgrown their current bike +|descr= A MapComplete theme: Publicly accessible towers to enjoy the view |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, bicyclelib +|genre= POI, editor, observation_towers }} {{service_item -|name= [https://mapcomplete.osm.be/maps maps] +|name= [https://mapcomplete.osm.be/openwindpowermap openwindpowermap] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:fr|en}} -|descr= A MapComplete theme: On this map you can find all maps OpenStreetMap knows - typically a big map on an information board showing the area, city or region, e.g. a tourist map on the back of a billboard, a map of a nature reserve, a map of cycling networks in the region, ...)

If a map is missing, you can easily map this map on OpenStreetMap. +|lang= {{#language:en|en}}, {{#language:fr|en}}, {{#language:nl|en}} +|descr= A MapComplete theme: A map for showing and editing wind turbines. +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Seppe Santens;]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, openwindpowermap +}} +{{service_item +|name= [https://mapcomplete.osm.be/parkings parkings] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:en|en}} +|descr= A MapComplete theme: This map shows different parking spots |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, maps +|genre= POI, editor, parkings }} {{service_item -|name= [https://mapcomplete.osm.be/fritures fritures] +|name= [https://mapcomplete.osm.be/playgrounds playgrounds] |region= Worldwide -|lang= {{#language:nl|en}}, {{#language:fr|en}} -|descr= A MapComplete theme: Op deze kaart vind je je favoriete frituur! +|lang= {{#language:nl|en}}, {{#language:en|en}}, {{#language:fr|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:ru|en}} +|descr= A MapComplete theme: On this map, you find playgrounds and can add more information |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, fritures +|genre= POI, editor, playgrounds }} {{service_item -|name= [https://mapcomplete.osm.be/benches benches] +|name= [https://mapcomplete.osm.be/shops shops] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:de|en}}, {{#language:fr|en}} -|descr= A MapComplete theme: This map shows all benches that are recorded in OpenStreetMap: Individual benches, and benches belonging to public transport stops or shelters. With an OpenStreetMap account, you can map new benches or edit details of existing benches. -|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Florian Edelmann;]}} -|image= MapComplete_Screenshot.png -|genre= POI, editor, benches -}} -{{service_item -|name= [https://mapcomplete.osm.be/charging_stations charging_stations] -|region= Worldwide -|lang= {{#language:en|en}} -|descr= A MapComplete theme: On this open map, one can find and mark information about charging stations +|lang= {{#language:en|en}}, {{#language:fr|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:ru|en}}, {{#language:nl|en}}, {{#language:ca|en}}, {{#language:id|en}} +|descr= A MapComplete theme: On this map, one can mark basic information about shops, add opening hours and phone numbers |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, charging_stations +|genre= POI, editor, shops +}} +{{service_item +|name= [https://mapcomplete.osm.be/sport_pitches sport_pitches] +|region= Worldwide +|lang= {{#language:nl|en}}, {{#language:fr|en}}, {{#language:en|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:ru|en}} +|descr= A MapComplete theme: A sport pitch is an area where sports are played +|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} +|image= MapComplete_Screenshot.png +|genre= POI, editor, sport_pitches }} {{service_item |name= [https://mapcomplete.osm.be/surveillance surveillance] |region= Worldwide -|lang= {{#language:en|en}}, {{#language:nl|en}} +|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:fr|en}}, {{#language:pl|en}} |descr= A MapComplete theme: On this open map, you can find surveillance cameras. |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png |genre= POI, editor, surveillance }} {{service_item -|name= [https://mapcomplete.osm.be/climbing climbing] -|region= Worldwide -|lang= {{#language:de|en}}, {{#language:en|en}}, {{#language:nl|en}} -|descr= A MapComplete theme: On this map you will find various climbing opportunities such as climbing gyms, bouldering halls and rocks in nature. -|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Christian Neumann ;]}} -|image= MapComplete_Screenshot.png -|genre= POI, editor, climbing -}} -{{service_item -|name= [https://mapcomplete.osm.be/playgrounds playgrounds] -|region= Worldwide -|lang= {{#language:nl|en}} -|descr= A MapComplete theme: Op deze kaart vind je speelplekken zoals speeltuinen, speelbossen en sportterreinen -|material= {{yes|[https://mapcomplete.osm.be/ Yes]}} -|image= MapComplete_Screenshot.png -|genre= POI, editor, playgrounds -}} -{{service_item |name= [https://mapcomplete.osm.be/trees trees] |region= Worldwide -|lang= {{#language:nl|en}}, {{#language:en|en}} +|lang= {{#language:nl|en}}, {{#language:en|en}}, {{#language:fr|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:pl|en}} |descr= A MapComplete theme: Map all the trees! |material= {{yes|[https://mapcomplete.osm.be/ Yes, by Midgard;]}} |image= MapComplete_Screenshot.png |genre= POI, editor, trees }} {{service_item -|name= [https://mapcomplete.osm.be/campersite campersite] +|name= [https://mapcomplete.osm.be/uk_addresses uk_addresses] |region= Worldwide |lang= {{#language:en|en}} -|descr= A MapComplete theme: This site collects all official camper stopover places and places where you can dump grey and black water. You can add details about the services provided and the cost. Add pictures and reviews. This is a website and a webapp. The data is stored in OpenStreetMap, so it will be free forever and can be re-used by any app. -|material= {{yes|[https://mapcomplete.osm.be/ Yes, by joost schouppe;]}} +|descr= A MapComplete theme: Contribute to OpenStreetMap by filling out address information +|material= {{yes|[https://mapcomplete.osm.be/ Yes, by Pieter Vander Vennet, Rob Nickerson, Russ Garrett;]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, campersite +|genre= POI, editor, uk_addresses }} {{service_item -|name= [https://mapcomplete.osm.be/sport_pitches sport_pitches] +|name= [https://mapcomplete.osm.be/waste_basket waste_basket] |region= Worldwide -|lang= {{#language:nl|en}} -|descr= A MapComplete theme: Een sportveld is een ingerichte plaats met infrastructuur om een sport te beoefenen +|lang= {{#language:en|en}}, {{#language:nl|en}} +|descr= A MapComplete theme: On this map, you'll find waste baskets near you. If a waste basket is missing on this map, you can add it yourself |material= {{yes|[https://mapcomplete.osm.be/ Yes]}} |image= MapComplete_Screenshot.png -|genre= POI, editor, sport_pitches +|genre= POI, editor, waste_basket }} |} \ No newline at end of file From 6890c5189e79d5a4f5d044ba09d3aa69c1c1551d Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 01:12:29 +0200 Subject: [PATCH 41/65] More refactoring --- UI/BigComponents/BackgroundSelector.ts | 4 ++- UI/BigComponents/DownloadPanel.ts | 2 +- UI/BigComponents/ImportButton.ts | 4 +-- UI/BigComponents/SimpleAddUI.ts | 4 +-- UI/Image/DeleteImage.ts | 8 ++--- UI/Image/ImageUploadFlow.ts | 4 +-- UI/Input/DropDown.ts | 2 +- UI/Popup/DeleteWizard.ts | 4 +-- UI/Popup/TagRenderingQuestion.ts | 4 +-- UI/ShowDataLayer/ShowDataLayer.ts | 32 +++++++++++-------- UI/ShowDataLayer/ShowTileInfo.ts | 24 ++------------ ...gregator.ts => TileHierarchyAggregator.ts} | 19 ++++++----- 12 files changed, 52 insertions(+), 59 deletions(-) rename UI/ShowDataLayer/{PerTileCountAggregator.ts => TileHierarchyAggregator.ts} (93%) diff --git a/UI/BigComponents/BackgroundSelector.ts b/UI/BigComponents/BackgroundSelector.ts index d13b4e9c0..f5d1a1415 100644 --- a/UI/BigComponents/BackgroundSelector.ts +++ b/UI/BigComponents/BackgroundSelector.ts @@ -25,7 +25,9 @@ export default class BackgroundSelector extends VariableUiElement { if (baseLayers.length <= 1) { return undefined; } - return new DropDown(Translations.t.general.backgroundMap.Clone(), baseLayers, State.state.backgroundLayer) + return new DropDown(Translations.t.general.backgroundMap.Clone(), baseLayers, State.state.backgroundLayer, { + select_class: 'bg-indigo-100 p-1 rounded hover:bg-indigo-200 w-full' + }) } ) ) diff --git a/UI/BigComponents/DownloadPanel.ts b/UI/BigComponents/DownloadPanel.ts index f23d98747..552f6f357 100644 --- a/UI/BigComponents/DownloadPanel.ts +++ b/UI/BigComponents/DownloadPanel.ts @@ -20,7 +20,7 @@ export class DownloadPanel extends Toggle { constructor() { const state: { featurePipeline: FeaturePipeline, - layoutToUse: UIEventSource, + layoutToUse: LayoutConfig, currentBounds: UIEventSource } = State.state diff --git a/UI/BigComponents/ImportButton.ts b/UI/BigComponents/ImportButton.ts index f62b912fd..160405264 100644 --- a/UI/BigComponents/ImportButton.ts +++ b/UI/BigComponents/ImportButton.ts @@ -31,14 +31,14 @@ export default class ImportButton extends Toggle { const button = new SubtleButton(imageUrl, message) - button.onClick(() => { + button.onClick(async () => { if (isImported.data) { return } originalTags.data["_imported"] = "yes" originalTags.ping() // will set isImported as per its definition const newElementAction = new CreateNewNodeAction(newTags.data, lat, lon) - State.state.changes.applyAction(newElementAction) + await State.state.changes.applyAction(newElementAction) State.state.selectedElement.setData(State.state.allElements.ContainingFeatures.get( newElementAction.newElementId )) diff --git a/UI/BigComponents/SimpleAddUI.ts b/UI/BigComponents/SimpleAddUI.ts index ca758ab80..5e8a7b46d 100644 --- a/UI/BigComponents/SimpleAddUI.ts +++ b/UI/BigComponents/SimpleAddUI.ts @@ -56,9 +56,9 @@ export default class SimpleAddUI extends Toggle { const presetsOverview = SimpleAddUI.CreateAllPresetsPanel(selectedPreset) - function createNewPoint(tags: any[], location: { lat: number, lon: number }, snapOntoWay?: OsmWay) { + async function createNewPoint(tags: any[], location: { lat: number, lon: number }, snapOntoWay?: OsmWay) { const newElementAction = new CreateNewNodeAction(tags, location.lat, location.lon, {snapOnto: snapOntoWay}) - State.state.changes.applyAction(newElementAction) + await State.state.changes.applyAction(newElementAction) selectedPreset.setData(undefined) isShown.setData(false) State.state.selectedElement.setData(State.state.allElements.ContainingFeatures.get( diff --git a/UI/Image/DeleteImage.ts b/UI/Image/DeleteImage.ts index fe3f2cf09..800eec53c 100644 --- a/UI/Image/DeleteImage.ts +++ b/UI/Image/DeleteImage.ts @@ -15,15 +15,15 @@ export default class DeleteImage extends Toggle { const isDeletedBadge = Translations.t.image.isDeleted.Clone() .SetClass("rounded-full p-1") .SetStyle("color:white;background:#ff8c8c") - .onClick(() => { - State.state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data)) + .onClick(async() => { + await State.state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data)) }); const deleteButton = Translations.t.image.doDelete.Clone() .SetClass("block w-full pl-4 pr-4") .SetStyle("color:white;background:#ff8c8c; border-top-left-radius:30rem; border-top-right-radius: 30rem;") - .onClick(() => { - State.state?.changes?.applyAction( + .onClick( async() => { + await State.state?.changes?.applyAction( new ChangeTagAction(tags.data.id, new Tag(key, ""), tags.data) ) }); diff --git a/UI/Image/ImageUploadFlow.ts b/UI/Image/ImageUploadFlow.ts index 432541395..4eec0b85c 100644 --- a/UI/Image/ImageUploadFlow.ts +++ b/UI/Image/ImageUploadFlow.ts @@ -29,10 +29,10 @@ export class ImageUploadFlow extends Toggle { key = imagePrefix + ":" + freeIndex; } console.log("Adding image:" + key, url); - State.state.changes + Promise.resolve(State.state.changes .applyAction(new ChangeTagAction( tags.id, new Tag(key, url), tagsSource.data - )) + ))) }) diff --git a/UI/Input/DropDown.ts b/UI/Input/DropDown.ts index 147ad0f50..fe8f8bc98 100644 --- a/UI/Input/DropDown.ts +++ b/UI/Input/DropDown.ts @@ -47,7 +47,7 @@ export class DropDown extends InputElement { } options = options ?? {} - options.select_class = options.select_class ?? 'bg-indigo-100 p-1 rounded hover:bg-indigo-200 w-full' + options.select_class = options.select_class ?? 'bg-indigo-100 p-1 rounded hover:bg-indigo-200' { diff --git a/UI/Popup/DeleteWizard.ts b/UI/Popup/DeleteWizard.ts index b81e82f47..6025ff890 100644 --- a/UI/Popup/DeleteWizard.ts +++ b/UI/Popup/DeleteWizard.ts @@ -51,14 +51,14 @@ export default class DeleteWizard extends Toggle { const confirm = new UIEventSource(false) - function softDelete(reason: string, tagsToApply: { k: string, v: string }[]) { + async function softDelete(reason: string, tagsToApply: { k: string, v: string }[]) { if (reason !== undefined) { tagsToApply.splice(0, 0, { k: "fixme", v: `A mapcomplete user marked this feature to be deleted (${reason})` }) } - (State.state?.changes ?? new Changes()) + await (State.state?.changes ?? new Changes()) .applyAction(new ChangeTagAction( id, new And(tagsToApply.map(kv => new Tag(kv.k, kv.v))), tagsSource.data )) diff --git a/UI/Popup/TagRenderingQuestion.ts b/UI/Popup/TagRenderingQuestion.ts index 5f0881d29..ea6839e14 100644 --- a/UI/Popup/TagRenderingQuestion.ts +++ b/UI/Popup/TagRenderingQuestion.ts @@ -58,10 +58,10 @@ export default class TagRenderingQuestion extends Combine { console.error("MultiAnswer failed - probably not a single option was possible", configuration) throw "MultiAnswer failed - probably not a single option was possible" } - const save = () => { + const save = async () => { const selection = inputElement.GetValue().data; if (selection) { - (State.state?.changes ?? new Changes()) + await (State.state?.changes ?? new Changes()) .applyAction(new ChangeTagAction( tags.data.id, selection, tags.data )) diff --git a/UI/ShowDataLayer/ShowDataLayer.ts b/UI/ShowDataLayer/ShowDataLayer.ts index 0d02bcd4e..ade1860ae 100644 --- a/UI/ShowDataLayer/ShowDataLayer.ts +++ b/UI/ShowDataLayer/ShowDataLayer.ts @@ -63,6 +63,7 @@ export default class ShowDataLayer { }) + State.state.selectedElement.addCallbackAndRunD(selected => { if (self._leafletMap.data === undefined) { return; @@ -76,17 +77,20 @@ export default class ShowDataLayer { if (leafletLayer.getPopup().isOpen()) { return; } - if (selected.properties.id === feature.properties.id) { - // A small sanity check to prevent infinite loops: - if (selected.geometry.type === feature.geometry.type // If a feature is rendered both as way and as point, opening one popup might trigger the other to open, which might trigger the one to open again - && feature.id === feature.properties.id // the feature might have as id 'node/-1' and as 'feature.properties.id' = 'the newly assigned id'. That is no good too - ) { - leafletLayer.openPopup() - } - if (feature.id !== feature.properties.id) { - console.trace("Not opening the popup for", feature) - } - + if (selected.properties.id !== feature.properties.id) { + return; + } + + if (feature.id !== feature.properties.id) { + // Probably a feature which has renamed + console.trace("Not opening the popup for", feature) + return; + } + if (selected.geometry.type === feature.geometry.type // If a feature is rendered both as way and as point, opening one popup might trigger the other to open, which might trigger the one to open again + && feature.id === feature.properties.id // the feature might have as id 'node/-1' and as 'feature.properties.id' = 'the newly assigned id'. That is no good too + ) { + console.log("Opening popup of feature", feature) + leafletLayer.openPopup() } }) @@ -167,8 +171,10 @@ export default class ShowDataLayer { return; } - const tagSource = feature.properties.id === undefined ? new UIEventSource(feature.properties) : - State.state.allElements.getEventSourceById(feature.properties.id) + let tagSource = State.state.allElements.getEventSourceById(feature.properties.id) + if(tagSource === undefined){ + tagSource = new UIEventSource(feature.properties) + } const clickable = !(layer.title === undefined && (layer.tagRenderings ?? []).length === 0) const style = layer.GenerateLeafletStyle(tagSource, clickable); const baseElement = style.icon.html; diff --git a/UI/ShowDataLayer/ShowTileInfo.ts b/UI/ShowDataLayer/ShowTileInfo.ts index a2fa322b6..1bb636727 100644 --- a/UI/ShowDataLayer/ShowTileInfo.ts +++ b/UI/ShowDataLayer/ShowTileInfo.ts @@ -1,32 +1,14 @@ import FeatureSource, {Tiled} from "../../Logic/FeatureSource/FeatureSource"; import {UIEventSource} from "../../Logic/UIEventSource"; -import {Utils} from "../../Utils"; import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; import ShowDataLayer from "./ShowDataLayer"; import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"; import {GeoOperations} from "../../Logic/GeoOperations"; import {Tiles} from "../../Models/TileRange"; - +import * as clusterstyle from "../../assets/layers/cluster_style/cluster_style.json" export default class ShowTileInfo { - public static readonly styling = new LayerConfig({ - id: "tileinfo_styling", - title: { - render: "Tile {z}/{x}/{y}" - }, - tagRenderings: [ - "all_tags" - ], - source: { - osmTags: "tileId~*" - }, - color: {"render": "#3c3"}, - width: { - "render": "1" - }, - label: { - render: "
{count}
" - } - }, "tileinfo", true) + public static readonly styling = new LayerConfig( + clusterstyle, "tileinfo", true) constructor(options: { source: FeatureSource & Tiled, leafletMap: UIEventSource, layer?: LayerConfig, diff --git a/UI/ShowDataLayer/PerTileCountAggregator.ts b/UI/ShowDataLayer/TileHierarchyAggregator.ts similarity index 93% rename from UI/ShowDataLayer/PerTileCountAggregator.ts rename to UI/ShowDataLayer/TileHierarchyAggregator.ts index f313e741f..4b1685981 100644 --- a/UI/ShowDataLayer/PerTileCountAggregator.ts +++ b/UI/ShowDataLayer/TileHierarchyAggregator.ts @@ -22,7 +22,7 @@ export class TileHierarchyAggregator implements FeatureSource { public readonly name; private readonly featuresStatic = [] - private readonly featureProperties: { count: number, tileId: number }; + private readonly featureProperties: { count: string, tileId: string, id: string }; private constructor(parent: TileHierarchyAggregator, z: number, x: number, y: number) { this._parent = parent; @@ -34,8 +34,9 @@ export class TileHierarchyAggregator implements FeatureSource { this.name = "Count(" + this._tileIndex + ")" const totals = { - tileId: this._tileIndex, - count: 0 + id: ""+this._tileIndex, + tileId: ""+this._tileIndex, + count: ""+0 } this.featureProperties = totals @@ -106,7 +107,7 @@ export class TileHierarchyAggregator implements FeatureSource { if (total === 0) { this.features.setData(TileHierarchyAggregator.empty) } else { - this.featureProperties.count = total; + this.featureProperties.count = "" + total; this.features.data = this.featuresStatic this.features.ping() } @@ -145,7 +146,6 @@ export class TileHierarchyAggregator implements FeatureSource { return new TileHierarchyAggregator(undefined, 0, 0, 0) } - private visitSubTiles(f : (aggr: TileHierarchyAggregator) => boolean){ const visitFurther = f(this) if(visitFurther){ @@ -153,8 +153,9 @@ export class TileHierarchyAggregator implements FeatureSource { } } - getCountsForZoom(locationControl: UIEventSource<{ zoom : number }>, cutoff: number) : FeatureSource{ + getCountsForZoom(locationControl: UIEventSource<{ zoom : number }>, cutoff: number = 0) : FeatureSource{ const self = this + return new StaticFeatureSource( locationControl.map(loc => { const features = [] @@ -205,9 +206,11 @@ class SingleTileCounter implements Tiled { const self = this source.features.map(f => { - self.countsPerLayer.data.set(layer.id, f.length) + const isDisplayed = source.layer.isDisplayed.data + self.countsPerLayer.data.set(layer.id, isDisplayed ? f.length : 0) self.countsPerLayer.ping() - }) + }, [source.layer.isDisplayed]) + } From c2d477c97af1d6083a8dfb29fb7c2a40c2082b5c Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 01:12:38 +0200 Subject: [PATCH 42/65] More refactoring --- InitUiElements.ts | 5 +- Logic/Actors/TitleHandler.ts | 2 +- Logic/ElementStorage.ts | 7 +- Logic/FeatureSource/FeaturePipeline.ts | 64 ++++++++++--------- .../Sources/FilteringFeatureSource.ts | 20 +----- Logic/MetaTagging.ts | 2 +- Logic/Osm/Changes.ts | 15 ++--- Logic/Tags/RegexTag.ts | 3 + Models/Constants.ts | 2 +- .../layers/cluster_style/cluster_style.json | 36 +++++++++++ .../toerisme_vlaanderen.json | 6 +- langs/themes/nl.json | 2 +- 12 files changed, 91 insertions(+), 73 deletions(-) create mode 100644 assets/layers/cluster_style/cluster_style.json diff --git a/InitUiElements.ts b/InitUiElements.ts index 40932dfd2..d0eb8b0d4 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -25,20 +25,18 @@ import ScrollableFullScreen from "./UI/Base/ScrollableFullScreen"; import Translations from "./UI/i18n/Translations"; import MapControlButton from "./UI/MapControlButton"; import LZString from "lz-string"; -import AllKnownLayers from "./Customizations/AllKnownLayers"; import AvailableBaseLayers from "./Logic/Actors/AvailableBaseLayers"; import LeftControls from "./UI/BigComponents/LeftControls"; import RightControls from "./UI/BigComponents/RightControls"; import {LayoutConfigJson} from "./Models/ThemeConfig/Json/LayoutConfigJson"; import LayoutConfig from "./Models/ThemeConfig/LayoutConfig"; -import LayerConfig from "./Models/ThemeConfig/LayerConfig"; import Minimap from "./UI/Base/Minimap"; import SelectedFeatureHandler from "./Logic/Actors/SelectedFeatureHandler"; import Combine from "./UI/Base/Combine"; import {SubtleButton} from "./UI/Base/SubtleButton"; import ShowTileInfo from "./UI/ShowDataLayer/ShowTileInfo"; import {Tiles} from "./Models/TileRange"; -import {TileHierarchyAggregator} from "./UI/ShowDataLayer/PerTileCountAggregator"; +import {TileHierarchyAggregator} from "./UI/ShowDataLayer/TileHierarchyAggregator"; import FilterConfig from "./Models/ThemeConfig/FilterConfig"; import FilteredLayer from "./Models/FilteredLayer"; import {BBox} from "./Logic/BBox"; @@ -435,6 +433,7 @@ export class InitUiElements { features: clusterCounter.getCountsForZoom(State.state.locationControl, State.state.layoutToUse.clustering.minNeededElements), leafletMap: State.state.leafletMap, layerToShow: ShowTileInfo.styling, + enablePopups: false }) State.state.featurePipeline = new FeaturePipeline( diff --git a/Logic/Actors/TitleHandler.ts b/Logic/Actors/TitleHandler.ts index 699a33aa8..91ec89b0c 100644 --- a/Logic/Actors/TitleHandler.ts +++ b/Logic/Actors/TitleHandler.ts @@ -29,7 +29,7 @@ export default class TitleHandler { if (layer.source.osmTags.matchesProperties(tags)) { const tagsSource = state.allElements.getEventSourceById(tags.id) const title = new TagRenderingAnswer(tagsSource, layer.title) - return new Combine([defaultTitle, " | ", title]).ConstructElement().innerText; + return new Combine([defaultTitle, " | ", title]).ConstructElement()?.innerText ?? defaultTitle; } } return defaultTitle diff --git a/Logic/ElementStorage.ts b/Logic/ElementStorage.ts index 91193ea6d..ae51094ae 100644 --- a/Logic/ElementStorage.ts +++ b/Logic/ElementStorage.ts @@ -39,11 +39,10 @@ export class ElementStorage { } getEventSourceById(elementId): UIEventSource { - if (this._elements.has(elementId)) { - return this._elements.get(elementId); + if(elementId === undefined){ + return undefined; } - console.error("Can not find eventsource with id ", elementId); - return undefined; + return this._elements.get(elementId); } has(id) { diff --git a/Logic/FeatureSource/FeaturePipeline.ts b/Logic/FeatureSource/FeaturePipeline.ts index d65771da2..e8d270f0b 100644 --- a/Logic/FeatureSource/FeaturePipeline.ts +++ b/Logic/FeatureSource/FeaturePipeline.ts @@ -62,11 +62,35 @@ export default class FeaturePipeline { /** * Maps tileid onto last download moment */ - const tileFreshnesses = new Map() + const tileFreshnesses = new UIEventSource>(new Map()) const osmSourceZoomLevel = 14 const useOsmApi = state.locationControl.map(l => l.zoom > (state.overpassMaxZoom.data ?? 12)) this.relationTracker = new RelationsTracker() + console.log("Tilefreshnesses are", tileFreshnesses.data) + const oldestAllowedDate = new Date(new Date().getTime() - (60 * 60 * 24 * 30 * 1000)); + const neededTilesFromOsm = state.currentBounds.map(bbox => { + if (bbox === undefined) { + return + } + const range = bbox.containingTileRange(osmSourceZoomLevel) + const tileIndexes = [] + if (range.total > 100) { + // Too much tiles! + return [] + } + Tiles.MapRange(range, (x, y) => { + const i = Tiles.tile_index(osmSourceZoomLevel, x, y); + if (tileFreshnesses.data.get(i) > oldestAllowedDate) { + console.debug("Skipping tile", osmSourceZoomLevel, x, y, "as a decently fresh one is available") + // The cached tiles contain decently fresh data + return; + } + tileIndexes.push(i) + }) + return tileIndexes + }, [tileFreshnesses]) + const updater = new OverpassFeatureSource(state, { relationTracker: this.relationTracker, @@ -75,8 +99,9 @@ export default class FeaturePipeline { // This callback contains metadata of the overpass call const range = bbox.containingTileRange(osmSourceZoomLevel) Tiles.MapRange(range, (x, y) => { - tileFreshnesses.set(Tiles.tile_index(osmSourceZoomLevel, x, y), freshness) + tileFreshnesses.data.set(Tiles.tile_index(osmSourceZoomLevel, x, y), freshness) }) + tileFreshnesses.ping(); } }); @@ -137,17 +162,17 @@ export default class FeaturePipeline { }, state) localStorage.tileFreshness.forEach((value, key) => { - if (tileFreshnesses.has(key)) { - const previous = tileFreshnesses.get(key) + if (tileFreshnesses.data.has(key)) { + const previous = tileFreshnesses.data.get(key) if (value < previous) { - tileFreshnesses.set(key, value) + tileFreshnesses.data.set(key, value) } } else { - tileFreshnesses.set(key, value) + tileFreshnesses.data.set(key, value) } + tileFreshnesses.ping() }) - continue } @@ -178,30 +203,7 @@ export default class FeaturePipeline { } } - console.log("Tilefreshnesses are", tileFreshnesses) - const oldestAllowedDate = new Date(new Date().getTime() - (60 * 60 * 24 * 30 * 1000)); - - const neededTilesFromOsm = state.currentBounds.map(bbox => { - if (bbox === undefined) { - return - } - const range = bbox.containingTileRange(osmSourceZoomLevel) - const tileIndexes = [] - if (range.total > 100) { - // Too much tiles! - return [] - } - Tiles.MapRange(range, (x, y) => { - const i = Tiles.tile_index(osmSourceZoomLevel, x, y); - if (tileFreshnesses.get(i) > oldestAllowedDate) { - console.debug("Skipping tile", osmSourceZoomLevel, x, y, "as a decently fresh one is available") - // The cached tiles contain decently fresh data - return; - } - tileIndexes.push(i) - }) - return tileIndexes - }) + const osmFeatureSource = new OsmFeatureSource({ isActive: useOsmApi, diff --git a/Logic/FeatureSource/Sources/FilteringFeatureSource.ts b/Logic/FeatureSource/Sources/FilteringFeatureSource.ts index 6b433f88d..0c2c9d92a 100644 --- a/Logic/FeatureSource/Sources/FilteringFeatureSource.ts +++ b/Logic/FeatureSource/Sources/FilteringFeatureSource.ts @@ -28,8 +28,9 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti this.layer = upstream.layer; const layer = upstream.layer; - + function update() { + const features: { feature: any; freshness: Date }[] = upstream.features.data; const newFeatures = features.filter((f) => { if ( @@ -60,11 +61,6 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti } - if (!layer.isDisplayed) { - // The layer itself is either disabled or hidden due to zoom constraints - // We should return true, but it might still match some other layer - return false; - } return true; }); @@ -75,20 +71,8 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti update(); }); - layer.isDisplayed.addCallback(isShown => { - if (isShown) { - update(); - } else { - self.features.setData([]) - } - }); layer.appliedFilters.addCallback(_ => { - if (!layer.isDisplayed.data) { - // Currently not shown. - // Note that a change in 'isSHown' will trigger an update as well, so we don't have to watch it another time - return; - } update() }) diff --git a/Logic/MetaTagging.ts b/Logic/MetaTagging.ts index 2a85e6292..ee4209f4a 100644 --- a/Logic/MetaTagging.ts +++ b/Logic/MetaTagging.ts @@ -63,7 +63,7 @@ export default class MetaTagging { } somethingChanged = somethingChanged || metatag.applyMetaTagsOnFeature(feature, freshness) } catch (e) { - console.error("Could not calculate metatag for ", metatag.keys.join(","), ":", e) + console.error("Could not calculate metatag for ", metatag.keys.join(","), ":", e, e.stack) } } diff --git a/Logic/Osm/Changes.ts b/Logic/Osm/Changes.ts index b4bf3b4ec..570bf553b 100644 --- a/Logic/Osm/Changes.ts +++ b/Logic/Osm/Changes.ts @@ -149,14 +149,13 @@ export class Changes { } - public applyAction(action: OsmChangeAction) { - action.Perform(this).then(changes => { - console.log("Received changes:", changes) - this.pendingChanges.data.push(...changes); - this.pendingChanges.ping(); - this.allChanges.data.push(...changes) - this.allChanges.ping() - }) + public async applyAction(action: OsmChangeAction): Promise { + const changes = await action.Perform(this) + console.log("Received changes:", changes) + this.pendingChanges.data.push(...changes); + this.pendingChanges.ping(); + this.allChanges.data.push(...changes) + this.allChanges.ping() } private CreateChangesetObjects(changes: ChangeDescription[], downloadedOsmObjects: OsmObject[]): { diff --git a/Logic/Tags/RegexTag.ts b/Logic/Tags/RegexTag.ts index 20fbbbcbf..fae2fd70b 100644 --- a/Logic/Tags/RegexTag.ts +++ b/Logic/Tags/RegexTag.ts @@ -19,6 +19,9 @@ export class RegexTag extends TagsFilter { if (fromTag === undefined) { return; } + if(typeof fromTag === "number"){ + fromTag = "" + fromTag; + } if (typeof possibleRegex === "string") { return fromTag === possibleRegex; } diff --git a/Models/Constants.ts b/Models/Constants.ts index 91c9e0015..a7f79bf39 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.10.0-alpha-3"; + public static vNumber = "0.10.0-alpha-4"; public static ImgurApiKey = '7070e7167f0a25a' // The user journey states thresholds when a new feature gets unlocked diff --git a/assets/layers/cluster_style/cluster_style.json b/assets/layers/cluster_style/cluster_style.json new file mode 100644 index 000000000..ea6760612 --- /dev/null +++ b/assets/layers/cluster_style/cluster_style.json @@ -0,0 +1,36 @@ +{ + "id": "cluster_style", + "description": "The style for the clustering in all themes.", + "source": { + "osmTags": "tileId~*" + }, + "color": { + "render": "#3c3", + "mappings": [ + { + "if": "count>200", + "then": "#f33" + }, + { + "if": "count>100", + "then": "#c93" + }, + { + "if": "count>50", + "then": "#cc3" + } + ] + }, + "width": { + "render": "1" + }, + "label": { + "render": "
{count}
", + "mappings": [ + { + "if": "count>99", + "then": "
>99
" + } + ] + } +} \ No newline at end of file diff --git a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json index aeea7f806..2b303ea14 100644 --- a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json +++ b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json @@ -14,7 +14,7 @@ "nl": "Een kaart om toeristisch relevante info op aan te duiden" }, "description": { - "nl": "Op deze kaart kan je info zien voor toeristen en zelf aanpasingen maken, zichtbaar voor iedereen" + "nl": "Op deze kaart kan je info zien die relevant is voor toerisme, zoals:
  • Eetgelegenheden
  • Cafés en bars
  • (Fiets)oplaadpunten
  • Fietspompen, fietserverhuur en fietswinkels
  • Uitkijktorens
  • ...
Zie je fouten op de kaart? Dan kan je zelf makkelijk aanpasingen maken, die zichtbaar zijn voor iedereen. Hiervoor dien je een gratis OpenStreetMap account voor te maken.

Met de steun van Toerisme Vlaanderen" }, "icon": "./assets/svg/star.svg", "startZoom": 8, @@ -39,9 +39,5 @@ "binocular", "observation_tower" ], - "overiddeAll": { - "minZoomVisible": 0 - }, - "hideFromOverview": true } \ No newline at end of file diff --git a/langs/themes/nl.json b/langs/themes/nl.json index a1e3dee82..e3220df4d 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -1008,7 +1008,7 @@ "title": "Surveillance under Surveillance" }, "toerisme_vlaanderen": { - "description": "Op deze kaart kan je info zien voor toeristen en zelf aanpasingen maken, zichtbaar voor iedereen", + "description": "Op deze kaart kan je info zien die relevant is voor toerisme, zoals:
  • Eetgelegenheden
  • Cafés en bars
  • (Fiets)oplaadpunten
  • Fietspompen, fietserverhuur en fietswinkels
  • Uitkijktorens
  • ...
Zie je fouten op de kaart? Dan kan je zelf makkelijk aanpasingen maken, die zichtbaar zijn voor iedereen. Hiervoor dien je een gratis OpenStreetMap account voor te maken.

Met de steun van Toerisme Vlaanderen", "shortDescription": "Een kaart om toeristisch relevante info op aan te duiden", "title": "Toeristisch relevante info" }, From a4bafe18a74357d1bbed16e39f3885bf23689fe2 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 16:35:56 +0200 Subject: [PATCH 43/65] Add capital letters to layer names --- assets/layers/parking/parking.json | 4 ++-- assets/layers/watermill/watermill.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/layers/parking/parking.json b/assets/layers/parking/parking.json index 1646d143e..b071901c6 100644 --- a/assets/layers/parking/parking.json +++ b/assets/layers/parking/parking.json @@ -1,7 +1,7 @@ { "id": "parking", "name": { - "nl": "parking" + "nl": "Parking" }, "minzoom": 12, "source": { @@ -189,4 +189,4 @@ } } ] -} \ No newline at end of file +} diff --git a/assets/layers/watermill/watermill.json b/assets/layers/watermill/watermill.json index 1908dc8a0..54b5f056c 100644 --- a/assets/layers/watermill/watermill.json +++ b/assets/layers/watermill/watermill.json @@ -1,7 +1,7 @@ { "id": "watermill", "name": { - "nl": "watermolens", + "nl": "Watermolens", "en": "Watermill" }, "minzoom": 12, @@ -170,4 +170,4 @@ "color": { "render": "#FFC0CB" } -} \ No newline at end of file +} From 09897b47e04e50ab748b88d46df38597d1108cba Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 16:55:05 +0200 Subject: [PATCH 44/65] Add mssing assets --- Logic/Actors/OverpassFeatureSource.ts | 108 ++++++++---------- Logic/FeatureSource/FeaturePipeline.ts | 22 ++-- Logic/Osm/Overpass.ts | 12 +- Models/Bounds.ts | 6 - Models/Constants.ts | 10 ++ Models/ThemeConfig/Json/LayoutConfigJson.ts | 4 +- Models/ThemeConfig/LayoutConfig.ts | 12 +- State.ts | 6 +- Utils.ts | 1 + .../toerisme_vlaanderen/license_info.json | 12 ++ assets/themes/toerisme_vlaanderen/logo.png | Bin 0 -> 11674 bytes 11 files changed, 104 insertions(+), 89 deletions(-) delete mode 100644 Models/Bounds.ts create mode 100644 assets/themes/toerisme_vlaanderen/license_info.json create mode 100644 assets/themes/toerisme_vlaanderen/logo.png diff --git a/Logic/Actors/OverpassFeatureSource.ts b/Logic/Actors/OverpassFeatureSource.ts index 248703954..fa5de3eed 100644 --- a/Logic/Actors/OverpassFeatureSource.ts +++ b/Logic/Actors/OverpassFeatureSource.ts @@ -2,7 +2,6 @@ import {UIEventSource} from "../UIEventSource"; import Loc from "../../Models/Loc"; import {Or} from "../Tags/Or"; import {Overpass} from "../Osm/Overpass"; -import Bounds from "../../Models/Bounds"; import FeatureSource from "../FeatureSource/FeatureSource"; import {Utils} from "../../Utils"; import {TagsFilter} from "../Tags/TagsFilter"; @@ -36,16 +35,17 @@ export default class OverpassFeatureSource implements FeatureSource { * If the map location changes, we check for each layer if it is loaded: * we start checking the bounds at the first zoom level the layer might operate. If in bounds - no reload needed, otherwise we continue walking down */ - private readonly _previousBounds: Map = new Map(); + private readonly _previousBounds: Map = new Map(); private readonly state: { readonly locationControl: UIEventSource, readonly layoutToUse: LayoutConfig, - readonly overpassUrl: UIEventSource; + readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; - readonly currentBounds :UIEventSource + readonly currentBounds: UIEventSource } private readonly _isActive: UIEventSource; private _onUpdated?: (bbox: BBox, dataFreshness: Date) => void; + /** * The most important layer should go first, as that one gets first pick for the questions */ @@ -53,20 +53,20 @@ export default class OverpassFeatureSource implements FeatureSource { state: { readonly locationControl: UIEventSource, readonly layoutToUse: LayoutConfig, - readonly overpassUrl: UIEventSource; + readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; readonly overpassMaxZoom: UIEventSource, - readonly currentBounds :UIEventSource - }, - - options?: { + readonly currentBounds: UIEventSource + }, + options?: { isActive?: UIEventSource, - onUpdated?: (bbox: BBox, freshness: Date) => void, - relationTracker: RelationsTracker}) { + onUpdated?: (bbox: BBox, freshness: Date) => void, + relationTracker: RelationsTracker + }) { this.state = state this._isActive = options.isActive; - this._onUpdated =options. onUpdated; + this._onUpdated = options.onUpdated; this.relationsTracker = options.relationTracker const location = state.locationControl const self = this; @@ -79,14 +79,14 @@ export default class OverpassFeatureSource implements FeatureSource { location.addCallback(() => { self.update() }); - + state.currentBounds.addCallback(_ => { self.update() }) - + } - private GetFilter(): Overpass { + private GetFilter(interpreterUrl: string): Overpass { let filters: TagsFilter[] = []; let extraScripts: string[] = []; for (const layer of this.state.layoutToUse.layers) { @@ -113,7 +113,7 @@ export default class OverpassFeatureSource implements FeatureSource { continue; } for (const previousLoadedBound of previousLoadedBounds) { - previouslyLoaded = previouslyLoaded || this.IsInBounds(previousLoadedBound); + previouslyLoaded = previouslyLoaded || this.state.currentBounds.data.isContainedIn(previousLoadedBound); if (previouslyLoaded) { break; } @@ -133,16 +133,16 @@ export default class OverpassFeatureSource implements FeatureSource { if (filters.length + extraScripts.length === 0) { return undefined; } - return new Overpass(new Or(filters), extraScripts, this.state.overpassUrl, this.state.overpassTimeout, this.relationsTracker); + return new Overpass(new Or(filters), extraScripts, interpreterUrl, this.state.overpassTimeout, this.relationsTracker); } private update() { - if(!this._isActive.data){ + if (!this._isActive.data) { return; } const self = this this.updateAsync().then(bboxAndDate => { - if(bboxAndDate === undefined || self._onUpdated === undefined){ + if (bboxAndDate === undefined || self._onUpdated === undefined) { return; } const [bbox, date] = bboxAndDate @@ -162,51 +162,54 @@ export default class OverpassFeatureSource implements FeatureSource { } const bounds = this.state.currentBounds.data?.pad(this.state.layoutToUse.widenFactor)?.expandToTileBounds(14); - + if (bounds === undefined) { return undefined; } - - const n = Math.min(90, bounds.getNorth()); - const e = Math.min(180, bounds.getEast()); - const s = Math.max(-90, bounds.getSouth()); - const w = Math.max(-180, bounds.getWest()); - const queryBounds = {north: n, east: e, south: s, west: w}; - - const self = this; - const overpass = this.GetFilter(); - - if (overpass === undefined) { - return undefined; - } - this.runningQuery.setData(true); let data: any = undefined let date: Date = undefined + const overpassUrls = self.state.overpassUrl.data + let lastUsed = 0; do { - try { - [data, date] = await overpass.queryGeoJson(queryBounds) + const overpass = this.GetFilter(overpassUrls[lastUsed]); + + if (overpass === undefined) { + return undefined; + } + this.runningQuery.setData(true); + + [data, date] = await overpass.queryGeoJson(bounds) console.log("Querying overpass is done", data) } catch (e) { self.retries.data++; self.retries.ping(); - console.error(`QUERY FAILED (retrying in ${5 * self.retries.data} sec) due to`, e); + console.error(`QUERY FAILED due to`, e); - self.timeout.setData(self.retries.data * 5); - - while (self.timeout.data > 0) { - await Utils.waitFor(1000) - self.timeout.data-- - self.timeout.ping(); + await Utils.waitFor(1000) + + if (lastUsed + 1 < overpassUrls.length) { + lastUsed++ + console.log("Trying next time with", overpassUrls[lastUsed]) + } else { + lastUsed = 0 + self.timeout.setData(self.retries.data * 5); + + while (self.timeout.data > 0) { + await Utils.waitFor(1000) + console.log(self.timeout.data) + self.timeout.data-- + self.timeout.ping(); + } } } } while (data === undefined); const z = Math.floor(this.state.locationControl.data.zoom ?? 0); - self._previousBounds.get(z).push(queryBounds); + self._previousBounds.get(z).push(bounds); self.retries.setData(0); try { @@ -215,25 +218,10 @@ export default class OverpassFeatureSource implements FeatureSource { return [bounds, date]; } catch (e) { console.error("Got the overpass response, but could not process it: ", e, e.stack) - }finally { + } finally { self.runningQuery.setData(false); } - } - - private IsInBounds(bounds: Bounds): boolean { - if (this._previousBounds === undefined) { - return false; - } - - const b = this.state.currentBounds.data; - return b.getSouth() >= bounds.south && - b.getNorth() <= bounds.north && - b.getEast() <= bounds.east && - b.getWest() >= bounds.west; - } - - } \ No newline at end of file diff --git a/Logic/FeatureSource/FeaturePipeline.ts b/Logic/FeatureSource/FeaturePipeline.ts index e8d270f0b..3db3a039d 100644 --- a/Logic/FeatureSource/FeaturePipeline.ts +++ b/Logic/FeatureSource/FeaturePipeline.ts @@ -30,10 +30,10 @@ import {Tiles} from "../../Models/TileRange"; export default class FeaturePipeline { public readonly sufficientlyZoomed: UIEventSource; - + public readonly runningQuery: UIEventSource; public readonly timeout: UIEventSource; - + public readonly somethingLoaded: UIEventSource = new UIEventSource(false) public readonly newDataLoadedSignal: UIEventSource = new UIEventSource(undefined) @@ -50,7 +50,7 @@ export default class FeaturePipeline { readonly changes: Changes, readonly layoutToUse: LayoutConfig, readonly leafletMap: any, - readonly overpassUrl: UIEventSource; + readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; readonly overpassMaxZoom: UIEventSource; readonly osmConnection: OsmConnection @@ -67,6 +67,7 @@ export default class FeaturePipeline { const useOsmApi = state.locationControl.map(l => l.zoom > (state.overpassMaxZoom.data ?? 12)) this.relationTracker = new RelationsTracker() + console.log("Tilefreshnesses are", tileFreshnesses.data) const oldestAllowedDate = new Date(new Date().getTime() - (60 * 60 * 24 * 30 * 1000)); const neededTilesFromOsm = state.currentBounds.map(bbox => { @@ -90,7 +91,7 @@ export default class FeaturePipeline { }) return tileIndexes }, [tileFreshnesses]) - + const updater = new OverpassFeatureSource(state, { relationTracker: this.relationTracker, @@ -105,8 +106,10 @@ export default class FeaturePipeline { } }); - + this.overpassUpdater = updater; + this.timeout = updater.timeout + this.sufficientlyZoomed = state.locationControl.map(location => { if (location?.zoom === undefined) { return false; @@ -115,10 +118,10 @@ export default class FeaturePipeline { return location.zoom >= minzoom; } ); - + this.timeout = updater.timeout - - + + // Register everything in the state' 'AllElements' new RegisteringAllFromFeatureSourceActor(updater) @@ -203,9 +206,8 @@ export default class FeaturePipeline { } } - - const osmFeatureSource = new OsmFeatureSource({ + const osmFeatureSource = new OsmFeatureSource({ isActive: useOsmApi, neededTiles: neededTilesFromOsm, handleTile: tile => { diff --git a/Logic/Osm/Overpass.ts b/Logic/Osm/Overpass.ts index 2bf1b4e70..47b92e278 100644 --- a/Logic/Osm/Overpass.ts +++ b/Logic/Osm/Overpass.ts @@ -1,9 +1,9 @@ import * as OsmToGeoJson from "osmtogeojson"; -import Bounds from "../../Models/Bounds"; import {TagsFilter} from "../Tags/TagsFilter"; import RelationsTracker from "./RelationsTracker"; import {Utils} from "../../Utils"; import {UIEventSource} from "../UIEventSource"; +import {BBox} from "../BBox"; /** * Interfaces overpass to get all the latest data @@ -11,7 +11,7 @@ import {UIEventSource} from "../UIEventSource"; export class Overpass { public static testUrl: string = null private _filter: TagsFilter - private readonly _interpreterUrl: UIEventSource; + private readonly _interpreterUrl: string; private readonly _timeout: UIEventSource; private readonly _extraScripts: string[]; private _includeMeta: boolean; @@ -19,7 +19,7 @@ export class Overpass { constructor(filter: TagsFilter, extraScripts: string[], - interpreterUrl: UIEventSource, + interpreterUrl: string, timeout: UIEventSource, relationTracker: RelationsTracker, includeMeta = true) { @@ -31,9 +31,9 @@ export class Overpass { this._relationTracker = relationTracker } - public async queryGeoJson(bounds: Bounds): Promise<[any, Date]> { + public async queryGeoJson(bounds: BBox): Promise<[any, Date]> { - let query = this.buildQuery("[bbox:" + bounds.south + "," + bounds.west + "," + bounds.north + "," + bounds.east + "]") + let query = this.buildQuery("[bbox:" + bounds.getSouth() + "," + bounds.getWest() + "," + bounds.getNorth() + "," + bounds.getEast() + "]") if (Overpass.testUrl !== null) { console.log("Using testing URL") @@ -68,6 +68,6 @@ export class Overpass { } const query = `[out:json][timeout:${this._timeout.data}]${bbox};(${filter});out body;${this._includeMeta ? 'out meta;' : ''}>;out skel qt;` - return `${this._interpreterUrl.data}?data=${encodeURIComponent(query)}` + return `${this._interpreterUrl}?data=${encodeURIComponent(query)}` } } diff --git a/Models/Bounds.ts b/Models/Bounds.ts deleted file mode 100644 index 3a993c8e0..000000000 --- a/Models/Bounds.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default interface Bounds { - north: number, - east: number, - south: number, - west: number -} \ No newline at end of file diff --git a/Models/Constants.ts b/Models/Constants.ts index a7f79bf39..b9855a293 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -4,6 +4,16 @@ export default class Constants { public static vNumber = "0.10.0-alpha-4"; public static ImgurApiKey = '7070e7167f0a25a' + public static defaultOverpassUrls = [ + // The official instance, 10000 queries per day per project allowed + "https://overpass-api.de/api/interpreter", + // 'Fair usage' + "https://overpass.kumi.systems/api/interpreter", + // "https://overpass.nchc.org.tw/api/interpreter", + "https://overpass.openstreetmap.ru/cgi/interpreter", + // The french api, only 1000 per day per project allowed, so we put it as last resort + "https://overpass.openstreetmap.fr/api/interpreter" + ] // The user journey states thresholds when a new feature gets unlocked public static userJourney = { diff --git a/Models/ThemeConfig/Json/LayoutConfigJson.ts b/Models/ThemeConfig/Json/LayoutConfigJson.ts index 887649fc4..73caee792 100644 --- a/Models/ThemeConfig/Json/LayoutConfigJson.ts +++ b/Models/ThemeConfig/Json/LayoutConfigJson.ts @@ -263,9 +263,9 @@ export interface LayoutConfigJson { enablePdfDownload?: boolean; /** - * Set a different overpass URL. Default: https://overpass-api.de/api/interpreter + * Set one or more overpass URLs to use for this theme.. */ - overpassUrl?: string; + overpassUrl?: string | string[]; /** * Set a different timeout for overpass queries - in seconds. Default: 30s */ diff --git a/Models/ThemeConfig/LayoutConfig.ts b/Models/ThemeConfig/LayoutConfig.ts index 9e6325039..4f8551632 100644 --- a/Models/ThemeConfig/LayoutConfig.ts +++ b/Models/ThemeConfig/LayoutConfig.ts @@ -6,6 +6,7 @@ import AllKnownLayers from "../../Customizations/AllKnownLayers"; import {Utils} from "../../Utils"; import LayerConfig from "./LayerConfig"; import {LayerConfigJson} from "./Json/LayerConfigJson"; +import Constants from "../Constants"; export default class LayoutConfig { public readonly id: string; @@ -50,7 +51,7 @@ export default class LayoutConfig { How long is the cache valid, in seconds? */ public readonly cacheTimeout?: number; - public readonly overpassUrl: string; + public readonly overpassUrl: string[]; public readonly overpassTimeout: number; public readonly official: boolean; @@ -157,7 +158,14 @@ export default class LayoutConfig { this.enablePdfDownload = json.enablePdfDownload ?? false; this.customCss = json.customCss; this.cacheTimeout = json.cacheTimout ?? (60 * 24 * 60 * 60) - this.overpassUrl = json.overpassUrl ?? "https://overpass-api.de/api/interpreter" + this.overpassUrl = Constants.defaultOverpassUrls + if(json.overpassUrl !== undefined){ + if(typeof json.overpassUrl === "string"){ + this.overpassUrl = [json.overpassUrl] + }else{ + this.overpassUrl = json.overpassUrl + } + } this.overpassTimeout = json.overpassTimeout ?? 30 } diff --git a/State.ts b/State.ts index 0af8e5a64..00dac3bb5 100644 --- a/State.ts +++ b/State.ts @@ -81,7 +81,7 @@ export default class State { public readonly featureSwitchEnableExport: UIEventSource; public readonly featureSwitchFakeUser: UIEventSource; public readonly featureSwitchExportAsPdf: UIEventSource; - public readonly overpassUrl: UIEventSource; + public readonly overpassUrl: UIEventSource; public readonly overpassTimeout: UIEventSource; @@ -321,9 +321,9 @@ export default class State { ); this.overpassUrl = QueryParameters.GetQueryParameter("overpassUrl", - layoutToUse?.overpassUrl, + layoutToUse?.overpassUrl.join(","), "Point mapcomplete to a different overpass-instance. Example: https://overpass-api.de/api/interpreter" - ) + ).map(param => param.split(","), [], urls => urls.join(",")) this.overpassTimeout = QueryParameters.GetQueryParameter("overpassTimeout", "" + layoutToUse?.overpassTimeout, diff --git a/Utils.ts b/Utils.ts index 424784205..bd5cd62a5 100644 --- a/Utils.ts +++ b/Utils.ts @@ -320,6 +320,7 @@ export class Utils { } xhr.send(); + xhr.onerror = reject } ) } diff --git a/assets/themes/toerisme_vlaanderen/license_info.json b/assets/themes/toerisme_vlaanderen/license_info.json new file mode 100644 index 000000000..374abea1e --- /dev/null +++ b/assets/themes/toerisme_vlaanderen/license_info.json @@ -0,0 +1,12 @@ +[ + { + "path": "logo.png", + "license": "Logo (all rights reserved)", + "authors": [ + "Toerisme Vlaanderen" + ], + "sources": [ + "https://www.toerismevlaanderen.be/" + ] + } +] \ No newline at end of file diff --git a/assets/themes/toerisme_vlaanderen/logo.png b/assets/themes/toerisme_vlaanderen/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6d0d16dd8458cd28b8130b2250618188a2eb8601 GIT binary patch literal 11674 zcmaKSWmuG5*EZeV&Ct>vLk}R0(um{?j5Gs7N_Q&KqKJTi63S509nv8VAt@!@-QVbQ z-|zeU_>TAbF|)6|*LkkB_S*ZJ+1GK#>p#*UCSV{yLqj9h(o{1?20)+=PVNfq`%P`^04I9|b~8ym5j_u8sH2l+032!* z@W|LMz{L(|&#t5hkoT8G5x7CU!2o|ZS9dR2e+Blxyt1hFpKf7xz+V$@7X|kJ1ocEu zAD{|@LjjUPQi66OQqllvppdAfw6uh@06DtT6=jLLjO06|F5-|@pBKTup!h7<^#7w)#Dk*zhKnd{ojuMHMF<;A3F~pxa;3M z?d^o2u246qySEoADAB(Wp(2-k40l2m5bUZ3v-9~gs->pD?&ITRFDt1gCL#kAlK_gV zsH>@niULI?Kr)g*5jAm9Nf8-UnLp0{5d1d~)gxq&!m6o=t4OJ+ONawSQP)FB88HcU zkcy0ygouioxHw4dU#yn9mp9nm4*JLGAFR{=V#WVYtgI>=3igJb^0&Q|4A1Jg^EGI5J5=^dx#(uEFmK( zBPH`pPy#F>Eg@kqBl=8Qg8d(`{eR8XzbUJOq}4@5r6ok9#YCiJL`7vlQffeul%$xd zn2egLh%~z}DjIt`S#KwASLi>B6XfdsPs`Qm&jOKk1-m<-Wdmfb>Iw$C z+e6_{cYu=@z#E3j!^;h7;|g8{2@2 zYWAy8Ra`)blfVWh?8DEN*2v!fw7ST?th4BSo!$z8h91!-`i>qFc{MvNq4r1O2&U4deT5f!G=P z2*8Wze$T3VG60am1d(x`-Pop^Jq;`p&W-@!Q3NWA4D#m&Kyjt8|Bn4~LJ--DlVO1% zqonEy`^-OL|6#kB;NO1^CH>b-6oIUy$BO_|uHzQ8jCb(=8%}tG_2o4GbrtV_#?JL2 zJb&B^%Wq|5TK|mthb(J7W7GQQKY=RMkMc8C{X?d?*3`#uQTZP@CctN>yoMPSXk0Vp zwezwA$W_2lj<^^LwEA{hE^v+F5YwN5uo5#87=#zm$6uMtb0?&l!)Vad!l%2YL#Fm9 zJ~+yZdYqbfdVUq5)w;*!KlDG-Zx9K zm8Il`M~-DM*u4PaGNB`Fq8kaF@0%g%&{k*}f7cZUh17#X9H;cxr$fRh#SsURwWRb+VA*V8~l*_D6=HJgBGAQ zaGsyTYdR(^I>0vq;2bvnD)R#EU2IF0-s%(FjG{K7(cwU6-{GY-J^x({RhjyTLTM;0IjD%$zl(n{5K2nI69K5w-U&U@h7F!C z9t~_+H%!A>>=!2abGpy{VAQhb)n?!Pi{6+$8ZehrEa0a`l|`4LNswz-&)R&7{|D35 ztkTK-Q|rsNzDwHE{Ysqp)=c!TRED&|gKQ7U)M(;^1-mN6Ti}jEUjuYhRkxD+*72`s z_riNui}Ga5RIdLB@v~yiLKi0zm@_^=4f14mo(JGsTq5L&9 z#$Ci(w{#7nF!#G3$4~h;*jLVOhi+PARgDSzx}MPlu4*yy!I^goVjcVEG)hOvC|I-D zjK@v%*u6^twD@8{j9Zs_ady>8^g4cVD+5zCH}`m;-1_Ht{;tA>o+`uk>RlDcD{ND# z0)chSou57N*1!pm8+wYsTHEnT4z)Y@x7#U1<0OxU z6nt$yGCZlpp^tDy=roQpPhHn({{j{AYhD}PvVNPNKe_Mc>**4i9p$gvq_{65_{zim zS=eX1i97O^SPq-0St&NDL;dgz5;kr{Bz2~3vukHtdGWo^sQJi#BQWuDi(CyFuP}0f zhkxzcd->e3jkGlJ0@EqLiECGeJxb`_=Qd<^%#%)c(Et*l_lo#O8?(=*za{ppcWSBw zO+0hV`nJHjR2tWWee^Hc9Q^`1ayHc77>KK}SYc*W-9l@AvXFQ=;*v7jMS;A{N8&0I zlicE{UDb_Arl{A2ZuoT-RWZ7$YRp-gv6*9zv&ugM)*0a!`cRf|>~^;VP2jO-cZZ}* zPw=DLS~e(ke6^lh3k?%YPhJsu8qW~MjK(6ltGZ5Z>0@Kh6>*HoH~mq+C+IV!B@K8x z7qUy<^fc-Iap`)5HW{Zc?%vUWljtH)9Q_bCY<(Cx=71&TmT^!wmW?PV!_ehaNM0{vKR#3TA>D!UG%Z-hK&+t_9c z1Z90F34cD~Q=vv%*`Copa0p!EJ$#8+Pseul`&vO zxfi6dYtg*!5gH;Kp8T4MjHUK;0ARH#$oRZG{_0Lh*W*i(&&`rG?S{?8#4G$;meCkT zzhe8QQe`=dYa)3pxv_2ht*t^8KG%r8M~QgOocF3*=~L;1i@MV|^Cy>>Q??$0>>If+ zYkshPJu&F`TBNvc#>e!ETy@AGt+Dathu*6VTOY1z6`^!DPQ^H<;NV~QkOjrPg1APE zYzV8V3PxD$fb~_Us~PwR>!)&CP!!4JXLMi6v;;vnRw5d&sC~c2fU5-$63X|yM<)SJ zSzACfl_^r>M8{j+J<`I!8UcE$b&Q(>a$Hg4@uJK-#D!F@Ieu%?dvFhf{E9@&V!^2w z)4^?5&%0I*d}Tw2t${|Z@Tsu6nO*$0#LwjpTu&aV%0wod?`7@#OtijqW)(TJ?QK$D z?5KCRPP0qx?)J)Wr5%QpW4>N05V&Q;`EXW%{(hhD9#SQ%(R+P_KXby%jA`UrO1HY> zFA#%V92;1Cq`%aEHRbCi%!m`jTbXosTSd?fG;)~8;mod}myFeHbh~qP&N`$q6vpC- z+uysIN-q@R8y-%!e2i%3`C;m@f>Q#NS+vDimrQh%vP{W2{^(SlxU3a?6+@v5SN)eoUPT!I1f0K}RMl z!uDOiA+v7s&c~ykmS8)X)>M+;g*wi&-KVzr`#$dY<%f=rAL^Ex*tZ=Kr=N|ZR+~b? z+Z1$CahFd`+3B9+e}s=vJ?5=HX;wjH|UY z!a_D#n?P~B2w_;pR%io&xo96gGoiGu8}cvel)Mr%Vy2Az7LieR8`CF z;kM07bf%(p)X(R23Xj}J&7$I&Sww`CPD}WD1a6Z-B2_Q@bP7~vVePeaxTY()l2(?#Szs}m9qw#`?;Iw`iU)0>yLEhVikD^T^ z^6#F>n?yGAJ~LZG`;-W)oj;tD*Rd{a#?vndc(_mD&En~#Nl)4RwgUN)If@ec2Uz2BdV4#Ju2Tlnzmn2wjcJ{ zZuu;IG$Qcltmj?O7ep@2P3YIPCK1~`lV8`;63EQk8fM%F<|-m_rN7kU=D%U|lDm@C zB-H8%x0DOgQhd{SddjdB#waasVftgS;IXZrxzQFSU`E8Bx1~XW$tL1;=QTbI5A)76 zv3ox?wX+b;b4x|eB_ zv09r6QT+1{GSgPw^P(GJ?sh=Mf$vjG)UW&5@;`Bo4rXwRav0lj=L8yAcK;rTj2kWl zF+W*mUQS-NA_zs26K_pxA4SI+k59`)p4aN{s3XBi(32_}rYocrdvh@`RYu=ZTuoq+f=6+|K=e+BDd0P!_tYaa` z|7GBb3;GajVKMSm$S$y))0Y)qZ_!CJ(Rmo?fAIyg(k%@hkaR2f3d)Lb*+b~1=doM5d$K&o|GpE9S3(#V|S5{ z6Z$={Q<&Z2^A^`C|M3OqE!T~;pH3k7tAUW2ZMOZqg--qhho~KRlBda#b6^QounC34 zM3Jh*J1MP&_{=Nz*%t;Y6q?&$NIb--pO$+gk16^4bu~8C!cP@CDaZmesLayrK@3@NBj$|qG^>>uuR#$ZE8A- zyt!aanb5P$LpuqOvpdWek6n1IH?&{Dt#qt%^RfjenWXV69NJeCg;f9dCS z5&?4aF;(B+H4$WF;KWDa_-hypdSe`yC`wiLM7 z5f|RH40tewQ_h-)$XOJfxs$7yOFMKcTJtFAet2bnaJNV6Wu48Yy(86TuNK*A_%V=S z1AyM_s`>i*Jrb6J*8$GF+xtd!T3_YCj<-o-<(dD!{V^*RcI3rFdR9NF)aWJp@}9?; z`6I7--mze9HGcl)jg^+EGY{Xp8hrQ6U&~?E3CKQi zR+$@|E5Z53gru#_qADaZuO{+&zf<4lW#b&{I zGJgj^S<( zZ1w$ib!yPt5K3Fo`KoKMQC52C7e*g5We``hDZu}yJj|WEsSNR@Mb@~W`bQLkU34TN z=~(~!kmdu>8+q$r(yV%7QI20E;Sav5j%KYHw>mXr?(rYrP7__u_P&s`z~Fn)!WOe4 zh55ndRm1{haR6q9yJ?15KFo)+p*@^gz+5Yg#m16dHImJ=K4My;xOcnv>1~)Fr{d^i zUbLp+c~Sn9K?oiri->+5PVJinj!hyW{A2yz=f&pb2@UE`W*F@^PFTGmaoQUqd5XN3 zodvQL*;-I`$se|FYtQqd7Fo@HUsrN{lGPf0n1%$qG&Vt^$dc!r_)11dCaTMpn%1`y zI7^=@U(YdcFoAu1KeW!ZnKangj5$nCR(9gUbK1$0HXd(uN>AdKCZjRp1>yp^>)p~d zZA`)II&M68-YqA79a}8@jla!`zl^Pi`W~zt@@*)7SykZY)c;)MMzh+CNDyS>t+Z=z zs{O2b6<*&gR%WiL_@a(TXQPoxd*|_%p*Jos;@(em+=>E%>ltkPJ21So_jiPEEX55W zAD7#Mew7=LA*~B~gRb$o+~|Q7QqFq2U8lJQxvudF6OW+0TY4kv_*usFsjeq15YMbN zr{}%c2QsEo%IHD83Zafbl8h%sMB@ilvQOvu_+CWrcDM3?!muYcHVR9#FzrToJozm+ zRF1d{(s*BK3-|Nnh0bvloJ(;pX+w0e_pobU&)Q{f^(}c;6pqdw%BTkOP+Tw=+^+>ie^X1 zlcxxwOH3s8Jf~IZq&E6sZ@q%fx>?-x!wLF*+Jh#CZufRfbv0wo>D8rdjIHpR`|y>U ze)_Fh{+_*5rdU=2<5*khlv%1nqGW!wvCLw^h11}9+A^}pM9U~SYPu5XQR15F+8zGc zX`Z8Z#+;MUsBr?4iUY;~DR=YHbBvl9_f)jlQ`%89f3`{YpZf`~R&HyIE`_Epvo14g z3;65f)}Oc7Ui9jyrZK)4IlxtVIH59cGA{nGD5Pu`7eXTCu_v(U^;7AK zy_~q(MzU*~D_GhZ-=&^F@s_=8qi2R@I%IcdY&8zhB_;b)XmY~O&~FNx58EbxB}C&( zU0FEkGw1Bq4{mOWufjb}!WN8@J89gG;P{Kt!WnWE$^IL4amZEd|{F}Ld3ede7=awlUe@{R!*L-jdLU~uJ_ zI5mi^+^)rYEE;zhIxcc9BTI0p|7$NAZ~8t?0bZVt=G0yv6E^}(RX8#2%%M$5e!G>Z z*pzTS`3O7Amu>l8ZEk@_FC$2lWkLJNXw?-<4SvcIkLcj>?-}1jL+$$swLrJgTEpDT zB}!f!F@%SO&xBS{^x2{-S6{C9oV8m~h*H?ctE8LHY3(=8imD3F#dinfxo!u-lj8Cvmy>Y|VBtyL& zY>8cA%FN2;Dz+mOT`#N@tR~}gH~hXMOziVi%fmdJFVcn|iCf_PbK!j#>Xo)O*|m0( zm)88K?l-fIeM<}YPl0_6>Vp>|#mqTNivDJ14+7yb6j%oM5I;AWYmOv&cAJ47qqcD^|4 zlF7l6^U_3dx}!Lmu7e}CNvoN1Gk?|9qR|)I1yEfydlW@IKK7#D#x1t9#hresnhJ=6 zQ#K9O$&Q#&-i=}kuBR3P=p0JgGU|^zd(rQv@VvuWZ@Y<3u`xikOUaygALhF63RWyF zC&hMTAc;@kz5TU7_T6E2cvZw{gEp5YEnSoR@=P1&3L_;huFx{N>kmK0^$YfLHyzT1 z8!9c;h1f7sewuePn$L7r-( z#$Jq%_B2gw+&+W3o-J*5j*I|)!~>qnrlX?zaRc^;4$^}SQ$};FAB?Qz#F;HSYn7G9 zCG$rU%f?tWN5cxW=YbL^d)i7>C}hxKe)3SxEG}p!NO($yJ956T<}#`4C-&=7mC$x# z@0hGQ$1={R-6z5wQXI}%)94nBLr|u+%@vt*PxSNWjcYPz8iGYU_}o>9)BE2hTa>y& zn58n@$=WpNMw+`7tTrj#Zc+xbJ7`k4287*;s9p5) z0l>rEWxmsX&BGs`%1w)|zWaqD?@8DAQ}NpK7c5c>Ln$xDk@O_2Qh)40dzckayn#wuZ&rU~l4-xOV* zJHE!Q-M_g5as<$vUV^*7WF8)I?!tcH@FuUmGM(t65)^i7D>Sg%-OHHmIp;3%;Y?-5-$Seg#emi>W0W>;YGzU(5<8)M#QEkRk#wJi2U zJ~O*p%*GNi@l^Qwq`}NH)~J~sZKsWiXipij6P8`BR!mH!7s5%QBe1E|>~1rof4PZU z)h!^QzPbuS^V~D(BHMK(B+t2r#M&i|;y7GFDA*tUjwwZ7cjI^cHyBs_I%E2iNj&CA zcc#EtcdK8LqP#EQx~3Convi?G3F4#eBL1%xWt&ynINS&xwfzOY{__hpB9-X^Cq&`&SLBGkIX*x@S@ zF)D#<_*x52>^oGHU5MEbCwr+3!M)?rasTBqn^9b_!jP!#F*@e(HX;+}`Pu?T`P5^Z z?sEF=Y)`)7FE-JQZoz@?DcXrL;7!}>R?YCY$o=~FSjh+X)K@`YA5E`6hz}vVyc6R~ zDgVUZ$5FE{rO$h+!8O3s}Nt zs{!Sbm4xO~%FJK|a?2wY8y=PJD=Qo8L+({x2ezD63$iv15?7hW?_Iaa#ueDVpzcXr zUbl$Xu^7{}X%rWmkyhGDY$_1?S{;VY_El8|G~0x2>GC19KVMs7swAKr2dngSOsl?4 zpk(y@=QLR)qf03j(}LvoMsfm{ot?_YT=+8MP~DIFTnVIt9#67zhKyv77mj3aHD1EIH1z}wO&WhB_5FOaWj@$)JverUkPO~cHj%{IZdj>27Q?I2a~ zr?b<6mxaCG*eW$}Ps*@$X^Lj1C=G|LGQAkf)SgFxPsc264nj8wJ=DKlEd&?=P1=A<{! ze)~?aRS=VcIcRk0p?6xTfg-P6OE?z&6i%WK`@Ya=C9#zXmS0M(lmDD5&%BV@$6@A` zRx;(=%9o0m@~%nWrMkBAlTR4Ha<7MWFERv>jeP<`0I=@KKyIMc`k&wG`F@Ci^VUe{i0aoZLiarMl$kXY)6or0Yy zp&AL-+1b@N>YS>~F$E+lRWuCBGYpfUAmvOgkv+WmI4=Jl|Jw(WnEkpTO;%8_M?`Co zdGgHnq)*$cBrVcJC4DZKW(^AubyX7Wwy;v|AG3t3!X(=L zP!t}E{zL2vBFq-5oMr26LnUNy3rX|p8_?E7TyMLDbmrePduG4!7r>A79ZD0JcZ72aCEbx-NzTDK>B z=i=&|wKLPIWrqCv#8MoiI2E6takj~5;#v*Nmugbx(WEeSGwgk}@q(ySu;Pt3_;Ua!&+SQt_Pbm0fY2P3U|EHp{ScDi#f*^W z&8gzwwl9ShAu96FkhGZHAy6r3;>j{jiyX?Izl7~>4@`(Ck*TaF!hP{idfezDoLACim= z%+DJp+r*~^TeKi}_>i&d&etb~_#xYPw93r!zm$G2Aw1JvuB9~xgd)jaxYuRmy*H1s z`xKqI@Ejw;aim1wN>I>ljh(B&re;@8C%Cf&R#Y)3^?Jj9L*P{Cb22x0ET(Mz%awvI z3!Z$V_08B_PLX0=DBx1a)aNBHg|C^FUgs^j);FOai^2u`Nw!cb^}KUf$}b=WBJFpI z6l4DRd0DLiPl+_fJ=2?JP6_mBjM~ogaruY$==+XM;D?xBsh8zKkgYpZsmq@TLGklp z2BPbAsWH!i+MpfQOwiT@tFs1_^yA_SHM*wdo z9)~QLx>}5g!=svLHaKK_BKpA_L}{qQri|5u2!1fFYPpxUN+%~+hmz^$%&ZHjYdu!2 zs(_ur+iVxWSF-ZfTyGfkS@DPiwMTgx0lM7*_~^JU+j8t*rMu^HG8u$v9@^u>}4&JRPv>1A}7nbH9?Q z$kqkTDkm4x7uk<-<25Mlrce(K8hvEAx$Y)P-S{0#4U4Ty6_ z{X@;_#^vgWmD)`L>94deUa>jJGhzYSu@uL2yznTo4D=wlF^O${MTFBa0(wc#7s4Ek zq#Zm5T`ej{xwx1t$|6j#Q8rzarX-$O=4s}fqYOd4l6CIU+v$gj2XA^?Uyn6$*f;AW zU6U+`HvJ(?!G_Rg%%mJ_S`0of9GMqilT7)TB_jX~yQHQ^CoF{wF^ z3mYrpQ3gj*=K|9JN->i%jcFTcv$I37`c}xhuEAwcb5?rAdaBVh+Kr zNKvVH?zPBX9_iLwf!_TCxTlKc*kM{BA1e+bGw1e2Yq}s3KIr|>@~$Vy6JXZ7+d@gI#F zB@q2+1)yKTgHow!?x-oE6$qbf2Ueg2Y~7Dmai_JM#Zjue& z>kMAB&GCo&9a`Ww_8eiaUQ}W^edON)*Iv2e{DpS}FPGWX+M|Sor~zD>z%@O@P9I7T zh>GBkATZ!xGfZoz?F{sPe0JD_`E35c8`5S1t5LeVKZ(3@vVjf%gKXZ<2%aWFNd$S0 zBJclb1mB`$eVo4Rtp3(FRG8b Date: Wed, 29 Sep 2021 17:42:12 +0200 Subject: [PATCH 45/65] Reset translations --- langs/layers/nl.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/langs/layers/nl.json b/langs/layers/nl.json index 8b133247b..8e6df7a08 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -2903,7 +2903,7 @@ }, "parking": { "description": "Parking", - "name": "parking", + "name": "Parking", "presets": { "0": { "description": "Voeg een ontbrekend, erkend pad toe.", @@ -3920,7 +3920,7 @@ }, "watermill": { "description": "Watermolens", - "name": "watermolens", + "name": "Watermolens", "tagRenderings": { "Access tag": { "mappings": { From 542a77b09c8705581b20ceeddbc22398118c7a43 Mon Sep 17 00:00:00 2001 From: SC Date: Wed, 29 Sep 2021 17:38:49 +0200 Subject: [PATCH 46/65] Added translation using Weblate (Portuguese) --- langs/shared-questions/pt.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 langs/shared-questions/pt.json diff --git a/langs/shared-questions/pt.json b/langs/shared-questions/pt.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/langs/shared-questions/pt.json @@ -0,0 +1 @@ +{} From 20db96a30ec887d582b063228c9ccda606df89c5 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 29 Sep 2021 17:38:55 +0200 Subject: [PATCH 47/65] Added translation using Weblate (Portuguese) --- langs/pt.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 langs/pt.json diff --git a/langs/pt.json b/langs/pt.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/langs/pt.json @@ -0,0 +1 @@ +{} From 393a1c2c1139fdeda95d068c0bbccc7d6a3fbc87 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 29 Sep 2021 17:38:59 +0200 Subject: [PATCH 48/65] Added translation using Weblate (Portuguese) --- langs/themes/pt.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 langs/themes/pt.json diff --git a/langs/themes/pt.json b/langs/themes/pt.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/langs/themes/pt.json @@ -0,0 +1 @@ +{} From 023e5d5e444c5a31ce4d2958516d1681e33abf78 Mon Sep 17 00:00:00 2001 From: SC Date: Wed, 29 Sep 2021 15:41:57 +0000 Subject: [PATCH 49/65] Translated using Weblate (Portuguese) Currently translated at 35.0% (7 of 20 strings) Translation: MapComplete/shared-questions Translate-URL: https://hosted.weblate.org/projects/mapcomplete/shared-questions/pt/ --- langs/shared-questions/pt.json | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/langs/shared-questions/pt.json b/langs/shared-questions/pt.json index 0967ef424..60330bb63 100644 --- a/langs/shared-questions/pt.json +++ b/langs/shared-questions/pt.json @@ -1 +1,27 @@ -{} +{ + "undefined": { + "level": { + "question": "Em que nível se encontra este elemento?", + "mappings": { + "3": { + "then": "Está no primeiro andar" + }, + "2": { + "then": "Está ao nível do rés-do-chão" + }, + "1": { + "then": "Está ao nível do rés-do-chão" + }, + "0": { + "then": "Está no subsolo" + } + } + }, + "email": { + "question": "Qual é o endereço de e-mail de {name}?" + }, + "description": { + "question": "Ainda há algo de relevante que não tenha podido dar nas perguntas anteriores? Adicione-o aqui.
Não repita factos já declarados" + } + } +} From fdcda66e5cecba37e3910621eb528b0c29988ffa Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 17:47:30 +0200 Subject: [PATCH 50/65] Small fixes to various layers, mostly presets related --- assets/layers/bench/bench.json | 36 ++--- assets/layers/birdhide/birdhide.json | 4 +- .../layers/drinking_water/drinking_water.json | 14 +- .../information_board/information_board.json | 10 +- .../layers/nature_reserve/nature_reserve.json | 2 +- assets/layers/parking/parking.json | 137 ++---------------- assets/layers/picnic_table/picnic_table.json | 10 +- assets/layers/toilet/toilet.json | 24 +-- assets/themes/natuurpunt/natuurpunt.json | 7 +- 9 files changed, 63 insertions(+), 181 deletions(-) diff --git a/assets/layers/bench/bench.json b/assets/layers/bench/bench.json index 5a94c40ad..af5bbd10b 100644 --- a/assets/layers/bench/bench.json +++ b/assets/layers/bench/bench.json @@ -581,37 +581,21 @@ "amenity=bench" ], "title": { - "en": "Bench", - "de": "Sitzbank", - "fr": "Banc", - "nl": "Zitbank", - "es": "Banco", - "it": "Panchina", + "en": "bench", + "de": "sitzbank", + "fr": "banc", + "nl": "zitbank", + "es": "banco", + "it": "panchina", "ru": "Скамейка", - "id": "Bangku", + "id": "bangku", "zh_Hans": "长椅", - "nb_NO": "Benk", + "nb_NO": "benk", "zh_Hant": "長椅", - "pt_BR": "Banco", - "fi": "Penkki", + "pt_BR": "banco", + "fi": "penkki", "pl": "Ławka" }, - "description": { - "en": "Add a new bench", - "de": "Neue Sitzbank eintragen", - "fr": "Ajouter un nouveau banc", - "nl": "Voeg een nieuwe zitbank toe", - "es": "Añadir un nuevo banco", - "hu": "Pad hozzáadása", - "it": "Aggiungi una nuova panchina", - "ru": "Добавить новую скамейку", - "zh_Hans": "增加一个新的长椅", - "nb_NO": "Legg til en ny benk", - "zh_Hant": "新增長椅", - "pt_BR": "Adicionar um novo banco", - "fi": "Lisää uusi penkki", - "pl": "Dodaj nową ławkę" - }, "presiceInput": { "preferredBackground": "photo" } diff --git a/assets/layers/birdhide/birdhide.json b/assets/layers/birdhide/birdhide.json index 1a581b8a0..38f8e1970 100644 --- a/assets/layers/birdhide/birdhide.json +++ b/assets/layers/birdhide/birdhide.json @@ -235,7 +235,7 @@ "amenity=shelter" ], "title": { - "nl": "Vogelkijkhut" + "nl": "vogelkijkhut" }, "description": { "nl": "Een overdekte hut waarbinnen er warm en droog naar vogels gekeken kan worden" @@ -248,7 +248,7 @@ "shelter=no" ], "title": { - "nl": "Vogelkijkwand" + "nl": "vogelkijkwand" }, "description": { "nl": "Een vogelkijkwand waarachter men kan staan om vogels te kijken" diff --git a/assets/layers/drinking_water/drinking_water.json b/assets/layers/drinking_water/drinking_water.json index 40cce1af9..43af3910c 100644 --- a/assets/layers/drinking_water/drinking_water.json +++ b/assets/layers/drinking_water/drinking_water.json @@ -57,14 +57,14 @@ "presets": [ { "title": { - "en": "Drinking water", - "nl": "Drinkbaar water", - "fr": "Eau potable", - "gl": "Auga potábel", - "de": "Trinkwasser", - "it": "Acqua potabile", + "en": "drinking water", + "nl": "drinkbaar water", + "fr": "eau potable", + "gl": "auga potábel", + "de": "trinkwasser", + "it": "acqua potabile", "ru": "Питьевая вода", - "id": "Air minum" + "id": "air minum" }, "tags": [ "amenity=drinking_water" diff --git a/assets/layers/information_board/information_board.json b/assets/layers/information_board/information_board.json index f25c71245..6f240fa4f 100644 --- a/assets/layers/information_board/information_board.json +++ b/assets/layers/information_board/information_board.json @@ -45,11 +45,11 @@ "information=board" ], "title": { - "nl": "Informatiebord", - "en": "Information board", - "it": "Pannello informativo", - "fr": "Panneau d'informations", - "de": "Informationstafel", + "nl": "informatiebord", + "en": "information board", + "it": "pannello informativo", + "fr": "panneau d'informations", + "de": "informationstafel", "ru": "Информационный щит" } } diff --git a/assets/layers/nature_reserve/nature_reserve.json b/assets/layers/nature_reserve/nature_reserve.json index dab52299c..c6fb976af 100644 --- a/assets/layers/nature_reserve/nature_reserve.json +++ b/assets/layers/nature_reserve/nature_reserve.json @@ -414,7 +414,7 @@ "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" ], "title": { - "nl": "Natuurreservaat" + "nl": "natuurreservaat" }, "description": { "nl": "Voeg een ontbrekend, erkend natuurreservaat toe, bv. een gebied dat beheerd wordt door het ANB of natuurpunt" diff --git a/assets/layers/parking/parking.json b/assets/layers/parking/parking.json index 1646d143e..5459e47cb 100644 --- a/assets/layers/parking/parking.json +++ b/assets/layers/parking/parking.json @@ -49,122 +49,7 @@ "nl": "Parking" }, "tagRenderings": [ - "images", - { - "render": { - "nl": "De toegankelijkheid van dit gebied is: {access:description}" - }, - "question": { - "nl": "Is dit gebied toegankelijk?" - }, - "freeform": { - "key": "access:description" - }, - "mappings": [ - { - "if": { - "and": [ - "access=yes", - "fee=" - ] - }, - "then": { - "nl": "Vrij toegankelijk" - } - }, - { - "if": { - "and": [ - "access=no", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk" - } - }, - { - "if": { - "and": [ - "access=private", - "fee=" - ] - }, - "then": { - "nl": "Niet toegankelijk, want privégebied" - } - }, - { - "if": { - "and": [ - "access=permissive", - "fee=" - ] - }, - "then": { - "nl": "Toegankelijk, ondanks dat het privegebied is" - } - }, - { - "if": { - "and": [ - "access=guided", - "fee=" - ] - }, - "then": { - "nl": "Enkel toegankelijk met een gids of tijdens een activiteit" - } - }, - { - "if": { - "and": [ - "access=yes", - "fee=yes" - ] - }, - "then": { - "nl": "Toegankelijk mits betaling" - } - } - ], - "id": "Access tag" - }, - { - "render": { - "nl": "Beheer door {operator}" - }, - "question": { - "nl": "Wie beheert dit pad?" - }, - "freeform": { - "key": "operator" - }, - "mappings": [ - { - "if": { - "and": [ - "operator=Natuurpunt" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door Natuurpunt" - } - }, - { - "if": { - "and": [ - "operator~(n|N)atuurpunt.*" - ] - }, - "then": { - "nl": "Dit gebied wordt beheerd door {operator}" - }, - "hideInAnswer": true - } - ], - "id": "Operator tag" - } + "images" ], "wayHandling": 1, "iconSize": { @@ -176,16 +61,24 @@ "presets": [ { "tags": [ - "amenity=parking", - "amenity=motorcycle_parking", - "amenity=bicycle_parking", - "fixme=Toegevoegd met MapComplete, geometry nog uit te tekenen" + "amenity=bicycle_parking" ], "title": { - "nl": "Paden" + "nl": "fietsparking" }, "description": { - "nl": "Voeg een ontbrekend, erkend pad toe." + "nl": "Voeg hier een fietsenstalling toe" + } + }, + { + "tags": [ + "amenity=parking" + ], + "title": { + "nl": "parking" + }, + "description": { + "nl": "Voeg hier een parking voor auto's toe" } } ] diff --git a/assets/layers/picnic_table/picnic_table.json b/assets/layers/picnic_table/picnic_table.json index dbe67a9af..c414410fe 100644 --- a/assets/layers/picnic_table/picnic_table.json +++ b/assets/layers/picnic_table/picnic_table.json @@ -92,12 +92,12 @@ "leisure=picnic_table" ], "title": { - "en": "Picnic table", - "nl": "Picnic-tafel", - "it": "Tavolo da picnic", + "en": "picnic table", + "nl": "picnic-tafel", + "it": "tavolo da picnic", "ru": "Стол для пикника", - "de": "Picknicktisch", - "fr": "Table de pique-nique" + "de": "picknicktisch", + "fr": "table de pique-nique" } } ], diff --git a/assets/layers/toilet/toilet.json b/assets/layers/toilet/toilet.json index da9b3ae90..68bc21fe6 100644 --- a/assets/layers/toilet/toilet.json +++ b/assets/layers/toilet/toilet.json @@ -47,12 +47,12 @@ "presets": [ { "title": { - "en": "Toilet", - "de": "Toilette", - "fr": "Toilettes", - "nl": "Toilet", - "ru": "Туалет", - "it": "Servizi igienici" + "en": "toilet", + "de": "toilette", + "fr": "toilettes", + "nl": "toilet", + "ru": "tуалет", + "it": "servizi igienici" }, "tags": [ "amenity=toilets" @@ -68,12 +68,12 @@ }, { "title": { - "en": "Toilets with wheelchair accessible toilet", - "de": "Toiletten mit rollstuhlgerechter Toilette", - "fr": "Toilettes accessible aux personnes à mobilité réduite", - "nl": "Een rolstoeltoegankelijke toilet", - "it": "Servizi igienici accessibili per persone in sedia a rotelle", - "ru": "Туалет с доступом для пользователей кресел-колясок" + "en": "toilets with wheelchair accessible toilet", + "de": "toiletten mit rollstuhlgerechter Toilette", + "fr": "toilettes accessible aux personnes à mobilité réduite", + "nl": "een rolstoeltoegankelijke toilet", + "it": "servizi igienici accessibili per persone in sedia a rotelle", + "ru": "tуалет с доступом для пользователей кресел-колясок" }, "tags": [ "amenity=toilets", diff --git a/assets/themes/natuurpunt/natuurpunt.json b/assets/themes/natuurpunt/natuurpunt.json index f0e921d38..1ed0b7e88 100644 --- a/assets/themes/natuurpunt/natuurpunt.json +++ b/assets/themes/natuurpunt/natuurpunt.json @@ -29,6 +29,10 @@ "enablePdfDownload": true, "enableDownload": true, "hideFromOverview": true, + "clustering": { + "#": "Disable clustering for this theme", + "maxZoom": 0 + }, "layers": [ { "#": "Nature reserve with geometry, z>=13", @@ -70,7 +74,8 @@ "minzoom": 1, "icon": { "render": "circle:#FE6F32;./assets/themes/natuurpunt/nature_reserve.svg" - } + }, + "presets": null } }, { From 36d62f9923d6cd9bb3dbbd866850e02e277dd7e5 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 17:48:15 +0200 Subject: [PATCH 51/65] Add blacklist of ids to geojson source in order to avoid duplicate features to be loaded multiple times --- Logic/FeatureSource/Sources/GeoJsonSource.ts | 19 ++++++++++++++++++- .../DynamicGeoJsonTileSource.ts | 11 ++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Logic/FeatureSource/Sources/GeoJsonSource.ts b/Logic/FeatureSource/Sources/GeoJsonSource.ts index 301f1bc55..b341a0dd3 100644 --- a/Logic/FeatureSource/Sources/GeoJsonSource.ts +++ b/Logic/FeatureSource/Sources/GeoJsonSource.ts @@ -21,14 +21,26 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { public readonly tileIndex public readonly bbox; + /** + * Only used if the actual source is a tiled geojson. + * A big feature might be contained in multiple tiles. + * However, we only want to load them once. The blacklist thus contains all ids of all features previously seen + * @private + */ + private readonly featureIdBlacklist?: UIEventSource> + public constructor(flayer: FilteredLayer, - zxy?: [number, number, number]) { + zxy?: [number, number, number], + options?: { + featureIdBlacklist?: UIEventSource> + }) { if (flayer.layerDef.source.geojsonZoomLevel !== undefined && zxy === undefined) { throw "Dynamic layers are not supported. Use 'DynamicGeoJsonTileSource instead" } this.layer = flayer; + this.featureIdBlacklist = options?.featureIdBlacklist let url = flayer.layerDef.source.geojsonSource.replace("{layer}", flayer.layerDef.id); if (zxy !== undefined) { const [z, x, y] = zxy; @@ -68,6 +80,7 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { const props = feature.properties for (const key in props) { if (typeof props[key] !== "string") { + // Make sure all the values are string, it crashes stuff otherwise props[key] = "" + props[key] } } @@ -82,6 +95,10 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled { continue; } self.seenids.add(props.id) + + if(self.featureIdBlacklist?.data?.has(props.id)){ + continue; + } let freshness: Date = time; if (feature.properties["_last_edit:timestamp"] !== undefined) { diff --git a/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts b/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts index 8843b182a..fcfdbea5a 100644 --- a/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts @@ -37,6 +37,8 @@ export default class DynamicGeoJsonTileSource extends DynamicTileSource { console.warn("No whitelist found for ", layer.layerDef.id, err) }) + const seenIds = new Set(); + const blackList = new UIEventSource(seenIds) super( layer, source.geojsonZoomLevel, @@ -50,8 +52,15 @@ export default class DynamicGeoJsonTileSource extends DynamicTileSource { const src = new GeoJsonSource( layer, - zxy + zxy, + { + featureIdBlacklist: blackList + } ) + src.features.addCallbackAndRunD(feats => { + feats.forEach(feat => seenIds.add(feat.feature.properties.id)) + blackList.ping(); + }) registerLayer(src) return src }, From a4aeed092b398fbcb9b359845d6fd71ac8319c66 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 17:55:55 +0200 Subject: [PATCH 52/65] Version bump --- Models/Constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Models/Constants.ts b/Models/Constants.ts index b9855a293..d524c6689 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.10.0-alpha-4"; + public static vNumber = "0.10.0-rc0"; public static ImgurApiKey = '7070e7167f0a25a' public static defaultOverpassUrls = [ // The official instance, 10000 queries per day per project allowed From 3d95324038f04acf1bfdeca3e7ce54dae01d7233 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 17:56:38 +0200 Subject: [PATCH 53/65] Small translation fixes --- langs/layers/de.json | 13 ++++---- langs/layers/en.json | 13 ++++---- langs/layers/es.json | 3 +- langs/layers/fi.json | 3 +- langs/layers/fr.json | 13 ++++---- langs/layers/gl.json | 2 +- langs/layers/hu.json | 5 ---- langs/layers/id.json | 4 +-- langs/layers/it.json | 13 ++++---- langs/layers/nb_NO.json | 3 +- langs/layers/nl.json | 63 +++++++++------------------------------ langs/layers/pl.json | 1 - langs/layers/pt_BR.json | 3 +- langs/layers/ru.json | 5 ++-- langs/layers/zh_Hans.json | 1 - langs/layers/zh_Hant.json | 1 - 16 files changed, 47 insertions(+), 99 deletions(-) diff --git a/langs/layers/de.json b/langs/layers/de.json index d98acb582..b95c28ac5 100644 --- a/langs/layers/de.json +++ b/langs/layers/de.json @@ -3,8 +3,7 @@ "name": "Sitzbänke", "presets": { "0": { - "description": "Neue Sitzbank eintragen", - "title": "Sitzbank" + "title": "sitzbank" } }, "tagRenderings": { @@ -754,7 +753,7 @@ "name": "Trinkwasser", "presets": { "0": { - "title": "Trinkwasser" + "title": "trinkwasser" } }, "tagRenderings": { @@ -823,7 +822,7 @@ "name": "Informationstafeln", "presets": { "0": { - "title": "Informationstafel" + "title": "informationstafel" } }, "title": { @@ -904,7 +903,7 @@ "name": "Picknick-Tische", "presets": { "0": { - "title": "Picknicktisch" + "title": "picknicktisch" } }, "tagRenderings": { @@ -1134,11 +1133,11 @@ "presets": { "0": { "description": "Eine öffentlich zugängliche Toilette", - "title": "Toilette" + "title": "toilette" }, "1": { "description": "Eine Toilettenanlage mit mindestens einer rollstuhlgerechten Toilette", - "title": "Toiletten mit rollstuhlgerechter Toilette" + "title": "toiletten mit rollstuhlgerechter Toilette" } }, "tagRenderings": { diff --git a/langs/layers/en.json b/langs/layers/en.json index 7ab575873..a3a428462 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -94,8 +94,7 @@ "name": "Benches", "presets": { "0": { - "description": "Add a new bench", - "title": "Bench" + "title": "bench" } }, "tagRenderings": { @@ -2375,7 +2374,7 @@ "name": "Drinking water", "presets": { "0": { - "title": "Drinking water" + "title": "drinking water" } }, "tagRenderings": { @@ -2587,7 +2586,7 @@ "name": "Information boards", "presets": { "0": { - "title": "Information board" + "title": "information board" } }, "title": { @@ -2733,7 +2732,7 @@ "name": "Picnic tables", "presets": { "0": { - "title": "Picnic table" + "title": "picnic table" } }, "tagRenderings": { @@ -3263,11 +3262,11 @@ "presets": { "0": { "description": "A publicly accessible toilet or restroom", - "title": "Toilet" + "title": "toilet" }, "1": { "description": "A restroom which has at least one wheelchair-accessible toilet", - "title": "Toilets with wheelchair accessible toilet" + "title": "toilets with wheelchair accessible toilet" } }, "tagRenderings": { diff --git a/langs/layers/es.json b/langs/layers/es.json index 9746ea958..44e99ca4c 100644 --- a/langs/layers/es.json +++ b/langs/layers/es.json @@ -3,8 +3,7 @@ "name": "Bancos", "presets": { "0": { - "description": "Añadir un nuevo banco", - "title": "Banco" + "title": "banco" } }, "tagRenderings": { diff --git a/langs/layers/fi.json b/langs/layers/fi.json index abe9d2b7f..a13231cd6 100644 --- a/langs/layers/fi.json +++ b/langs/layers/fi.json @@ -3,8 +3,7 @@ "name": "Penkit", "presets": { "0": { - "description": "Lisää uusi penkki", - "title": "Penkki" + "title": "penkki" } }, "tagRenderings": { diff --git a/langs/layers/fr.json b/langs/layers/fr.json index 009a50fc0..52c61d899 100644 --- a/langs/layers/fr.json +++ b/langs/layers/fr.json @@ -3,8 +3,7 @@ "name": "Bancs", "presets": { "0": { - "description": "Ajouter un nouveau banc", - "title": "Banc" + "title": "banc" } }, "tagRenderings": { @@ -810,7 +809,7 @@ "name": "Eau potable", "presets": { "0": { - "title": "Eau potable" + "title": "eau potable" } }, "tagRenderings": { @@ -951,7 +950,7 @@ "name": "Panneaux d'informations", "presets": { "0": { - "title": "Panneau d'informations" + "title": "panneau d'informations" } }, "title": { @@ -1043,7 +1042,7 @@ "name": "Tables de pique-nique", "presets": { "0": { - "title": "Table de pique-nique" + "title": "table de pique-nique" } }, "tagRenderings": { @@ -1550,11 +1549,11 @@ "presets": { "0": { "description": "Des toilettes", - "title": "Toilettes" + "title": "toilettes" }, "1": { "description": "Toilettes avec au moins un WC accessible aux personnes à mobilité réduite", - "title": "Toilettes accessible aux personnes à mobilité réduite" + "title": "toilettes accessible aux personnes à mobilité réduite" } }, "tagRenderings": { diff --git a/langs/layers/gl.json b/langs/layers/gl.json index 44f1a21ba..aa261176f 100644 --- a/langs/layers/gl.json +++ b/langs/layers/gl.json @@ -372,7 +372,7 @@ "name": "Auga potábel", "presets": { "0": { - "title": "Auga potábel" + "title": "auga potábel" } }, "title": { diff --git a/langs/layers/hu.json b/langs/layers/hu.json index 2842a2d33..5fb6aa09b 100644 --- a/langs/layers/hu.json +++ b/langs/layers/hu.json @@ -1,11 +1,6 @@ { "bench": { "name": "Padok", - "presets": { - "0": { - "description": "Pad hozzáadása" - } - }, "tagRenderings": { "bench-backrest": { "mappings": { diff --git a/langs/layers/id.json b/langs/layers/id.json index 7aacdc7aa..54f3e27c2 100644 --- a/langs/layers/id.json +++ b/langs/layers/id.json @@ -3,7 +3,7 @@ "name": "Bangku", "presets": { "0": { - "title": "Bangku" + "title": "bangku" } }, "tagRenderings": { @@ -65,7 +65,7 @@ "name": "Air minum", "presets": { "0": { - "title": "Air minum" + "title": "air minum" } }, "title": { diff --git a/langs/layers/it.json b/langs/layers/it.json index d5e8c4050..b8585841f 100644 --- a/langs/layers/it.json +++ b/langs/layers/it.json @@ -3,8 +3,7 @@ "name": "Panchine", "presets": { "0": { - "description": "Aggiungi una nuova panchina", - "title": "Panchina" + "title": "panchina" } }, "tagRenderings": { @@ -826,7 +825,7 @@ "name": "Acqua potabile", "presets": { "0": { - "title": "Acqua potabile" + "title": "acqua potabile" } }, "tagRenderings": { @@ -910,7 +909,7 @@ "name": "Pannelli informativi", "presets": { "0": { - "title": "Pannello informativo" + "title": "pannello informativo" } }, "title": { @@ -1002,7 +1001,7 @@ "name": "Tavoli da picnic", "presets": { "0": { - "title": "Tavolo da picnic" + "title": "tavolo da picnic" } }, "tagRenderings": { @@ -1509,11 +1508,11 @@ "presets": { "0": { "description": "Servizi igienici aperti al pubblico", - "title": "Servizi igienici" + "title": "servizi igienici" }, "1": { "description": "Servizi igienici che hanno almeno una toilette accessibile a persone in sedia a rotelle", - "title": "Servizi igienici accessibili per persone in sedia a rotelle" + "title": "servizi igienici accessibili per persone in sedia a rotelle" } }, "tagRenderings": { diff --git a/langs/layers/nb_NO.json b/langs/layers/nb_NO.json index e22f10944..c515216b9 100644 --- a/langs/layers/nb_NO.json +++ b/langs/layers/nb_NO.json @@ -3,8 +3,7 @@ "name": "Benker", "presets": { "0": { - "description": "Legg til en ny benk", - "title": "Benk" + "title": "benk" } }, "tagRenderings": { diff --git a/langs/layers/nl.json b/langs/layers/nl.json index 8b133247b..dec4d1973 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -93,8 +93,7 @@ "name": "Zitbanken", "presets": { "0": { - "description": "Voeg een nieuwe zitbank toe", - "title": "Zitbank" + "title": "zitbank" } }, "tagRenderings": { @@ -828,11 +827,11 @@ "presets": { "0": { "description": "Een overdekte hut waarbinnen er warm en droog naar vogels gekeken kan worden", - "title": "Vogelkijkhut" + "title": "vogelkijkhut" }, "1": { "description": "Een vogelkijkwand waarachter men kan staan om vogels te kijken", - "title": "Vogelkijkwand" + "title": "vogelkijkwand" } }, "size": { @@ -2321,7 +2320,7 @@ "name": "Drinkbaar water", "presets": { "0": { - "title": "Drinkbaar water" + "title": "drinkbaar water" } }, "tagRenderings": { @@ -2660,7 +2659,7 @@ "name": "Informatieborden", "presets": { "0": { - "title": "Informatiebord" + "title": "informatiebord" } }, "title": { @@ -2739,7 +2738,7 @@ "presets": { "0": { "description": "Voeg een ontbrekend, erkend natuurreservaat toe, bv. een gebied dat beheerd wordt door het ANB of natuurpunt", - "title": "Natuurreservaat" + "title": "natuurreservaat" } }, "tagRenderings": { @@ -2906,46 +2905,12 @@ "name": "parking", "presets": { "0": { - "description": "Voeg een ontbrekend, erkend pad toe.", - "title": "Paden" - } - }, - "tagRenderings": { - "Access tag": { - "mappings": { - "0": { - "then": "Vrij toegankelijk" - }, - "1": { - "then": "Niet toegankelijk" - }, - "2": { - "then": "Niet toegankelijk, want privégebied" - }, - "3": { - "then": "Toegankelijk, ondanks dat het privegebied is" - }, - "4": { - "then": "Enkel toegankelijk met een gids of tijdens een activiteit" - }, - "5": { - "then": "Toegankelijk mits betaling" - } - }, - "question": "Is dit gebied toegankelijk?", - "render": "De toegankelijkheid van dit gebied is: {access:description}" + "description": "Voeg hier een fietsenstalling toe", + "title": "fietsparking" }, - "Operator tag": { - "mappings": { - "0": { - "then": "Dit gebied wordt beheerd door Natuurpunt" - }, - "1": { - "then": "Dit gebied wordt beheerd door {operator}" - } - }, - "question": "Wie beheert dit pad?", - "render": "Beheer door {operator}" + "1": { + "description": "Voeg hier een parking voor auto's toe", + "title": "parking" } }, "title": { @@ -2968,7 +2933,7 @@ "name": "Picnictafels", "presets": { "0": { - "title": "Picnic-tafel" + "title": "picnic-tafel" } }, "tagRenderings": { @@ -3531,11 +3496,11 @@ "presets": { "0": { "description": "Een publieke toilet", - "title": "Toilet" + "title": "toilet" }, "1": { "description": "Deze toiletten hebben op zijn minst één rolstoeltoegankelijke WC", - "title": "Een rolstoeltoegankelijke toilet" + "title": "een rolstoeltoegankelijke toilet" } }, "tagRenderings": { diff --git a/langs/layers/pl.json b/langs/layers/pl.json index 7c91508bb..64b52a16b 100644 --- a/langs/layers/pl.json +++ b/langs/layers/pl.json @@ -3,7 +3,6 @@ "name": "Ławki", "presets": { "0": { - "description": "Dodaj nową ławkę", "title": "Ławka" } }, diff --git a/langs/layers/pt_BR.json b/langs/layers/pt_BR.json index 602d1ea85..923a5d76d 100644 --- a/langs/layers/pt_BR.json +++ b/langs/layers/pt_BR.json @@ -3,8 +3,7 @@ "name": "Bancos", "presets": { "0": { - "description": "Adicionar um novo banco", - "title": "Banco" + "title": "banco" } }, "tagRenderings": { diff --git a/langs/layers/ru.json b/langs/layers/ru.json index 2c6485f51..4e776b452 100644 --- a/langs/layers/ru.json +++ b/langs/layers/ru.json @@ -3,7 +3,6 @@ "name": "Скамейки", "presets": { "0": { - "description": "Добавить новую скамейку", "title": "Скамейка" } }, @@ -1023,10 +1022,10 @@ "presets": { "0": { "description": "Туалет или комната отдыха со свободным доступом", - "title": "Туалет" + "title": "tуалет" }, "1": { - "title": "Туалет с доступом для пользователей кресел-колясок" + "title": "tуалет с доступом для пользователей кресел-колясок" } }, "tagRenderings": { diff --git a/langs/layers/zh_Hans.json b/langs/layers/zh_Hans.json index 90b74fe66..360a52c61 100644 --- a/langs/layers/zh_Hans.json +++ b/langs/layers/zh_Hans.json @@ -3,7 +3,6 @@ "name": "长椅", "presets": { "0": { - "description": "增加一个新的长椅", "title": "长椅" } }, diff --git a/langs/layers/zh_Hant.json b/langs/layers/zh_Hant.json index 994ecb486..ccacafa7f 100644 --- a/langs/layers/zh_Hant.json +++ b/langs/layers/zh_Hant.json @@ -3,7 +3,6 @@ "name": "長椅", "presets": { "0": { - "description": "新增長椅", "title": "長椅" } }, From 018431401679c03c8e9c18ab041f6bb24eae509f Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 18:21:06 +0200 Subject: [PATCH 54/65] Add release notes --- Docs/Release_Notes.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Docs/Release_Notes.md b/Docs/Release_Notes.md index ea1b1ded2..c6f0ac35d 100644 --- a/Docs/Release_Notes.md +++ b/Docs/Release_Notes.md @@ -3,6 +3,41 @@ Release Notes Some highlights of new releases. +0.10 +---- + +The 0.10 version contains a lot of refactorings on various core of the application, namely in the rendering stack, the fetching of data and uploading. + +Some highlights are: + +1. The addition of fallback overpass servers +2. Fetching data from OSM directly (especially useful in the personal theme) +3. Splitting all the features per tile (with a maximum amount of features per tile, splitting further if needed), making everything a ton faster +4. If a tile has too much features, the featuers are not shown. Instead, a rectangle with the feature amount is shown. + +Furthermore, it contains a few new themes and theme updates: + +- Restaurants and fast food +- Pubs and cafés +- Charging stations got a major overhaul - thanks for all the input on the available plugs +- Observation towers and binoculars +- The addition of a hackerspace theme (as made on SOTM) + +Other various small improvements: + +- The filter state is now exposed in the URL, so can be shared +- Lots of other fixes, as usual + +0.8 and 0.9 +----------- + +Addition of filters per layer +Addition of a download-as-pdf for select themes +Addition of a download-as-geojson and download-as-csv for select themes + +... + + 0.7.0 ----- From 6dcc710cc2728773e22ee164b6c53a6d6875145b Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 19:48:36 +0200 Subject: [PATCH 55/65] Add a little hand, inviting the user to drag location inputs --- UI/Input/LocationInput.ts | 23 +++++++++--- assets/svg/hand.svg | 77 ++++++++++++++------------------------- index.css | 46 +++++++++++++++++++++++ test.ts | 26 ++++++------- 4 files changed, 101 insertions(+), 71 deletions(-) diff --git a/UI/Input/LocationInput.ts b/UI/Input/LocationInput.ts index 875fce9cb..adc441472 100644 --- a/UI/Input/LocationInput.ts +++ b/UI/Input/LocationInput.ts @@ -11,6 +11,7 @@ import {GeoOperations} from "../../Logic/GeoOperations"; import ShowDataLayer from "../ShowDataLayer"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import * as L from "leaflet"; +import {FixedUiElement} from "../Base/FixedUiElement"; export default class LocationInput extends InputElement { @@ -128,7 +129,7 @@ export default class LocationInput extends InputElement { }) } - this.mapBackground = options.mapBackground ?? State.state.backgroundLayer ?? new UIEventSource(AvailableBaseLayers.osmCarto) + this.mapBackground = options.mapBackground ?? State.state?.backgroundLayer ?? new UIEventSource(AvailableBaseLayers.osmCarto) this.SetClass("block h-full") } @@ -147,7 +148,7 @@ export default class LocationInput extends InputElement { { location: this._centerLocation, background: this.mapBackground, - attribution: this.mapBackground !== State.state.backgroundLayer, + attribution: this.mapBackground !== State.state?.backgroundLayer, lastClickLocation: clickLocation } ) @@ -219,7 +220,6 @@ export default class LocationInput extends InputElement { ) } } - this.mapBackground.map(layer => { const leaflet = map.leafletMap.data if (leaflet === undefined || layer === undefined) { @@ -231,20 +231,31 @@ export default class LocationInput extends InputElement { leaflet.setZoom(layer.max_zoom - 1) }, [map.leafletMap]) + + const animatedHand = Svg.hand_ui() + .SetStyle("width: 2rem; height: unset;") + .SetClass("hand-drag-animation block pointer-events-none") + return new Combine([ new Combine([ Svg.move_arrows_ui() .SetClass("block relative pointer-events-none") .SetStyle("left: -2.5rem; top: -2.5rem; width: 5rem; height: 5rem") - ]).SetClass("block w-0 h-0 z-10 relative") - .SetStyle("background: rgba(255, 128, 128, 0.21); left: 50%; top: 50%"), + ]).SetClass("block w-0 h-0 z-10 relative") + .SetStyle("background: rgba(255, 128, 128, 0.21); left: 50%; top: 50%; opacity: 0.5"), + + new Combine([ + animatedHand]) + .SetClass("block w-0 h-0 z-10 relative") + .SetStyle("left: calc(50% + 3rem); top: calc(50% + 2rem); opacity: 0.7"), + map .SetClass("z-0 relative block w-full h-full bg-gray-100") ]).ConstructElement(); } catch (e) { console.error("Could not generate LocationInputElement:", e) - return undefined; + return new FixedUiElement("Constructing a locationInput failed due to" + e).SetClass("alert").ConstructElement(); } } diff --git a/assets/svg/hand.svg b/assets/svg/hand.svg index 75118da95..bbef4187a 100644 --- a/assets/svg/hand.svg +++ b/assets/svg/hand.svg @@ -1,53 +1,30 @@ - - - - image/svg+xml - - - - - - - + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + id="svg6" + height="39.557907" + width="28.561806" + version="1.1"> + + + + image/svg+xml + + + + + + + diff --git a/index.css b/index.css index bf49576ee..bfdfad61a 100644 --- a/index.css +++ b/index.css @@ -307,6 +307,7 @@ li::marker { @keyframes slide { + /* This is the animation on the marker to add a new point - it slides through all the possible presets */ from { transform: translateX(0%); } @@ -316,6 +317,51 @@ li::marker { } } +.hand-drag-animation { + animation: hand-drag-animation 6s ease-in-out infinite; + transform-origin: 50% 125%; +} + +@keyframes hand-drag-animation { + /* This is the animation on the little extra hand on the location input. If fades in, invites the user to interact/drag the map */ + 0% { + opacity: 0; + transform: rotate(-30deg); + } + + 6% { + opacity: 1; + transform: rotate(-30deg); + } + + 12% { + opacity: 1; + transform: rotate(-45deg); + } + + 24% { + opacity: 1; + transform: rotate(-00deg); + } + + 30% { + opacity: 1; + transform: rotate(-30deg); + } + + + 36% { + opacity: 0; + transform: rotate(-30deg); + } + + 100% { + opacity: 0; + transform: rotate(-30deg); + } + +} + /**************************************/ diff --git a/test.ts b/test.ts index c34a6c303..51c8177a1 100644 --- a/test.ts +++ b/test.ts @@ -1,16 +1,12 @@ -const client_token = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" +import LocationInput from "./UI/Input/LocationInput"; +import Loc from "./Models/Loc"; +import {UIEventSource} from "./Logic/UIEventSource"; -const image_id = '196804715753265'; -const api_url = 'https://graph.mapillary.com/' + image_id + '?fields=thumb_1024_url&&access_token=' + client_token; -fetch(api_url, - { - headers: {'Authorization': 'OAuth ' + client_token} - } -).then(response => { - return response.json() -}).then( - json => { - const thumbnail_url = json["thumb_1024"] - console.log(thumbnail_url) - } -) \ No newline at end of file +new LocationInput({ + centerLocation: new UIEventSource({ + lat: 51.1110, + lon: 3.3701, + zoom : 14 + }) +}).SetStyle("height: 500px") + .AttachTo("maindiv"); \ No newline at end of file From 4da6070b2820ba3d66aa539832f141268ab5fd1b Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 19:56:59 +0200 Subject: [PATCH 56/65] Small fixes after feedback --- .../Actors/SaveTileToLocalStorageActor.ts | 4 +++- .../TiledFromLocalStorageSource.ts | 14 ++++++++++++-- assets/themes/cyclestreets/cyclestreets.json | 4 ++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Logic/FeatureSource/Actors/SaveTileToLocalStorageActor.ts b/Logic/FeatureSource/Actors/SaveTileToLocalStorageActor.ts index 331168bb8..22e6a7ba8 100644 --- a/Logic/FeatureSource/Actors/SaveTileToLocalStorageActor.ts +++ b/Logic/FeatureSource/Actors/SaveTileToLocalStorageActor.ts @@ -7,7 +7,8 @@ import {FeatureSourceForLayer} from "../FeatureSource"; export default class SaveTileToLocalStorageActor { public static readonly storageKey: string = "cached-features"; - + public static readonly formatVersion : string = "1" + constructor(source: FeatureSourceForLayer, tileIndex: number) { source.features.addCallbackAndRunD(features => { const key = `${SaveTileToLocalStorageActor.storageKey}-${source.layer.layerDef.id}-${tileIndex}` @@ -20,6 +21,7 @@ export default class SaveTileToLocalStorageActor { try { localStorage.setItem(key, JSON.stringify(features)); localStorage.setItem(key + "-time", JSON.stringify(now)) + localStorage.setItem(key+"-format", SaveTileToLocalStorageActor.formatVersion) } catch (e) { console.warn("Could not save the features to local storage:", e) } diff --git a/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts b/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts index 4b578b7da..3ad933d7e 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts @@ -32,8 +32,18 @@ public tileFreshness : Map = new Map() console.debug("Layer", layer.layerDef.id, "has following tiles in available in localstorage", indexes.map(i => Tiles.tile_from_index(i).join("/")).join(", ")) for (const index of indexes) { - const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layer.layerDef.id + "-" +index+"-time"; - const data = Number(localStorage.getItem(prefix)) + + const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layer.layerDef.id + "-" +index; + const version = localStorage.getItem(prefix+"-format") + if(version === undefined || version !== SaveTileToLocalStorageActor.formatVersion){ + // Invalid version! Remove this tile from local storage + localStorage.removeItem(prefix) + undefinedTiles.add(index) + console.log("Dropped old format tile", prefix) + continue + } + + const data = Number(localStorage.getItem(prefix+"-time")) const freshness = new Date() freshness.setTime(data) this.tileFreshness.set(index, freshness) diff --git a/assets/themes/cyclestreets/cyclestreets.json b/assets/themes/cyclestreets/cyclestreets.json index 45ad1a90c..39f75ac78 100644 --- a/assets/themes/cyclestreets/cyclestreets.json +++ b/assets/themes/cyclestreets/cyclestreets.json @@ -35,6 +35,10 @@ "startLon": 3.2228, "maintainer": "MapComplete", "widenfactor": 2, + "clustering": { + "maxZoom": 12, + "minNeededElements": 200 + }, "roamingRenderings": [ { "question": { From a6e8714ae07fe3f63f55172938de1f0503e5f543 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 23:56:59 +0200 Subject: [PATCH 57/65] Refactoring of image detection, fix loading wikimedia images --- Logic/Actors/ImageSearcher.ts | 173 ---------------- .../TiledFromLocalStorageSource.ts | 3 +- Logic/ImageProviders/AllImageProviders.ts | 54 ++++- Logic/ImageProviders/GenericImageProvider.ts | 36 ++++ .../ImageProviders/ImageAttributionSource.ts | 33 ---- Logic/ImageProviders/ImageProvider.ts | 64 ++++++ Logic/ImageProviders/Imgur.ts | 23 ++- Logic/ImageProviders/LicenseInfo.ts | 10 + Logic/ImageProviders/Mapillary.ts | 59 +++--- Logic/ImageProviders/WikidataImageProvider.ts | 51 +++++ Logic/ImageProviders/Wikimedia.ts | 185 ------------------ .../ImageProviders/WikimediaImageProvider.ts | 163 +++++++++++++++ Logic/UIEventSource.ts | 2 +- Models/Constants.ts | 7 +- UI/Image/AttributedImage.ts | 23 +-- UI/Image/Attribution.ts | 2 +- UI/Image/ImageCarousel.ts | 67 +++---- UI/SpecialVisualizations.ts | 7 +- assets/themes/natuurpunt/natuurpunt.json | 4 +- test/ImageSearcher.spec.ts | 28 --- test/TestAll.ts | 2 - 21 files changed, 468 insertions(+), 528 deletions(-) delete mode 100644 Logic/Actors/ImageSearcher.ts create mode 100644 Logic/ImageProviders/GenericImageProvider.ts delete mode 100644 Logic/ImageProviders/ImageAttributionSource.ts create mode 100644 Logic/ImageProviders/ImageProvider.ts create mode 100644 Logic/ImageProviders/LicenseInfo.ts create mode 100644 Logic/ImageProviders/WikidataImageProvider.ts delete mode 100644 Logic/ImageProviders/Wikimedia.ts create mode 100644 Logic/ImageProviders/WikimediaImageProvider.ts delete mode 100644 test/ImageSearcher.spec.ts diff --git a/Logic/Actors/ImageSearcher.ts b/Logic/Actors/ImageSearcher.ts deleted file mode 100644 index c2d089e51..000000000 --- a/Logic/Actors/ImageSearcher.ts +++ /dev/null @@ -1,173 +0,0 @@ -import {ImagesInCategory, Wikidata, Wikimedia} from "../ImageProviders/Wikimedia"; -import {UIEventSource} from "../UIEventSource"; - -/** - * There are multiple way to fetch images for an object - * 1) There is an image tag - * 2) There is an image tag, the image tag contains multiple ';'-separated URLS - * 3) there are multiple image tags, e.g. 'image', 'image:0', 'image:1', and 'image_0', 'image_1' - however, these are pretty rare so we are gonna ignore them - * 4) There is a wikimedia_commons-tag, which either has a 'File': or a 'category:' containing images - * 5) There is a wikidata-tag, and the wikidata item either has an 'image' attribute or has 'a link to a wikimedia commons category' - * 6) There is a wikipedia article, from which we can deduct the wikidata item - * - * For some images, author and license should be shown - */ -/** - * Class which search for all the possible locations for images and which builds a list of UI-elements for it. - * Note that this list is embedded into an UIEVentSource, ready to put it into a carousel. - * - */ -export class ImageSearcher extends UIEventSource<{ key: string, url: string }[]> { - - private static _cache = new Map(); - private readonly _wdItem = new UIEventSource(""); - private readonly _commons = new UIEventSource(""); - - private constructor(tags: UIEventSource, imagePrefix = "image", loadSpecial = true) { - super([]) - const self = this; - - function AddImages(images: { key: string, url: string }[]) { - const oldUrls = self.data.map(kurl => kurl.url); - let somethingChanged = false; - for (const image of images) { - const url = image.url; - - if (url === undefined || url === null || url === "") { - continue; - } - if (oldUrls.indexOf(url) >= 0) { - // Already exists - continue; - } - - self.data.push(image); - somethingChanged = true; - } - if (somethingChanged) { - self.ping(); - } - } - - function addImage(image: string) { - AddImages([{url: image, key: undefined}]); - } - - - // By wrapping this in a UIEventSource, we prevent multiple queries of loadWikiData - this._wdItem.addCallback(wdItemContents => { - ImageSearcher.loadWikidata(wdItemContents, addImage); - }); - this._commons.addCallback(commonsData => { - ImageSearcher.LoadCommons(commonsData, addImage) - }); - tags.addCallbackAndRun(tags => { - AddImages(ImageSearcher.LoadImages(tags, imagePrefix)); - }); - - if (loadSpecial) { - tags.addCallbackAndRunD(tags => { - - const wdItem = tags.wikidata; - if (wdItem !== undefined) { - self._wdItem.setData(wdItem); - } - const commons = tags.wikimedia_commons; - if (commons !== undefined) { - self._commons.setData(commons); - } - - if (tags.mapillary) { - let mapillary = tags.mapillary; - const prefix = "https://www.mapillary.com/map/im/"; - - let regex = /https?:\/\/www.mapillary.com\/app\/.*pKey=([^&]*).*/ - let match = mapillary.match(regex); - if (match) { - mapillary = match[1]; - } - - if (mapillary.indexOf(prefix) < 0) { - mapillary = prefix + mapillary; - } - - - AddImages([{url: mapillary, key: undefined}]); - } - }) - } - } - - public static construct(tags: UIEventSource, imagePrefix = "image", loadSpecial = true): ImageSearcher { - const key = tags.data["id"] + " " + imagePrefix + loadSpecial; - if (tags.data["id"] !== undefined && ImageSearcher._cache.has(key)) { - return ImageSearcher._cache.get(key) - } - - const searcher = new ImageSearcher(tags, imagePrefix, loadSpecial); - ImageSearcher._cache.set(key, searcher) - return searcher; - } - - private static loadWikidata(wikidataItem, addImage: ((url: string) => void)): void { - // Load the wikidata item, then detect usage on 'commons' - let allWikidataId = wikidataItem.split(";"); - for (let wikidataId of allWikidataId) { - // @ts-ignore - if (wikidataId.startsWith("Q")) { - wikidataId = wikidataId.substr(1); - } - Wikimedia.GetWikiData(parseInt(wikidataId), (wd: Wikidata) => { - addImage(wd.image); - Wikimedia.GetCategoryFiles(wd.commonsWiki, (images: ImagesInCategory) => { - for (const image of images.images) { - if (image.startsWith("File:")) { - addImage(image); - } - } - }) - }) - } - } - - private static LoadCommons(commonsData: string, addImage: ((url: string) => void)): void { - const allCommons: string[] = commonsData.split(";"); - for (const commons of allCommons) { - if (commons.startsWith("Category:")) { - Wikimedia.GetCategoryFiles(commons, (images: ImagesInCategory) => { - for (const image of images.images) { - if (image.startsWith("File:")) { - addImage(image) - } - } - }) - } else { - if (commons.startsWith("File:")) { - addImage(commons) - } - } - } - } - - private static LoadImages(tags: any, imagePrefix: string): { key: string, url: string }[] { - const imageTag = tags[imagePrefix]; - const images: { key: string, url: string }[] = []; - if (imageTag !== undefined) { - const bareImages = imageTag.split(";"); - for (const bareImage of bareImages) { - images.push({key: imagePrefix, url: bareImage}) - } - } - - for (const key in tags) { - if (key.startsWith(imagePrefix + ":")) { - const url = tags[key] - images.push({key: key, url: url}) - } - } - - - return images; - } - -} \ No newline at end of file diff --git a/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts b/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts index 3ad933d7e..016537968 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts @@ -24,11 +24,12 @@ public tileFreshness : Map = new Map() // @ts-ignore const indexes: number[] = Object.keys(localStorage) .filter(key => { - return key.startsWith(prefix) && !key.endsWith("-time"); + return key.startsWith(prefix) && !key.endsWith("-time") && !key.endsWith("-format"); }) .map(key => { return Number(key.substring(prefix.length)); }) + .filter(i => !isNaN(i)) console.debug("Layer", layer.layerDef.id, "has following tiles in available in localstorage", indexes.map(i => Tiles.tile_from_index(i).join("/")).join(", ")) for (const index of indexes) { diff --git a/Logic/ImageProviders/AllImageProviders.ts b/Logic/ImageProviders/AllImageProviders.ts index e616e59e7..c1fe3bb45 100644 --- a/Logic/ImageProviders/AllImageProviders.ts +++ b/Logic/ImageProviders/AllImageProviders.ts @@ -1,9 +1,59 @@ import {Mapillary} from "./Mapillary"; -import {Wikimedia} from "./Wikimedia"; +import {WikimediaImageProvider} from "./WikimediaImageProvider"; import {Imgur} from "./Imgur"; +import GenericImageProvider from "./GenericImageProvider"; +import {UIEventSource} from "../UIEventSource"; +import ImageProvider, {ProvidedImage} from "./ImageProvider"; +import {WikidataImageProvider} from "./WikidataImageProvider"; +import {Utils} from "../../Utils"; +/** + * A generic 'from the interwebz' image picker, without attribution + */ export default class AllImageProviders { - public static ImageAttributionSource = [Imgur.singleton, Mapillary.singleton, Wikimedia.singleton] + public static ImageAttributionSource: ImageProvider[] = [ + Imgur.singleton, + Mapillary.singleton, + WikidataImageProvider.singleton, + WikimediaImageProvider.singleton, + new GenericImageProvider(Imgur.defaultValuePrefix)] + + + private static _cache: Map> = new Map>() + + public static LoadImagesFor(tags: UIEventSource, imagePrefix: string, loadSpecialSource: boolean): UIEventSource { + const id = tags.data.id + if (id === undefined) { + return undefined; + } + + const cached = this._cache.get(tags.data.id) + if (cached !== undefined) { + return cached + } + + const source = new UIEventSource([]) + this._cache.set(id, source) + const allSources = [] + for (const imageProvider of AllImageProviders.ImageAttributionSource) { + const singleSource = imageProvider.GetRelevantUrls(tags) + allSources.push(singleSource) + singleSource.addCallbackAndRunD(_ => { + const all : ProvidedImage[] = [].concat(...allSources.map(source => source.data)) + const uniq = [] + const seen = new Set() + for (const img of all) { + if(seen.has(img.url)){ + continue + } + seen.add(img.url) + uniq.push(img) + } + source.setData(uniq) + }) + } + return source; + } } \ No newline at end of file diff --git a/Logic/ImageProviders/GenericImageProvider.ts b/Logic/ImageProviders/GenericImageProvider.ts new file mode 100644 index 000000000..170829fe0 --- /dev/null +++ b/Logic/ImageProviders/GenericImageProvider.ts @@ -0,0 +1,36 @@ +import ImageProvider, {ProvidedImage} from "./ImageProvider"; + +export default class GenericImageProvider extends ImageProvider { + public defaultKeyPrefixes: string[] = ["image"]; + + private readonly _valuePrefixBlacklist: string[]; + + public constructor(valuePrefixBlacklist: string[]) { + super(); + this._valuePrefixBlacklist = valuePrefixBlacklist; + } + + + protected DownloadAttribution(url: string) { + return undefined + } + + async ExtractUrls(key: string, value: string): Promise[]> { + + if (this._valuePrefixBlacklist.some(prefix => value.startsWith(prefix))) { + return [] + } + + return [Promise.resolve({ + key: key, + url: value, + provider: this + })] + } + + SourceIcon(backlinkSource?: string) { + return undefined; + } + + +} \ No newline at end of file diff --git a/Logic/ImageProviders/ImageAttributionSource.ts b/Logic/ImageProviders/ImageAttributionSource.ts deleted file mode 100644 index 1f0f097b7..000000000 --- a/Logic/ImageProviders/ImageAttributionSource.ts +++ /dev/null @@ -1,33 +0,0 @@ -import {UIEventSource} from "../UIEventSource"; -import {LicenseInfo} from "./Wikimedia"; -import BaseUIElement from "../../UI/BaseUIElement"; - - -export default abstract class ImageAttributionSource { - - private _cache = new Map>() - - GetAttributionFor(url: string): UIEventSource { - const cached = this._cache.get(url); - if (cached !== undefined) { - return cached; - } - const src = new UIEventSource(undefined) - this._cache.set(url, src) - this.DownloadAttribution(url).then(license => - src.setData(license)) - .catch(e => console.error("Could not download license information for ", url, " due to", e)) - return src; - } - - - public abstract SourceIcon(backlinkSource?: string): BaseUIElement; - - /*Converts a value to a URL. Can return null if not applicable*/ - public PrepareUrl(value: string): string | UIEventSource { - return value; - } - - protected abstract DownloadAttribution(url: string): Promise; - -} \ No newline at end of file diff --git a/Logic/ImageProviders/ImageProvider.ts b/Logic/ImageProviders/ImageProvider.ts new file mode 100644 index 000000000..67154d945 --- /dev/null +++ b/Logic/ImageProviders/ImageProvider.ts @@ -0,0 +1,64 @@ +import {UIEventSource} from "../UIEventSource"; +import BaseUIElement from "../../UI/BaseUIElement"; +import {LicenseInfo} from "./LicenseInfo"; + +export interface ProvidedImage { + url: string, key: string, provider: ImageProvider +} + +export default abstract class ImageProvider { + + protected abstract readonly defaultKeyPrefixes : string[] + + private _cache = new Map>() + + GetAttributionFor(url: string): UIEventSource { + const cached = this._cache.get(url); + if (cached !== undefined) { + return cached; + } + const src =UIEventSource.FromPromise(this.DownloadAttribution(url)) + this._cache.set(url, src) + return src; + } + + public abstract SourceIcon(backlinkSource?: string): BaseUIElement; + + protected abstract DownloadAttribution(url: string): Promise; + + /** + * Given a properies object, maps it onto _all_ the available pictures for this imageProvider + */ + public GetRelevantUrls(allTags: UIEventSource, options?: { + prefixes?: string[] + }):UIEventSource { + const prefixes = options?.prefixes ?? this.defaultKeyPrefixes + const relevantUrls = new UIEventSource<{ url: string; key: string; provider: ImageProvider }[]>([]) + const seenValues = new Set() + allTags.addCallbackAndRunD(tags => { + for (const key in tags) { + if(!prefixes.some(prefix => key.startsWith(prefix))){ + continue + } + const value = tags[key] + if(seenValues.has(value)){ + continue + } + seenValues.add(value) + + this.ExtractUrls(key, value).then(promises => { + for (const promise of promises) { + promise.then(providedImage => { + relevantUrls.data.push(providedImage) + relevantUrls.ping() + }) + } + }) + } + }) + return relevantUrls + } + + public abstract ExtractUrls(key: string, value: string) : Promise[]>; + +} \ No newline at end of file diff --git a/Logic/ImageProviders/Imgur.ts b/Logic/ImageProviders/Imgur.ts index f85f3228a..289dad1f8 100644 --- a/Logic/ImageProviders/Imgur.ts +++ b/Logic/ImageProviders/Imgur.ts @@ -1,12 +1,14 @@ -// @ts-ignore import $ from "jquery" -import {LicenseInfo} from "./Wikimedia"; -import ImageAttributionSource from "./ImageAttributionSource"; +import ImageProvider, {ProvidedImage} from "./ImageProvider"; import BaseUIElement from "../../UI/BaseUIElement"; import {Utils} from "../../Utils"; import Constants from "../../Models/Constants"; +import {LicenseInfo} from "./LicenseInfo"; -export class Imgur extends ImageAttributionSource { +export class Imgur extends ImageProvider { + + public static readonly defaultValuePrefix = ["https://i.imgur.com"] + public readonly defaultKeyPrefixes: string[] = ["image"]; public static readonly singleton = new Imgur(); @@ -87,7 +89,7 @@ export class Imgur extends ImageAttributionSource { return undefined; } - protected async DownloadAttribution(url: string): Promise { + protected DownloadAttribution: (url: string) => Promise = async (url: string) => { const hash = url.substr("https://i.imgur.com/".length).split(".jpg")[0]; const apiUrl = 'https://api.imgur.com/3/image/' + hash; @@ -110,5 +112,16 @@ export class Imgur extends ImageAttributionSource { return licenseInfo } + public async ExtractUrls(key: string, value: string): Promise[]> { + if (Imgur.defaultValuePrefix.some(prefix => value.startsWith(prefix))) { + return [Promise.resolve({ + url: value, + key: key, + provider: this + })] + } + return [] + } + } \ No newline at end of file diff --git a/Logic/ImageProviders/LicenseInfo.ts b/Logic/ImageProviders/LicenseInfo.ts new file mode 100644 index 000000000..b5954693c --- /dev/null +++ b/Logic/ImageProviders/LicenseInfo.ts @@ -0,0 +1,10 @@ +export class LicenseInfo { + artist: string = ""; + license: string = ""; + licenseShortName: string = ""; + usageTerms: string = ""; + attributionRequired: boolean = false; + copyrighted: boolean = false; + credit: string = ""; + description: string = ""; +} \ No newline at end of file diff --git a/Logic/ImageProviders/Mapillary.ts b/Logic/ImageProviders/Mapillary.ts index ae5808a01..45342bc14 100644 --- a/Logic/ImageProviders/Mapillary.ts +++ b/Logic/ImageProviders/Mapillary.ts @@ -1,19 +1,19 @@ -import {LicenseInfo} from "./Wikimedia"; -import ImageAttributionSource from "./ImageAttributionSource"; +import ImageProvider, {ProvidedImage} from "./ImageProvider"; import BaseUIElement from "../../UI/BaseUIElement"; import {UIEventSource} from "../UIEventSource"; import Svg from "../../Svg"; import {Utils} from "../../Utils"; +import {LicenseInfo} from "./LicenseInfo"; +import Constants from "../../Models/Constants"; -export class Mapillary extends ImageAttributionSource { +export class Mapillary extends ImageProvider { + defaultKeyPrefixes = ["mapillary"] + public static readonly singleton = new Mapillary(); private static readonly v4_cached_urls = new Map>(); - private static readonly client_token_v3 = 'TXhLaWthQ1d4RUg0czVxaTVoRjFJZzowNDczNjUzNmIyNTQyYzI2' - private static readonly client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" - private constructor() { super(); } @@ -56,29 +56,34 @@ export class Mapillary extends ImageAttributionSource { return Svg.mapillary_svg(); } - PrepareUrl(value: string): string | UIEventSource { - const keyV = Mapillary.ExtractKeyFromURL(value) - if (!keyV.isApiv4) { - return `https://images.mapillary.com/${keyV.key}/thumb-640.jpg?client_id=${Mapillary.client_token_v3}` - } else { - const key = keyV.key; - if (Mapillary.v4_cached_urls.has(key)) { - return Mapillary.v4_cached_urls.get(key) - } - - const metadataUrl = 'https://graph.mapillary.com/' + key + '?fields=thumb_1024_url&&access_token=' + Mapillary.client_token_v4; - const source = new UIEventSource(undefined) - Mapillary.v4_cached_urls.set(key, source) - Utils.downloadJson(metadataUrl).then( - json => { - console.warn("Got response on mapillary image", json, json["thumb_1024_url"]) - return source.setData(json["thumb_1024_url"]); - } - ) - return source - } + async ExtractUrls(key: string, value: string): Promise[]> { + return [this.PrepareUrlAsync(key, value)] } + private async PrepareUrlAsync(key: string, value: string): Promise { + const keyV = Mapillary.ExtractKeyFromURL(value) + if (!keyV.isApiv4) { + const url = `https://images.mapillary.com/${keyV.key}/thumb-640.jpg?client_id=${Constants.mapillary_client_token_v3}` + return { + url: url, + provider: this, + key: key + } + } else { + const key = keyV.key; + const metadataUrl = 'https://graph.mapillary.com/' + key + '?fields=thumb_1024_url&&access_token=' + Constants.mapillary_client_token_v4; + const source = new UIEventSource(undefined) + Mapillary.v4_cached_urls.set(key, source) + const response = await Utils.downloadJson(metadataUrl) + const url = response["thumb_1024_url"]; + return { + url: url, + provider: this, + key: key + } + } + } + protected async DownloadAttribution(url: string): Promise { const keyV = Mapillary.ExtractKeyFromURL(url) diff --git a/Logic/ImageProviders/WikidataImageProvider.ts b/Logic/ImageProviders/WikidataImageProvider.ts new file mode 100644 index 000000000..3bb7d3c91 --- /dev/null +++ b/Logic/ImageProviders/WikidataImageProvider.ts @@ -0,0 +1,51 @@ +import {Utils} from "../../Utils"; +import ImageProvider, {ProvidedImage} from "./ImageProvider"; +import BaseUIElement from "../../UI/BaseUIElement"; +import Svg from "../../Svg"; +import {WikimediaImageProvider} from "./WikimediaImageProvider"; + +export class WikidataImageProvider extends ImageProvider { + + public SourceIcon(backlinkSource?: string): BaseUIElement { + throw Svg.wikidata_svg(); + } + + public static readonly singleton = new WikidataImageProvider() + public readonly defaultKeyPrefixes = ["wikidata"] + + private constructor() { + super() + } + + protected DownloadAttribution(url: string): Promise { + throw new Error("Method not implemented; shouldn't be needed!"); + } + + public async ExtractUrls(key: string, value: string): Promise[]> { + const wikidataUrl = "https://www.wikidata.org/wiki/" + if (value.startsWith(wikidataUrl)) { + value = value.substring(wikidataUrl.length) + } + if (!value.startsWith("Q")) { + value = "Q" + value + } + const url = "https://www.wikidata.org/wiki/Special:EntityData/" + value + ".json"; + const response = await Utils.downloadJson(url) + const entity = response.entities[value]; + const commons = entity.sitelinks.commonswiki; + // P18 is the claim 'depicted in this image' + const image = entity.claims.P18?.[0]?.mainsnak?.datavalue?.value; + const allImages = [] + if (image !== undefined) { + // We found a 'File://' + const promises = await WikimediaImageProvider.singleton.ExtractUrls(key, image) + allImages.push(...promises) + } + if (commons !== undefined) { + const promises = await WikimediaImageProvider.singleton.ExtractUrls(commons, image) + allImages.push(...promises) + } + return allImages + } + +} \ No newline at end of file diff --git a/Logic/ImageProviders/Wikimedia.ts b/Logic/ImageProviders/Wikimedia.ts deleted file mode 100644 index cd5aea5d5..000000000 --- a/Logic/ImageProviders/Wikimedia.ts +++ /dev/null @@ -1,185 +0,0 @@ -import ImageAttributionSource from "./ImageAttributionSource"; -import BaseUIElement from "../../UI/BaseUIElement"; -import Svg from "../../Svg"; -import Link from "../../UI/Base/Link"; -import {Utils} from "../../Utils"; - -/** - * This module provides endpoints for wikipedia/wikimedia and others - */ -export class Wikimedia extends ImageAttributionSource { - - - public static readonly singleton = new Wikimedia(); - - private constructor() { - super(); - } - - - static ImageNameToUrl(filename: string, width: number = 500, height: number = 200): string { - filename = encodeURIComponent(filename); - return "https://commons.wikimedia.org/wiki/Special:FilePath/" + filename + "?width=" + width + "&height=" + height; - } - - static GetCategoryFiles(categoryName: string, handleCategory: ((ImagesInCategory: ImagesInCategory) => void), - alreadyLoaded = 0, - continueParameter: { k: string, param: string } = undefined) { - if (categoryName === undefined || categoryName === null || categoryName === "") { - return; - } - // @ts-ignore - if (!categoryName.startsWith("Category:")) { - categoryName = "Category:" + categoryName; - } - let url = "https://commons.wikimedia.org/w/api.php?" + - "action=query&list=categorymembers&format=json&" + - "&origin=*" + - "&cmtitle=" + encodeURIComponent(categoryName); - if (continueParameter !== undefined) { - url = url + "&" + continueParameter.k + "=" + continueParameter.param; - } - const self = this; - console.log("Loading a wikimedia category: ", url) - Utils.downloadJson(url).then((response) => { - let imageOverview = new ImagesInCategory(); - let members = response.query?.categorymembers; - if (members === undefined) { - members = []; - } - - for (const member of members) { - imageOverview.images.push(member.title); - } - console.log("Got images! ", imageOverview) - if (response.continue === undefined) { - handleCategory(imageOverview); - return; - } - - if (alreadyLoaded > 10) { - console.log(`Recursive wikimedia category load stopped for ${categoryName} - got already enough images now (${alreadyLoaded})`) - handleCategory(imageOverview) - return; - } - - self.GetCategoryFiles(categoryName, - (recursiveImages) => { - recursiveImages.images.push(...imageOverview.images); - handleCategory(recursiveImages); - }, - alreadyLoaded + 10, - {k: "cmcontinue", param: response.continue.cmcontinue}) - - }); - } - - static GetWikiData(id: number, handleWikidata: ((Wikidata) => void)) { - const url = "https://www.wikidata.org/wiki/Special:EntityData/Q" + id + ".json"; - Utils.downloadJson(url).then(response => { - const entity = response.entities["Q" + id]; - const commons = entity.sitelinks.commonswiki; - const wd = new Wikidata(); - wd.commonsWiki = commons?.title; - - // P18 is the claim 'depicted in this image' - const image = entity.claims.P18?.[0]?.mainsnak?.datavalue?.value; - if (image) { - wd.image = "File:" + image; - } - handleWikidata(wd); - }); - } - - private static ExtractFileName(url: string) { - if (!url.startsWith("http")) { - return url; - } - const path = new URL(url).pathname - return path.substring(path.lastIndexOf("/") + 1); - - } - - SourceIcon(backlink: string): BaseUIElement { - const img = Svg.wikimedia_commons_white_svg() - .SetStyle("width:2em;height: 2em"); - if (backlink === undefined) { - return img - } - - - return new Link(Svg.wikimedia_commons_white_img, - `https://commons.wikimedia.org/wiki/${backlink}`, true) - - - } - - PrepareUrl(value: string): string { - - if (value.toLowerCase().startsWith("https://commons.wikimedia.org/wiki/")) { - return value; - } - return Wikimedia.ImageNameToUrl(value, 500, 400) - .replace(/'/g, '%27'); - } - - protected async DownloadAttribution(filename: string): Promise { - filename = Wikimedia.ExtractFileName(filename) - - if (filename === "") { - return undefined; - } - - const url = "https://en.wikipedia.org/w/" + - "api.php?action=query&prop=imageinfo&iiprop=extmetadata&" + - "titles=" + filename + - "&format=json&origin=*"; - const data = await Utils.downloadJson(url) - const licenseInfo = new LicenseInfo(); - const license = (data.query.pages[-1].imageinfo ?? [])[0]?.extmetadata; - if (license === undefined) { - console.error("This file has no usable metedata or license attached... Please fix the license info file yourself!") - return undefined; - } - - licenseInfo.artist = license.Artist?.value; - licenseInfo.license = license.License?.value; - licenseInfo.copyrighted = license.Copyrighted?.value; - licenseInfo.attributionRequired = license.AttributionRequired?.value; - licenseInfo.usageTerms = license.UsageTerms?.value; - licenseInfo.licenseShortName = license.LicenseShortName?.value; - licenseInfo.credit = license.Credit?.value; - licenseInfo.description = license.ImageDescription?.value; - return licenseInfo; - - } - - -} - -export class Wikidata { - - commonsWiki: string; - image: string; - -} - -export class ImagesInCategory { - // Filenames of relevant images - images: string[] = []; -} - -export class LicenseInfo { - - - artist: string = ""; - license: string = ""; - licenseShortName: string = ""; - usageTerms: string = ""; - attributionRequired: boolean = false; - copyrighted: boolean = false; - credit: string = ""; - description: string = ""; - - -} \ No newline at end of file diff --git a/Logic/ImageProviders/WikimediaImageProvider.ts b/Logic/ImageProviders/WikimediaImageProvider.ts new file mode 100644 index 000000000..cf4c1837b --- /dev/null +++ b/Logic/ImageProviders/WikimediaImageProvider.ts @@ -0,0 +1,163 @@ +import ImageProvider, {ProvidedImage} from "./ImageProvider"; +import BaseUIElement from "../../UI/BaseUIElement"; +import Svg from "../../Svg"; +import Link from "../../UI/Base/Link"; +import {Utils} from "../../Utils"; +import {LicenseInfo} from "./LicenseInfo"; + +/** + * This module provides endpoints for wikimedia and others + */ +export class WikimediaImageProvider extends ImageProvider { + + + public readonly defaultKeyPrefixes = ["wikimedia_commons"] + public static readonly singleton = new WikimediaImageProvider(); + + private constructor() { + super(); + } + /** + * Recursively walks a wikimedia commons category in order to search for (image) files + * Returns (a promise of) a list of URLS + * @param categoryName The name of the wikimedia category + * @param maxLoad: the maximum amount of images to return + * @param continueParameter: if the page indicates that more pages should be loaded, this uses a token to continue. Provided by wikimedia + */ + private static async GetImagesInCategory(categoryName: string, + maxLoad = 10, + continueParameter: string = undefined): Promise { + if (categoryName === undefined || categoryName === null || categoryName === "") { + return []; + } + if (!categoryName.startsWith("Category:")) { + categoryName = "Category:" + categoryName; + } + + let url = "https://commons.wikimedia.org/w/api.php?" + + "action=query&list=categorymembers&format=json&" + + "&origin=*" + + "&cmtitle=" + encodeURIComponent(categoryName); + if (continueParameter !== undefined) { + url = `${url}&cmcontinue=${continueParameter}`; + } + console.log("Loading a wikimedia category: ", url) + const response = await Utils.downloadJson(url) + const members = response.query?.categorymembers ?? []; + const imageOverview: string[] = members.map(member => member.title); + + if (response.continue === undefined) { + // We are done crawling through the category - no continuation in sight + return imageOverview; + } + + if (maxLoad - imageOverview.length <= 0) { + console.log(`Recursive wikimedia category load stopped for ${categoryName}`) + return imageOverview; + } + + // We do have a continue token - let's load the next page + const recursive = await this.GetImagesInCategory(categoryName, maxLoad - imageOverview.length, response.continue.cmcontinue) + imageOverview.push(...recursive) + return imageOverview + } + + private static ExtractFileName(url: string) { + if (!url.startsWith("http")) { + return url; + } + const path = new URL(url).pathname + return path.substring(path.lastIndexOf("/") + 1); + + } + + SourceIcon(backlink: string): BaseUIElement { + const img = Svg.wikimedia_commons_white_svg() + .SetStyle("width:2em;height: 2em"); + if (backlink === undefined) { + return img + } + + + return new Link(Svg.wikimedia_commons_white_img, + `https://commons.wikimedia.org/wiki/${backlink}`, true) + + + } + + private PrepareUrl(value: string): string { + + if (value.toLowerCase().startsWith("https://commons.wikimedia.org/wiki/")) { + return value; + } + return (`https://commons.wikimedia.org/wiki/Special:FilePath/${encodeURIComponent(value)}?width=500&height=400`) + } + + protected async DownloadAttribution(filename: string): Promise { + filename = WikimediaImageProvider.ExtractFileName(filename) + + if (filename === "") { + return undefined; + } + + const url = "https://en.wikipedia.org/w/" + + "api.php?action=query&prop=imageinfo&iiprop=extmetadata&" + + "titles=" + filename + + "&format=json&origin=*"; + const data = await Utils.downloadJson(url) + const licenseInfo = new LicenseInfo(); + const license = (data.query.pages[-1].imageinfo ?? [])[0]?.extmetadata; + if (license === undefined) { + console.error("This file has no usable metedata or license attached... Please fix the license info file yourself!") + return undefined; + } + + licenseInfo.artist = license.Artist?.value; + licenseInfo.license = license.License?.value; + licenseInfo.copyrighted = license.Copyrighted?.value; + licenseInfo.attributionRequired = license.AttributionRequired?.value; + licenseInfo.usageTerms = license.UsageTerms?.value; + licenseInfo.licenseShortName = license.LicenseShortName?.value; + licenseInfo.credit = license.Credit?.value; + licenseInfo.description = license.ImageDescription?.value; + return licenseInfo; + + } + + private async UrlForImage(image: string): Promise{ + if(!image.startsWith("File:")){ + image = "File:"+image + } + return {url: this.PrepareUrl(image), key: undefined, provider: this} + } + + public async ExtractUrls(key: string, value: string): Promise[]> { + const commonsPrefix = "https://commons.wikimedia.org/wiki/" + if(value.startsWith(commonsPrefix)){ + value = value.substring(commonsPrefix.length) + } else if(value.startsWith("https://upload.wikimedia.org")){ + const result : ProvidedImage = { + key: undefined, + url: value, + provider: this + } + return [Promise.resolve(result)] + } + if(value.startsWith("Category:")){ + const urls = await WikimediaImageProvider.GetImagesInCategory(value) + return urls.map(image => this.UrlForImage(image)) + } + if(value.startsWith("File:")){ + return [this.UrlForImage(value)] + } + if(value.startsWith("http")){ + // PRobably an error + return [] + } + // We do a last effort and assume this is a file + return [this.UrlForImage("File:"+value)] + } + + +} + diff --git a/Logic/UIEventSource.ts b/Logic/UIEventSource.ts index 42282ea2a..5f51dc004 100644 --- a/Logic/UIEventSource.ts +++ b/Logic/UIEventSource.ts @@ -64,7 +64,7 @@ export class UIEventSource { public static FromPromise(promise : Promise): UIEventSource{ const src = new UIEventSource(undefined) - promise.then(d => src.setData(d)) + promise?.then(d => src.setData(d)) return src } diff --git a/Models/Constants.ts b/Models/Constants.ts index d524c6689..4e588a057 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,8 +2,11 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.10.0-rc0"; + public static vNumber = "0.10.0-rc1"; public static ImgurApiKey = '7070e7167f0a25a' + public static readonly mapillary_client_token_v3 = 'TXhLaWthQ1d4RUg0czVxaTVoRjFJZzowNDczNjUzNmIyNTQyYzI2' + public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" + public static defaultOverpassUrls = [ // The official instance, 10000 queries per day per project allowed "https://overpass-api.de/api/interpreter", @@ -15,6 +18,8 @@ export default class Constants { "https://overpass.openstreetmap.fr/api/interpreter" ] + + // The user journey states thresholds when a new feature gets unlocked public static userJourney = { moreScreenUnlock: 1, diff --git a/UI/Image/AttributedImage.ts b/UI/Image/AttributedImage.ts index 7614077c5..919a9ac17 100644 --- a/UI/Image/AttributedImage.ts +++ b/UI/Image/AttributedImage.ts @@ -1,30 +1,19 @@ import Combine from "../Base/Combine"; import Attribution from "./Attribution"; import Img from "../Base/Img"; -import ImageAttributionSource from "../../Logic/ImageProviders/ImageAttributionSource"; +import {ProvidedImage} from "../../Logic/ImageProviders/ImageProvider"; import BaseUIElement from "../BaseUIElement"; -import {VariableUiElement} from "../Base/VariableUIElement"; -import Loading from "../Base/Loading"; export class AttributedImage extends Combine { - constructor(urlSource: string, imgSource: ImageAttributionSource) { - const preparedUrl = imgSource.PrepareUrl(urlSource) + constructor(imageInfo: ProvidedImage) { let img: BaseUIElement; let attr: BaseUIElement - if (typeof preparedUrl === "string") { - img = new Img(urlSource); - attr = new Attribution(imgSource.GetAttributionFor(urlSource), imgSource.SourceIcon()) - } else { - img = new VariableUiElement(preparedUrl.map(url => { - if(url === undefined){ - return new Loading() - } - return new Img(url, false, {fallbackImage: './assets/svg/blocked.svg'}); - })) - attr = new VariableUiElement(preparedUrl.map(_ => new Attribution(imgSource.GetAttributionFor(urlSource), imgSource.SourceIcon()))) - } + img = new Img(imageInfo.url); + attr = new Attribution(imageInfo.provider.GetAttributionFor(imageInfo.url), + imageInfo.provider.SourceIcon(), + ) super([img, attr]); diff --git a/UI/Image/Attribution.ts b/UI/Image/Attribution.ts index 9afd9b815..f57911e93 100644 --- a/UI/Image/Attribution.ts +++ b/UI/Image/Attribution.ts @@ -3,7 +3,7 @@ import Translations from "../i18n/Translations"; import BaseUIElement from "../BaseUIElement"; import {VariableUiElement} from "../Base/VariableUIElement"; import {UIEventSource} from "../../Logic/UIEventSource"; -import {LicenseInfo} from "../../Logic/ImageProviders/Wikimedia"; +import {LicenseInfo} from "../../Logic/ImageProviders/LicenseInfo"; export default class Attribution extends VariableUiElement { diff --git a/UI/Image/ImageCarousel.ts b/UI/Image/ImageCarousel.ts index 4e7d032d2..c20f52080 100644 --- a/UI/Image/ImageCarousel.ts +++ b/UI/Image/ImageCarousel.ts @@ -4,29 +4,35 @@ import Combine from "../Base/Combine"; import DeleteImage from "./DeleteImage"; import {AttributedImage} from "./AttributedImage"; import BaseUIElement from "../BaseUIElement"; -import Img from "../Base/Img"; import Toggle from "../Input/Toggle"; -import {Wikimedia} from "../../Logic/ImageProviders/Wikimedia"; -import {Imgur} from "../../Logic/ImageProviders/Imgur"; -import {Mapillary} from "../../Logic/ImageProviders/Mapillary"; +import ImageProvider from "../../Logic/ImageProviders/ImageProvider"; export class ImageCarousel extends Toggle { - constructor(images: UIEventSource<{ key: string, url: string }[]>, tags: UIEventSource) { - const uiElements = images.map((imageURLS: { key: string, url: string }[]) => { + constructor(images: UIEventSource<{ key: string, url: string, provider: ImageProvider }[]>, tags: UIEventSource) { + const uiElements = images.map((imageURLS: { key: string, url: string, provider: ImageProvider }[]) => { const uiElements: BaseUIElement[] = []; for (const url of imageURLS) { - let image = ImageCarousel.CreateImageElement(url.url) - if (url.key !== undefined) { - image = new Combine([ - image, - new DeleteImage(url.key, tags).SetClass("delete-image-marker absolute top-0 left-0 pl-3") - ]).SetClass("relative"); + + try { + + let image = new AttributedImage(url) + + if (url.key !== undefined) { + image = new Combine([ + image, + new DeleteImage(url.key, tags).SetClass("delete-image-marker absolute top-0 left-0 pl-3") + ]).SetClass("relative"); + } + image + .SetClass("w-full block") + .SetStyle("min-width: 50px; background: grey;") + uiElements.push(image); + } catch (e) { + console.error("Could not generate image element for", url.url, "due to", e) } - image - .SetClass("w-full block") - .SetStyle("min-width: 50px; background: grey;") - uiElements.push(image); + + } return uiElements; }); @@ -38,33 +44,4 @@ export class ImageCarousel extends Toggle { ) this.SetClass("block w-full"); } - - /*** - * Creates either a 'simpleimage' or a 'wikimediaimage' based on the string - * @param url - * @constructor - */ - private static CreateImageElement(url: string): BaseUIElement { - // @ts-ignore - let attrSource: ImageAttributionSource = undefined; - if (url.startsWith("File:")) { - attrSource = Wikimedia.singleton - } else if (url.toLowerCase().startsWith("https://commons.wikimedia.org/wiki/")) { - attrSource = Wikimedia.singleton; - } else if (url.toLowerCase().startsWith("https://i.imgur.com/")) { - attrSource = Imgur.singleton - } else if (url.toLowerCase().startsWith("https://www.mapillary.com/map/im/")) { - attrSource = Mapillary.singleton - } else { - return new Img(url); - } - - try { - return new AttributedImage(url, attrSource) - } catch (e) { - console.error("Could not create an image: ", e) - return undefined; - } - - } } \ No newline at end of file diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 5b15cfdaa..4aba67e7d 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -13,20 +13,19 @@ import Translations from "./i18n/Translations"; import ReviewForm from "./Reviews/ReviewForm"; import OpeningHoursVisualization from "./OpeningHours/OpeningHoursVisualization"; import State from "../State"; -import {ImageSearcher} from "../Logic/Actors/ImageSearcher"; import BaseUIElement from "./BaseUIElement"; import Title from "./Base/Title"; import Table from "./Base/Table"; import Histogram from "./BigComponents/Histogram"; import Loc from "../Models/Loc"; import {Utils} from "../Utils"; -import BaseLayer from "../Models/BaseLayer"; import LayerConfig from "../Models/ThemeConfig/LayerConfig"; import ImportButton from "./BigComponents/ImportButton"; import {Tag} from "../Logic/Tags/Tag"; import StaticFeatureSource from "../Logic/FeatureSource/Sources/StaticFeatureSource"; import ShowDataMultiLayer from "./ShowDataLayer/ShowDataMultiLayer"; import Minimap from "./Base/Minimap"; +import AllImageProviders from "../Logic/ImageProviders/AllImageProviders"; export interface SpecialVisualization { funcName: string, @@ -76,9 +75,7 @@ export default class SpecialVisualizations { constr: (state: State, tags, args) => { const imagePrefix = args[0]; const loadSpecial = args[1].toLowerCase() === "true"; - const searcher: UIEventSource<{ key: string, url: string }[]> = ImageSearcher.construct(tags, imagePrefix, loadSpecial); - - return new ImageCarousel(searcher, tags); + return new ImageCarousel(AllImageProviders.LoadImagesFor(tags, imagePrefix, loadSpecial), tags); } }, { diff --git a/assets/themes/natuurpunt/natuurpunt.json b/assets/themes/natuurpunt/natuurpunt.json index 1ed0b7e88..c5345a55f 100644 --- a/assets/themes/natuurpunt/natuurpunt.json +++ b/assets/themes/natuurpunt/natuurpunt.json @@ -75,7 +75,7 @@ "icon": { "render": "circle:#FE6F32;./assets/themes/natuurpunt/nature_reserve.svg" }, - "presets": null + "presets": [] } }, { @@ -262,4 +262,4 @@ } } ] -} \ No newline at end of file +} diff --git a/test/ImageSearcher.spec.ts b/test/ImageSearcher.spec.ts deleted file mode 100644 index 9b3d713ac..000000000 --- a/test/ImageSearcher.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {Utils} from "../Utils"; -import {equal} from "assert"; -import T from "./TestHelper"; -import {UIEventSource} from "../Logic/UIEventSource"; -import {ImageSearcher} from "../Logic/Actors/ImageSearcher"; - -Utils.runningFromConsole = true; -export default class ImageSearcherSpec extends T { - - constructor() { - super("imagesearcher", [ - [ - "Should find images", - () => { - const tags = new UIEventSource({ - "mapillary": "https://www.mapillary.com/app/?pKey=bYH6FFl8LXAPapz4PNSh3Q" - }); - const searcher = ImageSearcher.construct(tags) - const result = searcher.data[0]; - equal(result.url, "https://www.mapillary.com/map/im/bYH6FFl8LXAPapz4PNSh3Q"); - } - ], - ]); - - } - - -} diff --git a/test/TestAll.ts b/test/TestAll.ts index 1a25a0afc..0efa98dd4 100644 --- a/test/TestAll.ts +++ b/test/TestAll.ts @@ -1,7 +1,6 @@ import TagSpec from "./Tag.spec"; import ImageAttributionSpec from "./ImageAttribution.spec"; import GeoOperationsSpec from "./GeoOperations.spec"; -import ImageSearcherSpec from "./ImageSearcher.spec"; import ThemeSpec from "./Theme.spec"; import UtilsSpec from "./Utils.spec"; import OsmObjectSpec from "./OsmObject.spec"; @@ -18,7 +17,6 @@ const allTests = [ new TagSpec(), new ImageAttributionSpec(), new GeoOperationsSpec(), - new ImageSearcherSpec(), new ThemeSpec(), new UtilsSpec(), new UnitsSpec(), From 0326668e622ce71e2e1a15f7e0dd7bdf5dc6fedb Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 23:58:17 +0200 Subject: [PATCH 58/65] Fix index page --- State.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/State.ts b/State.ts index 00dac3bb5..7279136b3 100644 --- a/State.ts +++ b/State.ts @@ -321,7 +321,7 @@ export default class State { ); this.overpassUrl = QueryParameters.GetQueryParameter("overpassUrl", - layoutToUse?.overpassUrl.join(","), + (layoutToUse?.overpassUrl ?? Constants.defaultOverpassUrls).join(",") , "Point mapcomplete to a different overpass-instance. Example: https://overpass-api.de/api/interpreter" ).map(param => param.split(","), [], urls => urls.join(",")) From 8cbb693c98e1fe619affb631b45dc5774ca3baef Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 29 Sep 2021 23:59:56 +0200 Subject: [PATCH 59/65] Fix geolocation --- Logic/Actors/GeoLocationHandler.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Logic/Actors/GeoLocationHandler.ts b/Logic/Actors/GeoLocationHandler.ts index 01e09a717..3abf8e8e2 100644 --- a/Logic/Actors/GeoLocationHandler.ts +++ b/Logic/Actors/GeoLocationHandler.ts @@ -60,12 +60,12 @@ export default class GeoLocationHandler extends VariableUiElement { * @private */ private readonly _previousLocationGrant: UIEventSource; - private readonly _layoutToUse: UIEventSource; + private readonly _layoutToUse: LayoutConfig; constructor( currentGPSLocation: UIEventSource<{ latlng: any; accuracy: number }>, leafletMap: UIEventSource, - layoutToUse: UIEventSource + layoutToUse: LayoutConfig ) { const hasLocation = currentGPSLocation.map( (location) => location !== undefined @@ -264,7 +264,7 @@ export default class GeoLocationHandler extends VariableUiElement { } // We check that the GPS location is not out of bounds - const b = this._layoutToUse.data.lockLocation; + const b = this._layoutToUse.lockLocation; let inRange = true; if (b) { if (b !== true) { From 32cbd6e2c139abbdf8cdbafcadbced1b2fb20780 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Thu, 30 Sep 2021 00:26:21 +0200 Subject: [PATCH 60/65] Also pickup wikimedia categories in the image tags, fix #433 --- Logic/ImageProviders/AllImageProviders.ts | 10 +++--- .../ImageProviders/WikimediaImageProvider.ts | 35 +++++++++++-------- Models/ThemeConfig/FilterConfig.ts | 4 +++ UI/BigComponents/SimpleAddUI.ts | 21 +++++++++-- UI/SpecialVisualizations.ts | 10 ++---- .../public_bookcase/public_bookcase.json | 6 ++-- 6 files changed, 55 insertions(+), 31 deletions(-) diff --git a/Logic/ImageProviders/AllImageProviders.ts b/Logic/ImageProviders/AllImageProviders.ts index c1fe3bb45..18589f635 100644 --- a/Logic/ImageProviders/AllImageProviders.ts +++ b/Logic/ImageProviders/AllImageProviders.ts @@ -5,7 +5,6 @@ import GenericImageProvider from "./GenericImageProvider"; import {UIEventSource} from "../UIEventSource"; import ImageProvider, {ProvidedImage} from "./ImageProvider"; import {WikidataImageProvider} from "./WikidataImageProvider"; -import {Utils} from "../../Utils"; /** * A generic 'from the interwebz' image picker, without attribution @@ -17,12 +16,12 @@ export default class AllImageProviders { Mapillary.singleton, WikidataImageProvider.singleton, WikimediaImageProvider.singleton, - new GenericImageProvider(Imgur.defaultValuePrefix)] + new GenericImageProvider([].concat(...Imgur.defaultValuePrefix, WikimediaImageProvider.commonsPrefix))] private static _cache: Map> = new Map>() - public static LoadImagesFor(tags: UIEventSource, imagePrefix: string, loadSpecialSource: boolean): UIEventSource { + public static LoadImagesFor(tags: UIEventSource, imagePrefix?: string): UIEventSource { const id = tags.data.id if (id === undefined) { return undefined; @@ -33,11 +32,14 @@ export default class AllImageProviders { return cached } + const source = new UIEventSource([]) this._cache.set(id, source) const allSources = [] for (const imageProvider of AllImageProviders.ImageAttributionSource) { - const singleSource = imageProvider.GetRelevantUrls(tags) + const singleSource = imageProvider.GetRelevantUrls(tags, { + prefixes: imagePrefix !== undefined ? [imagePrefix] : undefined + }) allSources.push(singleSource) singleSource.addCallbackAndRunD(_ => { const all : ProvidedImage[] = [].concat(...allSources.map(source => source.data)) diff --git a/Logic/ImageProviders/WikimediaImageProvider.ts b/Logic/ImageProviders/WikimediaImageProvider.ts index cf4c1837b..b8940a520 100644 --- a/Logic/ImageProviders/WikimediaImageProvider.ts +++ b/Logic/ImageProviders/WikimediaImageProvider.ts @@ -11,12 +11,15 @@ import {LicenseInfo} from "./LicenseInfo"; export class WikimediaImageProvider extends ImageProvider { - public readonly defaultKeyPrefixes = ["wikimedia_commons"] + private readonly commons_key = "wikimedia_commons" + public readonly defaultKeyPrefixes = [this.commons_key,"image"] public static readonly singleton = new WikimediaImageProvider(); + public static readonly commonsPrefix = "https://commons.wikimedia.org/wiki/" private constructor() { super(); } + /** * Recursively walks a wikimedia commons category in order to search for (image) files * Returns (a promise of) a list of URLS @@ -124,38 +127,42 @@ export class WikimediaImageProvider extends ImageProvider { } - private async UrlForImage(image: string): Promise{ - if(!image.startsWith("File:")){ - image = "File:"+image + private async UrlForImage(image: string): Promise { + if (!image.startsWith("File:")) { + image = "File:" + image } return {url: this.PrepareUrl(image), key: undefined, provider: this} } - + public async ExtractUrls(key: string, value: string): Promise[]> { - const commonsPrefix = "https://commons.wikimedia.org/wiki/" - if(value.startsWith(commonsPrefix)){ - value = value.substring(commonsPrefix.length) - } else if(value.startsWith("https://upload.wikimedia.org")){ - const result : ProvidedImage = { + + if(key !== this.commons_key && !value.startsWith(WikimediaImageProvider.commonsPrefix)){ + return [] + } + + if (value.startsWith(WikimediaImageProvider.commonsPrefix)) { + value = value.substring(WikimediaImageProvider.commonsPrefix.length) + } else if (value.startsWith("https://upload.wikimedia.org")) { + const result: ProvidedImage = { key: undefined, url: value, provider: this } return [Promise.resolve(result)] } - if(value.startsWith("Category:")){ + if (value.startsWith("Category:")) { const urls = await WikimediaImageProvider.GetImagesInCategory(value) return urls.map(image => this.UrlForImage(image)) } - if(value.startsWith("File:")){ + if (value.startsWith("File:")) { return [this.UrlForImage(value)] } - if(value.startsWith("http")){ + if (value.startsWith("http")) { // PRobably an error return [] } // We do a last effort and assume this is a file - return [this.UrlForImage("File:"+value)] + return [this.UrlForImage("File:" + value)] } diff --git a/Models/ThemeConfig/FilterConfig.ts b/Models/ThemeConfig/FilterConfig.ts index 2dd9f69d6..7a032c6de 100644 --- a/Models/ThemeConfig/FilterConfig.ts +++ b/Models/ThemeConfig/FilterConfig.ts @@ -42,5 +42,9 @@ export default class FilterConfig { return {question: question, osmTags: osmTags}; }); + + if(this.options.length > 1 && this.options[0].osmTags["and"]?.length !== 0){ + throw "Error in "+context+"."+this.id+": the first option of a multi-filter should always be the 'reset' option and not have any filters" + } } } \ No newline at end of file diff --git a/UI/BigComponents/SimpleAddUI.ts b/UI/BigComponents/SimpleAddUI.ts index 5e8a7b46d..ad6a73ec5 100644 --- a/UI/BigComponents/SimpleAddUI.ts +++ b/UI/BigComponents/SimpleAddUI.ts @@ -19,7 +19,6 @@ import CreateNewNodeAction from "../../Logic/Osm/Actions/CreateNewNodeAction"; import {OsmObject, OsmWay} from "../../Logic/Osm/OsmObject"; import PresetConfig from "../../Models/ThemeConfig/PresetConfig"; import FilteredLayer from "../../Models/FilteredLayer"; -import {And} from "../../Logic/Tags/And"; import {BBox} from "../../Logic/BBox"; /* @@ -230,7 +229,25 @@ export default class SimpleAddUI extends Toggle { const disableFiltersOrConfirm = new Toggle( openLayerOrConfirm, disableFilter, - preset.layerToAddTo.appliedFilters.map(filters => filters === undefined || filters.length === 0) + preset.layerToAddTo.appliedFilters.map(filters => { + if(filters === undefined || filters.length === 0){ + return true; + } + for (const filter of filters) { + if(filter.selected === 0 && filter.filter.options.length === 1){ + return false; + } + if(filter.selected !== undefined){ + const tags = filter.filter.options[filter.selected].osmTags + if(tags !== undefined && tags["and"]?.length !== 0){ + // This actually doesn't filter anything at all + return false; + } + } + } + return true + + }) ) diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 4aba67e7d..5801e1d88 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -66,16 +66,10 @@ export default class SpecialVisualizations { name: "image key/prefix", defaultValue: "image", doc: "The keys given to the images, e.g. if image is given, the first picture URL will be added as image, the second as image:0, the third as image:1, etc... " - }, - { - name: "smart search", - defaultValue: "true", - doc: "Also include images given via 'Wikidata', 'wikimedia_commons' and 'mapillary" - }], + }], constr: (state: State, tags, args) => { const imagePrefix = args[0]; - const loadSpecial = args[1].toLowerCase() === "true"; - return new ImageCarousel(AllImageProviders.LoadImagesFor(tags, imagePrefix, loadSpecial), tags); + return new ImageCarousel(AllImageProviders.LoadImagesFor(tags, imagePrefix), tags); } }, { diff --git a/assets/layers/public_bookcase/public_bookcase.json b/assets/layers/public_bookcase/public_bookcase.json index cc21f23f8..64b6230c1 100644 --- a/assets/layers/public_bookcase/public_bookcase.json +++ b/assets/layers/public_bookcase/public_bookcase.json @@ -465,9 +465,9 @@ "id": "inside", "options": [ { - "question": "Binnen of buiten", - "osmTags": { - "and": [] + "question": { + "nl": "Binnen of buiten", + "en": "Indoor or outdoor" } }, { From 4f456e8a7f68ac1ffd8241636733409c82671fab Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Thu, 30 Sep 2021 04:13:23 +0200 Subject: [PATCH 61/65] Better tracking of cached data, only load data if needed --- Logic/Actors/GeoLocationHandler.ts | 3 + Logic/Actors/OverpassFeatureSource.ts | 110 +++------ .../Actors/SaveTileToLocalStorageActor.ts | 26 +- Logic/FeatureSource/FeaturePipeline.ts | 225 ++++++++++++------ .../FeatureSource/TileFreshnessCalculator.ts | 72 ++++++ .../TiledFeatureSource/OsmFeatureSource.ts | 12 +- .../TiledFeatureSource/TileHierarchyMerger.ts | 1 - .../TiledFromLocalStorageSource.ts | 38 +-- Logic/SimpleMetaTagger.ts | 9 +- Models/Constants.ts | 2 +- Models/TileRange.ts | 1 + test/TestAll.ts | 4 +- test/TileFreshnessCalculator.spec.ts | 31 +++ 13 files changed, 349 insertions(+), 185 deletions(-) create mode 100644 Logic/FeatureSource/TileFreshnessCalculator.ts create mode 100644 test/TileFreshnessCalculator.spec.ts diff --git a/Logic/Actors/GeoLocationHandler.ts b/Logic/Actors/GeoLocationHandler.ts index 3abf8e8e2..43ce441d7 100644 --- a/Logic/Actors/GeoLocationHandler.ts +++ b/Logic/Actors/GeoLocationHandler.ts @@ -207,6 +207,9 @@ export default class GeoLocationHandler extends VariableUiElement { }); const map = self._leafletMap.data; + if(map === undefined){ + return; + } const newMarker = L.marker(location.latlng, {icon: icon}); newMarker.addTo(map); diff --git a/Logic/Actors/OverpassFeatureSource.ts b/Logic/Actors/OverpassFeatureSource.ts index fa5de3eed..4f4f7a77f 100644 --- a/Logic/Actors/OverpassFeatureSource.ts +++ b/Logic/Actors/OverpassFeatureSource.ts @@ -1,5 +1,4 @@ import {UIEventSource} from "../UIEventSource"; -import Loc from "../../Models/Loc"; import {Or} from "../Tags/Or"; import {Overpass} from "../Osm/Overpass"; import FeatureSource from "../FeatureSource/FeatureSource"; @@ -9,6 +8,8 @@ import SimpleMetaTagger from "../SimpleMetaTagger"; import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import RelationsTracker from "../Osm/RelationsTracker"; import {BBox} from "../BBox"; +import Loc from "../../Models/Loc"; +import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; export default class OverpassFeatureSource implements FeatureSource { @@ -28,14 +29,7 @@ export default class OverpassFeatureSource implements FeatureSource { private readonly retries: UIEventSource = new UIEventSource(0); - /** - * The previous bounds for which the query has been run at the given zoom level - * - * Note that some layers only activate on a certain zoom level. - * If the map location changes, we check for each layer if it is loaded: - * we start checking the bounds at the first zoom level the layer might operate. If in bounds - no reload needed, otherwise we continue walking down - */ - private readonly _previousBounds: Map = new Map(); + private readonly state: { readonly locationControl: UIEventSource, readonly layoutToUse: LayoutConfig, @@ -44,11 +38,8 @@ export default class OverpassFeatureSource implements FeatureSource { readonly currentBounds: UIEventSource } private readonly _isActive: UIEventSource; - private _onUpdated?: (bbox: BBox, dataFreshness: Date) => void; + private readonly onBboxLoaded: (bbox: BBox, date: Date, layers: LayerConfig[]) => void; - /** - * The most important layer should go first, as that one gets first pick for the questions - */ constructor( state: { readonly locationControl: UIEventSource, @@ -60,68 +51,25 @@ export default class OverpassFeatureSource implements FeatureSource { }, options?: { isActive?: UIEventSource, - onUpdated?: (bbox: BBox, freshness: Date) => void, - relationTracker: RelationsTracker + relationTracker: RelationsTracker, + onBboxLoaded?: (bbox: BBox, date: Date, layers: LayerConfig[]) => void }) { this.state = state this._isActive = options.isActive; - this._onUpdated = options.onUpdated; + this.onBboxLoaded = options.onBboxLoaded this.relationsTracker = options.relationTracker - const location = state.locationControl const self = this; - - for (let i = 0; i < 25; i++) { - // This update removes all data on all layers -> erase the map on lower levels too - this._previousBounds.set(i, []); - } - - location.addCallback(() => { - self.update() - }); - state.currentBounds.addCallback(_ => { self.update() }) } - private GetFilter(interpreterUrl: string): Overpass { + private GetFilter(interpreterUrl: string, layersToDownload: LayerConfig[]): Overpass { let filters: TagsFilter[] = []; let extraScripts: string[] = []; - for (const layer of this.state.layoutToUse.layers) { - if (typeof (layer) === "string") { - throw "A layer was not expanded!" - } - if (this.state.locationControl.data.zoom < layer.minzoom) { - continue; - } - if (layer.doNotDownload) { - continue; - } - if (layer.source.geojsonSource !== undefined) { - // Not our responsibility to download this layer! - continue; - } - - - // Check if data for this layer has already been loaded - let previouslyLoaded = false; - for (let z = layer.minzoom; z < 25 && !previouslyLoaded; z++) { - const previousLoadedBounds = this._previousBounds.get(z); - if (previousLoadedBounds === undefined) { - continue; - } - for (const previousLoadedBound of previousLoadedBounds) { - previouslyLoaded = previouslyLoaded || this.state.currentBounds.data.isContainedIn(previousLoadedBound); - if (previouslyLoaded) { - break; - } - } - } - if (previouslyLoaded) { - continue; - } + for (const layer of layersToDownload) { if (layer.source.overpassScript !== undefined) { extraScripts.push(layer.source.overpassScript) } else { @@ -140,17 +88,17 @@ export default class OverpassFeatureSource implements FeatureSource { if (!this._isActive.data) { return; } - const self = this - this.updateAsync().then(bboxAndDate => { - if (bboxAndDate === undefined || self._onUpdated === undefined) { + const self = this; + this.updateAsync().then(bboxDate => { + if(bboxDate === undefined || self.onBboxLoaded === undefined){ return; } - const [bbox, date] = bboxAndDate - self._onUpdated(bbox, date); + const [bbox, date, layers] = bboxDate + self.onBboxLoaded(bbox, date, layers) }) } - private async updateAsync(): Promise<[BBox, Date]> { + private async updateAsync(): Promise<[BBox, Date, LayerConfig[]]> { if (this.runningQuery.data) { console.log("Still running a query, not updating"); return undefined; @@ -167,6 +115,26 @@ export default class OverpassFeatureSource implements FeatureSource { return undefined; } const self = this; + + + const layersToDownload = [] + for (const layer of this.state.layoutToUse.layers) { + + if (typeof (layer) === "string") { + throw "A layer was not expanded!" + } + if(this.state.locationControl.data.zoom < layer.minzoom){ + continue; + } + if (layer.doNotDownload) { + continue; + } + if (layer.source.geojsonSource !== undefined) { + // Not our responsibility to download this layer! + continue; + } + layersToDownload.push(layer) + } let data: any = undefined let date: Date = undefined @@ -175,7 +143,8 @@ export default class OverpassFeatureSource implements FeatureSource { do { try { - const overpass = this.GetFilter(overpassUrls[lastUsed]); + + const overpass = this.GetFilter(overpassUrls[lastUsed], layersToDownload); if (overpass === undefined) { return undefined; @@ -208,14 +177,11 @@ export default class OverpassFeatureSource implements FeatureSource { } } while (data === undefined); - const z = Math.floor(this.state.locationControl.data.zoom ?? 0); - self._previousBounds.get(z).push(bounds); self.retries.setData(0); - try { data.features.forEach(feature => SimpleMetaTagger.objectMetaInfo.applyMetaTagsOnFeature(feature, date)); self.features.setData(data.features.map(f => ({feature: f, freshness: date}))); - return [bounds, date]; + return [bounds, date, layersToDownload]; } catch (e) { console.error("Got the overpass response, but could not process it: ", e, e.stack) } finally { diff --git a/Logic/FeatureSource/Actors/SaveTileToLocalStorageActor.ts b/Logic/FeatureSource/Actors/SaveTileToLocalStorageActor.ts index 22e6a7ba8..2894d56b8 100644 --- a/Logic/FeatureSource/Actors/SaveTileToLocalStorageActor.ts +++ b/Logic/FeatureSource/Actors/SaveTileToLocalStorageActor.ts @@ -7,28 +7,30 @@ import {FeatureSourceForLayer} from "../FeatureSource"; export default class SaveTileToLocalStorageActor { public static readonly storageKey: string = "cached-features"; - public static readonly formatVersion : string = "1" - + public static readonly formatVersion: string = "1" + constructor(source: FeatureSourceForLayer, tileIndex: number) { source.features.addCallbackAndRunD(features => { const key = `${SaveTileToLocalStorageActor.storageKey}-${source.layer.layerDef.id}-${tileIndex}` - const now = new Date().getTime() - - if (features.length == 0) { - return; - } + const now = new Date() try { - localStorage.setItem(key, JSON.stringify(features)); - localStorage.setItem(key + "-time", JSON.stringify(now)) - localStorage.setItem(key+"-format", SaveTileToLocalStorageActor.formatVersion) + if (features.length > 0) { + localStorage.setItem(key, JSON.stringify(features)); + } + // We _still_ write the time to know that this tile is empty! + SaveTileToLocalStorageActor.MarkVisited(source.layer.layerDef.id, tileIndex, now) } catch (e) { console.warn("Could not save the features to local storage:", e) } }) - - } + public static MarkVisited(layerId: string, tileId: number, freshness: Date){ + const key = `${SaveTileToLocalStorageActor.storageKey}-${layerId}-${tileId}` + localStorage.setItem(key + "-time", JSON.stringify(freshness.getTime())) + localStorage.setItem(key + "-format", SaveTileToLocalStorageActor.formatVersion) + + } } \ No newline at end of file diff --git a/Logic/FeatureSource/FeaturePipeline.ts b/Logic/FeatureSource/FeaturePipeline.ts index 3db3a039d..5d5b3e166 100644 --- a/Logic/FeatureSource/FeaturePipeline.ts +++ b/Logic/FeatureSource/FeaturePipeline.ts @@ -25,6 +25,7 @@ import {BBox} from "../BBox"; import OsmFeatureSource from "./TiledFeatureSource/OsmFeatureSource"; import {OsmConnection} from "../Osm/OsmConnection"; import {Tiles} from "../../Models/TileRange"; +import TileFreshnessCalculator from "./TileFreshnessCalculator"; export default class FeaturePipeline { @@ -38,9 +39,27 @@ export default class FeaturePipeline { public readonly newDataLoadedSignal: UIEventSource = new UIEventSource(undefined) private readonly overpassUpdater: OverpassFeatureSource + private state: { + readonly filteredLayers: UIEventSource, + readonly locationControl: UIEventSource, + readonly selectedElement: UIEventSource, + readonly changes: Changes, + readonly layoutToUse: LayoutConfig, + readonly leafletMap: any, + readonly overpassUrl: UIEventSource; + readonly overpassTimeout: UIEventSource; + readonly overpassMaxZoom: UIEventSource; + readonly osmConnection: OsmConnection + readonly currentBounds: UIEventSource + }; private readonly relationTracker: RelationsTracker private readonly perLayerHierarchy: Map; + private readonly freshnesses = new Map(); + + private readonly oldestAllowedDate: Date = new Date(new Date().getTime() - 60 * 60 * 24 * 30 * 1000); + private readonly osmSourceZoomLevel = 14 + constructor( handleFeatureSource: (source: FeatureSourceForLayer & Tiled) => void, state: { @@ -48,7 +67,7 @@ export default class FeaturePipeline { readonly locationControl: UIEventSource, readonly selectedElement: UIEventSource, readonly changes: Changes, - readonly layoutToUse: LayoutConfig, + readonly layoutToUse: LayoutConfig, readonly leafletMap: any, readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; @@ -56,59 +75,15 @@ export default class FeaturePipeline { readonly osmConnection: OsmConnection readonly currentBounds: UIEventSource }) { + this.state = state; const self = this - - /** - * Maps tileid onto last download moment - */ - const tileFreshnesses = new UIEventSource>(new Map()) - const osmSourceZoomLevel = 14 + // milliseconds const useOsmApi = state.locationControl.map(l => l.zoom > (state.overpassMaxZoom.data ?? 12)) this.relationTracker = new RelationsTracker() + const neededTilesFromOsm = this.getNeededTilesFromOsm() - console.log("Tilefreshnesses are", tileFreshnesses.data) - const oldestAllowedDate = new Date(new Date().getTime() - (60 * 60 * 24 * 30 * 1000)); - const neededTilesFromOsm = state.currentBounds.map(bbox => { - if (bbox === undefined) { - return - } - const range = bbox.containingTileRange(osmSourceZoomLevel) - const tileIndexes = [] - if (range.total > 100) { - // Too much tiles! - return [] - } - Tiles.MapRange(range, (x, y) => { - const i = Tiles.tile_index(osmSourceZoomLevel, x, y); - if (tileFreshnesses.data.get(i) > oldestAllowedDate) { - console.debug("Skipping tile", osmSourceZoomLevel, x, y, "as a decently fresh one is available") - // The cached tiles contain decently fresh data - return; - } - tileIndexes.push(i) - }) - return tileIndexes - }, [tileFreshnesses]) - - const updater = new OverpassFeatureSource(state, - { - relationTracker: this.relationTracker, - isActive: useOsmApi.map(b => !b), - onUpdated: (bbox, freshness) => { - // This callback contains metadata of the overpass call - const range = bbox.containingTileRange(osmSourceZoomLevel) - Tiles.MapRange(range, (x, y) => { - tileFreshnesses.data.set(Tiles.tile_index(osmSourceZoomLevel, x, y), freshness) - }) - tileFreshnesses.ping(); - - } - }); - - this.overpassUpdater = updater; - this.timeout = updater.timeout this.sufficientlyZoomed = state.locationControl.map(location => { if (location?.zoom === undefined) { @@ -119,12 +94,6 @@ export default class FeaturePipeline { } ); - this.timeout = updater.timeout - - - // Register everything in the state' 'AllElements' - new RegisteringAllFromFeatureSourceActor(updater) - const perLayerHierarchy = new Map() this.perLayerHierarchy = perLayerHierarchy @@ -140,40 +109,32 @@ export default class FeaturePipeline { handleFeatureSource(srcFiltered) self.somethingLoaded.setData(true) + self.freshnesses.get(src.layer.layerDef.id).addTileLoad(src.tileIndex, new Date()) }; - function addToHierarchy(src: FeatureSource & Tiled, layerId: string) { - perLayerHierarchy.get(layerId).registerTile(src) - } - for (const filteredLayer of state.filteredLayers.data) { - const hierarchy = new TileHierarchyMerger(filteredLayer, (tile, _) => patchedHandleFeatureSource(tile)) const id = filteredLayer.layerDef.id - perLayerHierarchy.set(id, hierarchy) const source = filteredLayer.layerDef.source + const hierarchy = new TileHierarchyMerger(filteredLayer, (tile, _) => patchedHandleFeatureSource(tile)) + perLayerHierarchy.set(id, hierarchy) + + this.freshnesses.set(id, new TileFreshnessCalculator()) + if (source.geojsonSource === undefined) { // This is an OSM layer // We load the cached values and register them // Getting data from upstream happens a bit lower - const localStorage = new TiledFromLocalStorageSource(filteredLayer, + new TiledFromLocalStorageSource(filteredLayer, (src) => { new RegisteringAllFromFeatureSourceActor(src) hierarchy.registerTile(src); src.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(src)) }, state) - localStorage.tileFreshness.forEach((value, key) => { - if (tileFreshnesses.data.has(key)) { - const previous = tileFreshnesses.data.get(key) - if (value < previous) { - tileFreshnesses.data.set(key, value) - } - } else { - tileFreshnesses.data.set(key, value) - } - tileFreshnesses.ping() + TiledFromLocalStorageSource.GetFreshnesses(id).forEach((value, key) => { + self.freshnesses.get(id).addTileLoad(key, value) }) continue @@ -189,7 +150,7 @@ export default class FeaturePipeline { dontEnforceMinZoom: true, registerTile: (tile) => { new RegisteringAllFromFeatureSourceActor(tile) - addToHierarchy(tile, id) + perLayerHierarchy.get(id).registerTile(tile) tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) } }) @@ -198,7 +159,7 @@ export default class FeaturePipeline { filteredLayer, tile => { new RegisteringAllFromFeatureSourceActor(tile) - addToHierarchy(tile, id) + perLayerHierarchy.get(id).registerTile(tile) tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) }, state @@ -213,14 +174,22 @@ export default class FeaturePipeline { handleTile: tile => { new RegisteringAllFromFeatureSourceActor(tile) new SaveTileToLocalStorageActor(tile, tile.tileIndex) - addToHierarchy(tile, tile.layer.layerDef.id), - tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) + perLayerHierarchy.get(tile.layer.layerDef.id).registerTile(tile) + tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) }, - state: state + state: state, + markTileVisited: (tileId) => + state.filteredLayers.data.forEach(flayer => { + SaveTileToLocalStorageActor.MarkVisited(flayer.layerDef.id, tileId, new Date()) + }) }) + const updater = this.initOverpassUpdater(state, useOsmApi) + this.overpassUpdater = updater; + this.timeout = updater.timeout + // Actually load data from the overpass source new PerLayerFeatureSourceSplitter(state.filteredLayers, (source) => TiledFeatureSource.createHierarchy(source, { @@ -232,7 +201,7 @@ export default class FeaturePipeline { registerTile: (tile) => { // We save the tile data for the given layer to local storage new SaveTileToLocalStorageActor(tile, tile.tileIndex) - addToHierarchy(new RememberingSource(tile), source.layer.layerDef.id); + perLayerHierarchy.get(source.layer.layerDef.id).registerTile(new RememberingSource(tile)) tile.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(tile)) } @@ -247,7 +216,7 @@ export default class FeaturePipeline { new PerLayerFeatureSourceSplitter(state.filteredLayers, (perLayer) => { // We don't bother to split them over tiles as it'll contain little features by default, so we simply add them like this - addToHierarchy(perLayer, perLayer.layer.layerDef.id) + perLayerHierarchy.get(perLayer.layer.layerDef.id).registerTile(perLayer) // AT last, we always apply the metatags whenever possible perLayer.features.addCallbackAndRunD(_ => self.applyMetaTags(perLayer)) perLayer.features.addCallbackAndRunD(_ => self.newDataLoadedSignal.setData(perLayer)) @@ -270,6 +239,106 @@ export default class FeaturePipeline { } + private freshnessForVisibleLayers(z: number, x: number, y: number): Date { + let oldestDate = undefined; + for (const flayer of this.state.filteredLayers.data) { + if (!flayer.isDisplayed.data) { + continue + } + if (this.state.locationControl.data.zoom < flayer.layerDef.minzoom) { + continue; + } + const freshness = this.freshnesses.get(flayer.layerDef.id).freshnessFor(z, x, y) + if (freshness === undefined) { + // SOmething is undefined --> we return undefined as we have to download + return undefined + } + if (oldestDate === undefined || oldestDate > freshness) { + oldestDate = freshness + } + } + return oldestDate + } + + private getNeededTilesFromOsm(): UIEventSource { + const self = this + return this.state.currentBounds.map(bbox => { + if (bbox === undefined) { + return + } + const osmSourceZoomLevel = self.osmSourceZoomLevel + const range = bbox.containingTileRange(osmSourceZoomLevel) + const tileIndexes = [] + if (range.total > 100) { + // Too much tiles! + return [] + } + Tiles.MapRange(range, (x, y) => { + const i = Tiles.tile_index(osmSourceZoomLevel, x, y); + const oldestDate = self.freshnessForVisibleLayers(osmSourceZoomLevel, x, y) + if (oldestDate !== undefined && oldestDate > this.oldestAllowedDate) { + console.debug("Skipping tile", osmSourceZoomLevel, x, y, "as a decently fresh one is available") + // The cached tiles contain decently fresh data + return; + } + tileIndexes.push(i) + }) + return tileIndexes + }) + } + + private initOverpassUpdater(state: { + layoutToUse: LayoutConfig, + currentBounds: UIEventSource, + locationControl: UIEventSource, + readonly overpassUrl: UIEventSource; + readonly overpassTimeout: UIEventSource; + readonly overpassMaxZoom: UIEventSource, + }, useOsmApi: UIEventSource): OverpassFeatureSource { + const minzoom = Math.min(...state.layoutToUse.layers.map(layer => layer.minzoom)) + const allUpToDateAndZoomSufficient = state.currentBounds.map(bbox => { + if (bbox === undefined) { + return true + } + let zoom = state.locationControl.data.zoom + if (zoom < minzoom) { + return true; + } + if (zoom > 16) { + zoom = 16 + } + if (zoom < 8) { + zoom = zoom + 2 + } + const range = bbox.containingTileRange(zoom) + const self = this; + const allFreshnesses = Tiles.MapRange(range, (x, y) => self.freshnessForVisibleLayers(zoom, x, y)) + return !allFreshnesses.some(freshness => freshness === undefined || freshness < this.oldestAllowedDate) + + }, [state.locationControl]) + + allUpToDateAndZoomSufficient.addCallbackAndRunD(allUpToDate => console.log("All up to data is: ", allUpToDate)) + const self = this; + const updater = new OverpassFeatureSource(state, + { + relationTracker: this.relationTracker, + isActive: useOsmApi.map(b => !b && !allUpToDateAndZoomSufficient.data, [allUpToDateAndZoomSufficient]), + onBboxLoaded: ((bbox, date, downloadedLayers) => { + Tiles.MapRange(bbox.containingTileRange(self.osmSourceZoomLevel), (x, y) => { + downloadedLayers.forEach(layer => { + SaveTileToLocalStorageActor.MarkVisited(layer.id, Tiles.tile_index(this.osmSourceZoomLevel, x, y), date) + }) + }) + + }) + }); + + + // Register everything in the state' 'AllElements' + new RegisteringAllFromFeatureSourceActor(updater) + return updater; + } + private applyMetaTags(src: FeatureSourceForLayer) { const self = this console.debug("Applying metatagging onto ", src.name) diff --git a/Logic/FeatureSource/TileFreshnessCalculator.ts b/Logic/FeatureSource/TileFreshnessCalculator.ts new file mode 100644 index 000000000..6b397f540 --- /dev/null +++ b/Logic/FeatureSource/TileFreshnessCalculator.ts @@ -0,0 +1,72 @@ +import {Tiles} from "../../Models/TileRange"; + +export default class TileFreshnessCalculator { + + /** + * All the freshnesses per tile index + * @private + */ + private readonly freshnesses = new Map(); + + /** + * Marks that some data got loaded for this layer + * @param tileId + * @param freshness + */ + public addTileLoad(tileId: number, freshness: Date){ + const existingFreshness = this.freshnessFor(...Tiles.tile_from_index(tileId)) + if(existingFreshness >= freshness){ + return; + } + this.freshnesses.set(tileId, freshness) + + + // Do we have freshness for the neighbouring tiles? If so, we can mark the tile above as loaded too! + let [z, x, y] = Tiles.tile_from_index(tileId) + if(z === 0){ + return; + } + x = x - (x % 2) // Make the tiles always even + y = y - (y % 2) + + const ul = this.freshnessFor(z, x, y)?.getTime() + if(ul === undefined){ + return + } + const ur = this.freshnessFor(z, x + 1, y)?.getTime() + if(ur === undefined){ + return + } + const ll = this.freshnessFor(z, x, y + 1)?.getTime() + if(ll === undefined){ + return + } + const lr = this.freshnessFor(z, x + 1, y + 1)?.getTime() + if(lr === undefined){ + return + } + + const leastFresh = Math.min(ul, ur, ll, lr) + const date = new Date() + date.setTime(leastFresh) + this.addTileLoad( + Tiles.tile_index(z - 1, Math.floor(x / 2), Math.floor(y / 2)), + date + ) + + } + + public freshnessFor(z: number, x: number, y:number): Date { + if(z < 0){ + return undefined + } + const tileId = Tiles.tile_index(z, x, y) + if(this.freshnesses.has(tileId)) { + return this.freshnesses.get(tileId) + } + // recurse up + return this.freshnessFor(z - 1, Math.floor(x /2), Math.floor(y / 2)) + + } + +} \ No newline at end of file diff --git a/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts b/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts index a7485facf..5641d5b98 100644 --- a/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts @@ -22,7 +22,8 @@ export default class OsmFeatureSource { neededTiles: UIEventSource, state: { readonly osmConnection: OsmConnection; - }; + }, + markTileVisited?: (tileId: number) => void }; private readonly downloadedTiles = new Set() @@ -33,7 +34,8 @@ export default class OsmFeatureSource { state: { readonly filteredLayers: UIEventSource; readonly osmConnection: OsmConnection; - }; + }, + markTileVisited?: (tileId: number) => void }) { this.options = options; this._backend = options.state.osmConnection._oauth_config.url; @@ -84,13 +86,17 @@ export default class OsmFeatureSource { flatProperties: true }); console.log("Tile geojson:", z, x, y, "is", geojson) + const index = Tiles.tile_index(z, x, y); new PerLayerFeatureSourceSplitter(this.filteredLayers, this.handleTile, new StaticFeatureSource(geojson.features, false), { - tileIndex: Tiles.tile_index(z, x, y) + tileIndex:index } ); + if(this.options.markTileVisited){ + this.options.markTileVisited(index) + } } catch (e) { console.error("Weird error: ", e) } diff --git a/Logic/FeatureSource/TiledFeatureSource/TileHierarchyMerger.ts b/Logic/FeatureSource/TiledFeatureSource/TileHierarchyMerger.ts index 844754854..6fd3dae65 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TileHierarchyMerger.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TileHierarchyMerger.ts @@ -2,7 +2,6 @@ import TileHierarchy from "./TileHierarchy"; import {UIEventSource} from "../../UIEventSource"; import FeatureSource, {FeatureSourceForLayer, IndexedFeatureSource, Tiled} from "../FeatureSource"; import FilteredLayer from "../../../Models/FilteredLayer"; -import {Utils} from "../../../Utils"; import FeatureSourceMerger from "../Sources/FeatureSourceMerger"; import {Tiles} from "../../../Models/TileRange"; import {BBox} from "../../BBox"; diff --git a/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts b/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts index 016537968..6f815f48d 100644 --- a/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/TiledFromLocalStorageSource.ts @@ -3,15 +3,29 @@ import {FeatureSourceForLayer, Tiled} from "../FeatureSource"; import {UIEventSource} from "../../UIEventSource"; import Loc from "../../../Models/Loc"; import TileHierarchy from "./TileHierarchy"; -import {Utils} from "../../../Utils"; import SaveTileToLocalStorageActor from "../Actors/SaveTileToLocalStorageActor"; import {Tiles} from "../../../Models/TileRange"; import {BBox} from "../../BBox"; export default class TiledFromLocalStorageSource implements TileHierarchy { public loadedTiles: Map = new Map(); -public tileFreshness : Map = new Map() - + + public static GetFreshnesses(layerId: string): Map { + const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layerId + "-" + const freshnesses = new Map() + for (const key of Object.keys(localStorage)) { + if(!(key.startsWith(prefix) && key.endsWith("-time"))){ + continue + } + const index = Number(key.substring(prefix.length, key.length - "-time".length)) + const time = Number(localStorage.getItem(key)) + const freshness = new Date() + freshness.setTime(time) + freshnesses.set(index, freshness) + } + return freshnesses + } + constructor(layer: FilteredLayer, handleFeatureSource: (src: FeatureSourceForLayer & Tiled, index: number) => void, state: { @@ -33,21 +47,17 @@ public tileFreshness : Map = new Map() console.debug("Layer", layer.layerDef.id, "has following tiles in available in localstorage", indexes.map(i => Tiles.tile_from_index(i).join("/")).join(", ")) for (const index of indexes) { - - const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layer.layerDef.id + "-" +index; - const version = localStorage.getItem(prefix+"-format") - if(version === undefined || version !== SaveTileToLocalStorageActor.formatVersion){ + + const prefix = SaveTileToLocalStorageActor.storageKey + "-" + layer.layerDef.id + "-" + index; + const version = localStorage.getItem(prefix + "-format") + if (version === undefined || version !== SaveTileToLocalStorageActor.formatVersion) { // Invalid version! Remove this tile from local storage localStorage.removeItem(prefix) + localStorage.removeItem(prefix+"-time") + localStorage.removeItem(prefix+"-format") undefinedTiles.add(index) console.log("Dropped old format tile", prefix) - continue } - - const data = Number(localStorage.getItem(prefix+"-time")) - const freshness = new Date() - freshness.setTime(data) - this.tileFreshness.set(index, freshness) } const zLevels = indexes.map(i => i % 100) @@ -91,8 +101,6 @@ public tileFreshness : Map = new Map() } , [layer.isDisplayed, state.leafletMap]).stabilized(50); - neededTiles.addCallbackAndRun(t => console.debug("Tiles to load from localstorage:", t)) - neededTiles.addCallbackAndRunD(neededIndexes => { for (const neededIndex of neededIndexes) { // We load the features from localStorage diff --git a/Logic/SimpleMetaTagger.ts b/Logic/SimpleMetaTagger.ts index 4b047fc7d..360bb54e5 100644 --- a/Logic/SimpleMetaTagger.ts +++ b/Logic/SimpleMetaTagger.ts @@ -97,7 +97,7 @@ export default class SimpleMetaTagger { continue; } for (const unit of units) { - if(unit === undefined){ + if (unit === undefined) { continue } if (unit.appliesToKeys === undefined) { @@ -108,7 +108,12 @@ export default class SimpleMetaTagger { continue; } const value = feature.properties[key] - const [, denomination] = unit.findDenomination(value) + const denom = unit.findDenomination(value) + if (denom === undefined) { + // no valid value found + break; + } + const [, denomination] = denom; let canonical = denomination?.canonicalValue(value) ?? undefined; if (canonical === value) { break; diff --git a/Models/Constants.ts b/Models/Constants.ts index 4e588a057..855f9dd2b 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.10.0-rc1"; + public static vNumber = "0.10.0-rc2"; public static ImgurApiKey = '7070e7167f0a25a' public static readonly mapillary_client_token_v3 = 'TXhLaWthQ1d4RUg0czVxaTVoRjFJZzowNDczNjUzNmIyNTQyYzI2' public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" diff --git a/Models/TileRange.ts b/Models/TileRange.ts index b61f192a0..da30e498c 100644 --- a/Models/TileRange.ts +++ b/Models/TileRange.ts @@ -107,4 +107,5 @@ export class Tiles { } } + } \ No newline at end of file diff --git a/test/TestAll.ts b/test/TestAll.ts index 0efa98dd4..6123681fb 100644 --- a/test/TestAll.ts +++ b/test/TestAll.ts @@ -9,6 +9,7 @@ import UnitsSpec from "./Units.spec"; import RelationSplitHandlerSpec from "./RelationSplitHandler.spec"; import SplitActionSpec from "./SplitAction.spec"; import {Utils} from "../Utils"; +import TileFreshnessCalculatorSpec from "./TileFreshnessCalculator.spec"; ScriptUtils.fixUtils() @@ -21,7 +22,8 @@ const allTests = [ new UtilsSpec(), new UnitsSpec(), new RelationSplitHandlerSpec(), - new SplitActionSpec() + new SplitActionSpec(), + new TileFreshnessCalculatorSpec() ] Utils.externalDownloadFunction = async (url) => { diff --git a/test/TileFreshnessCalculator.spec.ts b/test/TileFreshnessCalculator.spec.ts new file mode 100644 index 000000000..6305b9a5d --- /dev/null +++ b/test/TileFreshnessCalculator.spec.ts @@ -0,0 +1,31 @@ +import T from "./TestHelper"; +import TileFreshnessCalculator from "../Logic/FeatureSource/TileFreshnessCalculator"; +import {Tiles} from "../Models/TileRange"; +import {equal} from "assert"; + +export default class TileFreshnessCalculatorSpec extends T { + + constructor() { + super("TileFreshnessCalculatorSpec", [ + [ + "TileFresnessTests", + () => { + const calc = new TileFreshnessCalculator(); + // 19/266407/175535 + const date = new Date() + date.setTime(42) + calc.addTileLoad(Tiles.tile_index(19, 266406, 175534), date) + equal(42, calc.freshnessFor(19, 266406, 175534).getTime()) + equal(42, calc.freshnessFor(20, 266406 * 2, 175534 * 2 + 1).getTime()) + equal(undefined, calc.freshnessFor(19, 266406, 175535)) + equal(undefined, calc.freshnessFor(18, 266406 / 2, 175534 / 2)) + calc.addTileLoad(Tiles.tile_index(19, 266406, 175534+1), date) + calc.addTileLoad(Tiles.tile_index(19, 266406+1, 175534), date) + calc.addTileLoad(Tiles.tile_index(19, 266406+1, 175534+1), date) + equal(42, calc.freshnessFor(18, 266406 / 2, 175534 / 2).getTime()) + } + ] + ]) + } + +} \ No newline at end of file From 9ba27778717268e29f30d1c63e9c1092cf000522 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Thu, 30 Sep 2021 04:25:13 +0200 Subject: [PATCH 62/65] Add a few more questions to the toilet theme --- .../layers/cluster_style/cluster_style.json | 68 +++++++++---------- assets/layers/parking/parking.json | 2 +- assets/layers/toilet/toilet.json | 46 +++++++++++++ assets/layers/watermill/watermill.json | 2 +- assets/tagRenderings/questions.json | 21 ++++-- assets/themes/natuurpunt/natuurpunt.json | 2 +- langs/layers/en.json | 31 +++++++++ langs/layers/nl.json | 31 +++++++++ langs/shared-questions/pt.json | 38 +++++------ 9 files changed, 178 insertions(+), 63 deletions(-) diff --git a/assets/layers/cluster_style/cluster_style.json b/assets/layers/cluster_style/cluster_style.json index ea6760612..d6b68d113 100644 --- a/assets/layers/cluster_style/cluster_style.json +++ b/assets/layers/cluster_style/cluster_style.json @@ -1,36 +1,36 @@ { - "id": "cluster_style", - "description": "The style for the clustering in all themes.", - "source": { - "osmTags": "tileId~*" - }, - "color": { - "render": "#3c3", - "mappings": [ - { - "if": "count>200", - "then": "#f33" - }, - { - "if": "count>100", - "then": "#c93" - }, - { - "if": "count>50", - "then": "#cc3" - } - ] - }, - "width": { - "render": "1" - }, - "label": { - "render": "
{count}
", - "mappings": [ - { - "if": "count>99", - "then": "
>99
" - } - ] - } + "id": "cluster_style", + "description": "The style for the clustering in all themes.", + "source": { + "osmTags": "tileId~*" + }, + "color": { + "render": "#3c3", + "mappings": [ + { + "if": "count>200", + "then": "#f33" + }, + { + "if": "count>100", + "then": "#c93" + }, + { + "if": "count>50", + "then": "#cc3" + } + ] + }, + "width": { + "render": "1" + }, + "label": { + "render": "
{count}
", + "mappings": [ + { + "if": "count>99", + "then": "
>99
" + } + ] + } } \ No newline at end of file diff --git a/assets/layers/parking/parking.json b/assets/layers/parking/parking.json index 888ee00a9..42f09f53e 100644 --- a/assets/layers/parking/parking.json +++ b/assets/layers/parking/parking.json @@ -82,4 +82,4 @@ } } ] -} +} \ No newline at end of file diff --git a/assets/layers/toilet/toilet.json b/assets/layers/toilet/toilet.json index 68bc21fe6..8b10b35ee 100644 --- a/assets/layers/toilet/toilet.json +++ b/assets/layers/toilet/toilet.json @@ -407,6 +407,52 @@ } ], "id": "toilet-changing_table:location" + }, + { + "id": "toilet-handwashing", + "question": { + "en": "Do these toilets have a sink to wash your hands?", + "nl": "Hebben deze toiletten een lavabo om de handen te wassen?" + }, + "mappings": [ + { + "if": "toilets:handwashing=yes", + "then": { + "en": "This toilets have a sink to wash your hands", + "nl": "Deze toiletten hebben een lavabo waar men de handen kan wassen" + } + }, + { + "if": "toilets:handwashing=no", + "then": { + "en": "This toilets don't have a sink to wash your hands", + "nl": "Deze toiletten hebben geen lavabo waar men de handen kan wassen" + } + } + ] + }, + { + "id": "toilet-has-paper", + "question": { + "en": "Does one have to bring their own toilet paper to this toilet?", + "nl": "Moet je je eigen toiletpappier meenemen naar deze toilet?" + }, + "mappings": [ + { + "if": "toilets:paper_supplied=yes", + "then": { + "en": "Toilet paper is equipped with toilet paper", + "nl": "Deze toilet is voorzien van toiletpapier" + } + }, + { + "if": "toilets:paper_supplied=no", + "then": { + "en": "You have to bring your own toilet paper to this toilet", + "nl": "Je moet je eigen toiletpapier meebrengen naar deze toilet" + } + } + ] } ], "filter": [ diff --git a/assets/layers/watermill/watermill.json b/assets/layers/watermill/watermill.json index 54b5f056c..6f8dcb65f 100644 --- a/assets/layers/watermill/watermill.json +++ b/assets/layers/watermill/watermill.json @@ -170,4 +170,4 @@ "color": { "render": "#FFC0CB" } -} +} \ No newline at end of file diff --git a/assets/tagRenderings/questions.json b/assets/tagRenderings/questions.json index 30aab5b27..fb2e939bd 100644 --- a/assets/tagRenderings/questions.json +++ b/assets/tagRenderings/questions.json @@ -56,7 +56,8 @@ "de": "Was ist die Mail-Adresse von {name}?", "pt_BR": "Qual o endereço de e-mail de {name}?", "pl": "Jaki jest adres e-mail do {name}?", - "sv": "Vad är e-postadressen till {name}?" + "sv": "Vad är e-postadressen till {name}?", + "pt": "Qual é o endereço de e-mail de {name}?" }, "freeform": { "key": "email", @@ -184,7 +185,8 @@ "it": "C'è ancora qualche informazione importante che non è stato possibile fornire nelle domande precedenti? Aggiungila qui.
Non ripetere informazioni già fornite", "de": "Gibt es noch etwas, das die vorhergehenden Fragen nicht abgedeckt haben? Hier wäre Platz dafür.
Bitte keine bereits erhobenen Informationen.", "pl": "Czy jest jeszcze coś istotnego, czego nie mogłeś podać w poprzednich pytaniach? Dodaj to tutaj.
Nie powtarzaj już podanych faktów", - "pt_BR": "Ainda há algo de relevante que não pôde dar nas perguntas anteriores? Adicione aqui.
Não repita fatos já declarados" + "pt_BR": "Ainda há algo de relevante que não pôde dar nas perguntas anteriores? Adicione aqui.
Não repita fatos já declarados", + "pt": "Ainda há algo de relevante que não tenha podido dar nas perguntas anteriores? Adicione-o aqui.
Não repita factos já declarados" }, "render": "{description}", "freeform": { @@ -266,7 +268,8 @@ "fr": "À quel étage se situe l’élément ?", "pl": "Na jakim poziomie znajduje się ta funkcja?", "pt_BR": "Em que nível esse recurso está localizado?", - "ru": "На каком этаже находится этот объект?" + "ru": "На каком этаже находится этот объект?", + "pt": "Em que nível se encontra este elemento?" }, "render": { "en": "Located on the {level}th floor", @@ -294,7 +297,8 @@ "zh_Hant": "位於地下", "fr": "En sous-sol", "pl": "Znajduje się pod ziemią", - "sv": "Ligger under jorden" + "sv": "Ligger under jorden", + "pt": "Está no subsolo" }, "hideInAnswer": true }, @@ -309,7 +313,8 @@ "zh_Hant": "位於 1 樓", "fr": "Rez-de-chaussée", "pl": "Znajduje się na parterze", - "sv": "Ligger på bottenvåningen" + "sv": "Ligger på bottenvåningen", + "pt": "Está ao nível do rés-do-chão" } }, { @@ -324,7 +329,8 @@ "zh_Hant": "位於 1 樓", "fr": "Rez-de-chaussée", "pl": "Znajduje się na parterze", - "sv": "Ligger på bottenvåningen" + "sv": "Ligger på bottenvåningen", + "pt": "Está ao nível do rés-do-chão" } }, { @@ -338,7 +344,8 @@ "zh_Hant": "位於 2 樓", "fr": "Premier étage", "pl": "Znajduje się na pierwszym piętrze", - "sv": "Ligger på första våningen" + "sv": "Ligger på första våningen", + "pt": "Está no primeiro andar" } } ] diff --git a/assets/themes/natuurpunt/natuurpunt.json b/assets/themes/natuurpunt/natuurpunt.json index c5345a55f..7ebcab3b5 100644 --- a/assets/themes/natuurpunt/natuurpunt.json +++ b/assets/themes/natuurpunt/natuurpunt.json @@ -262,4 +262,4 @@ } } ] -} +} \ No newline at end of file diff --git a/langs/layers/en.json b/langs/layers/en.json index a3a428462..c107bdc35 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -2883,6 +2883,15 @@ }, "public_bookcase": { "description": "A streetside cabinet with books, accessible to anyone", + "filter": { + "2": { + "options": { + "0": { + "question": "Indoor or outdoor" + } + } + } + }, "name": "Bookcases", "presets": { "0": { @@ -3313,6 +3322,28 @@ "question": "How much does one have to pay for these toilets?", "render": "The fee is {charge}" }, + "toilet-handwashing": { + "mappings": { + "0": { + "then": "This toilets have a sink to wash your hands" + }, + "1": { + "then": "This toilets don't have a sink to wash your hands" + } + }, + "question": "Do these toilets have a sink to wash your hands?" + }, + "toilet-has-paper": { + "mappings": { + "0": { + "then": "Toilet paper is equipped with toilet paper" + }, + "1": { + "then": "You have to bring your own toilet paper to this toilet" + } + }, + "question": "Does one have to bring their own toilet paper to this toilet?" + }, "toilets-changing-table": { "mappings": { "0": { diff --git a/langs/layers/nl.json b/langs/layers/nl.json index d253c3161..b7a918c9c 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -3099,6 +3099,15 @@ }, "public_bookcase": { "description": "Een straatkastje met boeken voor iedereen", + "filter": { + "2": { + "options": { + "0": { + "question": "Binnen of buiten" + } + } + } + }, "name": "Boekenruilkastjes", "presets": { "0": { @@ -3547,6 +3556,28 @@ "question": "Hoeveel moet men betalen om deze toiletten te gebruiken?", "render": "De toiletten gebruiken kost {charge}" }, + "toilet-handwashing": { + "mappings": { + "0": { + "then": "Deze toiletten hebben een lavabo waar men de handen kan wassen" + }, + "1": { + "then": "Deze toiletten hebben geen lavabo waar men de handen kan wassen" + } + }, + "question": "Hebben deze toiletten een lavabo om de handen te wassen?" + }, + "toilet-has-paper": { + "mappings": { + "0": { + "then": "Deze toilet is voorzien van toiletpapier" + }, + "1": { + "then": "Je moet je eigen toiletpapier meebrengen naar deze toilet" + } + }, + "question": "Moet je je eigen toiletpappier meenemen naar deze toilet?" + }, "toilets-changing-table": { "mappings": { "0": { diff --git a/langs/shared-questions/pt.json b/langs/shared-questions/pt.json index 60330bb63..4ba738f83 100644 --- a/langs/shared-questions/pt.json +++ b/langs/shared-questions/pt.json @@ -1,27 +1,27 @@ { "undefined": { - "level": { - "question": "Em que nível se encontra este elemento?", - "mappings": { - "3": { - "then": "Está no primeiro andar" - }, - "2": { - "then": "Está ao nível do rés-do-chão" - }, - "1": { - "then": "Está ao nível do rés-do-chão" - }, - "0": { - "then": "Está no subsolo" - } - } + "description": { + "question": "Ainda há algo de relevante que não tenha podido dar nas perguntas anteriores? Adicione-o aqui.
Não repita factos já declarados" }, "email": { "question": "Qual é o endereço de e-mail de {name}?" }, - "description": { - "question": "Ainda há algo de relevante que não tenha podido dar nas perguntas anteriores? Adicione-o aqui.
Não repita factos já declarados" + "level": { + "mappings": { + "0": { + "then": "Está no subsolo" + }, + "1": { + "then": "Está ao nível do rés-do-chão" + }, + "2": { + "then": "Está ao nível do rés-do-chão" + }, + "3": { + "then": "Está no primeiro andar" + } + }, + "question": "Em que nível se encontra este elemento?" } } -} +} \ No newline at end of file From 8cdc0dba61be5695bd2f383f612db3af907dd150 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Thu, 30 Sep 2021 18:50:08 +0200 Subject: [PATCH 63/65] Add USB as socket to charging stations, some styling tweaks --- UI/BigComponents/FilterView.ts | 6 +- assets/layers/charging_station/README.md | 19 + .../charging_station/charging_station.json | 669 +++++++++++++----- assets/layers/charging_station/csvToJson.ts | 25 +- .../layers/charging_station/license_info.json | 10 + assets/layers/charging_station/types.csv | 29 +- assets/layers/charging_station/usb_port.svg | 74 ++ 7 files changed, 616 insertions(+), 216 deletions(-) create mode 100644 assets/layers/charging_station/README.md create mode 100644 assets/layers/charging_station/usb_port.svg diff --git a/UI/BigComponents/FilterView.ts b/UI/BigComponents/FilterView.ts index 249b3dacb..ffcdbc3c9 100644 --- a/UI/BigComponents/FilterView.ts +++ b/UI/BigComponents/FilterView.ts @@ -155,8 +155,8 @@ export default class FilterView extends VariableUiElement { const iconUnselected = Svg.checkbox_empty_svg().SetClass("block mr-2"); const toggle = new Toggle( - new Combine([icon, option.question.Clone()]).SetClass("flex"), - new Combine([iconUnselected, option.question.Clone()]).SetClass("flex") + new Combine([icon, option.question.Clone().SetClass("block")]).SetClass("flex"), + new Combine([iconUnselected, option.question.Clone().SetClass("block")]).SetClass("flex") ) .ToggleOnClick() .SetClass("block m-1") @@ -178,7 +178,7 @@ export default class FilterView extends VariableUiElement { const radio = new RadioButton( options.map( (option, i) => - new FixedInputElement(option.question.Clone(), i) + new FixedInputElement(option.question.Clone().SetClass("block"), i) ), { dontStyle: true diff --git a/assets/layers/charging_station/README.md b/assets/layers/charging_station/README.md new file mode 100644 index 000000000..445b81c1e --- /dev/null +++ b/assets/layers/charging_station/README.md @@ -0,0 +1,19 @@ +The charging station theme +========================== + +As you might have noticed, the charging station theme is complicated and large. + +There are a ton of repititive questions. Luckily, we can generate those. + +If you want to add a missing socket type, then: + +- Add all the properties in 'types.csv' +- Add an icon. (Note: icons are way better as pictures as they are perceived more abstractly) +- Update license_info.json with the copyright info of the new icon. Note that we strive to have Creative-commons icons only (though there are exceptions) + +AT this point, most of the work should be done; feel free to send a PR. If you would like to test it locally first (which is recommended) and have a working dev environment, then run: + +- Run 'ts-node csvToJson.ts' which will generate a new charging_station.json based on the protojson +- Run`npm run query:licenses` to get an interactive program to add the license of your artwork, followed by `npm run generate:licenses` +- Run `npm run generate:layeroverview` to generate the layer files +- Run `npm run start` to run the instance \ No newline at end of file diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json index f3caa2321..5a8385357 100644 --- a/assets/layers/charging_station/charging_station.json +++ b/assets/layers/charging_station/charging_station.json @@ -157,8 +157,8 @@ "if": "socket:schuko=1", "ifnot": "socket:schuko=", "then": { - "en": " Schuko wall plug without ground pin (CEE7/4 type F)", - "nl": " Schuko stekker zonder aardingspin (CEE7/4 type F)" + "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
", + "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F) Schuko wall plug without ground pin (CEE7/4 type F)", - "nl": " Schuko stekker zonder aardingspin (CEE7/4 type F)" + "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
", + "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F) European wall plug with ground pin (CEE7/4 type E)", - "nl": " Europese stekker met aardingspin (CEE7/4 type E)" + "en": "
European wall plug with ground pin (CEE7/4 type E)
", + "nl": "
Europese stekker met aardingspin (CEE7/4 type E) European wall plug with ground pin (CEE7/4 type E)", - "nl": " Europese stekker met aardingspin (CEE7/4 type E)" + "en": "
European wall plug with ground pin (CEE7/4 type E)
", + "nl": "
Europese stekker met aardingspin (CEE7/4 type E) Chademo", - "nl": " " + "en": "
Chademo
", + "nl": "
Chademo Chademo", - "nl": " " + "en": "
Chademo
", + "nl": "
Chademo Type 1 with cable (J1772)", - "nl": " Type 1 met kabel (J1772)" + "en": "
Type 1 with cable (J1772)
", + "nl": "
Type 1 met kabel (J1772) Type 1 with cable (J1772)", - "nl": " Type 1 met kabel (J1772)" + "en": "
Type 1 with cable (J1772)
", + "nl": "
Type 1 met kabel (J1772) Type 1 without cable (J1772)", - "nl": " Type 1 zonder kabel (J1772)" + "en": "
Type 1 without cable (J1772)
", + "nl": "
Type 1 zonder kabel (J1772) Type 1 without cable (J1772)", - "nl": " Type 1 zonder kabel (J1772)" + "en": "
Type 1 without cable (J1772)
", + "nl": "
Type 1 zonder kabel (J1772) Type 1 CCS (aka Type 1 Combo)", - "nl": " " + "en": "
Type 1 CCS (aka Type 1 Combo)
", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo) Type 1 CCS (aka Type 1 Combo)", - "nl": " " + "en": "
Type 1 CCS (aka Type 1 Combo)
", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo) Tesla Supercharger", - "nl": " " + "en": "
Tesla Supercharger
", + "nl": "
Tesla Supercharger Tesla Supercharger", - "nl": " " + "en": "
Tesla Supercharger
", + "nl": "
Tesla Supercharger Type 2 (mennekes)", - "nl": " " + "en": "
Type 2 (mennekes)
", + "nl": "
Type 2 (mennekes) Type 2 (mennekes)", - "nl": " " + "en": "
Type 2 (mennekes)
", + "nl": "
Type 2 (mennekes) Type 2 CCS (mennekes)", - "nl": " " + "en": "
Type 2 CCS (mennekes)
", + "nl": "
Type 2 CCS (mennekes) Type 2 CCS (mennekes)", - "nl": " " + "en": "
Type 2 CCS (mennekes)
", + "nl": "
Type 2 CCS (mennekes) Type 2 with cable (mennekes)", - "nl": " Type 2 met kabel (J1772)" + "en": "
Type 2 with cable (mennekes)
", + "nl": "
Type 2 met kabel (J1772) Type 2 with cable (mennekes)", - "nl": " Type 2 met kabel (J1772)" + "en": "
Type 2 with cable (mennekes)
", + "nl": "
Type 2 met kabel (J1772) Tesla Supercharger CCS (a branded type2_css)", - "nl": " " + "en": "
Tesla Supercharger CCS (a branded type2_css)
", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo) Tesla Supercharger CCS (a branded type2_css)", - "nl": " " + "en": "
Tesla Supercharger CCS (a branded type2_css)
", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo) Tesla Supercharger (destination)", - "nl": " " + "en": "
Tesla Supercharger (destination)
", + "nl": "
Tesla Supercharger (destination) Tesla Supercharger (destination)", - "nl": " " + "en": "
Tesla Supercharger (destination)
", + "nl": "
Tesla Supercharger (destination) Tesla supercharger (destination (A Type 2 with cable branded as tesla)", - "nl": " " + "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) Tesla supercharger (destination (A Type 2 with cable branded as tesla)", - "nl": " " + "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) USB to charge phones and small electronics
", + "nl": "
USB om GSMs en kleine electronica op te laden USB to charge phones and small electronics
", + "nl": "
USB om GSMs en kleine electronica op te ladenChademo are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + "nl": "Hoeveel stekkers van type Chademo heeft dit oplaadpunt?" }, "render": { "en": "There are Chademo plugs of type Chademo available here", - "nl": "Hier zijn stekkers van het type " + "nl": "Hier zijn Chademo stekkers van het type Chademo" }, "freeform": { "key": "socket:chademo", @@ -704,11 +865,11 @@ "id": "voltage-2", "question": { "en": "What voltage do the plugs with Chademo offer?", - "nl": "Welke spanning levert de stekker van type " + "nl": "Welke spanning levert de stekker van type Chademo " }, "render": { "en": "Chademo outputs {socket:chademo:voltage} volt", - "nl": " heeft een spanning van {socket:chademo:voltage} volt" + "nl": "Chademo heeft een spanning van {socket:chademo:voltage} volt" }, "freeform": { "key": "socket:chademo:voltage", @@ -719,7 +880,7 @@ "if": "socket:socket:chademo:voltage=500 V", "then": { "en": "Chademo outputs 500 volt", - "nl": " heeft een spanning van 500 volt" + "nl": "Chademo heeft een spanning van 500 volt" } } ], @@ -734,11 +895,11 @@ "id": "current-2", "question": { "en": "What current do the plugs with Chademo offer?", - "nl": "Welke stroom levert de stekker van type ?" + "nl": "Welke stroom levert de stekker van type Chademo ?" }, "render": { "en": "Chademo outputs at most {socket:chademo:current}A", - "nl": " levert een stroom van maximaal {socket:chademo:current}A" + "nl": "Chademo levert een stroom van maximaal {socket:chademo:current}A" }, "freeform": { "key": "socket:chademo:current", @@ -749,7 +910,7 @@ "if": "socket:socket:chademo:current=120 A", "then": { "en": "Chademo outputs at most 120 A", - "nl": " levert een stroom van maximaal 120 A" + "nl": "Chademo levert een stroom van maximaal 120 A" } } ], @@ -764,11 +925,11 @@ "id": "power-output-2", "question": { "en": "What power output does a single plug of type Chademo offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" + "nl": "Welk vermogen levert een enkele stekker van type Chademo ?" }, "render": { "en": "Chademo outputs at most {socket:chademo:output}", - "nl": " levert een vermogen van maximaal {socket:chademo:output}" + "nl": "Chademo levert een vermogen van maximaal {socket:chademo:output}" }, "freeform": { "key": "socket:chademo:output", @@ -779,7 +940,7 @@ "if": "socket:socket:chademo:output=50 kw", "then": { "en": "Chademo outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" + "nl": "Chademo levert een vermogen van maximaal 50 kw" } } ], @@ -1058,11 +1219,11 @@ "id": "plugs-5", "question": { "en": "How much plugs of type Type 1 CCS (aka Type 1 Combo) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + "nl": "Hoeveel stekkers van type Type 1 CCS (ook gekend als Type 1 Combo) heeft dit oplaadpunt?" }, "render": { "en": "There are Type 1 CCS (aka Type 1 Combo) plugs of type Type 1 CCS (aka Type 1 Combo) available here", - "nl": "Hier zijn stekkers van het type " + "nl": "Hier zijn Type 1 CCS (ook gekend als Type 1 Combo) stekkers van het type Type 1 CCS (ook gekend als Type 1 Combo)" }, "freeform": { "key": "socket:type1_combo", @@ -1079,11 +1240,11 @@ "id": "voltage-5", "question": { "en": "What voltage do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "nl": "Welke spanning levert de stekker van type " + "nl": "Welke spanning levert de stekker van type Type 1 CCS (ook gekend als Type 1 Combo) " }, "render": { "en": "Type 1 CCS (aka Type 1 Combo) outputs {socket:type1_combo:voltage} volt", - "nl": " heeft een spanning van {socket:type1_combo:voltage} volt" + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) heeft een spanning van {socket:type1_combo:voltage} volt" }, "freeform": { "key": "socket:type1_combo:voltage", @@ -1094,14 +1255,14 @@ "if": "socket:socket:type1_combo:voltage=400 V", "then": { "en": "Type 1 CCS (aka Type 1 Combo) outputs 400 volt", - "nl": " heeft een spanning van 400 volt" + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) heeft een spanning van 400 volt" } }, { "if": "socket:socket:type1_combo:voltage=1000 V", "then": { "en": "Type 1 CCS (aka Type 1 Combo) outputs 1000 volt", - "nl": " heeft een spanning van 1000 volt" + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) heeft een spanning van 1000 volt" } } ], @@ -1116,11 +1277,11 @@ "id": "current-5", "question": { "en": "What current do the plugs with Type 1 CCS (aka Type 1 Combo) offer?", - "nl": "Welke stroom levert de stekker van type ?" + "nl": "Welke stroom levert de stekker van type Type 1 CCS (ook gekend als Type 1 Combo) ?" }, "render": { "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:current}A", - "nl": " levert een stroom van maximaal {socket:type1_combo:current}A" + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een stroom van maximaal {socket:type1_combo:current}A" }, "freeform": { "key": "socket:type1_combo:current", @@ -1131,14 +1292,14 @@ "if": "socket:socket:type1_combo:current=50 A", "then": { "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 A", - "nl": " levert een stroom van maximaal 50 A" + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een stroom van maximaal 50 A" } }, { "if": "socket:socket:type1_combo:current=125 A", "then": { "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een stroom van maximaal 125 A" } } ], @@ -1153,11 +1314,11 @@ "id": "power-output-5", "question": { "en": "What power output does a single plug of type Type 1 CCS (aka Type 1 Combo) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" + "nl": "Welk vermogen levert een enkele stekker van type Type 1 CCS (ook gekend als Type 1 Combo) ?" }, "render": { "en": "Type 1 CCS (aka Type 1 Combo) outputs at most {socket:type1_combo:output}", - "nl": " levert een vermogen van maximaal {socket:type1_combo:output}" + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een vermogen van maximaal {socket:type1_combo:output}" }, "freeform": { "key": "socket:type1_combo:output", @@ -1168,28 +1329,28 @@ "if": "socket:socket:type1_combo:output=50 kw", "then": { "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een vermogen van maximaal 50 kw" } }, { "if": "socket:socket:type1_combo:output=62.5 kw", "then": { "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw", - "nl": " levert een vermogen van maximaal 62.5 kw" + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een vermogen van maximaal 62.5 kw" } }, { "if": "socket:socket:type1_combo:output=150 kw", "then": { "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw", - "nl": " levert een vermogen van maximaal 150 kw" + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een vermogen van maximaal 150 kw" } }, { "if": "socket:socket:type1_combo:output=350 kw", "then": { "en": "Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw", - "nl": " levert een vermogen van maximaal 350 kw" + "nl": "Type 1 CCS (ook gekend als Type 1 Combo) levert een vermogen van maximaal 350 kw" } } ], @@ -1204,11 +1365,11 @@ "id": "plugs-6", "question": { "en": "How much plugs of type Tesla Supercharger are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + "nl": "Hoeveel stekkers van type Tesla Supercharger heeft dit oplaadpunt?" }, "render": { "en": "There are Tesla Supercharger plugs of type Tesla Supercharger available here", - "nl": "Hier zijn stekkers van het type " + "nl": "Hier zijn Tesla Supercharger stekkers van het type Tesla Supercharger" }, "freeform": { "key": "socket:tesla_supercharger", @@ -1225,11 +1386,11 @@ "id": "voltage-6", "question": { "en": "What voltage do the plugs with Tesla Supercharger offer?", - "nl": "Welke spanning levert de stekker van type " + "nl": "Welke spanning levert de stekker van type Tesla Supercharger " }, "render": { "en": "Tesla Supercharger outputs {socket:tesla_supercharger:voltage} volt", - "nl": " heeft een spanning van {socket:tesla_supercharger:voltage} volt" + "nl": "Tesla Supercharger heeft een spanning van {socket:tesla_supercharger:voltage} volt" }, "freeform": { "key": "socket:tesla_supercharger:voltage", @@ -1240,7 +1401,7 @@ "if": "socket:socket:tesla_supercharger:voltage=480 V", "then": { "en": "Tesla Supercharger outputs 480 volt", - "nl": " heeft een spanning van 480 volt" + "nl": "Tesla Supercharger heeft een spanning van 480 volt" } } ], @@ -1255,11 +1416,11 @@ "id": "current-6", "question": { "en": "What current do the plugs with Tesla Supercharger offer?", - "nl": "Welke stroom levert de stekker van type ?" + "nl": "Welke stroom levert de stekker van type Tesla Supercharger ?" }, "render": { "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:current}A", - "nl": " levert een stroom van maximaal {socket:tesla_supercharger:current}A" + "nl": "Tesla Supercharger levert een stroom van maximaal {socket:tesla_supercharger:current}A" }, "freeform": { "key": "socket:tesla_supercharger:current", @@ -1270,14 +1431,14 @@ "if": "socket:socket:tesla_supercharger:current=125 A", "then": { "en": "Tesla Supercharger outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" + "nl": "Tesla Supercharger levert een stroom van maximaal 125 A" } }, { "if": "socket:socket:tesla_supercharger:current=350 A", "then": { "en": "Tesla Supercharger outputs at most 350 A", - "nl": " levert een stroom van maximaal 350 A" + "nl": "Tesla Supercharger levert een stroom van maximaal 350 A" } } ], @@ -1292,11 +1453,11 @@ "id": "power-output-6", "question": { "en": "What power output does a single plug of type Tesla Supercharger offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" + "nl": "Welk vermogen levert een enkele stekker van type Tesla Supercharger ?" }, "render": { "en": "Tesla Supercharger outputs at most {socket:tesla_supercharger:output}", - "nl": " levert een vermogen van maximaal {socket:tesla_supercharger:output}" + "nl": "Tesla Supercharger levert een vermogen van maximaal {socket:tesla_supercharger:output}" }, "freeform": { "key": "socket:tesla_supercharger:output", @@ -1307,21 +1468,21 @@ "if": "socket:socket:tesla_supercharger:output=120 kw", "then": { "en": "Tesla Supercharger outputs at most 120 kw", - "nl": " levert een vermogen van maximaal 120 kw" + "nl": "Tesla Supercharger levert een vermogen van maximaal 120 kw" } }, { "if": "socket:socket:tesla_supercharger:output=150 kw", "then": { "en": "Tesla Supercharger outputs at most 150 kw", - "nl": " levert een vermogen van maximaal 150 kw" + "nl": "Tesla Supercharger levert een vermogen van maximaal 150 kw" } }, { "if": "socket:socket:tesla_supercharger:output=250 kw", "then": { "en": "Tesla Supercharger outputs at most 250 kw", - "nl": " levert een vermogen van maximaal 250 kw" + "nl": "Tesla Supercharger levert een vermogen van maximaal 250 kw" } } ], @@ -1336,11 +1497,11 @@ "id": "plugs-7", "question": { "en": "How much plugs of type Type 2 (mennekes) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + "nl": "Hoeveel stekkers van type Type 2 (mennekes) heeft dit oplaadpunt?" }, "render": { "en": "There are Type 2 (mennekes) plugs of type Type 2 (mennekes) available here", - "nl": "Hier zijn stekkers van het type " + "nl": "Hier zijn Type 2 (mennekes) stekkers van het type Type 2 (mennekes)" }, "freeform": { "key": "socket:type2", @@ -1357,11 +1518,11 @@ "id": "voltage-7", "question": { "en": "What voltage do the plugs with Type 2 (mennekes) offer?", - "nl": "Welke spanning levert de stekker van type " + "nl": "Welke spanning levert de stekker van type Type 2 (mennekes) " }, "render": { "en": "Type 2 (mennekes) outputs {socket:type2:voltage} volt", - "nl": " heeft een spanning van {socket:type2:voltage} volt" + "nl": "Type 2 (mennekes) heeft een spanning van {socket:type2:voltage} volt" }, "freeform": { "key": "socket:type2:voltage", @@ -1372,14 +1533,14 @@ "if": "socket:socket:type2:voltage=230 V", "then": { "en": "Type 2 (mennekes) outputs 230 volt", - "nl": " heeft een spanning van 230 volt" + "nl": "Type 2 (mennekes) heeft een spanning van 230 volt" } }, { "if": "socket:socket:type2:voltage=400 V", "then": { "en": "Type 2 (mennekes) outputs 400 volt", - "nl": " heeft een spanning van 400 volt" + "nl": "Type 2 (mennekes) heeft een spanning van 400 volt" } } ], @@ -1394,11 +1555,11 @@ "id": "current-7", "question": { "en": "What current do the plugs with Type 2 (mennekes) offer?", - "nl": "Welke stroom levert de stekker van type ?" + "nl": "Welke stroom levert de stekker van type Type 2 (mennekes) ?" }, "render": { "en": "Type 2 (mennekes) outputs at most {socket:type2:current}A", - "nl": " levert een stroom van maximaal {socket:type2:current}A" + "nl": "Type 2 (mennekes) levert een stroom van maximaal {socket:type2:current}A" }, "freeform": { "key": "socket:type2:current", @@ -1409,14 +1570,14 @@ "if": "socket:socket:type2:current=16 A", "then": { "en": "Type 2 (mennekes) outputs at most 16 A", - "nl": " levert een stroom van maximaal 16 A" + "nl": "Type 2 (mennekes) levert een stroom van maximaal 16 A" } }, { "if": "socket:socket:type2:current=32 A", "then": { "en": "Type 2 (mennekes) outputs at most 32 A", - "nl": " levert een stroom van maximaal 32 A" + "nl": "Type 2 (mennekes) levert een stroom van maximaal 32 A" } } ], @@ -1431,11 +1592,11 @@ "id": "power-output-7", "question": { "en": "What power output does a single plug of type Type 2 (mennekes) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" + "nl": "Welk vermogen levert een enkele stekker van type Type 2 (mennekes) ?" }, "render": { "en": "Type 2 (mennekes) outputs at most {socket:type2:output}", - "nl": " levert een vermogen van maximaal {socket:type2:output}" + "nl": "Type 2 (mennekes) levert een vermogen van maximaal {socket:type2:output}" }, "freeform": { "key": "socket:type2:output", @@ -1446,14 +1607,14 @@ "if": "socket:socket:type2:output=11 kw", "then": { "en": "Type 2 (mennekes) outputs at most 11 kw", - "nl": " levert een vermogen van maximaal 11 kw" + "nl": "Type 2 (mennekes) levert een vermogen van maximaal 11 kw" } }, { "if": "socket:socket:type2:output=22 kw", "then": { "en": "Type 2 (mennekes) outputs at most 22 kw", - "nl": " levert een vermogen van maximaal 22 kw" + "nl": "Type 2 (mennekes) levert een vermogen van maximaal 22 kw" } } ], @@ -1468,11 +1629,11 @@ "id": "plugs-8", "question": { "en": "How much plugs of type Type 2 CCS (mennekes) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + "nl": "Hoeveel stekkers van type Type 2 CCS (mennekes) heeft dit oplaadpunt?" }, "render": { "en": "There are Type 2 CCS (mennekes) plugs of type Type 2 CCS (mennekes) available here", - "nl": "Hier zijn stekkers van het type " + "nl": "Hier zijn Type 2 CCS (mennekes) stekkers van het type Type 2 CCS (mennekes)" }, "freeform": { "key": "socket:type2_combo", @@ -1489,11 +1650,11 @@ "id": "voltage-8", "question": { "en": "What voltage do the plugs with Type 2 CCS (mennekes) offer?", - "nl": "Welke spanning levert de stekker van type " + "nl": "Welke spanning levert de stekker van type Type 2 CCS (mennekes) " }, "render": { "en": "Type 2 CCS (mennekes) outputs {socket:type2_combo:voltage} volt", - "nl": " heeft een spanning van {socket:type2_combo:voltage} volt" + "nl": "Type 2 CCS (mennekes) heeft een spanning van {socket:type2_combo:voltage} volt" }, "freeform": { "key": "socket:type2_combo:voltage", @@ -1504,14 +1665,14 @@ "if": "socket:socket:type2_combo:voltage=500 V", "then": { "en": "Type 2 CCS (mennekes) outputs 500 volt", - "nl": " heeft een spanning van 500 volt" + "nl": "Type 2 CCS (mennekes) heeft een spanning van 500 volt" } }, { "if": "socket:socket:type2_combo:voltage=920 V", "then": { "en": "Type 2 CCS (mennekes) outputs 920 volt", - "nl": " heeft een spanning van 920 volt" + "nl": "Type 2 CCS (mennekes) heeft een spanning van 920 volt" } } ], @@ -1526,11 +1687,11 @@ "id": "current-8", "question": { "en": "What current do the plugs with Type 2 CCS (mennekes) offer?", - "nl": "Welke stroom levert de stekker van type ?" + "nl": "Welke stroom levert de stekker van type Type 2 CCS (mennekes) ?" }, "render": { "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:current}A", - "nl": " levert een stroom van maximaal {socket:type2_combo:current}A" + "nl": "Type 2 CCS (mennekes) levert een stroom van maximaal {socket:type2_combo:current}A" }, "freeform": { "key": "socket:type2_combo:current", @@ -1541,14 +1702,14 @@ "if": "socket:socket:type2_combo:current=125 A", "then": { "en": "Type 2 CCS (mennekes) outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" + "nl": "Type 2 CCS (mennekes) levert een stroom van maximaal 125 A" } }, { "if": "socket:socket:type2_combo:current=350 A", "then": { "en": "Type 2 CCS (mennekes) outputs at most 350 A", - "nl": " levert een stroom van maximaal 350 A" + "nl": "Type 2 CCS (mennekes) levert een stroom van maximaal 350 A" } } ], @@ -1563,11 +1724,11 @@ "id": "power-output-8", "question": { "en": "What power output does a single plug of type Type 2 CCS (mennekes) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" + "nl": "Welk vermogen levert een enkele stekker van type Type 2 CCS (mennekes) ?" }, "render": { "en": "Type 2 CCS (mennekes) outputs at most {socket:type2_combo:output}", - "nl": " levert een vermogen van maximaal {socket:type2_combo:output}" + "nl": "Type 2 CCS (mennekes) levert een vermogen van maximaal {socket:type2_combo:output}" }, "freeform": { "key": "socket:type2_combo:output", @@ -1578,7 +1739,7 @@ "if": "socket:socket:type2_combo:output=50 kw", "then": { "en": "Type 2 CCS (mennekes) outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" + "nl": "Type 2 CCS (mennekes) levert een vermogen van maximaal 50 kw" } } ], @@ -1725,11 +1886,11 @@ "id": "plugs-10", "question": { "en": "How much plugs of type Tesla Supercharger CCS (a branded type2_css) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + "nl": "Hoeveel stekkers van type Tesla Supercharger CCS (een type2 CCS met Tesla-logo) heeft dit oplaadpunt?" }, "render": { "en": "There are Tesla Supercharger CCS (a branded type2_css) plugs of type Tesla Supercharger CCS (a branded type2_css) available here", - "nl": "Hier zijn stekkers van het type " + "nl": "Hier zijn Tesla Supercharger CCS (een type2 CCS met Tesla-logo) stekkers van het type Tesla Supercharger CCS (een type2 CCS met Tesla-logo)" }, "freeform": { "key": "socket:tesla_supercharger_ccs", @@ -1746,11 +1907,11 @@ "id": "voltage-10", "question": { "en": "What voltage do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", - "nl": "Welke spanning levert de stekker van type " + "nl": "Welke spanning levert de stekker van type Tesla Supercharger CCS (een type2 CCS met Tesla-logo) " }, "render": { "en": "Tesla Supercharger CCS (a branded type2_css) outputs {socket:tesla_supercharger_ccs:voltage} volt", - "nl": " heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" }, "freeform": { "key": "socket:tesla_supercharger_ccs:voltage", @@ -1761,14 +1922,14 @@ "if": "socket:socket:tesla_supercharger_ccs:voltage=500 V", "then": { "en": "Tesla Supercharger CCS (a branded type2_css) outputs 500 volt", - "nl": " heeft een spanning van 500 volt" + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) heeft een spanning van 500 volt" } }, { "if": "socket:socket:tesla_supercharger_ccs:voltage=920 V", "then": { "en": "Tesla Supercharger CCS (a branded type2_css) outputs 920 volt", - "nl": " heeft een spanning van 920 volt" + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) heeft een spanning van 920 volt" } } ], @@ -1783,11 +1944,11 @@ "id": "current-10", "question": { "en": "What current do the plugs with Tesla Supercharger CCS (a branded type2_css) offer?", - "nl": "Welke stroom levert de stekker van type ?" + "nl": "Welke stroom levert de stekker van type Tesla Supercharger CCS (een type2 CCS met Tesla-logo) ?" }, "render": { "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:current}A", - "nl": " levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" }, "freeform": { "key": "socket:tesla_supercharger_ccs:current", @@ -1798,14 +1959,14 @@ "if": "socket:socket:tesla_supercharger_ccs:current=125 A", "then": { "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) levert een stroom van maximaal 125 A" } }, { "if": "socket:socket:tesla_supercharger_ccs:current=350 A", "then": { "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A", - "nl": " levert een stroom van maximaal 350 A" + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) levert een stroom van maximaal 350 A" } } ], @@ -1820,11 +1981,11 @@ "id": "power-output-10", "question": { "en": "What power output does a single plug of type Tesla Supercharger CCS (a branded type2_css) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" + "nl": "Welk vermogen levert een enkele stekker van type Tesla Supercharger CCS (een type2 CCS met Tesla-logo) ?" }, "render": { "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most {socket:tesla_supercharger_ccs:output}", - "nl": " levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" }, "freeform": { "key": "socket:tesla_supercharger_ccs:output", @@ -1835,7 +1996,7 @@ "if": "socket:socket:tesla_supercharger_ccs:output=50 kw", "then": { "en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 50 kw", - "nl": " levert een vermogen van maximaal 50 kw" + "nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) levert een vermogen van maximaal 50 kw" } } ], @@ -1850,11 +2011,11 @@ "id": "plugs-11", "question": { "en": "How much plugs of type Tesla Supercharger (destination) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + "nl": "Hoeveel stekkers van type Tesla Supercharger (destination) heeft dit oplaadpunt?" }, "render": { "en": "There are Tesla Supercharger (destination) plugs of type Tesla Supercharger (destination) available here", - "nl": "Hier zijn stekkers van het type " + "nl": "Hier zijn Tesla Supercharger (destination) stekkers van het type Tesla Supercharger (destination)" }, "freeform": { "key": "socket:tesla_destination", @@ -1871,11 +2032,11 @@ "id": "voltage-11", "question": { "en": "What voltage do the plugs with Tesla Supercharger (destination) offer?", - "nl": "Welke spanning levert de stekker van type " + "nl": "Welke spanning levert de stekker van type Tesla Supercharger (destination) " }, "render": { "en": "Tesla Supercharger (destination) outputs {socket:tesla_destination:voltage} volt", - "nl": " heeft een spanning van {socket:tesla_destination:voltage} volt" + "nl": "Tesla Supercharger (destination) heeft een spanning van {socket:tesla_destination:voltage} volt" }, "freeform": { "key": "socket:tesla_destination:voltage", @@ -1886,7 +2047,7 @@ "if": "socket:socket:tesla_destination:voltage=480 V", "then": { "en": "Tesla Supercharger (destination) outputs 480 volt", - "nl": " heeft een spanning van 480 volt" + "nl": "Tesla Supercharger (destination) heeft een spanning van 480 volt" } } ], @@ -1901,11 +2062,11 @@ "id": "current-11", "question": { "en": "What current do the plugs with Tesla Supercharger (destination) offer?", - "nl": "Welke stroom levert de stekker van type ?" + "nl": "Welke stroom levert de stekker van type Tesla Supercharger (destination) ?" }, "render": { "en": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:current}A", - "nl": " levert een stroom van maximaal {socket:tesla_destination:current}A" + "nl": "Tesla Supercharger (destination) levert een stroom van maximaal {socket:tesla_destination:current}A" }, "freeform": { "key": "socket:tesla_destination:current", @@ -1916,14 +2077,14 @@ "if": "socket:socket:tesla_destination:current=125 A", "then": { "en": "Tesla Supercharger (destination) outputs at most 125 A", - "nl": " levert een stroom van maximaal 125 A" + "nl": "Tesla Supercharger (destination) levert een stroom van maximaal 125 A" } }, { "if": "socket:socket:tesla_destination:current=350 A", "then": { "en": "Tesla Supercharger (destination) outputs at most 350 A", - "nl": " levert een stroom van maximaal 350 A" + "nl": "Tesla Supercharger (destination) levert een stroom van maximaal 350 A" } } ], @@ -1938,11 +2099,11 @@ "id": "power-output-11", "question": { "en": "What power output does a single plug of type Tesla Supercharger (destination) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" + "nl": "Welk vermogen levert een enkele stekker van type Tesla Supercharger (destination) ?" }, "render": { "en": "Tesla Supercharger (destination) outputs at most {socket:tesla_destination:output}", - "nl": " levert een vermogen van maximaal {socket:tesla_destination:output}" + "nl": "Tesla Supercharger (destination) levert een vermogen van maximaal {socket:tesla_destination:output}" }, "freeform": { "key": "socket:tesla_destination:output", @@ -1953,21 +2114,21 @@ "if": "socket:socket:tesla_destination:output=120 kw", "then": { "en": "Tesla Supercharger (destination) outputs at most 120 kw", - "nl": " levert een vermogen van maximaal 120 kw" + "nl": "Tesla Supercharger (destination) levert een vermogen van maximaal 120 kw" } }, { "if": "socket:socket:tesla_destination:output=150 kw", "then": { "en": "Tesla Supercharger (destination) outputs at most 150 kw", - "nl": " levert een vermogen van maximaal 150 kw" + "nl": "Tesla Supercharger (destination) levert een vermogen van maximaal 150 kw" } }, { "if": "socket:socket:tesla_destination:output=250 kw", "then": { "en": "Tesla Supercharger (destination) outputs at most 250 kw", - "nl": " levert een vermogen van maximaal 250 kw" + "nl": "Tesla Supercharger (destination) levert een vermogen van maximaal 250 kw" } } ], @@ -1982,11 +2143,11 @@ "id": "plugs-12", "question": { "en": "How much plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) are available here?", - "nl": "Hoeveel stekkers van type heeft dit oplaadpunt?" + "nl": "Hoeveel stekkers van type Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) heeft dit oplaadpunt?" }, "render": { "en": "There are Tesla supercharger (destination (A Type 2 with cable branded as tesla) plugs of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) available here", - "nl": "Hier zijn stekkers van het type " + "nl": "Hier zijn Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) stekkers van het type Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)" }, "freeform": { "key": "socket:tesla_destination", @@ -2003,11 +2164,11 @@ "id": "voltage-12", "question": { "en": "What voltage do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "nl": "Welke spanning levert de stekker van type " + "nl": "Welke spanning levert de stekker van type Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) " }, "render": { "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs {socket:tesla_destination:voltage} volt", - "nl": " heeft een spanning van {socket:tesla_destination:voltage} volt" + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) heeft een spanning van {socket:tesla_destination:voltage} volt" }, "freeform": { "key": "socket:tesla_destination:voltage", @@ -2018,14 +2179,14 @@ "if": "socket:socket:tesla_destination:voltage=230 V", "then": { "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 230 volt", - "nl": " heeft een spanning van 230 volt" + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) heeft een spanning van 230 volt" } }, { "if": "socket:socket:tesla_destination:voltage=400 V", "then": { "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs 400 volt", - "nl": " heeft een spanning van 400 volt" + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) heeft een spanning van 400 volt" } } ], @@ -2040,11 +2201,11 @@ "id": "current-12", "question": { "en": "What current do the plugs with Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "nl": "Welke stroom levert de stekker van type ?" + "nl": "Welke stroom levert de stekker van type Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) ?" }, "render": { "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:current}A", - "nl": " levert een stroom van maximaal {socket:tesla_destination:current}A" + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) levert een stroom van maximaal {socket:tesla_destination:current}A" }, "freeform": { "key": "socket:tesla_destination:current", @@ -2055,14 +2216,14 @@ "if": "socket:socket:tesla_destination:current=16 A", "then": { "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 16 A", - "nl": " levert een stroom van maximaal 16 A" + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) levert een stroom van maximaal 16 A" } }, { "if": "socket:socket:tesla_destination:current=32 A", "then": { "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 32 A", - "nl": " levert een stroom van maximaal 32 A" + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) levert een stroom van maximaal 32 A" } } ], @@ -2077,11 +2238,11 @@ "id": "power-output-12", "question": { "en": "What power output does a single plug of type Tesla supercharger (destination (A Type 2 with cable branded as tesla) offer?", - "nl": "Welk vermogen levert een enkele stekker van type ?" + "nl": "Welk vermogen levert een enkele stekker van type Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) ?" }, "render": { "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most {socket:tesla_destination:output}", - "nl": " levert een vermogen van maximaal {socket:tesla_destination:output}" + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) levert een vermogen van maximaal {socket:tesla_destination:output}" }, "freeform": { "key": "socket:tesla_destination:output", @@ -2092,14 +2253,14 @@ "if": "socket:socket:tesla_destination:output=11 kw", "then": { "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 11 kw", - "nl": " levert een vermogen van maximaal 11 kw" + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) levert een vermogen van maximaal 11 kw" } }, { "if": "socket:socket:tesla_destination:output=22 kw", "then": { "en": "Tesla supercharger (destination (A Type 2 with cable branded as tesla) outputs at most 22 kw", - "nl": " levert een vermogen van maximaal 22 kw" + "nl": "Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) levert een vermogen van maximaal 22 kw" } } ], @@ -2110,6 +2271,131 @@ ] } }, + { + "id": "plugs-13", + "question": { + "en": "How much plugs of type USB to charge phones and small electronics are available here?", + "nl": "Hoeveel stekkers van type USB om GSMs en kleine electronica op te laden heeft dit oplaadpunt?" + }, + "render": { + "en": "There are USB to charge phones and small electronics plugs of type USB to charge phones and small electronics available here", + "nl": "Hier zijn USB om GSMs en kleine electronica op te laden stekkers van het type USB om GSMs en kleine electronica op te laden" + }, + "freeform": { + "key": "socket:USB-A", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:USB-A~*", + "socket:USB-A!=0" + ] + } + }, + { + "id": "voltage-13", + "question": { + "en": "What voltage do the plugs with USB to charge phones and small electronics offer?", + "nl": "Welke spanning levert de stekker van type USB om GSMs en kleine electronica op te laden " + }, + "render": { + "en": "USB to charge phones and small electronics outputs {socket:USB-A:voltage} volt", + "nl": "USB om GSMs en kleine electronica op te laden heeft een spanning van {socket:USB-A:voltage} volt" + }, + "freeform": { + "key": "socket:USB-A:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:USB-A:voltage=5 V", + "then": { + "en": "USB to charge phones and small electronics outputs 5 volt", + "nl": "USB om GSMs en kleine electronica op te laden heeft een spanning van 5 volt" + } + } + ], + "condition": { + "and": [ + "socket:USB-A~*", + "socket:USB-A!=0" + ] + } + }, + { + "id": "current-13", + "question": { + "en": "What current do the plugs with USB to charge phones and small electronics offer?", + "nl": "Welke stroom levert de stekker van type USB om GSMs en kleine electronica op te laden ?" + }, + "render": { + "en": "USB to charge phones and small electronics outputs at most {socket:USB-A:current}A", + "nl": "USB om GSMs en kleine electronica op te laden levert een stroom van maximaal {socket:USB-A:current}A" + }, + "freeform": { + "key": "socket:USB-A:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:USB-A:current=1 A", + "then": { + "en": "USB to charge phones and small electronics outputs at most 1 A", + "nl": "USB om GSMs en kleine electronica op te laden levert een stroom van maximaal 1 A" + } + }, + { + "if": "socket:socket:USB-A:current=2 A", + "then": { + "en": "USB to charge phones and small electronics outputs at most 2 A", + "nl": "USB om GSMs en kleine electronica op te laden levert een stroom van maximaal 2 A" + } + } + ], + "condition": { + "and": [ + "socket:USB-A~*", + "socket:USB-A!=0" + ] + } + }, + { + "id": "power-output-13", + "question": { + "en": "What power output does a single plug of type USB to charge phones and small electronics offer?", + "nl": "Welk vermogen levert een enkele stekker van type USB om GSMs en kleine electronica op te laden ?" + }, + "render": { + "en": "USB to charge phones and small electronics outputs at most {socket:USB-A:output}", + "nl": "USB om GSMs en kleine electronica op te laden levert een vermogen van maximaal {socket:USB-A:output}" + }, + "freeform": { + "key": "socket:USB-A:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:USB-A:output=5w", + "then": { + "en": "USB to charge phones and small electronics outputs at most 5w", + "nl": "USB om GSMs en kleine electronica op te laden levert een vermogen van maximaal 5w" + } + }, + { + "if": "socket:socket:USB-A:output=10w", + "then": { + "en": "USB to charge phones and small electronics outputs at most 10w", + "nl": "USB om GSMs en kleine electronica op te laden levert een vermogen van maximaal 10w" + } + } + ], + "condition": { + "and": [ + "socket:USB-A~*", + "socket:USB-A!=0" + ] + } + }, { "id": "Authentication", "question": { @@ -2305,24 +2591,6 @@ "nl": "Betalen via een lidkaart van het netwerk" } } - ], - "mappings": [ - { - "if": "payment:app=yes", - "ifnot": "payment:app=no", - "then": { - "en": "Payment is done using a dedicated app", - "nl": "Betalen via een app van het netwerk" - } - }, - { - "if": "payment:membership_card=yes", - "ifnot": "payment:membership_card=no", - "then": { - "en": "Payment is done using a membership card", - "nl": "Betalen via een lidkaart van het netwerk" - } - } ] } }, @@ -2519,7 +2787,12 @@ } }, { - "if": "amenity=charging_station", + "if": { + "and": [ + "amenity=charging_station", + "operational_status=" + ] + }, "then": { "en": "This charging station works", "nl": "Dit oplaadpunt werkt" @@ -2698,7 +2971,7 @@ { "question": { "en": "Has a Chademo connector", - "nl": "Heeft een " + "nl": "Heeft een Chademo " }, "osmTags": "socket:chademo~*" }, @@ -2719,28 +2992,28 @@ { "question": { "en": "Has a Type 1 CCS (aka Type 1 Combo) connector", - "nl": "Heeft een " + "nl": "Heeft een Type 1 CCS (ook gekend als Type 1 Combo) " }, "osmTags": "socket:type1_combo~*" }, { "question": { "en": "Has a Tesla Supercharger connector", - "nl": "Heeft een " + "nl": "Heeft een Tesla Supercharger " }, "osmTags": "socket:tesla_supercharger~*" }, { "question": { "en": "Has a Type 2 (mennekes) connector", - "nl": "Heeft een " + "nl": "Heeft een Type 2 (mennekes) " }, "osmTags": "socket:type2~*" }, { "question": { "en": "Has a Type 2 CCS (mennekes) connector", - "nl": "Heeft een " + "nl": "Heeft een Type 2 CCS (mennekes) " }, "osmTags": "socket:type2_combo~*" }, @@ -2754,23 +3027,30 @@ { "question": { "en": "Has a Tesla Supercharger CCS (a branded type2_css) connector", - "nl": "Heeft een " + "nl": "Heeft een Tesla Supercharger CCS (een type2 CCS met Tesla-logo) " }, "osmTags": "socket:tesla_supercharger_ccs~*" }, { "question": { "en": "Has a Tesla Supercharger (destination) connector", - "nl": "Heeft een " + "nl": "Heeft een Tesla Supercharger (destination) " }, "osmTags": "socket:tesla_destination~*" }, { "question": { "en": "Has a Tesla supercharger (destination (A Type 2 with cable branded as tesla) connector", - "nl": "Heeft een " + "nl": "Heeft een Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo) " }, "osmTags": "socket:tesla_destination~*" + }, + { + "question": { + "en": "Has a USB to charge phones and small electronics connector", + "nl": "Heeft een USB om GSMs en kleine electronica op te laden " + }, + "osmTags": "socket:USB-A~*" } ] } @@ -2853,7 +3133,8 @@ "socket:type2_cable:voltage", "socket:tesla_supercharger_ccs:voltage", "socket:tesla_destination:voltage", - "socket:tesla_destination:voltage" + "socket:tesla_destination:voltage", + "socket:USB-A:voltage" ], "applicableUnits": [ { @@ -2887,7 +3168,8 @@ "socket:type2_cable:current", "socket:tesla_supercharger_ccs:current", "socket:tesla_destination:current", - "socket:tesla_destination:current" + "socket:tesla_destination:current", + "socket:USB-A:current" ], "applicableUnits": [ { @@ -2920,7 +3202,8 @@ "socket:type2_cable:output", "socket:tesla_supercharger_ccs:output", "socket:tesla_destination:output", - "socket:tesla_destination:output" + "socket:tesla_destination:output", + "socket:USB-A:output" ], "applicableUnits": [ { diff --git a/assets/layers/charging_station/csvToJson.ts b/assets/layers/charging_station/csvToJson.ts index 4a5b04f53..1d0bab2f7 100644 --- a/assets/layers/charging_station/csvToJson.ts +++ b/assets/layers/charging_station/csvToJson.ts @@ -17,7 +17,8 @@ function loadCsv(file): { countryBlackList?: string[], commonVoltages?: number[], commonCurrents?: number[], - commonOutputs?: string[] + commonOutputs?: string[], + associatedVehicleTypes?:string[] }[] { const entries: string[] = Utils.NoNull(readFileSync(file, "utf8").split("\n").map(str => str.trim())) const header = entries.shift().split(",") @@ -29,7 +30,7 @@ function loadCsv(file): { } const v = {} - const colonSeperated = ["commonVoltages", "commonOutputs", "commonCurrents", "countryWhiteList","countryBlackList"] + const colonSeperated = ["commonVoltages", "commonOutputs", "commonCurrents", "countryWhiteList","countryBlackList","associatedVehicleTypes"] const descriptionTranslations = new Map() for (let j = 0; j < header.length; j++) { const key = header[j]; @@ -67,8 +68,8 @@ function run(file, protojson) { for (let i = 0; i < entries.length; i++){ const e = entries[i]; const txt = { - en: ` ${e.description.get("en")}`, - nl: ` ${e.description.get("nl")}` + en: `
${e.description.get("en")}
`, + nl: `
${e.description.get("nl")} 0) { + // This is a 'hideInAnswer', thus _reverse_ logic! const countries = e.countryWhiteList.map(country => "_country!=" + country) //HideInAnswer if it is in the wrong country json["hideInAnswer"] = {or: countries} }else if (e.countryBlackList .length > 0) { const countries = e.countryBlackList.map(country => "_country=" + country) //HideInAnswer if it is in the wrong country json["hideInAnswer"] = {or: countries} } + + if(e.associatedVehicleTypes?.length > 0 && e.associatedVehicleTypes.indexOf("*") < 0){ + // This plug only occurs if some vehicle specific vehicle type is present. + // IF all of the needed vehicle types are explicitly NO, then we hide this type as well + let hideInAnswer : any = {and: [].concat(...e.associatedVehicleTypes.map(neededVehicle => [neededVehicle+"~*", neededVehicle+"!=yes"]))} + if(json["hideInAnswer"] !== undefined){ + hideInAnswer = {or: [json["hideInAnswer"], hideInAnswer]} + } + json["hideInAnswer"] = hideInAnswer + } overview_question_answers.push(json) @@ -300,7 +312,8 @@ function run(file, protojson) { } proto["units"].push(...extraUnits) - mergeTranslations("charging_station.json",proto) + // mergeTranslations("charging_station.json",proto) + writeFileSync("charging_station.json", JSON.stringify(proto, undefined, " ")) } @@ -330,7 +343,6 @@ async function queryTagInfo(file, type, clean: ((s: string) => string)) { const countsArray = Array.from(counts.keys()) countsArray.sort() console.log(`${e.key}:${type} = ${countsArray.join(";")}`) - // console.log(`${countsArray.join(";")}`) } } @@ -362,6 +374,7 @@ function mergeTranslations(origPath, newConfig: LayerConfigJson){ } try { + console.log("Generating the charging_station.json file") run("types.csv", "charging_station.protojson") /*/ queryTagInfo("types.csv","voltage", s => s.trim()) diff --git a/assets/layers/charging_station/license_info.json b/assets/layers/charging_station/license_info.json index 96d5a1ef7..0445cb394 100644 --- a/assets/layers/charging_station/license_info.json +++ b/assets/layers/charging_station/license_info.json @@ -108,5 +108,15 @@ "sources": [ "https://upload.wikimedia.org/wikipedia/commons/2/20/UnderCon_icon.svg" ] + }, + { + "path": "usb_port.svg", + "license": "CC-BY", + "authors": [ + "Ryan Dardis" + ], + "sources": [ + "https://thenounproject.com/term/usb-port/94768/" + ] } ] \ No newline at end of file diff --git a/assets/layers/charging_station/types.csv b/assets/layers/charging_station/types.csv index 4b76be6a7..ad7f9cc17 100644 --- a/assets/layers/charging_station/types.csv +++ b/assets/layers/charging_station/types.csv @@ -1,14 +1,15 @@ -key,image,description:en,countryWhiteList,countryBlackList,commonVoltages,commonCurrents,commonOutputs,description:nl -socket:schuko,CEE7_4F.svg,Schuko wall plug without ground pin (CEE7/4 type F),be;fr;ma;tn;pl;cs;sk;mo,,230,16,3.6 kW,Schuko stekker zonder aardingspin (CEE7/4 type F) -socket:typee,TypeE.svg,European wall plug with ground pin (CEE7/4 type E),,,230,16,3 kW;22 kW;,Europese stekker met aardingspin (CEE7/4 type E) -socket:chademo,Chademo_type4.svg,Chademo,,,500,120,50 kW, -socket:type1_cable,Type1_J1772.svg,Type 1 with cable (J1772),,,200;240,32,3.7 kW;7 kW,Type 1 met kabel (J1772) -socket:type1,Type1_J1772.svg,Type 1 without cable (J1772),,,200;240,32,3.7 kW;6.6 kW;7 kW;7.2 kW,Type 1 zonder kabel (J1772) -socket:type1_combo,Type1-ccs.svg,Type 1 CCS (aka Type 1 Combo),,,400;1000,50;125,50 kW;62.5 kW;150 kW;350 kW;, -socket:tesla_supercharger,Tesla-hpwc-model-s.svg,Tesla Supercharger,,,480,125;350,120 kW;150 kW;250 kW, -socket:type2,Type2_socket.svg,Type 2 (mennekes),,,230;400,16;32,11 kW;22 kW, -socket:type2_combo,Type2_CCS.svg,Type 2 CCS (mennekes),,,500;920,125;350,50 kW, -socket:type2_cable,Type2_tethered.svg,Type 2 with cable (mennekes),,,230;400,16;32,11 kW;22 kW,Type 2 met kabel (J1772) -socket:tesla_supercharger_ccs,Type2_CCS.svg,Tesla Supercharger CCS (a branded type2_css),,,500;920,125;350,50 kW, -socket:tesla_destination,Tesla-hpwc-model-s.svg,Tesla Supercharger (destination),us,,480,125;350,120 kW;150 kW;250 kW, -socket:tesla_destination,Type2_tethered.svg,Tesla supercharger (destination (A Type 2 with cable branded as tesla),,us,230;400,16;32,11 kW;22 kW, +key,image,description:en,countryWhiteList,countryBlackList,commonVoltages,commonCurrents,commonOutputs,description:nl,associatedVehicleTypes +socket:schuko,CEE7_4F.svg,Schuko wall plug without ground pin (CEE7/4 type F),be;fr;ma;tn;pl;cs;sk;mo,,230,16,3.6 kW,Schuko stekker zonder aardingspin (CEE7/4 type F),* +socket:typee,TypeE.svg,European wall plug with ground pin (CEE7/4 type E),,,230,16,3 kW;22 kW;,Europese stekker met aardingspin (CEE7/4 type E),* +socket:chademo,Chademo_type4.svg,Chademo,,,500,120,50 kW,Chademo,car;motorcar;hgv;bus +socket:type1_cable,Type1_J1772.svg,Type 1 with cable (J1772),,,200;240,32,3.7 kW;7 kW,Type 1 met kabel (J1772),car;motorcar;hgv;bus +socket:type1,Type1_J1772.svg,Type 1 without cable (J1772),,,200;240,32,3.7 kW;6.6 kW;7 kW;7.2 kW,Type 1 zonder kabel (J1772),car;motorcar;hgv;bus +socket:type1_combo,Type1-ccs.svg,Type 1 CCS (aka Type 1 Combo),,,400;1000,50;125,50 kW;62.5 kW;150 kW;350 kW;,Type 1 CCS (ook gekend als Type 1 Combo),car;motorcar;hgv;bus +socket:tesla_supercharger,Tesla-hpwc-model-s.svg,Tesla Supercharger,,,480,125;350,120 kW;150 kW;250 kW,Tesla Supercharger,car;motorcar;hgv;bus +socket:type2,Type2_socket.svg,Type 2 (mennekes),,,230;400,16;32,11 kW;22 kW,Type 2 (mennekes),car;motorcar;hgv;bus +socket:type2_combo,Type2_CCS.svg,Type 2 CCS (mennekes),,,500;920,125;350,50 kW,Type 2 CCS (mennekes),car;motorcar;hgv;bus +socket:type2_cable,Type2_tethered.svg,Type 2 with cable (mennekes),,,230;400,16;32,11 kW;22 kW,Type 2 met kabel (J1772),car;motorcar;hgv;bus +socket:tesla_supercharger_ccs,Type2_CCS.svg,Tesla Supercharger CCS (a branded type2_css),,,500;920,125;350,50 kW,Tesla Supercharger CCS (een type2 CCS met Tesla-logo),car;motorcar;hgv;bus +socket:tesla_destination,Tesla-hpwc-model-s.svg,Tesla Supercharger (destination),us,,480,125;350,120 kW;150 kW;250 kW,Tesla Supercharger (destination),car;motorcar;hgv;bus +socket:tesla_destination,Type2_tethered.svg,Tesla supercharger (destination (A Type 2 with cable branded as tesla),,us,230;400,16;32,11 kW;22 kW,Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo),car;motorcar;hgv;bus +socket:USB-A,usb_port.svg,USB to charge phones and small electronics,,,5,1;2,5W;10W,USB om GSMs en kleine electronica op te laden,* diff --git a/assets/layers/charging_station/usb_port.svg b/assets/layers/charging_station/usb_port.svg new file mode 100644 index 000000000..f813f20f0 --- /dev/null +++ b/assets/layers/charging_station/usb_port.svg @@ -0,0 +1,74 @@ + +image/svg+xml \ No newline at end of file From 79031e89924fa052dcdb712e2a9c3f617ad57716 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 1 Oct 2021 00:06:34 +0200 Subject: [PATCH 64/65] Use node 16 in github actions, remove broken 'pull_request_check' github action --- .github/workflows/deploy_pietervdvn.yml | 2 +- .github/workflows/pull_request_check.yml | 71 ------------------- .../workflows/theme_validation_and_deploy.yml | 2 +- 3 files changed, 2 insertions(+), 73 deletions(-) delete mode 100644 .github/workflows/pull_request_check.yml diff --git a/.github/workflows/deploy_pietervdvn.yml b/.github/workflows/deploy_pietervdvn.yml index 54b89561a..dfa564468 100644 --- a/.github/workflows/deploy_pietervdvn.yml +++ b/.github/workflows/deploy_pietervdvn.yml @@ -11,7 +11,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v1.2.0 with: - node-version: '15' + node-version: '16' env: ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' diff --git a/.github/workflows/pull_request_check.yml b/.github/workflows/pull_request_check.yml deleted file mode 100644 index 27165f776..000000000 --- a/.github/workflows/pull_request_check.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: Pull request check -on: - pull_request_target: - types: [ opened, edited, synchronize, ready_for_review, review_requested ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - uses: actions/checkout@v2 - - name: Set up Node.js - uses: actions/setup-node@v1.2.0 - env: - ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' - - - name: install deps - run: npm ci - - - name: create generated dir - run: mkdir ./assets/generated - - - name: create stub themes - run: "echo '{\"layers\": [], \"themes\": []}' > ./assets/generated/known_layers_and_themes.json" - - - name: generate assets - run: npm run generate:images - - - name: generate translations - run: npm run generate:translations - - - name: Compile license info - run: npm run generate:licenses - - - name: Compile and validate themes and layers - run: npm run validate:layeroverview - - - name: Validate license info - run: npm run validate:licenses - - - name: Set failure key - run: | - ls - if [[ -f "layer_report.txt" || -f "missing_licenses.txt" ]]; then - echo "Found a report..." - echo "VALIDATION_FAILED=true" >> $GITHUB_ENV - else - echo "VALIDATION_FAILED=false" >> $GITHUB_ENV - fi - - - name: Test variable - run: echo "${{ env.VALIDATION_FAILED }}" - - - name: Archive reports - uses: actions/upload-artifact@v2 - if: >- - env.VALIDATION_FAILED == 'true' - with: - name: reports - path: | - layer_report.txt - missing_licenses.txt - - - name: Comment PR - uses: allthatjazzleo/actions-pull-request-add-comment@master - if: >- - env.VALIDATION_FAILED == 'true' - with: - message: "cat layer_report.txt missing_licenses.txt" - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/theme_validation_and_deploy.yml b/.github/workflows/theme_validation_and_deploy.yml index 06c0b7fdf..fd7efe0d8 100644 --- a/.github/workflows/theme_validation_and_deploy.yml +++ b/.github/workflows/theme_validation_and_deploy.yml @@ -13,7 +13,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v1.2.0 with: - node-version: '15' + node-version: '16' env: ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true' From 04a2f91b36e81a26e361a2a26c3026fd9bdae4ea Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 1 Oct 2021 00:23:44 +0200 Subject: [PATCH 65/65] Fix small styling issue with tabbed component --- UI/Base/TabbedComponent.ts | 2 +- css/index-tailwind-output.css | 102 +++++++++++++++++++++++++++++++--- 2 files changed, 94 insertions(+), 10 deletions(-) diff --git a/UI/Base/TabbedComponent.ts b/UI/Base/TabbedComponent.ts index b5a33871a..8f71a462a 100644 --- a/UI/Base/TabbedComponent.ts +++ b/UI/Base/TabbedComponent.ts @@ -31,7 +31,7 @@ export class TabbedComponent extends Combine { tabs.push(tab) } - const header = new Combine(tabs).SetClass("block tabs-header-bar") + const header = new Combine(tabs).SetClass("tabs-header-bar") const actualContent = new VariableUiElement( openedTabSrc.map(i => contentElements[i]) ) diff --git a/css/index-tailwind-output.css b/css/index-tailwind-output.css index e3d669e7c..568e2072f 100644 --- a/css/index-tailwind-output.css +++ b/css/index-tailwind-output.css @@ -1322,6 +1322,11 @@ video { background-color: rgba(156, 163, 175, var(--tw-bg-opacity)); } +.bg-indigo-100 { + --tw-bg-opacity: 1; + background-color: rgba(224, 231, 255, var(--tw-bg-opacity)); +} + .bg-gray-300 { --tw-bg-opacity: 1; background-color: rgba(209, 213, 219, var(--tw-bg-opacity)); @@ -1337,11 +1342,6 @@ video { background-color: rgba(229, 231, 235, var(--tw-bg-opacity)); } -.bg-indigo-100 { - --tw-bg-opacity: 1; - background-color: rgba(224, 231, 255, var(--tw-bg-opacity)); -} - .bg-gray-100 { --tw-bg-opacity: 1; background-color: rgba(243, 244, 246, var(--tw-bg-opacity)); @@ -1573,10 +1573,6 @@ video { text-decoration: underline; } -.line-through { - text-decoration: line-through; -} - .opacity-0 { opacity: 0; } @@ -1992,6 +1988,8 @@ li::marker { } @-webkit-keyframes slide { + /* This is the animation on the marker to add a new point - it slides through all the possible presets */ + from { transform: translateX(0%); } @@ -2002,6 +2000,8 @@ li::marker { } @keyframes slide { + /* This is the animation on the marker to add a new point - it slides through all the possible presets */ + from { transform: translateX(0%); } @@ -2011,6 +2011,90 @@ li::marker { } } +.hand-drag-animation { + -webkit-animation: hand-drag-animation 6s ease-in-out infinite; + animation: hand-drag-animation 6s ease-in-out infinite; + transform-origin: 50% 125%; +} + +@-webkit-keyframes hand-drag-animation { + /* This is the animation on the little extra hand on the location input. If fades in, invites the user to interact/drag the map */ + + 0% { + opacity: 0; + transform: rotate(-30deg); + } + + 6% { + opacity: 1; + transform: rotate(-30deg); + } + + 12% { + opacity: 1; + transform: rotate(-45deg); + } + + 24% { + opacity: 1; + transform: rotate(-00deg); + } + + 30% { + opacity: 1; + transform: rotate(-30deg); + } + + 36% { + opacity: 0; + transform: rotate(-30deg); + } + + 100% { + opacity: 0; + transform: rotate(-30deg); + } +} + +@keyframes hand-drag-animation { + /* This is the animation on the little extra hand on the location input. If fades in, invites the user to interact/drag the map */ + + 0% { + opacity: 0; + transform: rotate(-30deg); + } + + 6% { + opacity: 1; + transform: rotate(-30deg); + } + + 12% { + opacity: 1; + transform: rotate(-45deg); + } + + 24% { + opacity: 1; + transform: rotate(-00deg); + } + + 30% { + opacity: 1; + transform: rotate(-30deg); + } + + 36% { + opacity: 0; + transform: rotate(-30deg); + } + + 100% { + opacity: 0; + transform: rotate(-30deg); + } +} + /**************************************/ #topleft-tools {