From 3d5a53566c2cddf6a6f087282ed3743d158e0fc2 Mon Sep 17 00:00:00 2001 From: karenzshea Date: Mon, 12 Sep 2016 12:16:56 -0400 Subject: [PATCH] implement flag edge-weight-updates-over-factor, to log edge weight updates over provided x factor --- .../edge-weight-updates-over-factor.feature | 30 +++++++ features/options/contract/version.feature | 2 +- features/step_definitions/options.js | 4 + include/contractor/contractor.hpp | 3 +- include/contractor/contractor_config.hpp | 1 + src/contractor/contractor.cpp | 79 ++++++++++++++----- src/tools/contract.cpp | 6 +- 7 files changed, 103 insertions(+), 22 deletions(-) create mode 100644 features/options/contract/edge-weight-updates-over-factor.feature diff --git a/features/options/contract/edge-weight-updates-over-factor.feature b/features/options/contract/edge-weight-updates-over-factor.feature new file mode 100644 index 000000000..d38cc104b --- /dev/null +++ b/features/options/contract/edge-weight-updates-over-factor.feature @@ -0,0 +1,30 @@ +@contract @options @edge-weight-updates-over-factor +Feature: osrm-contract command line option: edge-weight-updates-over-factor + + Background: Log edge weight updates over given factor + + Scenario: Logging weight with updates over factor of 2, long segment + Given the node locations + | node | lat | lon | + | a | 0.1 | 0.1 | + | b | .05 | 0.1 | + | c | 0.3 | 0.1 | + And the ways + | nodes | highway | + | ab | residential | + | ac | primary | + Given the profile "testbot" + Given the extract extra arguments "--generate-edge-lookup" + Given the speed file + """ + 1,2,100 + 1,3,100 + """ + And the data has been extracted + When I run "osrm-contract --edge-weight-updates-over-factor 2 --segment-speed-file {speeds_file} {processed_file}" + And stderr should contain "weight updates" + And stderr should contain "New speed: 100 kph" + And I route I should get + | from | to | route | speed | + | a | b | ab,ab | 100 km/h | + | a | c | ac,ac | 100 km/h | diff --git a/features/options/contract/version.feature b/features/options/contract/version.feature index f361bb1e5..88ec8b734 100644 --- a/features/options/contract/version.feature +++ b/features/options/contract/version.feature @@ -6,7 +6,7 @@ Feature: osrm-contract command line options: version Background: Given the profile "testbot" - + Scenario: osrm-contract - Version, short When I run "osrm-contract --v" Then stderr should be empty diff --git a/features/step_definitions/options.js b/features/step_definitions/options.js index d2177bffd..3cb66508c 100644 --- a/features/step_definitions/options.js +++ b/features/step_definitions/options.js @@ -86,6 +86,10 @@ module.exports = function () { assert.equal(this.stdout.split('\n').length - 1, parseInt(lines)); }); + this.Then(/^stderr should contain (\d+) lines?$/, (lines) => { + assert.equal(this.stderr.split('\n').length - 1, parseInt(lines)); + }); + this.Then(/^datasource names should contain "(.+)"$/, (expectedData) => { var actualData = fs.readFileSync(this.processedCacheFile + '.datasource_names', {encoding:'UTF-8'}).trim().split('\n').join(','); assert.equal(actualData, expectedData); diff --git a/include/contractor/contractor.hpp b/include/contractor/contractor.hpp index 3c9dff9c0..7cc70cc48 100644 --- a/include/contractor/contractor.hpp +++ b/include/contractor/contractor.hpp @@ -89,7 +89,8 @@ class Contractor const std::string &geometry_filename, const std::string &datasource_names_filename, const std::string &datasource_indexes_filename, - const std::string &rtree_leaf_filename); + const std::string &rtree_leaf_filename, + const double log_edge_updates_factor); }; } } diff --git a/include/contractor/contractor_config.hpp b/include/contractor/contractor_config.hpp index e820b3f09..cdb1b080d 100644 --- a/include/contractor/contractor_config.hpp +++ b/include/contractor/contractor_config.hpp @@ -73,6 +73,7 @@ struct ContractorConfig bool use_cached_priority; unsigned requested_num_threads; + double log_edge_updates_factor; // A percentage of vertices that will be contracted for the hierarchy. // Offers a trade-off between preprocessing and query time. diff --git a/src/contractor/contractor.cpp b/src/contractor/contractor.cpp index ca45a63aa..aeb386329 100644 --- a/src/contractor/contractor.cpp +++ b/src/contractor/contractor.cpp @@ -81,6 +81,41 @@ inline EdgeWeight distanceAndSpeedToWeight(double distance_in_meters, double spe return std::max(1, static_cast(std::round(duration * 10))); } +// Returns updated edge weight +template +EdgeWeight getNewWeight(IterType speed_iter, + const double &segment_length, + const std::vector &segment_speed_filenames, + const EdgeWeight old_weight, + const double log_edge_updates_factor) +{ + const auto new_segment_weight = + (speed_iter->speed_source.speed > 0) + ? distanceAndSpeedToWeight(segment_length, speed_iter->speed_source.speed) + : INVALID_EDGE_WEIGHT; + // the check here is enabled by the `--edge-weight-updates-over-factor` flag + // it logs a warning if the new weight exceeds a heuristic of what a reasonable weight update is + if (log_edge_updates_factor > 0 && old_weight != 0) + { + auto new_secs = new_segment_weight / 10.0; + auto old_secs = old_weight / 10.0; + auto approx_original_speed = (segment_length / old_secs) * 3.6; + if (old_weight >= (new_segment_weight * log_edge_updates_factor)) + { + auto speed_file = segment_speed_filenames.at(speed_iter->speed_source.source - 1); + util::SimpleLogger().Write(logWARNING) + << "[weight updates] Edge weight update from " << old_secs << "s to " << new_secs << "s" + << ". New speed: " << speed_iter->speed_source.speed << " kph" + << ". Old speed: " << approx_original_speed << " kph" + << ". Segment length: " << segment_length << " m" + << ". Segment: " << speed_iter->segment.from << "," + << speed_iter->segment.to << " based on " << speed_file; + } + } + + return new_segment_weight; +} + int Contractor::Run() { #ifdef WIN32 @@ -113,7 +148,8 @@ int Contractor::Run() config.geometry_path, config.datasource_names_path, config.datasource_indexes_path, - config.rtree_leaf_path); + config.rtree_leaf_path, + config.log_edge_updates_factor); // Contracting the edge-expanded graph @@ -370,7 +406,8 @@ EdgeID Contractor::LoadEdgeExpandedGraph( const std::string &geometry_filename, const std::string &datasource_names_filename, const std::string &datasource_indexes_filename, - const std::string &rtree_leaf_filename) + const std::string &rtree_leaf_filename, + const double log_edge_updates_factor) { if (segment_speed_filenames.size() > 255 || turn_penalty_filenames.size() > 255) throw util::exception("Limit of 255 segment speed and turn penalty files each reached"); @@ -556,10 +593,12 @@ EdgeID Contractor::LoadEdgeExpandedGraph( extractor::QueryNode *u; extractor::QueryNode *v; + // forward_packed_geometry_id is the index id for geometry, weight and duration of the segments if (leaf_object.forward_packed_geometry_id != SPECIAL_EDGEID) { const unsigned forward_begin = m_geometry_indices.at(leaf_object.forward_packed_geometry_id); + const auto current_fwd_segment = &(m_geometry_list[forward_begin + leaf_object.fwd_segment_position]); if (leaf_object.fwd_segment_position == 0) { @@ -574,23 +613,23 @@ EdgeID Contractor::LoadEdgeExpandedGraph( leaf_object.fwd_segment_position - 1] .node_id]); v = &(internal_to_external_node_map - [m_geometry_list[forward_begin + leaf_object.fwd_segment_position] - .node_id]); + [current_fwd_segment->node_id]); } const double segment_length = util::coordinate_calculation::greatCircleDistance( util::Coordinate{u->lon, u->lat}, util::Coordinate{v->lon, v->lat}); auto forward_speed_iter = find(segment_speed_lookup, Segment{u->node_id, v->node_id}); + if (forward_speed_iter != segment_speed_lookup.end()) { - auto new_segment_weight = - (forward_speed_iter->speed_source.speed > 0) - ? distanceAndSpeedToWeight(segment_length, - forward_speed_iter->speed_source.speed) - : INVALID_EDGE_WEIGHT; - m_geometry_list[forward_begin + leaf_object.fwd_segment_position].weight = - new_segment_weight; + const auto new_segment_weight = getNewWeight( + forward_speed_iter, + segment_length, + segment_speed_filenames, + current_fwd_segment->weight, + log_edge_updates_factor); + current_fwd_segment->weight = new_segment_weight; m_geometry_datasource[forward_begin + leaf_object.fwd_segment_position] = forward_speed_iter->speed_source.source; @@ -603,6 +642,7 @@ EdgeID Contractor::LoadEdgeExpandedGraph( counters[LUA_SOURCE] += 1; } } + // reverse_packed_geometry_id is the index id for geometry, weight and duration of the segment if (leaf_object.reverse_packed_geometry_id != SPECIAL_EDGEID) { const unsigned reverse_begin = @@ -612,6 +652,7 @@ EdgeID Contractor::LoadEdgeExpandedGraph( int rev_segment_position = (reverse_end - reverse_begin) - leaf_object.fwd_segment_position - 1; + const auto current_rev_segment = &(m_geometry_list[reverse_begin + rev_segment_position]); if (rev_segment_position == 0) { u = &(internal_to_external_node_map[leaf_object.v]); @@ -625,7 +666,7 @@ EdgeID Contractor::LoadEdgeExpandedGraph( rev_segment_position - 1] .node_id]); v = &(internal_to_external_node_map - [m_geometry_list[reverse_begin + rev_segment_position].node_id]); + [current_rev_segment->node_id]); } const double segment_length = util::coordinate_calculation::greatCircleDistance( util::Coordinate{u->lon, u->lat}, util::Coordinate{v->lon, v->lat}); @@ -634,13 +675,13 @@ EdgeID Contractor::LoadEdgeExpandedGraph( find(segment_speed_lookup, Segment{u->node_id, v->node_id}); if (reverse_speed_iter != segment_speed_lookup.end()) { - auto new_segment_weight = - (reverse_speed_iter->speed_source.speed > 0) - ? distanceAndSpeedToWeight(segment_length, - reverse_speed_iter->speed_source.speed) - : INVALID_EDGE_WEIGHT; - m_geometry_list[reverse_begin + rev_segment_position].weight = - new_segment_weight; + const auto new_segment_weight = getNewWeight( + reverse_speed_iter, + segment_length, + segment_speed_filenames, + current_rev_segment->weight, + log_edge_updates_factor); + current_rev_segment->weight = new_segment_weight; m_geometry_datasource[reverse_begin + rev_segment_position] = reverse_speed_iter->speed_source.source; diff --git a/src/tools/contract.cpp b/src/tools/contract.cpp index e7caee21e..a68537f8c 100644 --- a/src/tools/contract.cpp +++ b/src/tools/contract.cpp @@ -52,7 +52,11 @@ return_code parseArguments(int argc, char *argv[], contractor::ContractorConfig "level-cache,o", boost::program_options::value(&contractor_config.use_cached_priority) ->default_value(false), - "Use .level file to retain the contaction level for each node from the last run."); + "Use .level file to retain the contaction level for each node from the last run.")( + "edge-weight-updates-over-factor", + boost::program_options::value(&contractor_config.log_edge_updates_factor) + ->default_value(0.0), + "Use with `--segment-speed-file`. Provide an `x` factor, by which Extractor will log edge weights updated by more than this factor"); // hidden options, will be allowed on command line, but will not be shown to the user boost::program_options::options_description hidden_options("Hidden options");