diff --git a/features/guidance/dedicated-turn-roads.feature b/features/guidance/dedicated-turn-roads.feature index 980ba5a82..8bb11bfad 100644 --- a/features/guidance/dedicated-turn-roads.feature +++ b/features/guidance/dedicated-turn-roads.feature @@ -32,9 +32,9 @@ Feature: Slipways and Dedicated Turn Lanes | restriction | abc | cfg | 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 | + | waypoints | route | turns | + | a,g | first,second,second | depart,turn right,arrive | + | a,1 | first,, | depart,turn right,arrive | Scenario: Turn Instead of Ramp - Max-Speed Given the node map @@ -63,9 +63,9 @@ Feature: Slipways and Dedicated Turn Lanes | restriction | abc | cfg | 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 | + | waypoints | route | turns | + | a,g | first,second,second | depart,turn right,arrive | + | a,1 | first,, | depart,turn right,arrive | Scenario: Turn Instead of Ramp @@ -94,8 +94,8 @@ Feature: Slipways and Dedicated Turn Lanes | efg | primary | second | When I route I should get - | waypoints | route | turns | - | a,g | first,,second,second | depart,off ramp slight right,turn straight,arrive | + | waypoints | route | turns | + | a,g | first,,second,second | depart,off ramp right,turn straight,arrive | Scenario: Turn Instead of Ramp Given the node map @@ -119,8 +119,8 @@ Feature: Slipways and Dedicated Turn Lanes | efg | primary | second | When I route I should get - | waypoints | route | turns | - | a,g | first,,second,second | depart,off ramp slight right,turn straight,arrive | + | waypoints | route | turns | + | a,g | first,,second,second | depart,off ramp right,turn straight,arrive | Scenario: Inner city expressway with on road Given the node map diff --git a/features/guidance/turn-angles.feature b/features/guidance/turn-angles.feature index cdb9ce76e..7d6f65a3d 100644 --- a/features/guidance/turn-angles.feature +++ b/features/guidance/turn-angles.feature @@ -201,14 +201,14 @@ Feature: Simple Turns | ef | residential | road | 2 | yes | When I route I should get - | waypoints | route | turns | - | a,c | road,road | depart,arrive | - | c,a | road,road | depart,arrive | - | g,a | turn,road,road | depart,turn left,arrive | - | g,c | turn,road,road | depart,turn right,arrive | - | g,f | turn,road | depart,arrive | - | c,f | road,road,road | depart,continue right,arrive | - | a,f | road,road,road | depart,continue uturn,arrive | + | waypoints | route | turns | locations | + | a,c | road,road | depart,arrive | a,c | + | c,a | road,road | depart,arrive | c,a | + | g,a | turn,road,road | depart,turn left,arrive | g,b,a | + | g,c | turn,road,road | depart,turn right,arrive | g,b,c | + | g,f | turn,road,road | depart,turn left,arrive | g,e,f | + | c,f | road,road,road | depart,continue right,arrive | c,b,f | + | a,f | road,road,road | depart,continue uturn,arrive | a,b,f | # http://www.openstreetmap.org/#map=19/52.48753/13.52838 Scenario: Traffic Circle @@ -773,9 +773,9 @@ Feature: Simple Turns When I route I should get | waypoints | route | turns | - | a,j | Siemens,Siemens,Siemens | depart,continue straight,arrive | + | a,j | Siemens,Siemens,Siemens | depart,continue slight right,arrive | | a,g | Siemens,Erna,Erna | depart,new name slight left,arrive | - | g,j | Erna,Siemens,Siemens | depart,turn sharp left,arrive | + | g,j | Erna,Siemens,Siemens | depart,turn left,arrive | | g,a | Erna,Siemens,Siemens | depart,new name slight right,arrive | #http://www.openstreetmap.org/#map=19/52.51303/13.32170 diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index 4c520c784..c62ffe469 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -212,7 +212,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti return lane_description; }; - // convert the lane description into an ID and, if necessary, remembr the description in the + // convert the lane description into an ID and, if necessary, remember the description in the // description_map const auto requestId = [&](const std::string &lane_string) { if (lane_string.empty()) diff --git a/src/extractor/guidance/coordinate_extractor.cpp b/src/extractor/guidance/coordinate_extractor.cpp index 101a33623..ed89dafde 100644 --- a/src/extractor/guidance/coordinate_extractor.cpp +++ b/src/extractor/guidance/coordinate_extractor.cpp @@ -38,6 +38,24 @@ const constexpr double FAR_LOOKAHEAD_DISTANCE = 20.0; // directions or a lane count specified, we use 2. Overestimating only makes our calculations safer, // so we are fine for 1-lane ways. larger than 2 lanes should usually be specified in the data. const constexpr std::uint16_t ASSUMED_LANE_COUNT = 2; + +// When looking at lane offsets, motorway exits often are modelled not at a 90 degree angle but at +// some slight turn. To correctly detect these offsets, we need to allow for a bit more than just +// the lane width as an offset +double GetOffsetCorrectionFactor(const RoadClassification &road_classification) +{ + if (road_classification.IsMotorwayClass() || road_classification.IsRampClass()) + return 2.5; + switch (road_classification.GetClass()) + { + case RoadPriorityClass::TRUNK: + return 2.0; + case RoadPriorityClass::PRIMARY: + return 1.5; + default: + return 1.0; + }; +}; } CoordinateExtractor::CoordinateExtractor( @@ -77,7 +95,8 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate( std::vector coordinates) const { const auto considered_lanes = - (intersection_lanes == 0) ? ASSUMED_LANE_COUNT : intersection_lanes; + GetOffsetCorrectionFactor(node_based_graph.GetEdgeData(turn_edge).road_classification) * + ((intersection_lanes == 0) ? ASSUMED_LANE_COUNT : intersection_lanes); /* if we are looking at a straight line, we don't care where exactly the coordinate * is. Simply return the final coordinate. Turn angles/turn vectors are the same no matter which @@ -104,7 +123,7 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate( const auto &turn_edge_data = node_based_graph.GetEdgeData(turn_edge); // roundabouts, check early to avoid other costly checks - if (turn_edge_data.roundabout || turn_edge_data.circular ) + if (turn_edge_data.roundabout || turn_edge_data.circular) return TrimCoordinatesToLength(std::move(coordinates), distance_to_skip_over_due_to_coordinate_inaccuracies) .back(); @@ -654,7 +673,7 @@ bool CoordinateExtractor::IsDirectOffset(const std::vector &co // a road usually is connected to the middle of the lanes. So the lane-offset has to // consider half to road const auto lane_offset = 0.5 * considered_lanes * ASSUMED_LANE_WIDTH; - return std::abs(width - lane_offset) < 0.5 * ASSUMED_LANE_WIDTH; + return width - lane_offset < ASSUMED_LANE_WIDTH; // less or going over at most a small bit }; // Check whether the very first coordinate is simply an offset. This is the case if the initial @@ -665,8 +684,10 @@ bool CoordinateExtractor::IsDirectOffset(const std::vector &co if (offset_index + 1 >= coordinates.size()) return false; + BOOST_ASSERT(segment_distances.size() == coordinates.size()); // the straight part has to be around the lane distance - if (!IsCloseToLaneDistance(segment_distances[offset_index])) + if (!IsCloseToLaneDistance(std::accumulate( + segment_distances.begin(), segment_distances.begin() + offset_index + 1, 0.))) return false; // the segment itself cannot be short @@ -674,14 +695,32 @@ bool CoordinateExtractor::IsDirectOffset(const std::vector &co return false; // if the remaining segment is short, we don't consider it an offset - if ((segment_length - std::max(straight_distance, segment_distances[1])) > 0.1 * segment_length) + if ((segment_length - std::max(straight_distance, segment_distances[1])) < 0.1 * segment_length) return false; + // when we compare too long a distance, we run into problems due to turning roads. Here we + // compute which index to consider when checking if the remaining road remains straight + const auto segment_offset_past_thirty_meters = + std::find_if(segment_distances.begin() + offset_index, + segment_distances.end(), + [accumulated_distance = 0.](const auto value) mutable { + accumulated_distance += value; + return value >= 30; + }); + + // transform the found offset in the segment distances into the appropriate part in the + // coordinates array + const auto deviation_compare_end = + coordinates.begin() + + std::min( + coordinates.size(), // don't go over + std::distance(segment_distances.begin(), segment_offset_past_thirty_meters) + 1); + // finally, we cannot be far off from a straight line for the remaining coordinates return 0.5 * ASSUMED_LANE_WIDTH > GetMaxDeviation(coordinates.begin() + offset_index, - coordinates.end(), + deviation_compare_end, coordinates[offset_index], - coordinates.back()); + *(deviation_compare_end - 1)); } std::vector