fix errors in coordinate extractor due to duplicated coordinates
fix offset calculation in curve detection
This commit is contained in:
@@ -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)) &&
|
||||
|
||||
Reference in New Issue
Block a user