refactor of post-processing
- moves collapse into a dedicated set of functions / files - make collapse scenarios distinct (slight performance cost) - reduce verbosity for short name segments (now actually working, was supposed to do so before)
This commit is contained in:
committed by
Patrick Niklaus
parent
8d83c3adbb
commit
6c3390f14d
@@ -146,8 +146,11 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t
|
||||
// name has not changed, suppress a turn here or indicate mode change
|
||||
else
|
||||
{
|
||||
return {in_mode == out_mode ? TurnType::Suppressed : TurnType::Notification,
|
||||
getTurnDirection(road.angle)};
|
||||
if (in_mode != out_mode)
|
||||
return {TurnType::Notification, getTurnDirection(road.angle)};
|
||||
else
|
||||
return {num_roads == 2 ? TurnType::NoTurn : TurnType::Suppressed,
|
||||
getTurnDirection(road.angle)};
|
||||
}
|
||||
}
|
||||
BOOST_ASSERT(type == TurnType::Continue);
|
||||
|
||||
@@ -120,12 +120,39 @@ IntersectionShapeData IntersectionNormalizer::MergeRoads(const IntersectionShape
|
||||
IntersectionShapeData
|
||||
IntersectionNormalizer::MergeRoads(const IntersectionNormalizationOperation direction,
|
||||
const IntersectionShapeData &lhs,
|
||||
const IntersectionShapeData &rhs) const
|
||||
const IntersectionShapeData &rhs,
|
||||
const double opposite_bearing) const
|
||||
{
|
||||
// In some intersections, turning roads can introduce artificial turns if we merge here.
|
||||
// Consider a scenario like:
|
||||
//
|
||||
// a . g - f
|
||||
// | .
|
||||
// | .
|
||||
// |.
|
||||
// d-b--------e
|
||||
// |
|
||||
// c
|
||||
//
|
||||
// Merging `bgf` and `be` would introduce an angle, even though d-b-e is perfectly straight
|
||||
// We don't change the angle, if such an opposite road exists
|
||||
if (direction.merged_eid == lhs.eid)
|
||||
return MergeRoads(rhs, lhs);
|
||||
{
|
||||
// change the angle only if the opposite direction is not nearly straight
|
||||
if (angularDeviation(opposite_bearing, rhs.bearing) >
|
||||
(STRAIGHT_ANGLE - MAXIMAL_ALLOWED_NO_TURN_DEVIATION))
|
||||
return rhs;
|
||||
else
|
||||
return MergeRoads(rhs, lhs);
|
||||
}
|
||||
else
|
||||
return MergeRoads(lhs, rhs);
|
||||
{
|
||||
if (angularDeviation(opposite_bearing, lhs.bearing) >
|
||||
(STRAIGHT_ANGLE - MAXIMAL_ALLOWED_NO_TURN_DEVIATION))
|
||||
return lhs;
|
||||
else
|
||||
return MergeRoads(lhs, rhs);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -163,7 +190,8 @@ IntersectionNormalizer::MergeSegregatedRoads(const NodeID intersection_node,
|
||||
// end up in the end. We only store what we have merged into other edges.
|
||||
std::vector<IntersectionNormalizationOperation> merging_map;
|
||||
const auto merge = [this, &merging_map](const IntersectionShapeData &first,
|
||||
const IntersectionShapeData &second) {
|
||||
const IntersectionShapeData &second,
|
||||
const double opposite_bearing) {
|
||||
|
||||
const auto direction = DetermineMergeDirection(first, second);
|
||||
BOOST_ASSERT(
|
||||
@@ -171,13 +199,27 @@ IntersectionNormalizer::MergeSegregatedRoads(const NodeID intersection_node,
|
||||
return pair.merged_eid == direction.merged_eid;
|
||||
}) == merging_map.end());
|
||||
merging_map.push_back(direction);
|
||||
return MergeRoads(direction, first, second);
|
||||
return MergeRoads(direction, first, second, opposite_bearing);
|
||||
};
|
||||
|
||||
if (intersection.size() <= 1)
|
||||
return {intersection, merging_map};
|
||||
|
||||
const auto intersection_copy = intersection;
|
||||
const auto opposite_bearing = [this, intersection_copy](const IntersectionShapeData &lhs,
|
||||
const IntersectionShapeData &rhs) {
|
||||
if (node_based_graph.GetEdgeData(lhs.eid).reversed)
|
||||
{
|
||||
return intersection_copy.FindClosestBearing(util::bearing::reverse(rhs.bearing))
|
||||
->bearing;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(node_based_graph.GetEdgeData(rhs.eid).reversed);
|
||||
return intersection_copy.FindClosestBearing(util::bearing::reverse(lhs.bearing))
|
||||
->bearing;
|
||||
}
|
||||
};
|
||||
// check for merges including the basic u-turn
|
||||
// these result in an adjustment of all other angles. This is due to how these angles are
|
||||
// perceived. Considering the following example:
|
||||
@@ -213,14 +255,16 @@ IntersectionNormalizer::MergeSegregatedRoads(const NodeID intersection_node,
|
||||
if (CanMerge(intersection_node, intersection, intersection.size() - 1, 0))
|
||||
{
|
||||
// moving `a` to the left
|
||||
intersection[0] = merge(intersection.front(), intersection.back());
|
||||
const auto opposite = opposite_bearing(intersection.front(), intersection.back());
|
||||
intersection[0] = merge(intersection.front(), intersection.back(), opposite);
|
||||
// FIXME if we have a left-sided country, we need to switch this off and enable it
|
||||
// below
|
||||
intersection.pop_back();
|
||||
}
|
||||
else if (CanMerge(intersection_node, intersection, 0, 1))
|
||||
{
|
||||
intersection[0] = merge(intersection.front(), intersection[1]);
|
||||
const auto opposite = opposite_bearing(intersection.front(), intersection[1]);
|
||||
intersection[0] = merge(intersection.front(), intersection[1], opposite);
|
||||
intersection.erase(intersection.begin() + 1);
|
||||
}
|
||||
|
||||
@@ -230,8 +274,10 @@ IntersectionNormalizer::MergeSegregatedRoads(const NodeID intersection_node,
|
||||
{
|
||||
if (CanMerge(intersection_node, intersection, getRight(index), index))
|
||||
{
|
||||
const auto opposite =
|
||||
opposite_bearing(intersection[getRight(index)], intersection[index]);
|
||||
intersection[getRight(index)] =
|
||||
merge(intersection[getRight(index)], intersection[index]);
|
||||
merge(intersection[getRight(index)], intersection[index], opposite);
|
||||
intersection.erase(intersection.begin() + index);
|
||||
--index;
|
||||
}
|
||||
|
||||
@@ -251,6 +251,7 @@ bool MergableRoadDetector::IsNarrowTriangle(const NodeID intersection_node,
|
||||
connector_turn->eid,
|
||||
connect_accumulator,
|
||||
selector);
|
||||
|
||||
// the if both items are connected
|
||||
return node_based_graph.GetTarget(connect_accumulator.via_edge_id) ==
|
||||
node_based_graph.GetTarget(right_accumulator.via_edge_id);
|
||||
|
||||
@@ -248,6 +248,20 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
|
||||
|
||||
sliproad_edge = intersection_finder.via_edge_id;
|
||||
const auto target_intersection = intersection_finder.intersection;
|
||||
if (target_intersection.isDeadEnd())
|
||||
continue;
|
||||
|
||||
const auto find_valid = [](const IntersectionView &view) {
|
||||
// according to our current sliproad idea, there should only be one valid turn
|
||||
auto itr = std::find_if(
|
||||
view.begin(), view.end(), [](const auto &road) { return road.entry_allowed; });
|
||||
BOOST_ASSERT(itr != view.end());
|
||||
return itr;
|
||||
};
|
||||
|
||||
// require all to be same mode, don't allow changes
|
||||
if (!allSameMode(source_edge_id, sliproad.eid, find_valid(target_intersection)->eid))
|
||||
continue;
|
||||
|
||||
// Constrain the Sliproad's target to sliproad, outgoing, incoming from main intersection
|
||||
if (target_intersection.size() != 3)
|
||||
@@ -673,6 +687,16 @@ bool SliproadHandler::isValidSliproadLink(const IntersectionViewData &sliproad,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SliproadHandler::allSameMode(const EdgeID from,
|
||||
const EdgeID sliproad_candidate,
|
||||
const EdgeID target_road) const
|
||||
{
|
||||
return node_based_graph.GetEdgeData(from).travel_mode ==
|
||||
node_based_graph.GetEdgeData(sliproad_candidate).travel_mode &&
|
||||
node_based_graph.GetEdgeData(sliproad_candidate).travel_mode ==
|
||||
node_based_graph.GetEdgeData(target_road).travel_mode;
|
||||
}
|
||||
|
||||
bool SliproadHandler::canBeTargetOfSliproad(const IntersectionView &intersection)
|
||||
{
|
||||
// Example to handle:
|
||||
|
||||
Reference in New Issue
Block a user