From 47a2271e273cb9a17e9feeacbb981117e189a7d3 Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Tue, 23 Dec 2014 11:30:45 +0100 Subject: [PATCH] copy edits: --- CMakeLists.txt | 10 +- algorithms/bfs_components.hpp | 52 +++++------ algorithms/tiny_components.hpp | 116 ++++++++++++++++++------ contractor/edge_based_graph_factory.cpp | 1 - features/car/maxspeed.feature | 24 +++-- profiles/car.lua | 3 + tools/components.cpp | 20 ++-- 7 files changed, 143 insertions(+), 83 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6fed7277..9bd885b4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,11 +60,9 @@ add_library(PHANTOMNODE OBJECT data_structures/phantom_node.cpp) set(ExtractorSources extract.cpp ${ExtractorGlob}) add_executable(osrm-extract ${ExtractorSources} $ $ $ $ $) -add_library(RESTRICTION OBJECT data_structures/restriction_map.cpp) - -file(GLOB PrepareGlob contractor/*.cpp data_structures/hilbert_value.cpp Util/compute_angle.cpp {RestrictionMapGlob}) +file(GLOB PrepareGlob contractor/*.cpp data_structures/hilbert_value.cpp data_structures/restriction_map.cpp Util/compute_angle.cpp) set(PrepareSources prepare.cpp ${PrepareGlob}) -add_executable(osrm-prepare ${PrepareSources} $ $ $ $ $ $) +add_executable(osrm-prepare ${PrepareSources} $ $ $ $ $) file(GLOB ServerGlob Server/*.cpp) file(GLOB DescriptorGlob descriptors/*.cpp) @@ -122,7 +120,7 @@ if(CMAKE_BUILD_TYPE MATCHES Release) if (HAS_LTO_FLAG) set(LTO_FLAGS "${LTO_FLAGS} -flto") - # Since gcc 4.9 the LTO format is non-standart ('slim'), so we need to use the build-in tools + # With GCC 4.9 the LTO format is non-standard ('slim'), so we need to use the build-in tools if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "4.9.0" AND NOT MINGW) message(STATUS "Using gcc specific binutils for LTO.") @@ -282,7 +280,7 @@ if(WITH_TOOLS OR BUILD_TOOLS) message(STATUS "Activating OSRM internal tools") find_package(GDAL) if(GDAL_FOUND) - add_executable(osrm-components tools/components.cpp $ $ $ $ $) + add_executable(osrm-components tools/components.cpp $ $ $ $) target_link_libraries(osrm-components ${TBB_LIBRARIES}) include_directories(${GDAL_INCLUDE_DIR}) target_link_libraries( diff --git a/algorithms/bfs_components.hpp b/algorithms/bfs_components.hpp index 57be63553..bdcbd5e43 100644 --- a/algorithms/bfs_components.hpp +++ b/algorithms/bfs_components.hpp @@ -122,38 +122,38 @@ template class BFSComponentExplorer const NodeID u = current_queue_item.second; // parent // increment size counter of current component ++current_component_size; - if (m_barrier_nodes.find(v) != m_barrier_nodes.end()) + const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end()); + if (!is_barrier_node) { - continue; - } - const NodeID to_node_of_only_restriction = - m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v); + const NodeID to_node_of_only_restriction = + m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v); - for (auto e2 : m_graph.GetAdjacentEdgeRange(v)) - { - const NodeID w = m_graph.GetTarget(e2); - - if (to_node_of_only_restriction != std::numeric_limits::max() && - w != to_node_of_only_restriction) + for (auto e2 : m_graph.GetAdjacentEdgeRange(v)) { - // At an only_-restriction but not at the right turn - continue; - } + const NodeID w = m_graph.GetTarget(e2); - if (u != w) - { - // only add an edge if turn is not a U-turn except - // when it is at the end of a dead-end street. - if (!m_restriction_map.CheckIfTurnIsRestricted(u, v, w)) + if (to_node_of_only_restriction != std::numeric_limits::max() && + w != to_node_of_only_restriction) { - // only add an edge if turn is not prohibited - if (std::numeric_limits::max() == m_component_index_list[w]) + // At an only_-restriction but not at the right turn + continue; + } + + if (u != w) + { + // only add an edge if turn is not a U-turn except + // when it is at the end of a dead-end street. + if (!m_restriction_map.CheckIfTurnIsRestricted(u, v, w)) { - // insert next (node, parent) only if w has - // not yet been explored - // mark node as read - m_component_index_list[w] = current_component; - bfs_queue.emplace(w, v); + // only add an edge if turn is not prohibited + if (std::numeric_limits::max() == m_component_index_list[w]) + { + // insert next (node, parent) only if w has + // not yet been explored + // mark node as read + m_component_index_list[w] = current_component; + bfs_queue.emplace(w, v); + } } } } diff --git a/algorithms/tiny_components.hpp b/algorithms/tiny_components.hpp index 322137562..44256e2ab 100644 --- a/algorithms/tiny_components.hpp +++ b/algorithms/tiny_components.hpp @@ -34,7 +34,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../data_structures/query_node.hpp" #include "../data_structures/percent.hpp" #include "../data_structures/restriction.hpp" -#include "../data_structures/restriction_map.hpp" #include "../data_structures/turn_instructions.hpp" #include "../Util/integer_range.hpp" @@ -76,23 +75,64 @@ class TarjanSCC bool on_stack; }; + using RestrictionSource = std::pair; + using RestrictionTarget = std::pair; + using EmanatingRestrictionsVector = std::vector; + using RestrictionMap = std::unordered_map; + + std::vector m_restriction_bucket_list; std::vector components_index; std::vector component_size_vector; std::shared_ptr m_node_based_graph; - std::unordered_set barrier_node_set; - RestrictionMap m_restriction_map; + std::unordered_set barrier_node_list; unsigned size_one_counter; + RestrictionMap m_restriction_map; public: TarjanSCC(std::shared_ptr graph, - const RestrictionMap &restrictions, - const std::vector &barrier_node_list) + std::vector &bn, + std::vector &irs) : components_index(graph->GetNumberOfNodes(), SPECIAL_NODEID), - m_node_based_graph(graph), m_restriction_map(restrictions), + m_node_based_graph(graph), size_one_counter(0) { - barrier_node_set.insert(std::begin(barrier_node_list), std::end(barrier_node_list)); - BOOST_ASSERT(m_node_based_graph->GetNumberOfNodes() > 0); + + TIMER_START(SCC_LOAD); + for (const TurnRestriction &restriction : irs) + { + std::pair restriction_source = {restriction.from.node, + restriction.via.node}; + unsigned index = 0; + const auto restriction_iterator = m_restriction_map.find(restriction_source); + if (restriction_iterator == 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_iterator->second; + // Map already contains an is_only_*-restriction + if (m_restriction_bucket_list.at(index).begin()->second) + { + continue; + } + else if (restriction.flags.is_only) + { + // We are going to insert an is_only_*-restriction. There can be only one. + m_restriction_bucket_list.at(index).clear(); + } + } + + m_restriction_bucket_list.at(index) + .emplace_back(restriction.to.node, restriction.flags.is_only); + } + + barrier_node_list.insert(bn.begin(), bn.end()); + + TIMER_STOP(SCC_LOAD); + SimpleLogger().Write() << "Loading data into SCC took " << TIMER_MSEC(SCC_LOAD)/1000. << "s"; } void Run() @@ -118,10 +158,8 @@ class TarjanSCC while (!recursion_stack.empty()) { TarjanStackFrame currentFrame = recursion_stack.top(); - const NodeID u = currentFrame.parent; const NodeID v = currentFrame.v; recursion_stack.pop(); - const bool before_recursion = processing_node_before_recursion[v]; if (before_recursion && tarjan_node_list[v].index != UINT_MAX) @@ -143,29 +181,9 @@ class TarjanSCC ++index; // Traverse outgoing edges - if (barrier_node_set.find(v) != barrier_node_set.end()) - { - continue; - } - - const NodeID to_node_of_only_restriction = - m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v); - for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(v)) { const auto vprime = m_node_based_graph->GetTarget(current_edge); - if (to_node_of_only_restriction != std::numeric_limits::max() && - vprime == to_node_of_only_restriction) - { - // At an only_-restriction but not at the right turn - // continue; - } - - if (m_restriction_map.CheckIfTurnIsRestricted(u, v, vprime)) - { - // continue; - } - if (SPECIAL_NODEID == tarjan_node_list[vprime].index) { recursion_stack.emplace(TarjanStackFrame(vprime, v)); @@ -235,6 +253,44 @@ class TarjanSCC { return component_size_vector[components_index[node]]; } + + private: + unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const + { + std::pair restriction_source = {u, v}; + const auto restriction_iterator = m_restriction_map.find(restriction_source); + if (restriction_iterator != m_restriction_map.end()) + { + const unsigned index = restriction_iterator->second; + for (const RestrictionSource &restriction_target : m_restriction_bucket_list.at(index)) + { + if (restriction_target.second) + { + return restriction_target.first; + } + } + } + return SPECIAL_NODEID; + } + + bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const + { + // only add an edge if turn is not a U-turn except it is the end of dead-end street. + std::pair restriction_source = {u, v}; + const auto restriction_iterator = m_restriction_map.find(restriction_source); + if (restriction_iterator != m_restriction_map.end()) + { + const unsigned index = restriction_iterator->second; + for (const RestrictionTarget &restriction_target : m_restriction_bucket_list.at(index)) + { + if (w == restriction_target.first) + { + return true; + } + } + } + return false; + } }; #endif /* TINY_COMPONENTS_HPP */ diff --git a/contractor/edge_based_graph_factory.cpp b/contractor/edge_based_graph_factory.cpp index d298c4e3b..c8f055307 100644 --- a/contractor/edge_based_graph_factory.cpp +++ b/contractor/edge_based_graph_factory.cpp @@ -52,7 +52,6 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory( m_node_info_list(node_info_list), m_node_based_graph(node_based_graph), m_restriction_map(std::move(restriction_map)), max_id(0) { - // insert into unordered sets for fast lookup m_barrier_nodes.insert(barrier_node_list.begin(), barrier_node_list.end()); m_traffic_lights.insert(traffic_light_node_list.begin(), traffic_light_node_list.end()); diff --git a/features/car/maxspeed.feature b/features/car/maxspeed.feature index 431fe24a7..8f85d3a67 100644 --- a/features/car/maxspeed.feature +++ b/features/car/maxspeed.feature @@ -8,19 +8,25 @@ OSRM will use 4/5 of the projected free-flow speed. Scenario: Car - Respect maxspeeds when lower that way type speed Given the node map - | a | b | c | d | + | a | b | c | d | e | f | g | And the ways - | nodes | highway | maxspeed | - | ab | trunk | | - | bc | trunk | 60 | - | cd | trunk | FR:urban | + | nodes | highway | maxspeed | + | ab | trunk | | + | bc | trunk | 60 | + | cd | trunk | FR:urban | + | de | trunk | CH:rural | + | ef | trunk | CH:trunk | + | fg | trunk | CH:motorway | When I route I should get - | from | to | route | speed | - | a | b | ab | 78 km/h | - | b | c | bc | 59 km/h +- 1 | - | c | d | cd | 50 km/h | + | from | to | route | speed | + | a | b | ab | 78 km/h | + | b | c | bc | 59 km/h +- 1 | + | c | d | cd | 50 km/h | + | d | e | de | 75 km/h | + | e | f | ef | 90 km/h | + | f | g | fg | 105 km/h | Scenario: Car - Do not ignore maxspeed when higher than way speed Given the node map diff --git a/profiles/car.lua b/profiles/car.lua index e14ceb3aa..ad5009636 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -103,6 +103,9 @@ maxspeed_table_default = { -- List only exceptions maxspeed_table = { + ["ch:rural"] = 80, + ["ch:trunk"] = 100, + ["ch:motorway"] = 120, ["de:living_street"] = 7, ["ru:living_street"] = 20, ["ru:urban"] = 60, diff --git a/tools/components.cpp b/tools/components.cpp index 79b09e9f5..dae7eb414 100644 --- a/tools/components.cpp +++ b/tools/components.cpp @@ -52,7 +52,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include std::vector coordinate_list; -std::vector restriction_list; +std::vector restrictions_vector; std::vector bollard_node_list; std::vector traffic_lights_list; @@ -107,12 +107,12 @@ int main(int argc, char *argv[]) } uint32_t usable_restrictions = 0; restriction_ifstream.read((char *)&usable_restrictions, sizeof(uint32_t)); - restriction_list.resize(usable_restrictions); + restrictions_vector.resize(usable_restrictions); // load restrictions if (usable_restrictions > 0) { - restriction_ifstream.read((char *)&(restriction_list[0]), + restriction_ifstream.read((char *)&(restrictions_vector[0]), usable_restrictions * sizeof(TurnRestriction)); } restriction_ifstream.close(); @@ -130,14 +130,14 @@ int main(int argc, char *argv[]) bollard_node_list, traffic_lights_list, &coordinate_list, - restriction_list); + restrictions_vector); input_stream.close(); - BOOST_ASSERT_MSG(restriction_list.size() == usable_restrictions, - "size of restriction_list changed"); + BOOST_ASSERT_MSG(restrictions_vector.size() == usable_restrictions, + "size of restrictions_vector changed"); - SimpleLogger().Write() << restriction_list.size() << " restrictions, " + SimpleLogger().Write() << restrictions_vector.size() << " restrictions, " << bollard_node_list.size() << " bollard nodes, " << traffic_lights_list.size() << " traffic lights"; @@ -179,11 +179,9 @@ int main(int argc, char *argv[]) edge_list.shrink_to_fit(); SimpleLogger().Write() << "Starting SCC graph traversal"; - - RestrictionMap restriction_map(restriction_list); auto tarjan = osrm::make_unique>(graph, - restriction_map, - bollard_node_list); + bollard_node_list, + restrictions_vector); tarjan->Run(); // output