From ecee13bffa881e6d84a3b83687df76059e9ab695 Mon Sep 17 00:00:00 2001 From: Moritz Kobitzsch Date: Thu, 20 Oct 2016 12:15:36 +0200 Subject: [PATCH] actually calculate distance instead of using `.distance` which is a timing value --- CHANGELOG.md | 1 + features/car/names.feature | 1 + .../guidance/dedicated-turn-roads.feature | 30 +++++++++++++++++++ features/guidance/turn-lanes.feature | 29 ++++++++++++++++-- .../guidance/coordinate_extractor.hpp | 5 ++++ .../guidance/intersection_generator.hpp | 3 ++ include/util/coordinate_calculation.hpp | 20 +++++++++++++ .../guidance/coordinate_extractor.cpp | 6 ++++ .../guidance/intersection_generator.cpp | 6 ++++ src/extractor/guidance/sliproad_handler.cpp | 8 +++-- src/extractor/guidance/turn_discovery.cpp | 8 ++++- 11 files changed, 111 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dccbf516..5ce4a4d31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ - Bugfixes - fixed a bug where polyline decoding on a defective polyline could end up in out-of-bound access on a vector - fixed compile errors in tile unit-test framework + - fixed a bug that could result in inconsistent behaviour when collapsing instructions - Debug Tiles - Added support for turn penalties diff --git a/features/car/names.feature b/features/car/names.feature index 333c7cca6..ca5d300d9 100644 --- a/features/car/names.feature +++ b/features/car/names.feature @@ -3,6 +3,7 @@ Feature: Car - Street names in instructions Background: Given the profile "car" + Given a grid size of 5 meters Scenario: Car - A named street Given the node map diff --git a/features/guidance/dedicated-turn-roads.feature b/features/guidance/dedicated-turn-roads.feature index afbf7cf60..d1cea4144 100644 --- a/features/guidance/dedicated-turn-roads.feature +++ b/features/guidance/dedicated-turn-roads.feature @@ -34,6 +34,36 @@ Feature: Slipways and Dedicated Turn Lanes | a,g | first,second,second | depart,turn right,arrive | | a,1 | first,, | depart,turn slight right,arrive | + Scenario: Turn Instead of Ramp - Max-Speed + Given the node map + """ + e + a-b-----c-d + `h | + || + 1|| + `| + f + | + g + """ + + And the ways + | nodes | highway | name | maxspeed | + | abcd | trunk | first | 70 | + | bhf | trunk_link | | 2 | + | ecfg | primary | second | 50 | + + And the relations + | type | way:from | way:to | node:via | restriction | + | restriction | abcd | ecfg | c | no_right_turn | + + When I route I should get + | waypoints | route | turns | + | a,g | first,second,second | depart,turn right,arrive | + | a,1 | first,, | depart,turn slight right,arrive | + + Scenario: Turn Instead of Ramp Given the node map """ diff --git a/features/guidance/turn-lanes.feature b/features/guidance/turn-lanes.feature index 3596746ca..6591e8d11 100644 --- a/features/guidance/turn-lanes.feature +++ b/features/guidance/turn-lanes.feature @@ -511,7 +511,7 @@ Feature: Turn Lane Guidance g c - a b d e + a b d e f """ @@ -523,8 +523,8 @@ Feature: Turn Lane Guidance | bc | road | left\|left | yes | primary | | de | road | | yes | primary | | fd | cross | | | secondary | - | dc | cross | | | secondary | - | cg | cross | | | secondary | + | dc | cross | | | secondary | + | cg | cross | | | secondary | And the relations | type | way:from | way:to | node:via | restriction | @@ -897,6 +897,29 @@ Feature: Turn Lane Guidance | x,d | road,road | depart,arrive | , | @partition-lanes + Scenario: Partitioned turn, Slight Curve - maxspeed + Given the node map + """ + f e + | | + | | + | c + a - b ' | + g d + """ + + And the ways + | nodes | name | highway | oneway | turn:lanes:forward | maxspeed | + | ab | road | primary | yes | left\|right | 1 | + | bc | cross | primary | yes | | 1 | + | fbg | cross | primary | yes | | 1 | + | dce | cross | primary | yes | | 1 | + + When I route I should get + | waypoints | route | turns | lanes | + | a,g | road,cross,cross | depart,turn right,arrive | ,left:false right:true, | + | a,e | road,cross,cross | depart,turn left,arrive | ,left:true right:false, | + Scenario: Partitioned turn, Slight Curve Given the node map """ diff --git a/include/extractor/guidance/coordinate_extractor.hpp b/include/extractor/guidance/coordinate_extractor.hpp index 348aac436..8ce8ffc9d 100644 --- a/include/extractor/guidance/coordinate_extractor.hpp +++ b/include/extractor/guidance/coordinate_extractor.hpp @@ -40,6 +40,11 @@ class CoordinateExtractor const bool traversed_in_reverse, const NodeID to_node) const; + // wrapper in case of normal forward edges (traversed_in_reverse = false, to_node = + // node_based_graph.GetTarget(turn_edge) + std::vector GetForwardCoordinatesAlongRoad(const NodeID from, + const EdgeID turn_edge) const; + /* When extracting the coordinates, we first extract all coordinates. We don't care about most * of them, though. * diff --git a/include/extractor/guidance/intersection_generator.hpp b/include/extractor/guidance/intersection_generator.hpp index 1ef2d7c9a..96cec3799 100644 --- a/include/extractor/guidance/intersection_generator.hpp +++ b/include/extractor/guidance/intersection_generator.hpp @@ -47,6 +47,9 @@ class IntersectionGenerator NodeID *resulting_from_node, EdgeID *resulting_via_edge) const; + // Allow access to the coordinate extractor for all owners + const CoordinateExtractor &GetCoordinateExtractor() const; + private: const util::NodeBasedDynamicGraph &node_based_graph; const RestrictionMap &restriction_map; diff --git a/include/util/coordinate_calculation.hpp b/include/util/coordinate_calculation.hpp index 8015f2262..ab5fdad2c 100644 --- a/include/util/coordinate_calculation.hpp +++ b/include/util/coordinate_calculation.hpp @@ -5,7 +5,9 @@ #include +#include #include +#include namespace osrm { @@ -30,6 +32,24 @@ double haversineDistance(const Coordinate first_coordinate, const Coordinate sec double greatCircleDistance(const Coordinate first_coordinate, const Coordinate second_coordinate); +// get the length of a full coordinate vector, using one of our basic functions to compute distances +template +double getLength(const std::vector &coordinates, BinaryOperation op) +{ + if (coordinates.empty()) + return 0.; + + double result = 0; + const auto functor = [&result, op](const Coordinate lhs, const Coordinate rhs) { + result += op(lhs, rhs); + return false; + }; + // side-effect find adding up distances + std::adjacent_find(coordinates.begin(), coordinates.end(), functor); + + return result; +} + // Find the closest distance and location between coordinate and the line connecting source and // target: // coordinate diff --git a/src/extractor/guidance/coordinate_extractor.cpp b/src/extractor/guidance/coordinate_extractor.cpp index e4b63fea1..98869da52 100644 --- a/src/extractor/guidance/coordinate_extractor.cpp +++ b/src/extractor/guidance/coordinate_extractor.cpp @@ -298,6 +298,12 @@ CoordinateExtractor::GetCoordinateAlongRoad(const NodeID intersection_node, return TrimCoordinatesToLength(coordinates, LOOKAHEAD_DISTANCE_WITHOUT_LANES).back(); } +std::vector +CoordinateExtractor::GetForwardCoordinatesAlongRoad(const NodeID from, const EdgeID turn_edge) const +{ + return GetCoordinatesAlongRoad(from, turn_edge, false, node_based_graph.GetTarget(turn_edge)); +} + std::vector CoordinateExtractor::GetCoordinatesAlongRoad(const NodeID intersection_node, const EdgeID turn_edge, diff --git a/src/extractor/guidance/intersection_generator.cpp b/src/extractor/guidance/intersection_generator.cpp index 56d9458d5..6b9355198 100644 --- a/src/extractor/guidance/intersection_generator.cpp +++ b/src/extractor/guidance/intersection_generator.cpp @@ -649,6 +649,12 @@ IntersectionGenerator::GetActualNextIntersection(const NodeID starting_node, return result; } +const CoordinateExtractor& +IntersectionGenerator::GetCoordinateExtractor() const +{ + return coordinate_extractor; +} + } // namespace guidance } // namespace extractor } // namespace osrm diff --git a/src/extractor/guidance/sliproad_handler.cpp b/src/extractor/guidance/sliproad_handler.cpp index a5767f479..96bebd3ca 100644 --- a/src/extractor/guidance/sliproad_handler.cpp +++ b/src/extractor/guidance/sliproad_handler.cpp @@ -162,8 +162,12 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection) return intersection; // Threshold check, if the intersection is too far away, don't bother continuing - const auto &next_road_data = node_based_graph.GetEdgeData(next_road.turn.eid); - if (next_road_data.distance > MAX_SLIPROAD_THRESHOLD) + const auto coordinate_extractor = intersection_generator.GetCoordinateExtractor(); + const auto next_road_length = util::coordinate_calculation::getLength( + coordinate_extractor.GetForwardCoordinatesAlongRoad( + node_based_graph.GetTarget(source_edge_id), next_road.turn.eid), + &util::coordinate_calculation::haversineDistance); + if (next_road_length > MAX_SLIPROAD_THRESHOLD) { return intersection; } diff --git a/src/extractor/guidance/turn_discovery.cpp b/src/extractor/guidance/turn_discovery.cpp index 1f779511b..26b9b432e 100644 --- a/src/extractor/guidance/turn_discovery.cpp +++ b/src/extractor/guidance/turn_discovery.cpp @@ -1,5 +1,6 @@ #include "extractor/guidance/turn_discovery.hpp" #include "extractor/guidance/constants.hpp" +#include "util/coordinate_calculation.hpp" namespace osrm { @@ -34,9 +35,14 @@ bool findPreviousIntersection(const NodeID node_v, */ const constexpr double COMBINE_DISTANCE_CUTOFF = 30; + const auto coordinate_extractor = turn_analysis.getGenerator().GetCoordinateExtractor(); + const auto via_edge_length = util::coordinate_calculation::getLength( + coordinate_extractor.GetForwardCoordinatesAlongRoad(node_v, via_edge), + &util::coordinate_calculation::haversineDistance); + // we check if via-edge is too short. In this case the previous turn cannot influence the turn // at via_edge and the intersection at NODE_W - if (node_based_graph.GetEdgeData(via_edge).distance > COMBINE_DISTANCE_CUTOFF) + if (via_edge_length > COMBINE_DISTANCE_CUTOFF) return false; // Node -> Via_Edge -> Intersection[0 == UTURN] -> reverse_of(via_edge) -> Intersection at node