fix errors in coordinate extractor due to duplicated coordinates
fix offset calculation in curve detection
This commit is contained in:
parent
17a18b5c7c
commit
a28a20a1ba
@ -271,11 +271,11 @@ Feature: Slipways and Dedicated Turn Lanes
|
||||
| jcghf | primary | Brauerstrasse | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,i | Ebertstrasse,Ebertstrasse | depart,arrive |
|
||||
| a,l | Ebertstrasse,Ebertstrasse | depart,arrive |
|
||||
| a,f | Ebertstrasse,Brauerstrasse,Brauerstrasse | depart,turn right,arrive |
|
||||
| a,1 | Ebertstrasse,, | depart,turn right,arrive |
|
||||
| waypoints | route | turns |
|
||||
| a,i | Ebertstrasse,Ebertstrasse | depart,arrive |
|
||||
| a,l | Ebertstrasse,Ebertstrasse | depart,arrive |
|
||||
| a,f | Ebertstrasse,Brauerstrasse,Brauerstrasse | depart,turn right,arrive |
|
||||
| a,1 | Ebertstrasse,, | depart,turn slight right,arrive |
|
||||
|
||||
#2839
|
||||
Scenario: Self-Loop
|
||||
|
@ -317,30 +317,30 @@ Feature: Simple Turns
|
||||
Scenario: Curved Turn At Cross
|
||||
Given the node map
|
||||
"""
|
||||
h
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
| . b - - - - - - - - - - - - - - - - - - a
|
||||
| .
|
||||
| .
|
||||
| c
|
||||
|
|
||||
|
|
||||
|
|
||||
d
|
||||
|
|
||||
|
|
||||
|
|
||||
e |
|
||||
. |
|
||||
. |
|
||||
g - - - - - - - - - - - - - f |
|
||||
|
|
||||
|
|
||||
|
|
||||
i
|
||||
h
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
| . b - - - - - - - - - - - - - - - - - - - - - - - a
|
||||
| .
|
||||
| .
|
||||
| c
|
||||
|
|
||||
|
|
||||
|
|
||||
d
|
||||
|
|
||||
|
|
||||
|
|
||||
e |
|
||||
. |
|
||||
. |
|
||||
g - - - - - - - - - - - - - - - - - - f |
|
||||
|
|
||||
|
|
||||
|
|
||||
i
|
||||
"""
|
||||
|
||||
And the ways
|
||||
@ -443,9 +443,9 @@ Feature: Simple Turns
|
||||
| ef | residential | road | 2 | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | locations |
|
||||
| g,f | turn,road,road | depart,turn left,arrive | g,e,f |
|
||||
| c,f | road,road,road | depart,continue right,arrive | c,b,f |
|
||||
| waypoints | route | turns | locations | # |
|
||||
| g,f | turn,road | depart,arrive | g,f | #could offer an additional turn at `e` if you don't detect the turn in between as curve |
|
||||
| c,f | road,road,road | depart,continue right,arrive | c,b,f | |
|
||||
|
||||
#http://www.openstreetmap.org/search?query=52.479264%2013.295617#map=19/52.47926/13.29562
|
||||
Scenario: Splitting Roads with curved split
|
||||
@ -627,12 +627,14 @@ Feature: Simple Turns
|
||||
| 1,h | ,allee,allee | depart,turn left,arrive |
|
||||
| 2,h | ,allee,allee | depart,turn left,arrive |
|
||||
|
||||
|
||||
#http://www.openstreetmap.org/#map=18/52.56251/13.32650
|
||||
@todo
|
||||
Scenario: Curved Turn on Separated Directions
|
||||
Given the node map
|
||||
"""
|
||||
e d
|
||||
f - - - - - - - - - - - - - - - c - - - - - - - - - - - j
|
||||
f c - - - - - - - - - - - j
|
||||
| l ' |
|
||||
| ' |
|
||||
| ' |
|
||||
@ -680,6 +682,58 @@ Feature: Simple Turns
|
||||
| j,o | Kapweg,Kapweg,Kapweg | depart,continue uturn,arrive |
|
||||
| a,i | Kurt,Kurt,Kurt | depart,continue uturn,arrive |
|
||||
|
||||
#http://www.openstreetmap.org/#map=18/52.56251/13.32650
|
||||
Scenario: Curved Turn on Separated Directions
|
||||
Given the node map
|
||||
"""
|
||||
e d
|
||||
f c - - - - - - - - - - - j
|
||||
| l ' |
|
||||
| ' |
|
||||
| ' |
|
||||
| ' |
|
||||
| ' |
|
||||
| n |
|
||||
| |
|
||||
| ' |
|
||||
| |
|
||||
| ' |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
|' |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
g |
|
||||
h - - - - - - - - - - - - - - - b - - - - - - - - - - - o
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
i a
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | name | oneway | lanes | highway |
|
||||
| jc | Kapweg | yes | 3 | primary |
|
||||
| clngh | Kapweg | yes | | primary_link |
|
||||
| hbo | Kapweg | yes | 2 | primary |
|
||||
| efh | Kurt | yes | 4 | secondary |
|
||||
| hi | Kurt | yes | 3 | primary |
|
||||
| ab | Kurt | yes | 4 | primary |
|
||||
| cd | Kurt | yes | 3 | secondary |
|
||||
| bc | Kurt | yes | 2 | primary |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| j,i | Kapweg,Kurt,Kurt | depart,turn left,arrive |
|
||||
| j,o | Kapweg,Kapweg,Kapweg | depart,continue uturn,arrive |
|
||||
| a,i | Kurt,Kurt,Kurt | depart,continue uturn,arrive |
|
||||
|
||||
#http://www.openstreetmap.org/#map=19/52.53731/13.36033
|
||||
Scenario: Splitting Road to Left
|
||||
Given the node map
|
||||
@ -1112,8 +1166,9 @@ Feature: Simple Turns
|
||||
"""
|
||||
|
||||
And the ways
|
||||
| nodes | name | highway | lanes |
|
||||
| abcdefghijklmnopc | circled | residential | 1 |
|
||||
| nodes | name | highway | lanes | oneway |
|
||||
| abc | circled | residential | 1 | no |
|
||||
| cdefghijklmnopc | circled | residential | 1 | yes |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | bearings | route | turns |
|
||||
@ -1168,3 +1223,40 @@ Feature: Simple Turns
|
||||
When I route I should get
|
||||
| waypoints | route |
|
||||
| a,e | ab,bcde,bcde |
|
||||
|
||||
|
||||
@3401
|
||||
Scenario: Curve With Duplicated Coordinates
|
||||
Given the node locations
|
||||
| node | lat | lon | # |
|
||||
| a | 0.9999280745650984 | 1.0 | |
|
||||
| b | 0.9999280745650984 | 1.0000179813587253 | |
|
||||
| c | 0.9999280745650984 | 1.0000359627174509 | |
|
||||
| d | 0.9999460559238238 | 1.0000674300952204 | |
|
||||
| e | 0.9999640372825492 | 1.0000809161142643 | |
|
||||
| f | 0.9999820186412746 | 1.0000854114539457 | |
|
||||
| g | 1.0 | 1.0000854114539457 | |
|
||||
| h | 1.0 | 1.0000854114539457 | #same as g |
|
||||
| z | 0.9999100932063729 | 1.0000179813587253 | |
|
||||
# g
|
||||
# |
|
||||
# f
|
||||
# '
|
||||
# e
|
||||
# '
|
||||
# d
|
||||
# '
|
||||
#a - b - c
|
||||
# |
|
||||
# z
|
||||
|
||||
And the ways
|
||||
| nodes | oneway | lanes | # |
|
||||
| ab | yes | 1 | |
|
||||
| zb | yes | 1 | |
|
||||
| bcdefgh | yes | 1 | #intentional duplication |
|
||||
|
||||
# we don't care for turn instructions, this is a coordinate extraction bug check
|
||||
When I route I should get
|
||||
| waypoints | route | intersections |
|
||||
| a,g | ab,bcdefgh,bcdefgh | true:90;true:45 false:180 false:270;true:180 |
|
||||
|
@ -125,13 +125,13 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
|
||||
|
||||
// due to repeated coordinates / smaller offset errors we skip over the very first parts of the
|
||||
// coordinate set to add a small level of fault tolerance
|
||||
const constexpr double distance_to_skip_over_due_to_coordinate_inaccuracies = 2;
|
||||
const constexpr double skipping_inaccuracies_distance = 2;
|
||||
|
||||
// fallback, mostly necessary for dead ends
|
||||
if (intersection_node == to_node)
|
||||
{
|
||||
const auto result = ExtractCoordinateAtLength(
|
||||
distance_to_skip_over_due_to_coordinate_inaccuracies, coordinates);
|
||||
skipping_inaccuracies_distance, coordinates);
|
||||
BOOST_ASSERT(is_valid_result(coordinates.back()));
|
||||
return result;
|
||||
}
|
||||
@ -147,7 +147,7 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
|
||||
if (turn_edge_data.roundabout || turn_edge_data.circular)
|
||||
{
|
||||
const auto result = ExtractCoordinateAtLength(
|
||||
distance_to_skip_over_due_to_coordinate_inaccuracies, coordinates);
|
||||
skipping_inaccuracies_distance, coordinates);
|
||||
BOOST_ASSERT(is_valid_result(result));
|
||||
return result;
|
||||
}
|
||||
@ -235,7 +235,7 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
|
||||
|
||||
// if we are now left with two, well than we don't have to worry, or the segment is very small
|
||||
if (coordinates.size() == 2 ||
|
||||
total_distance <= distance_to_skip_over_due_to_coordinate_inaccuracies)
|
||||
total_distance <= skipping_inaccuracies_distance)
|
||||
{
|
||||
BOOST_ASSERT(is_valid_result(coordinates.back()));
|
||||
return coordinates.back();
|
||||
@ -253,7 +253,7 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
|
||||
if (coordinates.front() == coordinates.back())
|
||||
{
|
||||
const auto result = ExtractCoordinateAtLength(
|
||||
distance_to_skip_over_due_to_coordinate_inaccuracies, coordinates);
|
||||
skipping_inaccuracies_distance, coordinates);
|
||||
BOOST_ASSERT(is_valid_result(result));
|
||||
return result;
|
||||
}
|
||||
@ -337,38 +337,9 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
|
||||
return result;
|
||||
}
|
||||
|
||||
if (IsCurve(coordinates,
|
||||
segment_distances,
|
||||
total_distance,
|
||||
considered_lanes * 0.5 * ASSUMED_LANE_WIDTH,
|
||||
turn_edge_data))
|
||||
{
|
||||
if (total_distance <= distance_to_skip_over_due_to_coordinate_inaccuracies)
|
||||
return coordinates.back();
|
||||
/*
|
||||
* In curves we now have to distinguish between larger curves and tiny curves modelling the
|
||||
* actual turn in the beginnig.
|
||||
*
|
||||
* We distinguish between turns that simply model the initial way of getting onto the
|
||||
* destination lanes and the ones that performa a larger turn.
|
||||
*/
|
||||
const double offset =
|
||||
std::min(0.5 * considered_lanes * ASSUMED_LANE_WIDTH, 0.2 * segment_distances.back());
|
||||
coordinates = TrimCoordinatesToLength(std::move(coordinates), offset, segment_distances);
|
||||
BOOST_ASSERT(coordinates.size() >= 2);
|
||||
segment_distances.resize(coordinates.size());
|
||||
segment_distances.back() = util::coordinate_calculation::haversineDistance(
|
||||
*(coordinates.end() - 2), coordinates.back());
|
||||
const auto vector_head = coordinates.back();
|
||||
coordinates =
|
||||
TrimCoordinatesToLength(std::move(coordinates), 0.5 * offset, segment_distances);
|
||||
BOOST_ASSERT(coordinates.size() >= 2);
|
||||
const auto result =
|
||||
GetCorrectedCoordinate(turn_coordinate, coordinates.back(), vector_head);
|
||||
BOOST_ASSERT(is_valid_result(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
// We check offsets before curves to avoid detecting lane offsets due to large roads as curves
|
||||
// (think major highway here). If the road is wide, it can have quite a few coordinates in the
|
||||
// beginning.
|
||||
if (IsDirectOffset(coordinates,
|
||||
straight_index,
|
||||
straight_distance,
|
||||
@ -387,6 +358,40 @@ util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate(
|
||||
return result;
|
||||
}
|
||||
|
||||
if (IsCurve(coordinates,
|
||||
segment_distances,
|
||||
total_distance,
|
||||
considered_lanes * 0.5 * ASSUMED_LANE_WIDTH,
|
||||
turn_edge_data))
|
||||
{
|
||||
if (total_distance <= skipping_inaccuracies_distance)
|
||||
return coordinates.back();
|
||||
/*
|
||||
* In curves we now have to distinguish between larger curves and tiny curves modelling the
|
||||
* actual turn in the beginnig.
|
||||
*
|
||||
* We distinguish between turns that simply model the initial way of getting onto the
|
||||
* destination lanes and the ones that performa a larger turn.
|
||||
*/
|
||||
coordinates =
|
||||
TrimCoordinatesToLength(std::move(coordinates),
|
||||
2 * skipping_inaccuracies_distance,
|
||||
segment_distances);
|
||||
BOOST_ASSERT(coordinates.size() >= 2);
|
||||
segment_distances.resize(coordinates.size());
|
||||
segment_distances.back() = util::coordinate_calculation::haversineDistance(
|
||||
*(coordinates.end() - 2), coordinates.back());
|
||||
const auto vector_head = coordinates.back();
|
||||
coordinates = TrimCoordinatesToLength(std::move(coordinates),
|
||||
skipping_inaccuracies_distance,
|
||||
segment_distances);
|
||||
BOOST_ASSERT(coordinates.size() >= 2);
|
||||
const auto result =
|
||||
GetCorrectedCoordinate(turn_coordinate, coordinates.back(), vector_head);
|
||||
BOOST_ASSERT(is_valid_result(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
{
|
||||
// skip over the first coordinates, in specific the assumed lane count. We add a small
|
||||
// safety factor, to not overshoot on the regression
|
||||
@ -600,6 +605,9 @@ CoordinateExtractor::GetCoordinatesAlongRoad(const NodeID intersection_node,
|
||||
std::back_inserter(result),
|
||||
compressedGeometryToCoordinate);
|
||||
}
|
||||
// filter duplicated coordinates
|
||||
auto end = std::unique(result.begin(), result.end());
|
||||
result.erase(end, result.end());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -693,12 +701,12 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
|
||||
std::tie(has_up_down_deviation, maximum_deviation_index, maximum_deviation) =
|
||||
[&coordinates, get_deviation]() -> std::tuple<bool, std::size_t, double> {
|
||||
const auto increasing = [&](const util::Coordinate lhs, const util::Coordinate rhs) {
|
||||
return get_deviation(coordinates.front(), coordinates.back(), lhs) <=
|
||||
return get_deviation(coordinates.front(), coordinates.back(), lhs) <
|
||||
get_deviation(coordinates.front(), coordinates.back(), rhs);
|
||||
};
|
||||
|
||||
const auto decreasing = [&](const util::Coordinate lhs, const util::Coordinate rhs) {
|
||||
return get_deviation(coordinates.front(), coordinates.back(), lhs) >=
|
||||
return get_deviation(coordinates.front(), coordinates.back(), lhs) >
|
||||
get_deviation(coordinates.front(), coordinates.back(), rhs);
|
||||
};
|
||||
|
||||
@ -709,16 +717,17 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
|
||||
return std::make_tuple(
|
||||
true, 1, get_deviation(coordinates.front(), coordinates.back(), coordinates[1]));
|
||||
|
||||
const auto maximum_itr =
|
||||
const auto one_past_maximum_iter =
|
||||
std::is_sorted_until(coordinates.begin() + 1, coordinates.end(), increasing);
|
||||
|
||||
if (maximum_itr == coordinates.end())
|
||||
if (one_past_maximum_iter == coordinates.end())
|
||||
return std::make_tuple(true, coordinates.size() - 1, 0.);
|
||||
else if (std::is_sorted(maximum_itr, coordinates.end(), decreasing))
|
||||
return std::make_tuple(
|
||||
true,
|
||||
std::distance(coordinates.begin(), maximum_itr),
|
||||
get_deviation(coordinates.front(), coordinates.back(), *maximum_itr));
|
||||
else if (std::is_sorted(one_past_maximum_iter, coordinates.end(), decreasing))
|
||||
return std::make_tuple(true,
|
||||
std::distance(coordinates.begin(), one_past_maximum_iter) - 1,
|
||||
get_deviation(coordinates.front(),
|
||||
coordinates.back(),
|
||||
*(one_past_maximum_iter - 1)));
|
||||
else
|
||||
return std::make_tuple(false, 0, 0.);
|
||||
}();
|
||||
@ -731,7 +740,7 @@ bool CoordinateExtractor::IsCurve(const std::vector<util::Coordinate> &coordinat
|
||||
// if the maximum deviation is at a quarter of the total curve, we are probably looking at a
|
||||
// normal turn
|
||||
const auto distance_to_max_deviation = std::accumulate(
|
||||
segment_distances.begin(), segment_distances.begin() + maximum_deviation_index, 0.);
|
||||
segment_distances.begin(), segment_distances.begin() + maximum_deviation_index + 1, 0.);
|
||||
|
||||
if ((distance_to_max_deviation <= 0.35 * segment_length ||
|
||||
maximum_deviation < std::max(0.3 * considered_lane_width, 0.5 * ASSUMED_LANE_WIDTH)) &&
|
||||
|
Loading…
Reference in New Issue
Block a user