adjusted for comments
This commit is contained in:
parent
9485c97738
commit
e14bc30428
@ -1,5 +1,5 @@
|
|||||||
#include "extractor/guidance/intersection_generator.hpp"
|
|
||||||
#include "extractor/guidance/constants.hpp"
|
#include "extractor/guidance/constants.hpp"
|
||||||
|
#include "extractor/guidance/intersection_generator.hpp"
|
||||||
#include "extractor/guidance/toolkit.hpp"
|
#include "extractor/guidance/toolkit.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -147,9 +147,9 @@ Intersection IntersectionGenerator::getConnectedRoads(const NodeID from_node,
|
|||||||
// after intersections sorting by angles, find the u-turn with (from_node == to_node)
|
// after intersections sorting by angles, find the u-turn with (from_node == to_node)
|
||||||
// that was inserted together with setting uturn_could_be_valid flag
|
// that was inserted together with setting uturn_could_be_valid flag
|
||||||
std::size_t self_u_turn = 0;
|
std::size_t self_u_turn = 0;
|
||||||
while (self_u_turn < intersection.size()
|
while (self_u_turn < intersection.size() &&
|
||||||
&& intersection[self_u_turn].turn.angle < std::numeric_limits<double>::epsilon()
|
intersection[self_u_turn].turn.angle < std::numeric_limits<double>::epsilon() &&
|
||||||
&& from_node != node_based_graph.GetTarget(intersection[self_u_turn].turn.eid))
|
from_node != node_based_graph.GetTarget(intersection[self_u_turn].turn.eid))
|
||||||
{
|
{
|
||||||
++self_u_turn;
|
++self_u_turn;
|
||||||
}
|
}
|
||||||
@ -244,9 +244,41 @@ Intersection IntersectionGenerator::mergeSegregatedRoads(Intersection intersecti
|
|||||||
}();
|
}();
|
||||||
|
|
||||||
// check for merges including the basic u-turn
|
// check for merges including the basic u-turn
|
||||||
// these result in an adjustment of all other angles
|
// these result in an adjustment of all other angles. This is due to how these angles are
|
||||||
|
// perceived. Considering the following example:
|
||||||
|
//
|
||||||
|
// c b
|
||||||
|
// Y
|
||||||
|
// a
|
||||||
|
//
|
||||||
|
// coming from a to b (given a road that splits at the fork into two one-ways), the turn is not
|
||||||
|
// considered as a turn but rather as going straight.
|
||||||
|
// Now if we look at the situation merging:
|
||||||
|
//
|
||||||
|
// a b
|
||||||
|
// \ /
|
||||||
|
// e - + - d
|
||||||
|
// |
|
||||||
|
// c
|
||||||
|
//
|
||||||
|
// With a,b representing the same road, the intersection itself represents a classif for way
|
||||||
|
// intersection so we handle it like
|
||||||
|
//
|
||||||
|
// (a),b
|
||||||
|
// |
|
||||||
|
// e - + - d
|
||||||
|
// |
|
||||||
|
// c
|
||||||
|
//
|
||||||
|
// To be able to consider this adjusted representation down the line, we merge some roads.
|
||||||
|
// If the merge occurs at the u-turn edge, we need to adjust all angles, though, since they are
|
||||||
|
// with respect to the now changed perceived location of a. If we move (a) to the left, we add
|
||||||
|
// the difference to all angles. Otherwise we subtract it.
|
||||||
|
bool merged_first = false;
|
||||||
if (mergable(0, intersection.size() - 1))
|
if (mergable(0, intersection.size() - 1))
|
||||||
{
|
{
|
||||||
|
merged_first = true;
|
||||||
|
// moving `a` to the left
|
||||||
const double correction_factor =
|
const double correction_factor =
|
||||||
(360 - intersection[intersection.size() - 1].turn.angle) / 2;
|
(360 - intersection[intersection.size() - 1].turn.angle) / 2;
|
||||||
for (std::size_t i = 1; i + 1 < intersection.size(); ++i)
|
for (std::size_t i = 1; i + 1 < intersection.size(); ++i)
|
||||||
@ -256,7 +288,21 @@ Intersection IntersectionGenerator::mergeSegregatedRoads(Intersection intersecti
|
|||||||
intersection[0] = merge(intersection.front(), intersection.back());
|
intersection[0] = merge(intersection.front(), intersection.back());
|
||||||
intersection[0].turn.angle = 0;
|
intersection[0].turn.angle = 0;
|
||||||
|
|
||||||
if (is_connected_to_roundabout)
|
intersection.pop_back();
|
||||||
|
}
|
||||||
|
else if (mergable(0, 1))
|
||||||
|
{
|
||||||
|
merged_first = true;
|
||||||
|
// moving `a` to the right
|
||||||
|
const double correction_factor = (intersection[1].turn.angle) / 2;
|
||||||
|
for (std::size_t i = 2; i < intersection.size(); ++i)
|
||||||
|
intersection[i].turn.angle -= correction_factor;
|
||||||
|
intersection[0] = merge(intersection[0], intersection[1]);
|
||||||
|
intersection[0].turn.angle = 0;
|
||||||
|
intersection.erase(intersection.begin() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (merged_first && is_connected_to_roundabout)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We are merging a u-turn against the direction of a roundabout
|
* We are merging a u-turn against the direction of a roundabout
|
||||||
@ -271,18 +317,6 @@ Intersection IntersectionGenerator::mergeSegregatedRoads(Intersection intersecti
|
|||||||
intersection[0].entry_allowed = false;
|
intersection[0].entry_allowed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
intersection.pop_back();
|
|
||||||
}
|
|
||||||
else if (mergable(0, 1))
|
|
||||||
{
|
|
||||||
const double correction_factor = (intersection[1].turn.angle) / 2;
|
|
||||||
for (std::size_t i = 2; i < intersection.size(); ++i)
|
|
||||||
intersection[i].turn.angle -= correction_factor;
|
|
||||||
intersection[0] = merge(intersection[0], intersection[1]);
|
|
||||||
intersection[0].turn.angle = 0;
|
|
||||||
intersection.erase(intersection.begin() + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// a merge including the first u-turn requres an adjustment of the turn angles
|
// a merge including the first u-turn requres an adjustment of the turn angles
|
||||||
// therefore these are handled prior to this step
|
// therefore these are handled prior to this step
|
||||||
for (std::size_t index = 2; index < intersection.size(); ++index)
|
for (std::size_t index = 2; index < intersection.size(); ++index)
|
||||||
|
@ -116,6 +116,13 @@ LaneDataVector laneDataFromDescription(const TurnLaneDescription &turn_lane_desc
|
|||||||
// which is invalid
|
// which is invalid
|
||||||
for (std::size_t index = 1; index < lane_data.size(); ++index)
|
for (std::size_t index = 1; index < lane_data.size(); ++index)
|
||||||
{
|
{
|
||||||
|
// u-turn located somewhere in the middle
|
||||||
|
// Right now we can only handle u-turns at the sides. If we find a u-turn somewhere in
|
||||||
|
// the middle of the tags, we abort the handling right here.
|
||||||
|
if (index + 1 < lane_data.size() &&
|
||||||
|
((lane_data[index].tag & TurnLaneType::uturn) != TurnLaneType::empty))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (lane_data[index - 1].to > lane_data[index].from)
|
if (lane_data[index - 1].to > lane_data[index].from)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -117,12 +117,18 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
|
|||||||
if (has_merge_lane || has_non_usable_u_turn)
|
if (has_merge_lane || has_non_usable_u_turn)
|
||||||
return intersection;
|
return intersection;
|
||||||
|
|
||||||
if (!lane_data.empty() && canMatchTrivially(intersection, lane_data) &&
|
// check if a u-turn is allowed (for some reason) and is missing from the list of tags (u-turn
|
||||||
|
// is often allowed from the `left` lane without an additional indication dedicated to u-turns).
|
||||||
|
const bool is_missing_valid_u_turn =
|
||||||
lane_data.size() !=
|
lane_data.size() !=
|
||||||
static_cast<std::size_t>((
|
static_cast<std::size_t>((
|
||||||
!hasTag(TurnLaneType::uturn, lane_data) && intersection[0].entry_allowed ? 1 : 0)) +
|
!hasTag(TurnLaneType::uturn, lane_data) && intersection[0].entry_allowed ? 1 : 0)) +
|
||||||
possible_entries &&
|
possible_entries &&
|
||||||
intersection[0].entry_allowed && !hasTag(TurnLaneType::none, lane_data))
|
intersection[0].entry_allowed;
|
||||||
|
|
||||||
|
// FIXME the lane to add depends on the side of driving/u-turn rules in the country
|
||||||
|
if (!lane_data.empty() && canMatchTrivially(intersection, lane_data) &&
|
||||||
|
!is_missing_valid_u_turn && !hasTag(TurnLaneType::none, lane_data))
|
||||||
lane_data.push_back({TurnLaneType::uturn, lane_data.back().to, lane_data.back().to});
|
lane_data.push_back({TurnLaneType::uturn, lane_data.back().to, lane_data.back().to});
|
||||||
|
|
||||||
bool is_simple = isSimpleIntersection(lane_data, intersection);
|
bool is_simple = isSimpleIntersection(lane_data, intersection);
|
||||||
@ -335,24 +341,34 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
|
|||||||
bool all_simple = true;
|
bool all_simple = true;
|
||||||
bool has_none = false;
|
bool has_none = false;
|
||||||
std::unordered_set<std::size_t> matched_indices;
|
std::unordered_set<std::size_t> matched_indices;
|
||||||
for (const auto &data : lane_data)
|
for (std::size_t data_index = 0; data_index < lane_data.size(); ++data_index)
|
||||||
{
|
{
|
||||||
|
const auto &data = lane_data[data_index];
|
||||||
if (data.tag == TurnLaneType::none)
|
if (data.tag == TurnLaneType::none)
|
||||||
{
|
{
|
||||||
has_none = true;
|
has_none = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// u-turn tags are at the outside of the lane-tags and require special handling, since
|
||||||
|
// locating their best match requires knowledge on the neighboring tag. (see documentation
|
||||||
|
// on findBestMatch/findBestMatchForReverse
|
||||||
const auto best_match = [&]() {
|
const auto best_match = [&]() {
|
||||||
|
// normal tag or u-turn as only choice (no other tag present)
|
||||||
if (data.tag != TurnLaneType::uturn || lane_data.size() == 1)
|
if (data.tag != TurnLaneType::uturn || lane_data.size() == 1)
|
||||||
return findBestMatch(data.tag, intersection);
|
return findBestMatch(data.tag, intersection);
|
||||||
|
|
||||||
// lane_data.size() > 1
|
BOOST_ASSERT(data.tag == TurnLaneType::uturn);
|
||||||
if (lane_data.back().tag == TurnLaneType::uturn)
|
// u-turn at the very left, leftmost turn at data_index - 1
|
||||||
return findBestMatchForReverse(lane_data[lane_data.size() - 2].tag, intersection);
|
if (data_index + 1 == lane_data.size())
|
||||||
|
return findBestMatchForReverse(lane_data[data_index - 1].tag, intersection);
|
||||||
|
|
||||||
BOOST_ASSERT(lane_data.front().tag == TurnLaneType::uturn);
|
// u-turn to the right (left-handed driving) -> rightmost turn to the left (data_index +
|
||||||
return findBestMatchForReverse(lane_data[1].tag, intersection);
|
// 1)
|
||||||
|
if (data_index == 0)
|
||||||
|
return findBestMatchForReverse(lane_data[data_index + 1].tag, intersection);
|
||||||
|
|
||||||
|
return intersection.begin();
|
||||||
}();
|
}();
|
||||||
std::size_t match_index = std::distance(intersection.begin(), best_match);
|
std::size_t match_index = std::distance(intersection.begin(), best_match);
|
||||||
all_simple &= (matched_indices.count(match_index) == 0);
|
all_simple &= (matched_indices.count(match_index) == 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user