Valhalla is an open source routing engine, with support for time-dependent routing and traffic.
It doesn't have at the moment any official step-by-step instructions on how to add traffic support, only a description of the feature: https://valhalla.readthedocs.io/thor/simple_traffic/
This repository shows how to create an instance of Valhalla with both types of supported traffic information:
traffic.tar
file that is memory mapped by Valhalla. The files needed for the two types of traffic are generated using a new tool valhalla_traffic_demo_utils
.
This has similar interface to existing Valhalla tools and makes use of data structures and algorithms in the Valhalla source code.
docker build -t valhalla-traffic .
docker run -p 8002:8002 -it valhalla-traffic bash
LD_LIBRARY_PATH=/usr/local/lib valhalla_service /valhalla_tiles/valhalla.json 1
curl http://localhost:8002/locate --data '{"locations": [{"lat": 42.506709, "lon": 1.523623}], "verbose": true}' | jq
One of the ways returned by the query should contain a non-empty predicted_speeds
array for predicted traffic, and a non-empty live_speed
object for live traffic. This means that Valhalla has the traffic information available.
Example:
[
{
"input_lon": 1.523623,
"input_lat": 42.50671,
...
"edges":[
{
"predicted_speeds":[6, 6, 6, 6, 6, 6, ... ],
"edge_info":{
"way_id":173167308,
...
},
"live_speed": {
"congestion_2": 0.03,
"breakpoint_1": 1,
"congestion_1": 0.02,
"speed_1": 40,
"congestion_0": 0,
"speed_2": 40,
"breakpoint_0": 1,
"speed_0": 40,
"overall_speed": 40
}
...
valhalla_traffic_demo_utils --config /valhalla_tiles/valhalla.json --update-live-traffic 0
LD_LIBRARY_PATH=/usr/local/lib valhalla_service /valhalla_tiles/valhalla.json 1
curl http://localhost:8002/locate --data '{"locations": [{"lat": 42.506709, "lon": 1.523623}], "verbose": true}' | jq | grep overall_speed
valhalla_traffic_demo_utils --config /valhalla_tiles/valhalla.json --update-live-traffic 30
curl http://localhost:8002/locate --data '{"locations": [{"lat": 42.506709, "lon": 1.523623}], "verbose": true}' | jq | grep overall_speed
The predicted traffic for the following OSM way is slowed as part of the Dockerfile commands: https://www.openstreetmap.org/way/173167308#map=17/42.50676/1.52457
As live traffic has priority over predicted traffic, make sure all live traffic speeds are set to 0, so they are ignored:
valhalla_traffic_demo_utils --config /valhalla_tiles/valhalla.json --update-live-traffic 0
When requested simple, non-time-dependent routing, Valhalla uses the way:
When requested time-dependent routing (Can be set in routing options in the demo), Valhalla avoids the way:
For predicted traffic, speeds must be higher than 5 Km/h to be taken into account. Anything lower than that is considered noise.
The free flow and constrained flow speeds are used by default by the routing API.
In order to use the predicted traffic information, the date_time
parameter needs to be set in the route request.
Check the GetSpeed
function in baldr/graphtile.h
for validation of live traffic data.
curl http://localhost:8002/route --data '{"locations":[{"lat":42.505884,"lon":1.520732},{"lat":42.50885,"lon":1.528551}],"costing":"auto","directions_options":{"units":"meters"}}' | jq
Decode polyline6: http://valhalla.github.io/demos/polyline/
curl http://localhost:8002/sources_to_targets --data '{"sources":[{"lat":42.505884,"lon":1.520732},{"lat":42.50885,"lon":1.528551},{"lat":42.508282,"lon":1.521729}], "targets":[{"lat":42.506076,"lon":1.517199},{"lat":42.509775,"lon":1.525169},{"lat":42.501021,"lon":1.51791}],"costing":"auto","directions_options":{"units":"kilometers"},"date_time":{"type":1,"value":"2021-08-30T23:50"}}' | jq
curl http://localhost:8002/isochrone --data '{"locations":[{"lat": 42.506709, "lon": 1.523623}],"costing":"auto","contours":[{"time":5,"color":"ff0000"}],"date_time":{"type":1,"value":"2021-09-30T23:50"}}' | jq
View isochrone: http://geojson.io/
Used to match a single point to the nearest road: (click on the map, get a green point -> click on the green point to get info) http://valhalla.github.io/demos/locate/
Or cmd line:
curl http://localhost:8002/locate --data '{"locations":[{"lat":42.505884,"lon":1.520732},{"lat":42.508282,"lon":1.521729}]}' | jq
curl http://localhost:8002/trace_route --data '{"shape":[{"lat":42.505884,"lon":1.520732,"type":"break"},{"lat":42.508282,"lon":1.521729,"type":"break"}],"costing":"auto","shape_match":"map_snap"}' | jq
curl http://localhost:8002/trace_attributes --data '{"shape":[{"lat":42.505884,"lon":1.520732,"type":"break"},{"lat":42.508282,"lon":1.521729,"type":"break"}],"costing":"auto","shape_match":"map_snap"}' | jq
Let's assume that the traffic information has to be generated based on some input data in the form of a list of raw acquired speeds for a given lat/lng point.
In order to get the valhalla way id of an array of lat/lng pairs, the following request can be used:
curl http://localhost:8002/trace_attributes --data '{"shape":[{"lat":<lat>,"lon":<lng>},{"lat":<lat>,"lon":<lng>}, ... ],"costing":"auto","shape_match":"map_snap","filters":{"attributes":["edge.names","edge.id", "edge.weighted_grade","edge.speed", "edge.way_id", "edge.length", "edge.traversability", "edge.density", "matched.distance_along_edge", "matched.edge_index", "matched.distance_from_trace_point"],"action":"include"}}' | jq
This will return for each point in the "shape" array an edge index, which can be used to get the way id from the same response.
After having the way id for each point, just follow the Dockerfile steps, ignoring the usage of the way_edges.txt
mapping.
valhalla_traffic_demo_utils.cc
needs to be compiled as part of the main cmake
+ make
calls.
Due to this, I have added two custom CmakeLists, which change from time to time in the upstream repository. Because the Valhalla repository is updated frequently, in order to remove the risk of future the breaking changes, a fixed commit is used to build Valhalla.
The two required changed CmakeLists are as follows:
src/
should add the microtar library, which is used by valhalla_traffic_demo_utils
:
target_include_directories(valhalla
PUBLIC
${VALHALLA_SOURCE_DIR}
...
${VALHALLA_SOURCE_DIR}/third_party/microtar/src
and
add_library(valhalla ${valhalla_src} ${VALHALLA_SOURCE_DIR}/third_party/microtar/src/microtar.h
${VALHALLA_SOURCE_DIR}/third_party/microtar/src/microtar.c)
valhalla_traffic_demo_utils
as part of the valhalla_data_tools
, for example:
set(valhalla_data_tools valhalla_build_statistics valhalla_ways_to_edges valhalla_validate_transit
valhalla_benchmark_admins valhalla_build_connectivity valhalla_build_tiles valhalla_build_admins
valhalla_convert_transit valhalla_fetch_transit valhalla_query_transit valhalla_add_predicted_traffic
valhalla_assign_speeds valhalla_traffic_demo_utils)