Pass edge-based node segregated flag to the post processing routine.

This commit is contained in:
vng 2017-10-19 13:56:47 +00:00 committed by Michael Krasnyk
parent ac5e095d17
commit ec7e58e10e
9 changed files with 89 additions and 8 deletions

View File

@ -74,7 +74,7 @@ Feature: Collapse
When I route I should get When I route I should get
| waypoints | route | turns | locations | | waypoints | route | turns | locations |
| a,i | first,second,third,third | depart,turn left,turn slight left,arrive | a,b,e,i | | a,i | first,third,third | depart,turn sharp left,arrive | a,b,i |
Scenario: Segregated Intersection, Cross Belonging to Correct Street Scenario: Segregated Intersection, Cross Belonging to Correct Street
Given the node map Given the node map

View File

@ -177,6 +177,7 @@ class RouteAPI : public BaseAPI
leg.steps = guidance::anticipateLaneChange(std::move(leg.steps)); leg.steps = guidance::anticipateLaneChange(std::move(leg.steps));
leg.steps = guidance::buildIntersections(std::move(leg.steps)); leg.steps = guidance::buildIntersections(std::move(leg.steps));
leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps)); leg.steps = guidance::suppressShortNameSegments(std::move(leg.steps));
leg.steps = guidance::suppressSegregated(std::move(leg.steps));
leg.steps = guidance::assignRelativeLocations(std::move(leg.steps), leg.steps = guidance::assignRelativeLocations(std::move(leg.steps),
leg_geometry, leg_geometry,
phantoms.source_phantom, phantoms.source_phantom,

View File

@ -56,6 +56,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const auto source_node_id = source_traversed_in_reverse ? source_node.reverse_segment_id.id const auto source_node_id = source_traversed_in_reverse ? source_node.reverse_segment_id.id
: source_node.forward_segment_id.id; : source_node.forward_segment_id.id;
const auto source_name_id = facade.GetNameIndex(source_node_id); const auto source_name_id = facade.GetNameIndex(source_node_id);
bool is_segregated = facade.IsSegregated(source_node_id);
const auto source_mode = facade.GetTravelMode(source_node_id); const auto source_mode = facade.GetTravelMode(source_node_id);
auto source_classes = facade.GetClasses(facade.GetClassData(source_node_id)); auto source_classes = facade.GetClasses(facade.GetClassData(source_node_id));
@ -127,6 +128,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
intersection.classes = facade.GetClasses(path_point.classes); intersection.classes = facade.GetClasses(path_point.classes);
steps.push_back(RouteStep{step_name_id, steps.push_back(RouteStep{step_name_id,
is_segregated,
name.to_string(), name.to_string(),
ref.to_string(), ref.to_string(),
pronunciation.to_string(), pronunciation.to_string(),
@ -147,10 +149,12 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
if (leg_data_index + 1 < leg_data.size()) if (leg_data_index + 1 < leg_data.size())
{ {
step_name_id = leg_data[leg_data_index + 1].name_id; step_name_id = leg_data[leg_data_index + 1].name_id;
is_segregated = leg_data[leg_data_index + 1].is_segregated;
} }
else else
{ {
step_name_id = facade.GetNameIndex(target_node_id); step_name_id = facade.GetNameIndex(target_node_id);
is_segregated = facade.IsSegregated(target_node_id);
} }
// extract bearings // extract bearings
@ -206,6 +210,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
intersection.classes = facade.GetClasses(facade.GetClassData(target_node_id)); intersection.classes = facade.GetClasses(facade.GetClassData(target_node_id));
BOOST_ASSERT(duration >= 0); BOOST_ASSERT(duration >= 0);
steps.push_back(RouteStep{step_name_id, steps.push_back(RouteStep{step_name_id,
is_segregated,
facade.GetNameForID(step_name_id).to_string(), facade.GetNameForID(step_name_id).to_string(),
facade.GetRefForID(step_name_id).to_string(), facade.GetRefForID(step_name_id).to_string(),
facade.GetPronunciationForID(step_name_id).to_string(), facade.GetPronunciationForID(step_name_id).to_string(),
@ -249,6 +254,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const EdgeWeight duration = std::max(0, target_duration - source_duration); const EdgeWeight duration = std::max(0, target_duration - source_duration);
steps.push_back(RouteStep{source_name_id, steps.push_back(RouteStep{source_name_id,
is_segregated,
facade.GetNameForID(source_name_id).to_string(), facade.GetNameForID(source_name_id).to_string(),
facade.GetRefForID(source_name_id).to_string(), facade.GetRefForID(source_name_id).to_string(),
facade.GetPronunciationForID(source_name_id).to_string(), facade.GetPronunciationForID(source_name_id).to_string(),
@ -290,6 +296,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
BOOST_ASSERT(!leg_geometry.locations.empty()); BOOST_ASSERT(!leg_geometry.locations.empty());
steps.push_back(RouteStep{target_name_id, steps.push_back(RouteStep{target_name_id,
facade.IsSegregated(target_node_id),
facade.GetNameForID(target_name_id).to_string(), facade.GetNameForID(target_name_id).to_string(),
facade.GetRefForID(target_name_id).to_string(), facade.GetRefForID(target_name_id).to_string(),
facade.GetPronunciationForID(target_name_id).to_string(), facade.GetPronunciationForID(target_name_id).to_string(),

View File

@ -140,6 +140,8 @@ void combineRouteSteps(RouteStep &step_at_turn_location,
// alias for suppressing a step, using CombineRouteStep with NoModificationStrategy only // alias for suppressing a step, using CombineRouteStep with NoModificationStrategy only
void suppressStep(RouteStep &step_at_turn_location, RouteStep &step_after_turn_location); void suppressStep(RouteStep &step_at_turn_location, RouteStep &step_after_turn_location);
std::vector<RouteStep> suppressSegregated(std::vector<RouteStep> steps);
} /* namespace guidance */ } /* namespace guidance */
} /* namespace osrm */ } /* namespace osrm */
} /* namespace osrm */ } /* namespace osrm */

View File

@ -60,6 +60,7 @@ inline IntermediateIntersection getInvalidIntersection()
struct RouteStep struct RouteStep
{ {
unsigned name_id; unsigned name_id;
bool is_segregated;
std::string name; std::string name;
std::string ref; std::string ref;
std::string pronunciation; std::string pronunciation;
@ -164,6 +165,8 @@ inline RouteStep &RouteStep::ElongateBy(const RouteStep &following_step)
following_step.intersections.begin(), following_step.intersections.begin(),
following_step.intersections.end()); following_step.intersections.end());
is_segregated = false;
return *this; return *this;
} }

View File

@ -27,6 +27,8 @@ struct PathData
NodeID turn_via_node; NodeID turn_via_node;
// name of the street that leads to the turn // name of the street that leads to the turn
unsigned name_id; unsigned name_id;
// segregated edge-based node that leads to the turn
bool is_segregated;
// weight that is traveled on the segment until the turn is reached // weight that is traveled on the segment until the turn is reached
// including the turn weight, if one exists // including the turn weight, if one exists
EdgeWeight weight_until_turn; EdgeWeight weight_until_turn;

View File

@ -164,6 +164,9 @@ void annotatePath(const FacadeT &facade,
const auto turn_id = edge_data.turn_id; // edge-based graph edge index const auto turn_id = edge_data.turn_id; // edge-based graph edge index
const auto node_id = *node_from; // edge-based graph node index const auto node_id = *node_from; // edge-based graph node index
const auto name_index = facade.GetNameIndex(node_id); const auto name_index = facade.GetNameIndex(node_id);
const bool is_segregated = facade.IsSegregated(node_id);
if (is_segregated)
util::Log() << "111 Segregated node";
const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id); const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id);
const extractor::TravelMode travel_mode = facade.GetTravelMode(node_id); const extractor::TravelMode travel_mode = facade.GetTravelMode(node_id);
const auto classes = facade.GetClassData(node_id); const auto classes = facade.GetClassData(node_id);
@ -193,6 +196,7 @@ void annotatePath(const FacadeT &facade,
{ {
unpacked_path.push_back(PathData{id_vector[segment_idx + 1], unpacked_path.push_back(PathData{id_vector[segment_idx + 1],
name_index, name_index,
is_segregated,
weight_vector[segment_idx], weight_vector[segment_idx],
0, 0,
duration_vector[segment_idx], duration_vector[segment_idx],
@ -266,6 +270,7 @@ void annotatePath(const FacadeT &facade,
unpacked_path.push_back( unpacked_path.push_back(
PathData{id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1], PathData{id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
facade.GetNameIndex(target_node_id), facade.GetNameIndex(target_node_id),
facade.IsSegregated(target_node_id),
weight_vector[segment_idx], weight_vector[segment_idx],
0, 0,
duration_vector[segment_idx], duration_vector[segment_idx],

View File

@ -51,15 +51,15 @@ double findTotalTurnAngle(const RouteStep &entry_step, const RouteStep &exit_ste
util::bearing::angleBetween(entry_step_entry_bearing, exit_step_exit_bearing); util::bearing::angleBetween(entry_step_entry_bearing, exit_step_exit_bearing);
// both angles are in the same direction, the total turn gets increased // both angles are in the same direction, the total turn gets increased
//  //
// a ---- b // a ---- b
// \  // \
// c // c
// | // |
// d // d
// //
// Will be considered just like // Will be considered just like
//  //
// a -----b // a -----b
// | // |
// c // c
@ -89,11 +89,11 @@ double findTotalTurnAngle(const RouteStep &entry_step, const RouteStep &exit_ste
else else
{ {
// to prevent ignoring angles like // to prevent ignoring angles like
//  //
// a -- b // a -- b
// | // |
// c -- d // c -- d
//  //
// We don't combine both turn angles here but keep the very first turn angle. // We don't combine both turn angles here but keep the very first turn angle.
// We choose the first one, since we consider the first maneuver in a merge range the // We choose the first one, since we consider the first maneuver in a merge range the
// important one // important one
@ -441,13 +441,14 @@ RouteSteps collapseTurnInstructions(RouteSteps steps)
TransferSignageStrategy(), TransferSignageStrategy(),
NoModificationStrategy()); NoModificationStrategy());
} }
// if the current collapsing triggers, we can check for advanced scenarios that only are // if the current collapsing triggers, we can check for advanced scenarios that only are
// possible after an inital collapse step (e.g. name change right after a u-turn) // possible after an inital collapse step (e.g. name change right after a u-turn)
//  //
// f - e - d // f - e - d
// | | // | |
// a - b - c // a - b - c
//  //
// In this scenario, bc and de might belong to a different road than a-b and f-e (since // In this scenario, bc and de might belong to a different road than a-b and f-e (since
// there are no fix conventions how to label them in segregated intersections). These steps // there are no fix conventions how to label them in segregated intersections). These steps
// might only become apparent after some initial collapsing // might only become apparent after some initial collapsing
@ -479,6 +480,64 @@ RouteSteps collapseTurnInstructions(RouteSteps steps)
return steps; return steps;
} }
std::vector<RouteStep> suppressSegregated(std::vector<RouteStep> steps)
{
if (steps.size() <= 2)
return steps;
// start of with no-op
for (auto current_step = steps.begin() + 1; current_step + 1 != steps.end(); ++current_step)
{
/// @todo All the prologue checks are taken from the collapseTurnInstructions function.
/// Factor out to the separate routing when changes will be approved.
if (entersRoundabout(current_step->maneuver.instruction) ||
staysOnRoundabout(current_step->maneuver.instruction))
{
// If postProcess is called before then all corresponding leavesRoundabout steps are
// removed and the current roundabout step can be ignored by directly proceeding to
// the next step.
// If postProcess is not called before then all steps till the next leavesRoundabout
// step must be skipped to prevent incorrect roundabouts post-processing.
// are we done for good?
if (current_step + 1 == steps.end())
break;
else
continue;
}
// only operate on actual turns
if (!hasTurnType(*current_step))
continue;
// don't collapse next step if it is a waypoint alread
const auto next_step = findNextTurn(current_step);
if (hasWaypointType(*next_step))
break;
const auto previous_step = findPreviousTurn(current_step);
// don't collapse anything that does change modes
if (current_step->mode != next_step->mode)
continue;
if (current_step->is_segregated)
{
/// @todo Need to apply correct combine strategies.
util::Log() << "222 Segregated node";
combineRouteSteps(*current_step,
*next_step,
AdjustToCombinedTurnStrategy(*previous_step),
TransferSignageStrategy(),
NoModificationStrategy());
}
}
return removeNoTurnInstructions(std::move(steps));
}
} // namespace guidance } // namespace guidance
} // namespace engine } // namespace engine
} // namespace osrm } // namespace osrm

View File

@ -39,6 +39,7 @@ BOOST_AUTO_TEST_CASE(trim_short_segments)
// Check that duplicated coordinate in the end is removed // Check that duplicated coordinate in the end is removed
std::vector<RouteStep> steps = {{324, std::vector<RouteStep> steps = {{324,
false,
"Central Park West", "Central Park West",
"", "",
"", "",
@ -60,6 +61,7 @@ BOOST_AUTO_TEST_CASE(trim_short_segments)
3, 3,
{intersection1}}, {intersection1}},
{324, {324,
false,
"Central Park West", "Central Park West",
"", "",
"", "",