restructure for review remarks

This commit is contained in:
Moritz Kobitzsch 2017-07-27 11:42:13 +02:00
parent 645b1ffd75
commit 8135f08958
14 changed files with 221 additions and 237 deletions

View File

@ -16,7 +16,10 @@
- Profiles must return a hash of profile functions. This makes it easier for profiles to include each other. - Profiles must return a hash of profile functions. This makes it easier for profiles to include each other.
- Guidance: add support for throughabouts - Guidance: add support for throughabouts
- Bugfixes - Bugfixes
- Properly save/retrieve datasource annotations for road segments ([#4346](https://github.com/Project-OSRM/osrm-backend/issues/4346)) - Properly save/retrieve datasource annotations for road segments ([#4346](https://github.com/Project-OSRM/osrm-backend/issues/4346)
- Algorithm)
- BREAKING: the file format requires re-processing due to the changes on via-ways
- Added support for via-way restrictions
# 5.9.2 # 5.9.2
- API: - API:

View File

@ -639,6 +639,8 @@ Feature: Car - Turn restrictions
| | \ / | | \ /
i - d - e - - - - - - - - - - - - - - - - - i - d - e - - - - - - - - - - - - - - - - -
""" """
# The long distances here are required to make other turns undesriable in comparison to the restricted turns.
# Otherwise they might just be picked without the actual turns being restricted
And the ways And the ways
| nodes | oneway | | nodes | oneway |

View File

@ -92,7 +92,7 @@ class EdgeBasedGraphFactory
const std::string &turn_duration_penalties_filename, const std::string &turn_duration_penalties_filename,
const std::string &turn_penalties_index_filename, const std::string &turn_penalties_index_filename,
const std::string &cnbg_ebg_mapping_path, const std::string &cnbg_ebg_mapping_path,
const RestrictionMap &restriction_map, const RestrictionMap &node_restriction_map,
const WayRestrictionMap &way_restriction_map); const WayRestrictionMap &way_restriction_map);
// The following get access functions destroy the content in the factory // The following get access functions destroy the content in the factory
@ -137,9 +137,11 @@ class EdgeBasedGraphFactory
EdgeBasedNodeDataContainer m_edge_based_node_container; EdgeBasedNodeDataContainer m_edge_based_node_container;
util::DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list; util::DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
// the number of edge-based nodes is mostly made up out of the edges in the node-based graph. // The number of edge-based nodes is mostly made up out of the edges in the node-based graph.
// Any edge in the node-based graph represents a node in the edge-based graph. In addition, we // Any edge in the node-based graph represents a node in the edge-based graph. In addition, we
// add a set of artificial edge-based nodes into the mix to model via-way turn restrictions. // add a set of artificial edge-based nodes into the mix to model via-way turn restrictions.
// See https://github.com/Project-OSRM/osrm-backend/issues/2681#issuecomment-313080353 for
// reference
std::uint64_t m_number_of_edge_based_nodes; std::uint64_t m_number_of_edge_based_nodes;
const std::vector<util::Coordinate> &m_coordinates; const std::vector<util::Coordinate> &m_coordinates;
@ -157,15 +159,21 @@ class EdgeBasedGraphFactory
unsigned RenumberEdges(); unsigned RenumberEdges();
// During the generation of the edge-expanded nodes, we need to also generate duplicates that
// represent state during via-way restrictions (see
// https://github.com/Project-OSRM/osrm-backend/issues/2681#issuecomment-313080353). Access to
// the information on what to duplicate and how is provided via the way_restriction_map
std::vector<NBGToEBG> GenerateEdgeExpandedNodes(const WayRestrictionMap &way_restriction_map); std::vector<NBGToEBG> GenerateEdgeExpandedNodes(const WayRestrictionMap &way_restriction_map);
// Edge-expanded edges are generate for all valid turns. The validity can be checked via the
// restriction maps
void GenerateEdgeExpandedEdges(ScriptingEnvironment &scripting_environment, void GenerateEdgeExpandedEdges(ScriptingEnvironment &scripting_environment,
const std::string &original_edge_data_filename, const std::string &original_edge_data_filename,
const std::string &turn_lane_data_filename, const std::string &turn_lane_data_filename,
const std::string &turn_weight_penalties_filename, const std::string &turn_weight_penalties_filename,
const std::string &turn_duration_penalties_filename, const std::string &turn_duration_penalties_filename,
const std::string &turn_penalties_index_filename, const std::string &turn_penalties_index_filename,
const RestrictionMap &restriction_map, const RestrictionMap &node_restriction_map,
const WayRestrictionMap &way_restriction_map); const WayRestrictionMap &way_restriction_map);
NBGToEBG InsertEdgeBasedNode(const NodeID u, const NodeID v); NBGToEBG InsertEdgeBasedNode(const NodeID u, const NodeID v);

View File

@ -51,7 +51,10 @@ class ExtractionContainers
unsigned max_internal_node_id; unsigned max_internal_node_id;
// list of restrictions before we transform them into the output types // list of restrictions before we transform them into the output types. Input containers
// reference OSMNodeIDs. We can only transform them to the correct internal IDs after we've read
// everything. Without a multi-parse approach, we have to remember the output restrictions
// before converting them to the internal formats
std::vector<InputConditionalTurnRestriction> restrictions_list; std::vector<InputConditionalTurnRestriction> restrictions_list;
// turn restrictions split into conditional and unconditional turn restrictions // turn restrictions split into conditional and unconditional turn restrictions

View File

@ -5,7 +5,7 @@
#include "util/opening_hours.hpp" #include "util/opening_hours.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include <boost/variant.hpp> #include "mapbox/variant.hpp"
#include <limits> #include <limits>
namespace osrm namespace osrm
@ -55,21 +55,21 @@ enum RestrictionType
struct InputTurnRestriction struct InputTurnRestriction
{ {
// keep in the same order as the turn restrictions below // keep in the same order as the turn restrictions below
boost::variant<InputNodeRestriction, InputWayRestriction> node_or_way; mapbox::util::variant<InputNodeRestriction, InputWayRestriction> node_or_way;
bool is_only; bool is_only;
OSMWayID From() const OSMWayID From() const
{ {
return node_or_way.which() == RestrictionType::NODE_RESTRICTION return node_or_way.which() == RestrictionType::NODE_RESTRICTION
? boost::get<InputNodeRestriction>(node_or_way).from ? mapbox::util::get<InputNodeRestriction>(node_or_way).from
: boost::get<InputWayRestriction>(node_or_way).from; : mapbox::util::get<InputWayRestriction>(node_or_way).from;
} }
OSMWayID To() const OSMWayID To() const
{ {
return node_or_way.which() == RestrictionType::NODE_RESTRICTION return node_or_way.which() == RestrictionType::NODE_RESTRICTION
? boost::get<InputNodeRestriction>(node_or_way).to ? mapbox::util::get<InputNodeRestriction>(node_or_way).to
: boost::get<InputWayRestriction>(node_or_way).to; : mapbox::util::get<InputWayRestriction>(node_or_way).to;
} }
RestrictionType Type() const RestrictionType Type() const
@ -81,25 +81,25 @@ struct InputTurnRestriction
InputWayRestriction &AsWayRestriction() InputWayRestriction &AsWayRestriction()
{ {
BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION); BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION);
return boost::get<InputWayRestriction>(node_or_way); return mapbox::util::get<InputWayRestriction>(node_or_way);
} }
const InputWayRestriction &AsWayRestriction() const const InputWayRestriction &AsWayRestriction() const
{ {
BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION); BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION);
return boost::get<InputWayRestriction>(node_or_way); return mapbox::util::get<InputWayRestriction>(node_or_way);
} }
InputNodeRestriction &AsNodeRestriction() InputNodeRestriction &AsNodeRestriction()
{ {
BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION); BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION);
return boost::get<InputNodeRestriction>(node_or_way); return mapbox::util::get<InputNodeRestriction>(node_or_way);
} }
const InputNodeRestriction &AsNodeRestriction() const const InputNodeRestriction &AsNodeRestriction() const
{ {
BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION); BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION);
return boost::get<InputNodeRestriction>(node_or_way); return mapbox::util::get<InputNodeRestriction>(node_or_way);
} }
}; };
struct InputConditionalTurnRestriction : InputTurnRestriction struct InputConditionalTurnRestriction : InputTurnRestriction
@ -121,12 +121,6 @@ struct NodeRestriction
return from != SPECIAL_NODEID && to != SPECIAL_NODEID && via != SPECIAL_NODEID; return from != SPECIAL_NODEID && to != SPECIAL_NODEID && via != SPECIAL_NODEID;
}; };
std::string ToString() const
{
return "From " + std::to_string(from) + " via " + std::to_string(via) + " to " +
std::to_string(to);
}
bool operator==(const NodeRestriction &other) const bool operator==(const NodeRestriction &other) const
{ {
return std::tie(from, via, to) == std::tie(other.from, other.via, other.to); return std::tie(from, via, to) == std::tie(other.from, other.via, other.to);
@ -168,7 +162,7 @@ struct WayRestriction
struct TurnRestriction struct TurnRestriction
{ {
// keep in the same order as the turn restrictions above // keep in the same order as the turn restrictions above
boost::variant<NodeRestriction, WayRestriction> node_or_way; mapbox::util::variant<NodeRestriction, WayRestriction> node_or_way;
bool is_only; bool is_only;
// construction for NodeRestrictions // construction for NodeRestrictions
@ -191,25 +185,25 @@ struct TurnRestriction
WayRestriction &AsWayRestriction() WayRestriction &AsWayRestriction()
{ {
BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION); BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION);
return boost::get<WayRestriction>(node_or_way); return mapbox::util::get<WayRestriction>(node_or_way);
} }
const WayRestriction &AsWayRestriction() const const WayRestriction &AsWayRestriction() const
{ {
BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION); BOOST_ASSERT(node_or_way.which() == RestrictionType::WAY_RESTRICTION);
return boost::get<WayRestriction>(node_or_way); return mapbox::util::get<WayRestriction>(node_or_way);
} }
NodeRestriction &AsNodeRestriction() NodeRestriction &AsNodeRestriction()
{ {
BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION); BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION);
return boost::get<NodeRestriction>(node_or_way); return mapbox::util::get<NodeRestriction>(node_or_way);
} }
const NodeRestriction &AsNodeRestriction() const const NodeRestriction &AsNodeRestriction() const
{ {
BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION); BOOST_ASSERT(node_or_way.which() == RestrictionType::NODE_RESTRICTION);
return boost::get<NodeRestriction>(node_or_way); return mapbox::util::get<NodeRestriction>(node_or_way);
} }
RestrictionType Type() const RestrictionType Type() const
@ -250,24 +244,6 @@ struct TurnRestriction
return AsNodeRestriction() == other.AsNodeRestriction(); return AsNodeRestriction() == other.AsNodeRestriction();
} }
} }
std::string ToString() const
{
std::string representation;
if (node_or_way.which() == RestrictionType::WAY_RESTRICTION)
{
auto const &way = AsWayRestriction();
representation =
"In: " + way.in_restriction.ToString() + " Out: " + way.out_restriction.ToString();
}
else
{
auto const &node = AsNodeRestriction();
representation = node.ToString();
}
representation += " is_only: " + std::to_string(is_only);
return representation;
}
}; };
struct ConditionalTurnRestriction : TurnRestriction struct ConditionalTurnRestriction : TurnRestriction

View File

@ -32,12 +32,12 @@ class RestrictionCompressor
void Compress(const NodeID from, const NodeID via, const NodeID to); void Compress(const NodeID from, const NodeID via, const NodeID to);
private: private:
// a turn restriction is given as `from head via node to tail`. Edges ending at `head` being // a turn restriction is given as `from star via node to end`. Edges ending at `head` being
// contracted move the head pointer to their respective head. Edges starting at tail move the // contracted move the head pointer to their respective head. Edges starting at tail move the
// tail values to their respective tails. Way turn restrictions are represented by two // tail values to their respective tails. Way turn restrictions are represented by two
// node-restrictions, so we can focus on them alone // node-restrictions, so we can focus on them alone
boost::unordered_multimap<NodeID, NodeRestriction *> heads; boost::unordered_multimap<NodeID, NodeRestriction *> starts;
boost::unordered_multimap<NodeID, NodeRestriction *> tails; boost::unordered_multimap<NodeID, NodeRestriction *> ends;
}; };
} // namespace extractor } // namespace extractor

View File

@ -186,18 +186,18 @@ inline void write(storage::io::FileWriter &writer, const TurnRestriction &restri
writer.WriteOne(restriction.is_only); writer.WriteOne(restriction.is_only);
if (restriction.Type() == RestrictionType::WAY_RESTRICTION) if (restriction.Type() == RestrictionType::WAY_RESTRICTION)
{ {
write(writer, boost::get<WayRestriction>(restriction.node_or_way)); write(writer, mapbox::util::get<WayRestriction>(restriction.node_or_way));
} }
else else
{ {
BOOST_ASSERT(restriction.Type() == RestrictionType::NODE_RESTRICTION); BOOST_ASSERT(restriction.Type() == RestrictionType::NODE_RESTRICTION);
write(writer, boost::get<NodeRestriction>(restriction.node_or_way)); write(writer, mapbox::util::get<NodeRestriction>(restriction.node_or_way));
} }
} }
inline void write(storage::io::FileWriter &writer, const ConditionalTurnRestriction &restriction) inline void write(storage::io::FileWriter &writer, const ConditionalTurnRestriction &restriction)
{ {
write(writer, static_cast<TurnRestriction>(restriction)); write(writer, static_cast<const TurnRestriction &>(restriction));
writer.WriteElementCount64(restriction.condition.size()); writer.WriteElementCount64(restriction.condition.size());
for (const auto &c : restriction.condition) for (const auto &c : restriction.condition)
{ {
@ -210,9 +210,7 @@ inline void write(storage::io::FileWriter &writer, const ConditionalTurnRestrict
inline void read(storage::io::FileReader &reader, ConditionalTurnRestriction &restriction) inline void read(storage::io::FileReader &reader, ConditionalTurnRestriction &restriction)
{ {
TurnRestriction base; read(reader, static_cast<TurnRestriction &>(restriction));
read(reader, base);
reinterpret_cast<TurnRestriction &>(restriction) = std::move(base);
const auto num_conditions = reader.ReadElementCount64(); const auto num_conditions = reader.ReadElementCount64();
restriction.condition.resize(num_conditions); restriction.condition.resize(num_conditions);
for (uint64_t i = 0; i < num_conditions; i++) for (uint64_t i = 0; i < num_conditions; i++)

View File

@ -23,30 +23,30 @@ class WayRestrictionMap
public: public:
struct ViaWay struct ViaWay
{ {
std::size_t id;
NodeID from; NodeID from;
NodeID to; NodeID to;
}; };
WayRestrictionMap(const std::vector<TurnRestriction> &turn_restrictions); WayRestrictionMap(const std::vector<TurnRestriction> &turn_restrictions);
// check if an edge between two nodes is a restricted turn. The check needs to be performed // Check if an edge between two nodes is a restricted turn. The check needs to be performed to
// find duplicated nodes during the creation of edge-based-edges
bool IsViaWay(const NodeID from, const NodeID to) const; bool IsViaWay(const NodeID from, const NodeID to) const;
// number of duplicated nodes // Every via-way results in a duplicated node that is required in the edge-based-graph. This
// count is essentially the same as the number of valid via-way restrictions (except for
// non-only restrictions that share the same in/via combination)
std::size_t NumberOfDuplicatedNodes() const; std::size_t NumberOfDuplicatedNodes() const;
// returns a representative for the duplicated way, consisting of the representative ID (first // Returns a representative for each duplicated node, consisting of the representative ID (first
// ID of the nodes restrictions) and the from/to vertices of the via-way // ID of the nodes restrictions) and the from/to vertices of the via-way
// This is used to construct edge based nodes that act as intermediate nodes. // This is used to construct edge based nodes that act as intermediate nodes.
std::vector<ViaWay> DuplicatedNodeRepresentatives() const; std::vector<ViaWay> DuplicatedNodeRepresentatives() const;
// Access all duplicated NodeIDs for a set of nodes indicating a via way // Access all duplicated NodeIDs for a set of nodes indicating a via way
util::range<std::size_t> DuplicatedNodeIDs(const NodeID from, const NodeID to) const; util::range<DuplicatedNodeID> DuplicatedNodeIDs(const NodeID from, const NodeID to) const;
// check whether a turn onto a given node is restricted, when coming from a duplicated node // check whether a turn onto a given node is restricted, when coming from a duplicated node
bool IsRestricted(std::size_t duplicated_node, const NodeID to) const; bool IsRestricted(DuplicatedNodeID duplicated_node, const NodeID to) const;
TurnRestriction const &GetRestriction(std::size_t) const;
// changes edge_based_node to the correct duplicated_node_id in case node_based_from, // changes edge_based_node to the correct duplicated_node_id in case node_based_from,
// node_based_via, node_based_to can be identified with a restriction group // node_based_via, node_based_to can be identified with a restriction group
@ -57,7 +57,7 @@ class WayRestrictionMap
const NodeID number_of_edge_based_nodes) const; const NodeID number_of_edge_based_nodes) const;
private: private:
std::size_t AsDuplicatedNodeID(const std::size_t restriction_id) const; DuplicatedNodeID AsDuplicatedNodeID(const RestrictionID restriction_id) const;
// access all restrictions that have the same starting way and via way. Any duplicated node // access all restrictions that have the same starting way and via way. Any duplicated node
// represents the same in-way + via-way combination. This vector contains data about all // represents the same in-way + via-way combination. This vector contains data about all
@ -75,10 +75,10 @@ class WayRestrictionMap
// //
// EBN: 0 . | 2 | 3 | 4 ... // EBN: 0 . | 2 | 3 | 4 ...
// duplicated node groups: ... | 5 | 7 | ... // duplicated node groups: ... | 5 | 7 | ...
std::vector<std::size_t> duplicated_node_groups; std::vector<DuplicatedNodeID> duplicated_node_groups;
boost::unordered_multimap<std::pair<NodeID, NodeID>, std::size_t> restriction_starts; boost::unordered_multimap<std::pair<NodeID, NodeID>, RestrictionID> restriction_starts;
boost::unordered_multimap<std::pair<NodeID, NodeID>, std::size_t> restriction_ends; boost::unordered_multimap<std::pair<NodeID, NodeID>, RestrictionID> restriction_ends;
std::vector<TurnRestriction> restriction_data; std::vector<TurnRestriction> restriction_data;
}; };

View File

@ -45,12 +45,18 @@ struct osm_node_id
struct osm_way_id struct osm_way_id
{ {
}; };
struct duplicated_node
{
};
} }
using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>; using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>;
static_assert(std::is_pod<OSMNodeID>(), "OSMNodeID is not a valid alias"); static_assert(std::is_pod<OSMNodeID>(), "OSMNodeID is not a valid alias");
using OSMWayID = osrm::Alias<std::uint64_t, tag::osm_way_id>; using OSMWayID = osrm::Alias<std::uint64_t, tag::osm_way_id>;
static_assert(std::is_pod<OSMWayID>(), "OSMWayID is not a valid alias"); static_assert(std::is_pod<OSMWayID>(), "OSMWayID is not a valid alias");
using DuplicatedNodeID = std::uint64_t;
using RestrictionID = std::uint64_t;
static const OSMNodeID SPECIAL_OSM_NODEID = static const OSMNodeID SPECIAL_OSM_NODEID =
OSMNodeID{std::numeric_limits<OSMNodeID::value_type>::max()}; OSMNodeID{std::numeric_limits<OSMNodeID::value_type>::max()};
static const OSMWayID SPECIAL_OSM_WAYID = static const OSMWayID SPECIAL_OSM_WAYID =

View File

@ -194,7 +194,7 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment,
const std::string &turn_duration_penalties_filename, const std::string &turn_duration_penalties_filename,
const std::string &turn_penalties_index_filename, const std::string &turn_penalties_index_filename,
const std::string &cnbg_ebg_mapping_path, const std::string &cnbg_ebg_mapping_path,
const RestrictionMap &restriction_map, const RestrictionMap &node_restriction_map,
const WayRestrictionMap &way_restriction_map) const WayRestrictionMap &way_restriction_map)
{ {
TIMER_START(renumber); TIMER_START(renumber);
@ -215,7 +215,7 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment,
turn_weight_penalties_filename, turn_weight_penalties_filename,
turn_duration_penalties_filename, turn_duration_penalties_filename,
turn_penalties_index_filename, turn_penalties_index_filename,
restriction_map, node_restriction_map,
way_restriction_map); way_restriction_map);
TIMER_STOP(generate_edges); TIMER_STOP(generate_edges);
@ -228,7 +228,7 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment,
/// Renumbers all _forward_ edges and sets the edge_id. /// Renumbers all _forward_ edges and sets the edge_id.
/// A specific numbering is not important. Any unique ID will do. /// A specific numbering is not important. Any unique ID will do.
/// Returns the number of edge based nodes. /// Returns the number of edge-based nodes.
unsigned EdgeBasedGraphFactory::RenumberEdges() unsigned EdgeBasedGraphFactory::RenumberEdges()
{ {
// heuristic: node-based graph node is a simple intersection with four edges (edge-based nodes) // heuristic: node-based graph node is a simple intersection with four edges (edge-based nodes)
@ -363,8 +363,10 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
BOOST_ASSERT(m_edge_based_node_segments.size() == m_edge_based_node_is_startpoint.size()); BOOST_ASSERT(m_edge_based_node_segments.size() == m_edge_based_node_is_startpoint.size());
BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_weights.size()); BOOST_ASSERT(m_number_of_edge_based_nodes == m_edge_based_node_weights.size());
util::Log() << "Generated " << m_number_of_edge_based_nodes << " nodes and " util::Log() << "Generated " << m_number_of_edge_based_nodes << " nodes ("
<< m_edge_based_node_segments.size() << " segments in edge-expanded graph"; << way_restriction_map.NumberOfDuplicatedNodes()
<< " of which are duplicates) and " << m_edge_based_node_segments.size()
<< " segments in edge-expanded graph";
return mapping; return mapping;
} }
@ -377,7 +379,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const std::string &turn_weight_penalties_filename, const std::string &turn_weight_penalties_filename,
const std::string &turn_duration_penalties_filename, const std::string &turn_duration_penalties_filename,
const std::string &turn_penalties_index_filename, const std::string &turn_penalties_index_filename,
const RestrictionMap &restriction_map, const RestrictionMap &node_restriction_map,
const WayRestrictionMap &way_restriction_map) const WayRestrictionMap &way_restriction_map)
{ {
@ -399,7 +401,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
SuffixTable street_name_suffix_table(scripting_environment); SuffixTable street_name_suffix_table(scripting_environment);
guidance::TurnAnalysis turn_analysis(*m_node_based_graph, guidance::TurnAnalysis turn_analysis(*m_node_based_graph,
m_coordinates, m_coordinates,
restriction_map, node_restriction_map,
m_barrier_nodes, m_barrier_nodes,
m_compressed_edge_container, m_compressed_edge_container,
name_table, name_table,
@ -492,24 +494,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
std::vector<EdgeWithData> delayed_data; std::vector<EdgeWithData> delayed_data;
}; };
// add into delayed data
const auto delayed_inserter = [](const auto &edge_with_data, auto &buffer) {
buffer.delayed_data.push_back(edge_with_data);
};
// add into main data
const auto continuous_inserter = [](const auto &edge_with_data, auto &buffer) {
buffer.continuous_data.edges_list.push_back(edge_with_data.edge);
buffer.continuous_data.turn_indexes.push_back(edge_with_data.turn_index);
buffer.continuous_data.turn_weight_penalties.push_back(
edge_with_data.turn_weight_penalty);
buffer.continuous_data.turn_duration_penalties.push_back(
edge_with_data.turn_duration_penalty);
buffer.continuous_data.turn_data_container.push_back(edge_with_data.turn_data);
};
// Generate edges for either artificial nodes or the main graph // Generate edges for either artificial nodes or the main graph
const auto generate_edges = [this, &scripting_environment, weight_multiplier]( const auto generate_edge = [this, &scripting_environment, weight_multiplier](
// what nodes will be used? In most cases this will be the id stored in the edge_data. // what nodes will be used? In most cases this will be the id stored in the edge_data.
// In case of duplicated nodes (e.g. due to via-way restrictions), one/both of these // In case of duplicated nodes (e.g. due to via-way restrictions), one/both of these
// might refer to a newly added edge based node // might refer to a newly added edge based node
@ -522,11 +508,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const auto node_based_edge_to, const auto node_based_edge_to,
const auto &intersection, const auto &intersection,
const auto &turn, const auto &turn,
const auto entry_class_id, const auto entry_class_id) {
// we require a sorted output, additional nodes are collected and added after the
// sorting is done Here we can specify how/where to add the data
auto inserter,
auto &output_buffer) {
const EdgeData &edge_data1 = m_node_based_graph->GetEdgeData(node_based_edge_from); const EdgeData &edge_data1 = m_node_based_graph->GetEdgeData(node_based_edge_from);
const EdgeData &edge_data2 = m_node_based_graph->GetEdgeData(node_based_edge_to); const EdgeData &edge_data2 = m_node_based_graph->GetEdgeData(node_based_edge_to);
@ -593,11 +575,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
lookup::TurnIndexBlock turn_index_block = {from_node, via_node, to_node}; lookup::TurnIndexBlock turn_index_block = {from_node, via_node, to_node};
// insert data into the designated buffer // insert data into the designated buffer
inserter( return EdgeWithData{
EdgeWithData{ edge_based_edge, turn_index_block, weight_penalty, duration_penalty, turn_data};
edge_based_edge, turn_index_block, weight_penalty, duration_penalty, turn_data},
output_buffer);
}; };
// Second part of the pipeline is where the intersection analysis is done for // Second part of the pipeline is where the intersection analysis is done for
@ -735,7 +714,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
m_node_based_graph->GetTarget(turn.eid), m_node_based_graph->GetTarget(turn.eid),
m_number_of_edge_based_nodes); m_number_of_edge_based_nodes);
generate_edges(edge_data1.edge_id, { // scope to forget edge_with_data after
const auto edge_with_data =
generate_edge(edge_data1.edge_id,
target_id, target_id,
node_along_road_entering, node_along_road_entering,
incoming_edge, incoming_edge,
@ -743,9 +724,18 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
turn.eid, turn.eid,
intersection, intersection,
turn, turn,
entry_class_id, entry_class_id);
continuous_inserter,
*buffer); buffer->continuous_data.edges_list.push_back(edge_with_data.edge);
buffer->continuous_data.turn_indexes.push_back(
edge_with_data.turn_index);
buffer->continuous_data.turn_weight_penalties.push_back(
edge_with_data.turn_weight_penalty);
buffer->continuous_data.turn_duration_penalties.push_back(
edge_with_data.turn_duration_penalty);
buffer->continuous_data.turn_data_container.push_back(
edge_with_data.turn_data);
}
// when turning off a a via-way turn restriction, we need to not only // when turning off a a via-way turn restriction, we need to not only
// handle the normal edges for the way, but also add turns for every // handle the normal edges for the way, but also add turns for every
@ -775,7 +765,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
if (is_restricted) if (is_restricted)
return; return;
generate_edges( // add into delayed data
auto edge_with_data = generate_edge(
NodeID(from_id), NodeID(from_id),
m_node_based_graph->GetEdgeData(turn.eid).edge_id, m_node_based_graph->GetEdgeData(turn.eid).edge_id,
node_along_road_entering, node_along_road_entering,
@ -784,10 +775,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
turn.eid, turn.eid,
intersection, intersection,
turn, turn,
entry_class_id, entry_class_id);
delayed_inserter,
*buffer);
buffer->delayed_data.push_back(std::move(edge_with_data));
}; };
std::for_each(duplicated_nodes.begin(), std::for_each(duplicated_nodes.begin(),
@ -812,7 +802,14 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
std::vector<EdgeWithData> delayed_data; std::vector<EdgeWithData> delayed_data;
auto const append_data_to_output = [&](IntersectionData const &data) { // Last part of the pipeline puts all the calculated data into the serial buffers
tbb::filter_t<std::shared_ptr<PipelineBuffer>, void> output_stage(
tbb::filter::serial_in_order, [&](const std::shared_ptr<PipelineBuffer> buffer) {
nodes_completed += buffer->nodes_processed;
progress.PrintStatus(nodes_completed);
// for readability
const auto &data = buffer->continuous_data;
// NOTE: potential overflow here if we hit 2^32 routable edges // NOTE: potential overflow here if we hit 2^32 routable edges
m_edge_based_edge_list.append(data.edges_list.begin(), data.edges_list.end()); m_edge_based_edge_list.append(data.edges_list.begin(), data.edges_list.end());
@ -836,14 +833,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
turn_indexes_write_buffer.size()); turn_indexes_write_buffer.size());
turn_indexes_write_buffer.clear(); turn_indexes_write_buffer.clear();
} }
};
// Last part of the pipeline puts all the calculated data into the serial buffers
tbb::filter_t<std::shared_ptr<PipelineBuffer>, void> output_stage(
tbb::filter::serial_in_order, [&](const std::shared_ptr<PipelineBuffer> buffer) {
nodes_completed += buffer->nodes_processed;
progress.PrintStatus(nodes_completed);
append_data_to_output(buffer->continuous_data);
delayed_data.insert( delayed_data.insert(
delayed_data.end(), buffer->delayed_data.begin(), buffer->delayed_data.end()); delayed_data.end(), buffer->delayed_data.begin(), buffer->delayed_data.end());
}); });
@ -927,7 +917,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
util::Log() << " contains " << m_edge_based_edge_list.size() << " edges"; util::Log() << " contains " << m_edge_based_edge_list.size() << " edges";
util::Log() << " skips " << restricted_turns_counter << " turns, " util::Log() << " skips " << restricted_turns_counter << " turns, "
"defined by " "defined by "
<< restriction_map.size() << " restrictions"; << node_restriction_map.size() << " restrictions";
util::Log() << " skips " << skipped_uturns_counter << " U turns"; util::Log() << " skips " << skipped_uturns_counter << " U turns";
util::Log() << " skips " << skipped_barrier_turns_counter << " turns over barriers"; util::Log() << " skips " << skipped_barrier_turns_counter << " turns over barriers";
} }

View File

@ -660,8 +660,13 @@ void ExtractionContainers::PrepareRestrictions()
// contain the start/end nodes of each way that is part of an restriction // contain the start/end nodes of each way that is part of an restriction
std::unordered_map<OSMWayID, FirstAndLastSegmentOfWay> referenced_ways; std::unordered_map<OSMWayID, FirstAndLastSegmentOfWay> referenced_ways;
// enter invalid IDs into the above maps to indicate that we want to find out about start/end // prepare for extracting source/destination nodes for all restrictions
// nodes of these ways {
util::UnbufferedLog log;
log << "Collecting start/end information on " << restrictions_list.size()
<< " restrictions...";
TIMER_START(prepare_restrictions);
const auto mark_ids = [&](auto const &turn_restriction) { const auto mark_ids = [&](auto const &turn_restriction) {
FirstAndLastSegmentOfWay dummy_segment{ FirstAndLastSegmentOfWay dummy_segment{
MAX_OSM_WAYID, MAX_OSM_NODEID, MAX_OSM_NODEID, MAX_OSM_NODEID, MAX_OSM_NODEID}; MAX_OSM_WAYID, MAX_OSM_NODEID, MAX_OSM_NODEID, MAX_OSM_NODEID, MAX_OSM_NODEID};
@ -681,6 +686,11 @@ void ExtractionContainers::PrepareRestrictions()
} }
}; };
std::for_each(restrictions_list.begin(), restrictions_list.end(), mark_ids);
// enter invalid IDs into the above maps to indicate that we want to find out about
// start/end
// nodes of these ways
// update the values for all edges already sporting SPECIAL_NODEID // update the values for all edges already sporting SPECIAL_NODEID
const auto set_ids = [&](auto const &start_end) { const auto set_ids = [&](auto const &start_end) {
auto itr = referenced_ways.find(start_end.way_id); auto itr = referenced_ways.find(start_end.way_id);
@ -688,13 +698,6 @@ void ExtractionContainers::PrepareRestrictions()
itr->second = start_end; itr->second = start_end;
}; };
// prepare for extracting source/destination nodes for all restrictions
{
util::UnbufferedLog log;
log << "Collecting start/end information on " << restrictions_list.size()
<< " restrictions...";
TIMER_START(prepare_restrictions);
std::for_each(restrictions_list.begin(), restrictions_list.end(), mark_ids);
std::for_each(way_start_end_id_list.cbegin(), way_start_end_id_list.cend(), set_ids); std::for_each(way_start_end_id_list.cbegin(), way_start_end_id_list.cend(), set_ids);
TIMER_STOP(prepare_restrictions); TIMER_STOP(prepare_restrictions);
log << "ok, after " << TIMER_SEC(prepare_restrictions) << "s"; log << "ok, after " << TIMER_SEC(prepare_restrictions) << "s";
@ -710,8 +713,6 @@ void ExtractionContainers::PrepareRestrictions()
return internal; return internal;
}; };
// Given:
// a -- b - ????????? - c -- d
// Given // Given
// a -- b - ????????? - c -- d as via segment // a -- b - ????????? - c -- d as via segment
// and either // and either
@ -720,6 +721,8 @@ void ExtractionContainers::PrepareRestrictions()
// (d,e) or (j,a) as entry-segment // (d,e) or (j,a) as entry-segment
auto const find_node_restriction = auto const find_node_restriction =
[&](auto const &segment, auto const &via_segment, auto const via_node) { [&](auto const &segment, auto const &via_segment, auto const via_node) {
// In case of way-restrictions, via-node will be set to MAX_OSM_NODEID to signal that
// the node is not present.
// connected at the front of the segment // connected at the front of the segment
if (via_node == MAX_OSM_NODEID || segment.first_segment_source_id == via_node) if (via_node == MAX_OSM_NODEID || segment.first_segment_source_id == via_node)
{ {
@ -779,8 +782,10 @@ void ExtractionContainers::PrepareRestrictions()
return find_node_restriction(from_segment_itr->second, to_segment_itr->second, via_node); return find_node_restriction(from_segment_itr->second, to_segment_itr->second, via_node);
}; };
// transform an OSMRestriction (based on WayIDs) into an OSRM restriction (base on NodeIDs) // Transform an OSMRestriction (based on WayIDs) into an OSRM restriction (base on NodeIDs).
// returns true on successful transformation, false in case of invalid references // Returns true on successful transformation, false in case of invalid references.
// Based on the auto type deduction, this transfor handles both conditional and unconditional
// turn restrictions.
const auto transform = [&](const auto &external_type, auto &internal_type) { const auto transform = [&](const auto &external_type, auto &internal_type) {
if (external_type.Type() == RestrictionType::WAY_RESTRICTION) if (external_type.Type() == RestrictionType::WAY_RESTRICTION)
{ {
@ -837,7 +842,7 @@ void ExtractionContainers::PrepareRestrictions()
TurnRestriction restriction; TurnRestriction restriction;
restriction.is_only = external_restriction.is_only; restriction.is_only = external_restriction.is_only;
if (transform(external_restriction, restriction)) if (transform(external_restriction, restriction))
unconditional_turn_restrictions.push_back(restriction); unconditional_turn_restrictions.push_back(std::move(restriction));
} }
// conditional turn restriction // conditional turn restriction
else else
@ -846,7 +851,7 @@ void ExtractionContainers::PrepareRestrictions()
restriction.is_only = external_restriction.is_only; restriction.is_only = external_restriction.is_only;
restriction.condition = std::move(external_restriction.condition); restriction.condition = std::move(external_restriction.condition);
if (transform(external_restriction, restriction)) if (transform(external_restriction, restriction))
conditional_turn_restrictions.push_back(restriction); conditional_turn_restrictions.push_back(std::move(restriction));
} }
}; };

View File

@ -12,13 +12,13 @@ namespace extractor
RestrictionCompressor::RestrictionCompressor(std::vector<TurnRestriction> &restrictions) RestrictionCompressor::RestrictionCompressor(std::vector<TurnRestriction> &restrictions)
{ {
// add a node restriction ptr to the heads/tails maps, needs to be a reference! // add a node restriction ptr to the starts/ends maps, needs to be a reference!
auto index = [&](auto &element) { auto index = [&](auto &element) {
heads.insert(std::make_pair(element.from, &element)); starts.insert(std::make_pair(element.from, &element));
tails.insert(std::make_pair(element.to, &element)); ends.insert(std::make_pair(element.to, &element));
}; };
// !needs to be reference, so we can get the correct address // !needs to be reference, so we can get the correct address
const auto index_heads_and_tails = [&](auto &restriction) { const auto index_starts_and_ends = [&](auto &restriction) {
if (restriction.Type() == RestrictionType::WAY_RESTRICTION) if (restriction.Type() == RestrictionType::WAY_RESTRICTION)
{ {
auto &way_restriction = restriction.AsWayRestriction(); auto &way_restriction = restriction.AsWayRestriction();
@ -33,21 +33,21 @@ RestrictionCompressor::RestrictionCompressor(std::vector<TurnRestriction> &restr
} }
}; };
// add all restrictions as their respective head-tail pointers // add all restrictions as their respective startend pointers
std::for_each(restrictions.begin(), restrictions.end(), index_heads_and_tails); std::for_each(restrictions.begin(), restrictions.end(), index_starts_and_ends);
} }
void RestrictionCompressor::Compress(const NodeID from, const NodeID via, const NodeID to) void RestrictionCompressor::Compress(const NodeID from, const NodeID via, const NodeID to)
{ {
const auto get_value = [](const auto pair) { return pair.second; }; // extract all startptrs and move them from via to from.
auto all_starts_range = starts.equal_range(via);
std::vector<NodeRestriction *> start_ptrs;
std::transform(all_starts_range.first,
all_starts_range.second,
std::back_inserter(start_ptrs),
[](const auto pair) { return pair.second; });
// extract all head ptrs and move them from via to from. const auto update_start = [&](auto ptr) {
auto all_heads_range = heads.equal_range(via);
std::vector<NodeRestriction *> head_ptrs;
std::transform(
all_heads_range.first, all_heads_range.second, std::back_inserter(head_ptrs), get_value);
const auto update_head = [&](auto ptr) {
// ____ | from - p.from | via - p.via | to - p.to | ____ // ____ | from - p.from | via - p.via | to - p.to | ____
BOOST_ASSERT(ptr->from == via); BOOST_ASSERT(ptr->from == via);
if (ptr->via == to) if (ptr->via == to)
@ -62,21 +62,23 @@ void RestrictionCompressor::Compress(const NodeID from, const NodeID via, const
} }
}; };
std::for_each(head_ptrs.begin(), head_ptrs.end(), update_head); std::for_each(start_ptrs.begin(), start_ptrs.end(), update_start);
const auto reinsert_head = [&](auto ptr) { heads.insert(std::make_pair(ptr->from, ptr)); };
// update the ptrs in our mapping // update the ptrs in our mapping
heads.erase(via); starts.erase(via);
std::for_each(head_ptrs.begin(), head_ptrs.end(), reinsert_head);
// extract all tail ptrs and move them from via to to const auto reinsert_start = [&](auto ptr) { starts.insert(std::make_pair(ptr->from, ptr)); };
auto all_tails_range = tails.equal_range(via); std::for_each(start_ptrs.begin(), start_ptrs.end(), reinsert_start);
std::vector<NodeRestriction *> tail_ptrs;
std::transform(
all_tails_range.first, all_tails_range.second, std::back_inserter(tail_ptrs), get_value);
const auto update_tail = [&](auto ptr) { // extract all end ptrs and move them from via to to
auto all_ends_range = ends.equal_range(via);
std::vector<NodeRestriction *> end_ptrs;
std::transform(all_ends_range.first,
all_ends_range.second,
std::back_inserter(end_ptrs),
[](const auto pair) { return pair.second; });
const auto update_end = [&](auto ptr) {
BOOST_ASSERT(ptr->to == via); BOOST_ASSERT(ptr->to == via);
// p.from | ____ - p.via | from - p.to | via - ____ | to // p.from | ____ - p.via | from - p.to | via - ____ | to
if (ptr->via == from) if (ptr->via == from)
@ -90,14 +92,13 @@ void RestrictionCompressor::Compress(const NodeID from, const NodeID via, const
ptr->to = from; ptr->to = from;
} }
}; };
std::for_each(end_ptrs.begin(), end_ptrs.end(), update_end);
const auto reinsert_tail = [&](auto ptr) { tails.insert(std::make_pair(ptr->to, ptr)); }; // update end ptrs in mapping
ends.erase(via);
std::for_each(tail_ptrs.begin(), tail_ptrs.end(), update_tail); const auto reinsert_end = [&](auto ptr) { ends.insert(std::make_pair(ptr->to, ptr)); };
std::for_each(end_ptrs.begin(), end_ptrs.end(), reinsert_end);
// update tail ptrs in mapping
tails.erase(via);
std::for_each(tail_ptrs.begin(), tail_ptrs.end(), reinsert_tail);
} }
} // namespace extractor } // namespace extractor

View File

@ -78,8 +78,9 @@ removeInvalidRestrictions(std::vector<TurnRestriction> restrictions,
} }
}; };
restrictions.erase(std::remove_if(restrictions.begin(), restrictions.end(), is_invalid), const auto end_valid_restrictions =
restrictions.end()); std::remove_if(restrictions.begin(), restrictions.end(), is_invalid);
restrictions.erase(end_valid_restrictions, restrictions.end());
return restrictions; return restrictions;
} }

View File

@ -1,4 +1,5 @@
#include "extractor/way_restriction_map.hpp" #include "extractor/way_restriction_map.hpp"
#include "util/for_each_pair.hpp"
#include <iterator> #include <iterator>
#include <tuple> #include <tuple>
@ -45,12 +46,10 @@ WayRestrictionMap::WayRestrictionMap(const std::vector<TurnRestriction> &turn_re
}; };
std::for_each(turn_restrictions.begin(), turn_restrictions.end(), extract_restrictions); std::for_each(turn_restrictions.begin(), turn_restrictions.end(), extract_restrictions);
const auto as_duplicated_node = const auto as_duplicated_node = [](auto const &restriction) {
[](auto const &restriction) -> std::tuple<NodeID, NodeID, NodeID> {
auto &way = restriction.AsWayRestriction(); auto &way = restriction.AsWayRestriction();
// group restrictions by the via-way. On same via-ways group by from // group restrictions by the via-way. On same via-ways group by from
return std::make_tuple( return std::tie(way.in_restriction.via, way.out_restriction.via, way.in_restriction.from);
way.in_restriction.via, way.out_restriction.via, way.in_restriction.from);
}; };
const auto by_duplicated_node = [&](auto const &lhs, auto const &rhs) { const auto by_duplicated_node = [&](auto const &lhs, auto const &rhs) {
@ -59,16 +58,14 @@ WayRestrictionMap::WayRestrictionMap(const std::vector<TurnRestriction> &turn_re
std::sort(restriction_data.begin(), restriction_data.end(), by_duplicated_node); std::sort(restriction_data.begin(), restriction_data.end(), by_duplicated_node);
std::size_t index = 0, duplication_id = 0;
// map all way restrictions into access containers // map all way restrictions into access containers
const auto prepare_way_restriction = [this, &index, &duplication_id, as_duplicated_node]( for (RestrictionID index = 0; index < restriction_data.size(); ++index)
const auto &restriction) { {
const auto &restriction = restriction_data[index];
const auto &way = restriction.AsWayRestriction(); const auto &way = restriction.AsWayRestriction();
restriction_starts.insert( restriction_starts.insert(
std::make_pair(std::make_pair(way.in_restriction.from, way.in_restriction.via), index)); std::make_pair(std::make_pair(way.in_restriction.from, way.in_restriction.via), index));
++index;
}; };
std::for_each(restriction_data.begin(), restriction_data.end(), prepare_way_restriction);
std::size_t offset = 1; std::size_t offset = 1;
// the first group starts at 0 // the first group starts at 0
@ -81,9 +78,8 @@ WayRestrictionMap::WayRestrictionMap(const std::vector<TurnRestriction> &turn_re
if (as_duplicated_node(lhs) != as_duplicated_node(rhs)) if (as_duplicated_node(lhs) != as_duplicated_node(rhs))
duplicated_node_groups.push_back(offset); duplicated_node_groups.push_back(offset);
++offset; ++offset;
return false; // continue until the end
}; };
std::adjacent_find(restriction_data.begin(), restriction_data.end(), add_offset_on_new_groups); util::for_each_pair(restriction_data.begin(), restriction_data.end(), add_offset_on_new_groups);
duplicated_node_groups.push_back(restriction_data.size()); duplicated_node_groups.push_back(restriction_data.size());
} }
@ -110,16 +106,16 @@ bool WayRestrictionMap::IsViaWay(const NodeID from, const NodeID to) const
return way.out_restriction.from == from && way.out_restriction.via == to; return way.out_restriction.from == from && way.out_restriction.via == to;
} }
std::size_t WayRestrictionMap::AsDuplicatedNodeID(const std::size_t restriction_id) const DuplicatedNodeID WayRestrictionMap::AsDuplicatedNodeID(const RestrictionID restriction_id) const
{ {
return std::distance(duplicated_node_groups.begin(), const auto upper_bound_restriction = std::upper_bound(
std::upper_bound(duplicated_node_groups.begin(), duplicated_node_groups.begin(), duplicated_node_groups.end(), restriction_id);
duplicated_node_groups.end(), const auto distance_to_upper_bound =
restriction_id)) - std::distance(duplicated_node_groups.begin(), upper_bound_restriction);
1; return distance_to_upper_bound - 1;
} }
util::range<std::size_t> WayRestrictionMap::DuplicatedNodeIDs(const NodeID from, util::range<DuplicatedNodeID> WayRestrictionMap::DuplicatedNodeIDs(const NodeID from,
const NodeID to) const const NodeID to) const
{ {
const auto duplicated_node_range_itr = std::equal_range( const auto duplicated_node_range_itr = std::equal_range(
@ -129,16 +125,16 @@ util::range<std::size_t> WayRestrictionMap::DuplicatedNodeIDs(const NodeID from,
return std::distance(restriction_data.begin(), itr); return std::distance(restriction_data.begin(), itr);
}; };
return util::irange<std::size_t>( return util::irange<DuplicatedNodeID>(
AsDuplicatedNodeID(as_restriction_id(duplicated_node_range_itr.first)), AsDuplicatedNodeID(as_restriction_id(duplicated_node_range_itr.first)),
AsDuplicatedNodeID(as_restriction_id(duplicated_node_range_itr.second))); AsDuplicatedNodeID(as_restriction_id(duplicated_node_range_itr.second)));
} }
bool WayRestrictionMap::IsRestricted(std::size_t duplicated_node, const NodeID to) const bool WayRestrictionMap::IsRestricted(DuplicatedNodeID duplicated_node, const NodeID to) const
{ {
// loop over all restrictions associated with the node. Mark as restricted based on // loop over all restrictions associated with the node. Mark as restricted based on
// is_only/restricted targets // is_only/restricted targets
for (std::size_t restriction_index = duplicated_node_groups[duplicated_node]; for (RestrictionID restriction_index = duplicated_node_groups[duplicated_node];
restriction_index != duplicated_node_groups[duplicated_node + 1]; restriction_index != duplicated_node_groups[duplicated_node + 1];
++restriction_index) ++restriction_index)
{ {
@ -153,11 +149,6 @@ bool WayRestrictionMap::IsRestricted(std::size_t duplicated_node, const NodeID t
return false; return false;
} }
TurnRestriction const &WayRestrictionMap::GetRestriction(const std::size_t id) const
{
return restriction_data[id];
}
std::vector<WayRestrictionMap::ViaWay> WayRestrictionMap::DuplicatedNodeRepresentatives() const std::vector<WayRestrictionMap::ViaWay> WayRestrictionMap::DuplicatedNodeRepresentatives() const
{ {
std::vector<ViaWay> result; std::vector<ViaWay> result;
@ -167,7 +158,7 @@ std::vector<WayRestrictionMap::ViaWay> WayRestrictionMap::DuplicatedNodeRepresen
std::back_inserter(result), std::back_inserter(result),
[&](auto const representative_id) -> ViaWay { [&](auto const representative_id) -> ViaWay {
auto &way = restriction_data[representative_id].AsWayRestriction(); auto &way = restriction_data[representative_id].AsWayRestriction();
return {representative_id, way.in_restriction.via, way.out_restriction.via}; return {way.in_restriction.via, way.out_restriction.via};
}); });
return result; return result;
} }