implement flag edge-weight-updates-over-factor, to log edge weight
updates over provided x factor
This commit is contained in:
parent
eafe3fa928
commit
3d5a53566c
@ -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 |
|
@ -86,6 +86,10 @@ module.exports = function () {
|
|||||||
assert.equal(this.stdout.split('\n').length - 1, parseInt(lines));
|
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) => {
|
this.Then(/^datasource names should contain "(.+)"$/, (expectedData) => {
|
||||||
var actualData = fs.readFileSync(this.processedCacheFile + '.datasource_names', {encoding:'UTF-8'}).trim().split('\n').join(',');
|
var actualData = fs.readFileSync(this.processedCacheFile + '.datasource_names', {encoding:'UTF-8'}).trim().split('\n').join(',');
|
||||||
assert.equal(actualData, expectedData);
|
assert.equal(actualData, expectedData);
|
||||||
|
@ -89,7 +89,8 @@ class Contractor
|
|||||||
const std::string &geometry_filename,
|
const std::string &geometry_filename,
|
||||||
const std::string &datasource_names_filename,
|
const std::string &datasource_names_filename,
|
||||||
const std::string &datasource_indexes_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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ struct ContractorConfig
|
|||||||
bool use_cached_priority;
|
bool use_cached_priority;
|
||||||
|
|
||||||
unsigned requested_num_threads;
|
unsigned requested_num_threads;
|
||||||
|
double log_edge_updates_factor;
|
||||||
|
|
||||||
// A percentage of vertices that will be contracted for the hierarchy.
|
// A percentage of vertices that will be contracted for the hierarchy.
|
||||||
// Offers a trade-off between preprocessing and query time.
|
// Offers a trade-off between preprocessing and query time.
|
||||||
|
@ -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)));
|
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()
|
int Contractor::Run()
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -113,7 +148,8 @@ int Contractor::Run()
|
|||||||
config.geometry_path,
|
config.geometry_path,
|
||||||
config.datasource_names_path,
|
config.datasource_names_path,
|
||||||
config.datasource_indexes_path,
|
config.datasource_indexes_path,
|
||||||
config.rtree_leaf_path);
|
config.rtree_leaf_path,
|
||||||
|
config.log_edge_updates_factor);
|
||||||
|
|
||||||
// Contracting the edge-expanded graph
|
// Contracting the edge-expanded graph
|
||||||
|
|
||||||
@ -370,7 +406,8 @@ EdgeID Contractor::LoadEdgeExpandedGraph(
|
|||||||
const std::string &geometry_filename,
|
const std::string &geometry_filename,
|
||||||
const std::string &datasource_names_filename,
|
const std::string &datasource_names_filename,
|
||||||
const std::string &datasource_indexes_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)
|
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");
|
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 *u;
|
||||||
extractor::QueryNode *v;
|
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)
|
if (leaf_object.forward_packed_geometry_id != SPECIAL_EDGEID)
|
||||||
{
|
{
|
||||||
const unsigned forward_begin =
|
const unsigned forward_begin =
|
||||||
m_geometry_indices.at(leaf_object.forward_packed_geometry_id);
|
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)
|
if (leaf_object.fwd_segment_position == 0)
|
||||||
{
|
{
|
||||||
@ -574,23 +613,23 @@ EdgeID Contractor::LoadEdgeExpandedGraph(
|
|||||||
leaf_object.fwd_segment_position - 1]
|
leaf_object.fwd_segment_position - 1]
|
||||||
.node_id]);
|
.node_id]);
|
||||||
v = &(internal_to_external_node_map
|
v = &(internal_to_external_node_map
|
||||||
[m_geometry_list[forward_begin + leaf_object.fwd_segment_position]
|
[current_fwd_segment->node_id]);
|
||||||
.node_id]);
|
|
||||||
}
|
}
|
||||||
const double segment_length = util::coordinate_calculation::greatCircleDistance(
|
const double segment_length = util::coordinate_calculation::greatCircleDistance(
|
||||||
util::Coordinate{u->lon, u->lat}, util::Coordinate{v->lon, v->lat});
|
util::Coordinate{u->lon, u->lat}, util::Coordinate{v->lon, v->lat});
|
||||||
|
|
||||||
auto forward_speed_iter =
|
auto forward_speed_iter =
|
||||||
find(segment_speed_lookup, Segment{u->node_id, v->node_id});
|
find(segment_speed_lookup, Segment{u->node_id, v->node_id});
|
||||||
|
|
||||||
if (forward_speed_iter != segment_speed_lookup.end())
|
if (forward_speed_iter != segment_speed_lookup.end())
|
||||||
{
|
{
|
||||||
auto new_segment_weight =
|
const auto new_segment_weight = getNewWeight(
|
||||||
(forward_speed_iter->speed_source.speed > 0)
|
forward_speed_iter,
|
||||||
? distanceAndSpeedToWeight(segment_length,
|
segment_length,
|
||||||
forward_speed_iter->speed_source.speed)
|
segment_speed_filenames,
|
||||||
: INVALID_EDGE_WEIGHT;
|
current_fwd_segment->weight,
|
||||||
m_geometry_list[forward_begin + leaf_object.fwd_segment_position].weight =
|
log_edge_updates_factor);
|
||||||
new_segment_weight;
|
current_fwd_segment->weight = new_segment_weight;
|
||||||
m_geometry_datasource[forward_begin + leaf_object.fwd_segment_position] =
|
m_geometry_datasource[forward_begin + leaf_object.fwd_segment_position] =
|
||||||
forward_speed_iter->speed_source.source;
|
forward_speed_iter->speed_source.source;
|
||||||
|
|
||||||
@ -603,6 +642,7 @@ EdgeID Contractor::LoadEdgeExpandedGraph(
|
|||||||
counters[LUA_SOURCE] += 1;
|
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)
|
if (leaf_object.reverse_packed_geometry_id != SPECIAL_EDGEID)
|
||||||
{
|
{
|
||||||
const unsigned reverse_begin =
|
const unsigned reverse_begin =
|
||||||
@ -612,6 +652,7 @@ EdgeID Contractor::LoadEdgeExpandedGraph(
|
|||||||
|
|
||||||
int rev_segment_position =
|
int rev_segment_position =
|
||||||
(reverse_end - reverse_begin) - leaf_object.fwd_segment_position - 1;
|
(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)
|
if (rev_segment_position == 0)
|
||||||
{
|
{
|
||||||
u = &(internal_to_external_node_map[leaf_object.v]);
|
u = &(internal_to_external_node_map[leaf_object.v]);
|
||||||
@ -625,7 +666,7 @@ EdgeID Contractor::LoadEdgeExpandedGraph(
|
|||||||
rev_segment_position - 1]
|
rev_segment_position - 1]
|
||||||
.node_id]);
|
.node_id]);
|
||||||
v = &(internal_to_external_node_map
|
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(
|
const double segment_length = util::coordinate_calculation::greatCircleDistance(
|
||||||
util::Coordinate{u->lon, u->lat}, util::Coordinate{v->lon, v->lat});
|
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});
|
find(segment_speed_lookup, Segment{u->node_id, v->node_id});
|
||||||
if (reverse_speed_iter != segment_speed_lookup.end())
|
if (reverse_speed_iter != segment_speed_lookup.end())
|
||||||
{
|
{
|
||||||
auto new_segment_weight =
|
const auto new_segment_weight = getNewWeight(
|
||||||
(reverse_speed_iter->speed_source.speed > 0)
|
reverse_speed_iter,
|
||||||
? distanceAndSpeedToWeight(segment_length,
|
segment_length,
|
||||||
reverse_speed_iter->speed_source.speed)
|
segment_speed_filenames,
|
||||||
: INVALID_EDGE_WEIGHT;
|
current_rev_segment->weight,
|
||||||
m_geometry_list[reverse_begin + rev_segment_position].weight =
|
log_edge_updates_factor);
|
||||||
new_segment_weight;
|
current_rev_segment->weight = new_segment_weight;
|
||||||
m_geometry_datasource[reverse_begin + rev_segment_position] =
|
m_geometry_datasource[reverse_begin + rev_segment_position] =
|
||||||
reverse_speed_iter->speed_source.source;
|
reverse_speed_iter->speed_source.source;
|
||||||
|
|
||||||
|
@ -52,7 +52,11 @@ return_code parseArguments(int argc, char *argv[], contractor::ContractorConfig
|
|||||||
"level-cache,o",
|
"level-cache,o",
|
||||||
boost::program_options::value<bool>(&contractor_config.use_cached_priority)
|
boost::program_options::value<bool>(&contractor_config.use_cached_priority)
|
||||||
->default_value(false),
|
->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
|
// 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");
|
boost::program_options::options_description hidden_options("Hidden options");
|
||||||
|
Loading…
Reference in New Issue
Block a user