diff --git a/.gitignore b/.gitignore
index a9dcf16ad..c5a6e0be2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,4 @@ service-worker.js
*.vsix
public/*.webmanifest
public/assets/generated/
+public/assets/langs/*
diff --git a/Docs/BuiltinIndex.md b/Docs/BuiltinIndex.md
index 85e91176e..1a6ad5306 100644
--- a/Docs/BuiltinIndex.md
+++ b/Docs/BuiltinIndex.md
@@ -90,7 +90,6 @@
- ambulancestation
- artwork
- atm
- - atm
- barrier
- bench
- bench_at_pt
@@ -219,7 +218,6 @@
- - atm
- atm
- bicycle_library
- bicycle_rental
@@ -292,6 +290,7 @@
- shops
- sports_centre
- tertiary_education
+ - vending_machine
- veterinary
@@ -614,6 +613,7 @@
- food
- hackerspace
- hotel
+ - pharmacy
- shops
- veterinary
diff --git a/Docs/Layers/all_vending_machine.md b/Docs/Layers/all_vending_machine.md
index 66ae52dd7..bf7e6ce66 100644
--- a/Docs/Layers/all_vending_machine.md
+++ b/Docs/Layers/all_vending_machine.md
@@ -47,7 +47,7 @@ this quick overview is incomplete
attribute | type | values which are supported by this layer
----------- | ------ | ------------------------------------------
[](https://taginfo.openstreetmap.org/keys/id#values) [id](https://wiki.openstreetmap.org/wiki/Key:id) | Multiple choice |
-[](https://taginfo.openstreetmap.org/keys/vending#values) [vending](https://wiki.openstreetmap.org/wiki/Key:vending) | [string](../SpecialInputElements.md#string) | [drinks](https://wiki.openstreetmap.org/wiki/Tag:vending%3Ddrinks) [sweets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dsweets) [food](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dfood) [cigarettes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcigarettes) [condoms](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcondoms) [coffee](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcoffee) [water](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dwater) [newspapers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dnewspapers) [bicycle_tube](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_tube) [milk](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmilk) [bread](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbread) [eggs](https://wiki.openstreetmap.org/wiki/Tag:vending%3Deggs) [cheese](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcheese) [honey](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dhoney) [potatoes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpotatoes) [meat](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmeat) [flowers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dflowers) [parking_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dparking_tickets) [elongated_coin](https://wiki.openstreetmap.org/wiki/Tag:vending%3Delongated_coin) [public_transport_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpublic_transport_tickets) [bicycle_light](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_light) [gloves](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dgloves) [bicycle_repair_kit](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_repair_kit) [bicycle_pump](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_pump) [bicycle_lock](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_lock)
+[](https://taginfo.openstreetmap.org/keys/vending#values) [vending](https://wiki.openstreetmap.org/wiki/Key:vending) | [string](../SpecialInputElements.md#string) | [drinks](https://wiki.openstreetmap.org/wiki/Tag:vending%3Ddrinks) [sweets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dsweets) [food](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dfood) [cigarettes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcigarettes) [condoms](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcondoms) [coffee](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcoffee) [water](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dwater) [newspapers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dnewspapers) [bicycle_tube](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_tube) [milk](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmilk) [bread](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbread) [eggs](https://wiki.openstreetmap.org/wiki/Tag:vending%3Deggs) [cheese](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcheese) [honey](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dhoney) [potatoes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpotatoes) [meat](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmeat) [fruit](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dfruit) [strawberries](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dstrawberries) [flowers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dflowers) [parking_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dparking_tickets) [elongated_coin](https://wiki.openstreetmap.org/wiki/Tag:vending%3Delongated_coin) [public_transport_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpublic_transport_tickets) [bicycle_light](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_light) [gloves](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dgloves) [bicycle_repair_kit](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_repair_kit) [bicycle_pump](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_pump) [bicycle_lock](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_lock)
[](https://taginfo.openstreetmap.org/keys/opening_hours#values) [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) | [opening_hours](../SpecialInputElements.md#opening_hours) | [24/7](https://wiki.openstreetmap.org/wiki/Tag:opening_hours%3D24/7)
[](https://taginfo.openstreetmap.org/keys/payment:coins:denominations#values) [payment:coins:denominations](https://wiki.openstreetmap.org/wiki/Key:payment:coins:denominations) | Multiple choice | [0.01 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.01 EUR) [0.02 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.02 EUR) [0.05 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.05 EUR) [0.10 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.10 EUR) [0.20 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.20 EUR) [0.50 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.50 EUR) [1 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D1 EUR) [2 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D2 EUR) [0.05 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.05 CHF) [0.10 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.10 CHF) [0.20 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.20 CHF) [0.50 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.50 CHF) [1 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D1 CHF) [2 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D2 CHF) [5 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D5 CHF)
[](https://taginfo.openstreetmap.org/keys/payment:notes:denominations#values) [payment:notes:denominations](https://wiki.openstreetmap.org/wiki/Key:payment:notes:denominations) | Multiple choice | [5 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D5 EUR) [10 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D10 EUR) [20 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D20 EUR) [50 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D50 EUR) [100 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D100 EUR) [200 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D200 EUR) [500 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D500 EUR) [10 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D10 CHF) [20 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D20 CHF) [50 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D50 CHF) [100 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D100 CHF) [200 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D200 CHF) [1000 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D1000 CHF)
@@ -55,6 +55,7 @@ attribute | type | values which are supported by this layer
[](https://taginfo.openstreetmap.org/keys/indoor#values) [indoor](https://wiki.openstreetmap.org/wiki/Key:indoor) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:indoor%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:indoor%3Dno)
[](https://taginfo.openstreetmap.org/keys/level#values) [level](https://wiki.openstreetmap.org/wiki/Key:level) | [float](../SpecialInputElements.md#float) | [0](https://wiki.openstreetmap.org/wiki/Tag:level%3D0) [1](https://wiki.openstreetmap.org/wiki/Tag:level%3D1) [-1](https://wiki.openstreetmap.org/wiki/Tag:level%3D-1)
[](https://taginfo.openstreetmap.org/keys/phone#values) [phone](https://wiki.openstreetmap.org/wiki/Key:phone) | [phone](../SpecialInputElements.md#phone) |
+[](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) |
@@ -120,6 +121,8 @@ This is rendered with `This vending machine sells {vending}`
- *Honey is sold* corresponds with `vending=honey`
- *Potatoes are sold* corresponds with `vending=potatoes`
- *Meat is sold* corresponds with `vending=meat`
+ - *Fruit is sold* corresponds with `vending=fruit`
+ - *Strawberries are sold* corresponds with `vending=strawberries`
- *Flowers are sold* corresponds with `vending=flowers`
- *Parking tickets are sold* corresponds with `vending=parking_tickets`
- *Pressed pennies are sold* corresponds with `vending=elongated_coin`
@@ -337,6 +340,28 @@ This tagrendering has labels `contact`
+### website
+
+
+
+The question is *What is the website of {title()}?*
+
+This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website)
+
+This is rendered with `{website}`
+
+
+
+
+
+ - *{contact:website}* corresponds with `contact:website~.+`
+ - This option cannot be chosen as answer
+
+
+This tagrendering has labels `contact`
+
+
+
### leftover-questions
@@ -435,15 +460,17 @@ vending.13 | Sale of cheese | vending~^(.*cheese.*)$
vending.14 | Sale of honey | vending~^(.*honey.*)$
vending.15 | Sale of potatoes | vending~^(.*potatoes.*)$
vending.16 | Sale of meat | vending~^(.*meat.*)$
-vending.17 | Sale of flowers | vending~^(.*flowers.*)$
-vending.18 | Sale of parking tickets | vending~^(.*parking_tickets.*)$
-vending.19 | Sale of pressed pennies | vending=elongated_coin
-vending.20 | Sale of public transport tickets | vending~^(.*public_transport_tickets.*)$
-vending.21 | Sale of bicycle lights | vending=bicycle_light
-vending.22 | Sale of gloves | vending=gloves
-vending.23 | Sale of bicycle repair kits | vending=bicycle_repair_kit
-vending.24 | Sale of bicycle pumps | vending=bicycle_pump
-vending.25 | Sale of bicycle locks | vending=bicycle_lock
+vending.17 | Sale of fruit | vending~^(.*fruit.*)$
+vending.18 | Sale of strawberries | vending~^(.*strawberries.*)$
+vending.19 | Sale of flowers | vending~^(.*flowers.*)$
+vending.20 | Sale of parking tickets | vending~^(.*parking_tickets.*)$
+vending.21 | Sale of pressed pennies | vending=elongated_coin
+vending.22 | Sale of public transport tickets | vending~^(.*public_transport_tickets.*)$
+vending.23 | Sale of bicycle lights | vending=bicycle_light
+vending.24 | Sale of gloves | vending=gloves
+vending.25 | Sale of bicycle repair kits | vending=bicycle_repair_kit
+vending.26 | Sale of bicycle pumps | vending=bicycle_pump
+vending.27 | Sale of bicycle locks | vending=bicycle_lock
This document is autogenerated from [assets/themes/vending_machine/vending_machine.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/themes/vending_machine/vending_machine.json)
diff --git a/Docs/Layers/cafe_pub.md b/Docs/Layers/cafe_pub.md
index 806fea93d..a82a76ab4 100644
--- a/Docs/Layers/cafe_pub.md
+++ b/Docs/Layers/cafe_pub.md
@@ -14,7 +14,7 @@ A layer showing cafés and pubs where one can gather around a drink. The layer a
- - This layer is shown at zoomlevel **0** and higher
+ - This layer is shown at zoomlevel **12** and higher
@@ -504,6 +504,20 @@ accepts_cash.0 | Accepts cash | payment:cash=yes
id | question | osmTags
---- | ---------- | ---------
accepts_cards.0 | Accepts payment cards | payment:cards=yes
+
+
+
+
+id | question | osmTags
+---- | ---------- | ---------
+has_internet.0 | Offers internet | internet_access=wlan\|internet_access=yes\|internet_access=wired
+
+
+
+
+id | question | osmTags
+---- | ---------- | ---------
+has_electricity.0 | Offers electricity | service:electricity=yes
This document is autogenerated from [assets/layers/cafe_pub/cafe_pub.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/cafe_pub/cafe_pub.json)
diff --git a/Docs/Layers/dogfoodb.md b/Docs/Layers/dogfoodb.md
index 37f750a7b..cbf54b87b 100644
--- a/Docs/Layers/dogfoodb.md
+++ b/Docs/Layers/dogfoodb.md
@@ -131,7 +131,7 @@ The question is *What type of business is this?*
- - *This is a fastfood-business, focused on fast service. If seating is available, these are rather limited and functional.* corresponds with `amenity=fast_food`
+ - *This is a fast-food business, focused on fast service. If seating is available, it is rather limited and functional.* corresponds with `amenity=fast_food`
- *A restaurant, focused on creating a nice experience where one is served at the table* corresponds with `amenity=restaurant`
@@ -300,7 +300,7 @@ The question is *Is this place accessible with a wheelchair?*
-The question is *Which food is served here?*
+The question is *What kind of food is served here?*
This rendering asks information about the property [cuisine](https://wiki.openstreetmap.org/wiki/Key:cuisine)
@@ -314,11 +314,11 @@ This is rendered with `This place mostly serves {cuisine}`
- *This is a friture* corresponds with `cuisine=friture`
- *Mainly serves pasta* corresponds with `cuisine=pasta`
- *This is kebab shop* corresponds with `cuisine=kebab`
- - *This is a sandwichbar* corresponds with `cuisine=sandwich`
+ - *This is a sandwich shop* corresponds with `cuisine=sandwich`
- *Burgers are served here* corresponds with `cuisine=burger`
- *Sushi is served here* corresponds with `cuisine=sushi`
- *Coffee is served here* corresponds with `cuisine=coffee`
- - *This is an italian restaurant (which serves more then pasta and pizza)* corresponds with `cuisine=italian`
+ - *This is an Italian restaurant (which serves more than pasta and pizza)* corresponds with `cuisine=italian`
- *French dishes are served here* corresponds with `cuisine=french`
- *Chinese dishes are served here* corresponds with `cuisine=chinese`
- *Greek dishes are served here* corresponds with `cuisine=greek`
@@ -370,7 +370,7 @@ The question is *Does this place offer take-away?*
-The question is *Delivers {title()} their food at home?*
+The question is *Does {title()} deliver food to your home?*
diff --git a/Docs/Layers/food.md b/Docs/Layers/food.md
index dc5f7650d..e9c1895a4 100644
--- a/Docs/Layers/food.md
+++ b/Docs/Layers/food.md
@@ -135,7 +135,7 @@ The question is *What type of business is this?*
- - *This is a fastfood-business, focused on fast service. If seating is available, these are rather limited and functional.* corresponds with `amenity=fast_food`
+ - *This is a fast-food business, focused on fast service. If seating is available, it is rather limited and functional.* corresponds with `amenity=fast_food`
- *A restaurant, focused on creating a nice experience where one is served at the table* corresponds with `amenity=restaurant`
@@ -304,7 +304,7 @@ The question is *Is this place accessible with a wheelchair?*
-The question is *Which food is served here?*
+The question is *What kind of food is served here?*
This rendering asks information about the property [cuisine](https://wiki.openstreetmap.org/wiki/Key:cuisine)
@@ -318,11 +318,11 @@ This is rendered with `This place mostly serves {cuisine}`
- *This is a friture* corresponds with `cuisine=friture`
- *Mainly serves pasta* corresponds with `cuisine=pasta`
- *This is kebab shop* corresponds with `cuisine=kebab`
- - *This is a sandwichbar* corresponds with `cuisine=sandwich`
+ - *This is a sandwich shop* corresponds with `cuisine=sandwich`
- *Burgers are served here* corresponds with `cuisine=burger`
- *Sushi is served here* corresponds with `cuisine=sushi`
- *Coffee is served here* corresponds with `cuisine=coffee`
- - *This is an italian restaurant (which serves more then pasta and pizza)* corresponds with `cuisine=italian`
+ - *This is an Italian restaurant (which serves more than pasta and pizza)* corresponds with `cuisine=italian`
- *French dishes are served here* corresponds with `cuisine=french`
- *Chinese dishes are served here* corresponds with `cuisine=chinese`
- *Greek dishes are served here* corresponds with `cuisine=greek`
@@ -374,7 +374,7 @@ The question is *Does this place offer take-away?*
-The question is *Delivers {title()} their food at home?*
+The question is *Does {title()} deliver food to your home?*
diff --git a/Docs/Layers/friture.md b/Docs/Layers/friture.md
index 09d2218f8..295c4a6f2 100644
--- a/Docs/Layers/friture.md
+++ b/Docs/Layers/friture.md
@@ -131,7 +131,7 @@ The question is *What type of business is this?*
- - *This is a fastfood-business, focused on fast service. If seating is available, these are rather limited and functional.* corresponds with `amenity=fast_food`
+ - *This is a fast-food business, focused on fast service. If seating is available, it is rather limited and functional.* corresponds with `amenity=fast_food`
- *A restaurant, focused on creating a nice experience where one is served at the table* corresponds with `amenity=restaurant`
@@ -300,7 +300,7 @@ The question is *Is this place accessible with a wheelchair?*
-The question is *Which food is served here?*
+The question is *What kind of food is served here?*
This rendering asks information about the property [cuisine](https://wiki.openstreetmap.org/wiki/Key:cuisine)
@@ -314,11 +314,11 @@ This is rendered with `This place mostly serves {cuisine}`
- *This is a friture* corresponds with `cuisine=friture`
- *Mainly serves pasta* corresponds with `cuisine=pasta`
- *This is kebab shop* corresponds with `cuisine=kebab`
- - *This is a sandwichbar* corresponds with `cuisine=sandwich`
+ - *This is a sandwich shop* corresponds with `cuisine=sandwich`
- *Burgers are served here* corresponds with `cuisine=burger`
- *Sushi is served here* corresponds with `cuisine=sushi`
- *Coffee is served here* corresponds with `cuisine=coffee`
- - *This is an italian restaurant (which serves more then pasta and pizza)* corresponds with `cuisine=italian`
+ - *This is an Italian restaurant (which serves more than pasta and pizza)* corresponds with `cuisine=italian`
- *French dishes are served here* corresponds with `cuisine=french`
- *Chinese dishes are served here* corresponds with `cuisine=chinese`
- *Greek dishes are served here* corresponds with `cuisine=greek`
@@ -370,7 +370,7 @@ The question is *Does this place offer take-away?*
-The question is *Delivers {title()} their food at home?*
+The question is *Does {title()} deliver food to your home?*
diff --git a/Docs/Layers/guidepost.md b/Docs/Layers/guidepost.md
index a450c2f08..20b084c30 100644
--- a/Docs/Layers/guidepost.md
+++ b/Docs/Layers/guidepost.md
@@ -15,6 +15,18 @@ Guideposts (also known as fingerposts or finger posts) are often found along off
- This layer is shown at zoomlevel **14** and higher
+ - Not visible in the layer selection by default. If you want to make this layer toggable, override `name`
+
+
+
+
+#### Themes using this layer
+
+
+
+
+
+ - [climbing](https://mapcomplete.org/climbing)
This is a special layer - data is not sourced from OpenStreetMap
diff --git a/Docs/Layers/pharmacy.md b/Docs/Layers/pharmacy.md
index de3354f42..9c91a38b6 100644
--- a/Docs/Layers/pharmacy.md
+++ b/Docs/Layers/pharmacy.md
@@ -90,6 +90,18 @@ This tagrendering has no question and is thus read-only
+### reviews
+
+
+
+Shows the reviews module (including the possibility to leave a review)
+
+This tagrendering has no question and is thus read-only
+
+
+
+
+
### name
diff --git a/Docs/Layers/toilet.md b/Docs/Layers/toilet.md
index 74daf39b6..31f03134f 100644
--- a/Docs/Layers/toilet.md
+++ b/Docs/Layers/toilet.md
@@ -297,7 +297,7 @@ This tagrendering has labels `relevant-questions`
-The question is *Which kind of toilets are this?*
+The question is *Which kind of toilets are these?*
@@ -367,8 +367,8 @@ The question is *Do these toilets have a sink to wash your hands?*
- - *This toilets have a sink to wash your hands* corresponds with `toilets:handwashing=yes`
- - *This toilets don't have a sink to wash your hands* corresponds with `toilets:handwashing=no`
+ - *These toilets have a sink to wash your hands* corresponds with `toilets:handwashing=yes`
+ - *These toilets don't have a sink to wash your hands* corresponds with `toilets:handwashing=no`
This tagrendering has labels `relevant-questions`
diff --git a/Docs/Layers/vending_machine.md b/Docs/Layers/vending_machine.md
index d31dbf0d9..4deeef5e7 100644
--- a/Docs/Layers/vending_machine.md
+++ b/Docs/Layers/vending_machine.md
@@ -47,7 +47,7 @@ this quick overview is incomplete
attribute | type | values which are supported by this layer
----------- | ------ | ------------------------------------------
[](https://taginfo.openstreetmap.org/keys/id#values) [id](https://wiki.openstreetmap.org/wiki/Key:id) | Multiple choice |
-[](https://taginfo.openstreetmap.org/keys/vending#values) [vending](https://wiki.openstreetmap.org/wiki/Key:vending) | [string](../SpecialInputElements.md#string) | [drinks](https://wiki.openstreetmap.org/wiki/Tag:vending%3Ddrinks) [sweets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dsweets) [food](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dfood) [cigarettes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcigarettes) [condoms](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcondoms) [coffee](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcoffee) [water](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dwater) [newspapers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dnewspapers) [bicycle_tube](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_tube) [milk](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmilk) [bread](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbread) [eggs](https://wiki.openstreetmap.org/wiki/Tag:vending%3Deggs) [cheese](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcheese) [honey](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dhoney) [potatoes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpotatoes) [meat](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmeat) [flowers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dflowers) [parking_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dparking_tickets) [elongated_coin](https://wiki.openstreetmap.org/wiki/Tag:vending%3Delongated_coin) [public_transport_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpublic_transport_tickets) [bicycle_light](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_light) [gloves](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dgloves) [bicycle_repair_kit](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_repair_kit) [bicycle_pump](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_pump) [bicycle_lock](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_lock)
+[](https://taginfo.openstreetmap.org/keys/vending#values) [vending](https://wiki.openstreetmap.org/wiki/Key:vending) | [string](../SpecialInputElements.md#string) | [drinks](https://wiki.openstreetmap.org/wiki/Tag:vending%3Ddrinks) [sweets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dsweets) [food](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dfood) [cigarettes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcigarettes) [condoms](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcondoms) [coffee](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcoffee) [water](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dwater) [newspapers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dnewspapers) [bicycle_tube](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_tube) [milk](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmilk) [bread](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbread) [eggs](https://wiki.openstreetmap.org/wiki/Tag:vending%3Deggs) [cheese](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dcheese) [honey](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dhoney) [potatoes](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpotatoes) [meat](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dmeat) [fruit](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dfruit) [strawberries](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dstrawberries) [flowers](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dflowers) [parking_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dparking_tickets) [elongated_coin](https://wiki.openstreetmap.org/wiki/Tag:vending%3Delongated_coin) [public_transport_tickets](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dpublic_transport_tickets) [bicycle_light](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_light) [gloves](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dgloves) [bicycle_repair_kit](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_repair_kit) [bicycle_pump](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_pump) [bicycle_lock](https://wiki.openstreetmap.org/wiki/Tag:vending%3Dbicycle_lock)
[](https://taginfo.openstreetmap.org/keys/opening_hours#values) [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) | [opening_hours](../SpecialInputElements.md#opening_hours) | [24/7](https://wiki.openstreetmap.org/wiki/Tag:opening_hours%3D24/7)
[](https://taginfo.openstreetmap.org/keys/payment:coins:denominations#values) [payment:coins:denominations](https://wiki.openstreetmap.org/wiki/Key:payment:coins:denominations) | Multiple choice | [0.01 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.01 EUR) [0.02 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.02 EUR) [0.05 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.05 EUR) [0.10 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.10 EUR) [0.20 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.20 EUR) [0.50 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.50 EUR) [1 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D1 EUR) [2 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D2 EUR) [0.05 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.05 CHF) [0.10 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.10 CHF) [0.20 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.20 CHF) [0.50 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D0.50 CHF) [1 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D1 CHF) [2 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D2 CHF) [5 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:coins:denominations%3D5 CHF)
[](https://taginfo.openstreetmap.org/keys/payment:notes:denominations#values) [payment:notes:denominations](https://wiki.openstreetmap.org/wiki/Key:payment:notes:denominations) | Multiple choice | [5 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D5 EUR) [10 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D10 EUR) [20 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D20 EUR) [50 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D50 EUR) [100 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D100 EUR) [200 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D200 EUR) [500 EUR](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D500 EUR) [10 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D10 CHF) [20 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D20 CHF) [50 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D50 CHF) [100 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D100 CHF) [200 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D200 CHF) [1000 CHF](https://wiki.openstreetmap.org/wiki/Tag:payment:notes:denominations%3D1000 CHF)
@@ -55,6 +55,7 @@ attribute | type | values which are supported by this layer
[](https://taginfo.openstreetmap.org/keys/indoor#values) [indoor](https://wiki.openstreetmap.org/wiki/Key:indoor) | Multiple choice | [yes](https://wiki.openstreetmap.org/wiki/Tag:indoor%3Dyes) [no](https://wiki.openstreetmap.org/wiki/Tag:indoor%3Dno)
[](https://taginfo.openstreetmap.org/keys/level#values) [level](https://wiki.openstreetmap.org/wiki/Key:level) | [float](../SpecialInputElements.md#float) | [0](https://wiki.openstreetmap.org/wiki/Tag:level%3D0) [1](https://wiki.openstreetmap.org/wiki/Tag:level%3D1) [-1](https://wiki.openstreetmap.org/wiki/Tag:level%3D-1)
[](https://taginfo.openstreetmap.org/keys/phone#values) [phone](https://wiki.openstreetmap.org/wiki/Key:phone) | [phone](../SpecialInputElements.md#phone) |
+[](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) |
@@ -120,6 +121,8 @@ This is rendered with `This vending machine sells {vending}`
- *Honey is sold* corresponds with `vending=honey`
- *Potatoes are sold* corresponds with `vending=potatoes`
- *Meat is sold* corresponds with `vending=meat`
+ - *Fruit is sold* corresponds with `vending=fruit`
+ - *Strawberries are sold* corresponds with `vending=strawberries`
- *Flowers are sold* corresponds with `vending=flowers`
- *Parking tickets are sold* corresponds with `vending=parking_tickets`
- *Pressed pennies are sold* corresponds with `vending=elongated_coin`
@@ -337,6 +340,28 @@ This tagrendering has labels `contact`
+### website
+
+
+
+The question is *What is the website of {title()}?*
+
+This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website)
+
+This is rendered with `{website}`
+
+
+
+
+
+ - *{contact:website}* corresponds with `contact:website~.+`
+ - This option cannot be chosen as answer
+
+
+This tagrendering has labels `contact`
+
+
+
### leftover-questions
@@ -435,15 +460,17 @@ vending.13 | Sale of cheese | vending~^(.*cheese.*)$
vending.14 | Sale of honey | vending~^(.*honey.*)$
vending.15 | Sale of potatoes | vending~^(.*potatoes.*)$
vending.16 | Sale of meat | vending~^(.*meat.*)$
-vending.17 | Sale of flowers | vending~^(.*flowers.*)$
-vending.18 | Sale of parking tickets | vending~^(.*parking_tickets.*)$
-vending.19 | Sale of pressed pennies | vending=elongated_coin
-vending.20 | Sale of public transport tickets | vending~^(.*public_transport_tickets.*)$
-vending.21 | Sale of bicycle lights | vending=bicycle_light
-vending.22 | Sale of gloves | vending=gloves
-vending.23 | Sale of bicycle repair kits | vending=bicycle_repair_kit
-vending.24 | Sale of bicycle pumps | vending=bicycle_pump
-vending.25 | Sale of bicycle locks | vending=bicycle_lock
+vending.17 | Sale of fruit | vending~^(.*fruit.*)$
+vending.18 | Sale of strawberries | vending~^(.*strawberries.*)$
+vending.19 | Sale of flowers | vending~^(.*flowers.*)$
+vending.20 | Sale of parking tickets | vending~^(.*parking_tickets.*)$
+vending.21 | Sale of pressed pennies | vending=elongated_coin
+vending.22 | Sale of public transport tickets | vending~^(.*public_transport_tickets.*)$
+vending.23 | Sale of bicycle lights | vending=bicycle_light
+vending.24 | Sale of gloves | vending=gloves
+vending.25 | Sale of bicycle repair kits | vending=bicycle_repair_kit
+vending.26 | Sale of bicycle pumps | vending=bicycle_pump
+vending.27 | Sale of bicycle locks | vending=bicycle_lock
This document is autogenerated from [assets/layers/vending_machine/vending_machine.json](https://github.com/pietervdvn/MapComplete/blob/develop/assets/layers/vending_machine/vending_machine.json)
diff --git a/Docs/SpecialRenderings.md b/Docs/SpecialRenderings.md
index df0fca5c9..7ea2310e2 100644
--- a/Docs/SpecialRenderings.md
+++ b/Docs/SpecialRenderings.md
@@ -118,8 +118,6 @@ In other words: use `{ "before": ..., "after": ..., "special": {"type": ..., "ar
* [Example usage of list_reviews](#example-usage-of-list_reviews)
+ [opening_hours_table](#opening_hours_table)
* [Example usage of opening_hours_table](#example-usage-of-opening_hours_table)
- + [live](#live)
- * [Example usage of live](#example-usage-of-live)
+ [canonical](#canonical)
* [Example usage of canonical](#example-usage-of-canonical)
+ [export_as_geojson](#export_as_geojson)
@@ -825,23 +823,6 @@ postfix | _empty string_ | Remove this string from the end of the value before p
-### live
-
- Downloads a JSON from the given URL, e.g. '{live(example.org/data.json, shorthand:x.y.z, other:a.b.c, shorthand)}' will download the given file, will create an object {shorthand: json[x][y][z], other: json[a][b][c] out of it and will return 'other' or 'json[a][b][c]. This is made to use in combination with tags, e.g. {live({url}, {url:format}, needed_value)}
-
-name | default | description
------- | --------- | -------------
-Url | _undefined_ | The URL to load
-Shorthands | _undefined_ | A list of shorthands, of the format 'shorthandname:path.path.path'. separated by ;
-path | _undefined_ | The path (or shorthand) that should be returned
-
-
-#### Example usage of live
-
- {live({url},{url:format},hour)} {live(https://data.mobility.brussels/bike/api/counts/?request=live&featureID=CB2105,hour:data.hour_cnt;day:data.day_cnt;year:data.year_cnt,hour)}
-
-
-
### canonical
Converts a short, canonical value into the long, translated text including the unit. This only works if a `unit` is defined for the corresponding value. The unit specification will be included in the text.
diff --git a/Docs/TagInfo/mapcomplete_climbing.json b/Docs/TagInfo/mapcomplete_climbing.json
index fea40f171..83afbdf82 100644
--- a/Docs/TagInfo/mapcomplete_climbing.json
+++ b/Docs/TagInfo/mapcomplete_climbing.json
@@ -2838,65 +2838,6 @@
"description": "Layer 'Shop' shows organic=no with a fixed text, namely 'This shop does not offer organic products' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots') (This is only shown if shop=supermarket|shop=convenience|shop=farm|shop=greengrocer|shop=health_food|shop=clothes|shop=shoes|shop=butcher|shop=cosmetics|shop=deli|shop=bakery|shop=alcohol|shop=seafood|shop=beverages|shop=florist)",
"value": "no"
},
- {
- "key": "amenity",
- "description": "The MapComplete theme Climbing gyms, clubs and spots has a layer Drinking water showing features with this tag",
- "value": "drinking_water"
- },
- {
- "key": "drinking_water",
- "description": "The MapComplete theme Climbing gyms, clubs and spots has a layer Drinking water showing features with this tag",
- "value": "yes"
- },
- {
- "key": "id",
- "description": "Layer 'Drinking water' shows id~.+ with a fixed text, namely 'You just created this element! Thanks for sharing this info with the world and helping people worldwide.' (in the mapcomplete.org theme 'Climbing gyms, clubs and spots') (This is only shown if _backend~.+&_last_edit:passed_time<300&|_version_number=1)"
- },
- {
- "key": "image",
- "description": "The layer 'Drinking water allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary"
- },
- {
- "key": "mapillary",
- "description": "The layer 'Drinking water allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary"
- },
- {
- "key": "wikidata",
- "description": "The layer 'Drinking water allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary"
- },
- {
- "key": "wikipedia",
- "description": "The layer 'Drinking water allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary"
- },
- {
- "key": "operational_status",
- "description": "Layer 'Drinking water' shows and asks freeform values for key 'operational_status' (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')"
- },
- {
- "key": "operational_status",
- "description": "Layer 'Drinking water' shows with a fixed text, namely 'This drinking water works' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots') Picking this answer will delete the key operational_status.",
- "value": ""
- },
- {
- "key": "operational_status",
- "description": "Layer 'Drinking water' shows operational_status=broken with a fixed text, namely 'This drinking water is broken' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')",
- "value": "broken"
- },
- {
- "key": "operational_status",
- "description": "Layer 'Drinking water' shows operational_status=closed with a fixed text, namely 'This drinking water is closed' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')",
- "value": "closed"
- },
- {
- "key": "bottle",
- "description": "Layer 'Drinking water' shows bottle=yes with a fixed text, namely 'It is easy to refill water bottles' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')",
- "value": "yes"
- },
- {
- "key": "bottle",
- "description": "Layer 'Drinking water' shows bottle=no with a fixed text, namely 'Water bottles may not fit' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')",
- "value": "no"
- },
{
"key": "amenity",
"description": "The MapComplete theme Climbing gyms, clubs and spots has a layer Toilets showing features with this tag",
@@ -3113,12 +3054,12 @@
},
{
"key": "toilets:handwashing",
- "description": "Layer 'Toilets' shows toilets:handwashing=yes with a fixed text, namely 'This toilets have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')",
+ "description": "Layer 'Toilets' shows toilets:handwashing=yes with a fixed text, namely 'These toilets have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')",
"value": "yes"
},
{
"key": "toilets:handwashing",
- "description": "Layer 'Toilets' shows toilets:handwashing=no with a fixed text, namely 'This toilets don't have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')",
+ "description": "Layer 'Toilets' shows toilets:handwashing=no with a fixed text, namely 'These toilets don't have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')",
"value": "no"
},
{
@@ -3134,6 +3075,65 @@
{
"key": "description",
"description": "Layer 'Toilets' shows and asks freeform values for key 'description' (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')"
+ },
+ {
+ "key": "amenity",
+ "description": "The MapComplete theme Climbing gyms, clubs and spots has a layer Drinking water showing features with this tag",
+ "value": "drinking_water"
+ },
+ {
+ "key": "drinking_water",
+ "description": "The MapComplete theme Climbing gyms, clubs and spots has a layer Drinking water showing features with this tag",
+ "value": "yes"
+ },
+ {
+ "key": "id",
+ "description": "Layer 'Drinking water' shows id~.+ with a fixed text, namely 'You just created this element! Thanks for sharing this info with the world and helping people worldwide.' (in the mapcomplete.org theme 'Climbing gyms, clubs and spots') (This is only shown if _backend~.+&_last_edit:passed_time<300&|_version_number=1)"
+ },
+ {
+ "key": "image",
+ "description": "The layer 'Drinking water allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary"
+ },
+ {
+ "key": "mapillary",
+ "description": "The layer 'Drinking water allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary"
+ },
+ {
+ "key": "wikidata",
+ "description": "The layer 'Drinking water allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary"
+ },
+ {
+ "key": "wikipedia",
+ "description": "The layer 'Drinking water allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary"
+ },
+ {
+ "key": "operational_status",
+ "description": "Layer 'Drinking water' shows and asks freeform values for key 'operational_status' (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')"
+ },
+ {
+ "key": "operational_status",
+ "description": "Layer 'Drinking water' shows with a fixed text, namely 'This drinking water works' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots') Picking this answer will delete the key operational_status.",
+ "value": ""
+ },
+ {
+ "key": "operational_status",
+ "description": "Layer 'Drinking water' shows operational_status=broken with a fixed text, namely 'This drinking water is broken' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')",
+ "value": "broken"
+ },
+ {
+ "key": "operational_status",
+ "description": "Layer 'Drinking water' shows operational_status=closed with a fixed text, namely 'This drinking water is closed' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')",
+ "value": "closed"
+ },
+ {
+ "key": "bottle",
+ "description": "Layer 'Drinking water' shows bottle=yes with a fixed text, namely 'It is easy to refill water bottles' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')",
+ "value": "yes"
+ },
+ {
+ "key": "bottle",
+ "description": "Layer 'Drinking water' shows bottle=no with a fixed text, namely 'Water bottles may not fit' and allows to pick this as a default answer (in the mapcomplete.org theme 'Climbing gyms, clubs and spots')",
+ "value": "no"
}
]
}
\ No newline at end of file
diff --git a/Docs/TagInfo/mapcomplete_food.json b/Docs/TagInfo/mapcomplete_food.json
index 16e351db3..61393ab1b 100644
--- a/Docs/TagInfo/mapcomplete_food.json
+++ b/Docs/TagInfo/mapcomplete_food.json
@@ -46,7 +46,7 @@
},
{
"key": "amenity",
- "description": "Layer 'Restaurants and fast food' shows amenity=fast_food with a fixed text, namely 'This is a fastfood-business, focused on fast service. If seating is available, these are rather limited and functional.' and allows to pick this as a default answer (in the mapcomplete.org theme 'Restaurants and fast food')",
+ "description": "Layer 'Restaurants and fast food' shows amenity=fast_food with a fixed text, namely 'This is a fast-food business, focused on fast service. If seating is available, it is rather limited and functional.' and allows to pick this as a default answer (in the mapcomplete.org theme 'Restaurants and fast food')",
"value": "fast_food"
},
{
@@ -172,7 +172,7 @@
},
{
"key": "cuisine",
- "description": "Layer 'Restaurants and fast food' shows cuisine=sandwich with a fixed text, namely 'This is a sandwichbar' and allows to pick this as a default answer (in the mapcomplete.org theme 'Restaurants and fast food')",
+ "description": "Layer 'Restaurants and fast food' shows cuisine=sandwich with a fixed text, namely 'This is a sandwich shop' and allows to pick this as a default answer (in the mapcomplete.org theme 'Restaurants and fast food')",
"value": "sandwich"
},
{
@@ -192,7 +192,7 @@
},
{
"key": "cuisine",
- "description": "Layer 'Restaurants and fast food' shows cuisine=italian with a fixed text, namely 'This is an italian restaurant (which serves more then pasta and pizza)' and allows to pick this as a default answer (in the mapcomplete.org theme 'Restaurants and fast food')",
+ "description": "Layer 'Restaurants and fast food' shows cuisine=italian with a fixed text, namely 'This is an Italian restaurant (which serves more than pasta and pizza)' and allows to pick this as a default answer (in the mapcomplete.org theme 'Restaurants and fast food')",
"value": "italian"
},
{
diff --git a/Docs/TagInfo/mapcomplete_fritures.json b/Docs/TagInfo/mapcomplete_fritures.json
index c3de637cd..9d245b2d5 100644
--- a/Docs/TagInfo/mapcomplete_fritures.json
+++ b/Docs/TagInfo/mapcomplete_fritures.json
@@ -50,7 +50,7 @@
},
{
"key": "amenity",
- "description": "Layer 'Fries shop' shows amenity=fast_food with a fixed text, namely 'This is a fastfood-business, focused on fast service. If seating is available, these are rather limited and functional.' and allows to pick this as a default answer (in the mapcomplete.org theme 'Fries shops')",
+ "description": "Layer 'Fries shop' shows amenity=fast_food with a fixed text, namely 'This is a fast-food business, focused on fast service. If seating is available, it is rather limited and functional.' and allows to pick this as a default answer (in the mapcomplete.org theme 'Fries shops')",
"value": "fast_food"
},
{
@@ -176,7 +176,7 @@
},
{
"key": "cuisine",
- "description": "Layer 'Fries shop' shows cuisine=sandwich with a fixed text, namely 'This is a sandwichbar' and allows to pick this as a default answer (in the mapcomplete.org theme 'Fries shops')",
+ "description": "Layer 'Fries shop' shows cuisine=sandwich with a fixed text, namely 'This is a sandwich shop' and allows to pick this as a default answer (in the mapcomplete.org theme 'Fries shops')",
"value": "sandwich"
},
{
@@ -196,7 +196,7 @@
},
{
"key": "cuisine",
- "description": "Layer 'Fries shop' shows cuisine=italian with a fixed text, namely 'This is an italian restaurant (which serves more then pasta and pizza)' and allows to pick this as a default answer (in the mapcomplete.org theme 'Fries shops')",
+ "description": "Layer 'Fries shop' shows cuisine=italian with a fixed text, namely 'This is an Italian restaurant (which serves more than pasta and pizza)' and allows to pick this as a default answer (in the mapcomplete.org theme 'Fries shops')",
"value": "italian"
},
{
diff --git a/Docs/TagInfo/mapcomplete_nature.json b/Docs/TagInfo/mapcomplete_nature.json
index d6a050921..c18dadfa7 100644
--- a/Docs/TagInfo/mapcomplete_nature.json
+++ b/Docs/TagInfo/mapcomplete_nature.json
@@ -1067,12 +1067,12 @@
},
{
"key": "toilets:handwashing",
- "description": "Layer 'Toilets' shows toilets:handwashing=yes with a fixed text, namely 'This toilets have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Into nature')",
+ "description": "Layer 'Toilets' shows toilets:handwashing=yes with a fixed text, namely 'These toilets have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Into nature')",
"value": "yes"
},
{
"key": "toilets:handwashing",
- "description": "Layer 'Toilets' shows toilets:handwashing=no with a fixed text, namely 'This toilets don't have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Into nature')",
+ "description": "Layer 'Toilets' shows toilets:handwashing=no with a fixed text, namely 'These toilets don't have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Into nature')",
"value": "no"
},
{
diff --git a/Docs/TagInfo/mapcomplete_onwheels.json b/Docs/TagInfo/mapcomplete_onwheels.json
index 6a66894ad..0ee4b5b13 100644
--- a/Docs/TagInfo/mapcomplete_onwheels.json
+++ b/Docs/TagInfo/mapcomplete_onwheels.json
@@ -556,7 +556,7 @@
},
{
"key": "amenity",
- "description": "Layer 'Restaurants and fast food' shows amenity=fast_food with a fixed text, namely 'This is a fastfood-business, focused on fast service. If seating is available, these are rather limited and functional.' and allows to pick this as a default answer (in the mapcomplete.org theme 'OnWheels')",
+ "description": "Layer 'Restaurants and fast food' shows amenity=fast_food with a fixed text, namely 'This is a fast-food business, focused on fast service. If seating is available, it is rather limited and functional.' and allows to pick this as a default answer (in the mapcomplete.org theme 'OnWheels')",
"value": "fast_food"
},
{
@@ -682,7 +682,7 @@
},
{
"key": "cuisine",
- "description": "Layer 'Restaurants and fast food' shows cuisine=sandwich with a fixed text, namely 'This is a sandwichbar' and allows to pick this as a default answer (in the mapcomplete.org theme 'OnWheels')",
+ "description": "Layer 'Restaurants and fast food' shows cuisine=sandwich with a fixed text, namely 'This is a sandwich shop' and allows to pick this as a default answer (in the mapcomplete.org theme 'OnWheels')",
"value": "sandwich"
},
{
@@ -702,7 +702,7 @@
},
{
"key": "cuisine",
- "description": "Layer 'Restaurants and fast food' shows cuisine=italian with a fixed text, namely 'This is an italian restaurant (which serves more then pasta and pizza)' and allows to pick this as a default answer (in the mapcomplete.org theme 'OnWheels')",
+ "description": "Layer 'Restaurants and fast food' shows cuisine=italian with a fixed text, namely 'This is an Italian restaurant (which serves more than pasta and pizza)' and allows to pick this as a default answer (in the mapcomplete.org theme 'OnWheels')",
"value": "italian"
},
{
@@ -2479,12 +2479,12 @@
},
{
"key": "toilets:handwashing",
- "description": "Layer 'Toilets' shows toilets:handwashing=yes with a fixed text, namely 'This toilets have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'OnWheels')",
+ "description": "Layer 'Toilets' shows toilets:handwashing=yes with a fixed text, namely 'These toilets have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'OnWheels')",
"value": "yes"
},
{
"key": "toilets:handwashing",
- "description": "Layer 'Toilets' shows toilets:handwashing=no with a fixed text, namely 'This toilets don't have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'OnWheels')",
+ "description": "Layer 'Toilets' shows toilets:handwashing=no with a fixed text, namely 'These toilets don't have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'OnWheels')",
"value": "no"
},
{
diff --git a/Docs/TagInfo/mapcomplete_pets.json b/Docs/TagInfo/mapcomplete_pets.json
index e45385925..3d0796117 100644
--- a/Docs/TagInfo/mapcomplete_pets.json
+++ b/Docs/TagInfo/mapcomplete_pets.json
@@ -120,7 +120,7 @@
},
{
"key": "amenity",
- "description": "Layer 'Dog friendly eateries' shows amenity=fast_food with a fixed text, namely 'This is a fastfood-business, focused on fast service. If seating is available, these are rather limited and functional.' and allows to pick this as a default answer (in the mapcomplete.org theme 'Veterinarians, dog parks and other pet-amenities')",
+ "description": "Layer 'Dog friendly eateries' shows amenity=fast_food with a fixed text, namely 'This is a fast-food business, focused on fast service. If seating is available, it is rather limited and functional.' and allows to pick this as a default answer (in the mapcomplete.org theme 'Veterinarians, dog parks and other pet-amenities')",
"value": "fast_food"
},
{
@@ -246,7 +246,7 @@
},
{
"key": "cuisine",
- "description": "Layer 'Dog friendly eateries' shows cuisine=sandwich with a fixed text, namely 'This is a sandwichbar' and allows to pick this as a default answer (in the mapcomplete.org theme 'Veterinarians, dog parks and other pet-amenities')",
+ "description": "Layer 'Dog friendly eateries' shows cuisine=sandwich with a fixed text, namely 'This is a sandwich shop' and allows to pick this as a default answer (in the mapcomplete.org theme 'Veterinarians, dog parks and other pet-amenities')",
"value": "sandwich"
},
{
@@ -266,7 +266,7 @@
},
{
"key": "cuisine",
- "description": "Layer 'Dog friendly eateries' shows cuisine=italian with a fixed text, namely 'This is an italian restaurant (which serves more then pasta and pizza)' and allows to pick this as a default answer (in the mapcomplete.org theme 'Veterinarians, dog parks and other pet-amenities')",
+ "description": "Layer 'Dog friendly eateries' shows cuisine=italian with a fixed text, namely 'This is an Italian restaurant (which serves more than pasta and pizza)' and allows to pick this as a default answer (in the mapcomplete.org theme 'Veterinarians, dog parks and other pet-amenities')",
"value": "italian"
},
{
diff --git a/Docs/TagInfo/mapcomplete_toilets.json b/Docs/TagInfo/mapcomplete_toilets.json
index e0f513297..6054927a7 100644
--- a/Docs/TagInfo/mapcomplete_toilets.json
+++ b/Docs/TagInfo/mapcomplete_toilets.json
@@ -226,12 +226,12 @@
},
{
"key": "toilets:handwashing",
- "description": "Layer 'Toilets' shows toilets:handwashing=yes with a fixed text, namely 'This toilets have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Public toilets')",
+ "description": "Layer 'Toilets' shows toilets:handwashing=yes with a fixed text, namely 'These toilets have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Public toilets')",
"value": "yes"
},
{
"key": "toilets:handwashing",
- "description": "Layer 'Toilets' shows toilets:handwashing=no with a fixed text, namely 'This toilets don't have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Public toilets')",
+ "description": "Layer 'Toilets' shows toilets:handwashing=no with a fixed text, namely 'These toilets don't have a sink to wash your hands' and allows to pick this as a default answer (in the mapcomplete.org theme 'Public toilets')",
"value": "no"
},
{
diff --git a/Docs/TagInfo/mapcomplete_vending_machine.json b/Docs/TagInfo/mapcomplete_vending_machine.json
index f71c8e6db..12eedf701 100644
--- a/Docs/TagInfo/mapcomplete_vending_machine.json
+++ b/Docs/TagInfo/mapcomplete_vending_machine.json
@@ -119,6 +119,16 @@
"description": "Layer 'Vending Machines' shows vending=meat with a fixed text, namely 'Meat is sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Vending Machines')",
"value": "meat"
},
+ {
+ "key": "vending",
+ "description": "Layer 'Vending Machines' shows vending=fruit with a fixed text, namely 'Fruit is sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Vending Machines')",
+ "value": "fruit"
+ },
+ {
+ "key": "vending",
+ "description": "Layer 'Vending Machines' shows vending=strawberries with a fixed text, namely 'Strawberries are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Vending Machines')",
+ "value": "strawberries"
+ },
{
"key": "vending",
"description": "Layer 'Vending Machines' shows vending=flowers with a fixed text, namely 'Flowers are sold' and allows to pick this as a default answer (in the mapcomplete.org theme 'Vending Machines')",
@@ -403,6 +413,14 @@
{
"key": "contact:phone",
"description": "Layer 'Vending Machines' shows contact:phone~.+ with a fixed text, namely '{contact:phone}' (in the mapcomplete.org theme 'Vending Machines')"
+ },
+ {
+ "key": "website",
+ "description": "Layer 'Vending Machines' shows and asks freeform values for key 'website' (in the mapcomplete.org theme 'Vending Machines')"
+ },
+ {
+ "key": "contact:website",
+ "description": "Layer 'Vending Machines' shows contact:website~.+ with a fixed text, namely '{contact:website}' (in the mapcomplete.org theme 'Vending Machines')"
}
]
}
\ No newline at end of file
diff --git a/Docs/Themes/climbing.md b/Docs/Themes/climbing.md
index 32f4a6379..97a8cba0b 100644
--- a/Docs/Themes/climbing.md
+++ b/Docs/Themes/climbing.md
@@ -18,8 +18,9 @@ This theme contains the following layers:
- [climbing_opportunity](../Layers/climbing_opportunity.md)
- [shops_with_climbing_shoe_repair](../Layers/shops_with_climbing_shoe_repair.md)
- [shops](../Layers/shops.md)
- - [drinking_water](../Layers/drinking_water.md)
- [toilet](../Layers/toilet.md)
+ - [drinking_water](../Layers/drinking_water.md)
+ - [guidepost](../Layers/guidepost.md)
- [selected_element](../Layers/selected_element.md)
- [gps_location](../Layers/gps_location.md)
- [gps_location_history](../Layers/gps_location_history.md)
diff --git a/Docs/URL_Parameters.md b/Docs/URL_Parameters.md
index 277293bfc..be2086659 100644
--- a/Docs/URL_Parameters.md
+++ b/Docs/URL_Parameters.md
@@ -11,7 +11,6 @@
- [What is a URL parameter?](#what-is-a-url-parameter)
- [language](#language)
- [fs-translation-mode](#fs-translation-mode)
- - [backend](#backend)
- [fake-user](#fake-user)
- [fs-enable-login](#fs-enable-login)
- [fs-search](#fs-search)
@@ -119,23 +118,12 @@ This documentation is defined in the source code at [Locale.ts](/src/UI/i18n/Loc
- backend
----------
-
- The OSM backend to use - can be used to redirect mapcomplete to the testing backend when using 'osm-test'
-
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L34)
-
- The default value is _osm_
-
-
-
fake-user
-----------
If true, 'dryrun' mode is activated and a fake user account is loaded
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L40)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L33)
The default value is _false_
@@ -146,7 +134,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Disables/Enables logging in and thus disables editing all together. This effectively puts MapComplete into read-only mode.
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L80)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L73)
The default value is _true_
@@ -157,7 +145,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Disables/Enables the search bar
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L85)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L78)
The default value is _true_
@@ -168,7 +156,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Disables/Enables the background layer control
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L90)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L83)
The default value is _true_
@@ -179,7 +167,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Disables/Enables the filter view
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L96)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L89)
The default value is _true_
@@ -190,7 +178,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Disables/enables the help menu or welcome message
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L102)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L95)
The default value is _true_
@@ -201,7 +189,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Disables/enables the button to get in touch with the community
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L107)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L100)
The default value is _true_
@@ -212,7 +200,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Disables/Enables the extraLink button. By default, if in iframe mode and the welcome message is hidden, a popout button to the full mapcomplete instance is shown instead (unless disabled with this switch or another extraLink button is enabled)
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L112)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L105)
The default value is _true_
@@ -223,7 +211,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Disables/Enables the 'More Quests'-tab in the welcome message
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L117)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L110)
The default value is _true_
@@ -234,7 +222,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Disables/Enables the 'Share-screen'-tab in the welcome message
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L122)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L115)
The default value is _true_
@@ -245,7 +233,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Disables/Enables the geolocation button
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L127)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L120)
The default value is _true_
@@ -256,7 +244,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Always show all questions
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L132)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L125)
The default value is _false_
@@ -267,7 +255,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Enable the export as GeoJSON and CSV button
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L138)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L131)
The default value is _true_
@@ -278,7 +266,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L153)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L145)
The default value is _false_
@@ -289,7 +277,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
If true, shows some extra debugging help such as all the available tags on every object
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L159)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L151)
The default value is _false_
@@ -300,7 +288,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Point mapcomplete to a different overpass-instance. Example: https://overpass-api.de/api/interpreter
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L165)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L157)
The default value is _https://overpass-api.de/api/interpreter,https://overpass.kumi.systems/api/interpreter,https://overpass.openstreetmap.ru/cgi/interpreter_
@@ -311,7 +299,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Set a different timeout (in seconds) for queries in overpass
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L176)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L168)
The default value is _30_
@@ -322,7 +310,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
point to switch between OSM-api and overpass
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L184)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L176)
The default value is _16_
@@ -333,7 +321,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
Tilesize when the OSM-API is used to fetch data within a BBOX
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L192)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L184)
The default value is _17_
@@ -344,7 +332,7 @@ This documentation is defined in the source code at [FeatureSwitchState.ts](/src
The id of the background layer to start with
-This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L199)
+This documentation is defined in the source code at [FeatureSwitchState.ts](/src/Logic/State/FeatureSwitchState.ts#L191)
No default value set
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 1f629e4e9..35b863823 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
@@ -33,7 +33,9 @@
{
"if": "name~*",
"then": {
- "en": "Bicycle tube vending machine {name}"
+ "en": "Bicycle tube vending machine {name}",
+ "ca": "Màquina expenedora de cambres d'aire de bicicletes {name}",
+ "de": "{name} Fahrradschlauch-Automat"
}
}
]
@@ -178,10 +180,14 @@
},
{
"question": {
- "en": "How much does a bicycle tube cost?"
+ "en": "How much does a bicycle tube cost?",
+ "ca": "Quant costa una cambra d'aire de bicicleta?",
+ "de": "Wie viel kostet ein Fahrradschlauch?"
},
"render": {
- "en": "A bicycle tube costs {charge}"
+ "en": "A bicycle tube costs {charge}",
+ "ca": "Una cambra d'aire de bicicleta costa {charge}",
+ "de": "Ein Fahrradschlauch kostet {charge}"
},
"freeform": {
"key": "charge"
@@ -191,25 +197,33 @@
"payment-options-split",
{
"question": {
- "en": "Which brand of tubes are sold here?"
+ "en": "Which brand of tubes are sold here?",
+ "ca": "Quines marques de cambres d'aire es venen aquí?",
+ "de": "Welche Fahrradschläuche werden hier verkauft?"
},
"freeform": {
"key": "brand"
},
"render": {
- "en": "{brand} tubes are sold here"
+ "en": "{brand} tubes are sold here",
+ "ca": "Aquí es venen cambres d'aire {brand}",
+ "de": "Hier werden Fahrradschläuche von {brand} verkauft"
},
"mappings": [
{
"if": "brand=Continental",
"then": {
- "en": "Continental tubes are sold here"
+ "en": "Continental tubes are sold here",
+ "ca": "Aquí es venen cambres d'aire Continental",
+ "de": "Hier werden Fahrradschläuche von Continental verkauft"
}
},
{
"if": "brand=Schwalbe",
"then": {
- "en": "Schwalbe tubes are sold here"
+ "en": "Schwalbe tubes are sold here",
+ "ca": "Aquí es venen cambres d'aire Schwalbe",
+ "de": "Hier werden Fahrradschläuche von Schwalbe verkauft"
}
}
],
@@ -218,20 +232,26 @@
},
{
"question": {
- "en": "Who maintains this vending machine?"
+ "en": "Who maintains this vending machine?",
+ "ca": "Qui manté aquesta màquina expenedora?",
+ "de": "Wer betreibt den Automaten?"
},
"render": "This vending machine is maintained by {operator}",
"mappings": [
{
"if": "operator=Schwalbe",
"then": {
- "en": "Maintained by Schwalbe"
+ "en": "Maintained by Schwalbe",
+ "ca": "Mantés per Schwalbe",
+ "de": "Betrieben von Schwalbe"
}
},
{
"if": "operator=Continental",
"then": {
- "en": "Maintained by Continental"
+ "en": "Maintained by Continental",
+ "ca": "Mantés per Continental",
+ "de": "Betrieben von Continental"
}
}
],
@@ -243,49 +263,63 @@
{
"id": "other-items-vending",
"question": {
- "en": "Are other biycle accessories sold here?"
+ "en": "Are other biycle accessories sold here?",
+ "ca": "Es venen altres accessoris per a bicicletes aquí?",
+ "de": "Wird weiteres Fahrradzubehör verkauft?"
},
"mappings": [
{
"if": "vending=bicycle_tube",
"then": {
"en": "Bicycle inner tubes are sold here",
- "nl": "Fietsbinnenbanden worden hier verkocht"
+ "nl": "Fietsbinnenbanden worden hier verkocht",
+ "ca": "Aquí es venen cambres d'aire de bicicletes",
+ "de": "Hier werden Fahrradschläuche verkauft"
}
},
{
"if": "vending=bicycle_light",
"then": {
"en": "Bicycle lights are sold here",
- "nl": "Fietslampjes worden hier verkocht"
+ "nl": "Fietslampjes worden hier verkocht",
+ "ca": "Aquí es venen llums per a bicicletes",
+ "de": "Hier werden Fahrradlampen verkauft"
}
},
{
"if": "vending=gloves",
"then": {
"en": "Gloves are sold here",
- "nl": "Handschoenen worden hier verkocht"
+ "nl": "Handschoenen worden hier verkocht",
+ "ca": "Aquí es venen guants",
+ "de": "Hier werden Fahrradhandschuhe verkauft"
}
},
{
"if": "vending=bicycle_repair_kit",
"then": {
"en": "Bicycle repair kits are sold here",
- "nl": "Fietsreparatiesets worden hier verkocht"
+ "nl": "Fietsreparatiesets worden hier verkocht",
+ "ca": "Aquí es venen kits de reparació de bicicletes",
+ "de": "Hier werden Fahrrad-Reparatursets verkauft"
}
},
{
"if": "vending=bicycle_pump",
"then": {
"en": "Bicycle pumps are sold here",
- "nl": "Fietspompen worden hier verkocht"
+ "nl": "Fietspompen worden hier verkocht",
+ "ca": "Aquí es venen bombes de bicicletes",
+ "de": "Hier werden Fahrradpumpen verkauft"
}
},
{
"if": "vending=bicycle_lock",
"then": {
"en": "Bicycle locks are sold here",
- "nl": "Fietssloten worden hier verkocht"
+ "nl": "Fietssloten worden hier verkocht",
+ "ca": "Aquí es venen cadenats per a bicicletes",
+ "de": "Hier werden Fahrradschlösser verkauft"
}
}
],
diff --git a/assets/layers/cafe_pub/cafe_pub.json b/assets/layers/cafe_pub/cafe_pub.json
index 32d2fe11d..7f1ca5141 100644
--- a/assets/layers/cafe_pub/cafe_pub.json
+++ b/assets/layers/cafe_pub/cafe_pub.json
@@ -293,10 +293,13 @@
"internet-ssid",
"reviews"
],
+ "minzoom": 12,
"filter": [
"open_now",
"accepts_cash",
- "accepts_cards"
+ "accepts_cards",
+ "has_internet",
+ "has_electricity"
],
"deletion": {
"softDeletionTags": {
diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json
index a9c448a47..6246457f4 100644
--- a/assets/layers/charging_station/charging_station.json
+++ b/assets/layers/charging_station/charging_station.json
@@ -889,7 +889,7 @@
"then": {
"en": "Tesla Supercharger CCS (a branded type2_css)",
"nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo)",
- "ca": "CSS Supercarregador Tesla (un tipus2_css de la marca)",
+ "ca": "CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css)",
"da": "Tesla Supercharger CCS (en mærkevare type2_css)",
"de": "Tesla Supercharger CCS (Typ 2 CSS von Tesla)",
"es": "CCS Supercargador Tesla (un tipo2_css con marca)"
@@ -935,7 +935,7 @@
"then": {
"en": "Tesla Supercharger CCS (a branded type2_css)",
"nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo)",
- "ca": "CSS Supercarregador Tesla (un tipus2_css de la marca)",
+ "ca": "CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css)",
"da": "Tesla Supercharger CCS (en mærkevare type2_css)",
"de": "Tesla Supercharger CCS (ein Markenzeichen von type2_css)",
"es": "CCS Supercargador Tesla (un tipo2_css con marca)"
@@ -1244,12 +1244,14 @@
"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?",
+ "ca": "Quants connectors del tipus
Endoll de paret Schuko sense pin de terra (CEE7/4 tipus F)
hi han disponibles aquí?",
"da": "Hvor mange stik af typen
Schuko vægstik uden jordstift (CEE7/4 type F)
er tilgængelige her?",
"de": "Wie viele Stecker vom Typ
Schuko-Stecker ohne Erdungsstift (CEE7/4 Typ F)
sind hier vorhanden?"
},
"render": {
"en": "There are {socket:schuko} plugs of type
Schuko wall plug without ground pin (CEE7/4 type F)
available here",
"nl": "Hier zijn {socket:schuko} stekkers van het type
Schuko stekker zonder aardingspin (CEE7/4 type F)
",
+ "ca": "Hi ha {socket:schuko} connectors del tipus
Endoll de paret Schuko sense pin de terra (CEE7/4 tipus F)
disponibles aquí",
"da": "Der findes {socket:schuko} stik af typen
Schuko-vægstik uden jord (CEE7/4 type F)
her",
"de": "Hier sind {socket:schuko} Stecker des Typs
Schuko-Stecker ohne Erdungsstift (CEE7/4 Typ F)
vorhanden"
},
@@ -1269,12 +1271,14 @@
"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?",
+ "ca": "Quants connectors del tipus
Endoll de paret Europeu amb pin de terra (CEE7/4 tipus E)
hi han disponibles aquí?",
"da": "Hvor mange stik af typen
Europæisk vægstik med jord (CEE7/4 type E)
er tilgængelige her?",
"de": "Wie viele Stecker des Typs
Europäischer Wandstecker mit Erdungsstift (CEE7/4 Typ E)
sind hier vorhanden?"
},
"render": {
"en": "There are {socket:typee} plugs of type
European wall plug with ground pin (CEE7/4 type E)
available here",
"nl": "Hier zijn {socket:typee} stekkers van het type
Europese stekker met aardingspin (CEE7/4 type E)
",
+ "ca": "Hi ha {socket:typee} connectors del tipus
Endoll de paret europeu amb pin de terra (CEE7/4 tipus E)
disponibles aquí",
"da": "Der findes {socket:typee} stik af typen
Europæisk vægstik med jord (CEE7/4 type E)
her",
"de": "Hier sind {socket:typee} Stecker des Typs
Europäischer Wandstecker mit Erdungsstift (CEE7/4 Typ E)
vorhanden"
},
@@ -1488,12 +1492,14 @@
"question": {
"en": "How much plugs of type
Tesla Supercharger CCS (a branded type2_css)
are available here?",
"nl": "Hoeveel stekkers van type
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
heeft dit oplaadpunt?",
+ "ca": "Quants connectors del tipus
CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css)
hi han disponibles aquí?",
"da": "Hvor mange stik af typen
Tesla Supercharger CCS (en mærkevare type2_css)
er tilgængelige her?",
"de": "Wie viele Stecker des Typs
Tesla Supercharger CCS (Typ 2 CSS von Tesla)
sind hier vorhanden?"
},
"render": {
"en": "There are {socket:tesla_supercharger_ccs} plugs of type
Tesla Supercharger CCS (a branded type2_css)
available here",
"nl": "Hier zijn {socket:tesla_supercharger_ccs} stekkers van het type
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
",
+ "ca": "Hi ha {socket:tesla_supercharger_ccs} connectors
Supercarregadro Tesla CCS (un cable de la marca Tesla Tipus2_css)
disponibles aquí",
"de": "Hier sind {socket:tesla_supercharger_ccs} Stecker des Typs
Tesla Supercharger CCS (Typ2 CSS von Tesla)
vorhanden"
},
"freeform": {
@@ -1676,13 +1682,14 @@
"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)
?",
- "ca": "Quina intensitat ofereixen els endolls amb
de paret Shuko sense pin de terra (CEE7/4 tipus F)
?",
+ "ca": "Quina intensitat ofereixen els connectors amb
endolls de paret Schuko sense pin de terra (CEE7/4 tipus F)
?",
"da": "Hvilken strømstyrke har stikkene med
Schuko-vægstik uden jordstift (CEE7/4 type F)
?",
"de": "Welche Stromstärke liefern die Anschlüsse mit
Schuko-Stecker ohne Schutzkontakt (CEE7/4 Typ 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",
+ "ca": "
L'endoll de paret Schuko sense pin de terra (CEE7/4 tipus F)
surt com a màxim a {socket:schuko:current}A",
"da": "
Schuko vægstik uden jord (CEE7/4 type F)
udgange højst {socket:schuko:current}A",
"de": "
Schuko-Stecker ohne Erdungsstift (CEE7/4 Typ F)
liefert maximal {socket:schuko:current} A"
},
@@ -1804,12 +1811,14 @@
"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)
?",
+ "ca": "Quina intensitat ofereixen els connectors amb
endolls de paret europeu amb pin de terra (CEE7/4 tipus F)
?",
"da": "Hvilken strømstyrke har stikkene med
Europæisk vægstik med jord (CEE7/4 type E)
?",
"de": "Welche Stromstärke bieten die Anschlüsse mit
europäischem Stecker mit Schutzkontakt (CEE7/4 Typ 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",
+ "ca": "
L'endoll de paret europeu amb pin de terra (CEE7/4 tipus F)
surt com a màxim a {socket:typee:current}A",
"da": "
Europæisk vægstik med jord (CEE7/4 type E)
udgange på højst {socket:typee:current}A",
"de": "
Europäischer Wandstecker mit Erdungsstift (CEE7/4 Typ E)
liefert maximal {socket:typee:current} A"
},
@@ -1823,6 +1832,7 @@
"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",
+ "ca": "Endoll de paret europeu amb pin de terra (CEE7/4 type E) surt com a màxim a 16A",
"da": "Europæisk vægstik med jord (CEE7/4 type E) yder højst 16 A",
"de": "Europäischer Wandstecker mit Erdungsstift (CEE7/4 Typ E) liefert maximal 16 A"
},
@@ -1951,6 +1961,7 @@
"render": {
"en": "
Chademo
outputs at most {socket:chademo:current}A",
"nl": "
Chademo
levert een stroom van maximaal {socket:chademo:current}A",
+ "ca": "
Chademo
surt com a màxim a {socket:chademo:current}A",
"de": "
Chademo
liefert maximal {socket:chademo:current} A"
},
"freeform": {
@@ -2081,12 +2092,14 @@
"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)
?",
+ "ca": "Quina corrent ofereixen els connectors
Tipus 1 amb cable (J1772)
?",
"da": "Hvilken strømstyrke har stikkene med
Type 1 med kabel (J1772)
(J1772)?",
"de": "Welche Stromstärke liefern die Stecker mit
Typ 1 mit 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",
+ "ca": "
Tipus 1 amb cable (J1772)
surt com a màxim a {socket:type1_cable:current}A",
"da": "
Type 1 med kabel (J1772)
udgange på højst {socket:type1_cable:current}A",
"de": "
Typ 1 mit Kabel (J1772)
liefert maximal {socket:type1_cable:current} A"
},
@@ -2100,6 +2113,7 @@
"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",
+ "ca": "Tipus 1 amb cable (J1772) surt com a màxim a 32A",
"da": "Type 1 med kabel (J1772) yder højst 32 A",
"de": "Typ 1 mit Kabel (J1772) liefert maximal 32 A"
},
@@ -2228,12 +2242,14 @@
"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)
?",
+ "ca": "Quina corrent ofereixen els connectors
Tipus 1 sense cable (J1772)
?",
"da": "Hvilken strømstyrke har stikkene med
Type 1 uden kabel (J1772)
?",
"de": "Welche Stromstärke liefern die Stecker mit
Typ 1 ohne 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",
+ "ca": "
Tipus 1 sense cable(J1772)
surt com a màxim a {socket:type1:current}A",
"da": "
Type 1 uden kabel (J1772)
udgange højst {socket:type1:current}A",
"de": "
Typ 1 ohne Kabel (J1772)
liefert maximal {socket:type1:current} A"
},
@@ -2247,6 +2263,7 @@
"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",
+ "ca": "Tipus 1 sense cable (J1772) surt com a màxim a 32A",
"da": " Type 1 uden-kabel (J1772)-udgange højst 32 A",
"de": "Typ 1 ohne Kabel (J1772) liefert maximal 32 A"
},
@@ -2399,12 +2416,14 @@
"question": {
"en": "What current do the plugs with
Type 1 CCS (aka Type 1 Combo)
offer?",
"nl": "Welke stroom levert de stekker van type
Type 1 CCS (ook gekend als Type 1 Combo)
?",
+ "ca": "Quina intensitat ofereixen els connectors
Tipus 1 CCS (també Tipus 1 Combo)
?",
"da": "Hvilken strømstyrke giver stikkene med
Type 1 CCS (også kendt som Type 1 Combo)
?",
"de": "Welche Stromstärke liefern die Stecker mit
Typ 1 CCS (Typ 1 Combo)
?"
},
"render": {
"en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most {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",
+ "ca": "
Tipus 1 CCS (també Tipus 1 Combo)
surt com a màxim a {socket:type1_combo:current}A",
"da": "
liefern maximal {socket:type2_combo:current} A"
},
@@ -3060,12 +3088,14 @@
"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)
?",
+ "ca": "Quina intensitat ofereixen els connectors
Tipus 2 amb cable (mennekes)
?",
"da": "Hvilken strømstyrke har stikkene med
Type 2 med kabel (mennekes)
?",
"de": "Welche Stromstärke liefern die Stecker mit
Typ 2 mit Kabel (Mennekes)
?"
},
"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",
+ "ca": "
Tipus 2 amb cable (mennekes)
surt com a màxim a {socket:type2_cable:current}A",
"de": "
Typ 2 mit Kabel (Mennekes)
liefert maximal {socket:type2_cable:current} A"
},
"freeform": {
@@ -3078,6 +3108,7 @@
"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",
+ "ca": "Tipus 2 amb cable (mennekes) surt com a màxim a 16A",
"da": "Type 2 med kabel (mennekes) udgange på højst 16 A",
"de": "Typ 2 mit Kabel (Mennekes) liefert maximal 16 A"
},
@@ -3091,6 +3122,7 @@
"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",
+ "ca": "Tipus 2 amb cable (mennekes) surt com a màxim a 32A",
"da": "Type 2 med kabel (mennekes) udgange på højst 32 A",
"de": "Typ 2 mit Kabel (Mennekes) liefert maximal 32 A"
},
@@ -3219,12 +3251,14 @@
"question": {
"en": "What current do the plugs with
Tesla Supercharger CCS (a branded type2_css)
offer?",
"nl": "Welke stroom levert de stekker van type
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
?",
+ "ca": "Quina corrent ofereixen els connectors
CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css)
?",
"da": "Hvilken strømstyrke har stikkene med
Tesla Supercharger CCS (en type2_css af mærketype2_css)
?",
"de": "Welche Stromstärke bieten die Anschlüsse mit
Tesla Supercharger CCS (Typ2 CSS von Tesla)
?"
},
"render": {
"en": "
Tesla Supercharger CCS (a branded type2_css)
outputs at most {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",
+ "ca": "
CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css)
surt com a màxim a {socket:tesla_supercharger_ccs:current}A",
"da": "
liefert maximal {socket:tesla_supercharger_ccs:current} A"
},
@@ -3238,6 +3272,7 @@
"then": {
"en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 125 A",
"nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) levert een stroom van maximaal 125 A",
+ "ca": "CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css) surt com a màxim a 125A",
"da": "Tesla Supercharger CCS (en mærkevare type2_css) yder højst 125 A",
"de": "Tesla Supercharger CCS (Typ 2 CSS) liefert maximal 125 A"
},
@@ -3251,6 +3286,7 @@
"then": {
"en": "Tesla Supercharger CCS (a branded type2_css) outputs at most 350 A",
"nl": "Tesla Supercharger CCS (een type2 CCS met Tesla-logo) levert een stroom van maximaal 350 A",
+ "ca": "CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css) surt com a màxim a 350A",
"da": "Tesla Supercharger CCS (en mærkevare type2_css) yder højst 350 A",
"de": "Tesla Supercharger CCS (Typ 2 CSS) liefert maximal 350 A"
},
@@ -3355,14 +3391,14 @@
"question": {
"en": "What current do the plugs with
Tesla Supercharger (Destination)
offer?",
"nl": "Welke stroom levert de stekker van type
Tesla Supercharger (Destination)
?",
- "ca": "Quin corrent fan els endolls amb
Tesla Supercharger (Destination)
offer?",
+ "ca": "Quina intensitat ofereixen els connectors
Supercarregador Tesla (Destí)
?",
"da": "Hvilken strømstyrke har stikkene med
Tesla Supercharger (Destination)
med Tesla Supercharger (Destination) ?",
"de": "Welche Stromstärke liefern die Anschlüsse mit
Tesla Supercharger (Destination)
?"
},
"render": {
"en": "
Tesla Supercharger (Destination)
outputs at most {socket:tesla_destination:current}A",
"nl": "
Tesla Supercharger (Destination)
levert een stroom van maximaal {socket:tesla_destination:current}A",
- "ca": "
Tesla Supercharger (Destinació)
sortida com a màxim {socket:tesla_destination:current}A",
+ "ca": "
Supercarregador Tesla (Destí)
surt com a màxim a {socket:tesla_destination:current}A",
"da": "
liefert maximal {socket:tesla_destination:current} A"
},
@@ -3376,7 +3412,7 @@
"then": {
"en": "Tesla Supercharger (Destination) outputs at most 125 A",
"nl": "Tesla Supercharger (destination) levert een stroom van maximaal 125 A",
- "ca": "Tesla Supercharger (Destinació) emet com a màxim 125 A",
+ "ca": "Supercarregador Tesla (Destí) surt com a màxim a 125 A",
"de": "Tesla Supercharger (Destination) liefert maximal 125 A"
},
"icon": {
@@ -3389,7 +3425,7 @@
"then": {
"en": "Tesla Supercharger (Destination) outputs at most 350 A",
"nl": "Tesla Supercharger (destination) levert een stroom van maximaal 350 A",
- "ca": "Tesla Supercharger (Destinació) emet com a màxim 350 A",
+ "ca": "Supercarregdor Tesla (Destinació) surt com a màxim a 350 A",
"de": "Tesla Supercharger (Destination) liefert maximal 350 A"
},
"icon": {
@@ -3529,13 +3565,14 @@
"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
Tesla Supercharger (Destination) (Een Type 2 met kabel en Tesla-logo)
?",
- "ca": "Quin corrent donen els endolls amb
Tesla Supercharger (destinació) (un tipus 2 amb cable amb la marca Tesla)
oferta?",
+ "ca": "Quina intensitat ofereixen els connectors
Supercarregador Tesla (Destí) (un tipus 2 amb cable amb la marca Tesla)
?",
"da": "Hvilken strømstyrke har stikkene med
Tesla Supercharger (Destination) (A Type 2 med kabel med Tesla-mærket)
?",
"de": "Welche Stromstärke liefern die Stecker mit
Tesla Supercharger (Destination) (Typ 2 mit Kabel von Tesla)
?"
},
"render": {
"en": "
Tesla Supercharger (Destination) (A Type 2 with cable branded as Tesla)
outputs at most {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",
+ "ca": "
Supercarregador Tesla (Destí) (un tipus 2 amb cable amb la marca Tesla)
surt com a màxim a {socket:tesla_destination:current}A",
"de": "
Tesla Supercharger (Destination) (Typ 2 mit Kabel von Tesla)
liefert maximal {socket:tesla_destination:current} A"
},
"freeform": {
@@ -3548,7 +3585,7 @@
"then": {
"en": "Tesla Supercharger (Destination) (A Type 2 with cable branded as tesla) outputs at most 16 A",
"nl": "Tesla supercharger (Destination (Een Type 2 met kabel en Tesla-logo) levert een stroom van maximaal 16 A",
- "ca": "Supercarregador Tesla (destinació) (Un Tipus 2 amb un cable de marca Tesla) surt com a màxim a 16 A",
+ "ca": "Supercarregador Tesla (Destí) (Un Tipus 2 amb un cable de marca Tesla) surt com a màxim a 16 A",
"da": "Tesla Supercharger (Destination) (A Type 2 med kabel mærket som tesla) yder højst 16 A",
"de": "Tesla Supercharger (Destination) (Typ 2 mit Kabel) liefert maximal 16 A"
},
@@ -3562,7 +3599,7 @@
"then": {
"en": "Tesla Supercharger (Destination) (A Type 2 with cable branded as Tesla) outputs at most 32 A",
"nl": "Tesla Supercharger (Destination (Een Type 2 met kabel en Tesla-logo) levert een stroom van maximaal 32 A",
- "ca": "Supercarregador Tesla (destinació) (Un Tipus 2 amb un cable de marca Tesla) surt com a màxim a 32 A",
+ "ca": "Supercarregador Tesla (Destí) (Un Tipus 2 amb un cable de marca Tesla) surt com a màxim a 32 A",
"da": "Tesla Supercharger (Destination) (A Type 2 med kabel af Tesla-mærket) yder højst 32 A",
"de": "Tesla Supercharger (Destination) (Typ 2 mit Kabel von Tesla) liefert maximal 32 A"
},
@@ -3679,7 +3716,7 @@
"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
?",
- "ca": "Quina corrent ofereixen els connectors amb
USBper a carrega telèfons i dispositius electrònics petits
?",
+ "ca": "Quina intensitat ofereixen els connectors amb
USBper a carrega telèfons i dispositius electrònics petits
?",
"da": "Hvilken strømstyrke har stikkene med
USB til opladning af telefoner og småt elektronikudstyr
?",
"de": "Welche Stromstärke liefern die Stecker mit
USB zum Laden von Handys und kleinen Elektrogeräten
?",
"es": "¿Qué corriente ofrecen los conectores con
USB para cargar teléfonos y dispositivos electrónicos pequeños
?"
@@ -3687,7 +3724,7 @@
"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",
- "ca": "
USBper a carregar telèfons i petits dispositius electrònics
com a màxim a {socket:USB-A:current}A",
+ "ca": "
USBper a carregar telèfons i petits dispositius electrònics
com a màxim a {socket:USB-A:current}A",
"da": "
USB til opladning af telefoner og småt elektronikudstyr
udsender højst {socket:USB-A:current}A",
"de": "
USB zum Aufladen von Telefonen und kleinen Elektrogeräten
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
",
- "ca": "Té un connector
CCS Tesla Supercharger (un tipus2_css de marca)
",
+ "ca": "Té un connector
CCS Tesla Supercharger (un cable de la marca Tesla Tipus2_css)
",
"da": "Har et
Tesla Supercharger CCS-stik (et mærkevarer type2_css)
stik",
"de": "Hat einen
Tesla Supercharger CCS (Typ 2 CSS vonTesla)
Anschluss",
"es": "Tiene un conector
Tesla Supercharger CCS (un tipo2_css de marca)
"
diff --git a/assets/layers/climbing/climbing.json b/assets/layers/climbing/climbing.json
index 5e8ef15e3..b1c66d5ed 100644
--- a/assets/layers/climbing/climbing.json
+++ b/assets/layers/climbing/climbing.json
@@ -180,7 +180,7 @@
"ja": "{climbing:boulder} ボルダールートがある",
"fr": "Il y a {climbing:boulder} problèmes de bloc",
"it": "Sono presenti {climbing:boulder} vie di arrampicata su massi",
- "ca": "Hi han {climbing:boulder} rutes d'escalada en bloc"
+ "ca": "Hi han {climbing:boulder} problemes d'escalada en bloc"
},
"hideInAnswer": true
}
diff --git a/assets/layers/climbing_area/climbing_area.json b/assets/layers/climbing_area/climbing_area.json
index 857f3eb97..b36d52eb4 100644
--- a/assets/layers/climbing_area/climbing_area.json
+++ b/assets/layers/climbing_area/climbing_area.json
@@ -147,7 +147,8 @@
"fr": "
Contient {_contained_climbing_routes_count} voies
{_contained_climbing_routes}
",
"it": "
Contiene {_contained_climbing_routes_count} vie
{_contained_climbing_routes}
",
"de": "
Enthält {_contained_climbing_routes_count} Routen
{_contained_climbing_routes}
",
- "nl": "
Bevat {_contained_climbing_routes_count} routes
{_contained_climbing_routes}
"
+ "nl": "
Bevat {_contained_climbing_routes_count} routes
{_contained_climbing_routes}
",
+ "ca": "
Conté {_contained_climbing_routes_count} rutes
{_contained_climbing_routes}
"
},
"condition": "_contained_climbing_routes~*",
"id": "Contained_climbing_routes"
@@ -206,7 +207,8 @@
"fr": "Rocher d’escalade, rocher avec une ou peu de voie permettant d’escalader sans corde",
"de": "Ein Kletterfelsen - ein einzelner Felsen oder eine Klippe mit einer oder wenigen Kletterrouten, die ohne Seil sicher bestiegen werden können",
"it": "Un masso per arrampicata (una singola roccia o falesia con una o poche vie di arrampicata che possono essere scalate in sicurezza senza una corda)",
- "nl": "Een klimboulder - een enkele rots of klif met één of enkele klimroutes die veilig zonder touw kunnen worden beklommen"
+ "nl": "Een klimboulder - een enkele rots of klif met één of enkele klimroutes die veilig zonder touw kunnen worden beklommen",
+ "ca": "Una roca d'escalada: una única roca o penya-segat amb una o unes quantes vies d'escalada que es poden escalar amb seguretat sense corda"
}
},
{
@@ -256,7 +258,8 @@
"de": "Kalkstein",
"it": "Calcare",
"pa_PK": "چونہ پتھر",
- "eu": "Kareharria"
+ "eu": "Kareharria",
+ "ca": "Calcària"
}
}
],
diff --git a/assets/layers/elevator/elevator.json b/assets/layers/elevator/elevator.json
index c54cee0e3..3fa8cb805 100644
--- a/assets/layers/elevator/elevator.json
+++ b/assets/layers/elevator/elevator.json
@@ -166,21 +166,24 @@
"id": "tactile_writing_available",
"question": {
"en": "Has this elevator tactile writing?",
- "ca": "Aquest ascensor té escriptura tàctil?"
+ "ca": "Aquest ascensor té escriptura tàctil?",
+ "de": "Hat dieser Aufzug taktile Schrift?"
},
"mappings": [
{
"if": "tactile_writing:braille=yes",
"then": {
"en": "This elevator has tactile writing in Braille",
- "ca": "L'ascensor té escriptura tàctil en Braille"
+ "ca": "L'ascensor té escriptura tàctil en Braille",
+ "de": "Dieser Aufzug hat eine taktile Schrift in Brailleschrift"
}
},
{
"if": "tactile_writing:braille=no",
"then": {
"en": "This elevator does not have tactile writing",
- "ca": "Aquest ascensor no té escriptura tàctil"
+ "ca": "Aquest ascensor no té escriptura tàctil",
+ "de": "Dieser Aufzug hat keine taktile Schrift"
}
}
]
diff --git a/assets/layers/elongated_coin/elongated_coin.json b/assets/layers/elongated_coin/elongated_coin.json
index ef8d661ae..b0b16f2b9 100644
--- a/assets/layers/elongated_coin/elongated_coin.json
+++ b/assets/layers/elongated_coin/elongated_coin.json
@@ -217,7 +217,7 @@
"en": "This penny press uses a 25 cent coin for pressing.",
"de": "Der Automat prägt 25 Cent Münzen.",
"es": "Esta prensa de centavo utiliza una moneda de 25 centavos para prensar.",
- "ca": "Esta premsa de cèntims utilitza una moneda de 20 cèntims per a premsar."
+ "ca": "Esta premsa de cèntims utilitza una moneda de 25 cèntims per a premsar."
},
"hideInAnswer": "_currency!~.*USD.*"
},
diff --git a/assets/layers/filters/filters.json b/assets/layers/filters/filters.json
index e89137e23..789151ea3 100644
--- a/assets/layers/filters/filters.json
+++ b/assets/layers/filters/filters.json
@@ -252,12 +252,14 @@
"options": [
{
"question": {
- "en": "No preference towards dogs"
+ "en": "No preference towards dogs",
+ "de": "Keine Bevorzugung von Hunden"
}
},
{
"question": {
- "en": "Dogs allowed"
+ "en": "Dogs allowed",
+ "de": "Hunde erlaubt"
},
"osmTags": {
"or": [
@@ -268,11 +270,40 @@
},
{
"question": {
- "en": "No dogs allowed"
+ "en": "No dogs allowed",
+ "de": "Keine Hunde erlaubt"
},
"osmTags": "dog=no"
}
]
+ },
+ {
+ "id": "has_internet",
+ "options": [
+ {
+ "question": {
+ "en": "Offers internet"
+ },
+ "osmTags": {
+ "or": [
+ "internet_access=wlan",
+ "internet_access=yes",
+ "internet_access=wired"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "id": "has_electricity",
+ "options": [
+ {
+ "question": {
+ "en": "Offers electricity"
+ },
+ "osmTags": "service:electricity=yes"
+ }
+ ]
}
]
}
diff --git a/assets/layers/food/food.json b/assets/layers/food/food.json
index 6f73c30cf..283dead87 100644
--- a/assets/layers/food/food.json
+++ b/assets/layers/food/food.json
@@ -77,7 +77,7 @@
"cuisine=friture"
],
"description": {
- "en": "A fastfood-business focused on french fries",
+ "en": "A fast-food business focused on french fries",
"nl": "Een fastfood-zaak waar je frieten koopt",
"de": "Eine Pommesbude",
"fr": "Une restauration rapide centré sur la vente de frites",
@@ -184,7 +184,7 @@
{
"if": "amenity=fast_food",
"then": {
- "en": "This is a fastfood-business, focused on fast service. If seating is available, these are rather limited and functional.",
+ "en": "This is a fast-food business, focused on fast service. If seating is available, it is rather limited and functional.",
"nl": "Dit is een fastfood-zaak. De focus ligt op snelle bediening, zitplaatsen zijn vaak beperkt en functioneel.",
"de": "Es handelt sich um einen Schnellimbiss, mit Fokus auf schnelle Bedienung am Tresen. Sitzmöglichkeiten sind begrenzt und funktional.",
"es": "Este es un negocio de comida rápida, centrado en servicio rápido. Si hay asientos disponibles, son más bien limitados y funcionales.",
@@ -217,7 +217,7 @@
{
"question": {
"nl": "Welk soort gerechten worden hier geserveerd?",
- "en": "Which food is served here?",
+ "en": "What kind of food is served here?",
"de": "Was für Essen gibt es hier?",
"es": "¿Qué comida se sirve aquí?",
"fr": "Quelle type de nourriture est servie ici ?",
@@ -287,7 +287,7 @@
{
"if": "cuisine=sandwich",
"then": {
- "en": "This is a sandwichbar",
+ "en": "This is a sandwich shop",
"nl": "Dit is een broodjeszaak",
"de": "Dies ist ein Sandwichladen",
"fr": "C'est une sandwicherie",
@@ -331,7 +331,7 @@
{
"if": "cuisine=italian",
"then": {
- "en": "This is an italian restaurant (which serves more then pasta and pizza)",
+ "en": "This is an Italian restaurant (which serves more than pasta and pizza)",
"nl": "Dit is een Italiaans restaurant (dat meer dan enkel pasta of pizza verkoopt)",
"de": "Dies ist ein italienisches Restaurant (das mehr als nur Pasta und Pizza serviert)",
"es": "Este es un restaurante italiano (que sirve más que pasta y pizza)",
@@ -512,7 +512,7 @@
{
"id": "delivery",
"question": {
- "en": "Delivers {title()} their food at home?",
+ "en": "Does {title()} deliver food to your home?",
"de": "Liefert {title()} Essen nach Hause?",
"nl": "Levert {title()} aan huis?",
"fr": "Est-ce que {title()} livre sa nourriture à domicile ?",
@@ -1013,7 +1013,8 @@
{
"question": {
"en": "Restaurants and fast food businesses",
- "ca": "Restaurants i negocis de menjar ràpid"
+ "ca": "Restaurants i negocis de menjar ràpid",
+ "de": "Restaurants und Schnellimbissbetriebe"
}
},
{
@@ -1045,7 +1046,8 @@
"question": {
"en": "Has a vegetarian menu",
"nl": "Heeft een vegetarisch menu",
- "ca": "Té menú vegetarià"
+ "ca": "Té menú vegetarià",
+ "de": "Hat ein vegetarisches Menü"
},
"osmTags": {
"or": [
diff --git a/assets/layers/ghost_bike/ghost_bike.json b/assets/layers/ghost_bike/ghost_bike.json
index aaee97ba5..76b285976 100644
--- a/assets/layers/ghost_bike/ghost_bike.json
+++ b/assets/layers/ghost_bike/ghost_bike.json
@@ -250,7 +250,8 @@
"it": "Piazzata in data {start_date}",
"fr": "Placé le {start_date}",
"ru": "Установлен {start_date}",
- "de": "Aufgestellt am {start_date}"
+ "de": "Aufgestellt am {start_date}",
+ "ca": "Col·locat el {start_date}"
},
"freeform": {
"key": "start_date",
diff --git a/assets/layers/guidepost/guidepost.json b/assets/layers/guidepost/guidepost.json
index 28e2d80b6..0c656080b 100644
--- a/assets/layers/guidepost/guidepost.json
+++ b/assets/layers/guidepost/guidepost.json
@@ -1,6 +1,6 @@
{
"id": "guidepost",
- "name": {
+ "title": {
"en": "Guideposts"
},
"description": {
@@ -32,7 +32,6 @@
"enableImproveAccuracy": "true",
"enableRelocation": "false"
},
- "title": {},
"pointRendering": [
{
"location": [
diff --git a/assets/layers/guidepost/signpost_example.jpg b/assets/layers/guidepost/guidepost_example.jpg
similarity index 100%
rename from assets/layers/guidepost/signpost_example.jpg
rename to assets/layers/guidepost/guidepost_example.jpg
diff --git a/assets/layers/guidepost/signpost_example.jpg.license b/assets/layers/guidepost/guidepost_example.jpg.license
similarity index 52%
rename from assets/layers/guidepost/signpost_example.jpg.license
rename to assets/layers/guidepost/guidepost_example.jpg.license
index c4fea401e..cd1b48769 100644
--- a/assets/layers/guidepost/signpost_example.jpg.license
+++ b/assets/layers/guidepost/guidepost_example.jpg.license
@@ -1,2 +1,2 @@
SPDX-FileCopyrightText: Mschaeuble
-SPDX-License-Identifier: CC0
\ No newline at end of file
+SPDX-License-Identifier: CC0-1.0
\ No newline at end of file
diff --git a/assets/layers/guidepost/license_info.json b/assets/layers/guidepost/license_info.json
index 851b7188a..da92f4adf 100644
--- a/assets/layers/guidepost/license_info.json
+++ b/assets/layers/guidepost/license_info.json
@@ -10,7 +10,7 @@
]
},
{
- "path": "signpost_example.jpg",
+ "path": "guidepost_example.jpg",
"license": "CC0-1.0",
"authors": [
"Mschaeuble"
@@ -19,4 +19,4 @@
"https://wiki.openstreetmap.org/wiki/File:Signpost.jpg"
]
}
-]
\ No newline at end of file
+]
diff --git a/assets/layers/indoors/indoors.json b/assets/layers/indoors/indoors.json
index 285b896b1..ba7aaa0f0 100644
--- a/assets/layers/indoors/indoors.json
+++ b/assets/layers/indoors/indoors.json
@@ -185,48 +185,61 @@
{
"id": "room-type",
"question": {
- "en": "What type of room is this?"
+ "en": "What type of room is this?",
+ "ca": "Quin tipus d'habitació és aquesta?",
+ "de": "Wie wird dieser Raum genutzt?"
},
"mappings": [
{
"if": "room=administration",
"then": {
- "en": "This is a administrative room"
+ "en": "This is a administrative room",
+ "de": "Dies ist ein Verwaltungsraum"
},
"icon": "./assets/layers/indoors/room_administration.svg"
},
{
"if": "room=auditorium",
"then": {
- "en": "This is a auditorium"
+ "en": "This is a auditorium",
+ "de": "Dies ist ein Auditorium",
+ "ca": "Açò és un auditori"
},
"icon": "./assets/layers/indoors/room_auditorium.svg"
},
{
"if": "room=bedroom",
"then": {
- "en": "This is a bedroom"
+ "en": "This is a bedroom",
+ "de": "Dies ist ein Schlafzimmer",
+ "ca": "Açò és un dormitori"
},
"icon": "./assets/layers/indoors/room_bedroom.svg"
},
{
"if": "room=chapel",
"then": {
- "en": "This is a chapel"
+ "en": "This is a chapel",
+ "de": "Dies ist eine Kapelle",
+ "ca": "Açò és una capella"
},
"icon": "./assets/layers/indoors/room_chapel.svg"
},
{
"if": "room=class",
"then": {
- "en": "This is a classroom"
+ "en": "This is a classroom",
+ "de": "Dies ist ein Klassenzimmer",
+ "ca": "Açò és una aula"
},
"icon": "./assets/layers/indoors/room_class.svg"
},
{
"if": "room=classroom",
"then": {
- "en": "This is a classroom"
+ "en": "This is a classroom",
+ "de": "Dies ist ein Klassenzimmer",
+ "ca": "Açò és una aula"
},
"icon": "./assets/layers/indoors/room_class.svg",
"hideInAnswer": true
@@ -234,112 +247,135 @@
{
"if": "room=computer",
"then": {
- "en": "This is a computer room"
+ "en": "This is a computer room",
+ "de": "Dies ist ein Computerraum"
},
"icon": "./assets/layers/indoors/room_computer.svg"
},
{
"if": "room=conference",
"then": {
- "en": "This is a conference room"
+ "en": "This is a conference room",
+ "de": "Dies ist ein Konferenzraum",
+ "ca": "Açò és una sala de conferències"
},
"icon": "./assets/layers/indoors/room_conference.svg"
},
{
"if": "room=crypt",
"then": {
- "en": "This is a crypt"
+ "en": "This is a crypt",
+ "de": "Dies ist eine Krypta",
+ "ca": "Açò és una cripta"
},
"icon": "./assets/layers/indoors/room_crypt.svg"
},
{
"if": "room=kitchen",
"then": {
- "en": "This is a kitchen"
+ "en": "This is a kitchen",
+ "de": "Dies ist eine Küche",
+ "ca": "Açò és una cuina"
},
"icon": "./assets/layers/indoors/room_kitchen.svg"
},
{
"if": "room=laboratory",
"then": {
- "en": "This is a laboratory"
+ "en": "This is a laboratory",
+ "de": "Dies ist ein Labor",
+ "ca": "Açò és un laboratori"
},
"icon": "./assets/layers/indoors/room_laboratory.svg"
},
{
"if": "room=library",
"then": {
- "en": "This is a library"
+ "en": "This is a library",
+ "de": "Dies ist eine Bibliothek"
},
"icon": "./assets/layers/indoors/room_library.svg"
},
{
"if": "room=locker",
"then": {
- "en": "This is a locker room"
+ "en": "This is a locker room",
+ "de": "Dies ist ein Umkleideraum"
},
"icon": "./assets/layers/indoors/room_locker.svg"
},
{
"if": "room=nursery",
"then": {
- "en": "This is a nursery"
+ "en": "This is a nursery",
+ "de": "Dies ist ein Kinderzimmer"
},
"icon": "./assets/layers/indoors/room_nursery.svg"
},
{
"if": "room=office",
"then": {
- "en": "This is an office"
+ "en": "This is an office",
+ "de": "Dies ist ein Büro",
+ "ca": "Açò és una oficina"
},
"icon": "./assets/layers/indoors/room_office.svg"
},
{
"if": "room=prison_cell",
"then": {
- "en": "This is a prison_cell"
+ "en": "This is a prison_cell",
+ "de": "Dies ist eine Gefängniszelle"
},
"icon": "./assets/layers/indoors/room_prison_cell.svg"
},
{
"if": "room=restaurant",
"then": {
- "en": "This is a restaurant"
+ "en": "This is a restaurant",
+ "de": "Dies ist ein Restaurant",
+ "ca": "Açò és un restaurant"
},
"icon": "./assets/layers/indoors/room_restaurant.svg"
},
{
"if": "room=security_check",
"then": {
- "en": "This is a room to perform security checks"
+ "en": "This is a room to perform security checks",
+ "de": "Dies ist ein Raum für Sicherheitskontrollen"
},
"icon": "./assets/layers/indoors/room_security_check.svg"
},
{
"if": "room=sport",
"then": {
- "en": "This is a sport room"
+ "en": "This is a sport room",
+ "de": "Dies ist ein Raum um Sport zu treiben"
},
"icon": "./assets/layers/indoors/room_sport.svg"
},
{
"if": "room=storage",
"then": {
- "en": "This is a storage room"
+ "en": "This is a storage room",
+ "ca": "Açò és un magatzem",
+ "de": "Dies ist ein Lagerraum"
},
"icon": "./assets/layers/indoors/room_storage.svg"
},
{
"if": "room=technical",
"then": {
- "en": "This is a technical room"
+ "en": "This is a technical room",
+ "de": "Dies ist ein Technikraum"
},
"icon": "./assets/layers/indoors/room_technical.svg"
},
{
"if": "room=toilets",
"then": {
- "en": "These are toilets"
+ "en": "These are toilets",
+ "de": "Dies ist ein WC-Raum"
},
"icon": "./assets/layers/indoors/room_toilets.svg",
"addExtraTags": [
@@ -349,7 +385,9 @@
{
"if": "room=waiting",
"then": {
- "en": "This is a waiting room"
+ "en": "This is a waiting room",
+ "ca": "Açò és una sala d'espera",
+ "de": "Dies ist ein Wartezimmer"
},
"icon": "./assets/layers/indoors/room_waiting.svg"
}
@@ -358,7 +396,8 @@
{
"id": "room-capacity",
"question": {
- "en": "How much people can at most fit in this room?"
+ "en": "How much people can at most fit in this room?",
+ "de": "Wie viele Personen passen höchstens in diesen Raum?"
},
"condition": {
"or": [
@@ -374,7 +413,8 @@
]
},
"render": {
- "en": "At most {capacity} people fit this room"
+ "en": "At most {capacity} people fit this room",
+ "de": "Kapazität für höchstens {capacity} Personen"
},
"freeform": {
"key": "capacity",
diff --git a/assets/layers/maproulette/maproulette.json b/assets/layers/maproulette/maproulette.json
index 6d4ae2e6b..2dca74533 100644
--- a/assets/layers/maproulette/maproulette.json
+++ b/assets/layers/maproulette/maproulette.json
@@ -52,7 +52,8 @@
"en": "Task is skipped",
"de": "Aufgabe wurde übersprungen",
"nl": "Taak werd overgeslagen",
- "pl": "Zadanie jest pominięte"
+ "pl": "Zadanie jest pominięte",
+ "ca": "La tasca s'ha botat"
}
},
{
@@ -61,7 +62,8 @@
"en": "Task is deleted",
"de": "Aufgabe wurde gelöscht",
"nl": "Taak werd verwijderd",
- "pl": "Zadania jest usunięte"
+ "pl": "Zadania jest usunięte",
+ "ca": "La tasca s'ha eliminat"
}
},
{
@@ -70,7 +72,8 @@
"en": "Task is already fixed",
"de": "Aufgabe wurde bereits erledigt",
"nl": "Taak was al opgelost",
- "pl": "Zadania jest już wykonane"
+ "pl": "Zadania jest już wykonane",
+ "ca": "La tasca ja està arreglada"
}
},
{
@@ -79,7 +82,8 @@
"en": "Task is marked as too hard",
"de": "Aufgabe wurde als zu schwer markiert",
"nl": "Taak werd als te moeilijk ervaren",
- "pl": "Zadanie jest oznaczone jako zbyt trudne"
+ "pl": "Zadanie jest oznaczone jako zbyt trudne",
+ "ca": "La tasca s'ha marcat com a molt difícil"
}
},
{
@@ -88,7 +92,8 @@
"en": "Task is disabled",
"de": "Aufgabe wurde deaktiviert",
"nl": "Taak is uitgeschakeld",
- "pl": "Zadanie jest wyłączone"
+ "pl": "Zadanie jest wyłączone",
+ "ca": "La tasca està deshabilitada"
}
}
]
diff --git a/assets/layers/maproulette_challenge/maproulette_challenge.json b/assets/layers/maproulette_challenge/maproulette_challenge.json
index 93482c1d5..ff731d60e 100644
--- a/assets/layers/maproulette_challenge/maproulette_challenge.json
+++ b/assets/layers/maproulette_challenge/maproulette_challenge.json
@@ -39,7 +39,8 @@
"then": {
"en": "Task is created",
"de": "Aufgabe wurde erstellt",
- "nl": "Taak is aangemaakt"
+ "nl": "Taak is aangemaakt",
+ "ca": "La tasca s'ha creat"
}
},
{
diff --git a/assets/layers/note/note.json b/assets/layers/note/note.json
index ee848f297..85657dcc1 100644
--- a/assets/layers/note/note.json
+++ b/assets/layers/note/note.json
@@ -140,7 +140,8 @@
"en": "Should not mention {search} in the first comment",
"nl": "Mag in de eerste opmerking niet \"{search}\" bevatten",
"de": "Sollte nicht {search} im ersten Kommentar erwähnen",
- "es": "No debe mencionar {search} en el primer comentario"
+ "es": "No debe mencionar {search} en el primer comentario",
+ "ca": "No s'ha de mencionar {search} al primer comentari"
}
}
]
diff --git a/assets/layers/parking_spaces/parking_spaces.json b/assets/layers/parking_spaces/parking_spaces.json
index e6625ae0e..d3bce0cce 100644
--- a/assets/layers/parking_spaces/parking_spaces.json
+++ b/assets/layers/parking_spaces/parking_spaces.json
@@ -25,7 +25,8 @@
"question": {
"en": "What kind of parking space is this?",
"de": "Welche Art von Stellplatz ist dies?",
- "nl": "Wat voor parkeerplek is dit?"
+ "nl": "Wat voor parkeerplek is dit?",
+ "ca": "Quin tipus d'espai d'aparcament és aquest?"
},
"mappings": [
{
@@ -151,7 +152,8 @@
"en": "This is a parking space reserved for taxis.",
"de": "Dies ist ein Stellplatz, der für Taxis reserviert ist.",
"nl": "Deze parkeerplek is gereserveerd voor taxis.",
- "pl": "To miejsce parkingowe jest przeznaczone dla taksówek."
+ "pl": "To miejsce parkingowe jest przeznaczone dla taksówek.",
+ "ca": "Aquest espai d'aparcament està reservat per a taxi."
}
},
{
@@ -197,7 +199,8 @@
"render": {
"en": "Parking Space",
"de": "Stellplatz",
- "nl": "Parkeerplek"
+ "nl": "Parkeerplek",
+ "ca": "Espai d'aparcament"
},
"mappings": [
{
diff --git a/assets/layers/parking_ticket_machine/parking_ticket_machine.json b/assets/layers/parking_ticket_machine/parking_ticket_machine.json
index 9ffd43854..bbf35af8c 100644
--- a/assets/layers/parking_ticket_machine/parking_ticket_machine.json
+++ b/assets/layers/parking_ticket_machine/parking_ticket_machine.json
@@ -9,7 +9,8 @@
"en": "Layer with parking ticket machines to pay for parking.",
"nl": "Laag met parkeerkaartautomaten om voor parkeren te betalen.",
"de": "Ebene mit Parkscheinautomaten zum Bezahlen des Parkens.",
- "fr": "Couche avec les distributeurs de tickets pour payer le parking."
+ "fr": "Couche avec les distributeurs de tickets pour payer le parking.",
+ "ca": "Capa amb màquines de bitllets d'aparcament per pagar l'aparcament."
},
"title": {
"render": {
diff --git a/assets/layers/pharmacy/pharmacy.json b/assets/layers/pharmacy/pharmacy.json
index 5c22077f4..7d2cde86d 100644
--- a/assets/layers/pharmacy/pharmacy.json
+++ b/assets/layers/pharmacy/pharmacy.json
@@ -47,6 +47,7 @@
"minzoom": 13,
"tagRenderings": [
"images",
+ "reviews",
{
"id": "name",
"freeform": {
diff --git a/assets/layers/playground/playground.json b/assets/layers/playground/playground.json
index 7c088e7d3..613245b96 100644
--- a/assets/layers/playground/playground.json
+++ b/assets/layers/playground/playground.json
@@ -249,7 +249,8 @@
"ru": "Доступно для детей старше {min_age} лет",
"fr": "Accessible aux enfants de plus de {min_age} ans",
"de": "Zugang nur für Kinder ab {min_age} Jahren",
- "es": "Accesible a niños menores de {min_age} años"
+ "es": "Accesible a niños menores de {min_age} años",
+ "ca": "Accessible a nens menors de {min_age} anys"
},
"question": {
"nl": "Wat is de minimale leeftijd om op deze speeltuin te mogen?",
diff --git a/assets/layers/postoffices/postoffices.json b/assets/layers/postoffices/postoffices.json
index 19cfe957f..86ddddd84 100644
--- a/assets/layers/postoffices/postoffices.json
+++ b/assets/layers/postoffices/postoffices.json
@@ -94,7 +94,8 @@
"de": "Wie sind die Öffnungszeiten dieser Poststelle?",
"es": "¿Cuáles son las horas de apertura para esta oficina postal?",
"nl": "Wat zijn de openingsuren voor dit postkantoor?",
- "fr": "Quelles sont les heures d’ouverture de ce bureau de poste ?"
+ "fr": "Quelles sont les heures d’ouverture de ce bureau de poste ?",
+ "ca": "Quines son els horaris d'apertura per a aquesta oficina postal?"
}
}
},
diff --git a/assets/layers/questions/questions.json b/assets/layers/questions/questions.json
index 7da3fe0bd..065f05e0b 100644
--- a/assets/layers/questions/questions.json
+++ b/assets/layers/questions/questions.json
@@ -1291,7 +1291,8 @@
"then": {
"en": "5 centimes coins are accepted",
"nl": "Munten van 5 rappen worden geaccepteerd",
- "ca": "S'accepten monedes de 5 cèntims"
+ "ca": "S'accepten monedes de 5 cèntims",
+ "de": "5-Centime-Münzen werden akzeptiert"
},
"hideInAnswer": "_currency!~.*CHF.*"
},
@@ -1301,7 +1302,8 @@
"then": {
"en": "10 centimes coins are accepted",
"nl": "Munten van 10 rappen worden geaccepteerd",
- "ca": "S'accepten monedes de 10 cèntims"
+ "ca": "S'accepten monedes de 10 cèntims",
+ "de": "10-Centime-Münzen werden akzeptiert"
},
"hideInAnswer": "_currency!~.*CHF.*"
},
@@ -1311,7 +1313,8 @@
"then": {
"en": "20 centimes coins are accepted",
"nl": "Munten van 20 rappen worden geaccepteerd",
- "ca": "S'accepten monedes de 20 cèntims"
+ "ca": "S'accepten monedes de 20 cèntims",
+ "de": "20-Centime-Münzen werden akzeptiert"
},
"hideInAnswer": "_currency!~.*CHF.*"
},
@@ -1320,7 +1323,9 @@
"icon": "./assets/layers/questions/denominations/chf/50rp-2019-800px.png",
"then": {
"en": "½ franc coins are accepted",
- "nl": "Munten van ½ frank worden geaccepteerd"
+ "nl": "Munten van ½ frank worden geaccepteerd",
+ "ca": "S'accepten monedes de ½ franc",
+ "de": "½-Schweizer Franken-Münzen werden akzeptiert"
},
"hideInAnswer": "_currency!~.*CHF.*"
},
@@ -1330,7 +1335,8 @@
"then": {
"en": "1 franc coins are accepted",
"nl": "Munten van 1 frank worden geaccepteerd",
- "ca": "S'accepten monedes d'1 franc"
+ "ca": "S'accepten monedes d'1 franc",
+ "de": "1-Schweizer Franken-Münzen werden akzeptiert"
},
"hideInAnswer": "_currency!~.*CHF.*"
},
@@ -1340,7 +1346,8 @@
"then": {
"en": "2 francs coins are accepted",
"nl": "Munten van 2 frank worden geaccepteerd",
- "ca": "S'accepten monedes de 2 francs"
+ "ca": "S'accepten monedes de 2 francs",
+ "de": "2-Schweizer Franken-Münzen werden akzeptiert"
},
"hideInAnswer": "_currency!~.*CHF.*"
},
@@ -1350,7 +1357,8 @@
"then": {
"en": "5 francs coins are accepted",
"nl": "Munten van 5 frank worden geaccepteerd",
- "ca": "S'accepten monedes de 5 francs"
+ "ca": "S'accepten monedes de 5 francs",
+ "de": "5-Schweizer Franken-Münzen werden akzeptiert"
},
"hideInAnswer": "_currency!~.*CHF.*"
}
@@ -1497,7 +1505,8 @@
"then": {
"en": "10 francs notes are accepted",
"nl": "Biljetten van 10 frank worden geaccepteerd",
- "ca": "S'accepten bitllets de 10 francs"
+ "ca": "S'accepten bitllets de 10 francs",
+ "de": "10-Schweizer Franken-Scheine werden akzeptiert"
},
"hideInAnswer": "_currency!~.*CHF.*"
},
@@ -1507,7 +1516,8 @@
"then": {
"en": "20 francs notes are accepted",
"nl": "Biljetten van 20 frank worden geaccepteerd",
- "ca": "S'accepten bitllets de 20 francs"
+ "ca": "S'accepten bitllets de 20 francs",
+ "de": "20-Schweizer Franken-Scheine werden akzeptiert"
},
"hideInAnswer": "_currency!~.*CHF.*"
},
@@ -1517,7 +1527,8 @@
"then": {
"en": "50 francs notes are accepted",
"nl": "Biljetten van 50 frank worden geaccepteerd",
- "ca": "S'accepten bitllets de 50 francs"
+ "ca": "S'accepten bitllets de 50 francs",
+ "de": "50-Schweizer Franken-Scheine werden akzeptiert"
},
"hideInAnswer": "_currency!~.*CHF.*"
},
@@ -1527,7 +1538,8 @@
"then": {
"en": "100 francs notes are accepted",
"nl": "Biljetten van 100 frank worden geaccepteerd",
- "ca": "S'accepten bitllets de 100 francs"
+ "ca": "S'accepten bitllets de 100 francs",
+ "de": "100-Schweizer Franken-Scheine werden akzeptiert"
},
"hideInAnswer": "_currency!~.*CHF.*"
},
@@ -1537,7 +1549,8 @@
"then": {
"en": "200 francs notes are accepted",
"nl": "Biljetten van 200 frank worden geaccepteerd",
- "ca": "S'accepten bitllets de 200 francs"
+ "ca": "S'accepten bitllets de 200 francs",
+ "de": "200-Schweizer Franken-Scheine werden akzeptiert"
},
"hideInAnswer": "_currency!~.*CHF.*"
},
@@ -1547,7 +1560,8 @@
"then": {
"en": "1000 francs notes are accepted",
"nl": "Biljetten van 1000 frank worden geaccepteerd",
- "ca": "S'accepten bitllets de 1000 francs"
+ "ca": "S'accepten bitllets de 1000 francs",
+ "de": "1000-Schweizer Franken-Scheine werden akzeptiert"
},
"hideInAnswer": "_currency!~.*CHF.*"
}
@@ -1680,7 +1694,8 @@
"condition": "repeat_on~*",
"render": {
"en": "Multiple, identical objects can be found on floors {repeat_on}.",
- "nl": "Er zijn verschillende, identieke objecten op verdiepingen {repeat_on}."
+ "nl": "Er zijn verschillende, identieke objecten op verdiepingen {repeat_on}.",
+ "de": "Mehrere identische Objekte können in Geschossen {repeat_on} gefunden werden."
}
},
{
diff --git a/assets/layers/slow_roads/slow_roads.json b/assets/layers/slow_roads/slow_roads.json
index 45511fcda..60813b096 100644
--- a/assets/layers/slow_roads/slow_roads.json
+++ b/assets/layers/slow_roads/slow_roads.json
@@ -122,7 +122,8 @@
"it": "La superficie è {surface}",
"de": "Die Oberfläche ist {surface}",
"eo": "La surfaco estas {surface}",
- "es": "La superficie es {surface}"
+ "es": "La superficie es {surface}",
+ "ca": "La superfícies és {surface}"
},
"freeform": {
"key": "surface"
@@ -202,7 +203,8 @@
"it": "La superficie è asfalto",
"fr": "La surface est en bitume",
"de": "Die Oberfläche ist Asphalt",
- "es": "La superficie es asfalto"
+ "es": "La superficie es asfalto",
+ "ca": "La superfícies és asfalt"
}
},
{
@@ -215,7 +217,8 @@
"it": "La superficie è calcestruzzo",
"de": "Die Oberfläche ist Beton",
"eo": "La surfaco estas betona",
- "es": "La superficie es hormigón"
+ "es": "La superficie es hormigón",
+ "ca": "La superfície es formigó"
}
},
{
@@ -226,7 +229,8 @@
"fr": "La surface est pavée",
"it": "La superficie è pavimentata",
"de": "Die Oberfläche ist gepflastert",
- "es": "La superficie está pavimentada"
+ "es": "La superficie está pavimentada",
+ "ca": "La superfície està pavimentada"
},
"hideInAnswer": true
}
diff --git a/assets/layers/sport_pitch/sport_pitch.json b/assets/layers/sport_pitch/sport_pitch.json
index 858078195..743e120ee 100644
--- a/assets/layers/sport_pitch/sport_pitch.json
+++ b/assets/layers/sport_pitch/sport_pitch.json
@@ -51,7 +51,8 @@
"en": "{sport} is played here",
"it": "Qui si gioca a {sport}",
"de": "Hier wird {sport} gespielt",
- "es": "Aquí se juega al {sport}"
+ "es": "Aquí se juega al {sport}",
+ "ca": "{sport} es juga aquí"
},
"freeform": {
"key": "sport"
@@ -62,7 +63,8 @@
"en": "Which sport can be played here?",
"it": "Quale sport si gioca qui?",
"de": "Welche Sportarten können hier gespielt werden?",
- "es": "¿Qué deporte se practica aquí?"
+ "es": "¿Qué deporte se puede practicar aquí?",
+ "ca": "Quin esport es pot practicar aquí?"
},
"multiAnswer": true,
"mappings": [
@@ -172,7 +174,8 @@
"then": {
"en": "This is a skatepark",
"nl": "Dit is een skatepark",
- "de": "Dies ist ein Skatepark"
+ "de": "Dies ist ein Skatepark",
+ "ca": "Açò és un skatepark"
}
}
],
@@ -235,7 +238,8 @@
"ru": "Поверхность - {surface}",
"it": "La superficie è {surface}",
"de": "Der Belag ist {surface}",
- "es": "La superficie es {surface}"
+ "es": "La superficie es {surface}",
+ "ca": "La superfícies és {surface}"
},
"freeform": {
"key": "surface"
diff --git a/assets/layers/sports_centre/sports_centre.json b/assets/layers/sports_centre/sports_centre.json
index db7cc8a9b..470ac8039 100644
--- a/assets/layers/sports_centre/sports_centre.json
+++ b/assets/layers/sports_centre/sports_centre.json
@@ -2,11 +2,13 @@
"id": "sports_centre",
"name": {
"en": "Sports centres",
- "de": "Sportzentren"
+ "de": "Sportzentren",
+ "ca": "Centres esportius"
},
"description": {
"en": "Indoor and outdoor sports centres can be found on this layer",
- "de": "Hallen- und Freiluftsportzentren sind auf dieser Ebene zu finden"
+ "de": "Hallen- und Freiluftsportzentren sind auf dieser Ebene zu finden",
+ "ca": "En aquesta capa es poden trobar centres esportius interiors i exteriors"
},
"minzoom": 12,
"source": {
@@ -15,7 +17,8 @@
"title": {
"render": {
"en": "Sports centre",
- "de": "Sportzentrum"
+ "de": "Sportzentrum",
+ "ca": "Centre esportiu"
},
"mappings": [
{
@@ -36,7 +39,8 @@
{
"title": {
"en": "a sports centre",
- "de": "ein Sportzentrum"
+ "de": "ein Sportzentrum",
+ "ca": "un centre esportiu"
},
"tags": [
"leisure=sports_centre"
diff --git a/assets/layers/stairs/stairs.json b/assets/layers/stairs/stairs.json
index fda912434..a7634269c 100644
--- a/assets/layers/stairs/stairs.json
+++ b/assets/layers/stairs/stairs.json
@@ -9,7 +9,8 @@
"description": {
"en": "Layer showing stairs and escalators",
"de": "Ebene mit Treppen und Rolltreppen",
- "nl": "Laag met trappen en roltrappen"
+ "nl": "Laag met trappen en roltrappen",
+ "ca": "Capa que mostra escales i escales mecàniques"
},
"title": {
"render": {
diff --git a/assets/layers/surveillance_camera/surveillance_camera.json b/assets/layers/surveillance_camera/surveillance_camera.json
index 935abdf9f..45f21da2c 100644
--- a/assets/layers/surveillance_camera/surveillance_camera.json
+++ b/assets/layers/surveillance_camera/surveillance_camera.json
@@ -44,25 +44,29 @@
"id": "has_alpr",
"question": {
"en": "Can this camera automatically detect license plates?",
- "ca": "Aquesta càmera pot detectar matrícules automàticament?"
+ "ca": "Aquesta càmera pot detectar matrícules automàticament?",
+ "de": "Dient diese Kamera der Nummernschilderkennung?"
},
"questionHint": {
"en": "An ALPR (Automatic License Plate Reader) typically has two lenses and an array of infrared LEDS in between.",
- "ca": "Un ALPR (lector automàtic de matrícules, per les seves sigles en anglès) normalment té dues lents i una sèrie de LEDs infrarojos entremig."
+ "ca": "Un ALPR (lector automàtic de matrícules, per les seves sigles en anglès) normalment té dues lents i una sèrie de LEDs infrarojos entremig.",
+ "de": "Eine Kamera zur Nummernschilderkennung hat üblicherweise zwei Linsen mit dazwischenliegenden Infrarot-LEDs."
},
"mappings": [
{
"if": "surveillance:type=camera",
"then": {
"en": "This is a camera without number plate recognition.",
- "ca": "Es tracta d'una càmera sense reconeixement de matrícules."
+ "ca": "Es tracta d'una càmera sense reconeixement de matrícules.",
+ "de": "Dies ist eine Kamera ohne Nummernschilderkennung."
}
},
{
"if": "surveillance:type=ALPR",
"then": {
"en": "This is an ALPR (Automatic License Plate Reader)",
- "ca": "Açò és un ALPR (lector automàtic de matrícules, per les seves sigles en anglès)"
+ "ca": "Açò és un ALPR (lector automàtic de matrícules, per les seves sigles en anglès)",
+ "de": "Dies ist eine Kamera mit Nummernschilderkennung"
},
"icon": {
"path": "./assets/layers/surveillance_camera/ALPR.svg"
@@ -349,7 +353,8 @@
"fr": "À quel niveau se trouve cette caméra ?",
"it": "A che piano si trova questa videocamera?",
"de": "Auf welcher Ebene befindet sich diese Kamera?",
- "es": "¿A qué nivel está colocada esta cámara?"
+ "es": "¿A qué nivel está colocada esta cámara?",
+ "ca": "A quina planta es troba aquesta càmera?"
},
"render": {
"en": "Located on level {level}",
@@ -637,11 +642,13 @@
],
"title": {
"en": "an ALPR camera (Automatic Number Plate Reader)",
- "ca": "una càmera ALPR (lector automàtic de matrícules, per les seves sigles en anglès)"
+ "ca": "una càmera ALPR (lector automàtic de matrícules, per les seves sigles en anglès)",
+ "de": "Eine Kamera zur automatischen Nummernschilderkennung"
},
"description": {
"en": "An ALPR typically has two lenses and an array of infrared lights.",
- "ca": "Un ALPR normalment té dues lents i una sèrie de llums infrarojes."
+ "ca": "Un ALPR normalment té dues lents i una sèrie de llums infrarojes.",
+ "de": "Eine automatische Nummernschilderkennung hat üblicherweise zwei Linsen und ein Reihe aus Infrarotlichtern."
},
"exampleImages": [
"./assets/layers/surveillance_camera/ALPR_Example.jpg",
@@ -656,11 +663,13 @@
],
"title": {
"en": "an ALPR camera (Automatic Number Plate Reader) mounted on a wall",
- "ca": "una càmera ALPR (lector automàtic de matrícules) muntada a la paret"
+ "ca": "una càmera ALPR (lector automàtic de matrícules) muntada a la paret",
+ "de": "eine Kamera zur Nummernschilderkennung, die an einer Wand befestigt ist"
},
"description": {
"en": "An ALPR typically has two lenses and an array of infrared lights.",
- "ca": "Un ALPR normalment té dues lents i una sèrie de llums infrarojes."
+ "ca": "Un ALPR normalment té dues lents i una sèrie de llums infrarojes.",
+ "de": "Eine automatische Nummernschilderkennung hat üblicherweise zwei Linsen und ein Reihe aus Infrarotlichtern."
},
"exampleImages": [
"./assets/layers/surveillance_camera/ALPR_Example.jpg",
diff --git a/assets/layers/tertiary_education/tertiary_education.json b/assets/layers/tertiary_education/tertiary_education.json
index d7b3f08f8..7291062c7 100644
--- a/assets/layers/tertiary_education/tertiary_education.json
+++ b/assets/layers/tertiary_education/tertiary_education.json
@@ -5,7 +5,8 @@
"nl": "Universiteiten en hogescholen",
"de": "Hochschulen und Universitäten",
"fr": "Collèges et universités",
- "da": "Gymnasier og universiteter"
+ "da": "Gymnasier og universiteter",
+ "ca": "Instituts superiors i universitats"
},
"description": "Layer with all tertiary education institutes (ISCED:2011 levels 6,7 and 8)",
"source": {
@@ -42,7 +43,8 @@
"nl": "Hogeschool",
"de": "(Fach)hochschule",
"fr": "Établissement d'enseignement supérieur non universitaire",
- "pa_PK": "کالج"
+ "pa_PK": "کالج",
+ "ca": "Institut superior"
}
},
{
@@ -64,7 +66,8 @@
"nl": "Onderwijsinstelling die tertiair onderwijs geeft",
"de": "Schule mit tertiärem Bildungsangebot",
"fr": "École dispensant un enseignement supérieur",
- "da": "Skole, der udbyder videregående uddannelser"
+ "da": "Skole, der udbyder videregående uddannelser",
+ "ca": "Escola que imparteix educació terciària"
}
}
]
@@ -88,7 +91,8 @@
"nl": "Dit is een onderwijsinstelling waar post-secundair, niet-tertiair onderwijs wordt gegeven. Om dit onderwijs te volgen, moet je je secundair onderwijs afgewerkt hebben maar de opleiding behaalt niet het niveau van van een bachelor.",
"de": "Es handelt sich um eine postsekundäre, nicht-tertiäre Bildungseinrichtung. Man muss die Sekundarstufe abgeschlossen haben, um sich hier einzuschreiben, aber es werden keine Bachelor-Abschlüsse (oder höhere Abschlüsse) verliehen",
"fr": "C'est un établissement d'enseignement post-secondaire, non tertiaire. Il faut avoir terminé l'enseignement secondaire pour s'inscrire ici, mais aucun baccalauréat (ou diplôme supérieur) n'est délivré ici",
- "da": "Dette er en institution for post-gymnasial, ikke-tertiær uddannelse. Man skal have gennemført en ungdomsuddannelse for at tilmelde sig her, men her uddeles ingen bachelor (eller højere) grader"
+ "da": "Dette er en institution for post-gymnasial, ikke-tertiær uddannelse. Man skal have gennemført en ungdomsuddannelse for at tilmelde sig her, men her uddeles ingen bachelor (eller højere) grader",
+ "ca": "Aquesta és una institució d'educació postsecundària i no terciària. S'ha d'haver completat l'educació secundària per matricular-se aquí, però aquí no s'obtenen títols de batxillerat (o superiors)"
}
},
{
@@ -179,7 +183,8 @@
"en": "An institute where tertiary education is given (at the level equivalent of a bachelors degree or higher). A single point per campus is enough - buildings and faculties should not be mapped with different university points.",
"nl": "Een onderwijsinstelling waar tertiair onderwijs wordt gegeven - dit is onderwijs waarvan het niveau overeenkomt met een bachelor of hoger is. Eén enkel punt per campus is genoeg - gebouwen en faculteiten worden hier niet op aangeduid.",
"de": "Eine Einrichtung, an der tertiäre Bildung vermittelt wird (auf dem Niveau eines Bachelor-Abschlusses oder höher). Ein einziger Punkt pro Campus ist ausreichend - Gebäude und Fakultäten sollten nicht mit Universitätspunkten gekennzeichnet werden.",
- "fr": "Un institut où l'on dispense un enseignement supérieur (au niveau équivalent à un bachelor ou plus). Un simple point par campus est suffisant - les bâtiments et les facultés ne doivent pas être cartographiés avec différents points d'université."
+ "fr": "Un institut où l'on dispense un enseignement supérieur (au niveau équivalent à un bachelor ou plus). Un simple point par campus est suffisant - les bâtiments et les facultés ne doivent pas être cartographiés avec différents points d'université.",
+ "ca": "Un institut on s'imparteix ensenyament terciari (al nivell equivalent de batxillerat o superior). N'hi ha prou amb un únic punt per campus: els edificis i les facultats no s'han de cartografiar amb diferents punts universitaris."
},
"tags": [
"amenity=university",
diff --git a/assets/layers/toilet/toilet.json b/assets/layers/toilet/toilet.json
index 192ccd226..07ffd42a5 100644
--- a/assets/layers/toilet/toilet.json
+++ b/assets/layers/toilet/toilet.json
@@ -400,7 +400,7 @@
"relevant-questions"
],
"question": {
- "en": "Which kind of toilets are this?",
+ "en": "Which kind of toilets are these?",
"de": "Welche Toiletten gibt es hier?",
"fr": "De quel type sont ces toilettes ?",
"nl": "Welke toiletten zijn dit?",
@@ -608,7 +608,7 @@
{
"if": "toilets:handwashing=yes",
"then": {
- "en": "This toilets have a sink to wash your hands",
+ "en": "These toilets have a sink to wash your hands",
"nl": "Deze toiletten hebben een lavabo waar men de handen kan wassen",
"de": "Die Toilette hat ein Handwaschbecken",
"es": "Estos baños tienen una pileta para lavarse las manos",
@@ -620,7 +620,7 @@
{
"if": "toilets:handwashing=no",
"then": {
- "en": "This toilets don't have a sink to wash your hands",
+ "en": "These toilets don't have a sink to wash your hands",
"nl": "Deze toiletten hebben geen lavabo waar men de handen kan wassen",
"de": "Die Toilette hat kein Handwaschbecken",
"es": "Estos baños no tienen una pileta para lavarse las manos",
diff --git a/assets/layers/toilet_at_amenity/toilet_at_amenity.json b/assets/layers/toilet_at_amenity/toilet_at_amenity.json
index 4b90c6a54..d1899e96c 100644
--- a/assets/layers/toilet_at_amenity/toilet_at_amenity.json
+++ b/assets/layers/toilet_at_amenity/toilet_at_amenity.json
@@ -14,7 +14,8 @@
"render": {
"en": "Toilet at amenity",
"de": "Toilette in Einrichtung",
- "nl": "Toilet in een voorziening"
+ "nl": "Toilet in een voorziening",
+ "ca": "Lavabo a la instal·lació"
},
"mappings": [
{
@@ -22,7 +23,8 @@
"then": {
"en": "Toilet at {name}",
"de": "Toilette in {name}",
- "nl": "Toilet bij {name}"
+ "nl": "Toilet bij {name}",
+ "ca": "Bany a {name}"
}
}
]
@@ -197,7 +199,8 @@
"condition": "toilets:access!=no",
"question": {
"en": "When is the amenity where these toilets are located open?",
- "de": "Wann ist der Ort, an dem sich diese Toiletten befinden, geöffnet?"
+ "de": "Wann ist der Ort, an dem sich diese Toiletten befinden, geöffnet?",
+ "ca": "Quan està oberta la instal·lació on es troben aquests lavabos?"
}
}
},
@@ -273,7 +276,8 @@
"nl": "De deur naar de rolstoeltoegankelijke toilet is {canonical(toilets:door:width)} wide",
"fr": "La porte des toilettes accessibles aux fauteuils roulants a une large de {canonical(toilets:door:width)}",
"de": "Die Tür zur rollstuhlgerechten Toilette ist {canonical(toilets:door:width)} breit",
- "da": "Døren til det kørestolsvenlige toilet er {canonical(toilets:door:width)} bred"
+ "da": "Døren til det kørestolsvenlige toilet er {canonical(toilets:door:width)} bred",
+ "ca": "La porta del vàter accessible amb cadira de rodes és {canonical(toilets:door:width)} d'ample"
},
"freeform": {
"key": "toilets:door:width",
@@ -329,7 +333,8 @@
"nl": "Gratis toegankelijk",
"de": "Nutzung kostenlos",
"fr": "Utilisation gratuite",
- "da": "Gratis at bruge"
+ "da": "Gratis at bruge",
+ "ca": "Ús gratuït"
},
"osmTags": {
"or": [
diff --git a/assets/layers/transit_routes/license_info.json b/assets/layers/transit_routes/license_info.json
new file mode 100644
index 000000000..2af5aeef8
--- /dev/null
+++ b/assets/layers/transit_routes/license_info.json
@@ -0,0 +1,12 @@
+[
+ {
+ "path": "relatify.png",
+ "license": "AGPLv3",
+ "authors": [
+ "Kamil Monicz"
+ ],
+ "sources": [
+ "https://github.com/Zaczero/osm-relatify/blob/main/web/static/img/icon.png"
+ ]
+ }
+]
\ No newline at end of file
diff --git a/assets/layers/transit_routes/relatify.png b/assets/layers/transit_routes/relatify.png
new file mode 100644
index 000000000..39b23abde
Binary files /dev/null and b/assets/layers/transit_routes/relatify.png differ
diff --git a/assets/layers/transit_routes/relatify.png.license b/assets/layers/transit_routes/relatify.png.license
new file mode 100644
index 000000000..b35ebf9ef
--- /dev/null
+++ b/assets/layers/transit_routes/relatify.png.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: Kamil Monicz
+SPDX-License-Identifier: AGPLv3
\ No newline at end of file
diff --git a/assets/layers/transit_routes/transit_routes.json b/assets/layers/transit_routes/transit_routes.json
index feda44f59..f3c69d03a 100644
--- a/assets/layers/transit_routes/transit_routes.json
+++ b/assets/layers/transit_routes/transit_routes.json
@@ -204,5 +204,20 @@
]
}
}
+ ],
+ "titleIcons": [
+ {
+ "condition": {
+ "and": [
+ "id~relation/[0-9]+",
+ "_numeric_id~*"
+ ]
+ },
+ "render": ""
+ },
+ "icons.defaults"
+ ],
+ "calculatedTags": [
+ "_numeric_id=feat.properties.id.split('/')[1]"
]
}
diff --git a/assets/layers/transit_stops/transit_stops.json b/assets/layers/transit_stops/transit_stops.json
index b4c59b434..7c1b1beb9 100644
--- a/assets/layers/transit_stops/transit_stops.json
+++ b/assets/layers/transit_stops/transit_stops.json
@@ -10,7 +10,8 @@
"description": {
"en": "Layer showing different types of transit stops.",
"de": "Ebene mit verschiedenen Arten von Haltestellen.",
- "da": "Lag, der viser forskellige typer transitstop."
+ "da": "Lag, der viser forskellige typer transitstop.",
+ "ca": "Capa que mostra diferents tipus de parades de transport públic."
},
"source": {
"osmTags": {
@@ -25,7 +26,8 @@
"en": "Transit Stop",
"de": "Haltestelle",
"da": "Transit Stop",
- "nl": "Bushalte"
+ "nl": "Bushalte",
+ "ca": "Parada de transport públic"
},
"mappings": [
{
@@ -40,12 +42,18 @@
}
]
},
- "calculatedTags": [
- "_routes=feat.memberships()",
- "_contained_routes_properties=feat.memberships().map(p => {return {id: p.relation.id, name: p.relation.properties.name} }).filter((v,i,a)=>a.findIndex(t=>(JSON.stringify(t) === JSON.stringify(v)))===i)",
- "_contained_route_ids=JSON.parse(feat.properties._contained_routes_properties ?? '[]').map(p => p.id)",
- "_contained_routes=JSON.parse(feat.properties._contained_routes_properties ?? '[]').map(p => `
"
+ }
],
"tagRenderings": [
{
diff --git a/assets/layers/tree_node/tree_node.json b/assets/layers/tree_node/tree_node.json
index 1ae5c68a2..b8af222fa 100644
--- a/assets/layers/tree_node/tree_node.json
+++ b/assets/layers/tree_node/tree_node.json
@@ -88,7 +88,7 @@
"da": "Hvilken art er dette træ?",
"pt": "Que espécie é esta árvore?",
"pt_BR": "Que espécie é esta árvore?",
- "ca": "Quina espècie és aquest arbre?"
+ "ca": "De quina espècie és aquest arbre?"
},
"render": {
"*": "{wikipedia(species:wikidata):max-height: 25rem}"
diff --git a/assets/layers/usersettings/usersettings.json b/assets/layers/usersettings/usersettings.json
index c0af1b2d5..addd7d935 100644
--- a/assets/layers/usersettings/usersettings.json
+++ b/assets/layers/usersettings/usersettings.json
@@ -115,14 +115,16 @@
},
"render": {
"en": "This thematic map has a predefined background layer set. Your default theme setting does not apply",
- "ca": "Aquest mapa temàtic té un conjunt de capes de fons predefinides. La configuració predeterminada del tema no s'aplica"
+ "ca": "Aquest mapa temàtic té un conjunt de capes de fons predefinides. La configuració predeterminada del tema no s'aplica",
+ "de": "Diese thematische Karte hat einen vordefinierten Hintergrund. Ihr Standardhintergrund wird nicht angewendet"
}
},
{
"id": "background-layer",
"question": {
"en": "What background layer should be shown by default?",
- "ca": "Quina capa de fons s'ha de mostrar per defecte?"
+ "ca": "Quina capa de fons s'ha de mostrar per defecte?",
+ "de": "Welche Hintergrundebene soll als Standard verwendet werden?"
},
"condition": "_theme:backgroundLayer=",
"mappings": [
@@ -130,35 +132,40 @@
"if": "mapcomplete-preferred-background-layer=",
"then": {
"en": "Use the default background layer",
- "ca": "Utilitzeu la capa de fons predeterminada"
+ "ca": "Utilitzeu la capa de fons predeterminada",
+ "de": "Standardhintergrund verwenden"
}
},
{
"if": "mapcomplete-preferred-background-layer=osm",
"then": {
"en": "Use OpenStreetMap-carto as default layer",
- "ca": "Utilitzeu OpenStreetMap-carto com a capa predeterminada"
+ "ca": "Utilitzeu OpenStreetMap-carto com a capa predeterminada",
+ "de": "OpenStreetMap-carto als Standardhintergrund verwenden"
}
},
{
"if": "mapcomplete-preferred-background-layer=photo",
"then": {
"en": "Use aerial imagery as default background",
- "ca": "Utilitzeu imatges aèries com a fons predeterminat"
+ "ca": "Utilitzeu imatges aèries com a fons predeterminat",
+ "de": "Satellitenbilder als Standardhintergrund verwenden"
}
},
{
"if": "mapcomplete-preferred-background-layer=map",
"then": {
"en": "Use a non-openstreetmap based map as default background",
- "ca": "Utilitzeu un mapa que no sigui openstreetmap com a fons predeterminat"
+ "ca": "Utilitzeu un mapa que no sigui openstreetmap com a fons predeterminat",
+ "de": "Eine eigene Karte als Standardhintergrund verwenden"
}
},
{
"if": "mapcomplete-preferred-background-layer:={__current_background}",
"then": {
"en": "Use the current background layer ({__current_background}) as default background",
- "ca": "Utilitzeu la capa de fons actual ({__current_background}) com a fons predeterminat"
+ "ca": "Utilitzeu la capa de fons actual ({__current_background}) com a fons predeterminat",
+ "de": "Aktuelle Hintergrundebene ({__current_background}) als Standardhintergrund verwenden"
},
"hideInAnswer": {
"or": [
@@ -172,7 +179,8 @@
"if": "mapcomplete-preferred-background-layer~*",
"then": {
"en": "Use background layer {mapcomplete-preferred-background-layer} as default background",
- "ca": "Utilitza la capa de fons {mapcomplete-preferred-background-layer} com a fons predeterminat"
+ "ca": "Utilitza la capa de fons {mapcomplete-preferred-background-layer} com a fons predeterminat",
+ "de": "Hintergrundebene {mapcomplete-preferred-background-layer} als Standardhintergrund verwenden"
},
"hideInAnswer": true
}
@@ -559,7 +567,8 @@
"fr": "Vous avez fait {_csCount} modifications ! C'est génial !",
"pt": "Você fez alterações em {_csCount} ocasiões diferentes! Isso é incrível!",
"nl": "Je hebt {_csCount} verschillende keren bijgedragen! Dat is indrukwekkend!",
- "da": "Du har lavet ændringer ved {_csCount} forskellige begivenheder! Det er fantastisk!"
+ "da": "Du har lavet ændringer ved {_csCount} forskellige begivenheder! Det er fantastisk!",
+ "es": "Has hecho cambios en {_csCount} ocasiones diferentes. ¡Es alucinante!"
},
"icon": "party"
}
diff --git a/assets/layers/vending_machine/fruits.svg b/assets/layers/vending_machine/fruits.svg
new file mode 100644
index 000000000..48478b6c4
--- /dev/null
+++ b/assets/layers/vending_machine/fruits.svg
@@ -0,0 +1,1034 @@
+
+
+
\ No newline at end of file
diff --git a/assets/layers/vending_machine/fruits.svg.license b/assets/layers/vending_machine/fruits.svg.license
new file mode 100644
index 000000000..854d8a8df
--- /dev/null
+++ b/assets/layers/vending_machine/fruits.svg.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: OpenClipart; frankes
+SPDX-License-Identifier: CC0-1.0
\ No newline at end of file
diff --git a/assets/layers/vending_machine/license_info.json b/assets/layers/vending_machine/license_info.json
index f910585c2..105c31a4b 100644
--- a/assets/layers/vending_machine/license_info.json
+++ b/assets/layers/vending_machine/license_info.json
@@ -29,6 +29,17 @@
"https://fontawesome.com/icons/egg?f=classic&s=solid"
]
},
+ {
+ "path": "fruits.svg",
+ "license": "CC0-1.0",
+ "authors": [
+ "OpenClipart",
+ "frankes"
+ ],
+ "sources": [
+ "https://openclipart.org/detail/244990/fruits-coloured"
+ ]
+ },
{
"path": "honey.svg",
"license": "CC-BY-4.0",
@@ -70,6 +81,17 @@
"https://fontawesome.com/icons/smoking?f=classic&s=solid"
]
},
+ {
+ "path": "strawberry.svg",
+ "license": "CC0-1.0",
+ "authors": [
+ "OpenClipart",
+ "baroquon"
+ ],
+ "sources": [
+ "https://openclipart.org/detail/23540/strawberry"
+ ]
+ },
{
"path": "utensils.svg",
"license": "CC-BY-4.0",
diff --git a/assets/layers/vending_machine/strawberry.svg b/assets/layers/vending_machine/strawberry.svg
new file mode 100644
index 000000000..22a799862
--- /dev/null
+++ b/assets/layers/vending_machine/strawberry.svg
@@ -0,0 +1,524 @@
+
+
+
\ No newline at end of file
diff --git a/assets/layers/vending_machine/strawberry.svg.license b/assets/layers/vending_machine/strawberry.svg.license
new file mode 100644
index 000000000..c079331f2
--- /dev/null
+++ b/assets/layers/vending_machine/strawberry.svg.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: OpenClipart; baroquon
+SPDX-License-Identifier: CC0-1.0
\ No newline at end of file
diff --git a/assets/layers/vending_machine/vending_machine.json b/assets/layers/vending_machine/vending_machine.json
index a27dc8d3c..8b7a8ac30 100644
--- a/assets/layers/vending_machine/vending_machine.json
+++ b/assets/layers/vending_machine/vending_machine.json
@@ -247,10 +247,29 @@
"then": {
"en": "Meat is sold",
"nl": "Vlees wordt verkocht",
- "ca": "Es venen productes carnis"
+ "ca": "Es venen productes carnis",
+ "de": "Fleisch wird verkauft"
},
"icon": "./assets/layers/id_presets/temaki-meat.svg"
},
+ {
+ "if": "vending=fruit",
+ "then": {
+ "en": "Fruit is sold",
+ "nl": "Fruit wordt verkocht",
+ "de": "Blumen werden verkauft"
+ },
+ "icon": "./assets/layers/vending_machine/fruits.svg"
+ },
+ {
+ "if": "vending=strawberries",
+ "then": {
+ "en": "Strawberries are sold",
+ "nl": "Aardbeien worden verkocht",
+ "de": "Parkscheine werden verkauft"
+ },
+ "icon": "./assets/layers/vending_machine/strawberry.svg"
+ },
{
"if": "vending=flowers",
"then": {
@@ -276,7 +295,8 @@
"if": "vending=elongated_coin",
"then": {
"en": "Pressed pennies are sold",
- "ca": "Es venen cèntims premsats"
+ "ca": "Es venen cèntims premsats",
+ "de": "Souvenirmünzen werden verkauft"
},
"icon": "./assets/themes/elongated_coin/penny.svg"
},
@@ -294,35 +314,40 @@
"if": "vending=bicycle_light",
"then": {
"en": "Bicycle lights are sold",
- "nl": "Fietslampjes worden verkocht"
+ "nl": "Fietslampjes worden verkocht",
+ "de": "Fahrradlampen werden verkauft"
}
},
{
"if": "vending=gloves",
"then": {
"en": "Gloves are sold",
- "nl": "Handschoenen worden verkocht"
+ "nl": "Handschoenen worden verkocht",
+ "de": "Fahrradhandschuhe werden verkauft"
}
},
{
"if": "vending=bicycle_repair_kit",
"then": {
"en": "Bicycle repair kits are sold",
- "nl": "Fietsreparatiesets worden verkocht"
+ "nl": "Fietsreparatiesets worden verkocht",
+ "de": "Fahrrad-Reparaturset werden verkauft"
}
},
{
"if": "vending=bicycle_pump",
"then": {
"en": "Bicycle pumps are sold",
- "nl": "Fietspompen worden verkocht"
+ "nl": "Fietspompen worden verkocht",
+ "de": "Fahrradpumpen werden verkauft"
}
},
{
"if": "vending=bicycle_lock",
"then": {
"en": "Bicycle locks are sold",
- "nl": "Fietssloten worden verkocht"
+ "nl": "Fietssloten worden verkocht",
+ "de": "Fahrradschlösser werden verkauft"
}
}
],
@@ -408,14 +433,17 @@
"override": {
"question": {
"en": "What is the phone number of the operator of this vending machine?",
- "ca": "Quin és el número de telèfon de l'operador d'aquesta màquina expenedora?"
+ "ca": "Quin és el número de telèfon de l'operador d'aquesta màquina expenedora?",
+ "de": "Wie lautet die Telefonnummer des Automatenbetreibers?"
},
"questionHint": {
"en": "This is the number you can call in case of problems with the vending machine",
- "ca": "Aquest és el número al qual podeu trucar en cas de problemes amb la màquina expenedora"
+ "ca": "Aquest és el número al qual podeu trucar en cas de problemes amb la màquina expenedora",
+ "de": "Die ist die Telefonnummer, die bei Problemen mit dem Automaten kontaktiert werden kann"
}
}
- }
+ },
+ "website"
],
"calculatedTags": [
"_vending_count=feat.properties.vending.split(';').length"
@@ -607,6 +635,22 @@
},
"osmTags": "vending~i~.*meat.*"
},
+ {
+ "question": {
+ "en": "Sale of fruit",
+ "nl": "Verkoop van fruit",
+ "ca": "Venda de flors"
+ },
+ "osmTags": "vending~i~.*fruit.*"
+ },
+ {
+ "question": {
+ "en": "Sale of strawberries",
+ "nl": "Verkoop van aardbeien",
+ "ca": "Venda de tiquets d'aparcament"
+ },
+ "osmTags": "vending~i~.*strawberries.*"
+ },
{
"question": {
"en": "Sale of flowers",
@@ -621,56 +665,64 @@
"osmTags": "vending~i~.*parking_tickets.*",
"question": {
"en": "Sale of parking tickets",
- "ca": "Venda de monedes premsades"
+ "ca": "Venda de bitllets de transport públic",
+ "de": "Verkauf von Parkscheinen"
}
},
{
"osmTags": "vending=elongated_coin",
"question": {
"en": "Sale of pressed pennies",
- "ca": "Venda de bitllets de transport públic"
+ "ca": "Venda de monedes premsades",
+ "de": "Verkauf von Souvenirmünzen"
}
},
{
"osmTags": "vending~i~.*public_transport_tickets.*",
"question": {
"en": "Sale of public transport tickets",
- "ca": "Venda de productes carnis"
+ "ca": "Venda de bitllets de transport públic",
+ "de": "Verkauf von Fahrscheinen"
}
},
{
"osmTags": "vending=bicycle_light",
"question": {
"en": "Sale of bicycle lights",
- "nl": "Verkoop van fietslampjes"
+ "nl": "Verkoop van fietslampjes",
+ "de": "Verkauf von Fahrradlampen"
}
},
{
"osmTags": "vending=gloves",
"question": {
"en": "Sale of gloves",
- "nl": "Verkoop van handschoenen"
+ "nl": "Verkoop van handschoenen",
+ "de": "Verkauf von Fahrradhandschuhen"
}
},
{
"osmTags": "vending=bicycle_repair_kit",
"question": {
"en": "Sale of bicycle repair kits",
- "nl": "Verkoop van fietsreparatiesets"
+ "nl": "Verkoop van fietsreparatiesets",
+ "de": "Verkauf von Fahrrad-Reparatursets"
}
},
{
"osmTags": "vending=bicycle_pump",
"question": {
"en": "Sale of bicycle pumps",
- "nl": "Verkoop van fietspompen"
+ "nl": "Verkoop van fietspompen",
+ "de": "Verkauf von Fahrradpumpen"
}
},
{
"osmTags": "vending=bicycle_lock",
"question": {
"en": "Sale of bicycle locks",
- "nl": "Verkoop van fietssloten"
+ "nl": "Verkoop van fietssloten",
+ "de": "Verkauf von Fahrradschlössern"
}
}
]
@@ -809,6 +861,33 @@
},
"then": "circle:white;./assets/layers/vending_machine/potato.svg"
},
+ {
+ "if": {
+ "and": [
+ "_vending_count>1",
+ "vending~.*meat.*"
+ ]
+ },
+ "then": "./assets/layers/id_presets/temaki-meat.svg"
+ },
+ {
+ "if": {
+ "and": [
+ "_vending_count>1",
+ "vending~.*fruit.*"
+ ]
+ },
+ "then": "./assets/layers/vending_machine/fruits.svg"
+ },
+ {
+ "if": {
+ "and": [
+ "_vending_count>1",
+ "vending~.*strawberries.*"
+ ]
+ },
+ "then": "./assets/layers/vending_machine/strawberry.svg"
+ },
{
"if": {
"and": [
@@ -907,6 +986,14 @@
"if": "vending=meat",
"then": "./assets/layers/id_presets/temaki-meat.svg"
},
+ {
+ "if": "vending=fruit",
+ "then": "./assets/layers/vending_machine/fruits.svg"
+ },
+ {
+ "if": "vending=strawberries",
+ "then": "./assets/layers/vending_machine/strawberry.svg"
+ },
{
"if": "vending=flowers",
"then": "circle:white;./assets/layers/id_presets/maki-florist.svg"
diff --git a/assets/themes/climbing/climbing.json b/assets/themes/climbing/climbing.json
index e139cc7e9..90f4dc383 100644
--- a/assets/themes/climbing/climbing.json
+++ b/assets/themes/climbing/climbing.json
@@ -461,8 +461,16 @@
]
}
},
- "drinking_water",
- "toilet"
+ {
+ "builtin": [
+ "toilet",
+ "drinking_water",
+ "guidepost"
+ ],
+ "override": {
+ "minzoom": 15
+ }
+ }
],
"credits": "Christian Neumann "
-}
\ No newline at end of file
+}
diff --git a/langs/ca.json b/langs/ca.json
index 5ff6fcdd5..4178af93c 100644
--- a/langs/ca.json
+++ b/langs/ca.json
@@ -197,6 +197,7 @@
"example": "Exemple",
"examples": "Exemples",
"fewChangesBefore": "Contesta unes quantes preguntes sobre elements existents abans d'afegir-ne un de nou.",
+ "geopermissionDenied": "Es va denegar l'ús de la geolocalització",
"getStartedLogin": "Entra a OpenStreetMap per començar",
"getStartedNewAccount": " o crea un nou compte",
"goToInbox": "Obrir missatges",
@@ -556,11 +557,16 @@
"reviews": {
"affiliated_reviewer_warning": "(Ressenya afiliada)",
"attribution": "Les ressenyes funcionen gràcies a Mangrove Reviews i estan disponibles sota CC-BY 4.0.",
- "i_am_affiliated": "Tinc alguna filiació amb aquest objecte Marca-ho si n'ets cap, creador, treballador, …",
+ "i_am_affiliated": "Tinc alguna filiació amb aquest objecte",
+ "i_am_affiliated_explanation": "Marqueu si sou propietari, creador, empleat,…",
"name_required": "És requerit un nom per mostrar i crear revisions",
"no_reviews_yet": "No hi ha revisions encara. Sigues el primer a escriure'n una i ajuda al negoci i a les dades lliures!",
+ "question": "Com valoraries {title()}?",
+ "question_opinion": "Com va ser la vostra experiència?",
+ "reviewing_as": "Ressenyant com a {nickname}",
+ "reviewing_as_anonymous": "Ressenyant com a anònim",
"save": "Desar",
- "saved": "Revisió compartida. Gràcies per compartir!",
+ "saved": "Ressenya compartida. Gràcies per compartir!",
"saving_review": "Desant…",
"title": "{count} revisions",
"title_singular": "Una revisió",
diff --git a/langs/cs.json b/langs/cs.json
index fe833def6..a2f0f24f5 100644
--- a/langs/cs.json
+++ b/langs/cs.json
@@ -1,4 +1,7 @@
{
+ "advanced": {
+ "title": "Pokročilé funkce"
+ },
"centerMessage": {
"loadingData": "Načítání dat…",
"ready": "Hotovo!",
diff --git a/langs/de.json b/langs/de.json
index 93c229561..8c37d23bb 100644
--- a/langs/de.json
+++ b/langs/de.json
@@ -197,6 +197,7 @@
"example": "Beispiel",
"examples": "Beispiele",
"fewChangesBefore": "Bitte beantworten Sie einige Fragen zu bestehenden Objekten, bevor Sie ein neues Objekt hinzufügen.",
+ "geopermissionDenied": "Die Verwendung der Standortbestimmung wurde verweigert",
"getStartedLogin": "Bei OpenStreetMap anmelden, um loszulegen",
"getStartedNewAccount": " oder ein neues Konto anlegen",
"goToInbox": "Posteingang öffnen",
@@ -417,7 +418,20 @@
"respectPrivacy": "Bitte respektieren Sie die Privatsphäre. Fotografieren Sie weder Personen noch Nummernschilder. Benutzen Sie keine urheberrechtlich geschützten Quellen wie z.B. Google Maps oder Google Streetview.",
"toBig": "Ihr Bild ist mit {actual_size} zu groß. Die maximale Bildgröße ist {max_size}",
"upload": {
- "failReasons": "Keine Internetverbindung"
+ "failReasons": "Keine Internetverbindung",
+ "failReasonsAdvanced": "Alternativ dazu können Sie einstellen, dass Ihr Browser und Ihre Erweiterungen die APIs von Drittanbietern nicht blockieren.",
+ "multiple": {
+ "done": "{count} Bilder erfolgreich hochgeladen. Vielen Dank!",
+ "partiallyDone": "{count} Bilder werden hochgeladen, {done} Bilder erledigt…",
+ "someFailed": "Entschuldigung, {count} Bilder konnten nicht hochgeladen werden",
+ "uploading": "{count} Bilder werden hochgeladen…"
+ },
+ "one": {
+ "done": "Bild erfolgreich hochgeladen. Vielen Dank!",
+ "failed": "Entschuldigung, das Bild konnte nicht hochgeladen werden",
+ "retrying": "Das Bild wird wiederholt hochgeladen…",
+ "uploading": "Das Bild wird hochgeladen…"
+ }
},
"uploadDone": "Ihr Bild wurde hinzugefügt. Vielen Dank für Ihre Hilfe!",
"uploadFailed": "Das Bild konnte nicht hochladen werden. Haben Sie eine aktive Internetverbindung und sind APIs von Dritten erlaubt? Der Brave Browser oder UMatrix blockieren diese eventuell.",
@@ -504,7 +518,9 @@
},
"plantDetection": {
"back": "Zurück zur Artenübersicht",
+ "button": "Automatische Erkennung der Pflanzenart durch die KI von Plantnet.org",
"confirm": "Arten auswählen",
+ "done": "Die Art wurde übernommen",
"error": "Bei der Erkennung der Baumart ist ein Fehler aufgetreten: {error}",
"howTo": {
"intro": "Für optimale Ergebnisse,",
@@ -521,7 +537,8 @@
"poweredByPlantnet": "Bereitgestellt von plantnet.org",
"querying": "Abfrage bei plantnet.org mit {length} Fotos",
"seeInfo": "Weitere Informationen über diese Art",
- "takeImages": "Machen Sie Fotos vom Baum, um die Baumart automatisch zu erkennen"
+ "takeImages": "Machen Sie Fotos vom Baum, um die Baumart automatisch zu erkennen",
+ "tryAgain": "Wähle eine andere Art"
},
"privacy": {
"editing": "Ihre Änderungen werden auf OpenStreetMap gespeichert und sind öffentlich zugänglich. Ein mit MapComplete erstellter Änderungssatz enthält folgende Daten:
Ihre Änderungen
Ihren Benutzernamen
Den Zeitpunkt Ihrer Änderungen
Das bei Ihren Änderungen verwendete MapComplete-Thema
Die Sprache Ihrer Benutzeroberfläche
Ihre Entfernung zu den geänderten Objekten. Dadurch kann festgestellt werden, ob die Änderungen vor Ort gespeichert wurden
Ausführliche Informationen finden Sie in den Datenschutzbestimmungen auf OpenStreetMap.org. Wir möchten Sie daran erinnern, dass Sie zur Anmeldung einen fiktiven Namen verwenden können.",
@@ -540,11 +557,16 @@
"reviews": {
"affiliated_reviewer_warning": "(Partner-Rezension)",
"attribution": "Rezensionen von Mangrove Reviews sind unter CC-BY 4.0 verfügbar.",
- "i_am_affiliated": "Ich bin an diesem Objekt beteiligt Auswählen, wenn Sie Eigentümer, Ersteller, Angestellter … sind",
+ "i_am_affiliated": "Ich bin mit diesem Objekt vertraut",
+ "i_am_affiliated_explanation": "Prüfung, ob Sie der Eigentümer, Ersteller, Angestellter, … sind",
"name_required": "Der Name des Objekts ist erforderlich, um Bewertungen zu erstellen und anzuzeigen",
"no_reviews_yet": "Es gibt noch keine Bewertungen. Hilf mit der ersten Bewertung dem Geschäft und der Open Data Bewegung!",
+ "question": "Wie bewerten Sie {title()}?",
+ "question_opinion": "Wie war Ihre Erfahrung?",
+ "reviewing_as": "Als {nickname} bewerten",
+ "reviewing_as_anonymous": "Anonym bewerten",
"save": "Speichern",
- "saved": "Bewertung gespeichert. Danke fürs Teilen!",
+ "saved": "Bewertung gespeichert. Danke fürs Teilen!",
"saving_review": "Speichern…",
"title": "{count} Rezensionen",
"title_singular": "Eine Rezension",
diff --git a/langs/layers/ca.json b/langs/layers/ca.json
index eb44d799a..29273fcef 100644
--- a/langs/layers/ca.json
+++ b/langs/layers/ca.json
@@ -1034,9 +1034,64 @@
},
"question": "Aquesta màquina expenedora encara funciona?",
"render": "L'estat operatiu és {operational_status}"
+ },
+ "bicycle_tube_vending_machine-brand": {
+ "mappings": {
+ "0": {
+ "then": "Aquí es venen cambres d'aire Continental"
+ },
+ "1": {
+ "then": "Aquí es venen cambres d'aire Schwalbe"
+ }
+ },
+ "question": "Quines marques de cambres d'aire es venen aquí?",
+ "render": "Aquí es venen cambres d'aire {brand}"
+ },
+ "bicycle_tube_vending_machine-charge": {
+ "question": "Quant costa una cambra d'aire de bicicleta?",
+ "render": "Una cambra d'aire de bicicleta costa {charge}"
+ },
+ "bicycle_tube_vending_machine-operator": {
+ "mappings": {
+ "0": {
+ "then": "Mantés per Schwalbe"
+ },
+ "1": {
+ "then": "Mantés per Continental"
+ }
+ },
+ "question": "Qui manté aquesta màquina expenedora?"
+ },
+ "other-items-vending": {
+ "mappings": {
+ "0": {
+ "then": "Aquí es venen cambres d'aire de bicicletes"
+ },
+ "1": {
+ "then": "Aquí es venen llums per a bicicletes"
+ },
+ "2": {
+ "then": "Aquí es venen guants"
+ },
+ "3": {
+ "then": "Aquí es venen kits de reparació de bicicletes"
+ },
+ "4": {
+ "then": "Aquí es venen bombes de bicicletes"
+ },
+ "5": {
+ "then": "Aquí es venen cadenats per a bicicletes"
+ }
+ },
+ "question": "Es venen altres accessoris per a bicicletes aquí?"
}
},
"title": {
+ "mappings": {
+ "0": {
+ "then": "Màquina expenedora de cambres d'aire de bicicletes {name}"
+ }
+ },
"render": "Màquina expenedora de tubs de bicicleta"
}
},
@@ -1858,7 +1913,7 @@
"question": "Té un connector
Tipus 2 amb cable (mennekes)
"
},
"11": {
- "question": "Té un connector
CCS Tesla Supercharger (un tipus2_css de marca)
"
+ "question": "Té un connector
CCS Tesla Supercharger (un cable de la marca Tesla Tipus2_css)
"
},
"12": {
"question": "Té un connector
Tesla Supercharger (destination)
"
@@ -1984,10 +2039,10 @@
"then": "Tipus 2 amb cable (mennekes)"
},
"20": {
- "then": "CSS Supercarregador Tesla (un tipus2_css de la marca)"
+ "then": "CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css)"
},
"21": {
- "then": "CSS Supercarregador Tesla (un tipus2_css de la marca)"
+ "then": "CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css)"
},
"22": {
"then": "Supercarregador Tesla (destí)"
@@ -2137,30 +2192,53 @@
"then": "Endoll de paret Shuko sense ping de terra (CEE7/4 tipus F) surt com a màxim 16 A"
}
},
- "question": "Quina intensitat ofereixen els endolls amb
de paret Shuko sense pin de terra (CEE7/4 tipus F)
?"
+ "question": "Quina intensitat ofereixen els connectors amb
endolls de paret Schuko sense pin de terra (CEE7/4 tipus F)
?",
+ "render": "
L'endoll de paret Schuko sense pin de terra (CEE7/4 tipus F)
surt com a màxim a {socket:schuko:current}A"
+ },
+ "current-1": {
+ "mappings": {
+ "0": {
+ "then": "Endoll de paret europeu amb pin de terra (CEE7/4 type E) surt com a màxim a 16A"
+ }
+ },
+ "question": "Quina intensitat ofereixen els connectors amb
endolls de paret europeu amb pin de terra (CEE7/4 tipus F)
?",
+ "render": "
L'endoll de paret europeu amb pin de terra (CEE7/4 tipus F)
surt com a màxim a {socket:typee:current}A"
+ },
+ "current-10": {
+ "mappings": {
+ "0": {
+ "then": "CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css) surt com a màxim a 125A"
+ },
+ "1": {
+ "then": "CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css) surt com a màxim a 350A"
+ }
+ },
+ "question": "Quina corrent ofereixen els connectors
CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css)
?",
+ "render": "
CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css)
surt com a màxim a {socket:tesla_supercharger_ccs:current}A"
},
"current-11": {
"mappings": {
"0": {
- "then": "Tesla Supercharger (Destinació) emet com a màxim 125 A"
+ "then": "Supercarregador Tesla (Destí) surt com a màxim a 125 A"
},
"1": {
- "then": "Tesla Supercharger (Destinació) emet com a màxim 350 A"
+ "then": "Supercarregdor Tesla (Destinació) surt com a màxim a 350 A"
}
},
- "question": "Quin corrent fan els endolls amb
Tesla Supercharger (Destination)
offer?",
- "render": "
Tesla Supercharger (Destinació)
sortida com a màxim {socket:tesla_destination:current}A"
+ "question": "Quina intensitat ofereixen els connectors
Supercarregador Tesla (Destí)
?",
+ "render": "
Supercarregador Tesla (Destí)
surt com a màxim a {socket:tesla_destination:current}A"
},
"current-12": {
"mappings": {
"0": {
- "then": "Supercarregador Tesla (destinació) (Un Tipus 2 amb un cable de marca Tesla) surt com a màxim a 16 A"
+ "then": "Supercarregador Tesla (Destí) (Un Tipus 2 amb un cable de marca Tesla) surt com a màxim a 16 A"
},
"1": {
- "then": "Supercarregador Tesla (destinació) (Un Tipus 2 amb un cable de marca Tesla) surt com a màxim a 32 A"
+ "then": "Supercarregador Tesla (Destí) (Un Tipus 2 amb un cable de marca Tesla) surt com a màxim a 32 A"
}
},
- "question": "Quin corrent donen els endolls amb
Tesla Supercharger (destinació) (un tipus 2 amb cable amb la marca Tesla)
oferta?"
+ "question": "Quina intensitat ofereixen els connectors
Supercarregador Tesla (Destí) (un tipus 2 amb cable amb la marca Tesla)
?",
+ "render": "
Supercarregador Tesla (Destí) (un tipus 2 amb cable amb la marca Tesla)
surt com a màxim a {socket:tesla_destination:current}A"
},
"current-13": {
"mappings": {
@@ -2171,8 +2249,16 @@
"then": "USB per a carregar telèfons i dispositius petits fins a 2 A"
}
},
- "question": "Quina corrent ofereixen els connectors amb
USBper a carrega telèfons i dispositius electrònics petits
?",
- "render": "
USBper a carregar telèfons i petits dispositius electrònics
com a màxim a {socket:USB-A:current}A"
+ "question": "Quina intensitat ofereixen els connectors amb
USBper a carrega telèfons i dispositius electrònics petits
?",
+ "render": "
USBper a carregar telèfons i petits dispositius electrònics
com a màxim a {socket:USB-A:current}A"
+ },
+ "current-14": {
+ "question": "Quina intensitat ofereixen els connectors
Bosch Active Connect amb 3 pins i cable
?",
+ "render": "
Bosch Active Connect amb 3 pins i cable
surt com a màxim a {socket:bosch_3pin:current}A"
+ },
+ "current-15": {
+ "question": "Quina corrent ofereixen els connectors
Bosch Active Connect amb 5 pins i cable
?",
+ "render": "
Bosch Active Connect amb 5 pins i cable
surt com a màxim a {socket:bosch_5pin:current}A"
},
"current-2": {
"mappings": {
@@ -2180,7 +2266,50 @@
"then": "Chademo surt com a màxim a 120 A"
}
},
- "question": "Quin corrent ofereixen els endolls amb
Chademo
?"
+ "question": "Quin corrent ofereixen els endolls amb
Chademo
?",
+ "render": "
Chademo
surt com a màxim a {socket:chademo:current}A"
+ },
+ "current-3": {
+ "mappings": {
+ "0": {
+ "then": "Tipus 1 amb cable (J1772) surt com a màxim a 32A"
+ }
+ },
+ "question": "Quina corrent ofereixen els connectors
Tipus 1 amb cable (J1772)
?",
+ "render": "
Tipus 1 amb cable (J1772)
surt com a màxim a {socket:type1_cable:current}A"
+ },
+ "current-4": {
+ "mappings": {
+ "0": {
+ "then": "Tipus 1 sense cable (J1772) surt com a màxim a 32A"
+ }
+ },
+ "question": "Quina corrent ofereixen els connectors
Tipus 1 sense cable (J1772)
?",
+ "render": "
Tipus 1 sense cable(J1772)
surt com a màxim a {socket:type1:current}A"
+ },
+ "current-5": {
+ "mappings": {
+ "0": {
+ "then": "Tipus 1 CCS (també Tipus 1 Combo) surt com a màxim a 50A"
+ },
+ "1": {
+ "then": "Tipus 1 CCS (també Tipus 1 Combo) surt com a màxim a 125A"
+ }
+ },
+ "question": "Quina intensitat ofereixen els connectors
Tipus 1 CCS (també Tipus 1 Combo)
?",
+ "render": "
Tipus 1 CCS (també Tipus 1 Combo)
surt com a màxim a {socket:type1_combo:current}A"
+ },
+ "current-6": {
+ "mappings": {
+ "0": {
+ "then": "Supercarregador Tesla surt com a màxim a 125A"
+ },
+ "1": {
+ "then": "Supercarregador Tesla surt com a màxim a 350A"
+ }
+ },
+ "question": "Quina intensitat ofereixen els connectors
Supercarregador Tesla
?",
+ "render": "
Supercarregador Tesla
surt com a màxim a {socket:tesla_supercharger:current}A"
},
"current-7": {
"mappings": {
@@ -2190,7 +2319,9 @@
"1": {
"then": "Tipus 2 (menneks) surt com a màxim a 32 A"
}
- }
+ },
+ "question": "Quina intensitat ofereixen els connectors
Tipus 2 (mennekes)
?",
+ "render": "
Tipus 2 (mennekes)
surt com a màxim a {socket:type2:current}A"
},
"current-8": {
"mappings": {
@@ -2201,7 +2332,20 @@
"then": "Tipus 2 CCS (mennekes) surt com a màxim a 350 A"
}
},
- "question": "Quin corrent ofereixen els endolls amb
Tipus 2 CCS (mennekes)
?"
+ "question": "Quina intensitat ofereixen els connectors
Tipus 2 CCS (mennekes)
?",
+ "render": "
Tipus 2 CSS (mennekes)
surt com a màxim a {socket:type2_combo:current}"
+ },
+ "current-9": {
+ "mappings": {
+ "0": {
+ "then": "Tipus 2 amb cable (mennekes) surt com a màxim a 16A"
+ },
+ "1": {
+ "then": "Tipus 2 amb cable (mennekes) surt com a màxim a 32A"
+ }
+ },
+ "question": "Quina intensitat ofereixen els connectors
Tipus 2 amb cable (mennekes)
?",
+ "render": "
Tipus 2 amb cable (mennekes)
surt com a màxim a {socket:type2_cable:current}A"
},
"email": {
"question": "Quin és el correu electrònic de l'operadora?",
@@ -2240,6 +2384,18 @@
"question": "A quin número es pot cridar si hi ha algun problema amb aquest punt de càrrega?",
"render": "En cas de problemes, truqueu a {phone}"
},
+ "plugs-0": {
+ "question": "Quants connectors del tipus
Endoll de paret Schuko sense pin de terra (CEE7/4 tipus F)
hi han disponibles aquí?",
+ "render": "Hi ha {socket:schuko} connectors del tipus
Endoll de paret Schuko sense pin de terra (CEE7/4 tipus F)
disponibles aquí"
+ },
+ "plugs-1": {
+ "question": "Quants connectors del tipus
Endoll de paret Europeu amb pin de terra (CEE7/4 tipus E)
hi han disponibles aquí?",
+ "render": "Hi ha {socket:typee} connectors del tipus
Endoll de paret europeu amb pin de terra (CEE7/4 tipus E)
disponibles aquí"
+ },
+ "plugs-10": {
+ "question": "Quants connectors del tipus
CCS Supercarregador Tesla (un cable de la marca Tesla Tipus2_css)
hi han disponibles aquí?",
+ "render": "Hi ha {socket:tesla_supercharger_ccs} connectors
Supercarregadro Tesla CCS (un cable de la marca Tesla Tipus2_css)
disponibles aquí"
+ },
"plugs-2": {
"render": "Aquí hi ha {socket:chademo} endolls del tipus
Chademo
disponibles"
},
@@ -2367,7 +2523,7 @@
"then": "L'escalada en bloc és possible, tot i que només hi ha unes poques rutes"
},
"3": {
- "then": "Hi han {climbing:boulder} rutes d'escalada en bloc"
+ "then": "Hi han {climbing:boulder} problemes d'escalada en bloc"
}
},
"question": "És possible fer escalda en bloc aquí?"
@@ -2396,10 +2552,25 @@
}
},
"tagRenderings": {
+ "Contained_climbing_routes": {
+ "render": "
Conté {_contained_climbing_routes_count} rutes
{_contained_climbing_routes}
"
+ },
"Rock type (crag/rock/cliff only)": {
+ "mappings": {
+ "0": {
+ "then": "Calcària"
+ }
+ },
"question": "Quin és el tipus de roca aquí?",
"render": "El tipus de roca és {rock}"
},
+ "Type": {
+ "mappings": {
+ "0": {
+ "then": "Una roca d'escalada: una única roca o penya-segat amb una o unes quantes vies d'escalada que es poden escalar amb seguretat sense corda"
+ }
+ }
+ },
"name": {
"render": "{name}"
}
@@ -3529,7 +3700,7 @@
"then": "Esta premsa de cèntims utilitza una moneda de 10 cèntims per a premsar."
},
"3": {
- "then": "Esta premsa de cèntims utilitza una moneda de 20 cèntims per a premsar."
+ "then": "Esta premsa de cèntims utilitza una moneda de 25 cèntims per a premsar."
},
"4": {
"then": "Esta premsa de cèntims utilitza una moneda de 50 cèntims per a premsar."
@@ -4424,7 +4595,8 @@
}
},
"ghost_bike-start_date": {
- "question": "Quan es va instal·lar aquesta bicicleta Ghost?"
+ "question": "Quan es va instal·lar aquesta bicicleta Ghost?",
+ "render": "Col·locat el {start_date}"
}
},
"title": {
@@ -4731,6 +4903,50 @@
},
"question": "Quin és el número de referència d'aquesta habitació?",
"render": "Aquesta habitació té el número de referència {ref}"
+ },
+ "room-type": {
+ "mappings": {
+ "1": {
+ "then": "Açò és un auditori"
+ },
+ "2": {
+ "then": "Açò és un dormitori"
+ },
+ "3": {
+ "then": "Açò és una capella"
+ },
+ "4": {
+ "then": "Açò és una aula"
+ },
+ "5": {
+ "then": "Açò és una aula"
+ },
+ "7": {
+ "then": "Açò és una sala de conferències"
+ },
+ "8": {
+ "then": "Açò és una cripta"
+ },
+ "9": {
+ "then": "Açò és una cuina"
+ },
+ "10": {
+ "then": "Açò és un laboratori"
+ },
+ "14": {
+ "then": "Açò és una oficina"
+ },
+ "16": {
+ "then": "Açò és un restaurant"
+ },
+ "19": {
+ "then": "Açò és un magatzem"
+ },
+ "22": {
+ "then": "Açò és una sala d'espera"
+ }
+ },
+ "question": "Quin tipus d'habitació és aquesta?"
}
},
"title": {
@@ -5083,6 +5299,21 @@
},
"2": {
"then": "La tasca és un fals positiu"
+ },
+ "3": {
+ "then": "La tasca s'ha botat"
+ },
+ "4": {
+ "then": "La tasca s'ha eliminat"
+ },
+ "5": {
+ "then": "La tasca ja està arreglada"
+ },
+ "6": {
+ "then": "La tasca s'ha marcat com a molt difícil"
+ },
+ "7": {
+ "then": "La tasca està deshabilitada"
}
}
}
@@ -5126,6 +5357,9 @@
"tagRenderings": {
"status": {
"mappings": {
+ "0": {
+ "then": "La tasca s'ha creat"
+ },
"1": {
"then": "La tasca està arreglada"
},
@@ -5332,6 +5566,13 @@
}
}
},
+ "1": {
+ "options": {
+ "0": {
+ "question": "No s'ha de mencionar {search} al primer comentari"
+ }
+ }
+ },
"2": {
"options": {
"0": {
@@ -5731,12 +5972,20 @@
},
"11": {
"then": "Es tracta d'una plaça d'aparcament reservada al personal."
+ },
+ "12": {
+ "then": "Aquest espai d'aparcament està reservat per a taxi."
}
- }
+ },
+ "question": "Quin tipus d'espai d'aparcament és aquest?"
}
+ },
+ "title": {
+ "render": "Espai d'aparcament"
}
},
"parking_ticket_machine": {
+ "description": "Capa amb màquines de bitllets d'aparcament per pagar l'aparcament.",
"presets": {
"0": {
"title": "una màquina de tiquets d'aparcament"
@@ -5940,7 +6189,8 @@
"render": "Accessible per a nens de com a màxim {max_age}"
},
"playground-min_age": {
- "question": "Quina és l'edat mínima requerida per a accedir al parc infantil?"
+ "question": "Quina és l'edat mínima requerida per a accedir al parc infantil?",
+ "render": "Accessible a nens menors de {min_age} anys"
},
"playground-opening_hours": {
"mappings": {
@@ -6049,6 +6299,11 @@
"question": "Pots enviar cartes des d'aquí?",
"render": "Podeu enviar cartes amb aquestes empreses: {post_office:letter_from}"
},
+ "opening_hours": {
+ "override": {
+ "question": "Quines son els horaris d'apertura per a aquesta oficina postal?"
+ }
+ },
"parcel-from": {
"mappings": {
"0": {
@@ -6321,6 +6576,9 @@
"10": {
"then": "S'accepten monedes de 20 cèntims"
},
+ "11": {
+ "then": "S'accepten monedes de ½ franc"
+ },
"12": {
"then": "S'accepten monedes d'1 franc"
},
@@ -7277,8 +7535,18 @@
},
"3": {
"then": "La superfície és sorra"
+ },
+ "5": {
+ "then": "La superfícies és asfalt"
+ },
+ "6": {
+ "then": "La superfície es formigó"
+ },
+ "7": {
+ "then": "La superfície està pavimentada"
}
- }
+ },
+ "render": "La superfícies és {surface}"
}
}
},
@@ -7451,8 +7719,13 @@
},
"4": {
"then": "Aquí es juga al corfbol"
+ },
+ "6": {
+ "then": "Açò és un skatepark"
}
- }
+ },
+ "question": "Quin esport es pot practicar aquí?",
+ "render": "{sport} es juga aquí"
},
"sport_pitch-surface": {
"mappings": {
@@ -7472,14 +7745,28 @@
"then": "La superfície és formigó"
}
},
- "question": "Quina és la superfície d'aquest camp esportiu?"
+ "question": "Quina és la superfície d'aquest camp esportiu?",
+ "render": "La superfícies és {surface}"
}
},
"title": {
"render": "Camp d'esports"
}
},
+ "sports_centre": {
+ "description": "En aquesta capa es poden trobar centres esportius interiors i exteriors",
+ "name": "Centres esportius",
+ "presets": {
+ "0": {
+ "title": "un centre esportiu"
+ }
+ },
+ "title": {
+ "render": "Centre esportiu"
+ }
+ },
"stairs": {
+ "description": "Capa que mostra escales i escales mecàniques",
"name": "Escales",
"tagRenderings": {
"conveying": {
@@ -7746,6 +8033,7 @@
"question": "Quin tipus de càmera és aquesta?"
},
"Level": {
+ "question": "A quina planta es troba aquesta càmera?",
"render": "Ubicat a la planta {level}"
},
"Operator": {
@@ -7852,14 +8140,19 @@
}
},
"tertiary_education": {
+ "name": "Instituts superiors i universitats",
"presets": {
"0": {
+ "description": "Un institut on s'imparteix ensenyament terciari (al nivell equivalent de batxillerat o superior). N'hi ha prou amb un únic punt per campus: els edificis i les facultats no s'han de cartografiar amb diferents punts universitaris.",
"title": "una universitat"
}
},
"tagRenderings": {
"institution-kind": {
"mappings": {
+ "0": {
+ "then": "Aquesta és una institució d'educació postsecundària i no terciària. S'ha d'haver completat l'educació secundària per matricular-se aquí, però aquí no s'obtenen títols de batxillerat (o superiors)"
+ },
"1": {
"then": "Açò és una universitat, una institució d'educació terciaria on s'imparteixen carreres universitàries o superior."
}
@@ -7883,8 +8176,14 @@
},
"title": {
"mappings": {
+ "1": {
+ "then": "Institut superior"
+ },
"2": {
"then": "Universitat"
+ },
+ "3": {
+ "then": "Escola que imparteix educació terciària"
}
}
}
@@ -8147,10 +8446,22 @@
"question": "Accessible amb cadira de rodes"
}
}
+ },
+ "2": {
+ "options": {
+ "0": {
+ "question": "Ús gratuït"
+ }
+ }
}
},
"name": "Lavabos a altres instal·lacions",
"tagRenderings": {
+ "opening_hours": {
+ "override": {
+ "question": "Quan està oberta la instal·lació on es troben aquests lavabos?"
+ }
+ },
"toilet-access": {
"mappings": {
"0": {
@@ -8202,9 +8513,18 @@
"question": "Hi ha un lavabo específic per a usuaris amb cadira de rodes?"
},
"wheelchair-door-width": {
- "question": "Quina és l'amplada de la porta del lavabo accessible per a cadira de rodes?"
+ "question": "Quina és l'amplada de la porta del lavabo accessible per a cadira de rodes?",
+ "render": "La porta del vàter accessible amb cadira de rodes és {canonical(toilets:door:width)} d'ample"
}
},
+ "title": {
+ "mappings": {
+ "0": {
+ "then": "Bany a {name}"
+ }
+ },
+ "render": "Lavabo a la instal·lació"
+ },
"units": {
"0": {
"applicableUnits": {
@@ -8283,6 +8603,7 @@
}
},
"transit_stops": {
+ "description": "Capa que mostra diferents tipus de parades de transport públic.",
"filter": {
"0": {
"options": {
@@ -8415,7 +8736,8 @@
"0": {
"then": "Parada {name}"
}
- }
+ },
+ "render": "Parada de transport públic"
}
},
"tree_node": {
@@ -8520,7 +8842,7 @@
"question": "És un arbre de fulla ampla o d'agulla?"
},
"tree-species-wikidata": {
- "question": "Quina espècie és aquest arbre?"
+ "question": "De quina espècie és aquest arbre?"
},
"tree_node-name": {
"mappings": {
@@ -8805,17 +9127,21 @@
"16": {
"question": "Venda de productes carnis"
},
- "17": {
- "question": "Venda d'aparcament"
- },
+
"18": {
- "question": "Venda de monedes premsades"
+ "question": "Venda de tiquets d'aparcament"
},
"19": {
- "question": "Venda de bitllets de transport públic"
+ "question": "Venda de flors"
},
"20": {
- "question": "Venda de productes carnis"
+ "question": "Venda de bitllets de transport públic"
+ },
+ "21": {
+ "question": "Venda de monedes premsades"
+ },
+ "22": {
+ "question": "Venda de bitllets de transport públic"
}
}
}
@@ -8904,16 +9230,16 @@
"15": {
"then": "Es venen productes carnis"
},
- "16": {
+ "18": {
"then": "Es venen flors"
},
- "17": {
+ "19": {
"then": "Es venen tiquets d'aparcament"
},
- "18": {
+ "20": {
"then": "Es venen cèntims premsats"
},
- "19": {
+ "21": {
"then": "Es venen bitllets de transport públic"
}
},
@@ -9243,4 +9569,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/langs/layers/de.json b/langs/layers/de.json
index 284a69c67..7a7f88cb2 100644
--- a/langs/layers/de.json
+++ b/langs/layers/de.json
@@ -1034,9 +1034,64 @@
},
"question": "Ist dieser Automat in Betrieb?",
"render": "Der Betriebszustand ist {operational_status}"
+ },
+ "bicycle_tube_vending_machine-brand": {
+ "mappings": {
+ "0": {
+ "then": "Hier werden Fahrradschläuche von Continental verkauft"
+ },
+ "1": {
+ "then": "Hier werden Fahrradschläuche von Schwalbe verkauft"
+ }
+ },
+ "question": "Welche Fahrradschläuche werden hier verkauft?",
+ "render": "Hier werden Fahrradschläuche von {brand} verkauft"
+ },
+ "bicycle_tube_vending_machine-charge": {
+ "question": "Wie viel kostet ein Fahrradschlauch?",
+ "render": "Ein Fahrradschlauch kostet {charge}"
+ },
+ "bicycle_tube_vending_machine-operator": {
+ "mappings": {
+ "0": {
+ "then": "Betrieben von Schwalbe"
+ },
+ "1": {
+ "then": "Betrieben von Continental"
+ }
+ },
+ "question": "Wer betreibt den Automaten?"
+ },
+ "other-items-vending": {
+ "mappings": {
+ "0": {
+ "then": "Hier werden Fahrradschläuche verkauft"
+ },
+ "1": {
+ "then": "Hier werden Fahrradlampen verkauft"
+ },
+ "2": {
+ "then": "Hier werden Fahrradhandschuhe verkauft"
+ },
+ "3": {
+ "then": "Hier werden Fahrrad-Reparatursets verkauft"
+ },
+ "4": {
+ "then": "Hier werden Fahrradpumpen verkauft"
+ },
+ "5": {
+ "then": "Hier werden Fahrradschlösser verkauft"
+ }
+ },
+ "question": "Wird weiteres Fahrradzubehör verkauft?"
}
},
"title": {
+ "mappings": {
+ "0": {
+ "then": "{name} Fahrradschlauch-Automat"
+ }
+ },
"render": "Fahrradschlauch-Automat"
}
},
@@ -4217,6 +4272,17 @@
"question": "Verfügt der Aufzug über eine Sprachausgabe?",
"questionHint": "Z.B. werden Stockwerke angesagt"
},
+ "tactile_writing_available": {
+ "mappings": {
+ "0": {
+ "then": "Dieser Aufzug hat eine taktile Schrift in Brailleschrift"
+ },
+ "1": {
+ "then": "Dieser Aufzug hat keine taktile Schrift"
+ }
+ },
+ "question": "Hat dieser Aufzug taktile Schrift?"
+ },
"tactile_writing_language": {
"render": {
"special": {
@@ -4631,6 +4697,19 @@
"question": "Nutzung kostenlos"
}
}
+ },
+ "10": {
+ "options": {
+ "0": {
+ "question": "Keine Bevorzugung von Hunden"
+ },
+ "1": {
+ "question": "Hunde erlaubt"
+ },
+ "2": {
+ "question": "Keine Hunde erlaubt"
+ }
+ }
}
}
},
@@ -4880,6 +4959,9 @@
},
"2": {
"options": {
+ "0": {
+ "question": "Restaurants und Schnellimbissbetriebe"
+ },
"1": {
"question": "Nur Fastfood-Geschäfte"
},
@@ -4888,6 +4970,13 @@
}
}
},
+ "3": {
+ "options": {
+ "0": {
+ "question": "Hat ein vegetarisches Menü"
+ }
+ }
+ },
"4": {
"options": {
"0": {
@@ -5532,6 +5621,84 @@
},
"question": "Wie lautet die Nummer dieses Raums?",
"render": "Dieser Raum hat die Raumnummer {ref}"
+ },
+ "room-capacity": {
+ "question": "Wie viele Personen passen höchstens in diesen Raum?",
+ "render": "Kapazität für höchstens {capacity} Personen"
+ },
+ "room-type": {
+ "mappings": {
+ "0": {
+ "then": "Dies ist ein Verwaltungsraum"
+ },
+ "1": {
+ "then": "Dies ist ein Auditorium"
+ },
+ "2": {
+ "then": "Dies ist ein Schlafzimmer"
+ },
+ "3": {
+ "then": "Dies ist eine Kapelle"
+ },
+ "4": {
+ "then": "Dies ist ein Klassenzimmer"
+ },
+ "5": {
+ "then": "Dies ist ein Klassenzimmer"
+ },
+ "6": {
+ "then": "Dies ist ein Computerraum"
+ },
+ "7": {
+ "then": "Dies ist ein Konferenzraum"
+ },
+ "8": {
+ "then": "Dies ist eine Krypta"
+ },
+ "9": {
+ "then": "Dies ist eine Küche"
+ },
+ "10": {
+ "then": "Dies ist ein Labor"
+ },
+ "11": {
+ "then": "Dies ist eine Bibliothek"
+ },
+ "12": {
+ "then": "Dies ist ein Umkleideraum"
+ },
+ "13": {
+ "then": "Dies ist ein Kinderzimmer"
+ },
+ "14": {
+ "then": "Dies ist ein Büro"
+ },
+ "15": {
+ "then": "Dies ist eine Gefängniszelle"
+ },
+ "16": {
+ "then": "Dies ist ein Restaurant"
+ },
+ "17": {
+ "then": "Dies ist ein Raum für Sicherheitskontrollen"
+ },
+ "18": {
+ "then": "Dies ist ein Raum um Sport zu treiben"
+ },
+ "19": {
+ "then": "Dies ist ein Lagerraum"
+ },
+ "20": {
+ "then": "Dies ist ein Technikraum"
+ },
+ "21": {
+ "then": "Dies ist ein WC-Raum"
+ },
+ "22": {
+ "then": "Dies ist ein Wartezimmer"
+ }
+ },
+ "question": "Wie wird dieser Raum genutzt?"
}
},
"title": {
@@ -7225,6 +7392,27 @@
},
"7": {
"then": "2-Euro-Münzen werden akzeptiert"
+ },
+ "8": {
+ "then": "5-Centime-Münzen werden akzeptiert"
+ },
+ "9": {
+ "then": "10-Centime-Münzen werden akzeptiert"
+ },
+ "10": {
+ "then": "20-Centime-Münzen werden akzeptiert"
+ },
+ "11": {
+ "then": "½-Schweizer Franken-Münzen werden akzeptiert"
+ },
+ "12": {
+ "then": "1-Schweizer Franken-Münzen werden akzeptiert"
+ },
+ "13": {
+ "then": "2-Schweizer Franken-Münzen werden akzeptiert"
+ },
+ "14": {
+ "then": "5-Schweizer Franken-Münzen werden akzeptiert"
}
},
"question": "Mit welchen Münzen kann man hier bezahlen?"
@@ -7251,6 +7439,24 @@
},
"6": {
"then": "500-Euro-Scheine werden angenommen"
+ },
+ "7": {
+ "then": "10-Schweizer Franken-Scheine werden akzeptiert"
+ },
+ "8": {
+ "then": "20-Schweizer Franken-Scheine werden akzeptiert"
+ },
+ "9": {
+ "then": "50-Schweizer Franken-Scheine werden akzeptiert"
+ },
+ "10": {
+ "then": "100-Schweizer Franken-Scheine werden akzeptiert"
+ },
+ "11": {
+ "then": "200-Schweizer Franken-Scheine werden akzeptiert"
+ },
+ "12": {
+ "then": "1000-Schweizer Franken-Scheine werden akzeptiert"
}
},
"question": "Mit welchen Banknoten kann man hier bezahlen?"
@@ -7443,6 +7649,9 @@
"phone": {
"question": "Wie lautet die Telefonnummer von {title()}?"
},
+ "repeated": {
+ "render": "Mehrere identische Objekte können in Geschossen {repeat_on} gefunden werden."
+ },
"service:electricity": {
"mappings": {
"0": {
@@ -8708,6 +8917,14 @@
},
"1": {
"title": "eine an einer Wand montierte Überwachungskamera"
+ },
+ "2": {
+ "description": "Eine automatische Nummernschilderkennung hat üblicherweise zwei Linsen und ein Reihe aus Infrarotlichtern.",
+ "title": "Eine Kamera zur automatischen Nummernschilderkennung"
+ },
+ "3": {
+ "description": "Eine automatische Nummernschilderkennung hat üblicherweise zwei Linsen und ein Reihe aus Infrarotlichtern.",
+ "title": "eine Kamera zur Nummernschilderkennung, die an einer Wand befestigt ist"
}
},
"tagRenderings": {
@@ -8801,6 +9018,18 @@
"question": "In welche Himmelsrichtung filmt diese Kamera?",
"render": "filmt in Himmelsrichtung {camera:direction}"
},
+ "has_alpr": {
+ "mappings": {
+ "0": {
+ "then": "Dies ist eine Kamera ohne Nummernschilderkennung."
+ },
+ "1": {
+ "then": "Dies ist eine Kamera mit Nummernschilderkennung"
+ }
+ },
+ "question": "Dient diese Kamera der Nummernschilderkennung?",
+ "questionHint": "Eine Kamera zur Nummernschilderkennung hat üblicherweise zwei Linsen mit dazwischenliegenden Infrarot-LEDs."
+ },
"is_indoor": {
"mappings": {
"0": {
@@ -9565,6 +9794,32 @@
},
"question": "Sollen Fragen für unbekannte Datenfelder einzeln oder zusammen angezeigt werden?"
},
+ "background-layer": {
+ "mappings": {
+ "0": {
+ "then": "Standardhintergrund verwenden"
+ },
+ "1": {
+ "then": "OpenStreetMap-carto als Standardhintergrund verwenden"
+ },
+ "2": {
+ "then": "Satellitenbilder als Standardhintergrund verwenden"
+ },
+ "3": {
+ "then": "Eine eigene Karte als Standardhintergrund verwenden"
+ },
+ "4": {
+ "then": "Aktuelle Hintergrundebene ({__current_background}) als Standardhintergrund verwenden"
+ },
+ "5": {
+ "then": "Hintergrundebene {mapcomplete-preferred-background-layer} als Standardhintergrund verwenden"
+ }
+ },
+ "question": "Welche Hintergrundebene soll als Standard verwendet werden?"
+ },
+ "background-layer-readonly": {
+ "render": "Diese thematische Karte hat einen vordefinierten Hintergrund. Ihr Standardhintergrund wird nicht angewendet"
+ },
"contributor-thanks": {
"mappings": {
"0": {
@@ -9786,8 +10041,32 @@
"16": {
"question": "Verkauf von Fleisch"
},
- "17": {
+ "19": {
"question": "Verkauf von Blumen"
+ },
+ "20": {
+ "question": "Verkauf von Parkscheinen"
+ },
+ "21": {
+ "question": "Verkauf von Souvenirmünzen"
+ },
+ "22": {
+ "question": "Verkauf von Fahrscheinen"
+ },
+ "23": {
+ "question": "Verkauf von Fahrradlampen"
+ },
+ "24": {
+ "question": "Verkauf von Fahrradhandschuhen"
+ },
+ "25": {
+ "question": "Verkauf von Fahrrad-Reparatursets"
+ },
+ "26": {
+ "question": "Verkauf von Fahrradpumpen"
+ },
+ "27": {
+ "question": "Verkauf von Fahrradschlössern"
}
}
}
@@ -9820,6 +10099,12 @@
"question": "Wer betreibt diesen Verkaufsautomaten?",
"render": "Dieser Verkaufsautomat wird betrieben von {operator}"
},
+ "phone": {
+ "override": {
+ "question": "Wie lautet die Telefonnummer des Automatenbetreibers?",
+ "questionHint": "Die ist die Telefonnummer, die bei Problemen mit dem Automaten kontaktiert werden kann"
+ }
+ },
"vending": {
"mappings": {
"0": {
@@ -9867,14 +10152,41 @@
"14": {
"then": "Kartoffeln werden verkauft"
},
+ "15": {
+ "then": "Fleisch wird verkauft"
+ },
"16": {
"then": "Blumen werden verkauft"
},
"17": {
"then": "Parkscheine werden verkauft"
},
+ "18": {
+ "then": "Blumen werden verkauft"
+ },
"19": {
+ "then": "Parkscheine werden verkauft"
+ },
+ "20": {
+ "then": "Souvenirmünzen werden verkauft"
+ },
+ "21": {
"then": "Fahrscheine werden verkauft"
+ },
+ "22": {
+ "then": "Fahrradlampen werden verkauft"
+ },
+ "23": {
+ "then": "Fahrradhandschuhe werden verkauft"
+ },
+ "24": {
+ "then": "Fahrrad-Reparaturset werden verkauft"
+ },
+ "25": {
+ "then": "Fahrradpumpen werden verkauft"
+ },
+ "26": {
+ "then": "Fahrradschlösser werden verkauft"
}
},
"question": "Was wird in diesem Automaten verkauft?",
diff --git a/langs/layers/en.json b/langs/layers/en.json
index f95609cd9..40cd3669f 100644
--- a/langs/layers/en.json
+++ b/langs/layers/en.json
@@ -4711,6 +4711,20 @@
"question": "No dogs allowed"
}
}
+ },
+ "11": {
+ "options": {
+ "0": {
+ "question": "Offers internet"
+ }
+ }
+ },
+ "12": {
+ "options": {
+ "0": {
+ "question": "Offers electricity"
+ }
+ }
}
}
},
@@ -5004,7 +5018,7 @@
"title": "a fastfood"
},
"2": {
- "description": "A fastfood-business focused on french fries",
+ "description": "A fast-food business focused on french fries",
"title": "a fries shop"
}
},
@@ -5024,7 +5038,7 @@
"then": "This is kebab shop"
},
"4": {
- "then": "This is a sandwichbar"
+ "then": "This is a sandwich shop"
},
"5": {
"then": "Burgers are served here"
@@ -5036,7 +5050,7 @@
"then": "Coffee is served here"
},
"8": {
- "then": "This is an italian restaurant (which serves more then pasta and pizza)"
+ "then": "This is an Italian restaurant (which serves more than pasta and pizza)"
},
"9": {
"then": "French dishes are served here"
@@ -5057,13 +5071,13 @@
"then": "Thai dishes are served here"
}
},
- "question": "Which food is served here?",
+ "question": "What kind of food is served here?",
"render": "This place mostly serves {cuisine}"
},
"Fastfood vs restaurant": {
"mappings": {
"0": {
- "then": "This is a fastfood-business, focused on fast service. If seating is available, these are rather limited and functional."
+ "then": "This is a fast-food business, focused on fast service. If seating is available, it is rather limited and functional."
},
"1": {
"then": "A restaurant, focused on creating a nice experience where one is served at the table"
@@ -5149,7 +5163,7 @@
"then": "This business does not deliver at home"
}
},
- "question": "Delivers {title()} their food at home?"
+ "question": "Does {title()} deliver food to your home?"
},
"friture-oil": {
"mappings": {
@@ -9265,10 +9279,10 @@
"toilet-handwashing": {
"mappings": {
"0": {
- "then": "This toilets have a sink to wash your hands"
+ "then": "These toilets have a sink to wash your hands"
},
"1": {
- "then": "This toilets don't have a sink to wash your hands"
+ "then": "These toilets don't have a sink to wash your hands"
}
},
"question": "Do these toilets have a sink to wash your hands?"
@@ -9321,7 +9335,7 @@
"then": "Both seated toilets and urinals are available here"
}
},
- "question": "Which kind of toilets are this?"
+ "question": "Which kind of toilets are these?"
},
"toilets-wheelchair": {
"mappings": {
@@ -10053,30 +10067,36 @@
"question": "Sale of meat"
},
"17": {
- "question": "Sale of flowers"
+ "question": "Sale of fruit"
},
"18": {
- "question": "Sale of parking tickets"
+ "question": "Sale of strawberries"
},
"19": {
- "question": "Sale of pressed pennies"
+ "question": "Sale of flowers"
},
"20": {
- "question": "Sale of public transport tickets"
+ "question": "Sale of parking tickets"
},
"21": {
- "question": "Sale of bicycle lights"
+ "question": "Sale of pressed pennies"
},
"22": {
- "question": "Sale of gloves"
+ "question": "Sale of public transport tickets"
},
"23": {
- "question": "Sale of bicycle repair kits"
+ "question": "Sale of bicycle lights"
},
"24": {
- "question": "Sale of bicycle pumps"
+ "question": "Sale of gloves"
},
"25": {
+ "question": "Sale of bicycle repair kits"
+ },
+ "26": {
+ "question": "Sale of bicycle pumps"
+ },
+ "27": {
"question": "Sale of bicycle locks"
}
}
@@ -10167,30 +10187,36 @@
"then": "Meat is sold"
},
"16": {
- "then": "Flowers are sold"
+ "then": "Fruit is sold"
},
"17": {
- "then": "Parking tickets are sold"
+ "then": "Strawberries are sold"
},
"18": {
- "then": "Pressed pennies are sold"
+ "then": "Flowers are sold"
},
"19": {
- "then": "Public transport tickets are sold"
+ "then": "Parking tickets are sold"
},
"20": {
- "then": "Bicycle lights are sold"
+ "then": "Pressed pennies are sold"
},
"21": {
- "then": "Gloves are sold"
+ "then": "Public transport tickets are sold"
},
"22": {
- "then": "Bicycle repair kits are sold"
+ "then": "Bicycle lights are sold"
},
"23": {
- "then": "Bicycle pumps are sold"
+ "then": "Gloves are sold"
},
"24": {
+ "then": "Bicycle repair kits are sold"
+ },
+ "25": {
+ "then": "Bicycle pumps are sold"
+ },
+ "26": {
"then": "Bicycle locks are sold"
}
},
diff --git a/langs/layers/es.json b/langs/layers/es.json
index d2e92f45d..44d875390 100644
--- a/langs/layers/es.json
+++ b/langs/layers/es.json
@@ -4193,7 +4193,7 @@
"then": "Aquí se juega al baloncesto"
}
},
- "question": "¿Qué deporte se practica aquí?",
+ "question": "¿Qué deporte se puede practicar aquí?",
"render": "Aquí se juega al {sport}"
},
"sport_pitch-surface": {
@@ -4779,6 +4779,13 @@
},
"usersettings": {
"tagRenderings": {
+ "cscount-thanks": {
+ "mappings": {
+ "0": {
+ "then": "Has hecho cambios en {_csCount} ocasiones diferentes. ¡Es alucinante!"
+ }
+ }
+ },
"picture-license": {
"mappings": {
"1": {
diff --git a/langs/layers/fr.json b/langs/layers/fr.json
index fb9f2e3bc..d1d813804 100644
--- a/langs/layers/fr.json
+++ b/langs/layers/fr.json
@@ -6576,7 +6576,7 @@
"15": {
"question": "Vente de pommes de terre"
},
- "17": {
+ "19": {
"question": "Vente de fleurs"
}
}
@@ -6657,7 +6657,7 @@
"14": {
"then": "Vent des pommes de terre"
},
- "16": {
+ "18": {
"then": "Vent des fleurs"
}
},
diff --git a/langs/layers/nl.json b/langs/layers/nl.json
index 0c1013095..355773c15 100644
--- a/langs/layers/nl.json
+++ b/langs/layers/nl.json
@@ -9077,21 +9077,27 @@
"question": "Verkoop van vlees"
},
"17": {
+ "question": "Verkoop van fruit"
+ },
+ "18": {
+ "question": "Verkoop van aardbeien"
+ },
+ "19": {
"question": "Verkoop van bloemen"
},
- "21": {
+ "23": {
"question": "Verkoop van fietslampjes"
},
- "22": {
+ "24": {
"question": "Verkoop van handschoenen"
},
- "23": {
+ "25": {
"question": "Verkoop van fietsreparatiesets"
},
- "24": {
+ "26": {
"question": "Verkoop van fietspompen"
},
- "25": {
+ "27": {
"question": "Verkoop van fietssloten"
}
}
@@ -9176,27 +9182,33 @@
"then": "Vlees wordt verkocht"
},
"16": {
- "then": "Bloemen worden verkocht"
+ "then": "Fruit wordt verkocht"
},
"17": {
- "then": "Parkeerkaarten worden verkocht"
+ "then": "Aardbeien worden verkocht"
+ },
+ "18": {
+ "then": "Bloemen worden verkocht"
},
"19": {
- "then": "Openbaar vervoerkaartjes worden verkocht"
- },
- "20": {
- "then": "Fietslampjes worden verkocht"
+ "then": "Parkeerkaarten worden verkocht"
},
"21": {
- "then": "Handschoenen worden verkocht"
+ "then": "Openbaar vervoerkaartjes worden verkocht"
},
"22": {
- "then": "Fietsreparatiesets worden verkocht"
+ "then": "Fietslampjes worden verkocht"
},
"23": {
- "then": "Fietspompen worden verkocht"
+ "then": "Handschoenen worden verkocht"
},
"24": {
+ "then": "Fietsreparatiesets worden verkocht"
+ },
+ "25": {
+ "then": "Fietspompen worden verkocht"
+ },
+ "26": {
"then": "Fietssloten worden verkocht"
}
},
diff --git a/package-lock.json b/package-lock.json
index ee8c40538..e4e268736 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "mapcomplete",
- "version": "0.33.5",
+ "version": "0.33.7",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "mapcomplete",
- "version": "0.33.5",
+ "version": "0.33.7",
"license": "GPL-3.0-or-later",
"dependencies": {
"@rgossiaux/svelte-headlessui": "^1.0.2",
@@ -23,6 +23,7 @@
"chart.js": "^3.8.0",
"country-language": "^0.1.7",
"country-to-currency": "^1.0.10",
+ "crypto": "^1.0.1",
"csv-parse": "^5.1.0",
"doctest-ts-improved": "^0.8.8",
"dompurify": "^3.0.5",
@@ -4971,9 +4972,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001541",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001541.tgz",
- "integrity": "sha512-bLOsqxDgTqUBkzxbNlSBt8annkDpQB9NdzdTbO2ooJ+eC/IQcvDspDc058g84ejCelF7vHUx57KIOjEecOHXaw==",
+ "version": "1.0.30001546",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001546.tgz",
+ "integrity": "sha512-zvtSJwuQFpewSyRrI3AsftF6rM0X80mZkChIt1spBGEvRglCrjTniXvinc8JKRoqTwXAgvqTImaN9igfSMtUBw==",
"dev": true,
"funding": [
{
@@ -5393,6 +5394,12 @@
"node": ">= 8"
}
},
+ "node_modules/crypto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz",
+ "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==",
+ "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in."
+ },
"node_modules/css-line-break": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
@@ -17027,9 +17034,9 @@
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="
},
"caniuse-lite": {
- "version": "1.0.30001541",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001541.tgz",
- "integrity": "sha512-bLOsqxDgTqUBkzxbNlSBt8annkDpQB9NdzdTbO2ooJ+eC/IQcvDspDc058g84ejCelF7vHUx57KIOjEecOHXaw==",
+ "version": "1.0.30001546",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001546.tgz",
+ "integrity": "sha512-zvtSJwuQFpewSyRrI3AsftF6rM0X80mZkChIt1spBGEvRglCrjTniXvinc8JKRoqTwXAgvqTImaN9igfSMtUBw==",
"dev": true
},
"canvg": {
@@ -17347,6 +17354,11 @@
"which": "^2.0.1"
}
},
+ "crypto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz",
+ "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig=="
+ },
"css-line-break": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
diff --git a/package.json b/package.json
index c42f4f3f5..ef52f608c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "mapcomplete",
- "version": "0.33.6",
+ "version": "0.33.7",
"repository": "https://github.com/pietervdvn/MapComplete",
"description": "A small website to edit OSM easily",
"bugs": "https://github.com/pietervdvn/MapComplete/issues",
@@ -17,23 +17,10 @@
"Alternatively, you can override the `osm` credentials using the environment variables `VITE_OSM_OAUTH_CLIENT_ID` and `VITE_OSM_OAUTH_SECRET`"
],
"oauth_credentials": {
- "osm_pietervdvn": {
- "#": "This client_id is registered by 'Pieter Vander Vennet' on OSM.org",
- "oauth_client_id": "sa1ngLJBJ8McmzHElN8NYtIDm5TZTYEYhq3-0snO4Qc",
- "oauth_secret": "XU_cD5Mvw9VKk9T0t_gO8V7cbRC4Hmw2Tb4Rv0Zmz-U",
- "url": "https://www.openstreetmap.org"
- },
- "osm": {
- "#": "This client-id is registered by 'MapComplete' on osm.org",
- "oauth_client_id": "K93H1d8ve7p-tVLE1ZwsQ4lAFLQk8INx5vfTLMu5DWk",
- "oauth_secret": "NBWGhWDrD3QDB35xtVuxv4aExnmIt4FA_WgeLtwxasg",
- "url": "https://www.openstreetmap.org"
- },
- "osm-test": {
- "oauth_client_id": "HwUn6GPxGm1m9WwMarxTglhy6dBTM4YkaV1I9h6pDGU",
- "oauth_secret": "luFZtPJg7j96K6WM6RpcZ_3M-r6muuDq6fG1ygk0I_4",
- "url": "https://master.apis.dev.openstreetmap.org"
- }
+ "#": "This client-id is registered by 'MapComplete' on osm.org",
+ "oauth_client_id": "K93H1d8ve7p-tVLE1ZwsQ4lAFLQk8INx5vfTLMu5DWk",
+ "oauth_secret": "NBWGhWDrD3QDB35xtVuxv4aExnmIt4FA_WgeLtwxasg",
+ "url": "https://www.openstreetmap.org"
},
"api_keys": {
"#": "Various API-keys for various services. Feel free to reuse those in another MapComplete-hosted version",
@@ -45,7 +32,8 @@
"https://overpass.kumi.systems/api/interpreter",
"https://overpass.openstreetmap.ru/cgi/interpreter"
],
- "country_coder_host": "https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/latlon2country"
+ "country_coder_host": "https://raw.githubusercontent.com/pietervdvn/MapComplete-data/main/latlon2country",
+ "nominatimEndpoint": "https://nominatim.openstreetmap.org/search?"
},
"scripts": {
"start": "npm run generate:layeroverview && npm run strt",
@@ -122,6 +110,7 @@
"chart.js": "^3.8.0",
"country-language": "^0.1.7",
"country-to-currency": "^1.0.10",
+ "crypto": "^1.0.1",
"csv-parse": "^5.1.0",
"doctest-ts-improved": "^0.8.8",
"dompurify": "^3.0.5",
diff --git a/scripts/build.sh b/scripts/build.sh
index 3b1cf07b8..6649d61ca 100755
--- a/scripts/build.sh
+++ b/scripts/build.sh
@@ -8,6 +8,8 @@ rm -rf dist/*
rm -rf .cache
mkdir dist 2> /dev/null
mkdir dist/assets 2> /dev/null
+mkdir dist/assets/langs 2> /dev/null
+mkdir dist/assets/langs/layers 2> /dev/null
export NODE_OPTIONS="--max-old-space-size=8192"
@@ -38,7 +40,8 @@ then
export ASSET_URL
echo "$ASSET_URL"
else
- ASSET_URL="$BRANCH"
+ # ASSET_URL="$BRANCH"
+ ASSET_URL="./"
export ASSET_URL
echo "$ASSET_URL"
fi
@@ -51,5 +54,5 @@ vite build $SRC_MAPS
cp -r assets/layers/ dist/assets/layers/
cp -r assets/themes/ dist/assets/themes/
cp -r assets/svg/ dist/assets/svg/
-
+cp -r langs/layers/ dist/assets/langs/layers/
export NODE_OPTIONS=""
diff --git a/scripts/generateLayouts.ts b/scripts/generateLayouts.ts
index d62a736d2..c938e07dc 100644
--- a/scripts/generateLayouts.ts
+++ b/scripts/generateLayouts.ts
@@ -8,7 +8,17 @@ import LayoutConfig from "../src/Models/ThemeConfig/LayoutConfig"
import xml2js from "xml2js"
import ScriptUtils from "./ScriptUtils"
import { Utils } from "../src/Utils"
-
+import SpecialVisualizations from "../src/UI/SpecialVisualizations"
+import Constants from "../src/Models/Constants"
+import {
+ AvailableRasterLayers,
+ EditorLayerIndexProperties,
+ RasterLayerPolygon,
+} from "../src/Models/RasterLayers"
+import { ImmutableStore } from "../src/Logic/UIEventSource"
+import * as crypto from "crypto"
+import * as eli from "../src/assets/editor-layer-index.json"
+import dom from "svelte/types/compiler/compile/render_dom"
const sharp = require("sharp")
const template = readFileSync("theme.html", "utf8")
const codeTemplate = readFileSync("src/index_theme.ts.template", "utf8")
@@ -195,31 +205,118 @@ function asLangSpan(t: Translation, tag = "span"): string {
if (lang === "_context") {
continue
}
- values.push(`<${tag} lang='${lang}'>${t.translations[lang]}${tag}>`)
+ values.push(`<${tag} lang="${lang}">${t.translations[lang]}${tag}>`)
}
return values.join("\n")
}
-let cspCached: string = undefined
-function generateCsp(): string {
- if (cspCached !== undefined) {
- return cspCached
+let previousSrc: Set = new Set()
+
+let eliUrlsCached: string[]
+function eliUrls(): string[] {
+ if (eliUrlsCached) {
+ return eliUrlsCached
+ }
+ const urls: string[] = []
+ const regex = /{switch:([^}]+)}/
+ for (const feature of eli.features) {
+ const url = (feature).properties.url
+ const match = url.match(regex)
+ if (match) {
+ const domains = match[1].split(",")
+ const subpart = match[0]
+ urls.push(...domains.map((d) => url.replace(subpart, d)))
+ } else {
+ urls.push(url)
+ }
+ }
+ eliUrlsCached = urls
+ return urls
+}
+
+function generateCsp(
+ layout: LayoutConfig,
+ options: {
+ scriptSrcs: string[]
+ }
+): string {
+ const apiUrls: string[] = [
+ "'self'",
+ ...Constants.defaultOverpassUrls,
+ Constants.countryCoderEndpoint,
+ Constants.nominatimEndpoint,
+ AvailableRasterLayers.maptilerCarto.properties.url,
+ AvailableRasterLayers.maptilerDefaultLayer.properties.url,
+ "https://api.openstreetmap.org",
+ "https://pietervdvn.goatcounter.com",
+ ]
+ .concat(...SpecialVisualizations.specialVisualizations.map((sv) => sv.needsUrls))
+ .concat(...eliUrls())
+
+ const geojsonSources: string[] = layout.layers.map((l) => l.source?.geojsonSource)
+ const hosts = new Set()
+ const eliLayers: RasterLayerPolygon[] = AvailableRasterLayers.layersAvailableAt(
+ new ImmutableStore({ lon: 0, lat: 0 })
+ ).data
+ const vectorLayers = eliLayers.filter((l) => l.properties.type === "vector")
+ const vectorSources = vectorLayers.map((l) => l.properties.url)
+ apiUrls.push(...vectorSources)
+ for (const connectSource of apiUrls.concat(geojsonSources)) {
+ if (!connectSource) {
+ continue
+ }
+ try {
+ const url = new URL(connectSource)
+ hosts.add("https://" + url.host)
+ } catch (e) {
+ hosts.add(connectSource)
+ }
}
- const csp = {
+ const connectSrc = Array.from(hosts).sort()
+
+ const newSrcs = connectSrc.filter((newItem) => !previousSrc.has(newItem))
+
+ console.log(
+ "Got",
+ hosts.size,
+ "connect-src items for theme",
+ layout.id,
+ "(extra sources: ",
+ newSrcs.join(" ") + ")"
+ )
+ previousSrc = hosts
+
+ const csp: Record = {
"default-src": "'self'",
- "script-src": "'self'",
- "img-src": "*",
- "connect-src": "*",
+ "script-src": ["'self'", "https://gc.zgo.at/count.js", ...(options?.scriptSrcs ?? [])].join(
+ " "
+ ),
+ "img-src": "* data:", // maplibre depends on 'data:' to load
+ "connect-src": connectSrc.join(" "),
+ "report-to": "https://report.mapcomplete.org/csp",
+ "worker-src": "'self' blob:", // Vite somehow loads the worker via a 'blob'
+ "style-src": "'self' 'unsafe-inline'", // unsafe-inline is needed to change the default background pin colours
}
const content = Object.keys(csp)
- .map((k) => k + ": " + csp[k])
+ .map((k) => k + " " + csp[k])
.join("; ")
- cspCached = ``
- return cspCached
+ return [
+ ``,
+ ``,
+ ].join("\n")
}
+const removeOtherLanguages = readFileSync("./src/UI/RemoveOtherLanguages.js", "utf8")
+ .split("\n")
+ .map((s) => s.trim())
+ .join("\n")
+const removeOtherLanguagesHash = crypto
+ .createHash("sha256")
+ .update(removeOtherLanguages)
+ .digest("base64")
+
async function createLandingPage(layout: LayoutConfig, manifest, whiteIcons, alreadyWritten) {
Locale.language.setData(layout.language[0])
const targetLanguage = layout.language[0]
@@ -290,8 +387,11 @@ async function createLandingPage(layout: LayoutConfig, manifest, whiteIcons, alr
...apple_icons,
].join("\n")
- const loadingText = Translations.t.general.loadingTheme.Subs({ theme: ogTitle })
-
+ const loadingText = Translations.t.general.loadingTheme.Subs({ theme: layout.title })
+ const templateLines = template.split("\n")
+ const removeOtherLanguagesReference = templateLines.find(
+ (line) => line.indexOf("./src/UI/RemoveOtherLanguages.js") >= 0
+ )
let output = template
.replace("Loading MapComplete, hang on...", asLangSpan(loadingText, "h1"))
.replace(
@@ -299,7 +399,13 @@ async function createLandingPage(layout: LayoutConfig, manifest, whiteIcons, alr
Translations.t.general.poweredByOsm.textFor(targetLanguage)
)
.replace(/.*/s, themeSpecific)
- .replace(//, generateCsp())
+ .replace(
+ //,
+ generateCsp(layout, {
+ scriptSrcs: [`'sha256-${removeOtherLanguagesHash}'`],
+ })
+ )
+ .replace(removeOtherLanguagesReference, "")
.replace(
/.*/s,
asLangSpan(layout.shortDescription)
@@ -310,8 +416,8 @@ async function createLandingPage(layout: LayoutConfig, manifest, whiteIcons, alr
)
.replace(
- '',
- ``
+ /.*\/src\/index\.ts.*/,
+ ``
)
return output
diff --git a/scripts/hetzner/config/Caddyfile b/scripts/hetzner/config/Caddyfile
index c3583e001..f6fedc58e 100644
--- a/scripts/hetzner/config/Caddyfile
+++ b/scripts/hetzner/config/Caddyfile
@@ -4,13 +4,16 @@ hosted.mapcomplete.org {
header {
+Permissions-Policy "interest-cohort=()"
+Report-To `\{"group":"csp-endpoint", "max_age": 86400,"endpoints": [\{"url": "https://report.mapcomplete.org/csp"}], "include_subdomains": true}`
- +Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' https://gc.zgo.at ; img-src * ; report-uri https://report.mapcomplete.org/csp ; report-to csp-endpoint ;"
}
}
countrycoder.mapcomplete.org {
root * tiles/
file_server
+ header {
+ +Permissions-Policy "interest-cohort=()"
+ +Access-Control-Allow-Origin https://hosted.mapcomplete.org https://dev.mapcomplete.org https://mapcomplete.org
+ }
}
diff --git a/scripts/hetzner/deployHetzner.sh b/scripts/hetzner/deployHetzner.sh
index 6f1044d22..af9443faf 100755
--- a/scripts/hetzner/deployHetzner.sh
+++ b/scripts/hetzner/deployHetzner.sh
@@ -10,15 +10,16 @@
# unzip tiles.zip
MAPCOMPLETE_CONFIGURATION="config_hetzner"
+cp config.json config.json.bu &&
+cp ./scripts/hetzner/config.json . && # Copy the config _before_ building, as the config might contain some needed URLs
npm run reset:layeroverview
npm run test
-cp config.json config.json.bu &&
-cp ./scripts/hetzner/config.json . &&
npm run prepare-deploy &&
mv config.json.bu config.json &&
zip dist.zip -r dist/* &&
-scp -r dist.zip hetzner:/root/ &&
-scp ./scripts/hetzner/config/* hetzner:/root/
-ssh hetzner -t "unzip dist.zip && rm dist.zip && rm -rf public/ && mv dist public && caddy stop && caddy start"
+scp ./scripts/hetzner/config/* hetzner:/root/ &&
+rsync -rzh --progress dist.zip hetzner:/root/ &&
+echo "Upload completed, deploying config and booting" &&
+ssh hetzner -t "unzip dist.zip && rm dist.zip && rm -rf public/ && mv dist public && caddy stop && caddy start" &&
rm dist.zip
npm run clean
diff --git a/src/InstallServiceWorker.ts b/src/InstallServiceWorker.ts
new file mode 100644
index 000000000..49afbed20
--- /dev/null
+++ b/src/InstallServiceWorker.ts
@@ -0,0 +1,13 @@
+export {}
+window.addEventListener("load", async () => {
+ if (!("serviceWorker" in navigator)) {
+ console.log("Service workers are not supported")
+ return
+ }
+ try {
+ await navigator.serviceWorker.register("/service-worker.js")
+ console.log("Service worker registration successful")
+ } catch (err) {
+ console.error("Service worker registration failed", err)
+ }
+})
diff --git a/src/Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource.ts b/src/Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource.ts
index 307312af3..c22f82433 100644
--- a/src/Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource.ts
+++ b/src/Logic/FeatureSource/Sources/NewGeometryFromChangesFeatureSource.ts
@@ -55,8 +55,13 @@ export class NewGeometryFromChangesFeatureSource implements WritableFeatureSourc
* @private
*/
private handleChange(change: ChangeDescription): boolean {
- const allElementStorage = this._allElementStorage
+ if (change.changes === undefined) {
+ // The geometry is not described - not a new point or geometry change, but probably a tagchange to a newly created point
+ // Not something that should be handled here
+ return false
+ }
+ const allElementStorage = this._allElementStorage
console.log("Handling pending change", change)
if (change.id > 0) {
// This is an already existing object
@@ -85,10 +90,6 @@ export class NewGeometryFromChangesFeatureSource implements WritableFeatureSourc
this._featureProperties.trackFeature(feature)
this.addNewFeature(feature)
return true
- } else if (change.changes === undefined) {
- // The geometry is not described - not a new point or geometry change, but probably a tagchange to a newly created point
- // Not something that should be handled here
- return false
}
try {
@@ -150,7 +151,7 @@ export class NewGeometryFromChangesFeatureSource implements WritableFeatureSourc
continue
}
- somethingChanged ||= this.handleChange(change)
+ somethingChanged = this.handleChange(change) || somethingChanged // important: _first_ evaluate the method, to avoid shortcutting
}
if (somethingChanged) {
this.features.ping()
diff --git a/src/Logic/ImageProviders/AllImageProviders.ts b/src/Logic/ImageProviders/AllImageProviders.ts
index 89318aeb3..5fc9c1ec7 100644
--- a/src/Logic/ImageProviders/AllImageProviders.ts
+++ b/src/Logic/ImageProviders/AllImageProviders.ts
@@ -23,27 +23,27 @@ export default class AllImageProviders {
)
),
]
-
+ public static apiUrls: string[] = [].concat(
+ ...AllImageProviders.ImageAttributionSource.map((src) => src.apiUrls())
+ )
+ public static defaultKeys = [].concat(
+ AllImageProviders.ImageAttributionSource.map((provider) => provider.defaultKeyPrefixes)
+ )
private static providersByName = {
imgur: Imgur.singleton,
mapillary: Mapillary.singleton,
wikidata: WikidataImageProvider.singleton,
wikimedia: WikimediaImageProvider.singleton,
}
-
- public static byName(name: string) {
- return AllImageProviders.providersByName[name.toLowerCase()]
- }
-
- public static defaultKeys = [].concat(
- AllImageProviders.ImageAttributionSource.map((provider) => provider.defaultKeyPrefixes)
- )
-
private static _cache: Map> = new Map<
string,
UIEventSource
>()
+ public static byName(name: string) {
+ return AllImageProviders.providersByName[name.toLowerCase()]
+ }
+
public static LoadImagesFor(
tags: Store>,
tagKey?: string[]
diff --git a/src/Logic/ImageProviders/GenericImageProvider.ts b/src/Logic/ImageProviders/GenericImageProvider.ts
index 4cb382b23..178137027 100644
--- a/src/Logic/ImageProviders/GenericImageProvider.ts
+++ b/src/Logic/ImageProviders/GenericImageProvider.ts
@@ -3,6 +3,10 @@ import ImageProvider, { ProvidedImage } from "./ImageProvider"
export default class GenericImageProvider extends ImageProvider {
public defaultKeyPrefixes: string[] = ["image"]
+ public apiUrls(): string[] {
+ return []
+ }
+
private readonly _valuePrefixBlacklist: string[]
public constructor(valuePrefixBlacklist: string[]) {
diff --git a/src/Logic/ImageProviders/ImageProvider.ts b/src/Logic/ImageProviders/ImageProvider.ts
index 92d3bc941..6d42623ce 100644
--- a/src/Logic/ImageProviders/ImageProvider.ts
+++ b/src/Logic/ImageProviders/ImageProvider.ts
@@ -65,4 +65,6 @@ export default abstract class ImageProvider {
public abstract ExtractUrls(key: string, value: string): Promise[]>
public abstract DownloadAttribution(url: string): Promise
+
+ public abstract apiUrls(): string[]
}
diff --git a/src/Logic/ImageProviders/Imgur.ts b/src/Logic/ImageProviders/Imgur.ts
index 536616403..b84fe606f 100644
--- a/src/Logic/ImageProviders/Imgur.ts
+++ b/src/Logic/ImageProviders/Imgur.ts
@@ -10,10 +10,16 @@ export class Imgur extends ImageProvider implements ImageUploader {
public static readonly singleton = new Imgur()
public readonly defaultKeyPrefixes: string[] = ["image"]
public readonly maxFileSizeInMegabytes = 10
+ public static readonly apiUrl = "https://api.imgur.com/3/image"
+
private constructor() {
super()
}
+ apiUrls(): string[] {
+ return [Imgur.apiUrl]
+ }
+
/**
* Uploads an image, returns the URL where to find the image
* @param title
@@ -25,7 +31,7 @@ export class Imgur extends ImageProvider implements ImageUploader {
description: string,
blob: File
): Promise<{ key: string; value: string }> {
- const apiUrl = "https://api.imgur.com/3/image"
+ const apiUrl = Imgur.apiUrl
const apiKey = Constants.ImgurApiKey
const formData = new FormData()
diff --git a/src/Logic/ImageProviders/Mapillary.ts b/src/Logic/ImageProviders/Mapillary.ts
index 102bb709b..96ec29ebc 100644
--- a/src/Logic/ImageProviders/Mapillary.ts
+++ b/src/Logic/ImageProviders/Mapillary.ts
@@ -17,6 +17,10 @@ export class Mapillary extends ImageProvider {
]
defaultKeyPrefixes = ["mapillary", "image"]
+ apiUrls(): string[] {
+ return ["https://mapillary.com", "https://www.mapillary.com", "https://graph.mapillary.com"]
+ }
+
/**
* Indicates that this is the same URL
* Ignores 'stp' parameter
diff --git a/src/Logic/ImageProviders/WikidataImageProvider.ts b/src/Logic/ImageProviders/WikidataImageProvider.ts
index 043fee4b7..1c7cbea8a 100644
--- a/src/Logic/ImageProviders/WikidataImageProvider.ts
+++ b/src/Logic/ImageProviders/WikidataImageProvider.ts
@@ -5,6 +5,9 @@ import { WikimediaImageProvider } from "./WikimediaImageProvider"
import Wikidata from "../Web/Wikidata"
export class WikidataImageProvider extends ImageProvider {
+ public apiUrls(): string[] {
+ return Wikidata.neededUrls
+ }
public static readonly singleton = new WikidataImageProvider()
public readonly defaultKeyPrefixes = ["wikidata"]
diff --git a/src/Logic/ImageProviders/WikimediaImageProvider.ts b/src/Logic/ImageProviders/WikimediaImageProvider.ts
index f9f40261d..a9841b8fd 100644
--- a/src/Logic/ImageProviders/WikimediaImageProvider.ts
+++ b/src/Logic/ImageProviders/WikimediaImageProvider.ts
@@ -11,11 +11,11 @@ import Wikimedia from "../Web/Wikimedia"
*/
export class WikimediaImageProvider extends ImageProvider {
public static readonly singleton = new WikimediaImageProvider()
- public static readonly commonsPrefixes = [
+ public static readonly apiUrls = [
"https://commons.wikimedia.org/wiki/",
"https://upload.wikimedia.org",
- "File:",
]
+ public static readonly commonsPrefixes = [...WikimediaImageProvider.apiUrls, "File:"]
private readonly commons_key = "wikimedia_commons"
public readonly defaultKeyPrefixes = [this.commons_key, "image"]
@@ -66,6 +66,10 @@ export class WikimediaImageProvider extends ImageProvider {
return value
}
+ apiUrls(): string[] {
+ return WikimediaImageProvider.apiUrls
+ }
+
SourceIcon(backlink: string): BaseUIElement {
const img = Svg.wikimedia_commons_white_svg().SetStyle("width:2em;height: 2em")
if (backlink === undefined) {
diff --git a/src/Logic/Maproulette.ts b/src/Logic/Maproulette.ts
index 50f550c43..922aa8384 100644
--- a/src/Logic/Maproulette.ts
+++ b/src/Logic/Maproulette.ts
@@ -1,6 +1,8 @@
import Constants from "../Models/Constants"
export default class Maproulette {
+ public static readonly defaultEndpoint = "https://maproulette.org/api/v2"
+
public static readonly STATUS_OPEN = 0
public static readonly STATUS_FIXED = 1
public static readonly STATUS_FALSE_POSITIVE = 2
@@ -20,59 +22,28 @@ export default class Maproulette {
6: "Too hard",
9: "Disabled",
}
-
+ public static singleton = new Maproulette()
/*
* The API endpoint to use
*/
endpoint: string
-
/**
* The API key to use for all requests
*/
private readonly apiKey: string
- public static singleton = new Maproulette()
/**
* Creates a new Maproulette instance
* @param endpoint The API endpoint to use
*/
- constructor(endpoint: string = "https://maproulette.org/api/v2") {
- this.endpoint = endpoint
+ constructor(endpoint?: string) {
+ this.endpoint = endpoint ?? Maproulette.defaultEndpoint
+ if (!this.endpoint) {
+ throw "MapRoulette endpoint is undefined. Make sure that `Maproulette.defaultEndpoint` is defined on top of the class"
+ }
this.apiKey = Constants.MaprouletteApiKey
}
- /**
- * Close a task; might throw an error
- *
- * Also see:https://maproulette.org/docs/swagger-ui/index.html?url=/assets/swagger.json&docExpansion=none#/Task/setTaskStatus
- * @param taskId The task to close
- * @param status A number indicating the status. Use MapRoulette.STATUS_*
- * @param options Additional settings to pass. Refer to the API-docs for more information
- */
- async closeTask(
- taskId: number,
- status = Maproulette.STATUS_FIXED,
- options?: {
- comment?: string
- tags?: string
- requestReview?: boolean
- completionResponses?: Record
- }
- ): Promise {
- const response = await fetch(`${this.endpoint}/task/${taskId}/${status}`, {
- method: "PUT",
- headers: {
- "Content-Type": "application/json",
- apiKey: this.apiKey,
- },
- body: options !== undefined ? JSON.stringify(options) : undefined,
- })
- if (response.status !== 204) {
- console.log(`Failed to close task: ${response.status}`)
- throw `Failed to close task: ${response.status}`
- }
- }
-
/**
* Converts a status text into the corresponding number
*
@@ -91,4 +62,37 @@ export default class Maproulette {
}
return undefined
}
+
+ /**
+ * Close a task; might throw an error
+ *
+ * Also see:https://maproulette.org/docs/swagger-ui/index.html?url=/assets/swagger.json&docExpansion=none#/Task/setTaskStatus
+ * @param taskId The task to close
+ * @param status A number indicating the status. Use MapRoulette.STATUS_*
+ * @param options Additional settings to pass. Refer to the API-docs for more information
+ */
+ async closeTask(
+ taskId: number,
+ status = Maproulette.STATUS_FIXED,
+ options?: {
+ comment?: string
+ tags?: string
+ requestReview?: boolean
+ completionResponses?: Record
+ }
+ ): Promise {
+ console.log("Maproulette: setting", `${this.endpoint}/task/${taskId}/${status}`, options)
+ const response = await fetch(`${this.endpoint}/task/${taskId}/${status}`, {
+ method: "PUT",
+ headers: {
+ "Content-Type": "application/json",
+ apiKey: this.apiKey,
+ },
+ body: options !== undefined ? JSON.stringify(options) : undefined,
+ })
+ if (response.status !== 204) {
+ console.log(`Failed to close task: ${response.status}`)
+ throw `Failed to close task: ${response.status}`
+ }
+ }
}
diff --git a/src/Logic/Osm/AuthConfig.ts b/src/Logic/Osm/AuthConfig.ts
new file mode 100644
index 000000000..b3c2330e2
--- /dev/null
+++ b/src/Logic/Osm/AuthConfig.ts
@@ -0,0 +1,6 @@
+export interface AuthConfig {
+ "#"?: string // optional comment
+ oauth_client_id: string
+ oauth_secret: string
+ url: string
+}
diff --git a/src/Logic/Osm/Changes.ts b/src/Logic/Osm/Changes.ts
index 208184848..2c0f8df02 100644
--- a/src/Logic/Osm/Changes.ts
+++ b/src/Logic/Osm/Changes.ts
@@ -525,11 +525,13 @@ export class Changes {
pending = pending.map((ch) => ChangeDescriptionTools.rewriteIds(ch, remappings))
console.log("Result is", pending)
}
+
const changes: {
newObjects: OsmObject[]
modifiedObjects: OsmObject[]
deletedObjects: OsmObject[]
} = self.CreateChangesetObjects(pending, objects)
+
return Changes.createChangesetFor("" + csId, changes)
},
metatags,
@@ -558,19 +560,11 @@ export class Changes {
const successes = await Promise.all(
Array.from(pendingPerTheme, async ([theme, pendingChanges]) => {
try {
- const openChangeset = this.state.osmConnection
- .GetPreference("current-open-changeset-" + theme)
- .sync(
- (str) => {
- const n = Number(str)
- if (isNaN(n)) {
- return undefined
- }
- return n
- },
- [],
- (n) => "" + n
+ const openChangeset = UIEventSource.asInt(
+ this.state.osmConnection.GetPreference(
+ "current-open-changeset-" + theme
)
+ )
console.log(
"Using current-open-changeset-" +
theme +
diff --git a/src/Logic/Osm/Geocoding.ts b/src/Logic/Osm/Geocoding.ts
index 09da7af6d..d3af5d6a5 100644
--- a/src/Logic/Osm/Geocoding.ts
+++ b/src/Logic/Osm/Geocoding.ts
@@ -1,5 +1,6 @@
import { Utils } from "../../Utils"
import { BBox } from "../BBox"
+import Constants from "../../Models/Constants"
export interface GeoCodeResult {
display_name: string
@@ -15,7 +16,7 @@ export interface GeoCodeResult {
}
export class Geocoding {
- private static readonly host = "https://nominatim.openstreetmap.org/search?"
+ public static readonly host = Constants.nominatimEndpoint
static async Search(query: string, bbox: BBox): Promise {
const b = bbox ?? BBox.global
diff --git a/src/Logic/Osm/OsmConnection.ts b/src/Logic/Osm/OsmConnection.ts
index 6f4e3755b..ecf29dcf2 100644
--- a/src/Logic/Osm/OsmConnection.ts
+++ b/src/Logic/Osm/OsmConnection.ts
@@ -4,7 +4,8 @@ import { Store, Stores, UIEventSource } from "../UIEventSource"
import { OsmPreferences } from "./OsmPreferences"
import { Utils } from "../../Utils"
import { LocalStorageSource } from "../Web/LocalStorageSource"
-import * as config from "../../../package.json"
+import { AuthConfig } from "./AuthConfig"
+import Constants from "../../Models/Constants"
export default class UserDetails {
public loggedIn = false
@@ -25,18 +26,9 @@ export default class UserDetails {
}
}
-export interface AuthConfig {
- "#"?: string // optional comment
- oauth_client_id: string
- oauth_secret: string
- url: string
-}
-
export type OsmServiceState = "online" | "readonly" | "offline" | "unknown" | "unreachable"
export class OsmConnection {
- public static readonly oauth_configs: Record =
- config.config.oauth_credentials
public auth
public userDetails: UIEventSource
public isLoggedIn: Store
@@ -53,7 +45,7 @@ export class OsmConnection {
public preferencesHandler: OsmPreferences
public readonly _oauth_config: AuthConfig
private readonly _dryRun: Store
- private fakeUser: boolean
+ private readonly fakeUser: boolean
private _onLoggedIn: ((userDetails: UserDetails) => void)[] = []
private readonly _iframeMode: Boolean | boolean
private readonly _singlePage: boolean
@@ -65,15 +57,12 @@ export class OsmConnection {
oauth_token?: UIEventSource
// Used to keep multiple changesets open and to write to the correct changeset
singlePage?: boolean
- osmConfiguration?: "osm" | "osm-test"
attemptLogin?: true | boolean
}) {
- options = options ?? {}
- this.fakeUser = options.fakeUser ?? false
- this._singlePage = options.singlePage ?? true
- this._oauth_config =
- OsmConnection.oauth_configs[options.osmConfiguration ?? "osm"] ??
- OsmConnection.oauth_configs.osm
+ options ??= {}
+ this.fakeUser = options?.fakeUser ?? false
+ this._singlePage = options?.singlePage ?? true
+ this._oauth_config = Constants.osmAuthConfig
console.debug("Using backend", this._oauth_config.url)
this._iframeMode = Utils.runningFromConsole ? false : window !== window.top
@@ -83,11 +72,8 @@ export class OsmConnection {
import.meta.env.VITE_OSM_OAUTH_SECRET !== undefined
) {
console.debug("Using environment variables for oauth config")
- this._oauth_config = {
- oauth_client_id: import.meta.env.VITE_OSM_OAUTH_CLIENT_ID,
- oauth_secret: import.meta.env.VITE_OSM_OAUTH_SECRET,
- url: "https://api.openstreetmap.org",
- }
+ this._oauth_config.oauth_client_id = import.meta.env.VITE_OSM_OAUTH_CLIENT_ID
+ this._oauth_config.oauth_secret = import.meta.env.VITE_OSM_OAUTH_SECRET
}
this.userDetails = new UIEventSource(
diff --git a/src/Logic/Osm/OsmPreferences.ts b/src/Logic/Osm/OsmPreferences.ts
index cd10b414f..cb009c074 100644
--- a/src/Logic/Osm/OsmPreferences.ts
+++ b/src/Logic/Osm/OsmPreferences.ts
@@ -1,9 +1,17 @@
import { UIEventSource } from "../UIEventSource"
import UserDetails, { OsmConnection } from "./OsmConnection"
import { Utils } from "../../Utils"
+import { LocalStorageSource } from "../Web/LocalStorageSource"
export class OsmPreferences {
- public preferences = new UIEventSource>({}, "all-osm-preferences")
+ /**
+ * A dictionary containing all the preferences. The 'preferenceSources' will be initialized from this
+ * We keep a local copy of them, to init mapcomplete with the previous choices and to be able to get the open changesets right away
+ */
+ public preferences = LocalStorageSource.GetParsed>(
+ "all-osm-preferences",
+ {}
+ )
private readonly preferenceSources = new Map>()
private auth: any
private userDetails: UIEventSource
diff --git a/src/Logic/State/FeatureSwitchState.ts b/src/Logic/State/FeatureSwitchState.ts
index a776ae6af..3fda13afd 100644
--- a/src/Logic/State/FeatureSwitchState.ts
+++ b/src/Logic/State/FeatureSwitchState.ts
@@ -28,15 +28,8 @@ class FeatureSwitchUtils {
export class OsmConnectionFeatureSwitches {
public readonly featureSwitchFakeUser: UIEventSource
- public readonly featureSwitchApiURL: UIEventSource
constructor() {
- this.featureSwitchApiURL = QueryParameters.GetQueryParameter(
- "backend",
- "osm",
- "The OSM backend to use - can be used to redirect mapcomplete to the testing backend when using 'osm-test'"
- )
-
this.featureSwitchFakeUser = QueryParameters.GetBooleanQueryParameter(
"fake-user",
false,
@@ -143,7 +136,6 @@ export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
let testingDefaultValue = false
if (
- this.featureSwitchApiURL.data !== "osm-test" &&
!Utils.runningFromConsole &&
(location.hostname === "localhost" || location.hostname === "127.0.0.1")
) {
@@ -172,7 +164,7 @@ export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
(urls) => urls?.join(",")
)
- this.overpassTimeout = UIEventSource.asFloat(
+ this.overpassTimeout = UIEventSource.asInt(
QueryParameters.GetQueryParameter(
"overpassTimeout",
"" + layoutToUse?.overpassTimeout,
@@ -188,7 +180,7 @@ export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
)
)
- this.osmApiTileSize = UIEventSource.asFloat(
+ this.osmApiTileSize = UIEventSource.asInt(
QueryParameters.GetQueryParameter(
"osmApiTileSize",
"" + layoutToUse?.osmApiTileSize,
diff --git a/src/Logic/UIEventSource.ts b/src/Logic/UIEventSource.ts
index 19b130ad5..20fb6ead8 100644
--- a/src/Logic/UIEventSource.ts
+++ b/src/Logic/UIEventSource.ts
@@ -612,6 +612,48 @@ export class UIEventSource extends Store implements Writable {
return src
}
+ /**
+ *
+ * @param source
+ * UIEventSource.asInt(new UIEventSource("123")).data // => 123
+ * UIEventSource.asInt(new UIEventSource("123456789")).data // => 123456789
+ *
+ * const srcStr = new UIEventSource("123456789"))
+ * const srcInt = UIEventSource.asInt(srcStr)
+ * srcInt.setData(987654321)
+ * srcStr.data // => "987654321"
+ */
+ public static asInt(source: UIEventSource): UIEventSource {
+ return source.sync(
+ (str) => {
+ let parsed = parseInt(str)
+ return isNaN(parsed) ? undefined : parsed
+ },
+ [],
+ (fl) => {
+ if (fl === undefined || isNaN(fl)) {
+ return undefined
+ }
+ return "" + fl
+ }
+ )
+ }
+
+ /**
+ * UIEventSource.asFloat(new UIEventSource("123")).data // => 123
+ * UIEventSource.asFloat(new UIEventSource("123456789")).data // => 123456789
+ * UIEventSource.asFloat(new UIEventSource("0.5")).data // => 0.5
+ * UIEventSource.asFloat(new UIEventSource("0.125")).data // => 0.125
+ * UIEventSource.asFloat(new UIEventSource("0.0000000001")).data // => 0.0000000001
+ *
+ *
+ * const srcStr = new UIEventSource("123456789"))
+ * const srcInt = UIEventSource.asFloat(srcStr)
+ * srcInt.setData(987654321)
+ * srcStr.data // => "987654321"
+ * @param source
+ */
+
public static asFloat(source: UIEventSource): UIEventSource {
return source.sync(
(str) => {
@@ -623,7 +665,7 @@ export class UIEventSource extends Store implements Writable {
if (fl === undefined || isNaN(fl)) {
return undefined
}
- return ("" + fl).substr(0, 8)
+ return "" + fl
}
)
}
diff --git a/src/Logic/Web/NearbyImagesSearch.ts b/src/Logic/Web/NearbyImagesSearch.ts
index 665cc66e7..2c81f19e0 100644
--- a/src/Logic/Web/NearbyImagesSearch.ts
+++ b/src/Logic/Web/NearbyImagesSearch.ts
@@ -1,9 +1,9 @@
import { IndexedFeatureSource } from "../FeatureSource/FeatureSource"
import { GeoOperations } from "../GeoOperations"
import { ImmutableStore, Store, Stores, UIEventSource } from "../UIEventSource"
-import { Mapillary } from "../ImageProviders/Mapillary"
import P4C from "pic4carto"
import { Utils } from "../../Utils"
+
export interface NearbyImageOptions {
lon: number
lat: number
@@ -35,17 +35,12 @@ export interface P4CPicture {
}
/**
- * Uses Pic4wCarto to fetch nearby images from various providers
+ * Uses Pic4Carto to fetch nearby images from various providers
*/
export default class NearbyImagesSearch {
- private static readonly services = [
- "mapillary",
- "flickr",
- "openstreetcam",
- "wikicommons",
- ] as const
-
- private individualStores
+ public static readonly services = ["mapillary", "flickr", "kartaview", "wikicommons"] as const
+ public static readonly apiUrls = ["https://api.flickr.com"]
+ private readonly individualStores: Store<{ images: P4CPicture[]; beforeFilter: number }>[]
private readonly _store: UIEventSource = new UIEventSource([])
public readonly store: Store = this._store
private readonly _options: NearbyImageOptions
@@ -71,16 +66,16 @@ export default class NearbyImagesSearch {
this.update()
}
- private static buildPictureFetcher(
+ private static async fetchImages(
options: NearbyImageOptions,
- fetcher: "mapillary" | "flickr" | "openstreetcam" | "wikicommons"
- ): Store<{ images: P4CPicture[]; beforeFilter: number }> {
+ fetcher: P4CService
+ ): Promise {
const picManager = new P4C.PicturesManager({ usefetchers: [fetcher] })
- const searchRadius = options.searchRadius ?? 100
const maxAgeSeconds = (options.maxDaysOld ?? 3 * 365) * 24 * 60 * 60 * 1000
+ const searchRadius = options.searchRadius ?? 100
- const p4cStore = Stores.FromPromise(
- picManager.startPicsRetrievalAround(
+ try {
+ const pics: P4CPicture[] = await picManager.startPicsRetrievalAround(
new P4C.LatLng(options.lat, options.lon),
searchRadius,
{
@@ -88,7 +83,21 @@ export default class NearbyImagesSearch {
towardscenter: false,
}
)
+ return pics
+ } catch (e) {
+ console.error("Could not fetch images from service", fetcher, e)
+ return []
+ }
+ }
+
+ private static buildPictureFetcher(
+ options: NearbyImageOptions,
+ fetcher: P4CService
+ ): Store<{ images: P4CPicture[]; beforeFilter: number }> {
+ const p4cStore = Stores.FromPromise(
+ NearbyImagesSearch.fetchImages(options, fetcher)
)
+ const searchRadius = options.searchRadius ?? 100
return p4cStore.map(
(images) => {
if (images === undefined) {
@@ -220,3 +229,5 @@ class ImagesInLoadedDataFetcher {
return foundImages
}
}
+
+type P4CService = (typeof NearbyImagesSearch.services)[number]
diff --git a/src/Logic/Web/PlantNet.ts b/src/Logic/Web/PlantNet.ts
index dab705ad0..4012040e0 100644
--- a/src/Logic/Web/PlantNet.ts
+++ b/src/Logic/Web/PlantNet.ts
@@ -1,7 +1,7 @@
import { Utils } from "../../Utils"
export default class PlantNet {
- private static baseUrl =
+ public static baseUrl =
"https://my-api.plantnet.org/v2/identify/all?api-key=2b10AAsjzwzJvucA5Ncm5qxe"
public static query(imageUrls: string[]): Promise {
diff --git a/src/Logic/Web/Wikidata.ts b/src/Logic/Web/Wikidata.ts
index 31eaa33d8..1f60f32ec 100644
--- a/src/Logic/Web/Wikidata.ts
+++ b/src/Logic/Web/Wikidata.ts
@@ -123,6 +123,11 @@ export interface WikidataAdvancedSearchoptions extends WikidataSearchoptions {
* Utility functions around wikidata
*/
export default class Wikidata {
+ public static readonly neededUrls = [
+ "https://www.wikidata.org/",
+ "https://wikidata.org/",
+ "https://query.wikidata.org",
+ ]
private static readonly _identifierPrefixes = ["Q", "L"].map((str) => str.toLowerCase())
private static readonly _prefixesToRemove = [
"https://www.wikidata.org/wiki/Lexeme:",
@@ -130,11 +135,11 @@ export default class Wikidata {
"http://www.wikidata.org/entity/",
"Lexeme:",
].map((str) => str.toLowerCase())
-
private static readonly _storeCache = new Map<
string,
Store<{ success: WikidataResponse } | { error: any }>
>()
+
/**
* Same as LoadWikidataEntry, but wrapped into a UIEventSource
* @param value
@@ -388,6 +393,7 @@ export default class Wikidata {
}
private static _cache = new Map>()
+
public static async LoadWikidataEntryAsync(value: string | number): Promise {
const key = "" + value
const cached = Wikidata._cache.get(key)
@@ -398,6 +404,7 @@ export default class Wikidata {
Wikidata._cache.set(key, uncached)
return uncached
}
+
/**
* Loads a wikidata page
* @returns the entity of the given value
diff --git a/src/Logic/Web/Wikipedia.ts b/src/Logic/Web/Wikipedia.ts
index 0cde301db..81f7bba90 100644
--- a/src/Logic/Web/Wikipedia.ts
+++ b/src/Logic/Web/Wikipedia.ts
@@ -34,6 +34,8 @@ export default class Wikipedia {
private static readonly idsToRemove = ["sjabloon_zie"]
+ public static readonly neededUrls = ["*.wikipedia.org"]
+
private static readonly _cache = new Map>()
private static _fullDetailsCache = new Map>()
public readonly backend: string
diff --git a/src/Models/Constants.ts b/src/Models/Constants.ts
index 75ea6f73f..ad68f6979 100644
--- a/src/Models/Constants.ts
+++ b/src/Models/Constants.ts
@@ -1,6 +1,7 @@
import * as packagefile from "../../package.json"
import * as extraconfig from "../../config.json"
import { Utils } from "../Utils"
+import { AuthConfig } from "../Logic/Osm/AuthConfig"
export type PriviligedLayerType = (typeof Constants.priviliged_layers)[number]
@@ -104,8 +105,9 @@ export default class Constants {
public static ImgurApiKey = Constants.config.api_keys.imgur
public static readonly mapillary_client_token_v4 = Constants.config.api_keys.mapillary_v4
public static defaultOverpassUrls = Constants.config.default_overpass_urls
- static countryCoderEndpoint: string = Constants.config.country_coder_host
-
+ public static countryCoderEndpoint: string = Constants.config.country_coder_host
+ public static osmAuthConfig: AuthConfig = Constants.config.oauth_credentials
+ public static nominatimEndpoint: string = Constants.config.nominatimEndpoint
/**
* These are the values that are allowed to use as 'backdrop' icon for a map pin
*/
diff --git a/src/Models/MapProperties.ts b/src/Models/MapProperties.ts
index a47acac57..c83a485ee 100644
--- a/src/Models/MapProperties.ts
+++ b/src/Models/MapProperties.ts
@@ -13,7 +13,6 @@ export interface MapProperties {
readonly allowMoving: UIEventSource
readonly allowRotating: UIEventSource
readonly lastClickLocation: Store<{ lon: number; lat: number }>
-
readonly allowZooming: UIEventSource
}
diff --git a/src/Models/ThemeConfig/PointRenderingConfig.ts b/src/Models/ThemeConfig/PointRenderingConfig.ts
index 885fe6d93..b43bbe5af 100644
--- a/src/Models/ThemeConfig/PointRenderingConfig.ts
+++ b/src/Models/ThemeConfig/PointRenderingConfig.ts
@@ -13,7 +13,6 @@ import Combine from "../../UI/Base/Combine"
import { VariableUiElement } from "../../UI/Base/VariableUIElement"
import { TagRenderingConfigJson } from "./Json/TagRenderingConfigJson"
import SvelteUIElement from "../../UI/Base/SvelteUIElement"
-import Marker from "../../UI/Map/Marker.svelte"
import DynamicMarker from "../../UI/Map/DynamicMarker.svelte"
export class IconConfig extends WithContextLoader {
@@ -83,7 +82,7 @@ export default class PointRenderingConfig extends WithContextLoader {
})
if (json.marker === undefined && json.label === undefined) {
- throw `${context}: A point rendering should define at least an icon or a marker`
+ throw `At ${context}: A point rendering should define at least an marker or a label`
}
if (this.location.size == 0) {
diff --git a/src/Models/ThemeViewState.ts b/src/Models/ThemeViewState.ts
index 1adc59b5a..a15f6b056 100644
--- a/src/Models/ThemeViewState.ts
+++ b/src/Models/ThemeViewState.ts
@@ -141,7 +141,6 @@ export default class ThemeViewState implements SpecialVisualizationState {
undefined,
"Used to complete the login"
),
- osmConfiguration: <"osm" | "osm-test">this.featureSwitches.featureSwitchApiURL.data,
})
this.userRelatedState = new UserRelatedState(
this.osmConnection,
@@ -538,7 +537,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.mapProperties.maxbounds.setData(bbox)
ShowDataLayer.showRange(
this.map,
- new StaticFeatureSource([bbox.asGeoJson({})]),
+ new StaticFeatureSource([bbox.asGeoJson({ id: "range" })]),
this.featureSwitches.featureSwitchIsTesting
)
}
@@ -576,7 +575,6 @@ export default class ThemeViewState implements SpecialVisualizationState {
}
this.featureProperties.trackFeatureSource(features)
- // this.indexedFeatures.addSource(features)
new ShowDataLayer(this.map, {
features,
doShowLayer: flayer.isDisplayed,
diff --git a/src/UI/AllThemesGui.ts b/src/UI/AllThemesGui.ts
index 437fb3ac4..94be0e5f7 100644
--- a/src/UI/AllThemesGui.ts
+++ b/src/UI/AllThemesGui.ts
@@ -23,7 +23,6 @@ export default class AllThemesGui {
undefined,
"Used to complete the login"
),
- osmConfiguration: <"osm" | "osm-test">featureSwitches.featureSwitchApiURL.data,
})
const state = new UserRelatedState(osmConnection)
const intro = new Combine([
diff --git a/src/UI/BigComponents/OpenJosm.ts b/src/UI/BigComponents/OpenJosm.ts
index 8f86f6d98..3eafbd2ac 100644
--- a/src/UI/BigComponents/OpenJosm.ts
+++ b/src/UI/BigComponents/OpenJosm.ts
@@ -11,6 +11,7 @@ import { Utils } from "../../Utils"
import Constants from "../../Models/Constants"
export class OpenJosm extends Combine {
+ public static readonly needsUrls = ["http://127.0.0.1:8111/load_and_zoom"]
constructor(osmConnection: OsmConnection, bounds: Store, iconStyle?: string) {
const t = Translations.t.general.attribution
diff --git a/src/UI/BigComponents/SelectedElementView.svelte b/src/UI/BigComponents/SelectedElementView.svelte
index 62408bfca..924d6f7f3 100644
--- a/src/UI/BigComponents/SelectedElementView.svelte
+++ b/src/UI/BigComponents/SelectedElementView.svelte
@@ -14,13 +14,6 @@
export let tags: UIEventSource>
export let highlightedRendering: UIEventSource = undefined
- let _tags: Record
- onDestroy(
- tags.addCallbackAndRun((tags) => {
- _tags = tags
- })
- )
-
let _metatags: Record
onDestroy(
state.userRelatedState.preferencesAsTags.addCallbackAndRun((tags) => {
@@ -29,7 +22,7 @@
)
-{#if _tags._deleted === "yes"}
+{#if $tags._deleted === "yes"}