use weight_multiplier to convert fallback durations to weights

This commit is contained in:
Michael Krasnyk 2017-02-10 11:41:31 +01:00 committed by Patrick Niklaus
parent 2218658969
commit ce685da92c
2 changed files with 60 additions and 19 deletions

View File

@ -285,3 +285,37 @@ Feature: Weight tests
| a,d | , | 59.9m | 62,0 | 24s,0s | | a,d | , | 59.9m | 62,0 | 24s,0s |
| a,e | ,, | 60.1m | 68.7,10,0 | 38.5s,11s,0s | | a,e | ,, | 60.1m | 68.7,10,0 | 38.5s,11s,0s |
| d,e | ,, | 39.9m | 10,10,0 | 11s,11s,0s | | d,e | ,, | 39.9m | 10,10,0 | 11s,11s,0s |
Scenario: Step weights -- segment_function with speed and turn updates with fallback to durations
Given the profile file "testbot" extended with
"""
api_version = 1
properties.weight_precision = 3
"""
And the node map
"""
a---b---c---d
.
e
"""
And the ways
| nodes |
| abcd |
| ce |
And the speed file
"""
1,2,24
2,1,24
"""
And the turn penalty file
"""
2,3,5,1
"""
And the contract extra arguments "--segment-speed-file {speeds_file} --turn-penalty-file {penalties_file}"
When I route I should get
| waypoints | route | distance | weights | times |
| a,d | abcd,abcd | 59.9m | 6.993,0 | 7s,0s |
| a,e | abcd,ce,ce | 60.1m | 6.002,2.002,0 | 6s,2s,0s |
| d,e | abcd,ce,ce | 39.9m | 1.991,2.002,0 | 2s,2s,0s |

View File

@ -291,13 +291,22 @@ template <typename Key, typename Value> struct CSVFilesParser
inline EdgeWeight ConvertToDuration(double distance_in_meters, double speed_in_kmh) inline EdgeWeight ConvertToDuration(double distance_in_meters, double speed_in_kmh)
{ {
if (speed_in_kmh <= 0.) if (speed_in_kmh <= 0.)
return INVALID_EDGE_WEIGHT; return MAXIMAL_EDGE_DURATION;
const double speed_in_ms = speed_in_kmh / 3.6; const double speed_in_ms = speed_in_kmh / 3.6;
const double duration = distance_in_meters / speed_in_ms; const double duration = distance_in_meters / speed_in_ms;
return std::max<EdgeWeight>(1, static_cast<EdgeWeight>(std::round(duration * 10.))); return std::max<EdgeWeight>(1, static_cast<EdgeWeight>(std::round(duration * 10.)));
} }
inline EdgeWeight ConvertToWeight(double weight, double weight_multiplier, EdgeWeight duration)
{
if (std::isfinite(weight))
return std::round(weight * weight_multiplier);
return duration == MAXIMAL_EDGE_DURATION ? INVALID_EDGE_WEIGHT
: duration * weight_multiplier / 10.;
}
// Returns updated edge weight // Returns updated edge weight
void GetNewWeight(const ContractorConfig &config, void GetNewWeight(const ContractorConfig &config,
const SpeedSource &value, const SpeedSource &value,
@ -312,9 +321,8 @@ void GetNewWeight(const ContractorConfig &config,
new_segment_duration = ConvertToDuration(segment_length, value.speed); new_segment_duration = ConvertToDuration(segment_length, value.speed);
// Update the edge weight or fallback to the new edge duration // Update the edge weight or fallback to the new edge duration
new_segment_weight = std::isfinite(value.weight) new_segment_weight =
? std::round(value.weight * config.weight_multiplier) ConvertToWeight(value.weight, config.weight_multiplier, new_segment_duration);
: new_segment_duration;
// The check here is enabled by the `--edge-weight-updates-over-factor` flag it logs a warning // The check here is enabled by the `--edge-weight-updates-over-factor` flag it logs a warning
// if the new duration exceeds a heuristic of what a reasonable duration update is // if the new duration exceeds a heuristic of what a reasonable duration update is
@ -363,6 +371,14 @@ int Contractor::Run()
EdgeID max_edge_id = LoadEdgeExpandedGraph(config, edge_based_edge_list, node_weights); EdgeID max_edge_id = LoadEdgeExpandedGraph(config, edge_based_edge_list, node_weights);
#if !defined(NDEBUG)
if (config.turn_penalty_lookup_paths.empty())
{ // don't check weights consistency with turn updates that can break assertion
// condition with turn weight penalties negative updates
CheckWeightsConsistency(config, edge_based_edge_list);
}
#endif
// Contracting the edge-expanded graph // Contracting the edge-expanded graph
TIMER_START(contraction); TIMER_START(contraction);
@ -838,9 +854,8 @@ Contractor::LoadEdgeExpandedGraph(const ContractorConfig &config,
segment_duration = ConvertToDuration(segment.segment_length, value->speed); segment_duration = ConvertToDuration(segment.segment_length, value->speed);
segment_weight = std::isfinite(value->weight) segment_weight = ConvertToWeight(
? std::round(value->weight * config.weight_multiplier) value->weight, config.weight_multiplier, segment_duration);
: segment_duration;
} }
// Update the edge weight and the next OSM node ID // Update the edge weight and the next OSM node ID
@ -868,10 +883,10 @@ Contractor::LoadEdgeExpandedGraph(const ContractorConfig &config,
{ {
turn_duration_penalty = turn_duration_penalty =
boost::numeric_cast<TurnPenalty>(std::round(value->duration * 10.)); boost::numeric_cast<TurnPenalty>(std::round(value->duration * 10.));
turn_weight_penalty = std::isfinite(value->weight) turn_weight_penalty = boost::numeric_cast<TurnPenalty>(
? boost::numeric_cast<TurnPenalty>(std::round( std::round(std::isfinite(value->weight)
value->weight * config.weight_multiplier)) ? value->weight * config.weight_multiplier
: turn_duration_penalty; : turn_duration_penalty * config.weight_multiplier / 10.));
const auto weight_min_value = static_cast<EdgeWeight>(header->num_osm_nodes); const auto weight_min_value = static_cast<EdgeWeight>(header->num_osm_nodes);
if (turn_weight_penalty + new_weight < weight_min_value) if (turn_weight_penalty + new_weight < weight_min_value)
@ -918,14 +933,6 @@ Contractor::LoadEdgeExpandedGraph(const ContractorConfig &config,
[&] { save_penalties(config.turn_duration_penalties_path, turn_duration_penalties); }); [&] { save_penalties(config.turn_duration_penalties_path, turn_duration_penalties); });
} }
#if !defined(NDEBUG)
if (!update_turn_penalties)
{ // don't check weights consistency with turn updates that can break assertion
// condition with turn weight penalties negative updates
CheckWeightsConsistency(config, edge_based_edge_list);
}
#endif
util::Log() << "Done reading edges"; util::Log() << "Done reading edges";
return graph_header.max_edge_id; return graph_header.max_edge_id;
} }