Add support for multiple via-way restrictions (#5907)

Currently OSRM only supports turn restrictions with a single via-node or one
via-way. OSM allows for multiple via-ways to represent longer and more
complex restrictions.

This PR extends the use of duplicate nodes for representng via-way turn
restrictions to also support multi via-way restrictions. Effectively, this
increases the edge-based graph size by the number of edges in multi via-way
restrictions. However, given the low number of these restrictions it
has little effect on total graph size.

In addition, we add a new step in the extraction phase that constructs
a restriction graph to support more complex relationships between restrictions,
such as nested restrictions and overlapping restrictions.
This commit is contained in:
Michael Bell
2020-12-20 21:59:57 +00:00
committed by GitHub
parent eb1d399f3b
commit 5266ac1635
48 changed files with 3170 additions and 1406 deletions
+23 -50
View File
@@ -12,8 +12,9 @@
#include "extractor/maneuver_override_relation_parser.hpp"
#include "extractor/name_table.hpp"
#include "extractor/node_based_graph_factory.hpp"
#include "extractor/node_restriction_map.hpp"
#include "extractor/restriction_filter.hpp"
#include "extractor/restriction_index.hpp"
#include "extractor/restriction_graph.hpp"
#include "extractor/restriction_parser.hpp"
#include "extractor/scripting_environment.hpp"
#include "extractor/tarjan_scc.hpp"
@@ -215,12 +216,8 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
LaneDescriptionMap turn_lane_map;
std::vector<TurnRestriction> turn_restrictions;
std::vector<ConditionalTurnRestriction> conditional_turn_restrictions;
std::vector<UnresolvedManeuverOverride> unresolved_maneuver_overrides;
std::tie(turn_lane_map,
turn_restrictions,
conditional_turn_restrictions,
unresolved_maneuver_overrides) =
std::tie(turn_lane_map, turn_restrictions, unresolved_maneuver_overrides) =
ParseOSMData(scripting_environment, number_of_threads);
// Transform the node-based graph that OSM is based on into an edge-based graph
@@ -242,7 +239,6 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
NodeBasedGraphFactory node_based_graph_factory(config.GetPath(".osrm"),
scripting_environment,
turn_restrictions,
conditional_turn_restrictions,
unresolved_maneuver_overrides);
NameTable name_table;
@@ -283,8 +279,8 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
edge_based_nodes_container =
EdgeBasedNodeDataContainer({}, std::move(node_based_graph_factory.GetAnnotationData()));
conditional_turn_restrictions =
removeInvalidRestrictions(std::move(conditional_turn_restrictions), node_based_graph);
turn_restrictions = removeInvalidRestrictions(std::move(turn_restrictions), node_based_graph);
auto restriction_graph = constructRestrictionGraph(turn_restrictions);
const auto number_of_node_based_nodes = node_based_graph.GetNumberOfNodes();
@@ -294,8 +290,7 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
node_based_graph_factory.GetCompressedEdges(),
barrier_nodes,
traffic_signals,
turn_restrictions,
conditional_turn_restrictions,
restriction_graph,
segregated_edges,
name_table,
unresolved_maneuver_overrides,
@@ -314,8 +309,7 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
coordinates,
node_based_graph_factory.GetCompressedEdges(),
barrier_nodes,
turn_restrictions,
conditional_turn_restrictions,
restriction_graph,
name_table,
std::move(turn_lane_map),
scripting_environment);
@@ -374,12 +368,10 @@ int Extractor::run(ScriptingEnvironment &scripting_environment)
return 0;
}
std::tuple<LaneDescriptionMap,
std::vector<TurnRestriction>,
std::vector<ConditionalTurnRestriction>,
std::vector<UnresolvedManeuverOverride>>
Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
const unsigned number_of_threads)
std::
tuple<LaneDescriptionMap, std::vector<TurnRestriction>, std::vector<UnresolvedManeuverOverride>>
Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
const unsigned number_of_threads)
{
TIMER_START(extracting);
@@ -455,7 +447,7 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
std::vector<std::pair<const osmium::Node &, ExtractionNode>> resulting_nodes;
std::vector<std::pair<const osmium::Way &, ExtractionWay>> resulting_ways;
std::vector<std::pair<const osmium::Relation &, ExtractionRelation>> resulting_relations;
std::vector<InputConditionalTurnRestriction> resulting_restrictions;
std::vector<InputTurnRestriction> resulting_restrictions;
std::vector<InputManeuverOverride> resulting_maneuver_overrides;
};
@@ -638,8 +630,7 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment,
util::Log() << "extraction finished after " << TIMER_SEC(extracting) << "s";
return std::make_tuple(std::move(turn_lane_map),
std::move(extraction_containers.unconditional_turn_restrictions),
std::move(extraction_containers.conditional_turn_restrictions),
std::move(extraction_containers.turn_restrictions),
std::move(extraction_containers.internal_maneuver_overrides));
}
@@ -712,8 +703,7 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
const CompressedEdgeContainer &compressed_edge_container,
const std::unordered_set<NodeID> &barrier_nodes,
const std::unordered_set<NodeID> &traffic_signals,
const std::vector<TurnRestriction> &turn_restrictions,
const std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
const RestrictionGraph &restriction_graph,
const std::unordered_set<EdgeID> &segregated_edges,
const NameTable &name_table,
const std::vector<UnresolvedManeuverOverride> &maneuver_overrides,
@@ -740,21 +730,10 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
turn_lane_map);
const auto create_edge_based_edges = [&]() {
// scoped to relase intermediate datastructures right after the call
std::vector<TurnRestriction> node_restrictions;
for (auto const &t : turn_restrictions)
if (t.Type() == RestrictionType::NODE_RESTRICTION)
node_restrictions.push_back(t);
std::vector<ConditionalTurnRestriction> conditional_node_restrictions;
for (auto const &t : conditional_turn_restrictions)
if (t.Type() == RestrictionType::NODE_RESTRICTION)
conditional_node_restrictions.push_back(t);
RestrictionMap via_node_restriction_map(node_restrictions, IndexNodeByFromAndVia());
WayRestrictionMap via_way_restriction_map(conditional_turn_restrictions);
ConditionalRestrictionMap conditional_node_restriction_map(conditional_node_restrictions,
IndexNodeByFromAndVia());
// scoped to release intermediate data structures right after the call
RestrictionMap unconditional_node_restriction_map(restriction_graph);
ConditionalRestrictionMap conditional_node_restriction_map(restriction_graph);
WayRestrictionMap via_way_restriction_map(restriction_graph);
edge_based_graph_factory.Run(scripting_environment,
config.GetPath(".osrm.turn_weight_penalties").string(),
config.GetPath(".osrm.turn_duration_penalties").string(),
@@ -762,7 +741,7 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
config.GetPath(".osrm.cnbg_to_ebg").string(),
config.GetPath(".osrm.restrictions").string(),
config.GetPath(".osrm.maneuver_overrides").string(),
via_node_restriction_map,
unconditional_node_restriction_map,
conditional_node_restriction_map,
via_way_restriction_map,
maneuver_overrides);
@@ -833,8 +812,7 @@ void Extractor::ProcessGuidanceTurns(
const std::vector<util::Coordinate> &node_coordinates,
const CompressedEdgeContainer &compressed_edge_container,
const std::unordered_set<NodeID> &barrier_nodes,
const std::vector<TurnRestriction> &turn_restrictions,
const std::vector<ConditionalTurnRestriction> &conditional_turn_restrictions,
const RestrictionGraph &restriction_graph,
const NameTable &name_table,
LaneDescriptionMap lane_description_map,
ScriptingEnvironment &scripting_environment)
@@ -853,20 +831,15 @@ void Extractor::ProcessGuidanceTurns(
SuffixTable street_name_suffix_table(scripting_environment);
const auto &turn_lanes_data = transformTurnLaneMapIntoArrays(lane_description_map);
std::vector<TurnRestriction> node_restrictions;
for (auto const &t : turn_restrictions)
if (t.Type() == RestrictionType::NODE_RESTRICTION)
node_restrictions.push_back(t);
RestrictionMap node_restriction_map(node_restrictions, IndexNodeByFromAndVia());
WayRestrictionMap way_restriction_map(conditional_turn_restrictions);
RestrictionMap unconditional_node_restriction_map(restriction_graph);
WayRestrictionMap way_restriction_map(restriction_graph);
osrm::guidance::annotateTurns(node_based_graph,
edge_based_node_container,
node_coordinates,
compressed_edge_container,
barrier_nodes,
node_restriction_map,
unconditional_node_restriction_map,
way_restriction_map,
name_table,
street_name_suffix_table,