From 012c2f83b199cb1f030eb2623fb03c9e42e0f4a9 Mon Sep 17 00:00:00 2001 From: Moritz Kobitzsch Date: Mon, 17 Jul 2017 16:33:18 +0200 Subject: [PATCH] state --- include/extractor/way_restriction_map.hpp | 14 +++++--- src/extractor/edge_based_graph_factory.cpp | 38 +++++++--------------- src/extractor/way_restriction_map.cpp | 30 +++++++++++++---- 3 files changed, 43 insertions(+), 39 deletions(-) diff --git a/include/extractor/way_restriction_map.hpp b/include/extractor/way_restriction_map.hpp index e4998cb5ef..2132c3a21e 100644 --- a/include/extractor/way_restriction_map.hpp +++ b/include/extractor/way_restriction_map.hpp @@ -28,14 +28,10 @@ class WayRestrictionMap }; WayRestrictionMap(const std::vector &turn_restrictions); - bool IsViaWay(const NodeID from, const NodeID to) const; - - // check if an edge between two nodes is a restricted turn + // check if an edge between two nodes is a restricted turn. The check needs to be performed bool IsStart(const NodeID from, const NodeID to) const; bool IsEnd(const NodeID from, const NodeID to) const; - std::size_t Size() const; - // number of duplicated nodes std::size_t NumberOfDuplicatedNodes() const; @@ -52,6 +48,14 @@ class WayRestrictionMap TurnRestriction const &GetRestriction(std::size_t) 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 + NodeID RemapIfRestricted(const NodeID edge_based_node, + const NodeID node_based_from, + const NodeID node_based_via, + const NodeID node_based_to, + const NodeID number_of_edge_based_nodes) const; + private: // 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 diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index ab3987c285..75a785235c 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -322,7 +322,8 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re const auto via_ways = way_restriction_map.DuplicatedNodeRepresentatives(); util::Percent progress(log, via_ways.size()); - NodeID edge_based_node_id = NodeID(m_number_of_edge_based_nodes - way_restriction_map.NumberOfDuplicatedNodes()); + NodeID edge_based_node_id = + NodeID(m_number_of_edge_based_nodes - way_restriction_map.NumberOfDuplicatedNodes()); std::size_t progress_counter = 0; // allocate enough space for the mapping for (const auto way : via_ways) @@ -785,8 +786,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( m_node_based_graph->GetEdgeData(incoming_edge); const EdgeData &edge_data2 = m_node_based_graph->GetEdgeData(turn.eid); - auto target_id = edge_data2.edge_id; - // In case a way restriction starts at a given location, add a turn onto // every artificial node eminating here. // @@ -800,30 +799,15 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // ab via be to ef // // has two artifical nodes (be/bc) with restrictions starting at `ab`. - // - if (way_restriction_map.IsStart( - node_at_center_of_intersection, - m_node_based_graph->GetTarget(turn.eid))) - { - const auto restriction_ids = way_restriction_map.GetIDs( - node_at_center_of_intersection, - m_node_based_graph->GetTarget(turn.eid)); - for (auto restriction_id : restriction_ids) - { - const auto &restriction = - way_restriction_map.GetRestriction(restriction_id) - .AsWayRestriction(); - - // target the artificial node - if (restriction.in_restriction.from == node_along_road_entering) - { - target_id = - m_number_of_edge_based_nodes - - way_restriction_map.NumberOfDuplicatedNodes() + - way_restriction_map.DuplicatedNodeID(restriction_id); - } - } - } + // Since every restriction group (abc | abe) refers to the same + // artificial node, we simply have to find a single representative for + // the turn. + auto const target_id = way_restriction_map.RemapIfRestricted( + edge_data2.edge_id, + node_along_road_entering, + node_at_center_of_intersection, + 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, diff --git a/src/extractor/way_restriction_map.cpp b/src/extractor/way_restriction_map.cpp index d3aabf21f1..e510148a47 100644 --- a/src/extractor/way_restriction_map.cpp +++ b/src/extractor/way_restriction_map.cpp @@ -36,7 +36,7 @@ WayRestrictionMap::WayRestrictionMap(const std::vector &turn_re const auto &way = restriction.AsWayRestriction(); restriction_starts.insert( - std::make_pair(std::make_pair(way.in_restriction.via, way.in_restriction.to), index)); + std::make_pair(std::make_pair(way.in_restriction.from, way.in_restriction.via), index)); restriction_ends.insert(std::make_pair( std::make_pair(way.out_restriction.from, way.out_restriction.via), index)); via_ways.insert( @@ -84,12 +84,6 @@ bool WayRestrictionMap::IsEnd(const NodeID from, const NodeID to) const { return restriction_ends.count(std::make_pair(from, to)) > 0; } -bool WayRestrictionMap::IsViaWay(const NodeID from, const NodeID to) const -{ - return via_ways.count(std::make_pair(from, to)) > 0; -} - -std::size_t WayRestrictionMap::Size() const { return via_ways.size(); } std::vector WayRestrictionMap::GetIDs(const NodeID from, const NodeID to) const { @@ -122,5 +116,27 @@ std::vector WayRestrictionMap::DuplicatedNodeRepresen return result; } +NodeID WayRestrictionMap::RemapIfRestricted(const NodeID edge_based_node, + const NodeID node_based_from, + const NodeID node_based_via, + const NodeID node_based_to, + const NodeID number_of_edge_based_nodes) const +{ + auto range = restriction_starts.equal_range(std::make_pair(node_based_from, node_based_via)); + + // returns true if the ID saved in an iterator belongs to a turn restriction that references + // node_based_to as destination of the `in_restriction` + auto const restriction_targets_to = [node_based_to, this](const auto &pair) { + return restriction_data[pair.second].AsWayRestriction().in_restriction.to == node_based_to; + }; + auto itr = std::find_if(range.first, range.second, restriction_targets_to); + + // in case we found a matching restriction, we can remap the edge_based_node + if (itr != range.second) + return number_of_edge_based_nodes - NumberOfDuplicatedNodes() + DuplicatedNodeID(itr->second); + else + return edge_based_node; +} + } // namespace extractor } // namespace osrm