Setting up your own BRouter instance and start hacking

Posted on November 05, 2018 in Dev • 7 min read

I recently started to have a deeper look into routing for bikes, on top of OpenStreetMap data and came across BRouter. The website and the app might seem old school, but this is definitely one of the best routing engine out there (especially for bikes) and it is FOSS! One of the great advantage of BRouter is that it is written in Java and is light enough so that it can run on Android devices!

In this first article, we’ll install our own instance and quickly go through the various components. In a future article, we’ll focus on profiles and profile development.

Note: My instance is live at brouter.phyks.me (note that the server is not super powerful so the routing computation might take some time). Segments are available for metropolitan France only. More on the available profiles at the end of this article.

Getting the BRouter code and building it

BRouter code is available on Github. There are multiple components (folders) in the repository. The more important are:

  • brouter-core (the core logic)
  • brouter-routing-app (the Android part)
  • brouter-server (the HTTP server which exposes an HTTP API on top of Brouter)
  • misc with a lot of utility scripts, profiles and helpers.

In this article, we will focus on setting up a web interface for Brouter (similar to http://brouter.de/brouter-web/). We then want to build only the brouter-server part (and its dependencies). This can be quickly done using:

mvn install -pl brouter-server -am -Dmaven.javadoc.skip=true -DskipTests

Note: For those which are not familiar with Java (as I am), mvn install just builds the code (not actually doing an install as in make install). -pl brouter-server -am makes it only build brouter-server (and dependencies), which is required if you don’t want to deal with setting up Android Studio to correctly build the Android part. -Dmaven.javadoc.skip=true skips the JavaDoc part (documentation generation from the code, such as Doxygen or Python Sphinx). -DskipTests do not run the unittests.

You can then run (replace the 1.4.11 by the current version)

java -Xmx128M -Xms128M -Xmn8M -DmaxRunningTime=300 -cp brouter-server/target/brouter-server-1.4.11-jar-with-dependencies.jar btools.server.RouteServer misc/segments4 misc/profiles2 customprofiles 17777 1

to actually run the server (a very basic helper script is available as well). In this command line, -Xmx128M -Xms128M -Xmn8M -DmaxRunningTime=300 are just the default parameters to limit the memory consumption. misc/segments4, misc/profiles2 and customprofiles are folder to store the segments file and the profiles (see below). 17777 is the port to listen on.

EDIT: customprofiles are profiles written by users and sent to BRouter-server to use it (through a file upload feature, basically), instead of limiting the server to the profiles provided by default. In Brouter-web, you can access this feature by clicking the spanner icon on the right hande side. With the previous command line, uploaded custom profiles will be stored in misc/profiles2/customprofiles. If you host a production BRouter server, it is probably a good idea to have a cron task to periodically wipe the content of customprofiles (or older files in this folder) and to carefully check the permissions and accesses of files in this folder (as you would do for any file upload feature).

Your BRouter server is now listening and ready, but we still have to provide it with OSM data (segments files) and profiles. Note that this server simply exposes a HTTP API and there is no frontend on top of it at the moment (we will add one in the end of the article).

Getting segments files

Downloading pre-built segments files

BRouter extracts the relevant tags and features from OSM data and encode them in .rd5 segments files, split in rectangles of 5 degrees of latitude and longitude. Then, only the relevant part of the map are used, making it lighter.

The segments files are built weekly for the whole planet for the brouter.de instance and are available at http://brouter.de/brouter/segments4/.

You can also download only the required files for the geographical area you wish to cover. For mainland France, this means between latitude 40 and 50 and between longitude 0 and 5. This can be easily done with the following script:

cd misc/segments4

for i in $(seq 40 5 50); do
    for j in $(seq 0 5 5); do
        wget -N "http://brouter.de/brouter/segments4/E${j}_N${i}.rd5"
    done
    wget -N "http://brouter.de/brouter/segments4/W5_N${i}.rd5"
done

You can put segments files anywhere you want, but you have to provide the path of the segments files to the java command-line to start the BRouter server.

EDIT: If you are not sure about the segments files to download, you can call brouter-server for a specific route in the area you want to cover (http://localhost:17777/brouter?lonlats=START_LONGITUDE%2CSTART_LATITUE%7CEND_LONGITUDE%2CEND_LATITUDE&profile=trekking&alternativeidx=0&format=geojson, editing latitude and longitude accordingly) and BRouter will answer you back with the missing segments files names.

Building map segments

If you would rather build the map segments on your own, rather than downloading the pre-built one, there is a script in misc/scripts/mapcreation to download the latest dump of OSM data of the planet (or a smaller dump, if you edit the script accordingly) and process it.

Note: If you are curious about the tags and features included in the segments files, they are defined in the misc/profiles2/lookups.dat file.

A quick look at profiles

BRouter has the advantage of offering a nice and easy way to tweak the weights of road segments through profiles. A default set of profiles is available in the misc/profiles2 folder.

There are also a large number of profiles out there, in particular:

Note: I mainly focus on regular bike profiles here. I am not really interested into car routing (the best results for BRouter seems to be given with the car profiles using the kinematic model but I have no idea how this compares to OSRM or other routing engine). I never rode a velomobile, so I don’t really know which profiles are better fits for these.

Customizable profiles are a great strength of BRouter but the number of available profiles is quickly misleading. It is also easy to start developping profiles for everything, having profiles for each particular use case or weather condition. Then, it is quite difficult to find which are the best profiles out there.

Having played a bit with a number of profiles, I really think only a handful of profiles should be kept for normal use and they can match with a lot of different situations. I would personnally keep (as on my instance):

  • misc/profiles2/trekking.brf, the default “trekking” profile for general bike routing, be for routing in the city or for holidays in the country side / along cycle routes. This is really a wide use case profile.
  • safety” profile (as on the brouter.de website) which is actually the same profile as the “trekking” one with avoid_unsafe set to true to avoid routes without cycle ways.
  • misc/profiles2/fastbike.brf (with this PR) for speed (often coming with unsafe ways), typically if you want to go fast from one point to another or if you are sportive on your road bike.

Note: The “trekking” profile, although being one of the best one around has some drawbacks, which I tried to fix in the “phyks-trekking” (and “phyks-safety”) profiles on my instance. This is still a Work In Progress and there will be another article about profile creation.

BRouter web interface

The official instance at brouter.de has a modern web frontend. This frontend is FOSS as well and the code is available at https://github.com/nrenner/brouter-web (and the README is well documented). We will see how to add it in front of our BRouter server.

First, let us clone the BRouter-web git repository:

git clone https://github.com/nrenner/brouter-web

Then, if we don’t have bower and gulp, we can run npm install to install them locally. Otherwise, you can skip this step and use the system wide binaries instead of the local ones. Then, we can install the required JS dependencies

./node_modules/.bin/bower install

and finally we can build the code for production

./node_modules/.bin/gulp

We will then configure the frontend:

cp config.template.js config.js
$EDITOR config.js

We can configure the available profiles (listed in the frontend) and the BRouter server URL and port.

We will then configure the keys used by the frontend:

cp keys.template.js keys.js
$EDITOR keys.js

There is no need to fill-in the API keys in this file, it only depends on the features of the frontend you want to use. For instance, if you want to remove the “API key required” watermark on the OpenCycleMap background, create a key for Thunderforest.

Note: There is no need to rebuild the app (running gulp) when you edit the configuration or the keys.

The brouter-web repository can then be served directly with your HTTP server (or you can use python3 -m http.server to spawn a webserver serving this content). Head to your web server with your browser (http://localhost:8000 if you use python3 -m http.server) and enjoy your new working BRouter instance!

EDIT: An alternative interface, with a much more modern look and feel (but fewer advanced features) is brouter-online. It seems to no longer be maintained, but a fork with updated dependencies and compatibility with latest BRouter server code is available here. Pull requests are more than welcome on this one! :)