From 85aa87edb08acdbf26228f1e932df8c32e2f7cdf Mon Sep 17 00:00:00 2001 From: 4aiman Date: Mon, 26 Oct 2026 21:08:22 +0300 Subject: [PATCH] BRouter trekking: avoid fords / grade5 tracks / bad-visibility trails by default Routed through icy fords and abandoned descents 3x. Penalise ford nodes & ways (ford=yes|stepping_stones), tracktype=grade5 and trail_visibility=bad|horrible|no in the trekking profile, gated by a new %allow_adventure% param (default false = avoid). Both profile copies (asset + staging) kept in sync. NOTE: profile syntax must be verified by routing on device; a bad profile makes routeBrouter error out (safe), not produce bad routes. --- .../assets/brouter/profiles2/trekking.brf | 21 +- .../profiles2/trekking.brf | 447 ++++++++++++++++++ 2 files changed, 462 insertions(+), 6 deletions(-) create mode 100644 tools/brouter-web-staging/profiles2/trekking.brf diff --git a/src-tauri/gen/android/app/src/main/assets/brouter/profiles2/trekking.brf b/src-tauri/gen/android/app/src/main/assets/brouter/profiles2/trekking.brf index af3aef2..b4fd21b 100644 --- a/src-tauri/gen/android/app/src/main/assets/brouter/profiles2/trekking.brf +++ b/src-tauri/gen/android/app/src/main/assets/brouter/profiles2/trekking.brf @@ -58,6 +58,8 @@ assign processUnusedTags = false # %processUnusedTags% | Set true to assign unpavedPenalty = 1.0 # %unpavedPenalty% | Extra penalty multiplier applied to the non-probablyGood cost of track/road/path/footway ways depending on tracktype grade | number +assign allow_adventure = false # %allow_adventure% | Set true to ALLOW fords, grade5 tracks and bad-visibility trails (adventure mode). Default false avoids them. | boolean + ---context:way # following code refers to way-tags # classifier constants @@ -128,9 +130,16 @@ assign initialclassifier = # this is added to the total cost each time the costfactor # changed # +# Adventure penalty: keep the router off fords, abandoned (grade5) tracks and +# bad/invisible trails unless the rider opts into adventure mode (%allow_adventure%). +assign adventurepenalty = + if allow_adventure then 0 + else add ( if ford=yes|stepping_stones then 100000 else 0 ) + ( if or tracktype=grade5 trail_visibility=bad|horrible|no then 20000 else 0 ) + assign initialcost = - if ( equal initialclassifier classifier_ferry ) then 10000 - else 0 + add adventurepenalty + ( if ( equal initialclassifier classifier_ferry ) then 10000 else 0 ) # # implicit access here just from the motorroad tag @@ -432,7 +441,7 @@ assign footaccess = else not foot=private|no assign initialcost = - if or highway=traffic_signals and highway=crossing crossing=traffic_signals then 20 - else - if bikeaccess then 0 - else ( if footaccess then 100 else 1000000 ) + add ( if allow_adventure then 0 else if ford=yes|stepping_stones then 100000 else 0 ) + ( if or highway=traffic_signals and highway=crossing crossing=traffic_signals then 20 + else if bikeaccess then 0 + else ( if footaccess then 100 else 1000000 ) ) diff --git a/tools/brouter-web-staging/profiles2/trekking.brf b/tools/brouter-web-staging/profiles2/trekking.brf new file mode 100644 index 0000000..b4fd21b --- /dev/null +++ b/tools/brouter-web-staging/profiles2/trekking.brf @@ -0,0 +1,447 @@ +# *** The trekking profile is for slow travel +# *** and avoiding car traffic, but still with +# *** a focus on approaching your destination +# *** efficiently. + +---context:global # following code refers to global config + +# Bike profile +assign validForBikes = true + +# Use the following switches to change behaviour +assign allow_steps = true # %allow_steps% | Set false to disallow steps | boolean +assign allow_ferries = true # %allow_ferries% | Set false to disallow ferries | boolean +assign ignore_cycleroutes = false # %ignore_cycleroutes% | Set true for better elevation results | boolean +assign stick_to_cycleroutes = false # %stick_to_cycleroutes% | Set true to just follow cycleroutes | boolean +assign use_proposed_cycleroutes = false # %use_proposed_cycleroutes% | Set to true to consider proposed and regular cycleroutes as equals | boolean +assign avoid_unsafe = false # %avoid_unsafe% | Set true to avoid standard highways | boolean + +assign add_beeline = false # %add_beeline% | Enable beeline on distant start/end points | boolean + +assign consider_noise = false # %consider_noise% | Activate to prefer a low-noise route | boolean +assign consider_river = false # %consider_river% | Activate to prefer a route along rivers, lakes, etc. | boolean +assign consider_forest = false # %consider_forest% | Activate to prefer a route in forest or parks | boolean +assign consider_town = false # %consider_town% | Activate to bypass cities / big towns as far as possible | boolean +assign consider_traffic = false # %consider_traffic% | Activate to consider traffic estimates | boolean + + + +# Change elevation parameters +assign consider_elevation = true # %consider_elevation% | Set true to favor a route with few elevation meters | boolean + +assign downhillcost = 60 # %downhillcost% | Cost for going downhill | number +assign downhillcutoff = 1.5 # %downhillcutoff% | Gradients below this value in percents are not counted. | number +assign uphillcost = 0 # %uphillcost% | Cost for going uphill | number +assign uphillcutoff = 1.5 # %uphillcutoff% | Gradients below this value in percents are not counted. | number + +assign downhillcost = if consider_elevation then downhillcost else 0 +assign uphillcost = if consider_elevation then uphillcost else 0 + +# Kinematic model parameters (travel time computation) +assign totalMass = 90 # %totalMass% | Mass (in kg) of the bike + biker, for travel time computation | number +assign maxSpeed = 45 # %maxSpeed% | Absolute maximum speed (in km/h), for travel time computation | number +assign S_C_x = 0.225 # %S_C_x% | Drag coefficient times the reference area (in m^2), for travel time computation | number +assign C_r = 0.01 # %C_r% | Rolling resistance coefficient (dimensionless), for travel time computation | number +assign bikerPower = 100 # %bikerPower% | Average power (in W) provided by the biker, for travel time computation | number + +# Turn instructions settings +assign turnInstructionMode = 1 # %turnInstructionMode% | Mode for the generated turn instructions | [0=none, 1=auto-choose, 2=locus-style, 3=osmand-style, 4=comment-style, 5=gpsies-style, 6=orux-style, 7=locus-old-style] +assign turnInstructionCatchingRange = 40 # %turnInstructionCatchingRange% | Within this distance (in m) several turning instructions are combined into one and the turning angles are better approximated to the general direction | number +assign turnInstructionRoundabouts = true # %turnInstructionRoundabouts% | Set "false" to avoid generating special turning instructions for roundabouts | boolean +assign considerTurnRestrictions = true # %considerTurnRestrictions% | Set true to take turn restrictions into account | boolean + +# with engine defaults, long parts of routing to via points may be removed +assign correctMisplacedViaPoints = false # %correctMisplacedViaPoints% | Set to true to remove detours due to via points (going back and forth on the same route) | boolean +assign correctMisplacedViaPointsDistance = 400 # %correctMisplacedViaPointsDistance% | Only remove detours shorter than this (one-way) distance (in m) (engine defaults to 0 which removes detours whatever their length) | number + +assign processUnusedTags = false # %processUnusedTags% | Set true to output unused tags in data tab | boolean + +assign unpavedPenalty = 1.0 # %unpavedPenalty% | Extra penalty multiplier applied to the non-probablyGood cost of track/road/path/footway ways depending on tracktype grade | number + +assign allow_adventure = false # %allow_adventure% | Set true to ALLOW fords, grade5 tracks and bad-visibility trails (adventure mode). Default false avoids them. | boolean + +---context:way # following code refers to way-tags + +# classifier constants +assign classifier_none = 1 +assign classifier_ferry = 2 + +# +# pre-calculate some logical expressions +# + +assign any_cycleroute = + if not use_proposed_cycleroutes then + if route_bicycle_icn=yes then true + else if route_bicycle_ncn=yes then true + else if route_bicycle_rcn=yes then true + else if route_bicycle_lcn=yes then true + else false + else + if route_bicycle_icn=yes|proposed then true + else if route_bicycle_ncn=yes|proposed then true + else if route_bicycle_rcn=yes|proposed then true + else if route_bicycle_lcn=yes|proposed then true + else false + +assign nodeaccessgranted = + if any_cycleroute then true + else lcn=yes + +assign is_ldcr = + if ignore_cycleroutes then false + else any_cycleroute + +# set isbike considering access, local cycle route or the presence of a cycleway on the highway +assign hasbikerouteoraccess = + or bicycle_road=yes or cyclestreet=yes or bicycle=yes|permissive|designated lcn=yes + +assign hascycleway = not + and ( or cycleway= cycleway=no|none ) and ( or cycleway:left= cycleway:left=no ) and ( or cycleway:right= cycleway:right=no ) ( or cycleway:both= cycleway:both=no ) + +assign isbike = or hasbikerouteoraccess hascycleway + +assign ispaved = or surface=paved|asphalt|concrete|paving_stones|sett smoothness=excellent|good +assign isunpaved = not or ispaved or ( and surface= smoothness= ) or surface=fine_gravel|cobblestone smoothness=intermediate|bad +assign probablyGood = or ispaved and ( or isbike highway=footway ) not isunpaved + + +# +# this is the cost (in Meter) for a 90-degree turn +# The actual cost is calculated as turncost*cos(angle) +# (Suppressing turncost while following longdistance-cycleways +# makes them a little bit more magnetic) +# +assign turncost = if is_ldcr then 0 + else if junction=roundabout then 0 + else 90 + + +# +# for any change in initialclassifier, initialcost is added once +# +assign initialclassifier = + if route=ferry then classifier_ferry + else classifier_none + + +# +# calculate the initial cost +# this is added to the total cost each time the costfactor +# changed +# +# Adventure penalty: keep the router off fords, abandoned (grade5) tracks and +# bad/invisible trails unless the rider opts into adventure mode (%allow_adventure%). +assign adventurepenalty = + if allow_adventure then 0 + else add ( if ford=yes|stepping_stones then 100000 else 0 ) + ( if or tracktype=grade5 trail_visibility=bad|horrible|no then 20000 else 0 ) + +assign initialcost = + add adventurepenalty + ( if ( equal initialclassifier classifier_ferry ) then 10000 else 0 ) + +# +# implicit access here just from the motorroad tag +# (implicit access rules from highway tag handled elsewhere) +# +assign defaultaccess = + if access= then not motorroad=yes + else if access=private|no then false + else true + +# +# calculate logical bike access +# +assign bikeaccess = + if bicycle= then + ( + if bicycle_road=yes then true + else if vehicle= then ( if highway=footway then false else defaultaccess ) + else not vehicle=private|no + ) + else not bicycle=private|no|dismount|use_sidepath + +# +# calculate logical foot access +# +assign footaccess = + if bicycle=dismount then true + else if foot= then defaultaccess + else not foot=private|no|use_sidepath + +# +# if not bike-, but foot-access, just a moderate penalty, +# otherwise access is forbidden +# +assign accesspenalty = + if bikeaccess then 0 + else if footaccess then 4 + else if any_cycleroute then 15 + else if bicycle=use_sidepath then 25 + else 10000 + +# +# handle one-ways. On primary roads, wrong-oneways should +# be close to forbidden, while on other ways we just add +# 4 to the costfactor (making it at least 5 - you are allowed +# to push your bike) + +# are we against legal direction on a oneway? +assign badoneway = + if reversedirection=yes then + if oneway:bicycle=yes then true + else if oneway= then junction=roundabout + else oneway=yes|true|1 + else oneway=-1 + +assign onewaypenalty = + if ( badoneway ) then + ( + if ( + and hascycleway + or and cycleway:left=lane|track|shared_lane|share_busway + cycleway:left:oneway=no|-1 + or and cycleway:right=lane|track|shared_lane|share_busway + cycleway:right:oneway=no|-1 + or and cycleway:both=lane|track|shared_lane|share_busway + #or cycleway:both:oneway=no|-1 + or cycleway:left:oneway=no|-1 + cycleway:right:oneway=no|-1 + or cycleway=opposite|opposite_lane|opposite_track + or cycleway:left=opposite|opposite_lane|opposite_track + cycleway:right=opposite|opposite_lane|opposite_track + ) then 0 + else if ( oneway:bicycle=no ) then 0 + else if ( not footaccess ) then 100 + else if ( junction=roundabout|circular ) then 60 + else if ( highway=primary|primary_link ) then 50 + else if ( highway=secondary|secondary_link ) then 30 + else if ( highway=tertiary|tertiary_link ) then 20 + else 4.0 + ) + else 0.0 + +# add estimate tags +assign traffic_penalty + switch consider_traffic + switch estimated_traffic_class= 0 + switch estimated_traffic_class=1|2 0.2 + switch estimated_traffic_class=3 0.4 + switch estimated_traffic_class=4 0.6 + switch estimated_traffic_class=5 0.8 + switch estimated_traffic_class=6|7 1 99 0 + + +assign noise_penalty + switch consider_noise + switch estimated_noise_class= 0 + switch estimated_noise_class=1 0.3 + switch estimated_noise_class=2 0.5 + switch estimated_noise_class=3 0.8 + switch estimated_noise_class=4 1.4 + switch estimated_noise_class=5 1.7 + switch estimated_noise_class=6 2 0 0 + +assign no_river_penalty + switch consider_river + switch estimated_river_class= 2 + switch estimated_river_class=1 1.3 + switch estimated_river_class=2 1 + switch estimated_river_class=3 0.7 + switch estimated_river_class=4 0.4 + switch estimated_river_class=5 0.1 + switch estimated_river_class=6 0 99 0 + +assign no_forest_penalty + switch consider_forest + switch estimated_forest_class= 1 + switch estimated_forest_class=1 0.5 + switch estimated_forest_class=2 0.4 + switch estimated_forest_class=3 0.25 + switch estimated_forest_class=4 0.15 + switch estimated_forest_class=5 0.1 + switch estimated_forest_class=6 0 99 0 + +assign town_penalty + switch consider_town + switch estimated_town_class= 0 + switch estimated_town_class=1 0.5 + switch estimated_town_class=2 0.9 + switch estimated_town_class=3 1.2 + switch estimated_town_class=4 1.3 + switch estimated_town_class=5 1.4 + switch estimated_town_class=6 1.6 99 0 + +# +# calculate the cost-factor, which is the factor +# by which the distance of a way-segment is multiplied +# to calculate the cost of that segment. The costfactor +# must be >=1 and it's supposed to be close to 1 for +# the type of way the routing profile is searching for +# +assign isresidentialorliving = or highway=residential|living_street living_street=yes +assign costfactor + + # + # exclude rivers, rails etc. + # + if ( and highway= not route=ferry ) then 10000 + + # + # exclude motorways and proposed, abandoned under construction roads + # + else if ( highway=motorway|motorway_link ) then 10000 + else if ( highway=proposed|abandoned|construction ) then 10000 + + # + # all other exclusions below (access, steps, ferries,..) + # should not be deleted by the decoder, to be available + # in voice-hint-processing + # + else min 9999 + + add town_penalty + add no_forest_penalty + add no_river_penalty + add noise_penalty + add traffic_penalty + + # + # apply oneway-and access-penalties + # + add max onewaypenalty accesspenalty + + # + # steps and ferries are special. Note this is handled + # before the cycleroute-switch, to be able + # to really exclude them be setting cost to infinity + # + if ( highway=steps ) then ( if allow_steps then 40 else 10000 ) + else if ( route=ferry ) then ( if allow_ferries then 5.67 else 10000 ) + + # + # handle long-distance cycle-routes. + # + else if ( is_ldcr ) then 1 # always treated as perfect (=1) + else + add ( if stick_to_cycleroutes then 0.5 else 0.05 ) # everything else somewhat up + + # + # some other highway types + # + if ( highway=pedestrian ) then ( if isbike then ( if hascycleway then 1.1 else 2.2 ) else 3 ) + else if ( highway=bridleway ) then 5 + else if ( highway=cycleway ) then 1 + else if ( isresidentialorliving ) then ( if isunpaved then 1.5 else 1.1 ) + else if ( highway=service ) then ( if isunpaved then 1.6 else 1.3 ) + + # + # tracks and track-like ways are rated mainly be tracktype/grade + # But note that if no tracktype is given (mainly for road/path/footway) + # it can be o.k. if there's any other hint for quality + # + else if ( highway=track|road|path|footway ) then + ( + if ( tracktype=grade1 ) then ( if probablyGood then 1.0 else add 1.0 multiply 0.3 unpavedPenalty ) + else if ( tracktype=grade2 ) then ( if probablyGood then 1.1 else add 1.1 multiply 0.9 unpavedPenalty ) + else if ( tracktype=grade3 ) then ( if probablyGood then 1.5 else add 1.5 multiply 1.5 unpavedPenalty ) + else if ( tracktype=grade4 ) then ( if probablyGood then 2.0 else add 2.0 multiply 3.0 unpavedPenalty ) + else if ( tracktype=grade5 ) then ( if probablyGood then 3.0 else add 3.0 multiply 2.0 unpavedPenalty ) + else ( if probablyGood then 1.0 else add 1.0 multiply 4.0 unpavedPenalty ) + ) + + # + # When avoiding unsafe ways, avoid highways without a bike hint + # + else add ( if ( and avoid_unsafe not isbike ) then 2 else 0 ) + + # + # actuals roads are o.k. if we have a bike hint + # + if ( highway=trunk|trunk_link ) then ( if isbike then 1.5 else 10 ) + else if ( highway=primary|primary_link ) then ( if isbike then 1.2 else 3 ) + else if ( highway=secondary|secondary_link ) then ( if isbike then 1.1 else 1.6 ) + else if ( highway=tertiary|tertiary_link ) then ( if isbike then 1.0 else 1.4 ) + else if ( highway=unclassified ) then ( if isbike then 1.0 else 1.3 ) + + # + # default for any other highway type not handled above + # + else 2.0 + + +# way priorities used for voice hint generation + +assign priorityclassifier = + + if ( highway=motorway ) then 30 + else if ( highway=motorway_link ) then 29 + else if ( highway=trunk ) then 28 + else if ( highway=trunk_link ) then 27 + else if ( highway=primary ) then 26 + else if ( highway=primary_link ) then 25 + else if ( highway=secondary ) then 24 + else if ( highway=secondary_link ) then 23 + else if ( highway=tertiary ) then 22 + else if ( highway=tertiary_link ) then 21 + else if ( highway=unclassified ) then 20 + else if ( isresidentialorliving ) then 6 + else if ( highway=service ) then 6 + else if ( highway=cycleway ) then 6 + else if ( or bicycle=designated bicycle_road=yes ) then 6 + else if ( highway=track ) then if tracktype=grade1 then 6 else 4 + else if ( highway=bridleway|road|path|footway ) then 4 + else if ( highway=steps ) then 2 + else if ( highway=pedestrian ) then 2 + else 0 + +# some more classifying bits used for voice hint generation... + +assign isbadoneway = not equal onewaypenalty 0 +assign isgoodoneway = if reversedirection=yes then oneway=-1 + else if oneway= then junction=roundabout else oneway=yes|true|1 +assign isroundabout = junction=roundabout +assign islinktype = highway=motorway_link|trunk_link|primary_link|secondary_link|tertiary_link +assign isgoodforcars = if greater priorityclassifier 6 then true + else if ( or isresidentialorliving highway=service ) then true + else if ( and highway=track tracktype=grade1 ) then true + else false + +# ... encoded into a bitmask + +assign classifiermask add isbadoneway + add multiply isgoodoneway 2 + add multiply isroundabout 4 + add multiply islinktype 8 + multiply isgoodforcars 16 + +# include `smoothness=` tags in the response's WayTags for track analysis +assign dummyUsage = smoothness= + +---context:node # following code refers to node tags + +assign defaultaccess = + if ( access= ) then true # add default barrier restrictions here! + else if ( access=private|no ) then false + else true + +assign bikeaccess = + if nodeaccessgranted=yes then true + else if bicycle= then + ( + if vehicle= then defaultaccess + else not vehicle=private|no + ) + else not bicycle=private|no|dismount + +assign footaccess = + if bicycle=dismount then true + else if foot= then defaultaccess + else not foot=private|no + +assign initialcost = + add ( if allow_adventure then 0 else if ford=yes|stepping_stones then 100000 else 0 ) + ( if or highway=traffic_signals and highway=crossing crossing=traffic_signals then 20 + else if bikeaccess then 0 + else ( if footaccess then 100 else 1000000 ) )