From 13bf4fab3288c7546d55c1e5f56994c71323ae27 Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Fri, 19 Dec 2014 16:46:12 +0100 Subject: [PATCH] make implementation of restriction map independent of graph type --- contractor/edge_based_graph_factory.cpp | 4 +- contractor/processing_chain.cpp | 3 +- data_structures/restriction_map.cpp | 129 ++++++++---------------- data_structures/restriction_map.hpp | 78 ++++++++++++-- 4 files changed, 114 insertions(+), 100 deletions(-) diff --git a/contractor/edge_based_graph_factory.cpp b/contractor/edge_based_graph_factory.cpp index 375d5a58c..d298c4e3b 100644 --- a/contractor/edge_based_graph_factory.cpp +++ b/contractor/edge_based_graph_factory.cpp @@ -389,10 +389,10 @@ void EdgeBasedGraphFactory::CompressGeometry() // update any involved turn restrictions m_restriction_map->FixupStartingTurnRestriction(node_u, node_v, node_w); - m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v, node_w); + m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v, node_w, m_node_based_graph); m_restriction_map->FixupStartingTurnRestriction(node_w, node_v, node_u); - m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u); + m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u, m_node_based_graph); // store compressed geometry in container m_geometry_compressor.CompressEdge( diff --git a/contractor/processing_chain.cpp b/contractor/processing_chain.cpp index 933b5e937..f265c8953 100644 --- a/contractor/processing_chain.cpp +++ b/contractor/processing_chain.cpp @@ -510,8 +510,7 @@ Prepare::BuildEdgeExpandedGraph(lua_State *lua_state, SimpleLogger().Write() << "Generating edge-expanded graph representation"; std::shared_ptr node_based_graph = NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list); - std::unique_ptr restriction_map = - std::unique_ptr(new RestrictionMap(node_based_graph, restriction_list)); + std::unique_ptr restriction_map = osrm::make_unique(restriction_list); std::shared_ptr edge_based_graph_factory = std::make_shared(node_based_graph, std::move(restriction_map), diff --git a/data_structures/restriction_map.cpp b/data_structures/restriction_map.cpp index 5d414b6ae..507df5ab6 100644 --- a/data_structures/restriction_map.cpp +++ b/data_structures/restriction_map.cpp @@ -27,98 +27,53 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "restriction_map.hpp" +RestrictionMap::RestrictionMap(const std::vector &restriction_list) + : m_count(0) + { + // decompose restriction consisting of a start, via and end node into a + // a pair of starting edge and a list of all end nodes + for (auto &restriction : restriction_list) + { + m_restriction_start_nodes.insert(restriction.from.node); + m_no_turn_via_node_set.insert(restriction.via.node); + + RestrictionSource restriction_source = {restriction.from.node, restriction.via.node}; + + unsigned index; + auto restriction_iter = m_restriction_map.find(restriction_source); + if (restriction_iter == m_restriction_map.end()) + { + index = m_restriction_bucket_list.size(); + m_restriction_bucket_list.resize(index + 1); + m_restriction_map.emplace(restriction_source, index); + } + else + { + index = restriction_iter->second; + // Map already contains an is_only_*-restriction + if (m_restriction_bucket_list.at(index).begin()->is_only) + { + continue; + } + else if (restriction.flags.is_only) + { + // We are going to insert an is_only_*-restriction. There can be only one. + m_count -= m_restriction_bucket_list.at(index).size(); + m_restriction_bucket_list.at(index).clear(); + } + } + ++m_count; + m_restriction_bucket_list.at(index) + .emplace_back(restriction.to.node, restriction.flags.is_only); + } + } + + bool RestrictionMap::IsViaNode(const NodeID node) const { return m_no_turn_via_node_set.find(node) != m_no_turn_via_node_set.end(); } -RestrictionMap::RestrictionMap(const std::shared_ptr &graph, - const std::vector &restriction_list) - : m_count(0), m_graph(graph) -{ - // decompose restriction consisting of a start, via and end node into a - // a pair of starting edge and a list of all end nodes - for (auto &restriction : restriction_list) - { - m_restriction_start_nodes.insert(restriction.from.node); - m_no_turn_via_node_set.insert(restriction.via.node); - - RestrictionSource restriction_source = {restriction.from.node, restriction.via.node}; - - unsigned index; - auto restriction_iter = m_restriction_map.find(restriction_source); - if (restriction_iter == m_restriction_map.end()) - { - index = m_restriction_bucket_list.size(); - m_restriction_bucket_list.resize(index + 1); - m_restriction_map.emplace(restriction_source, index); - } - else - { - index = restriction_iter->second; - // Map already contains an is_only_*-restriction - if (m_restriction_bucket_list.at(index).begin()->is_only) - { - continue; - } - else if (restriction.flags.is_only) - { - // We are going to insert an is_only_*-restriction. There can be only one. - m_count -= m_restriction_bucket_list.at(index).size(); - m_restriction_bucket_list.at(index).clear(); - } - } - ++m_count; - m_restriction_bucket_list.at(index) - .emplace_back(restriction.to.node, restriction.flags.is_only); - } -} - -// Replace end v with w in each turn restriction containing u as via node -void RestrictionMap::FixupArrivingTurnRestriction(const NodeID node_u, - const NodeID node_v, - const NodeID node_w) -{ - BOOST_ASSERT(node_u != SPECIAL_NODEID); - BOOST_ASSERT(node_v != SPECIAL_NODEID); - BOOST_ASSERT(node_w != SPECIAL_NODEID); - - if (!IsViaNode(node_u)) - { - return; - } - - // find all potential start edges. It is more efficent to get a (small) list - // of potential start edges than iterating over all buckets - std::vector predecessors; - for (const EdgeID current_edge_id : m_graph->GetAdjacentEdgeRange(node_u)) - { - const NodeID target = m_graph->GetTarget(current_edge_id); - if (node_v != target) - { - predecessors.push_back(target); - } - } - - for (const NodeID node_x : predecessors) - { - const auto restriction_iterator = m_restriction_map.find({node_x, node_u}); - if (restriction_iterator == m_restriction_map.end()) - { - continue; - } - - const unsigned index = restriction_iterator->second; - auto &bucket = m_restriction_bucket_list.at(index); - for (RestrictionTarget &restriction_target : bucket) - { - if (node_v == restriction_target.target_node) - { - restriction_target.target_node = node_w; - } - } - } -} // Replaces start edge (v, w) with (u, w). Only start node changes. void RestrictionMap::FixupStartingTurnRestriction(const NodeID node_u, diff --git a/data_structures/restriction_map.hpp b/data_structures/restriction_map.hpp index 17dad317c..7633faf4d 100644 --- a/data_structures/restriction_map.hpp +++ b/data_structures/restriction_map.hpp @@ -30,13 +30,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include "node_based_graph.hpp" #include "restriction.hpp" #include "../Util/std_hash.hpp" #include "../typedefs.h" +#include + #include #include +#include struct RestrictionSource { @@ -94,26 +96,84 @@ template <> struct hash class RestrictionMap { public: - RestrictionMap(const std::shared_ptr &graph, - const std::vector &input_restrictions_list); + RestrictionMap(const std::vector &restriction_list); + + // Replace end v with w in each turn restriction containing u as via node + template + void FixupArrivingTurnRestriction(const NodeID node_u, + const NodeID node_v, + const NodeID node_w, + const std::shared_ptr &graph) + { + BOOST_ASSERT(node_u != SPECIAL_NODEID); + BOOST_ASSERT(node_v != SPECIAL_NODEID); + BOOST_ASSERT(node_w != SPECIAL_NODEID); + + if (!IsViaNode(node_u)) + { + return; + } + + // find all potential start edges. It is more efficent to get a (small) list + // of potential start edges than iterating over all buckets + std::vector predecessors; + for (const EdgeID current_edge_id : graph->GetAdjacentEdgeRange(node_u)) + { + const NodeID target = graph->GetTarget(current_edge_id); + if (node_v != target) + { + predecessors.push_back(target); + } + } + + for (const NodeID node_x : predecessors) + { + const auto restriction_iterator = m_restriction_map.find({node_x, node_u}); + if (restriction_iterator == m_restriction_map.end()) + { + continue; + } + + const unsigned index = restriction_iterator->second; + auto &bucket = m_restriction_bucket_list.at(index); + for (RestrictionTarget &restriction_target : bucket) + { + if (node_v == restriction_target.target_node) + { + restriction_target.target_node = node_w; + } + } + } + } - void FixupArrivingTurnRestriction(const NodeID u, const NodeID v, const NodeID w); - void FixupStartingTurnRestriction(const NodeID u, const NodeID v, const NodeID w); - NodeID CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const; - bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const; bool IsViaNode(const NodeID node) const; + + + // Replaces start edge (v, w) with (u, w). Only start node changes. + void FixupStartingTurnRestriction(const NodeID node_u, + const NodeID node_v, + const NodeID node_w); + + // Check if edge (u, v) is the start of any turn restriction. + // If so returns id of first target node. + NodeID CheckForEmanatingIsOnlyTurn(const NodeID node_u, const NodeID node_v) const; + // Checks if turn is actually a turn restriction. + bool CheckIfTurnIsRestricted(const NodeID node_u, + const NodeID node_v, + const NodeID node_w) const; + std::size_t size() { return m_count; } private: + // check of node is the start of any restriction bool IsSourceNode(const NodeID node) const; + using EmanatingRestrictionsVector = std::vector; - using EdgeData = NodeBasedDynamicGraph::EdgeData; std::size_t m_count; - std::shared_ptr m_graph; //! index -> list of (target, isOnly) std::vector m_restriction_bucket_list; //! maps (start, via) -> bucket index