implement flag edge-weight-updates-over-factor, to log edge weight

updates over provided x factor
This commit is contained in:
karenzshea 2016-09-12 12:16:56 -04:00 committed by Moritz Kobitzsch
parent eafe3fa928
commit 3d5a53566c
7 changed files with 103 additions and 22 deletions

View File

@ -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 |

View File

@ -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

View File

@ -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);

View File

@ -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);
};
}
}

View File

@ -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.

View File

@ -81,6 +81,41 @@ inline EdgeWeight distanceAndSpeedToWeight(double distance_in_meters, double spe
return std::max<EdgeWeight>(1, static_cast<EdgeWeight>(std::round(duration * 10)));
}
// Returns updated edge weight
template <class IterType>
EdgeWeight getNewWeight(IterType speed_iter,
const double &segment_length,
const std::vector<std::string> &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;

View File

@ -52,7 +52,11 @@ return_code parseArguments(int argc, char *argv[], contractor::ContractorConfig
"level-cache,o",
boost::program_options::value<bool>(&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<double>(&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");