Writing a BRouter profile

I recently started to have a deeper look into routing for bikes, on top of
OpenStreetMap data and came across
BRouter. This article is a follow-up to the
first and
second ones and it will quickly cover
how to write your own profile or extend a profile.

The main (official) documentation about profile development is the
profile developers
guide. It can be
quite lengthy but covers well all the basis. The main parts you have to worry
about to write your profile is the
lookups.dat and the profiles files.

The lookups.dat has already been covered in the previous
article of this series. The only
additional point to keep in mind is that when you use aliases in this file,
only the first value will be emitted: zone:maxspeed;0000001616 20 DE:20
FR:20 will only emit a single usable value (20) in profile for the three
possible values (20, DE:20 and FR:20).

Quick overview of the key points for writing a BRouter profile

The profile developers
guide covers all the
valid expressions in the profile file (variables, operations, etc). Note that
all operators use a prefix notation and not the (rather usual) infix notation.

Let us have a look at the
trekking.brf
profile. There are three different contexts: global, way and node.

costfactor
which is a cost proportional to the length of the way and is actually the main
cost source.

In the node context, only initialcost is to be filled.

Personal tips for writing BRouter profiles

Here is a quick list of personal tips after writing and contributing to some
BRouter profiles (and reviewing a bunch of them!):

There are a
lot,
really a lot,
quitetoomany, really too
many
profiles out there. This is a personal view but I rather believe in a “one
size fits all” approach for BRouter profiles than a super optimized
profile for each possible use case, including the current weather. Plus
having many variables means you are likely to over-optimize for your
specific route and the profile will not be easily reusable.

When testing your profile on routes, try to use diverse routes and check on
the full set. Optimizing for a particular use case might actually be
over-optimization and is likely to give bad results on other routes.

brouter-web has a “Data” tab
which gives the complete details of the current route and the associated
costs. Coupled with putting waypoints to force a particular route, it is
really a super valuable tool to write profiles and find about costs!

Unit-testing BRouter profiles for easier development

Wetneb introduced the idea of having a kind of unit-testing to help writing
profiles in this issue. This
is a super useful idea indeed, to be able to compare profiles and prevent
regressions when tweaking variables.

In this notebook, I tried to have a mix of routes and edge cases to cover
typical use cases and ensure my profile is not overfitting for a particular
use case:

Complete routes I am familiar with, either in large city (Paris), medium
sized city (Clermont-Ferrand), following bike routes (cycle travel) and in
the countryside (out of marked bike routes).

Tests on specific features. For these tests, you should take care to have a
“stable” route meaning that if you move slightly the start or end point
for your edge case, the BRouter route is not moving, so that the test can
actually be significant (and avoid hysteretic behavior).