diff --git a/Customizations/AllKnownLayouts.ts b/Customizations/AllKnownLayouts.ts
index ef4d43546..19290f902 100644
--- a/Customizations/AllKnownLayouts.ts
+++ b/Customizations/AllKnownLayouts.ts
@@ -15,6 +15,7 @@ import * as benches from "../assets/themes/benches/benches.json";
import * as charging_stations from "../assets/themes/charging_stations/charging_stations.json"
import * as widths from "../assets/themes/widths/width.json"
import * as drinking_water from "../assets/themes/drinking_water/drinking_water.json"
+import * as climbing from "../assets/themes/climbing/climbing.json"
import * as surveillance_cameras from "../assets/themes/surveillance_cameras/surveillance_cameras.json"
import * as personal from "../assets/themes/personalLayout/personalLayout.json"
import LayerConfig from "./JSON/LayerConfig";
@@ -62,6 +63,7 @@ export class AllKnownLayouts {
// new LayoutConfig(buurtnatuur),
// new LayoutConfig(bike_monitoring_stations),
// new LayoutConfig(surveillance_cameras)
+ new LayoutConfig(climbing),
];
diff --git a/Customizations/JSON/LayerConfigJson.ts b/Customizations/JSON/LayerConfigJson.ts
index 98df035ff..caa19d5e3 100644
--- a/Customizations/JSON/LayerConfigJson.ts
+++ b/Customizations/JSON/LayerConfigJson.ts
@@ -91,8 +91,8 @@ export interface LayerConfigJson {
/**
* Wayhandling: should a way/area be displayed as:
* 0) The way itself
- * 1) The centerpoint and the way
- * 2) Only the centerpoint
+ * 1) Only the centerpoint
+ * 2) The centerpoint and the way
*/
wayHandling?: number;
diff --git a/Logic/Osm/ChangesetHandler.ts b/Logic/Osm/ChangesetHandler.ts
index a432bc08a..5c23ac5f1 100644
--- a/Logic/Osm/ChangesetHandler.ts
+++ b/Logic/Osm/ChangesetHandler.ts
@@ -1,3 +1,4 @@
+import escapeHtml from "escape-html";
import {OsmConnection, UserDetails} from "./OsmConnection";
import {UIEventSource} from "../UIEventSource";
import {ElementStorage} from "../ElementStorage";
@@ -105,7 +106,7 @@ export class ChangesetHandler {
``,
``,
surveySource,
- layout.maintainer !== undefined ? `` : "",
+ layout.maintainer !== undefined ? `` : "",
``].join("")
}, function (err, response) {
if (response === undefined) {
diff --git a/UI/UserBadge.ts b/UI/UserBadge.ts
index 04ffcd9ac..614c5c541 100644
--- a/UI/UserBadge.ts
+++ b/UI/UserBadge.ts
@@ -109,7 +109,7 @@ export class UserBadge extends UIElement {
const userName = new Link(
new FixedUiElement(user.name),
- `https://www.openstreetmap.org/user/${user.name}'`,
+ `https://www.openstreetmap.org/user/${user.name}`,
true);
diff --git a/assets/questions/questions.json b/assets/questions/questions.json
index 2595eab2c..557f1add4 100644
--- a/assets/questions/questions.json
+++ b/assets/questions/questions.json
@@ -1,8 +1,31 @@
{
+ "email": {
+ "render": "{email}",
+ "freeform": {
+ "key": "email",
+ "type": "email"
+ }
+ },
+
"images": {
"render": "{image_carousel()}{image_upload()}"
},
-
+
+ "opening_hours": {
+ "question": {
+ "en": "What are the opening hours of {name}?",
+ "de": "Was sind die Öffnungszeiten von {name}?"
+ },
+ "render": {
+ "de": "
Öffnungszeiten
{opening_hours_table(opening_hours)}",
+ "en": "Opening hours
{opening_hours_table(opening_hours)}"
+ },
+ "freeform": {
+ "key": "opening_hours",
+ "type": "opening_hours"
+ }
+ },
+
"osmlink": {
"render": "",
"mappings":[{
@@ -11,6 +34,18 @@
}]
},
+ "phone": {
+ "question": {
+ "en": "What is the phone number of {name}?",
+ "de": "Was ist die Telefonnummer von {name}?"
+ },
+ "render": "{phone}",
+ "freeform": {
+ "key": "phone",
+ "type": "phone"
+ }
+ },
+
"wikipedialink": {
"render": "",
"condition": "wikipedia~*"
@@ -18,10 +53,11 @@
"website": {
"question": {
- "en": "What is the website of {name}?",
- "nl": "Wat is de website van {name}?",
- "fr": "Quel est le site internet de {name}?",
- "gl": "Cal é a páxina web de {name}?"
+ "en": "What is the officical website of {name}?",
+ "de": "Was ist die offizielle Website von {name}?",
+ "nl": "Wat is de officiële website van {name}?",
+ "fr": "Quel est le site internet officiel de {name}?",
+ "gl": "Cal é a páxina web official de {name}?"
},
"render": "{website}",
"freeform": {
@@ -29,4 +65,4 @@
"type": "url"
}
}
-}
\ No newline at end of file
+}
diff --git a/assets/themes/climbing/climbing.json b/assets/themes/climbing/climbing.json
new file mode 100644
index 000000000..2ff41f7d1
--- /dev/null
+++ b/assets/themes/climbing/climbing.json
@@ -0,0 +1,435 @@
+{
+ "id": "climbing",
+ "title": {
+ "nl": "Open Klimkaart",
+ "de": "Offene Kletterkarte",
+ "en": "Open Climbing Map"
+ },
+ "description": {
+ "nl": "Op deze kaart vind je verschillende klimgelegenheden, zoals klimzalen, bolderzalen en klimmen in de natuur",
+ "de": "Auf dieser Karte finden Sie verschiedene Klettermöglichkeiten wie Kletterhallen, Boulderhallen und Felsen in der Natur.",
+ "en": "On this map you will find various climbing opportunities such as climbing gyms, bouldering halls and rocks in nature."
+ },
+ "language": [
+ "de",
+ "en"
+ ],
+ "maintainer": "Christian Neumann ",
+ "icon": "./assets/themes/climbing/climbing_no_rope.svg",
+ "version": "0",
+ "startLat": 0,
+ "startLon": 0,
+ "startZoom": 1,
+ "widenFactor": 0.05,
+ "socialImage": "",
+ "layers": [
+ {
+ "id": "climbing",
+ "name": {
+ "nl": "Klimgelegenheiden",
+ "de": "Klettermöglichkeiten",
+ "en": "Climbing opportunities"
+ },
+ "minzoom": 10,
+ "overpassTags": {
+ "and": [
+ "sport=climbing",
+ "climbing!~route",
+ "leisure!~sports_centre"
+ ]
+ },
+ "title": {
+ "render": {
+ "en": "Climbing opportunity",
+ "nl": "Klimgelegenheid",
+ "de": "Klettermöglichkeit"
+ }
+ },
+ "description": {
+ "nl": "Een klimgelegenheid",
+ "de": "Eine Klettergelegenheit",
+ "en": "A climbing opportunity"
+ },
+ "tagRenderings": [
+ {
+ "render": {
+ "en": "{name}",
+ "nl": "{name}",
+ "de": "{name}"
+ },
+ "question": {
+ "en": "What is the name of this climbing opportunity?",
+ "nl": "Wat is de naam van dit Klimgelegenheid?",
+ "de": "Wie heißt diese Klettergelegenheit?"
+ },
+ "freeform": {
+ "key": "name"
+ },
+ "mappings": [
+ {
+ "if": {
+ "and": [
+ "noname=yes",
+ "name="
+ ]
+ },
+ "then": {
+ "en": "This climbing opportunity doesn't have a name",
+ "nl": "Dit Klimgelegenheid heeft geen naam",
+ "de": "Diese Klettergelegenheit hat keinen Namen"
+ }
+ }
+ ]
+ }
+ ],
+ "hideUnderlayingFeaturesMinPercentage": 0,
+ "icon": {
+ "render": "./assets/themes/climbing/climbing_no_rope.svg"
+ },
+ "width": {
+ "render": "8"
+ },
+ "iconSize": {
+ "render": "40,40,center"
+ },
+ "color": {
+ "render": "#00f"
+ },
+ "presets": [
+ {
+ "tags": [
+ "sport=climbing"
+ ],
+ "title": {
+ "en": "Climbing opportunity",
+ "nl": "Klimgelegenheid",
+ "de": "Klettermöglichkeit"
+ },
+ "description": {
+ "nl": "Een klimgelegenheid",
+ "de": "Eine Klettergelegenheit",
+ "en": "A climbing opportunity"
+ }
+ }
+ ],
+ "wayHandling": 1
+ },
+ {
+ "id": "climbing_gym",
+ "name": {
+ "de": "Kletterhallen",
+ "en": "Climbing gyms"
+ },
+ "minzoom": 10,
+ "overpassTags": {
+ "and": [
+ "sport=climbing",
+ "leisure=sports_centre"
+ ]
+ },
+ "title": {
+ "render": {
+ "nl": "Klimzaal",
+ "de": "Kletterhalle",
+ "en": "Climbing gym"
+ }
+ },
+ "description": {
+ "de": "Eine Kletterhalle",
+ "en": "A climbing gym"
+ },
+ "tagRenderings": [
+ {
+ "render": {
+ "en": "{name}",
+ "nl": "{name}",
+ "de": "{name}"
+ },
+ "question": {
+ "en": "What is the name of this climbing gym?",
+ "nl": "Wat is de naam van dit Klimzaal?",
+ "de": "Wie heißt diese Kletterhalle?"
+ },
+ "freeform": {
+ "key": "name"
+ }
+ },
+ "website",
+ "phone",
+ "email",
+ "opening_hours"
+ ],
+ "hideUnderlayingFeaturesMinPercentage": 0,
+ "icon": {
+ "render": "./assets/themes/climbing/climbing_gym.svg"
+ },
+ "width": "0",
+ "iconSize": {
+ "render": "40,40,center"
+ },
+ "wayHandling": 1
+ },
+ {
+ "id": "climbing_route",
+ "name": {
+ "en": "Climbing routes",
+ "de": "Kletterrouten"
+ },
+ "minzoom": 18,
+ "overpassTags": {
+ "and": [
+ "climbing=route"
+ ]
+ },
+ "title": {
+ "render": {
+ "de": "Kleterroute",
+ "en": "Climbing route"
+ }
+ },
+ "tagRenderings": [
+ {
+ "render": {
+ "en": "{name}",
+ "nl": "{name}",
+ "de": "{name}"
+ },
+ "question": {
+ "en": "What is the name of this climbing route?",
+ "de": "Wie heißt diese Kletterroute?"
+ },
+ "freeform": {
+ "key": "name"
+ },
+ "mappings": [
+ {
+ "if": {
+ "and": [
+ "noname=yes",
+ "name="
+ ]
+ },
+ "then": {
+ "en": "This climbing route doesn't have a name",
+ "de": "Diese Kletterroute hat keinen Namen"
+ }
+ }
+ ]
+ }
+ ],
+ "hideUnderlayingFeaturesMinPercentage": 1,
+ "icon": {
+ "render": "./assets/themes/climbing/climbing_route.svg"
+ },
+ "width": {
+ "render": "4"
+ },
+ "iconSize": {
+ "render": "20,20,center"
+ },
+ "color": {
+ "render": "#0f0"
+ }
+ }
+ ],
+ "roamingRenderings": [
+ {
+ "question": {
+ "en": "Is there a (unofficial) website with more informations (e.g. topos)?",
+ "de": "Gibt es eine (inoffizielle) Website mit mehr Informationen (z.B. Topos)?"
+ },
+ "condition": {
+ "and": [
+ "leisure!~sports_centre",
+ "sport=climbing"
+ ]
+ },
+ "render": "{url}",
+ "freeform": {
+ "key": "url",
+ "type": "url"
+ }
+ },
+ {
+ "render": {
+ "de": "Die Routen sind durchschnittlich {climbing:length}m lang",
+ "en": "The routes are {climbing:length}m long in average"
+ },
+ "condition": {
+ "and": [
+ "climbing!~route",
+ {
+ "or": [
+ "climbing=sport",
+ "climbing=traditional"
+ ]
+ }
+ ]
+ },
+ "question": {
+ "de": "Wie lang sind die Routen (durchschnittlich) in Metern?",
+ "en": "What is the (average) length of the routes in meters?"
+ },
+ "freeform": {
+ "key": "climbing:length",
+ "type": "pnat"
+ }
+ },
+ {
+ "question": {
+ "de": "Kann hier gebouldert werden?",
+ "en": "Is bouldering possible here?"
+ },
+ "mappings": [
+ {
+ "if": "climbing:boulder=yes",
+ "then": {
+ "de": "Hier kann gebouldert werden",
+ "en": "Bouldering is possible here"
+ }
+ },
+ {
+ "if": "climbing:boulder=no",
+ "then": {
+ "de": "Hier kann nicht gebouldert werden",
+ "en": "Bouldering is not possible here"
+ }
+ },
+ {
+ "if": "climbing:boulder~*",
+ "then": {
+ "de": "Hier gibt es {climbing:boulder} Boulder-Routen",
+ "en": "There are {climbing:boulder} boulder routes"
+ },
+ "hideInAnswer": true
+ }
+ ]
+ },
+ {
+ "question": {
+ "de": "Ist Toprope-Klettern hier möglich?",
+ "en": "Is toprope climbing possible here?"
+ },
+ "mappings": [
+ {
+ "if": "climbing:toprope=yes",
+ "then": {
+ "de": "Toprope-Klettern ist hier möglich",
+ "en": "Toprope climbing is possible here"
+ }
+ },
+ {
+ "if": "climbing:toprope=no",
+ "then": {
+ "de": "Toprope-Climbing ist hier nicht möglich",
+ "en": "Toprope climbing is not possible here"
+ }
+ },
+ {
+ "if": "climbing:toprope~*",
+ "then": {
+ "de": "Hier gibt es {climbing:toprope} Toprope-Routen",
+ "en": "There are {climbing:toprope} toprope routes"
+ },
+ "hideInAnswer": true
+ }
+ ]
+ },
+ {
+ "question": {
+ "de": "Ist hier Sportklettern möglich (feste Ankerpunkte)?",
+ "en": "Is sport climbing possible here (fixed anchors)?"
+ },
+ "mappings": [
+ {
+ "if": "climbing:sport=yes",
+ "then": {
+ "de": "Sportklettern ist hier möglich",
+ "en": "Sport climbing is possible here"
+ }
+ },
+ {
+ "if": "climbing:sport=no",
+ "then": {
+ "de": "Sportklettern ist hier nicht möglich",
+ "en": "Sport climbing is not possible here"
+ }
+ },
+ {
+ "if": "climbing:sport~*",
+ "then": {
+ "de": "Hier gibt es {climbing:sport} Sportkletter-Routen",
+ "en": "There are {climbing:sport} sport climbing routes"
+ },
+ "hideInAnswer": true
+ }
+ ]
+ },
+ {
+ "question": {
+ "de": "Ist hier traditionelles Klettern möglich (eigene Sicherung z.B. mit Klemmkleilen)?",
+ "en": "Is traditional climbing possible here (using own gear e.g. chocks)?"
+ },
+ "mappings": [
+ {
+ "if": "climbing:traditional=yes",
+ "then": {
+ "de": "Traditionelles Klettern ist hier möglich",
+ "en": "Traditional climbing is possible here"
+ }
+ },
+ {
+ "if": "climbing:traditional=no",
+ "then": {
+ "de": "Traditionelles Klettern ist hier nicht möglich",
+ "en": "Traditional climbing is not possible here"
+ }
+ },
+ {
+ "if": "climbing:traditional~*",
+ "then": {
+ "de": "Hier gibt es {climbing:traditional} Routen für traditionelles Klettern",
+ "en": "There are {climbing:traditional} traditional climbing routes"
+ },
+ "hideInAnswer": true
+ }
+ ]
+ },
+ {
+ "question": {
+ "de": "Gibt es hier eine Speedkletter-Wand?",
+ "en": "Is there a speed climbing wall?"
+ },
+ "condition": {
+ "and": [
+ "leisure=sports_centre",
+ "climbing:sport=yes"
+ ]
+ },
+ "mappings": [
+ {
+ "if": "climbing:speed=yes",
+ "then": {
+ "de": "Hier gibt es eine Speedkletter-Wand",
+ "en": "There is a speed climbing wall"
+ }
+ },
+ {
+ "if": "climbing:speed=no",
+ "then": {
+ "de": "Hier gibt es keine Speedkletter-Wand",
+ "en": "There is no speed climbing wall"
+ }
+ },
+ {
+ "if": "climbing:speed~*",
+ "then": {
+ "de": "Hier gibt es {climbing:speed} Speedkletter-Routen",
+ "en": "There are {climbing:speed} speed climbing walls"
+ },
+ "hideInAnswer": true
+ }
+ ]
+ }
+ ]
+}
diff --git a/assets/themes/climbing/climbing_gym.svg b/assets/themes/climbing/climbing_gym.svg
new file mode 100644
index 000000000..6818a8f19
--- /dev/null
+++ b/assets/themes/climbing/climbing_gym.svg
@@ -0,0 +1,86 @@
+
+
diff --git a/assets/themes/climbing/climbing_no_rope.svg b/assets/themes/climbing/climbing_no_rope.svg
new file mode 100644
index 000000000..3703f4b9f
--- /dev/null
+++ b/assets/themes/climbing/climbing_no_rope.svg
@@ -0,0 +1,71 @@
+
+
diff --git a/assets/themes/climbing/climbing_rope.svg b/assets/themes/climbing/climbing_rope.svg
new file mode 100644
index 000000000..f225524a4
--- /dev/null
+++ b/assets/themes/climbing/climbing_rope.svg
@@ -0,0 +1,81 @@
+
+
diff --git a/assets/themes/climbing/climbing_route.svg b/assets/themes/climbing/climbing_route.svg
new file mode 100644
index 000000000..e1829a86b
--- /dev/null
+++ b/assets/themes/climbing/climbing_route.svg
@@ -0,0 +1,85 @@
+
+