restructure for review remarks
This commit is contained in:
parent
645b1ffd75
commit
8135f08958
@ -16,7 +16,10 @@
|
||||
- Profiles must return a hash of profile functions. This makes it easier for profiles to include each other.
|
||||
- Guidance: add support for throughabouts
|
||||
- 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
|
||||
- API:
|
||||
|
@ -639,6 +639,8 @@ Feature: Car - Turn restrictions
|
||||
| | \ /
|
||||
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
|
||||
| nodes | oneway |
|
||||
|
@ -92,7 +92,7 @@ class EdgeBasedGraphFactory
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &cnbg_ebg_mapping_path,
|
||||
const RestrictionMap &restriction_map,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map);
|
||||
|
||||
// The following get access functions destroy the content in the factory
|
||||
@ -137,9 +137,11 @@ class EdgeBasedGraphFactory
|
||||
EdgeBasedNodeDataContainer m_edge_based_node_container;
|
||||
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
|
||||
// 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;
|
||||
|
||||
const std::vector<util::Coordinate> &m_coordinates;
|
||||
@ -157,15 +159,21 @@ class EdgeBasedGraphFactory
|
||||
|
||||
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);
|
||||
|
||||
// Edge-expanded edges are generate for all valid turns. The validity can be checked via the
|
||||
// restriction maps
|
||||
void GenerateEdgeExpandedEdges(ScriptingEnvironment &scripting_environment,
|
||||
const std::string &original_edge_data_filename,
|
||||
const std::string &turn_lane_data_filename,
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const RestrictionMap &restriction_map,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map);
|
||||
|
||||
NBGToEBG InsertEdgeBasedNode(const NodeID u, const NodeID v);
|
||||
|
@ -51,7 +51,10 @@ class ExtractionContainers
|
||||
|
||||
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;
|
||||
|
||||
// turn restrictions split into conditional and unconditional turn restrictions
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "util/opening_hours.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include "mapbox/variant.hpp"
|
||||
#include <limits>
|
||||
|
||||
namespace osrm
|
||||
@ -55,21 +55,21 @@ enum RestrictionType
|
||||
struct InputTurnRestriction
|
||||
{
|
||||
// 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;
|
||||
|
||||
OSMWayID From() const
|
||||
{
|
||||
return node_or_way.which() == RestrictionType::NODE_RESTRICTION
|
||||
? boost::get<InputNodeRestriction>(node_or_way).from
|
||||
: boost::get<InputWayRestriction>(node_or_way).from;
|
||||
? mapbox::util::get<InputNodeRestriction>(node_or_way).from
|
||||
: mapbox::util::get<InputWayRestriction>(node_or_way).from;
|
||||
}
|
||||
|
||||
OSMWayID To() const
|
||||
{
|
||||
return node_or_way.which() == RestrictionType::NODE_RESTRICTION
|
||||
? boost::get<InputNodeRestriction>(node_or_way).to
|
||||
: boost::get<InputWayRestriction>(node_or_way).to;
|
||||
? mapbox::util::get<InputNodeRestriction>(node_or_way).to
|
||||
: mapbox::util::get<InputWayRestriction>(node_or_way).to;
|
||||
}
|
||||
|
||||
RestrictionType Type() const
|
||||
@ -81,25 +81,25 @@ struct InputTurnRestriction
|
||||
InputWayRestriction &AsWayRestriction()
|
||||
{
|
||||
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
|
||||
{
|
||||
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()
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
@ -121,12 +121,6 @@ struct NodeRestriction
|
||||
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
|
||||
{
|
||||
return std::tie(from, via, to) == std::tie(other.from, other.via, other.to);
|
||||
@ -168,7 +162,7 @@ struct WayRestriction
|
||||
struct TurnRestriction
|
||||
{
|
||||
// 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;
|
||||
|
||||
// construction for NodeRestrictions
|
||||
@ -191,25 +185,25 @@ struct TurnRestriction
|
||||
WayRestriction &AsWayRestriction()
|
||||
{
|
||||
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
|
||||
{
|
||||
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()
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
@ -250,24 +244,6 @@ struct TurnRestriction
|
||||
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
|
||||
|
@ -32,12 +32,12 @@ class RestrictionCompressor
|
||||
void Compress(const NodeID from, const NodeID via, const NodeID to);
|
||||
|
||||
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
|
||||
// tail values to their respective tails. Way turn restrictions are represented by two
|
||||
// node-restrictions, so we can focus on them alone
|
||||
boost::unordered_multimap<NodeID, NodeRestriction *> heads;
|
||||
boost::unordered_multimap<NodeID, NodeRestriction *> tails;
|
||||
boost::unordered_multimap<NodeID, NodeRestriction *> starts;
|
||||
boost::unordered_multimap<NodeID, NodeRestriction *> ends;
|
||||
};
|
||||
|
||||
} // namespace extractor
|
||||
|
@ -186,18 +186,18 @@ inline void write(storage::io::FileWriter &writer, const TurnRestriction &restri
|
||||
writer.WriteOne(restriction.is_only);
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
write(writer, static_cast<TurnRestriction>(restriction));
|
||||
write(writer, static_cast<const TurnRestriction &>(restriction));
|
||||
writer.WriteElementCount64(restriction.condition.size());
|
||||
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)
|
||||
{
|
||||
TurnRestriction base;
|
||||
read(reader, base);
|
||||
reinterpret_cast<TurnRestriction &>(restriction) = std::move(base);
|
||||
read(reader, static_cast<TurnRestriction &>(restriction));
|
||||
const auto num_conditions = reader.ReadElementCount64();
|
||||
restriction.condition.resize(num_conditions);
|
||||
for (uint64_t i = 0; i < num_conditions; i++)
|
||||
|
@ -23,30 +23,30 @@ class WayRestrictionMap
|
||||
public:
|
||||
struct ViaWay
|
||||
{
|
||||
std::size_t id;
|
||||
NodeID from;
|
||||
NodeID to;
|
||||
};
|
||||
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;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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
|
||||
// This is used to construct edge based nodes that act as intermediate nodes.
|
||||
std::vector<ViaWay> DuplicatedNodeRepresentatives() const;
|
||||
|
||||
// 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
|
||||
bool IsRestricted(std::size_t duplicated_node, const NodeID to) const;
|
||||
|
||||
TurnRestriction const &GetRestriction(std::size_t) const;
|
||||
bool IsRestricted(DuplicatedNodeID duplicated_node, const NodeID to) const;
|
||||
|
||||
// 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
|
||||
@ -57,7 +57,7 @@ class WayRestrictionMap
|
||||
const NodeID number_of_edge_based_nodes) const;
|
||||
|
||||
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
|
||||
// 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 ...
|
||||
// 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>, std::size_t> restriction_ends;
|
||||
boost::unordered_multimap<std::pair<NodeID, NodeID>, RestrictionID> restriction_starts;
|
||||
boost::unordered_multimap<std::pair<NodeID, NodeID>, RestrictionID> restriction_ends;
|
||||
|
||||
std::vector<TurnRestriction> restriction_data;
|
||||
};
|
||||
|
@ -45,12 +45,18 @@ struct osm_node_id
|
||||
struct osm_way_id
|
||||
{
|
||||
};
|
||||
struct duplicated_node
|
||||
{
|
||||
};
|
||||
}
|
||||
using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>;
|
||||
static_assert(std::is_pod<OSMNodeID>(), "OSMNodeID is not a valid alias");
|
||||
using OSMWayID = osrm::Alias<std::uint64_t, tag::osm_way_id>;
|
||||
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 =
|
||||
OSMNodeID{std::numeric_limits<OSMNodeID::value_type>::max()};
|
||||
static const OSMWayID SPECIAL_OSM_WAYID =
|
||||
|
@ -194,7 +194,7 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const std::string &cnbg_ebg_mapping_path,
|
||||
const RestrictionMap &restriction_map,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map)
|
||||
{
|
||||
TIMER_START(renumber);
|
||||
@ -215,7 +215,7 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment,
|
||||
turn_weight_penalties_filename,
|
||||
turn_duration_penalties_filename,
|
||||
turn_penalties_index_filename,
|
||||
restriction_map,
|
||||
node_restriction_map,
|
||||
way_restriction_map);
|
||||
|
||||
TIMER_STOP(generate_edges);
|
||||
@ -228,7 +228,7 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment,
|
||||
|
||||
/// Renumbers all _forward_ edges and sets the edge_id.
|
||||
/// 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()
|
||||
{
|
||||
// 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_number_of_edge_based_nodes == m_edge_based_node_weights.size());
|
||||
|
||||
util::Log() << "Generated " << m_number_of_edge_based_nodes << " nodes and "
|
||||
<< m_edge_based_node_segments.size() << " segments in edge-expanded graph";
|
||||
util::Log() << "Generated " << m_number_of_edge_based_nodes << " nodes ("
|
||||
<< way_restriction_map.NumberOfDuplicatedNodes()
|
||||
<< " of which are duplicates) and " << m_edge_based_node_segments.size()
|
||||
<< " segments in edge-expanded graph";
|
||||
|
||||
return mapping;
|
||||
}
|
||||
@ -377,7 +379,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
const std::string &turn_weight_penalties_filename,
|
||||
const std::string &turn_duration_penalties_filename,
|
||||
const std::string &turn_penalties_index_filename,
|
||||
const RestrictionMap &restriction_map,
|
||||
const RestrictionMap &node_restriction_map,
|
||||
const WayRestrictionMap &way_restriction_map)
|
||||
{
|
||||
|
||||
@ -399,7 +401,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
SuffixTable street_name_suffix_table(scripting_environment);
|
||||
guidance::TurnAnalysis turn_analysis(*m_node_based_graph,
|
||||
m_coordinates,
|
||||
restriction_map,
|
||||
node_restriction_map,
|
||||
m_barrier_nodes,
|
||||
m_compressed_edge_container,
|
||||
name_table,
|
||||
@ -492,24 +494,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
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
|
||||
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.
|
||||
// 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
|
||||
@ -522,11 +508,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
const auto node_based_edge_to,
|
||||
const auto &intersection,
|
||||
const auto &turn,
|
||||
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 auto entry_class_id) {
|
||||
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);
|
||||
|
||||
@ -593,11 +575,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
lookup::TurnIndexBlock turn_index_block = {from_node, via_node, to_node};
|
||||
|
||||
// insert data into the designated buffer
|
||||
inserter(
|
||||
EdgeWithData{
|
||||
edge_based_edge, turn_index_block, weight_penalty, duration_penalty, turn_data},
|
||||
output_buffer);
|
||||
|
||||
return EdgeWithData{
|
||||
edge_based_edge, turn_index_block, weight_penalty, duration_penalty, turn_data};
|
||||
};
|
||||
|
||||
// Second part of the pipeline is where the intersection analysis is done for
|
||||
@ -735,17 +714,28 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
m_node_based_graph->GetTarget(turn.eid),
|
||||
m_number_of_edge_based_nodes);
|
||||
|
||||
generate_edges(edge_data1.edge_id,
|
||||
target_id,
|
||||
node_along_road_entering,
|
||||
incoming_edge,
|
||||
node_at_center_of_intersection,
|
||||
turn.eid,
|
||||
intersection,
|
||||
turn,
|
||||
entry_class_id,
|
||||
continuous_inserter,
|
||||
*buffer);
|
||||
{ // scope to forget edge_with_data after
|
||||
const auto edge_with_data =
|
||||
generate_edge(edge_data1.edge_id,
|
||||
target_id,
|
||||
node_along_road_entering,
|
||||
incoming_edge,
|
||||
node_at_center_of_intersection,
|
||||
turn.eid,
|
||||
intersection,
|
||||
turn,
|
||||
entry_class_id);
|
||||
|
||||
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
|
||||
// handle the normal edges for the way, but also add turns for every
|
||||
@ -775,7 +765,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
if (is_restricted)
|
||||
return;
|
||||
|
||||
generate_edges(
|
||||
// add into delayed data
|
||||
auto edge_with_data = generate_edge(
|
||||
NodeID(from_id),
|
||||
m_node_based_graph->GetEdgeData(turn.eid).edge_id,
|
||||
node_along_road_entering,
|
||||
@ -784,10 +775,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
turn.eid,
|
||||
intersection,
|
||||
turn,
|
||||
entry_class_id,
|
||||
delayed_inserter,
|
||||
*buffer);
|
||||
entry_class_id);
|
||||
|
||||
buffer->delayed_data.push_back(std::move(edge_with_data));
|
||||
};
|
||||
|
||||
std::for_each(duplicated_nodes.begin(),
|
||||
@ -812,38 +802,38 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
|
||||
std::vector<EdgeWithData> delayed_data;
|
||||
|
||||
auto const append_data_to_output = [&](IntersectionData const &data) {
|
||||
// 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());
|
||||
|
||||
BOOST_ASSERT(m_edge_based_edge_list.size() <= std::numeric_limits<NodeID>::max());
|
||||
|
||||
turn_weight_penalties.insert(turn_weight_penalties.end(),
|
||||
data.turn_weight_penalties.begin(),
|
||||
data.turn_weight_penalties.end());
|
||||
turn_duration_penalties.insert(turn_duration_penalties.end(),
|
||||
data.turn_duration_penalties.begin(),
|
||||
data.turn_duration_penalties.end());
|
||||
turn_data_container.append(data.turn_data_container);
|
||||
turn_indexes_write_buffer.insert(turn_indexes_write_buffer.end(),
|
||||
data.turn_indexes.begin(),
|
||||
data.turn_indexes.end());
|
||||
|
||||
// Buffer writes to reduce syscall count
|
||||
if (turn_indexes_write_buffer.size() >= TURN_INDEX_WRITE_BUFFER_SIZE)
|
||||
{
|
||||
turn_penalties_index_file.WriteFrom(turn_indexes_write_buffer.data(),
|
||||
turn_indexes_write_buffer.size());
|
||||
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);
|
||||
|
||||
// for readability
|
||||
const auto &data = buffer->continuous_data;
|
||||
// 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());
|
||||
|
||||
BOOST_ASSERT(m_edge_based_edge_list.size() <= std::numeric_limits<NodeID>::max());
|
||||
|
||||
turn_weight_penalties.insert(turn_weight_penalties.end(),
|
||||
data.turn_weight_penalties.begin(),
|
||||
data.turn_weight_penalties.end());
|
||||
turn_duration_penalties.insert(turn_duration_penalties.end(),
|
||||
data.turn_duration_penalties.begin(),
|
||||
data.turn_duration_penalties.end());
|
||||
turn_data_container.append(data.turn_data_container);
|
||||
turn_indexes_write_buffer.insert(turn_indexes_write_buffer.end(),
|
||||
data.turn_indexes.begin(),
|
||||
data.turn_indexes.end());
|
||||
|
||||
// Buffer writes to reduce syscall count
|
||||
if (turn_indexes_write_buffer.size() >= TURN_INDEX_WRITE_BUFFER_SIZE)
|
||||
{
|
||||
turn_penalties_index_file.WriteFrom(turn_indexes_write_buffer.data(),
|
||||
turn_indexes_write_buffer.size());
|
||||
turn_indexes_write_buffer.clear();
|
||||
}
|
||||
|
||||
delayed_data.insert(
|
||||
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() << " skips " << restricted_turns_counter << " turns, "
|
||||
"defined by "
|
||||
<< restriction_map.size() << " restrictions";
|
||||
<< node_restriction_map.size() << " restrictions";
|
||||
util::Log() << " skips " << skipped_uturns_counter << " U turns";
|
||||
util::Log() << " skips " << skipped_barrier_turns_counter << " turns over barriers";
|
||||
}
|
||||
|
@ -660,41 +660,44 @@ void ExtractionContainers::PrepareRestrictions()
|
||||
// contain the start/end nodes of each way that is part of an restriction
|
||||
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
|
||||
// nodes of these ways
|
||||
const auto mark_ids = [&](auto const &turn_restriction) {
|
||||
FirstAndLastSegmentOfWay dummy_segment{
|
||||
MAX_OSM_WAYID, MAX_OSM_NODEID, MAX_OSM_NODEID, MAX_OSM_NODEID, MAX_OSM_NODEID};
|
||||
if (turn_restriction.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
const auto &way = turn_restriction.AsWayRestriction();
|
||||
referenced_ways[way.from] = dummy_segment;
|
||||
referenced_ways[way.to] = dummy_segment;
|
||||
referenced_ways[way.via] = dummy_segment;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(turn_restriction.Type() == RestrictionType::NODE_RESTRICTION);
|
||||
const auto &node = turn_restriction.AsNodeRestriction();
|
||||
referenced_ways[node.from] = dummy_segment;
|
||||
referenced_ways[node.to] = dummy_segment;
|
||||
}
|
||||
};
|
||||
|
||||
// update the values for all edges already sporting SPECIAL_NODEID
|
||||
const auto set_ids = [&](auto const &start_end) {
|
||||
auto itr = referenced_ways.find(start_end.way_id);
|
||||
if (itr != referenced_ways.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);
|
||||
|
||||
const auto mark_ids = [&](auto const &turn_restriction) {
|
||||
FirstAndLastSegmentOfWay dummy_segment{
|
||||
MAX_OSM_WAYID, MAX_OSM_NODEID, MAX_OSM_NODEID, MAX_OSM_NODEID, MAX_OSM_NODEID};
|
||||
if (turn_restriction.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
const auto &way = turn_restriction.AsWayRestriction();
|
||||
referenced_ways[way.from] = dummy_segment;
|
||||
referenced_ways[way.to] = dummy_segment;
|
||||
referenced_ways[way.via] = dummy_segment;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(turn_restriction.Type() == RestrictionType::NODE_RESTRICTION);
|
||||
const auto &node = turn_restriction.AsNodeRestriction();
|
||||
referenced_ways[node.from] = dummy_segment;
|
||||
referenced_ways[node.to] = dummy_segment;
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
const auto set_ids = [&](auto const &start_end) {
|
||||
auto itr = referenced_ways.find(start_end.way_id);
|
||||
if (itr != referenced_ways.end())
|
||||
itr->second = start_end;
|
||||
};
|
||||
|
||||
std::for_each(way_start_end_id_list.cbegin(), way_start_end_id_list.cend(), set_ids);
|
||||
TIMER_STOP(prepare_restrictions);
|
||||
log << "ok, after " << TIMER_SEC(prepare_restrictions) << "s";
|
||||
@ -710,8 +713,6 @@ void ExtractionContainers::PrepareRestrictions()
|
||||
return internal;
|
||||
};
|
||||
|
||||
// Given:
|
||||
// a -- b - ????????? - c -- d
|
||||
// Given
|
||||
// a -- b - ????????? - c -- d as via segment
|
||||
// and either
|
||||
@ -720,6 +721,8 @@ void ExtractionContainers::PrepareRestrictions()
|
||||
// (d,e) or (j,a) as entry-segment
|
||||
auto const find_node_restriction =
|
||||
[&](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
|
||||
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);
|
||||
};
|
||||
|
||||
// transform an OSMRestriction (based on WayIDs) into an OSRM restriction (base on NodeIDs)
|
||||
// returns true on successful transformation, false in case of invalid references
|
||||
// Transform an OSMRestriction (based on WayIDs) into an OSRM restriction (base on NodeIDs).
|
||||
// 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) {
|
||||
if (external_type.Type() == RestrictionType::WAY_RESTRICTION)
|
||||
{
|
||||
@ -837,7 +842,7 @@ void ExtractionContainers::PrepareRestrictions()
|
||||
TurnRestriction restriction;
|
||||
restriction.is_only = external_restriction.is_only;
|
||||
if (transform(external_restriction, restriction))
|
||||
unconditional_turn_restrictions.push_back(restriction);
|
||||
unconditional_turn_restrictions.push_back(std::move(restriction));
|
||||
}
|
||||
// conditional turn restriction
|
||||
else
|
||||
@ -846,7 +851,7 @@ void ExtractionContainers::PrepareRestrictions()
|
||||
restriction.is_only = external_restriction.is_only;
|
||||
restriction.condition = std::move(external_restriction.condition);
|
||||
if (transform(external_restriction, restriction))
|
||||
conditional_turn_restrictions.push_back(restriction);
|
||||
conditional_turn_restrictions.push_back(std::move(restriction));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -12,13 +12,13 @@ namespace extractor
|
||||
|
||||
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) {
|
||||
heads.insert(std::make_pair(element.from, &element));
|
||||
tails.insert(std::make_pair(element.to, &element));
|
||||
starts.insert(std::make_pair(element.from, &element));
|
||||
ends.insert(std::make_pair(element.to, &element));
|
||||
};
|
||||
// !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)
|
||||
{
|
||||
auto &way_restriction = restriction.AsWayRestriction();
|
||||
@ -33,21 +33,21 @@ RestrictionCompressor::RestrictionCompressor(std::vector<TurnRestriction> &restr
|
||||
}
|
||||
};
|
||||
|
||||
// add all restrictions as their respective head-tail pointers
|
||||
std::for_each(restrictions.begin(), restrictions.end(), index_heads_and_tails);
|
||||
// add all restrictions as their respective startend pointers
|
||||
std::for_each(restrictions.begin(), restrictions.end(), index_starts_and_ends);
|
||||
}
|
||||
|
||||
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.
|
||||
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) {
|
||||
const auto update_start = [&](auto ptr) {
|
||||
// ____ | from - p.from | via - p.via | to - p.to | ____
|
||||
BOOST_ASSERT(ptr->from == via);
|
||||
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);
|
||||
|
||||
const auto reinsert_head = [&](auto ptr) { heads.insert(std::make_pair(ptr->from, ptr)); };
|
||||
std::for_each(start_ptrs.begin(), start_ptrs.end(), update_start);
|
||||
|
||||
// update the ptrs in our mapping
|
||||
heads.erase(via);
|
||||
std::for_each(head_ptrs.begin(), head_ptrs.end(), reinsert_head);
|
||||
starts.erase(via);
|
||||
|
||||
// extract all tail ptrs and move them from via to to
|
||||
auto all_tails_range = tails.equal_range(via);
|
||||
std::vector<NodeRestriction *> tail_ptrs;
|
||||
std::transform(
|
||||
all_tails_range.first, all_tails_range.second, std::back_inserter(tail_ptrs), get_value);
|
||||
const auto reinsert_start = [&](auto ptr) { starts.insert(std::make_pair(ptr->from, ptr)); };
|
||||
std::for_each(start_ptrs.begin(), start_ptrs.end(), reinsert_start);
|
||||
|
||||
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);
|
||||
// p.from | ____ - p.via | from - p.to | via - ____ | to
|
||||
if (ptr->via == from)
|
||||
@ -90,14 +92,13 @@ void RestrictionCompressor::Compress(const NodeID from, const NodeID via, const
|
||||
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);
|
||||
|
||||
// update tail ptrs in mapping
|
||||
tails.erase(via);
|
||||
std::for_each(tail_ptrs.begin(), tail_ptrs.end(), reinsert_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);
|
||||
}
|
||||
|
||||
} // namespace extractor
|
||||
|
@ -78,8 +78,9 @@ removeInvalidRestrictions(std::vector<TurnRestriction> restrictions,
|
||||
}
|
||||
};
|
||||
|
||||
restrictions.erase(std::remove_if(restrictions.begin(), restrictions.end(), is_invalid),
|
||||
restrictions.end());
|
||||
const auto end_valid_restrictions =
|
||||
std::remove_if(restrictions.begin(), restrictions.end(), is_invalid);
|
||||
restrictions.erase(end_valid_restrictions, restrictions.end());
|
||||
|
||||
return restrictions;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "extractor/way_restriction_map.hpp"
|
||||
#include "util/for_each_pair.hpp"
|
||||
|
||||
#include <iterator>
|
||||
#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);
|
||||
|
||||
const auto as_duplicated_node =
|
||||
[](auto const &restriction) -> std::tuple<NodeID, NodeID, NodeID> {
|
||||
const auto as_duplicated_node = [](auto const &restriction) {
|
||||
auto &way = restriction.AsWayRestriction();
|
||||
// group restrictions by the via-way. On same via-ways group by from
|
||||
return std::make_tuple(
|
||||
way.in_restriction.via, way.out_restriction.via, way.in_restriction.from);
|
||||
return std::tie(way.in_restriction.via, way.out_restriction.via, way.in_restriction.from);
|
||||
};
|
||||
|
||||
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::size_t index = 0, duplication_id = 0;
|
||||
// map all way restrictions into access containers
|
||||
const auto prepare_way_restriction = [this, &index, &duplication_id, as_duplicated_node](
|
||||
const auto &restriction) {
|
||||
for (RestrictionID index = 0; index < restriction_data.size(); ++index)
|
||||
{
|
||||
const auto &restriction = restriction_data[index];
|
||||
const auto &way = restriction.AsWayRestriction();
|
||||
restriction_starts.insert(
|
||||
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;
|
||||
// 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))
|
||||
duplicated_node_groups.push_back(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());
|
||||
}
|
||||
|
||||
@ -110,17 +106,17 @@ bool WayRestrictionMap::IsViaWay(const NodeID from, const NodeID to) const
|
||||
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(),
|
||||
std::upper_bound(duplicated_node_groups.begin(),
|
||||
duplicated_node_groups.end(),
|
||||
restriction_id)) -
|
||||
1;
|
||||
const auto upper_bound_restriction = std::upper_bound(
|
||||
duplicated_node_groups.begin(), duplicated_node_groups.end(), restriction_id);
|
||||
const auto distance_to_upper_bound =
|
||||
std::distance(duplicated_node_groups.begin(), upper_bound_restriction);
|
||||
return distance_to_upper_bound - 1;
|
||||
}
|
||||
|
||||
util::range<std::size_t> WayRestrictionMap::DuplicatedNodeIDs(const NodeID from,
|
||||
const NodeID to) const
|
||||
util::range<DuplicatedNodeID> WayRestrictionMap::DuplicatedNodeIDs(const NodeID from,
|
||||
const NodeID to) const
|
||||
{
|
||||
const auto duplicated_node_range_itr = std::equal_range(
|
||||
restriction_data.begin(), restriction_data.end(), std::make_tuple(from, to), FindViaWay());
|
||||
@ -129,16 +125,16 @@ util::range<std::size_t> WayRestrictionMap::DuplicatedNodeIDs(const NodeID from,
|
||||
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.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
|
||||
// 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)
|
||||
{
|
||||
@ -153,11 +149,6 @@ bool WayRestrictionMap::IsRestricted(std::size_t duplicated_node, const NodeID t
|
||||
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<ViaWay> result;
|
||||
@ -167,7 +158,7 @@ std::vector<WayRestrictionMap::ViaWay> WayRestrictionMap::DuplicatedNodeRepresen
|
||||
std::back_inserter(result),
|
||||
[&](auto const representative_id) -> ViaWay {
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user