Change traffic CSV field value from weight to rate

and make the value required.

If the weight name is 'duration' than the rate value
can be computed as speed / 3.6

Issue: https://github.com/Project-OSRM/osrm-backend/issues/3823
This commit is contained in:
Michael Krasnyk 2017-04-10 16:44:48 +02:00 committed by Patrick Niklaus
parent a88fef2937
commit 37794a5e8a
6 changed files with 68 additions and 56 deletions

View File

@ -213,7 +213,7 @@ Feature: Basic Map Matching
And the speed file
"""
1,2,36
1,2,36,10
"""
And the contract extra arguments "--segment-speed-file {speeds_file}"
@ -240,7 +240,7 @@ Feature: Basic Map Matching
And the speed file
"""
1,2,36
1,2,36,10
"""
And the contract extra arguments "--segment-speed-file {speeds_file}"

View File

@ -30,12 +30,12 @@ Feature: Traffic - speeds
And the customize extra arguments "--segment-speed-file {speeds_file}"
And the speed file
"""
1,2,0
2,1,0
2,3,27
3,2,27
1,4,27
4,1,27
1,2,0,0
2,1,0,0
2,3,27,7.5
3,2,27,7.5
1,4,27,7.5
4,1,27,7.5
"""
And the query options
| annotations | datasources |
@ -56,12 +56,12 @@ Feature: Traffic - speeds
And the customize extra arguments "--segment-speed-file {speeds_file}"
And the speed file
"""
1,2,1,20020.7
2,1,1,20020.7
2,3,27,741.5
3,2,27,741.5
1,4,27,1275.7
4,1,27,1275.7
1,2,1,0.2777777
2,1,1
2,3,27
3,2,27,7.5
1,4,27,7.5
4,1,27,7.5
"""
And the query options
| annotations | datasources |
@ -89,26 +89,26 @@ Feature: Traffic - speeds
And the customize extra arguments "--segment-speed-file {speeds_file}"
And the speed file
"""
1,2,1,20020.789
2,1,1,20020.123
2,3,27,741.56789
3,2,27,741.3
1,4,1,34445.12
4,1,1,34445.3
1,2,1,0.27777777
2,1,1,0.27777777
2,3,27,7.5
3,2,27
1,4,1
4,1,1
"""
And the query options
| annotations | datasources |
When I route I should get
| from | to | route | speed | weights | a:datasources |
| a | b | ab,ab | 1 km/h | 20020.789,0 | 1:0 |
| a | c | ab,bc,bc | 2 km/h | 20020.789,741.568,0 | 1:1:0 |
| b | c | bc,bc | 27 km/h | 741.568,0 | 1:0 |
| a | d | ab,eb,de,de | 2 km/h | 20020.789,378.169,400.415,0 | 1:0:0 |
| a | b | ab,ab | 1 km/h | 20020.735,0 | 1:0 |
| a | c | ab,bc,bc | 2 km/h | 20020.735,741.509,0 | 1:1:0 |
| b | c | bc,bc | 27 km/h | 741.509,0 | 1:0 |
| a | d | ab,eb,de,de | 2 km/h | 20020.735,378.169,400.415,0 | 1:0:0 |
| d | c | dc,dc | 36 km/h | 956.805,0 | 0 |
| g | b | ab,ab | 1 km/h | 10010.392,0 | 1:0 |
| a | g | ab,ab | 1 km/h | 10010.397,0 | 1 |
| g | a | ab,ab | 1 km/h | 10010.064,0 | 1:1 |
| g | b | ab,ab | 1 km/h | 10010.365,0 | 1:0 |
| a | g | ab,ab | 1 km/h | 10010.37,0 | 1 |
| g | a | ab,ab | 1 km/h | 10010.37,0 | 1:1 |
Scenario: Speeds that isolate a single node (a)
@ -121,10 +121,10 @@ Feature: Traffic - speeds
"""
1,2,0
2,1,0
2,3,27
3,2,27
1,4,0
4,1,0
2,3,27,7.5
3,2,27,7.5
1,4,0,0
4,1,0,0
"""
And the query options
| annotations | true |

View File

@ -284,8 +284,8 @@ Feature: Weight tests
When I route I should get
| waypoints | route | distance | weights | times |
| a,d | , | 59.9m | 62,0 | 24s,0s |
| a,e | ,, | 60.1m | 68.7,10,0 | 38.5s,11s,0s |
| a,d | , | 59.9m | 20.5,0 | 24s,0s |
| a,e | ,, | 60.1m | 27.2,10,0 | 38.5s,11s,0s |
| d,e | ,, | 39.9m | 10,10,0 | 11s,11s,0s |
@traffic @speed
@ -320,6 +320,6 @@ Feature: Weight tests
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 |
| a,d | abcd,abcd | 59.9m | 6.996,0 | 7s,0s |
| a,e | abcd,ce,ce | 60.1m | 6.005,2.002,0 | 6s,2s,0s |
| d,e | abcd,ce,ce | 39.9m | 1.991,2.002,0 | 2s,2s,0s |

View File

@ -49,9 +49,9 @@ struct Segment final
struct SpeedSource final
{
SpeedSource() : speed(0), weight(std::numeric_limits<double>::quiet_NaN()) {}
SpeedSource() : speed(0), rate(std::numeric_limits<double>::quiet_NaN()) {}
unsigned speed;
double weight;
double rate;
std::uint8_t source;
};

View File

@ -11,7 +11,7 @@ BOOST_FUSION_ADAPT_STRUCT(osrm::updater::Segment,
(decltype(osrm::updater::Segment::to), to))
BOOST_FUSION_ADAPT_STRUCT(osrm::updater::SpeedSource,
(decltype(osrm::updater::SpeedSource::speed), speed)
(decltype(osrm::updater::SpeedSource::weight), weight))
(decltype(osrm::updater::SpeedSource::rate), rate))
BOOST_FUSION_ADAPT_STRUCT(osrm::updater::Turn,
(decltype(osrm::updater::Turn::from), from)
(decltype(osrm::updater::Turn::via), via)

View File

@ -62,18 +62,34 @@ inline EdgeWeight convertToDuration(double speed_in_kmh, double distance_in_mete
if (speed_in_kmh <= 0.)
return MAXIMAL_EDGE_DURATION;
const double speed_in_ms = speed_in_kmh / 3.6;
const double duration = distance_in_meters / speed_in_ms;
return std::max<EdgeWeight>(1, static_cast<EdgeWeight>(std::round(duration * 10.)));
const auto speed_in_ms = speed_in_kmh / 3.6;
const auto duration = distance_in_meters / speed_in_ms;
return std::max(1, boost::numeric_cast<EdgeWeight>(std::round(duration * 10.)));
}
inline EdgeWeight convertToWeight(double weight, double weight_multiplier, EdgeWeight duration)
inline EdgeWeight convertToWeight(const SpeedSource &value,
double distance_in_meters,
const extractor::ProfileProperties &profile_properties)
{
if (std::isfinite(weight))
return std::round(weight * weight_multiplier);
double rate = value.rate;
if (!std::isfinite(rate))
{
if (!profile_properties.fallback_to_duration)
{
util::Log(logWARNING) << "rate is not specified for '"
<< profile_properties.GetWeightName()
<< "', falling back to speed";
}
return duration == MAXIMAL_EDGE_DURATION ? INVALID_EDGE_WEIGHT
: duration * weight_multiplier / 10.;
rate = value.speed / 3.6;
}
if (rate <= 0.)
return INVALID_EDGE_WEIGHT;
const auto weight_multiplier = profile_properties.GetWeightMultiplier();
const auto weight = distance_in_meters / rate;
return std::max(1, boost::numeric_cast<EdgeWeight>(std::round(weight * weight_multiplier)));
}
#if !defined(NDEBUG)
@ -140,8 +156,6 @@ updateSegmentData(const UpdaterConfig &config,
const SegmentLookupTable &segment_speed_lookup,
extractor::SegmentDataContainer &segment_data)
{
auto weight_multiplier = profile_properties.GetWeightMultiplier();
std::vector<util::Coordinate> coordinates;
util::PackedVector<OSMNodeID> osm_node_ids;
extractor::files::readNodes(config.node_based_graph_path, coordinates, osm_node_ids);
@ -191,10 +205,9 @@ updateSegmentData(const UpdaterConfig &config,
auto v = osm_node_ids[nodes_range[segment_offset + 1]];
if (auto value = segment_speed_lookup({u, v}))
{
auto new_duration =
convertToDuration(value->speed, segment_lengths[segment_offset]);
auto new_weight =
convertToWeight(value->weight, weight_multiplier, new_duration);
auto segment_length = segment_lengths[segment_offset];
auto new_duration = convertToDuration(value->speed, segment_length);
auto new_weight = convertToWeight(*value, segment_length, profile_properties);
fwd_was_updated = true;
fwd_weights_range[segment_offset] = new_weight;
@ -225,10 +238,9 @@ updateSegmentData(const UpdaterConfig &config,
auto v = osm_node_ids[nodes_range[segment_offset + 1]];
if (auto value = segment_speed_lookup({v, u}))
{
auto new_duration =
convertToDuration(value->speed, segment_lengths[segment_offset]);
auto new_weight =
convertToWeight(value->weight, weight_multiplier, new_duration);
auto segment_length = segment_lengths[segment_offset];
auto new_duration = convertToDuration(value->speed, segment_length);
auto new_weight = convertToWeight(*value, segment_length, profile_properties);
rev_was_updated = true;
rev_weights_range[segment_offset] = new_weight;