Implement Turn Lane Api

This commit is contained in:
Moritz Kobitzsch
2016-06-15 14:38:24 +02:00
parent ec0a1a4ab1
commit 5d91b759d1
59 changed files with 1274 additions and 439 deletions
+29 -24
View File
@@ -1,8 +1,8 @@
#include "extractor/guidance/turn_lane_handler.hpp"
#include "extractor/guidance/constants.hpp"
#include "extractor/guidance/turn_discovery.hpp"
#include "extractor/guidance/turn_lane_handler.hpp"
#include "extractor/guidance/turn_lane_matcher.hpp"
#include "extractor/guidance/turn_lane_augmentation.hpp"
#include "extractor/guidance/turn_lane_matcher.hpp"
#include "util/simple_logger.hpp"
#include "util/typedefs.hpp"
@@ -40,7 +40,7 @@ TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_g
}
/*
Turn lanes are given in the form of strings that closely correspond to the direction modifiers
Turn lanes are given in the form of strings that closely correspond to the direction modifiers
we use for our turn types. However, we still cannot simply perform a 1:1 assignment.
This function parses the turn_lane_strings of a format that describes an intersection as:
@@ -58,11 +58,9 @@ TurnLaneHandler::TurnLaneHandler(const util::NodeBasedDynamicGraph &node_based_g
*/
Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
const EdgeID via_edge,
Intersection intersection) const
Intersection intersection,
LaneDataIdMap &id_map) const
{
// initialize to invalid
for (auto &road : intersection)
road.turn.instruction.lane_tupel = {0, INVALID_LANEID};
const auto &data = node_based_graph.GetEdgeData(via_edge);
const auto turn_lane_string = data.lane_string_id != INVALID_LANE_STRINGID
? turn_lane_strings.GetNameForID(data.lane_string_id)
@@ -89,17 +87,15 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
const std::size_t possible_entries = getNumberOfTurns(intersection);
// merge does not justify an instruction
const bool has_merge_lane = (hasTag("merge_to_left", lane_data) ||
hasTag("merge_to_right", lane_data));
const bool has_merge_lane =
(hasTag("merge_to_left", lane_data) || hasTag("merge_to_right", lane_data));
// Dead end streets that don't have any left-tag. This can happen due to the fallbacks for
// broken data/barriers.
const bool has_non_usable_u_turn =
(intersection[0].entry_allowed && !hasTag("none", lane_data) &&
!hasTag("left", lane_data) &&
!hasTag("sharp_left", lane_data) &&
!hasTag("reverse", lane_data) &&
lane_data.size() + 1 == possible_entries);
!hasTag("left", lane_data) && !hasTag("sharp_left", lane_data) &&
!hasTag("reverse", lane_data) && lane_data.size() + 1 == possible_entries);
if (has_merge_lane || has_non_usable_u_turn)
return std::move(intersection);
@@ -118,7 +114,8 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
if (is_simple)
{
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
return simpleMatchTuplesToTurns(std::move(intersection), lane_data);
return simpleMatchTuplesToTurns(
std::move(intersection), lane_data, data.lane_string_id, id_map);
}
// if the intersection is not simple but we have lane data, we check for intersections with
// middle islands. We have two cases. The first one is providing lane data on the current
@@ -138,7 +135,8 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
isSimpleIntersection(lane_data, intersection))
{
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
return simpleMatchTuplesToTurns(std::move(intersection), lane_data);
return simpleMatchTuplesToTurns(
std::move(intersection), lane_data, data.lane_string_id, id_map);
}
}
}
@@ -148,7 +146,7 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
{
// acquire the lane data of a previous segment and, if possible, use it for the current
// intersection.
return handleTurnAtPreviousIntersection(at, via_edge, std::move(intersection));
return handleTurnAtPreviousIntersection(at, via_edge, std::move(intersection), id_map);
}
return std::move(intersection);
@@ -158,7 +156,8 @@ Intersection TurnLaneHandler::assignTurnLanes(const NodeID at,
// actually take the turn, we need to look back to the edge we drove onto the intersection with.
Intersection TurnLaneHandler::handleTurnAtPreviousIntersection(const NodeID at,
const EdgeID via_edge,
Intersection intersection) const
Intersection intersection,
LaneDataIdMap &id_map) const
{
NodeID previous_node = SPECIAL_NODEID;
Intersection previous_intersection;
@@ -176,6 +175,7 @@ Intersection TurnLaneHandler::handleTurnAtPreviousIntersection(const NodeID at,
previous_id,
previous_intersection))
return "";
BOOST_ASSERT(previous_id != SPECIAL_EDGEID);
const auto &previous_data = node_based_graph.GetEdgeData(previous_id);
auto previous_string = previous_data.lane_string_id != INVALID_LANE_STRINGID
@@ -204,11 +204,13 @@ Intersection TurnLaneHandler::handleTurnAtPreviousIntersection(const NodeID at,
if (lane_data.empty())
return std::move(intersection);
const auto &previous_data = node_based_graph.GetEdgeData(previous_id);
const auto is_simple = isSimpleIntersection(lane_data, intersection);
if (is_simple)
{
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
return simpleMatchTuplesToTurns(std::move(intersection), lane_data);
return simpleMatchTuplesToTurns(
std::move(intersection), lane_data, previous_data.lane_string_id, id_map);
}
else
{
@@ -227,14 +229,14 @@ Intersection TurnLaneHandler::handleTurnAtPreviousIntersection(const NodeID at,
isSimpleIntersection(lane_data, intersection))
{
lane_data = handleNoneValueAtSimpleTurn(std::move(lane_data), intersection);
return simpleMatchTuplesToTurns(std::move(intersection), lane_data);
return simpleMatchTuplesToTurns(
std::move(intersection), lane_data, previous_data.lane_string_id, id_map);
}
}
}
return std::move(intersection);
}
/* A simple intersection does not depend on the next intersection coming up. This is important
* for turn lanes, since traffic signals and/or segregated a intersection can influence the
* interpretation of turn-lanes at a given turn.
@@ -296,7 +298,7 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data,
}
if (num_turns > lane_data.size() && intersection[0].entry_allowed &&
!( hasTag("reverse", lane_data) ||
!(hasTag("reverse", lane_data) ||
(lane_data.back().tag != "left" && lane_data.back().tag != "sharp_left")))
{
return false;
@@ -417,7 +419,7 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
return {turn_lane_data, {}};
}
std::size_t none_index = std::distance(turn_lane_data.begin(),findTag("none", turn_lane_data));
std::size_t none_index = std::distance(turn_lane_data.begin(), findTag("none", turn_lane_data));
// if the turn lanes are pull forward, we might have to add an additional straight tag
// did we find something that matches against the straightmost road?
@@ -486,7 +488,9 @@ std::pair<LaneDataVector, LaneDataVector> TurnLaneHandler::partitionLaneData(
}
Intersection TurnLaneHandler::simpleMatchTuplesToTurns(Intersection intersection,
const LaneDataVector &lane_data) const
const LaneDataVector &lane_data,
const LaneStringID lane_string_id,
LaneDataIdMap &id_map) const
{
if (lane_data.empty() || !canMatchTrivially(intersection, lane_data))
return std::move(intersection);
@@ -496,7 +500,8 @@ Intersection TurnLaneHandler::simpleMatchTuplesToTurns(Intersection intersection
return boost::starts_with(data.tag, "merge");
}) == 0);
return triviallyMatchLanesToTurns(std::move(intersection), lane_data, node_based_graph);
return triviallyMatchLanesToTurns(
std::move(intersection), lane_data, node_based_graph, lane_string_id, id_map);
}
} // namespace lanes