Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
felixguendling authored Sep 22, 2024
1 parent ccae81c commit f820ecd
Showing 1 changed file with 12 additions and 9 deletions.
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,18 @@ To implement more finegrained control over path finding, it might be necessary t

The current set of routing profiles can be found in the [`include/osr/routing/profiles`](https://github.com/motis-project/osr/tree/master/include/osr/routing/profiles) folder. Here's what a profile needs to provide in order to be usable by the shortest path algorithm:

- Types:
- `node` struct: a node defines what is considered a node for this routing profile. The most basic definition of a node would basically be just what's considered a node in the data model (`node_idx_t`, see above). However, for many profiles, this is not succifient. Let's take the foot routing profile as an example: for indoor routing, it should be possible to distinguish the same OSM node on different levels. Therefore, the level has to be part of the foot profile's node definition. Another example is the car profile: to be able to detect u-turns (just changing the direction but staying on the same way), the node has to define the current direction. In order to properly handle turn restrictions, also the last used way has to be part of the node definition. The member function `node::get_key()` returns the key (see `key`).
- `label` struct: basically the same as the `node` struct but it should additionally carry the routing costs (currently tracked in seconds). The label has to provide `get_node()` and `cost()` member functions.
- `key`: The shortest path algorithm (e.g. Dijkstra) tracks minimal costs to each node in a hash map. In theory, it would be sufficient to use `node` as hash map key as we need to only track one shortest path to each profile `node`. To allow for a more efficient storage, multiple nodes can share the same hash map key, therefore reducing the hash map size (which can speedup the routing significantly). Therefore, a profile can define a `key` which can be the same as `node` but doesn't have to be. The key doesn't need any member functions and can therefore just be a typedef to `node_idx_t` (in the most simple case).
- `entry`: The entry is the hash map entry and is stored for each `key`. It has to store the costs and precessor. If `key` maps several `node`s to the same `entry`, then the `entry` has to store costs and predecessory for each of the `node`s. It has to provide the following member functions:
- `std::optional<node> pred(node)`: returns the predecessor for the node, or `std::nullopt` if this `node` has never been visited.
- `cost_t cost(node)`: returns the shortest path costs to this `node`
- `bool update(label, node, cost_t, node pred)`: updates the costs for this node if they are better than the previously stored costs and returns `true` if the costs where updated and `false` otherwise.
- Static functions:
#### Types

- `node` struct: a node defines what is considered a node for this routing profile. The most basic definition of a node would basically be just what's considered a node in the data model (`node_idx_t`, see above). However, for many profiles, this is not succifient. Let's take the foot routing profile as an example: for indoor routing, it should be possible to distinguish the same OSM node on different levels. Therefore, the level has to be part of the foot profile's node definition. Another example is the car profile: to be able to detect u-turns (just changing the direction but staying on the same way), the node has to define the current direction. In order to properly handle turn restrictions, also the last used way has to be part of the node definition. The member function `node::get_key()` returns the key (see `key`).
- `label` struct: basically the same as the `node` struct but it should additionally carry the routing costs (currently tracked in seconds). The label has to provide `get_node()` and `cost()` member functions.
- `key`: The shortest path algorithm (e.g. Dijkstra) tracks minimal costs to each node in a hash map. In theory, it would be sufficient to use `node` as hash map key as we need to only track one shortest path to each profile `node`. To allow for a more efficient storage, multiple nodes can share the same hash map key, therefore reducing the hash map size (which can speedup the routing significantly). Therefore, a profile can define a `key` which can be the same as `node` but doesn't have to be. The key doesn't need any member functions and can therefore just be a typedef to `node_idx_t` (in the most simple case).
- `entry`: The entry is the hash map entry and is stored for each `key`. It has to store the costs and precessor. If `key` maps several `node`s to the same `entry`, then the `entry` has to store costs and predecessory for each of the `node`s. It has to provide the following member functions:
- `std::optional<node> pred(node)`: returns the predecessor for the node, or `std::nullopt` if this `node` has never been visited.
- `cost_t cost(node)`: returns the shortest path costs to this `node`
- `bool update(label, node, cost_t, node pred)`: updates the costs for this node if they are better than the previously stored costs and returns `true` if the costs where updated and `false` otherwise.

#### Static functions

- `resolve_start_node(ways::routing, way_idx_t, node_idx_t, level_t, direction, Fn&& f)`: resolves all nodes that belong to this particular (`way_idx_t`, `node_idx_t`, `level_t`, `direction`) combination. `Fn f` will be called with each `node`. It's the task of the profile to give the routing algorithm and entry point to its overlay graph.
- `resolve_all(ways::routing, node_ix_t, level_t, Fn&& f)`: Same as `resolve_start_node`, just without the condition that `way_idx_t` has to match.
- `adjacent<SearcHdir, WithBlocked, Fn>(ways::routing, node, bitvec<node_idx_t> blocked, Fn&& f)`: Calls `Fn f` with each adjacent neighbor of the given `node`. This is used in the shortest path algorithm to expand a node and visit all its neighbors. This takes a runtime provided bit vector `blocked` into account where bit `i` indicates if `i` can be visited or not. This allows us to dynamically block nodes depending on the routing query.
Expand Down

0 comments on commit f820ecd

Please sign in to comment.