Implement Turn Lane Api
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "extractor/edge_based_graph_factory.hpp"
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/exception.hpp"
|
||||
@@ -182,6 +182,7 @@ void EdgeBasedGraphFactory::FlushVectorToStream(
|
||||
}
|
||||
|
||||
void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
lua_State *lua_state,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_penalty_filename,
|
||||
@@ -198,6 +199,7 @@ void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
|
||||
|
||||
TIMER_START(generate_edges);
|
||||
GenerateEdgeExpandedEdges(original_edge_data_filename,
|
||||
turn_lane_data_filename,
|
||||
lua_state,
|
||||
edge_segment_lookup_filename,
|
||||
edge_penalty_filename,
|
||||
@@ -296,6 +298,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
|
||||
/// Actually it also generates OriginalEdgeData and serializes them...
|
||||
void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
const std::string &original_edge_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
lua_State *lua_state,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_fixed_penalties_filename,
|
||||
@@ -348,6 +351,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
bearing_class_by_node_based_node.resize(m_node_based_graph->GetNumberOfNodes(),
|
||||
std::numeric_limits<std::uint32_t>::max());
|
||||
|
||||
guidance::LaneDataIdMap lane_data_map;
|
||||
for (const auto node_u : util::irange(0u, m_node_based_graph->GetNumberOfNodes()))
|
||||
{
|
||||
progress.PrintStatus(node_u);
|
||||
@@ -364,8 +368,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
intersection =
|
||||
turn_analysis.assignTurnTypes(node_u, edge_from_u, std::move(intersection));
|
||||
|
||||
intersection =
|
||||
turn_lane_handler.assignTurnLanes(node_u, edge_from_u, std::move(intersection));
|
||||
intersection = turn_lane_handler.assignTurnLanes(
|
||||
node_u, edge_from_u, std::move(intersection), lane_data_map);
|
||||
const auto possible_turns = turn_analysis.transformIntersectionIntoTurns(intersection);
|
||||
|
||||
// the entry class depends on the turn, so we have to classify the interesction for
|
||||
@@ -437,6 +441,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
original_edge_data_vector.emplace_back(
|
||||
m_compressed_edge_container.GetPositionForID(edge_from_u),
|
||||
edge_data1.name_id,
|
||||
turn.lane_data_id,
|
||||
turn_instruction,
|
||||
entry_class_id,
|
||||
edge_data1.travel_mode);
|
||||
@@ -541,6 +546,22 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
util::SimpleLogger().Write() << "Created " << entry_class_hash.size() << " entry classes and "
|
||||
<< bearing_class_hash.size() << " Bearing Classes";
|
||||
|
||||
util::SimpleLogger().Write() << "Writing Turn Lane Data to File...";
|
||||
std::ofstream turn_lane_data_file(turn_lane_data_filename.c_str(), std::ios::binary);
|
||||
std::vector<util::guidance::LaneTupelIdPair> lane_data(lane_data_map.size());
|
||||
// extract lane data sorted by ID
|
||||
for (auto itr : lane_data_map)
|
||||
lane_data[itr.second] = itr.first;
|
||||
|
||||
std::uint64_t size = lane_data.size();
|
||||
turn_lane_data_file.write(reinterpret_cast<const char *>(&size), sizeof(size));
|
||||
|
||||
if (!lane_data.empty())
|
||||
turn_lane_data_file.write(reinterpret_cast<const char *>(&lane_data[0]),
|
||||
sizeof(util::guidance::LaneTupelIdPair) * lane_data.size());
|
||||
|
||||
util::SimpleLogger().Write() << "done.";
|
||||
|
||||
FlushVectorToStream(edge_data_file, original_edge_data_vector);
|
||||
|
||||
// Finally jump back to the empty space at the beginning and write length prefix
|
||||
|
||||
@@ -51,8 +51,6 @@ ExtractionContainers::ExtractionContainers()
|
||||
name_lengths.push_back(0);
|
||||
name_lengths.push_back(0);
|
||||
name_lengths.push_back(0);
|
||||
name_lengths.push_back(0);
|
||||
name_lengths.push_back(0);
|
||||
turn_lane_lengths.push_back(0);
|
||||
}
|
||||
|
||||
@@ -87,8 +85,8 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
|
||||
PrepareRestrictions();
|
||||
WriteRestrictions(restrictions_file_name);
|
||||
|
||||
WriteCharData(name_file_name,name_lengths,name_char_data);
|
||||
WriteCharData(turn_lane_file_name,turn_lane_lengths,turn_lane_char_data);
|
||||
WriteCharData(name_file_name, name_lengths, name_char_data);
|
||||
WriteCharData(turn_lane_file_name, turn_lane_lengths, turn_lane_char_data);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
|
||||
@@ -239,7 +239,7 @@ int Extractor::run()
|
||||
extraction_containers.PrepareData(config.output_file_name,
|
||||
config.restriction_file_name,
|
||||
config.names_file_name,
|
||||
config.turn_lane_file_name,
|
||||
config.turn_lane_strings_file_name,
|
||||
main_context.state);
|
||||
|
||||
WriteProfileProperties(config.profile_properties_output_path, main_context.properties);
|
||||
@@ -504,7 +504,7 @@ Extractor::BuildEdgeExpandedGraph(lua_State *lua_state,
|
||||
compressed_edge_container.SerializeInternalVector(config.geometry_output_path);
|
||||
|
||||
util::NameTable name_table(config.names_file_name);
|
||||
util::NameTable turn_lanes(config.turn_lane_file_name);
|
||||
util::NameTable turn_lanes(config.turn_lane_strings_file_name);
|
||||
|
||||
EdgeBasedGraphFactory edge_based_graph_factory(
|
||||
node_based_graph,
|
||||
@@ -518,6 +518,7 @@ Extractor::BuildEdgeExpandedGraph(lua_State *lua_state,
|
||||
turn_lanes);
|
||||
|
||||
edge_based_graph_factory.Run(config.edge_output_path,
|
||||
config.turn_lane_data_file_name,
|
||||
lua_state,
|
||||
config.edge_segment_lookup_path,
|
||||
config.edge_penalty_path,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "extractor/extractor_callbacks.hpp"
|
||||
#include "extractor/extraction_containers.hpp"
|
||||
#include "extractor/extraction_node.hpp"
|
||||
#include "extractor/extraction_way.hpp"
|
||||
#include "extractor/extractor_callbacks.hpp"
|
||||
|
||||
#include "extractor/external_memory_node.hpp"
|
||||
#include "extractor/restriction.hpp"
|
||||
@@ -149,9 +149,17 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
|
||||
// Otherwise fetches the id based on the name and returns it without insertion.
|
||||
|
||||
const constexpr auto MAX_STRING_LENGTH = 255u;
|
||||
const auto requestId = [this,MAX_STRING_LENGTH](const std::string turn_lane_string) {
|
||||
if( turn_lane_string == "" )
|
||||
const auto requestId = [this, MAX_STRING_LENGTH](const std::string &turn_lane_string_) {
|
||||
if (turn_lane_string_ == "")
|
||||
return INVALID_LANE_STRINGID;
|
||||
|
||||
// requires https://github.com/cucumber/cucumber-js/issues/417
|
||||
// remove this handling when the issue is contained
|
||||
std::string turn_lane_string = turn_lane_string_;
|
||||
for (auto &val : turn_lane_string)
|
||||
if (val == '&')
|
||||
val = '|';
|
||||
|
||||
const auto &lane_map_iterator = lane_map.find(turn_lane_string);
|
||||
if (lane_map.end() == lane_map_iterator)
|
||||
{
|
||||
|
||||
@@ -113,7 +113,7 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
// traffic signals in the `traffic_lights` list, which EdgeData
|
||||
// doesn't have access to.
|
||||
const bool has_node_penalty = traffic_lights.find(node_v) != traffic_lights.end();
|
||||
if( has_node_penalty )
|
||||
if (has_node_penalty)
|
||||
continue;
|
||||
|
||||
// Get distances before graph is modified
|
||||
@@ -168,10 +168,10 @@ void GraphCompressor::Compress(const std::unordered_set<NodeID> &barrier_nodes,
|
||||
return front;
|
||||
return back;
|
||||
};
|
||||
graph.GetEdgeData(forward_e1).lane_string_id =
|
||||
selectLaneID(graph.GetEdgeData(forward_e1).lane_string_id, fwd_edge_data2.lane_string_id);
|
||||
graph.GetEdgeData(reverse_e1).lane_string_id =
|
||||
selectLaneID(graph.GetEdgeData(reverse_e1).lane_string_id, rev_edge_data2.lane_string_id);
|
||||
graph.GetEdgeData(forward_e1).lane_string_id = selectLaneID(
|
||||
graph.GetEdgeData(forward_e1).lane_string_id, fwd_edge_data2.lane_string_id);
|
||||
graph.GetEdgeData(reverse_e1).lane_string_id = selectLaneID(
|
||||
graph.GetEdgeData(reverse_e1).lane_string_id, rev_edge_data2.lane_string_id);
|
||||
|
||||
// remove e2's (if bidir, otherwise only one)
|
||||
graph.DeleteEdge(node_v, forward_e2);
|
||||
|
||||
@@ -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