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
+3 -6
View File
@@ -22,12 +22,9 @@ std::string toString(const ConnectedRoad &road)
result += " angle: ";
result += std::to_string(road.turn.angle);
result += " instruction: ";
result +=
std::to_string(static_cast<std::int32_t>(road.turn.instruction.type)) + " " +
std::to_string(static_cast<std::int32_t>(road.turn.instruction.direction_modifier)) + " " +
std::to_string(static_cast<std::int32_t>(road.turn.instruction.lane_tupel.lanes_in_turn)) +
" " + std::to_string(static_cast<std::int32_t>(
road.turn.instruction.lane_tupel.first_lane_from_the_right));
result += std::to_string(static_cast<std::int32_t>(road.turn.instruction.type)) + " " +
std::to_string(static_cast<std::int32_t>(road.turn.instruction.direction_modifier)) +
" " + std::to_string(static_cast<std::int32_t>(road.turn.lane_data_id));
return result;
}
@@ -1,5 +1,5 @@
#include "extractor/guidance/constants.hpp"
#include "extractor/guidance/intersection_generator.hpp"
#include "extractor/guidance/constants.hpp"
#include "extractor/guidance/toolkit.hpp"
#include <algorithm>
@@ -114,9 +114,12 @@ Intersection IntersectionGenerator::getConnectedRoads(const NodeID from_node,
has_uturn_edge = true;
}
intersection.push_back(ConnectedRoad(
TurnOperation{onto_edge, angle, {TurnType::Invalid, DirectionModifier::UTurn}},
turn_is_valid));
intersection.push_back(
ConnectedRoad(TurnOperation{onto_edge,
angle,
{TurnType::Invalid, DirectionModifier::UTurn},
INVALID_LANE_DATAID},
turn_is_valid));
}
// We hit the case of a street leading into nothing-ness. Since the code here assumes that this
@@ -124,7 +127,9 @@ Intersection IntersectionGenerator::getConnectedRoads(const NodeID from_node,
if (!has_uturn_edge)
{
intersection.push_back(
{TurnOperation{via_eid, 0., {TurnType::Invalid, DirectionModifier::UTurn}}, false});
{TurnOperation{
via_eid, 0., {TurnType::Invalid, DirectionModifier::UTurn}, INVALID_LANE_DATAID},
false});
}
const auto ByAngle = [](const ConnectedRoad &first, const ConnectedRoad second) {
@@ -373,11 +373,12 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou
if (1 == node_based_graph.GetDirectedOutDegree(node_v))
{
// No turn possible.
if( intersection.size() == 2 )
if (intersection.size() == 2)
turn.instruction = TurnInstruction::NO_TURN();
else
{
turn.instruction.type = TurnType::Suppressed; //make sure to report intersection
turn.instruction.type =
TurnType::Suppressed; // make sure to report intersection
turn.instruction.direction_modifier = getTurnDirection(turn.angle);
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
#include "extractor/guidance/constants.hpp"
#include "extractor/guidance/turn_discovery.hpp"
#include "extractor/guidance/constants.hpp"
namespace osrm
{
@@ -2,9 +2,9 @@
#include "util/simple_logger.hpp"
#include <algorithm>
#include <boost/assert.hpp>
#include <cstddef>
#include <utility>
#include <boost/assert.hpp>
namespace osrm
{
@@ -171,7 +171,6 @@ LaneDataVector handleRenamingSituations(const std::size_t none_index,
has_left |= modifier == DirectionModifier::SharpLeft;
}
// find missing tag and augment neighboring, if possible
if (none_index == 0)
{
+5 -5
View File
@@ -52,8 +52,7 @@ LaneDataVector laneDataFromString(std::string turn_lane_string)
// count the number of lanes
const auto num_lanes = [](const std::string &turn_lane_string) {
return boost::numeric_cast<LaneID>(
std::count(turn_lane_string.begin(), turn_lane_string.end(), '|') + 1 +
std::count(turn_lane_string.begin(), turn_lane_string.end(), '&'));
std::count(turn_lane_string.begin(), turn_lane_string.end(), '|') + 1);
}(turn_lane_string);
const auto getNextTag = [](std::string &string, const char *separators) {
@@ -103,7 +102,7 @@ LaneDataVector laneDataFromString(std::string turn_lane_string)
// FIXME this is a cucumber workaround, since escaping does not work properly in
// cucumber.js (see https://github.com/cucumber/cucumber-js/issues/417). Needs to be
// changed to "|" only, when the bug is fixed
auto lane = getNextTag(turn_lane_string, "|&");
auto lane = getNextTag(turn_lane_string, "|");
setLaneData(lane_map, lane, lane_nr);
++lane_nr;
} while (lane_nr < num_lanes);
@@ -135,8 +134,9 @@ LaneDataVector::const_iterator findTag(const std::string &tag, const LaneDataVec
});
}
bool hasTag(const std::string &tag, const LaneDataVector &data){
return findTag(tag,data) != data.cend();
bool hasTag(const std::string &tag, const LaneDataVector &data)
{
return findTag(tag, data) != data.cend();
}
} // namespace lanes
+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
+26 -6
View File
@@ -1,8 +1,11 @@
#include "extractor/guidance/toolkit.hpp"
#include "extractor/guidance/turn_lane_matcher.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "util/guidance/toolkit.hpp"
#include <boost/assert.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <functional>
namespace osrm
{
@@ -169,9 +172,27 @@ bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &l
Intersection triviallyMatchLanesToTurns(Intersection intersection,
const LaneDataVector &lane_data,
const util::NodeBasedDynamicGraph &node_based_graph)
const util::NodeBasedDynamicGraph &node_based_graph,
const LaneStringID lane_string_id,
LaneDataIdMap &lane_data_to_id)
{
std::size_t road_index = 1, lane = 0;
const auto matchRoad = [&](ConnectedRoad &road, const TurnLaneData &data) {
LaneTupelIdPair key{{LaneID(data.to - data.from + 1), data.from}, lane_string_id};
auto lane_data_id = boost::numeric_cast<LaneDataID>(lane_data_to_id.size());
const auto it = lane_data_to_id.find(key);
if (it == lane_data_to_id.end())
lane_data_to_id.insert({key, lane_data_id});
else
lane_data_id = it->second;
// set lane id instead after the switch:
road.turn.lane_data_id = lane_data_id;
};
for (; road_index < intersection.size() && lane < lane_data.size(); ++road_index)
{
if (intersection[road_index].entry_allowed)
@@ -185,8 +206,7 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
if (TurnType::Suppressed == intersection[road_index].turn.instruction.type)
intersection[road_index].turn.instruction.type = TurnType::UseLane;
intersection[road_index].turn.instruction.lane_tupel = {
LaneID(lane_data[lane].to - lane_data[lane].from + 1), lane_data[lane].from};
matchRoad(intersection[road_index], lane_data[lane]);
++lane;
}
}
@@ -209,8 +229,8 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection,
intersection[u_turn].entry_allowed = true;
intersection[u_turn].turn.instruction.type = TurnType::Turn;
intersection[u_turn].turn.instruction.direction_modifier = DirectionModifier::UTurn;
intersection[u_turn].turn.instruction.lane_tupel = {
LaneID(lane_data.back().to - lane_data.back().from + 1), lane_data.back().from};
matchRoad(intersection[u_turn], lane_data.back());
}
return std::move(intersection);
}