Implement Turn Lane Api
This commit is contained in:
@@ -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,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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user