BRouter Documentation

repository·master·Indexed 20 days ago

https://github.com/abrensch/brouter

A configurable, elevation-aware OpenStreetMap (OSM) offline router optimized for bicycle and energy-efficient car travel. Supports Android apps, standalone HTTP servers, and Docker deployments. Features a 2-pass routing algorithm with adaptive cost-cutoff, custom .rd5 segment data files, and a flexible profiling system for multi-modal routing.

Tokens
16.6K
Snippets
35
Records
88
Agent score
72%

What's inside BRouter

  1. Map OsmAnd profiles to specific BRouter profiles (OsmAnd v4.7.1+)

    master

    In OsmAnd version 4.7.1 and higher, you can use a naming convention to automatically map an OsmAnd profile to a specific BRouter profile file (.brf).

    If an OsmAnd profile meets both these conditions:

    1. It has BRouter defined as the navigation service.
    2. The profile name follows the pattern Brouter[mystring]

    Then OsmAnd will instruct the BRouter app to use the profile named mystring (e.g., Brouter[trekking] uses trekking.brf). This replaces the basic mapping defined in serviceconfig.dat.

    Warning: The mapping is case-sensitive. If the specified profile is not found in the BRouter app, routing will fail with the error: Could not calculate route...

    OsmAnd-profile name | Brouter-app profile
    -------------------|---------------------
    Brouter[trekking]  | "trekking" (trekking.brf)
    Brouter[racebike]  | "racebike" (racebike.brf)
  2. How the BRouter 2-pass routing algorithm works

    master

    BRouter employs a 2-pass approach to balance speed and accuracy using an adaptive cost-cutoff:

    1. First Pass: Uses a high heuristic coefficient (e.g., c=1.5) to perform a quick search towards the destination. This pass provides a maximum-cost estimate.
    2. Second Pass: Uses a coefficient of 0 (Dijkstra) to find the optimal path. It uses the cost estimate from the first pass to implement an adaptive cost-cutoff. Any path with a remaining air-distance larger than the difference between its current cost and the maximum cost estimate is dropped, significantly limiting the search area.

    Recalculations: If the destination is the same as a previous calculation, BRouter can skip the first pass and attempt to find a match with the previous result to establish a cost estimate quickly. If a recalculation times out, the system may publish a merged track from the best match between the new and old calculations.

    Implementation Detail: BRouter uses c=0 for the second pass instead of c=1 (A-Star) because a Dijkstra-based search results in a smaller 'open-set', reducing memory consumption and improving performance.

  3. How BRouter handles turn costs and elevation

    master

    BRouter adapts standard routing algorithms to handle complex cost factors:

    • Turn Costs: To allow turn costs and initial costs in the path-cost-function, BRouter redefines the graph structure. In BRouter's Dijkstra implementation, 'nodes' are actually the links between OSM nodes, and 'edges' are the transitions between links at an OSM node. This allows turn angles to be treated as valid cost terms.
    • Elevation: Elevation costs include a low-pass filter on SRTM altitudes via an elevation-hysteresis-buffer. Because this buffer manages potential future costs, the path cost is not a 'true cost' in the strict mathematical sense. BRouter manages this by delaying node decisions by one step to reduce glitches.
  4. Configure the Elevation Buffer to filter noise

    master

    The Elevation Buffer is a feature used to filter elevation noise (e.g., from SRTM data) along a route. It uses three variables:

    • elevationpenaltybuffer (default: 5m): When buffer content exceeds this, BRouter starts converting buffered elevation to ElevationCost using up/downhillcost.
    • elevationmaxbuffer (default: 10m): The maximum size of the buffer. Once exceeded, all elevation is converted to Elevationcost using the up/downhill[maxslope]cost ratio.
    • elevationbufferreduce (default: 0% slope): The rate of conversion of the buffer content above elevationpenaltybuffer to ElevationCost.

    Conversion Logic: Elevation is first cut out by 10 * up/downhillcutoff per km. Remaining elevation accumulates in the buffer. When the buffer reaches elevationmaxbuffer, it is converted to cost using the ratio defined by up/downhill[maxslope]cost (or up/downhillmaxslopecost).

  5. Understand traffic_class estimation factors

    master

    The traffic_class is an estimation of traffic density based on several spatial and demographic factors.

    Key inputs for traffic estimation:

    • Town Population: Calculated for primary, secondary, and tertiary segments using the formula: SUM(population of each town < 100 km) / ( town-radius + 2500 + dist(segment-position to the town) ** 2 ). town-radius is sqrt(population).
    • Industrial Areas: Size of landuse=industrial areas and distance to them (excludes solar and wind farms).
    • Airports: International airports.
    • Highway Density: Calculated on a 100 km² grid. High density of tertiary and higher roads generally decreases traffic, except near motorway junctions where traffic increases.
    • Motorway/Trunk Density: Calculated on a 100 km² grid. High motorway density decreases traffic on primary/secondary/tertiary roads.
    • Mountain Ranges: Density of peaks > 400m. Traffic on highways in these regions is generally higher due to local population or industrial needs.
  6. Understand the routing logic of the Inline Skating profile

    master

    The Inline Skating profile is calibrated for long-distance point-to-point skating, prioritizing enjoyment and safety over pure distance optimization. It differs from standard cycling or walking profiles in the following ways:

    Surface Preferences

    • Preferred: Smooth asphalt or concrete.
    • Tolerable: Paving stones or cobblestones (only for short stretches).
    • Avoided: Unpaved or dirt surfaces.

    Elevation and Speed

    • The Sweet Spot: A gentle descent of -2% to -5% allows for effortless cruising at approximately 22 km/h.
    • Steep Downhills: Gradients steeper than -10% are penalized because braking requirements cap the average speed at ~22 km/h.
    • Uphills: The profile prefers short, steep climbs over long, gentle inclines. Long, gentle 2-5% climbs are penalized as they waste more time than a single short steep burst for the same total elevation gain.
    • Flat Terrain: Targets a cruise speed of 20 km/h on gradients between -1.5% and +1.5%.

    Road Types and Safety

    • Preferred: Cycleways, residential streets, and footways/sidewalks.
    • Avoided: Primary and trunk roads. The profile favors quiet roads because skaters are slower and more vulnerable to traffic than cyclists.
  7. How BRouter voice hints are calculated and formatted

    master

    BRouter calculates voice hints based on junction angles and 'bad ways' (ways not used at a specific junction). For example, a 90-degree turn might be labeled as a "sharp right turn" if another available way is at 110 degrees.

    Voice hints are not present in all export formats, and their presentation varies by format. Supported GPX formats for voice hints include:

    • OsmAnd
    • Locus
    • Comment-style
    • Gpsies
    • Orux

    Key logic rules applied during calculation:

    • Continue: Shown only if the way crosses a higher priority way.
    • Roundabouts: Include an exit marker.
    • U-turns: Calculated between -179 and +179 degrees.
    • Merging: Hints near each other are merged (e.g., "left, left" becomes "u-turn left").
    • Highway Exits: A marker is used when a highway exit is followed by a way in nearly the same direction.
    • Beeline: Routing goes direct from one 'via' point to the next.
    • Motorway Exits: Identified when a junction on a motorway uses a motorway_link and the subsequent way is less than a motorway_link.
  8. Understand how environmental pseudo tags are generated

    master

    BRouter uses 'pseudo tags' to apply environmental penalties (noise, river, forest, town, traffic) during routing. These are generated during OSM data processing using spatial SQL queries (found in brouter.sql).

    The Process:

    1. Roads are extended with a 32m buffer, creating a 64m wide line.
    2. The system calculates the percentage of this line that falls within specific environmental zones (e.g., a forest or near a noisy road).
    3. This percentage is converted into a factor, which is then assigned to a specific class (e.g., noise_class).

    Important Limitation: Because the class is based on the average environment along an entire OSM way, a single OSM way that passes through multiple distinct environments may have an inaccurate classification.

  9. Understand the BRouter Android directory structure

    master

    BRouter organizes its data into several specific subdirectories within the <basedir>. Understanding this structure is essential for managing routing data, profiles, and configuration files.

    directorydescription
    <basedir>/brouter/modesContains serviceconfig.dat (routing-mode/profile mapping) and cached route results for recalculations.
    <basedir>/brouter/profiles2Contains lookup.dat (OSM tag access), serverconfig.txt, and routing profiles (*.brf).
    <basedir>/brouter/segments4Primary location for routing data files (*.rd5). Also contains storageconfig.txt.
    <basedir>/brouter/importUsed for file exchange with other apps.
    <basedir>/brouter/import/tracksPlace nogo*.gpx files here or where calculated routes (brouter*.gpx) are stored.

    Note: The segments4 directory is the primary location for routing data. While you can use a secondary directory, the Download Manager always writes new data to segments4.

  10. Enable timeout-free recalculations for long distances

    master

    You can combine the service interface (for dynamic recalculations) with the file interface (for long-distance capability) to avoid the 60-second timeout.

    Workflow:

    1. Initial Calculation: Use the file interface to calculate a long-distance track to your destination.
    2. Bind to Mode: Use the Server Mode button to bind this track to one or more routing-modes. This stores a reference track in the brouter/modes subdirectory.
    3. Active Navigation: Use the service interface for the actual trip.

    How it works:

    When you request a route via the service interface to the exact same destination (within 5m of the original waypoint), BRouter uses the reference track to perform a specialized, high-speed calculation. This ensures the result is returned within the 60-second limit while still allowing for automatic recalculations if you deviate from the track.

  11. Format lonlats for routing points

    master

    The lonlats parameter is a list of positions for the route. It is preferred over using separate lons and lats parameters. You can use special syntax within the lonlats list to control routing behavior:

    • Mandatory Stops: To ensure a point is reached (rather than just being a 'via' point that might be bypassed), use one of these formats:
      • Add the point to the pois list.
      • Name the point in the list: ...|x,y,"stop here"|...
      • Add an unnamed point: ...|x,y,m|...
    • Beelines (Direct segments): To define a straight starting point, use the d (direct) flag: ...|x,y,d|.... The subsequent point does not need a declaration.
    • Note on Beelines: If you need to name a point while using beelines, use the straight router parameter instead, providing the index of the point.
    ...|x,y,"stop here"|...
    ...|x,y,m|...
    ...|x,y,d|...
  12. Understand BRouter profile script contexts

    master

    BRouter profile scripts operate in three distinct contexts: global, way, and node.

    • global: Contains configuration shared across all contexts. Variables defined here are read-only and visible in both way and node sections.
    • way: The primary context for routing logic, where way-specific tags and costs are processed.
    • node: Used for node-specific logic.

    Context Separation & Accessing Variables: Way-tags and Node-tags are treated independently. To switch contexts in a script, use the special markers ---context:way and ---context:node.

    While contexts are separated, the node context can access variables from the originating way using the way: prefix. For example: if greater way:costfactor 5 then ...

    Note: There is a legacy-hack for the nodeaccessgranted variable allowing it to be accessed without a prefix, but the way: prefix is the standard for all other way variables.