diff --git a/features/guidance/turn.feature b/features/guidance/turn.feature index c5c4df9cb..da34be0b5 100644 --- a/features/guidance/turn.feature +++ b/features/guidance/turn.feature @@ -975,6 +975,7 @@ Feature: Simple Turns Given the node map | | f | | | | e | | + | | | | | g | | d | | | | | | | | | @@ -1012,3 +1013,27 @@ Feature: Simple Turns | f,a | depart,arrive | Hermannstr,Hermannstr | | y,f | depart,arrive | Hermannstr,Hermannstr | | f,y | depart,arrive | Hermannstr,Hermannstr | + + Scenario: Turning into splitting road + Given the node map + | | a | | | + | | b | | | + | | | | | + | | | | | + | c | | d | | + | | | | | + | | | | e | + | | | | | + | | | f | | + + And the ways + | nodes | name | highway | oneway | + | ab | road | primary | no | + | bc | road | primary | yes | + | fdb | road | primary | yes | + | de | turn | primary | no | + + When I route I should get + | waypoints | turns | route | + | f,a | depart,arrive | road,road | + | e,a | depart,turn slight right,arrive | turn,road,road | diff --git a/include/util/debug.hpp b/include/util/debug.hpp index de16cc7be..6c78afec8 100644 --- a/include/util/debug.hpp +++ b/include/util/debug.hpp @@ -25,8 +25,6 @@ inline void print(const engine::guidance::RouteStep &step) std::cout << static_cast(step.maneuver.instruction.type) << " " << static_cast(step.maneuver.instruction.direction_modifier) << " " << static_cast(step.maneuver.waypoint_type) << " " - << " Lanes: (" << static_cast(lanes.lanes_in_turn) << ", " - << static_cast(lanes.first_lane_from_the_right) << ")" << " Duration: " << step.duration << " Distance: " << step.distance << " Geometry: " << step.geometry_begin << " " << step.geometry_end << " exit: " << step.maneuver.exit << " Intersections: " << step.intersections.size() @@ -40,6 +38,8 @@ inline void print(const engine::guidance::RouteStep &step) std::cout << ", entry: "; for (auto entry : intersection.entry) std::cout << " " << (entry ? "true" : "false"); + std::cout << " Lanes: (" << static_cast(intersection.lanes.lanes_in_turn) << ", " + << static_cast(intersection.lanes.first_lane_from_the_right) << ")"; std::cout << ")"; } std::cout << "] name[" << step.name_id << "]: " << step.name; diff --git a/src/engine/guidance/post_processing.cpp b/src/engine/guidance/post_processing.cpp index 98d9d28c6..bce40f2dc 100644 --- a/src/engine/guidance/post_processing.cpp +++ b/src/engine/guidance/post_processing.cpp @@ -815,6 +815,20 @@ std::vector collapseTurns(std::vector steps) invalidateStep(steps[step_index]); } } + else if (step_index + 2 < steps.size() && + current_step.maneuver.instruction.type == TurnType::NewName && + steps[step_index + 1].maneuver.instruction.type == TurnType::NewName && + one_back_step.name == steps[step_index + 1].name) + { + // if we are crossing an intersection and go immediately after into a name change, + // we don't wan't to collapse the initial intersection. + // a - b ---BRIDGE -- c + steps[one_back_index] = + elongate(std::move(steps[one_back_index]), + elongate(std::move(steps[step_index]), steps[step_index + 1])); + invalidateStep(steps[step_index]); + invalidateStep(steps[step_index + 1]); + } else if (choiceless(current_step, one_back_step) || one_back_step.distance <= MAX_COLLAPSE_DISTANCE) { diff --git a/src/extractor/guidance/intersection_generator.cpp b/src/extractor/guidance/intersection_generator.cpp index c16fa980b..5311cd713 100644 --- a/src/extractor/guidance/intersection_generator.cpp +++ b/src/extractor/guidance/intersection_generator.cpp @@ -160,7 +160,7 @@ Intersection IntersectionGenerator::getConnectedRoads(const NodeID from_node, intersection[self_u_turn].entry_allowed = true; } - return mergeSegregatedRoads(std::move(intersection)); + return intersection; } bool IntersectionGenerator::canMerge(const Intersection &intersection, @@ -184,8 +184,8 @@ bool IntersectionGenerator::canMerge(const Intersection &intersection, if (first_data.road_classification != second_data.road_classification) return false; - //may not be on a roundabout - if( first_data.roundabout || second_data.roundabout) + // may not be on a roundabout + if (first_data.roundabout || second_data.roundabout) return false; // exactly one of them has to be reversed @@ -381,12 +381,12 @@ Intersection IntersectionGenerator::mergeSegregatedRoads(Intersection intersecti Intersection IntersectionGenerator::adjustForJoiningRoads(const NodeID node_at_intersection, Intersection intersection) const { + // nothing to do for dead ends + if ( intersection.size() <= 1) + return intersection; + for (auto &road : intersection) { - // prune to short intersections to save on compute overhead - if (node_based_graph.GetEdgeData(road.turn.eid).distance > 10) - continue; - // to find out about the above situation, we need to look at the next intersection (at d in // the example). If the initial road can be merged to the left/right, we are about to adjust // the angle. @@ -395,15 +395,36 @@ Intersection IntersectionGenerator::adjustForJoiningRoads(const NodeID node_at_i if (next_intersection_along_road.size() <= 1) continue; + const auto adjustAngle = [](double angle, double offset) { + angle += offset; + if (angle > 360) + return angle - 360.; + else if (angle < 0) + return angle + 360.; + return angle; + }; + if (canMerge(next_intersection_along_road, 0, 1)) { - std::cout << "Merge at next intersection" << std::endl; + const auto offset = 0.5 * angularDeviation(next_intersection_along_road[0].turn.angle, + next_intersection_along_road[1].turn.angle); + // at the target intersection, we merge to the right, so we need to shift the current + // angle to the left + road.turn.angle = adjustAngle(road.turn.angle, offset); } else if (canMerge(next_intersection_along_road, 0, next_intersection_along_road.size() - 1)) { - std::cout << "Merge at next intersection (2)" << std::endl; + const auto offset = + 0.5 * angularDeviation( + next_intersection_along_road[0].turn.angle, + next_intersection_along_road[next_intersection_along_road.size() - 1] + .turn.angle); + // at the target intersection, we merge to the left, so we need to shift the current + // angle to the right + road.turn.angle = adjustAngle(road.turn.angle, -offset); } } + std::cout << std::flush; return intersection; }