Import brouter website as markdown

This commit is contained in:
Manuel Fuhr 2021-11-30 19:12:41 +01:00
parent c6bdf1709c
commit 0b9ea9b4c0
10 changed files with 687 additions and 0 deletions

View file

@ -0,0 +1,97 @@
---
title: "Routing algorithm"
---
## Routing algorithm: 2-pass routing with adaptive cost-cutoff
There's not so much to say about the routing algorithm, because the basic ideas
like [Dijkstra's algorithm](http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)
or the [A-Star algorithm](http://en.wikipedia.org/wiki/A*_search_algorithm) are
well documented.
Since Dijkstra uses only the path-cost-function `g(x)`, while A-Star add's the
remaining air-distance to the destination as a *future-cost-function* `h(x)`,
you can consider both algorithms to be equivalent if you introduce a *heuristic
coefficient* `c`:
```
cost-function = g(x) + c*h(x)
```
It is known that you get a correct result if `c` is in the range 0..1, and if
`g(x)` and `h(x)` satisfy some conditions.
For `c>1` you do not get a correct result. However, if c is larger than the
average ratio of the path cost-function g(x) and the air-distance, you get a
quick heuristic search which is heading towards the destination with a
processing time that scales linear with distance, not quadratic as for a correct
(`c<1`) search.
BRouter uses a 2-pass algorithm as a mixed approach with e.g. `c=1.5` for the
first pass and `c=0` for the second pass. The trick here is that the second pass
can use a cost-cutoff from the maximum-cost-estimate that the first pass
delivers to limit the search area, because any path with a remaining
air-distance larger than the difference of the current cost and the maximum cost
estimate can be dropped. And this cost-cutoff is adaptive: if during the second
pass a match is found with the first pass result, the maximum cost estimate is
lowered on-the-fly if this match gives a combined path with a lower cost.
For recalculations, where you still know the result from the last calculation
for the same destination, the first pass can be skipped, by looking for a match
with the last calculations result. You can expect to find such a match and thus
a maximum cost estimate soon enough, so you get an effective limit on the search
area. If a recalculation does not finish within a given timeout, it's usually
o.k. to publish a merged track from the best match between the new and the old
calculation, because the far-end of a route usually does not change by an
immediate recalculation in case you get off the track.
The reason that `c=0` (=Dijkstra) is used in the second pass and not `c=1`
(=A-Star) is simply that for `c=0` the open-set is smaller, because many paths
run into the cutoff at an early time and do not have to be managed in the
open-set anymore. And because the size of the open-set has an impact on
performance and memory consumption, c=0 is choosen for the second pass. The
open-set is what's displayed in the graphical app-animation of the brouter-app.
However, you can change the coefficients of both passes in the routing-profile
via the variables `pass1coefficient` and `pass2coefficient`, as you can see in
the car-test profile. A negative coefficient disables a pass, so you can e.g.
force BRouter to use plain A-Star with:
```
assign pass1coefficient=1
assign pass2coefficient=-1
```
or do some super-fast dirty trick with *non-optimal* results (there are routers
out there doing that!!):
```
assign pass1coefficient=2
assign pass2coefficient=-1
```
Some more words on the conditions that the path-cost-funtion g(x) has to
fullfill. Mathematically it reads that you need *non-negative edge costs*, but
the meaning is that at the time you reach a node you must be sure that no other
path reaching this node at a later time can lead to a better result over all.
If you have *turn-costs* in your cost function, this is obviously not the case,
because the overall result depends and the angle at which the next edge is
leaving this node.... However, there's a straight forward solution for that
problem by redefining edges and nodes: in BRouter, *nodes* in the Dijkstra-sense
are not OSM-Nodes, but the links between them, and the edges in the Dijkstra
sense are the transitions between the links at the OSM-Nodes. With that
redefinition, *turn-cost* and also *initial-costs* become valid terms in the
path-cost-function.
However, there's still a problem with the elevation term in the cost-function,
because this includes a low-pass-filter applied on the SRTM-altitudes that
internally is implemented as an *elevation-hysteresis-buffer* that is managed
parallel to the path's cost. So the path's cost is no longer the *true cost* of
a path, because the hysteresis-buffer contains potential costs that maybe
realized later, or maybe not.
Strictly speaking, neither Dijkstra nor A-Star can handle that. And in BRouter,
there's no real solution. There's a mechanism to delay the node-decision one
step further and so to reduce the probablity of glitches from that dirtyness,
but mainly the solution is *don't care*.

View file

@ -0,0 +1,20 @@
## Alternative route calculations
Sometimes the routing result is not what you want, and you are looking for some
other way, following the same routing preferences, but not following the way of
the first choice routing result.
Maybe you don't like the first choice, or you are planning a roundtrip and don't
want to go back the same way. For this purpose, BRouter can calculate
alternatives.
This feature is well known from handheld-navigation systems, but not found in
online services. This is because these online services need to use
pre-calculations for fast processing and cannot handle individual routing
criteria. BRouter does not do any precalculations for specific routing profiles,
so it can do whatever you ask for.
When using a second choice route, you may want to recalculate the route using
[via or nogo points](vianogo.md) in order to define the overall routing
according to your preferences but have a route that is first choice except for
these explicit constraints.

View file

@ -0,0 +1,27 @@
## Freely configurable routing profile
A major reason for the limited usefulness of most bike routing software is that
routing preferences are a personal issue. Not even will MTB and racing cyclist
never agree on common routing preferences, also the same people will have
different preferences for day and night, dry and wet weather, etc. The only
solution for that problem is the use of a freely configurable cost function that
can easily be adapted to personal needs. This is far more flexible compared to a
set of static functions with a fixed set of configuration variables.
To make that point somewhat clearer: there are other routers that are highly
configurable, look at [routino](http://www.routino.org/uk/router.html) for an
example. However, these are one-dimensional parameter sets that do not allow to
handle arbitrary correlation. BRouter's configuration is different. It is more a
scripting language that allows you to program the cost function instead of just
configuring it. E.g. a non-graded track is generally not a good track. But if it
has a surface=asphalt tag, it probably is. On the other hand, a grade5-track
with surface=asphalt is primarily a grade5-track and you should not ignore that.
Such logic is not implementable in one-dimensional parameter sets.
See some [sample profiles](profiles2) provided for the online router.
See the trekking-profile [`trekking.brf`](profiles2/trekking.brf) as the
reference-profile with some explanations on the meaning of this script.
See the [profile_developers_guide.txt](profile_developers_guide.txt) for a
technical reference.

View file

@ -0,0 +1,15 @@
## Following long distance cycle routes
The long distance cycle network (see
[www.opencyclemap.org](http://www.opencyclemap.org)) is the first thing to
consider when planning a cycle trip. BRouter can do that, and the `trekking`
profile makes use of it. It does that implicitly by just making them cheap in
the cost-function, so that the routing sometimes *snaps in* to long distance
cycle routes.
That's a good choice for long distance cycling, because these routes are a *safe
harbor* almost free of bad surprises. However, when really looking for the
*optimal* route between A and B to use it more than once (e.g. your daily
commute) you may want to ignore the long-distance network, to put more focus on
*hard-facts* like distance, hills and surface quality (use the
`trekking-ignore-cr` profile for that purpose).

View file

@ -0,0 +1,24 @@
## Elevation algorithm
Elevation awareness is the most important issue in bike routing if not routing
in a flat country. But in most routing software, elevation is either not handled
at all or in a way that is not really useful.
Even worse, most tools do not even report on elevation in a useful manner. The
far-too-high *total climbs* usually reported do not only accumulate real, small
height-variations that are averaged-out by the bikers momentum - they accumulate
also noise and grid-interpolation errors from the elevation data source.
For most regions, BRouter uses elevation data from the [Shuttle Radar Topography
Mission (SRTM)](http://srtm.usgs.gov/), precisely the hole-filled Version 4.1
Data provided by [srtm.csi.cgiar.org](http://srtm.csi.cgiar.org/), which is the
data that is displayed e.g. in Google Earth and which is used in most
elevation-enabled routing tools. However, the routing algorithm is able to
extract the information on real ascends and descends and ignores the noise.
For latitudes above 60 degree in northern Europe, BRouter uses Lidar data, that
were [compiled and resampled by Sonny](https://data.opendataportal.at/dataset/dtm-europe)
On the reporting side, BRouter uses a similar concept to compute the *filtered
ascend*, which is the ascend without the noise and the small hills and which
turned out to be a valid concept to estimate the real elevation penalty.

53
docs/features/offline.md Normal file
View file

@ -0,0 +1,53 @@
## Ofline routing on Android phones
BRouter is first and foremost an offline tool. It runs on any Android phone. The
online version offered here is just for a trial and for convenience. While many
smartphone routing software use online services to do the actual route
calculations, the advantages of the offline approach are evident:
- It is more reliable, data connection problems and server-side problems are no
issue
- It works in foreign countries where data connections are either not available
or very expensive
- It does not raise any data privacy issues
- You can use a cheap dedicated, second phone for navigation, without having to
put your business smartphone on an untrusted bike mount and run it's battery
low
The downside is that advanced route calculations are difficult to do on a
smartphone with limited computing and memory resources, which may lead
developers to implement simplifications into the routing algorithm that affect
the quality of the routing results. BRouter always does it's best on the
quality, but has a processing time that scales quadratic with distance, leading
to a limit at about 150km in air-distance, which is enough for a bikers daytrip.
### Installing the BETA Version of BRouter on an Android smartphone.
Before trying the Android app, you should have a look one the [online
version](/brouter-web) to see what it's doing.
What you should also do before trying the BRouter Android app is to install, an
get familiar with, one of the supported map-apps. This is either
[OsmAnd](http://www.osmand.net), which is a full offline navigation solution on
it's own, but especially it's a wonderful offline OSM map tool and is able to
give spoken directions to routes calculated either internally or externally.
Other options are [Locus](http://www.locusmap.eu/) or
[OruxMaps](http://www.oruxmaps.com/index_en.html).
The BRouter Android app assumes that at least one of OsmAnd, Locus or OruxMaps
is installed - it will not work otherwise.
If you are o.k. with all that, you can install the BRouter Android app from the
[brouter_1_6_1.zip](../brouter_bin/brouter_1_6_1.zip) installation ZIP-file
including the APK and read the [readme.txt](readme.txt) ( **READ ME !** ) for
details on how to add routing data and navigation profiles to your installation
and how the interfacing between BRouter and the supported map-tools works.
Navigation profiles and the lookup-data are [here](profiles2) Routing data files
per 5*5-degree square are [here](/brouter/segments4)
(The Map-Snapshot date is about 2 days before the timestamp of the routing data
files)

19
docs/features/vianogo.md Normal file
View file

@ -0,0 +1,19 @@
## Via-Points and NoGo-Areas
BRouter can process via-points and nogo-areas, and [brouter-web](/brouter-web)
offers on online interface to edit both of them.
For offline use, nogo-areas can be defined as wayoints using a special naming
convention. Handling of via-points during offline use depends on the mode of
operation, see the README for details.
NoGo-Areas are forbidden areas. In fact, these are areas, not points, with a
default radius of 20m around the given point. Every way that is touching this
disc of 20m radius is excluded by the routing algorithm. But the radius can also
be specified: a waypoint `nogo` default to 20m radius, but `nogo100` defines a
nogo area with 100m radius. Theres no limit in radius, so you can also exclude a
whole geographic region with a single nogo-area.
Nogo areas are useful if you encouter an obstacle that is not contained in the
underlying map. But they can also be useful in planning alternative routes by
excluding e.g. a certain bridge or ferry.