Repository: openstreetmap/iD (JavaScript)

Issue:
Add rendering for climbing route features
### Description

Right now, climbing features don't have any styling
> <img width="688" alt="Image" src="https://github.com/user-attachments/assets/c988ba39-a3df-485b-933a-6d5f4ef4c737" />

[Location](https://ideditor.netlify.app/#locale=en&map=17.54/68.16505/16.59361&disable_features=boundaries&background=geovekst-nib)

The issues connected to https://github.com/openstreetmap/id-tagging-schema/issues/31 work on addding presets for those features.

I think we should look into adding some styling for those ways as well.

### Screenshots

Looking at existing styles (Left to right: Ladder, Steps, Slipway(Drivable), Chair Lift) I think something that looks similar to Ladder/Steps is good, maybe with a red color like the chair lift (something that highlights the "danger" :)).

<img width="520" alt="Image" src="https://github.com/user-attachments/assets/c2005a24-064b-4a18-8b45-4d932f92f9b5" />



Fix (patch):
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 79e60443f32..2a09e2d36fb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -43,6 +43,7 @@ _Breaking developer changes, which may affect downstream projects or sites that
 * Consider other name-like tags for labelling features, such as `lock_name` ([#9588], thanks [@k-yle])
 * Always take reduced map size due to open side panels into account when zooming to selected entities
 * Limit landuse tags that are considered for "Landuse" area features ([#11184], thanks [@youssefelzedy])
+* Render climbing routes and via ferrata ways as dotted lines ([#11133], thanks [@harahu])
 #### :scissors: Operations
 #### :camera: Street-Level
 * Fix bug where "tag photo id on selected map feature" is sometimes not working on the first opened photo ([#11021])
@@ -69,12 +70,13 @@ _Breaking developer changes, which may affect downstream projects or sites that
 [#10645]: https://github.com/openstreetmap/iD/pull/10645
 [#11020]: https://github.com/openstreetmap/iD/pull/11020
 [#11021]: https://github.com/openstreetmap/iD/issues/11021
+[#11133]: https://github.com/openstreetmap/iD/issues/11133
 [#11184]: https://github.com/openstreetmap/iD/pull/11184
 [#11206]: https://github.com/openstreetmap/iD/issues/11206
 [#11211]: https://github.com/openstreetmap/iD/issues/11211
 [#11247]: https://github.com/openstreetmap/iD/issues/11247
 [@bhavyaKhatri2703]: https://github.com/bhavyaKhatri2703
-
+[@harahu]: https://github.com/harahu
 
 # v2.35.3
 ##### 2025-07-19
diff --git a/css/30_highways.css b/css/30_highways.css
index a997d63e7b8..21221358890 100644
--- a/css/30_highways.css
+++ b/css/30_highways.css
@@ -269,6 +269,7 @@ path.line.shadow.tag-highway-cycleway,
 path.line.shadow.tag-highway-bridleway,
 path.line.shadow.tag-highway-corridor,
 path.line.shadow.tag-highway-ladder,
+path.line.shadow.tag-highway-via_ferrata,
 path.line.shadow.tag-highway-steps {
     stroke-width: 16;
 }
@@ -278,6 +279,7 @@ path.line.casing.tag-highway-cycleway,
 path.line.casing.tag-highway-bridleway,
 path.line.casing.tag-highway-corridor,
 path.line.casing.tag-highway-ladder,
+path.line.casing.tag-highway-via_ferrata,
 path.line.casing.tag-highway-steps {
     stroke-width: 5;
 }
@@ -287,6 +289,7 @@ path.line.stroke.tag-highway-cycleway,
 path.line.stroke.tag-highway-bridleway,
 path.line.stroke.tag-highway-corridor,
 path.line.stroke.tag-highway-ladder,
+path.line.stroke.tag-highway-via_ferrata,
 path.line.stroke.tag-highway-steps {
     stroke-width: 3;
 }
@@ -340,6 +343,7 @@ path.line.stroke.tag-highway-steps {
 .low-zoom path.line.shadow.tag-highway-bridleway,
 .low-zoom path.line.shadow.tag-highway-corridor,
 .low-zoom path.line.shadow.tag-highway-ladder,
+.low-zoom path.line.shadow.tag-highway-via_ferrata,
 .low-zoom path.line.shadow.tag-highway-steps {
     stroke-width: 12;
 }
@@ -349,6 +353,7 @@ path.line.stroke.tag-highway-steps {
 .low-zoom path.line.casing.tag-highway-bridleway,
 .low-zoom path.line.casing.tag-highway-corridor,
 .low-zoom path.line.casing.tag-highway-ladder,
+.low-zoom path.line.casing.tag-highway-via_ferrata,
 .low-zoom path.line.casing.tag-highway-steps {
     stroke-width: 3;
 }
@@ -358,6 +363,7 @@ path.line.stroke.tag-highway-steps {
 .low-zoom path.line.stroke.tag-highway-bridleway,
 .low-zoom path.line.stroke.tag-highway-corridor,
 .low-zoom path.line.stroke.tag-highway-ladder,
+.low-zoom path.line.stroke.tag-highway-via_ferrata,
 .low-zoom path.line.stroke.tag-highway-steps {
     stroke-width: 1;
 }
@@ -640,6 +646,16 @@ path.line.stroke.tag-highway-ladder,
     stroke: #fff;
 }
 
+path.line.casing.tag-highway-via_ferrata {
+    stroke: none;
+}
+
+path.line.stroke.tag-highway-via_ferrata {
+    stroke-width: 5;
+    stroke: #6f1f1f;
+    stroke-linecap: round;
+    stroke-dasharray: 0, 9;
+}
 
 /* crossings */
 path.line.stroke.tag-highway.tag-crossing-unmarked {
diff --git a/css/50_misc.css b/css/50_misc.css
index ad28c1c5e7c..1a6de0d6791 100644
--- a/css/50_misc.css
+++ b/css/50_misc.css
@@ -113,6 +113,13 @@ path.line.casing.tag-piste {
     stroke: #444;
 }
 
+/* climbing routes */
+path.line.stroke.tag-climbing-route {
+    stroke: #6f1f1f;
+    stroke-linecap: round;
+    stroke-dasharray: 0, 7;
+    stroke-width: 3;
+}
 
 /* Attractions */
 path.line.stroke.tag-attraction-summer_toboggan {
diff --git a/modules/svg/tag_classes.js b/modules/svg/tag_classes.js
index b74853a367d..b7e2c9358fd 100644
--- a/modules/svg/tag_classes.js
+++ b/modules/svg/tag_classes.js
@@ -7,7 +7,7 @@ export function svgTagClasses() {
         'building', 'highway', 'railway', 'waterway', 'aeroway', 'aerialway',
         'piste:type', 'boundary', 'power', 'amenity', 'natural', 'landuse',
         'leisure', 'military', 'place', 'man_made', 'route', 'attraction',
-        'roller_coaster', 'building:part', 'indoor'
+        'roller_coaster', 'building:part', 'indoor', 'climbing'
     ];
     var statuses = Object.keys(osmLifecyclePrefixes);
     var secondaries = [
diff --git a/modules/ui/preset_icon.js b/modules/ui/preset_icon.js
index 935d3c8c27f..4522aad2b30 100644
--- a/modules/ui/preset_icon.js
+++ b/modules/ui/preset_icon.js
@@ -353,6 +353,7 @@ export function uiPresetIcon() {
   const routeSegments = {
     bicycle: ['highway/cycleway', 'highway/cycleway', 'highway/cycleway'],
     bus: ['highway/unclassified', 'highway/secondary', 'highway/primary'],
+    climbing: ['climbing/route', 'climbing/route', 'climbing/route'],
     trolleybus: ['highway/unclassified', 'highway/secondary', 'highway/primary'],
     detour: ['highway/tertiary', 'highway/residential', 'highway/unclassified'],
     ferry: ['route/ferry', 'route/ferry', 'route/ferry'],