roundabout for segregated entry roads
This commit is contained in:
committed by
Patrick Niklaus
parent
be5b49e391
commit
e59a7926a2
@@ -208,6 +208,15 @@ Intersection IntersectionGenerator::mergeSegregatedRoads(Intersection intersecti
|
||||
if (intersection.size() == 1)
|
||||
return intersection;
|
||||
|
||||
const bool is_connected_to_roundabout = [this,&intersection]() {
|
||||
for (const auto &road : intersection)
|
||||
{
|
||||
if (node_based_graph.GetEdgeData(road.turn.eid).roundabout)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
|
||||
// check for merges including the basic u-turn
|
||||
// these result in an adjustment of all other angles
|
||||
if (mergable(0, intersection.size() - 1))
|
||||
@@ -216,8 +225,24 @@ Intersection IntersectionGenerator::mergeSegregatedRoads(Intersection intersecti
|
||||
(360 - intersection[intersection.size() - 1].turn.angle) / 2;
|
||||
for (std::size_t i = 1; i + 1 < intersection.size(); ++i)
|
||||
intersection[i].turn.angle += correction_factor;
|
||||
|
||||
// FIXME if we have a left-sided country, we need to switch this off and enable it below
|
||||
intersection[0] = merge(intersection.front(), intersection.back());
|
||||
intersection[0].turn.angle = 0;
|
||||
|
||||
if (is_connected_to_roundabout)
|
||||
{
|
||||
// We are merging a u-turn against the direction of a roundabout
|
||||
//
|
||||
// -----------> roundabout
|
||||
// / \
|
||||
// out in
|
||||
//
|
||||
// These cases have to be disabled, even if they are not forbidden specifically by a
|
||||
// relation
|
||||
intersection[0].entry_allowed = false;
|
||||
}
|
||||
|
||||
intersection.pop_back();
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ bool RoundaboutHandler::canProcess(const NodeID from_nid,
|
||||
Intersection RoundaboutHandler::
|
||||
operator()(const NodeID from_nid, const EdgeID via_eid, Intersection intersection) const
|
||||
{
|
||||
invalidateExitAgainstDirection(from_nid, via_eid, intersection);
|
||||
const auto flags = getRoundaboutFlags(from_nid, via_eid, intersection);
|
||||
const bool is_rotary = isRotary(node_based_graph.GetTarget(via_eid));
|
||||
// find the radius of the roundabout
|
||||
@@ -55,7 +56,7 @@ detail::RoundaboutFlags RoundaboutHandler::getRoundaboutFlags(
|
||||
{
|
||||
const auto &edge_data = node_based_graph.GetEdgeData(road.turn.eid);
|
||||
// only check actual outgoing edges
|
||||
if (edge_data.reversed)
|
||||
if (edge_data.reversed || !road.entry_allowed )
|
||||
continue;
|
||||
|
||||
if (edge_data.roundabout)
|
||||
@@ -79,6 +80,42 @@ detail::RoundaboutFlags RoundaboutHandler::getRoundaboutFlags(
|
||||
return {on_roundabout, can_enter_roundabout, can_exit_roundabout_separately};
|
||||
}
|
||||
|
||||
void RoundaboutHandler::invalidateExitAgainstDirection(const NodeID from_nid,
|
||||
const EdgeID via_eid,
|
||||
Intersection &intersection) const
|
||||
{
|
||||
const auto &in_edge_data = node_based_graph.GetEdgeData(via_eid);
|
||||
if( in_edge_data.roundabout )
|
||||
return;
|
||||
|
||||
bool past_roundabout_angle = false;
|
||||
for (auto &road : intersection)
|
||||
{
|
||||
const auto &edge_data = node_based_graph.GetEdgeData(road.turn.eid);
|
||||
// only check actual outgoing edges
|
||||
if (edge_data.reversed)
|
||||
{
|
||||
// remember whether we have seen the roundabout in-part
|
||||
if (edge_data.roundabout)
|
||||
past_roundabout_angle = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Exiting roundabouts at an entry point is technically a data-modelling issue.
|
||||
// This workaround handles cases in which an exit precedes and entry. The resulting
|
||||
// u-turn against the roundabout direction is invalidated.
|
||||
// The sorting of the angles represents a problem for left-sided driving, though.
|
||||
// FIXME in case of left-sided driving, we have to check whether we can enter the
|
||||
// roundabout later in the cycle, rather than prior.
|
||||
if (!edge_data.roundabout && node_based_graph.GetTarget(road.turn.eid) != from_nid &&
|
||||
past_roundabout_angle)
|
||||
{
|
||||
road.entry_allowed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RoundaboutHandler::isRotary(const NodeID nid) const
|
||||
{
|
||||
// translate a node ID into its respective coordinate stored in the node_info_list
|
||||
@@ -191,7 +228,6 @@ Intersection RoundaboutHandler::handleRoundabouts(const bool is_rotary,
|
||||
const bool can_exit_roundabout_separately,
|
||||
Intersection intersection) const
|
||||
{
|
||||
// TODO requires differentiation between roundabouts and rotaries
|
||||
// detect via radius (get via circle through three vertices)
|
||||
NodeID node_v = node_based_graph.GetTarget(via_eid);
|
||||
if (on_roundabout)
|
||||
|
||||
Reference in New Issue
Block a user