feat(train): routes planned through the instance's BRouter (ADR 0030, D44)

The routing endpoint plans a route through the waypoints for one of six
profiles, for the people signed in, at most 50 waypoints and 30 plans a
person a minute, nothing kept or logged; refused without BROUTER_URL.
BRouter's GeoJSON is read into points, elevations, climb and descent
above 3 m, turn hints and stretches by surface. Train's running profile
for BRouter, halkyon-run.brf, is a first guess not yet tried on BRouter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-28 23:37:47 +01:00
commit 781576726a
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -0,0 +1,135 @@
# Halkyon Train's running profile for BRouter (ADR 0030, D44): BRouter has
# none for running, its hiking profiles sending runners up steps and rough
# paths, its cycling ones off footpaths. Paths, footways, tracks and quiet
# streets first, any surface; big roads only where nothing else goes, steps
# and scrambles avoided, motorways never. Written on BRouter's `shortest.brf`
# (its access rules and its voice hints' classifiers kept), 28 Oct 2026; not
# yet tried on a BRouter: the costs are a first guess, to be tuned on runs.
---context:global # following code refers to global config
# A climb costs a little, as it does a runner; going down costs nothing.
assign downhillcost 0
assign downhillcutoff 1.5
assign uphillcost 15
assign uphillcutoff 1.5
assign turnInstructionMode = 2 # locus-style, as Train asks for
assign validForFoot 1
---context:way # following code refers to way-tags
assign turncost 0
assign initialclassifier =
if route=ferry then 1
else 0
assign initialcost switch route=ferry 10000 0
#
# implicit access here just from the motorroad tag
#
assign defaultaccess
switch access=
(
if motorroad=yes then false
else if highway=motorway|motorway_link then false
else true
)
switch or access=private access=no
false
true
#
# foot access
#
assign footaccess
switch foot=
defaultaccess
not or foot=private or foot=no foot=use_sidepath
# A big road is run along on its sidewalk where it has one.
assign hassidewalk = or sidewalk=both|left|right|yes or sidewalk:both=yes or sidewalk:left=yes sidewalk:right=yes
# Scrambles and climbing routes are no running.
assign isscramble = sac_scale=demanding_mountain_hiking|alpine_hiking|demanding_alpine_hiking|difficult_alpine_hiking
assign costfactor
add switch footaccess 0 100000
switch and highway= not route=ferry 100000
switch route=ferry 5.67
switch or highway=motorway highway=motorway_link 100000
switch or highway=proposed highway=abandoned 100000
switch isscramble 20
switch highway=path|footway|pedestrian|track|bridleway 1
switch highway=living_street|residential|service|cycleway 1.15
switch highway=steps 3
switch highway=unclassified|road 1.3
switch highway=tertiary|tertiary_link switch hassidewalk 1.3 1.8
switch highway=secondary|secondary_link switch hassidewalk 1.5 2.5
switch highway=primary|primary_link switch hassidewalk 1.8 4
switch highway=trunk|trunk_link switch hassidewalk 3 10
1.5
# way priorities used for voice hint generation (as BRouter's own)
assign isresidentialorliving = or highway=residential|living_street living_street=yes
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 ( 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
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
assign classifiermask add multiply isroundabout 4
add multiply islinktype 8
multiply isgoodforcars 16
# The surface and smoothness in the answer's way tags, for the planner's
# stretches.
assign dummyUsage = or surface= smoothness=
---context:node # following code refers to node tags
assign defaultaccess
switch access=
1
switch or access=private access=no
0
1
assign footaccess
switch foot=
defaultaccess
switch or foot=private foot=no
0
1
assign initialcost switch footaccess 0 1000000