Update logic could be found in updater.cpp, both MLD and CH use LoadAndUpdateEdgeExpandedGraph to update graph cost
For duration change in the following format(More details)
from_osm_id,to_osm_id,edge_speed_in_km_h
After loading csv data into a sorted array, it will iterate from/to pairs in OSRM data to update segment cost(code)
// Iterate all edges and get (begin_node_id, end_node_id) as (u,v) pair
// Try to find (u, v) in traffic.csv file
if (auto value = segment_speed_lookup({u, v}))
{
// if there exists update, then update duration and weight
auto segment_length = segment_lengths[segment_offset];
auto new_duration = convertToDuration(value->speed, segment_length);
auto new_weight =
convertToWeight(fwd_weights_range[segment_offset], *value, segment_length);
fwd_was_updated = true;
fwd_weights_range[segment_offset] = new_weight;
fwd_durations_range[segment_offset] = new_duration;
fwd_datasources_range[segment_offset] = value->source;
counters[value->source] += 1;
}
Turn penalty should be input in the following format(More details)
from_osm_id,via_osm_id,to_osm_id,penalty_in_secs
After loading into sorted array, then iterate all turns to check whether it needs to be updated(code)
// osm_turn is a tuple generated by {from_node_id, via_node_id, to_node_id}
if (auto value = turn_penalty_lookup(osm_turn))
{
turn_duration_penalty =
boost::numeric_cast<TurnPenalty>(std::round(value->duration * 10.));
turn_weight_penalty = boost::numeric_cast<TurnPenalty>(std::round(
std::isfinite(value->weight) ? value->weight * weight_multiplier
: turn_duration_penalty * weight_multiplier / 10.));
turn_duration_penalties[edge_index] = turn_duration_penalty;
turn_weight_penalties[edge_index] = turn_weight_penalty;
updated_turns.push_back(edge_index);
}
Based on Berlin OSM data, we tried to prove customization step would update specific link's weight/duration.
Here is the selected routing case. we picked one wayid in the middle of the route.
From OSM map data, there are totally 4 points in that wayid
25663401 (part of ways Friedrichstraße (435164424), Krausenstraße (4588225), and Krausenstraße (458953718))
25663409 (part of ways Schützenstraße (24242838) and Schützenstraße (4611773))
25663743 (part of way Mauerstraße (24242835))
25663420 (part of ways Zimmerstraße (66071387), Friedrichstraße (327979624), Friedrichstraße (32938172), and Zimmerstraße (4611774))
Create a traffic.csv file
25663401,25663409,1
25663409,25663743,1
25663743,25663420,1
The last 1 means the speed is 1 km/h.
By the commend we found weight matrix be updated based on traffic.csv.
./osrm-customize berlin.osrm --segment-speed-file traffic.csv
In OSRM, Here is the place to update segment cost
Comments
- Based on debug, we prove that update unit is the node pairs inside each way. Which is aligned with osrm-wiki
The from/to ids are OSM node IDs that are directly connected. To update the speed for an entire way, you must list each node pair along the way in the CSV file.
- To debug TBB, please set thread = 1 at the beginning of main
tbb::task_scheduler_init init(1);
- On Mac with XCode, I met issue related with osrm_update and osrm_store could not generate libosrm_store.a and libosrm_update.a, solve the issue by modifying CMakeLists.txt under osrm-backend
-add_library(osrm_update $<TARGET_OBJECTS:UPDATER> $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
-add_library(osrm_store $<TARGET_OBJECTS:STORAGE> $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
+add_library(osrm_update src/updater/csv_source.cpp src/updater/updater.cpp $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
+add_library(osrm_store src/storage/io_config.cpp src/storage/storage.cpp $<TARGET_OBJECTS:MICROTAR> $<TARGET_OBJECTS:UTIL>)
- The input of custmization is osm_id pairs, OSRM would convert internal NodeID to osm_id for the matching
std::vector<util::Coordinate> coordinates;
extractor::PackedOSMIDs osm_node_ids;
extractor::files::readNodes(config.GetPath(".osrm.nbg_nodes"), coordinates, osm_node_ids);
// ...
auto u = osm_node_ids[internal_node_id];
In service's code or unit test code, you could use facade to do similar conversion
auto osm_nodeid = facade.GetOSMNodeIDOfNode(internal_node_id);
auto node_coordinate = facade.GetCoordinateOfNode(internal_node_id);