Don't include turn costs when calculation weight/duration/speed annotations.

This commit is contained in:
Daniel Patterson 2017-07-24 12:47:05 -07:00
parent 6c0ab24100
commit dac6bb27aa
6 changed files with 71 additions and 12 deletions

View File

@ -539,10 +539,10 @@ Annotation of the whole route leg with fine-grained information about each segme
**Properties**
- `distance`: The distance, in metres, between each pair of coordinates
- `duration`: The duration between each pair of coordinates, in seconds
- `duration`: The duration between each pair of coordinates, in seconds. Does not include the duration of any turns.
- `datasources`: The index of the datasource for the speed between each pair of coordinates. `0` is the default profile, other values are supplied via `--segment-speed-file` to `osrm-contract`
- `nodes`: The OSM node ID for each coordinate along the route, excluding the first/last user-supplied coordinates
- `weight`: The weights between each pair of coordinates
- `weight`: The weights between each pair of coordinates. Does not include any turn costs.
- `speed`: Convenience field, calculation of `distance / duration` rounded to one decimal place
#### Example

View File

@ -0,0 +1,30 @@
@routing @speed @annotations @turn_penalty
Feature: Annotations
Background:
Given the profile "turnbot"
Given a grid size of 100 meters
Scenario: Ensure that turn penalties aren't included in annotations
Given the node map
"""
h i
j k l m
"""
And the query options
| annotations | duration,speed,weight |
And the ways
| nodes | highway |
| hk | residential |
| il | residential |
| jk | residential |
| lk | residential |
| lm | residential |
When I route I should get
| from | to | route | a:speed | a:weight |
| h | j | hk,jk,jk | 6.7:6.7 | 15:15 |
| i | m | il,lm,lm | 6.7:6.7 | 15:15 |
| j | m | jk,lm | 6.7:6.7:6.7 | 15:15:15 |

View File

@ -78,10 +78,18 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
}
prev_coordinate = coordinate;
geometry.annotations.emplace_back(
LegGeometry::Annotation{current_distance,
path_point.duration_until_turn / 10.,
path_point.weight_until_turn / facade.GetWeightMultiplier(),
geometry.annotations.emplace_back(LegGeometry::Annotation{
current_distance,
// NOTE: we want annotations to include only the duration/weight
// of the segment itself. For segments immediately before
// a turn, the duration_until_turn/weight_until_turn values
// include the turn cost. To counter this, we subtract
// the duration_of_turn/weight_of_turn value, which is 0 for
// non-preceeding-turn segments, but contains the turn value
// for segments before a turn.
(path_point.duration_until_turn - path_point.duration_of_turn) / 10.,
(path_point.weight_until_turn - path_point.weight_of_turn) /
facade.GetWeightMultiplier(),
path_point.datasource_id});
geometry.locations.push_back(std::move(coordinate));
geometry.osm_node_ids.push_back(facade.GetOSMNodeIDOfNode(path_point.turn_via_node));

View File

@ -38,8 +38,12 @@ struct LegGeometry
struct Annotation
{
double distance; // distance in meters
double duration; // duration in seconds
double weight; // weight value
// Total duration of a segment, in seconds, NOT including
// the turn penalty if the segment preceeds a turn
double duration;
double weight; // weight value, NOT including the turn weight
DatasourceID datasource;
};
std::vector<Annotation> annotations;

View File

@ -24,9 +24,17 @@ struct PathData
// name of the street that leads to the turn
unsigned name_id;
// weight that is traveled on the segment until the turn is reached
// including the turn weight, if one exists
EdgeWeight weight_until_turn;
// duration that is traveled on the segment until the turn is reached
// If this segment immediately preceeds a turn, then duration_of_turn
// will contain the weight of the turn. Otherwise it will be 0.
EdgeWeight weight_of_turn;
// duration that is traveled on the segment until the turn is reached,
// including a turn if the segment preceeds one.
EdgeWeight duration_until_turn;
// If this segment immediately preceeds a turn, then duration_of_turn
// will contain the duration of the turn. Otherwise it will be 0.
EdgeWeight duration_of_turn;
// instruction to execute at the turn
extractor::guidance::TurnInstruction turn_instruction;
// turn lane data

View File

@ -186,7 +186,9 @@ void annotatePath(const FacadeT &facade,
unpacked_path.push_back(PathData{id_vector[segment_idx + 1],
name_index,
weight_vector[segment_idx],
0,
duration_vector[segment_idx],
0,
extractor::guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
travel_mode,
@ -200,10 +202,15 @@ void annotatePath(const FacadeT &facade,
if (facade.HasLaneData(turn_id))
unpacked_path.back().lane_data = facade.GetLaneData(turn_id);
const auto turn_duration = facade.GetDurationPenaltyForEdgeID(turn_id);
const auto turn_weight = facade.GetWeightPenaltyForEdgeID(turn_id);
unpacked_path.back().entry_class = facade.GetEntryClass(turn_id);
unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().duration_until_turn += facade.GetDurationPenaltyForEdgeID(turn_id);
unpacked_path.back().weight_until_turn += facade.GetWeightPenaltyForEdgeID(turn_id);
unpacked_path.back().duration_until_turn += turn_duration;
unpacked_path.back().duration_of_turn = turn_duration;
unpacked_path.back().weight_until_turn += turn_weight;
unpacked_path.back().weight_of_turn = turn_weight;
unpacked_path.back().pre_turn_bearing = facade.PreTurnBearing(turn_id);
unpacked_path.back().post_turn_bearing = facade.PostTurnBearing(turn_id);
}
@ -262,7 +269,9 @@ void annotatePath(const FacadeT &facade,
PathData{id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
facade.GetNameIndex(target_node_id),
weight_vector[segment_idx],
0,
duration_vector[segment_idx],
0,
extractor::guidance::TurnInstruction::NO_TURN(),
{{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID},
facade.GetTravelMode(target_node_id),