fix coordinate extraction / errors in offset detector

This commit is contained in:
Moritz Kobitzsch 2016-11-29 10:23:13 +01:00
parent 560d8ffec0
commit 5775679f64
4 changed files with 67 additions and 28 deletions

View File

@ -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

View File

@ -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

View File

@ -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())

View File

@ -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<util::Coordinate> 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<util::Coordinate> &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<util::Coordinate> &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<util::Coordinate> &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<std::size_t>(
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<double>