From 9792493fda54394ed19239ad93f2d86b80c879b7 Mon Sep 17 00:00:00 2001 From: Chau Nguyen Date: Thu, 11 Jan 2018 13:33:35 +0100 Subject: [PATCH 01/37] init commit --- include/extractor/extraction_turn.hpp | 89 ++++++++++++------- include/extractor/scripting_environment.hpp | 3 +- .../extractor/scripting_environment_lua.hpp | 2 +- profiles/bicycle.lua | 2 +- profiles/car.lua | 6 +- profiles/foot.lua | 4 +- src/extractor/edge_based_graph_factory.cpp | 19 ++-- src/extractor/graph_compressor.cpp | 18 ++-- src/extractor/scripting_environment_lua.cpp | 30 ++++--- 9 files changed, 99 insertions(+), 74 deletions(-) diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index 4f45a098750..63e272c6f5c 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -7,40 +7,61 @@ #include -namespace osrm -{ -namespace extractor -{ - -struct ExtractionTurn -{ - ExtractionTurn(double angle, - int number_of_roads, - bool is_u_turn, - bool has_traffic_light, - bool source_restricted, - bool target_restricted, - bool is_left_hand_driving, - TravelMode source_mode, - TravelMode target_mode) - : angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn), - has_traffic_light(has_traffic_light), source_restricted(source_restricted), - target_restricted(target_restricted), is_left_hand_driving(is_left_hand_driving), - weight(0.), duration(0.), source_mode(source_mode), target_mode(target_mode) - { - } - - const double angle; - const int number_of_roads; - const bool is_u_turn; - const bool has_traffic_light; - const bool source_restricted; - const bool target_restricted; - const bool is_left_hand_driving; - double weight; - double duration; - const TravelMode source_mode; - const TravelMode target_mode; +namespace osrm { +namespace extractor { + +struct ExtractionTurnLeg { + ExtractionTurnLeg(bool is_restricted, TravelMode mode, bool is_motorway, + bool is_link, int number_of_lanes) + : is_restricted(is_restricted), + mode(mode), + is_motorway(is_motorway), + is_link(is_link), + number_of_lanes(number_of_lanes) {} + + const bool is_restricted; + const TravelMode mode; + const bool is_motorway; + const bool is_link; + const int number_of_lanes; +}; + +struct ExtractionTurn { + ExtractionTurn(double angle, int number_of_roads, bool is_u_turn, + bool has_traffic_light, bool is_left_hand_driving) + : angle(180. - angle), + number_of_roads(number_of_roads), + is_u_turn(is_u_turn), + has_traffic_light(has_traffic_light), + is_left_hand_driving(is_left_hand_driving), + weight(0.), + duration(0.), + + // depr aaarghARGH @CHAUTODO + source_mode(TRAVEL_MODE_DRIVING), + target_mode(TRAVEL_MODE_DRIVING), + source_restricted(true), + target_restricted(true) {} + + const double angle; + const int number_of_roads; + const bool is_u_turn; + const bool has_traffic_light; + const bool is_left_hand_driving; + + // std::vector roads_on_the_right; + // std::vector roads_on_the_left; + + double weight; + double duration; + + + + // deprecated ARGH @CHAUTODO + const TravelMode source_mode; + const TravelMode target_mode; + const bool source_restricted; + const bool target_restricted; }; } } diff --git a/include/extractor/scripting_environment.hpp b/include/extractor/scripting_environment.hpp index e5ceb07866c..300aa134bb7 100644 --- a/include/extractor/scripting_environment.hpp +++ b/include/extractor/scripting_environment.hpp @@ -36,6 +36,7 @@ class ExtractionRelationContainer; struct ExtractionNode; struct ExtractionWay; struct ExtractionTurn; +struct ExtractionTurnLeg; struct ExtractionSegment; /** @@ -57,7 +58,7 @@ class ScriptingEnvironment virtual std::vector GetNameSuffixList() = 0; virtual std::vector GetRestrictions() = 0; virtual std::vector GetRelations() = 0; - virtual void ProcessTurn(ExtractionTurn &turn) = 0; + virtual void ProcessTurn(ExtractionTurn &turn, ExtractionTurnLeg &source, ExtractionTurnLeg &target) = 0; virtual void ProcessSegment(ExtractionSegment &segment) = 0; virtual void diff --git a/include/extractor/scripting_environment_lua.hpp b/include/extractor/scripting_environment_lua.hpp index b9b0cf62942..9300eda2a69 100644 --- a/include/extractor/scripting_environment_lua.hpp +++ b/include/extractor/scripting_environment_lua.hpp @@ -82,7 +82,7 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment std::vector GetClassNames() override; std::vector GetRestrictions() override; std::vector GetRelations() override; - void ProcessTurn(ExtractionTurn &turn) override; + void ProcessTurn(ExtractionTurn &turn, ExtractionTurnLeg &source, ExtractionTurnLeg &target) override; void ProcessSegment(ExtractionSegment &segment) override; void diff --git a/profiles/bicycle.lua b/profiles/bicycle.lua index 4014b02b0c8..e96c85b992f 100644 --- a/profiles/bicycle.lua +++ b/profiles/bicycle.lua @@ -557,7 +557,7 @@ function process_way(profile, way, result) WayHandlers.run(profile, way, result, data, handlers) end -function process_turn(profile, turn) +function process_turn(profile, turn, source, target) -- compute turn penalty as angle^2, with a left/right bias local normalized_angle = turn.angle / 90.0 if normalized_angle >= 0.0 then diff --git a/profiles/car.lua b/profiles/car.lua index c58a1612053..a929acabd17 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -423,7 +423,7 @@ function process_way(profile, way, result, relations) end end -function process_turn(profile, turn) +function process_turn(profile, turn, source, target) -- Use a sigmoid function to return a penalty that maxes out at turn_penalty -- over the space of 0-180 degrees. Values here were chosen by fitting -- the function to some turn penalty samples from real driving. @@ -434,7 +434,7 @@ function process_turn(profile, turn) turn.duration = profile.properties.traffic_light_penalty end - if turn.number_of_roads > 2 or turn.source_mode ~= turn.target_mode or turn.is_u_turn then + if turn.number_of_roads > 2 or source.mode ~= target.mode or turn.is_u_turn then if turn.angle >= 0 then turn.duration = turn.duration + turn_penalty / (1 + math.exp( -((13 / turn_bias) * turn.angle/180 - 6.5*turn_bias))) else @@ -455,7 +455,7 @@ function process_turn(profile, turn) if profile.properties.weight_name == 'routability' then -- penalize turns from non-local access only segments onto local access only tags - if not turn.source_restricted and turn.target_restricted then + if not source.is_restricted and target.is_restricted then turn.weight = constants.max_turn_weight end end diff --git a/profiles/foot.lua b/profiles/foot.lua index f0527337bf8..40e42cb8bcf 100644 --- a/profiles/foot.lua +++ b/profiles/foot.lua @@ -250,7 +250,7 @@ function process_way(profile, way, result) WayHandlers.run(profile, way, result, data, handlers) end -function process_turn (profile, turn) +function process_turn (profile, turn, source, target) turn.duration = 0. if turn.direction_modifier == direction_modifier.u_turn then @@ -262,7 +262,7 @@ function process_turn (profile, turn) end if profile.properties.weight_name == 'routability' then -- penalize turns from non-local access only segments onto local access only tags - if not turn.source_restricted and turn.target_restricted then + if not source.is_restricted and target.is_restricted then turn.weight = turn.weight + 3000 end end diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 43e92adfe5b..081fd8be1e3 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -603,13 +603,18 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( m_node_based_graph.GetOutDegree(intersection_node), turn.instruction.IsUTurn(), is_traffic_light, - edge_data1.flags.restricted, - edge_data2.flags.restricted, - m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data) - .is_left_hand_driving, - m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data).travel_mode, - m_edge_based_node_container.GetAnnotation(edge_data2.annotation_data).travel_mode); - scripting_environment.ProcessTurn(extracted_turn); + m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data).is_left_hand_driving); + ExtractionTurnLeg extracted_source_leg(edge_data1.flags.restricted, + m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data).travel_mode, + edge_data1.flags.road_classification.IsMotorwayClass(), + edge_data1.flags.road_classification.IsLinkClass(), + edge_data1.flags.road_classification.GetNumberOfLanes()); + ExtractionTurnLeg extracted_target_leg(edge_data2.flags.restricted, + m_edge_based_node_container.GetAnnotation(edge_data2.annotation_data).travel_mode, + edge_data2.flags.road_classification.IsMotorwayClass(), + edge_data2.flags.road_classification.IsLinkClass(), + edge_data2.flags.road_classification.GetNumberOfLanes()); + scripting_environment.ProcessTurn(extracted_turn, extracted_source_leg, extracted_target_leg); // turn penalties are limited to [-2^15, 2^15) which roughly // translates to 54 minutes and fits signed 16bit deci-seconds diff --git a/src/extractor/graph_compressor.cpp b/src/extractor/graph_compressor.cpp index 37f8ef32dd2..1bafe76665f 100644 --- a/src/extractor/graph_compressor.cpp +++ b/src/extractor/graph_compressor.cpp @@ -220,18 +220,12 @@ void GraphCompressor::Compress( continue; // generate an artifical turn for the turn penalty generation - ExtractionTurn extraction_turn( - 0, - 2, - false, - true, - fwd_edge_data1.flags.restricted, - fwd_edge_data2.flags.restricted, - node_data_container[fwd_edge_data1.annotation_data].is_left_hand_driving, - TRAVEL_MODE_DRIVING, - TRAVEL_MODE_DRIVING); - - scripting_environment.ProcessTurn(extraction_turn); + ExtractionTurn extraction_turn(0, 2, false, true, false); + ExtractionTurnLeg source_leg(false, TRAVEL_MODE_DRIVING, + false, false, 1); + ExtractionTurnLeg target_leg(false, TRAVEL_MODE_DRIVING, + false, false, 1); + scripting_environment.ProcessTurn(extraction_turn, source_leg, target_leg); node_duration_penalty = extraction_turn.duration * 10; node_weight_penalty = extraction_turn.weight * weight_multiplier; } diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index ae601243995..058b595acd5 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -670,6 +670,18 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) { case 4: { + context.state.new_usertype("ExtractionTurnLeg", + "is_restricted", + &ExtractionTurnLeg::is_restricted, + "mode", + &ExtractionTurnLeg::mode, + "is_motorway", + &ExtractionTurnLeg::is_motorway, + "is_link", + &ExtractionTurnLeg::is_link, + "number_of_lanes", + &ExtractionTurnLeg::number_of_lanes); + context.state.new_usertype("ExtractionTurn", "angle", &ExtractionTurn::angle, @@ -679,20 +691,12 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) &ExtractionTurn::is_u_turn, "has_traffic_light", &ExtractionTurn::has_traffic_light, + "is_left_hand_driving", + &ExtractionTurn::is_left_hand_driving, "weight", &ExtractionTurn::weight, "duration", - &ExtractionTurn::duration, - "source_restricted", - &ExtractionTurn::source_restricted, - "target_restricted", - &ExtractionTurn::target_restricted, - "is_left_hand_driving", - &ExtractionTurn::is_left_hand_driving, - "source_mode", - &ExtractionTurn::source_mode, - "target_mode", - &ExtractionTurn::target_mode); + &ExtractionTurn::duration); initV2Context(); break; } @@ -965,7 +969,7 @@ std::vector Sol2ScriptingEnvironment::GetRelations() } } -void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn) +void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn, ExtractionTurnLeg &source, ExtractionTurnLeg &target) { auto &context = GetSol2Context(); @@ -976,7 +980,7 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn) case 2: if (context.has_turn_penalty_function) { - context.turn_function(context.profile_table, turn); + context.turn_function(context.profile_table, turn, source, target); // Turn weight falls back to the duration value in deciseconds // or uses the extracted unit-less weight value From 9450f13e9d672bef519505428fe5040f8e445673 Mon Sep 17 00:00:00 2001 From: Chau Nguyen Date: Thu, 11 Jan 2018 22:47:50 +0100 Subject: [PATCH 02/37] prevent breaking API change --- include/extractor/extraction_turn.hpp | 66 ++++++++++---- include/extractor/scripting_environment.hpp | 2 +- .../extractor/scripting_environment_lua.hpp | 2 +- profiles/bicycle.lua | 2 +- profiles/car.lua | 6 +- profiles/foot.lua | 4 +- src/extractor/edge_based_graph_factory.cpp | 85 ++++++++++++++----- src/extractor/graph_compressor.cpp | 13 +-- src/extractor/scripting_environment_lua.cpp | 32 ++++++- 9 files changed, 158 insertions(+), 54 deletions(-) diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index 63e272c6f5c..737344b48f6 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -28,40 +28,70 @@ struct ExtractionTurnLeg { struct ExtractionTurn { ExtractionTurn(double angle, int number_of_roads, bool is_u_turn, - bool has_traffic_light, bool is_left_hand_driving) + bool has_traffic_light, bool is_left_hand_driving, + bool source_restricted, TravelMode source_mode, + bool source_is_motorway, bool source_is_link, + int source_number_of_lanes, bool target_restricted, + TravelMode target_mode, bool target_is_motorway, + bool target_is_link, int target_number_of_lanes, + std::vector &roads_on_the_right, + std::vector &roads_on_the_left) : angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn), has_traffic_light(has_traffic_light), is_left_hand_driving(is_left_hand_driving), - weight(0.), - duration(0.), - // depr aaarghARGH @CHAUTODO - source_mode(TRAVEL_MODE_DRIVING), - target_mode(TRAVEL_MODE_DRIVING), - source_restricted(true), - target_restricted(true) {} + source_restricted(source_restricted), + source_mode(source_mode), + source_is_motorway(source_is_motorway), + source_is_link(source_is_link), + source_number_of_lanes(source_number_of_lanes), + + target_restricted(target_restricted), + target_mode(target_mode), + target_is_motorway(target_is_motorway), + target_is_link(target_is_link), + target_number_of_lanes(target_number_of_lanes), + roads_on_the_right(roads_on_the_right), + roads_on_the_left(roads_on_the_left), + weight(0.), + duration(0.) + + { + BOOST_ASSERT_MSG( + !is_u_turn || roads_on_the_left.size() == 0, + "there cannot be roads on the left when there is a u turn"); + BOOST_ASSERT_MSG(roads_on_the_right.size() + roads_on_the_left.size() + is_u_turn + 2 == + number_of_roads, + "number of roads at intersection do not match"); + } const double angle; const int number_of_roads; const bool is_u_turn; const bool has_traffic_light; const bool is_left_hand_driving; - // std::vector roads_on_the_right; - // std::vector roads_on_the_left; - - double weight; - double duration; + // source info + const bool source_restricted; + const TravelMode source_mode; + const bool source_is_motorway; + const bool source_is_link; + const int source_number_of_lanes; + // target info + const bool target_restricted; + const TravelMode target_mode; + const bool target_is_motorway; + const bool target_is_link; + const int target_number_of_lanes; + const std::vector roads_on_the_right; + const std::vector roads_on_the_left; - // deprecated ARGH @CHAUTODO - const TravelMode source_mode; - const TravelMode target_mode; - const bool source_restricted; - const bool target_restricted; + double weight; + double duration; }; } } diff --git a/include/extractor/scripting_environment.hpp b/include/extractor/scripting_environment.hpp index 300aa134bb7..75e8b241756 100644 --- a/include/extractor/scripting_environment.hpp +++ b/include/extractor/scripting_environment.hpp @@ -58,7 +58,7 @@ class ScriptingEnvironment virtual std::vector GetNameSuffixList() = 0; virtual std::vector GetRestrictions() = 0; virtual std::vector GetRelations() = 0; - virtual void ProcessTurn(ExtractionTurn &turn, ExtractionTurnLeg &source, ExtractionTurnLeg &target) = 0; + virtual void ProcessTurn(ExtractionTurn &turn) = 0; virtual void ProcessSegment(ExtractionSegment &segment) = 0; virtual void diff --git a/include/extractor/scripting_environment_lua.hpp b/include/extractor/scripting_environment_lua.hpp index 9300eda2a69..b9b0cf62942 100644 --- a/include/extractor/scripting_environment_lua.hpp +++ b/include/extractor/scripting_environment_lua.hpp @@ -82,7 +82,7 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment std::vector GetClassNames() override; std::vector GetRestrictions() override; std::vector GetRelations() override; - void ProcessTurn(ExtractionTurn &turn, ExtractionTurnLeg &source, ExtractionTurnLeg &target) override; + void ProcessTurn(ExtractionTurn &turn) override; void ProcessSegment(ExtractionSegment &segment) override; void diff --git a/profiles/bicycle.lua b/profiles/bicycle.lua index e96c85b992f..4014b02b0c8 100644 --- a/profiles/bicycle.lua +++ b/profiles/bicycle.lua @@ -557,7 +557,7 @@ function process_way(profile, way, result) WayHandlers.run(profile, way, result, data, handlers) end -function process_turn(profile, turn, source, target) +function process_turn(profile, turn) -- compute turn penalty as angle^2, with a left/right bias local normalized_angle = turn.angle / 90.0 if normalized_angle >= 0.0 then diff --git a/profiles/car.lua b/profiles/car.lua index a929acabd17..c58a1612053 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -423,7 +423,7 @@ function process_way(profile, way, result, relations) end end -function process_turn(profile, turn, source, target) +function process_turn(profile, turn) -- Use a sigmoid function to return a penalty that maxes out at turn_penalty -- over the space of 0-180 degrees. Values here were chosen by fitting -- the function to some turn penalty samples from real driving. @@ -434,7 +434,7 @@ function process_turn(profile, turn, source, target) turn.duration = profile.properties.traffic_light_penalty end - if turn.number_of_roads > 2 or source.mode ~= target.mode or turn.is_u_turn then + if turn.number_of_roads > 2 or turn.source_mode ~= turn.target_mode or turn.is_u_turn then if turn.angle >= 0 then turn.duration = turn.duration + turn_penalty / (1 + math.exp( -((13 / turn_bias) * turn.angle/180 - 6.5*turn_bias))) else @@ -455,7 +455,7 @@ function process_turn(profile, turn, source, target) if profile.properties.weight_name == 'routability' then -- penalize turns from non-local access only segments onto local access only tags - if not source.is_restricted and target.is_restricted then + if not turn.source_restricted and turn.target_restricted then turn.weight = constants.max_turn_weight end end diff --git a/profiles/foot.lua b/profiles/foot.lua index 40e42cb8bcf..f0527337bf8 100644 --- a/profiles/foot.lua +++ b/profiles/foot.lua @@ -250,7 +250,7 @@ function process_way(profile, way, result) WayHandlers.run(profile, way, result, data, handlers) end -function process_turn (profile, turn, source, target) +function process_turn (profile, turn) turn.duration = 0. if turn.direction_modifier == direction_modifier.u_turn then @@ -262,7 +262,7 @@ function process_turn (profile, turn, source, target) end if profile.properties.weight_name == 'routability' then -- penalize turns from non-local access only segments onto local access only tags - if not source.is_restricted and target.is_restricted then + if not turn.source_restricted and turn.target_restricted then turn.weight = turn.weight + 3000 end end diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 081fd8be1e3..6d0f6027acd 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -562,7 +562,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const auto node_based_edge_to, const auto incoming_bearing, const auto &turn, - const auto entry_class_id) { + const auto entry_class_id, + const auto &node_based_edges_right, + const auto &node_based_edges_left) { const auto node_restricted = isRestricted(node_along_road_entering, intersection_node, @@ -598,23 +600,48 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // compute weight and duration penalties auto is_traffic_light = m_traffic_lights.count(intersection_node); + std::vector roads_on_the_right; + std::vector roads_on_the_left; + for (auto eid : node_based_edges_right) { + const auto &edge_data = m_node_based_graph.GetEdgeData(eid); + roads_on_the_right.emplace_back(edge_data.flags.restricted, + m_edge_based_node_container.GetAnnotation(edge_data.annotation_data).travel_mode, + edge_data.flags.road_classification.IsMotorwayClass(), + edge_data.flags.road_classification.IsLinkClass(), + edge_data.flags.road_classification.GetNumberOfLanes()); + } + for (auto eid : node_based_edges_left) { + const auto &edge_data = m_node_based_graph.GetEdgeData(eid); + roads_on_the_left.emplace_back(edge_data.flags.restricted, + m_edge_based_node_container.GetAnnotation(edge_data.annotation_data).travel_mode, + edge_data.flags.road_classification.IsMotorwayClass(), + edge_data.flags.road_classification.IsLinkClass(), + edge_data.flags.road_classification.GetNumberOfLanes()); + } + ExtractionTurn extracted_turn( - turn.angle, - m_node_based_graph.GetOutDegree(intersection_node), - turn.instruction.IsUTurn(), - is_traffic_light, - m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data).is_left_hand_driving); - ExtractionTurnLeg extracted_source_leg(edge_data1.flags.restricted, - m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data).travel_mode, - edge_data1.flags.road_classification.IsMotorwayClass(), - edge_data1.flags.road_classification.IsLinkClass(), - edge_data1.flags.road_classification.GetNumberOfLanes()); - ExtractionTurnLeg extracted_target_leg(edge_data2.flags.restricted, - m_edge_based_node_container.GetAnnotation(edge_data2.annotation_data).travel_mode, - edge_data2.flags.road_classification.IsMotorwayClass(), - edge_data2.flags.road_classification.IsLinkClass(), - edge_data2.flags.road_classification.GetNumberOfLanes()); - scripting_environment.ProcessTurn(extracted_turn, extracted_source_leg, extracted_target_leg); + turn.angle, m_node_based_graph.GetOutDegree(intersection_node), + turn.instruction.IsUTurn(), is_traffic_light, + m_edge_based_node_container + .GetAnnotation(edge_data1.annotation_data) + .is_left_hand_driving, + edge_data1.flags.restricted, + m_edge_based_node_container + .GetAnnotation(edge_data1.annotation_data) + .travel_mode, + edge_data1.flags.road_classification.IsMotorwayClass(), + edge_data1.flags.road_classification.IsLinkClass(), + edge_data1.flags.road_classification.GetNumberOfLanes(), + edge_data2.flags.restricted, + m_edge_based_node_container + .GetAnnotation(edge_data2.annotation_data) + .travel_mode, + edge_data2.flags.road_classification.IsMotorwayClass(), + edge_data2.flags.road_classification.IsLinkClass(), + edge_data2.flags.road_classification.GetNumberOfLanes(), + roads_on_the_right, roads_on_the_left); + scripting_environment.ProcessTurn( + extracted_turn); // turn penalties are limited to [-2^15, 2^15) which roughly // translates to 54 minutes and fits signed 16bit deci-seconds @@ -785,6 +812,18 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( OSRM_ASSERT(turn != intersection.end(), m_coordinates[intersection_node]); + + // memory problem @CHAUTODO? + std::vector node_based_edges_right; + std::vector node_based_edges_left; + std::size_t outgoing_pos = turn - intersection.begin(); + for (std::size_t connected_road = 0; connected_road < outgoing_pos; connected_road++) { + node_based_edges_right.push_back(intersection[connected_road].eid); + } + for (std::size_t connected_road = outgoing_pos+1; connected_road < intersection.size(); connected_road++) { + node_based_edges_left.push_back(intersection[connected_road].eid); + } + // In case a way restriction starts at a given location, add a turn onto // every artificial node eminating here. // @@ -822,7 +861,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( outgoing_edge.edge, reversed_incoming_bearing, *turn, - entry_class_id); + entry_class_id, + node_based_edges_right, + node_based_edges_left); buffer->continuous_data.edges_list.push_back( edge_with_data_and_condition.first.edge); @@ -884,7 +925,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( outgoing_edge.edge, reversed_incoming_bearing, *turn, - entry_class_id); + entry_class_id, + node_based_edges_right, + node_based_edges_left); buffer->delayed_data.push_back( std::move(edge_with_data_and_condition.first)); @@ -918,7 +961,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( outgoing_edge.edge, reversed_incoming_bearing, *turn, - entry_class_id); + entry_class_id, + node_based_edges_right, + node_based_edges_left); buffer->delayed_data.push_back( std::move(edge_with_data_and_condition.first)); diff --git a/src/extractor/graph_compressor.cpp b/src/extractor/graph_compressor.cpp index 1bafe76665f..275b1f4901d 100644 --- a/src/extractor/graph_compressor.cpp +++ b/src/extractor/graph_compressor.cpp @@ -220,12 +220,13 @@ void GraphCompressor::Compress( continue; // generate an artifical turn for the turn penalty generation - ExtractionTurn extraction_turn(0, 2, false, true, false); - ExtractionTurnLeg source_leg(false, TRAVEL_MODE_DRIVING, - false, false, 1); - ExtractionTurnLeg target_leg(false, TRAVEL_MODE_DRIVING, - false, false, 1); - scripting_environment.ProcessTurn(extraction_turn, source_leg, target_leg); + std::vector roads_on_the_right; + std::vector roads_on_the_left; + ExtractionTurn extraction_turn(0, 2, false, true, false, + false, TRAVEL_MODE_DRIVING, false, false, 1, + false, TRAVEL_MODE_DRIVING, false, false, 1, + roads_on_the_right, roads_on_the_left); + scripting_environment.ProcessTurn(extraction_turn); node_duration_penalty = extraction_turn.duration * 10; node_weight_penalty = extraction_turn.weight * weight_multiplier; } diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index 058b595acd5..a7d3e5417ce 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -693,6 +693,34 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) &ExtractionTurn::has_traffic_light, "is_left_hand_driving", &ExtractionTurn::is_left_hand_driving, + + "source_restricted", + &ExtractionTurn::source_restricted, + "source_mode", + &ExtractionTurn::source_mode, + "source_is_motorway", + &ExtractionTurn::source_is_motorway, + "source_is_link", + &ExtractionTurn::source_is_link, + "source_number_of_lanes", + &ExtractionTurn::source_number_of_lanes, + + "target_restricted", + &ExtractionTurn::target_restricted, + "target_mode", + &ExtractionTurn::target_mode, + "target_is_motorway", + &ExtractionTurn::target_is_motorway, + "target_is_link", + &ExtractionTurn::target_is_link, + "target_number_of_lanes", + &ExtractionTurn::target_number_of_lanes, + + + "roads_on_the_right", + &ExtractionTurn::roads_on_the_right, + "roads_on_the_left", + &ExtractionTurn::roads_on_the_left, "weight", &ExtractionTurn::weight, "duration", @@ -969,7 +997,7 @@ std::vector Sol2ScriptingEnvironment::GetRelations() } } -void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn, ExtractionTurnLeg &source, ExtractionTurnLeg &target) +void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn) { auto &context = GetSol2Context(); @@ -980,7 +1008,7 @@ void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn, ExtractionTurnL case 2: if (context.has_turn_penalty_function) { - context.turn_function(context.profile_table, turn, source, target); + context.turn_function(context.profile_table, turn); // Turn weight falls back to the duration value in deciseconds // or uses the extracted unit-less weight value From 6775d86b00752335b3ab17376cc740f399650f98 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Mon, 15 Jan 2018 10:18:53 +0100 Subject: [PATCH 03/37] set and store highway and access classification for the turn function --- include/extractor/extraction_way.hpp | 6 ++++++ include/extractor/node_based_edge.hpp | 13 ++++++++--- include/extractor/scripting_environment.hpp | 1 - profiles/car.lua | 24 ++++++++++++++++++++- profiles/lib/way_handlers.lua | 15 +++++++++++++ src/extractor/extractor_callbacks.cpp | 18 ++++++++++++++-- src/extractor/scripting_environment_lua.cpp | 6 +++++- 7 files changed, 75 insertions(+), 8 deletions(-) diff --git a/include/extractor/extraction_way.hpp b/include/extractor/extraction_way.hpp index a44fb2140f2..04c427a7a43 100644 --- a/include/extractor/extraction_way.hpp +++ b/include/extractor/extraction_way.hpp @@ -63,6 +63,8 @@ struct ExtractionWay forward_restricted = false; backward_restricted = false; is_left_hand_driving = false; + highway_turn_classification = 0; + access_turn_classification = 0; } // wrappers to allow assigning nil (nullptr) to string values @@ -123,6 +125,10 @@ struct ExtractionWay bool backward_restricted : 1; bool is_left_hand_driving : 1; bool : 2; + + // user classifications for turn penalties + std::uint8_t highway_turn_classification; // @CHAUTODO memory? limit to 3 bits? // 8 + std::uint8_t access_turn_classification; // 3 are enough }; } } diff --git a/include/extractor/node_based_edge.hpp b/include/extractor/node_based_edge.hpp index baa34e98de5..0ef2642bc11 100644 --- a/include/extractor/node_based_edge.hpp +++ b/include/extractor/node_based_edge.hpp @@ -27,6 +27,10 @@ struct NodeBasedEdgeClassification std::uint8_t startpoint : 1; // 1 std::uint8_t restricted : 1; // 1 guidance::RoadClassification road_classification; // 16 2 + std::uint8_t highway_classification; // @CHAUTODO memory? limit to 3 bits? // 8 + std::uint8_t access_classification; // 3 are enough // 8 + std::uint8_t speed; // one bit could be saved here too I guess, so 7 // 8 + NodeBasedEdgeClassification(); @@ -37,10 +41,13 @@ struct NodeBasedEdgeClassification const bool circular, const bool startpoint, const bool restricted, - guidance::RoadClassification road_classification) + guidance::RoadClassification road_classification, + const std::uint8_t highway_classification, + const std::uint8_t access_classification, + const std::uint8_t speed) : forward(forward), backward(backward), is_split(is_split), roundabout(roundabout), circular(circular), startpoint(startpoint), restricted(restricted), - road_classification(road_classification) + road_classification(road_classification), highway_classification(highway_classification), access_classification(access_classification), speed(speed) { } @@ -183,7 +190,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM() { } -static_assert(sizeof(extractor::NodeBasedEdge) == 28, +static_assert(sizeof(extractor::NodeBasedEdge) == 32, "Size of extractor::NodeBasedEdge type is " "bigger than expected. This will influence " "memory consumption."); diff --git a/include/extractor/scripting_environment.hpp b/include/extractor/scripting_environment.hpp index 75e8b241756..e5ceb07866c 100644 --- a/include/extractor/scripting_environment.hpp +++ b/include/extractor/scripting_environment.hpp @@ -36,7 +36,6 @@ class ExtractionRelationContainer; struct ExtractionNode; struct ExtractionWay; struct ExtractionTurn; -struct ExtractionTurnLeg; struct ExtractionSegment; /** diff --git a/profiles/car.lua b/profiles/car.lua index c58a1612053..128acaadd07 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -298,6 +298,25 @@ function setup() relation_types = Sequence { "route" + }, + + highway_turn_classification = { + ['motorway'] = 0, + ['motorway_link'] = 0, + ['trunk'] = 0, + ['trunk_link'] = 0, + ['primary'] = 0, + ['primary_link'] = 0, + ['secondary'] = 1, + ['secondary_link'] = 1, + ['tertiary'] = 2, + ['tertiary_link'] = 2, + ['residential'] = 3, + ['living_street'] = 3, + ['unclassified'] = 1 + }, + + access_turn_classification = { } } end @@ -413,7 +432,10 @@ function process_way(profile, way, result, relations) WayHandlers.names, -- set weight properties of the way - WayHandlers.weights + WayHandlers.weights, + + -- set classification of ways relevant for turns + WayHandlers.way_classification_for_turn } WayHandlers.run(profile, way, result, data, handlers, relations) diff --git a/profiles/lib/way_handlers.lua b/profiles/lib/way_handlers.lua index 58d25f11039..d0ee490c363 100644 --- a/profiles/lib/way_handlers.lua +++ b/profiles/lib/way_handlers.lua @@ -221,6 +221,21 @@ function WayHandlers.hov(profile,way,result,data) end end + +-- set highway and access classification by user preference +function WayHandlers.way_classification_for_turn(profile,way,result,data) + local highway = way:get_value_by_key("highway") + local access = way:get_value_by_key("access") + + if highway and profile.highway_turn_classification[highway] then + result.highway_turn_classification = profile.highway_turn_classification[highway] + end + if access and profile.access_turn_classification[access] then + result.access_turn_classification = profile.access_turn_classification[access] + end +end + + -- check accessibility by traversing our access tag hierarchy function WayHandlers.access(profile,way,result,data) data.forward_access, data.backward_access = diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index 184adf268b2..8bd5ed1d32b 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -405,6 +405,9 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti forward_classes, parsed_way.forward_travel_mode, parsed_way.is_left_hand_driving}); + + std::uint8_t speed = parsed_way.forward_speed > 255 ? 255 : parsed_way.forward_speed; + util::for_each_pair( nodes.cbegin(), nodes.cend(), @@ -423,7 +426,11 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti parsed_way.circular, parsed_way.is_startpoint, parsed_way.forward_restricted, - road_classification}}; + road_classification, + // @CHAUTODO + parsed_way.highway_turn_classification, + parsed_way.access_turn_classification, + speed}}; external_memory.all_edges_list.push_back(InternalExtractorEdge( std::move(edge), forward_weight_data, forward_duration_data, {})); @@ -438,6 +445,8 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti backward_classes, parsed_way.backward_travel_mode, parsed_way.is_left_hand_driving}); + + std::uint8_t speed = parsed_way.backward_speed > 255 ? 255 : parsed_way.backward_speed; util::for_each_pair( nodes.cbegin(), nodes.cend(), @@ -456,7 +465,12 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti parsed_way.circular, parsed_way.is_startpoint, parsed_way.backward_restricted, - road_classification}}; + road_classification, + // @CHAUTODO + parsed_way.highway_turn_classification, + parsed_way.access_turn_classification, + speed + }}; external_memory.all_edges_list.push_back(InternalExtractorEdge( std::move(edge), backward_weight_data, backward_duration_data, {})); diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index a7d3e5417ce..db16bb2c657 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -346,7 +346,11 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) [](ExtractionWay &way, bool flag) { way.backward_restricted = flag; }), "is_left_hand_driving", sol::property([](const ExtractionWay &way) { return way.is_left_hand_driving; }, - [](ExtractionWay &way, bool flag) { way.is_left_hand_driving = flag; })); + [](ExtractionWay &way, bool flag) { way.is_left_hand_driving = flag; }), + "highway_turn_classification", + &ExtractionWay::highway_turn_classification, + "access_turn_classification", + &ExtractionWay::access_turn_classification); auto getTypedRefBySol = [](const sol::object &obj) -> ExtractionRelation::OsmIDTyped { if (obj.is()) From 2a29c64fdabcb747622db121e3db6adb8155b82d Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Mon, 15 Jan 2018 11:43:33 +0100 Subject: [PATCH 04/37] expose highway turn classification and access turn classification and speed to the lua profile turn function --- include/extractor/extraction_turn.hpp | 28 ++++++++++++++++++--- include/extractor/node_based_edge.hpp | 10 ++++---- src/extractor/edge_based_graph_factory.cpp | 16 ++++++++++-- src/extractor/graph_compressor.cpp | 4 +-- src/extractor/scripting_environment_lua.cpp | 14 ++++++++++- 5 files changed, 59 insertions(+), 13 deletions(-) diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index 737344b48f6..c93f2ff3fc9 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -12,18 +12,24 @@ namespace extractor { struct ExtractionTurnLeg { ExtractionTurnLeg(bool is_restricted, TravelMode mode, bool is_motorway, - bool is_link, int number_of_lanes) + bool is_link, int number_of_lanes, int highway_turn_classification, int access_turn_classification, int speed) : is_restricted(is_restricted), mode(mode), is_motorway(is_motorway), is_link(is_link), - number_of_lanes(number_of_lanes) {} + number_of_lanes(number_of_lanes), + highway_turn_classification(highway_turn_classification), + access_turn_classification(access_turn_classification), + speed(speed) {} const bool is_restricted; const TravelMode mode; const bool is_motorway; const bool is_link; const int number_of_lanes; + const int highway_turn_classification; + const int access_turn_classification; + const int speed; }; struct ExtractionTurn { @@ -31,9 +37,13 @@ struct ExtractionTurn { bool has_traffic_light, bool is_left_hand_driving, bool source_restricted, TravelMode source_mode, bool source_is_motorway, bool source_is_link, - int source_number_of_lanes, bool target_restricted, + int source_number_of_lanes, + int source_highway_turn_classification, + int source_access_turn_classification, int source_speed, bool target_restricted, TravelMode target_mode, bool target_is_motorway, bool target_is_link, int target_number_of_lanes, + int target_highway_turn_classification, + int target_access_turn_classification, int target_speed, std::vector &roads_on_the_right, std::vector &roads_on_the_left) : angle(180. - angle), @@ -47,12 +57,18 @@ struct ExtractionTurn { source_is_motorway(source_is_motorway), source_is_link(source_is_link), source_number_of_lanes(source_number_of_lanes), + source_highway_turn_classification(source_highway_turn_classification), + source_access_turn_classification(source_access_turn_classification), + source_speed(source_speed), target_restricted(target_restricted), target_mode(target_mode), target_is_motorway(target_is_motorway), target_is_link(target_is_link), target_number_of_lanes(target_number_of_lanes), + target_highway_turn_classification(target_highway_turn_classification), + target_access_turn_classification(target_access_turn_classification), + target_speed(target_speed), roads_on_the_right(roads_on_the_right), roads_on_the_left(roads_on_the_left), @@ -79,6 +95,9 @@ struct ExtractionTurn { const bool source_is_motorway; const bool source_is_link; const int source_number_of_lanes; + const int source_highway_turn_classification; + const int source_access_turn_classification; + const int source_speed; // target info const bool target_restricted; @@ -86,6 +105,9 @@ struct ExtractionTurn { const bool target_is_motorway; const bool target_is_link; const int target_number_of_lanes; + const int target_highway_turn_classification; + const int target_access_turn_classification; + const int target_speed; const std::vector roads_on_the_right; const std::vector roads_on_the_left; diff --git a/include/extractor/node_based_edge.hpp b/include/extractor/node_based_edge.hpp index 0ef2642bc11..be2f234f44f 100644 --- a/include/extractor/node_based_edge.hpp +++ b/include/extractor/node_based_edge.hpp @@ -27,8 +27,8 @@ struct NodeBasedEdgeClassification std::uint8_t startpoint : 1; // 1 std::uint8_t restricted : 1; // 1 guidance::RoadClassification road_classification; // 16 2 - std::uint8_t highway_classification; // @CHAUTODO memory? limit to 3 bits? // 8 - std::uint8_t access_classification; // 3 are enough // 8 + std::uint8_t highway_turn_classification; // @CHAUTODO memory? limit to 3 bits? // 8 + std::uint8_t access_turn_classification; // 3 are enough // 8 std::uint8_t speed; // one bit could be saved here too I guess, so 7 // 8 @@ -42,12 +42,12 @@ struct NodeBasedEdgeClassification const bool startpoint, const bool restricted, guidance::RoadClassification road_classification, - const std::uint8_t highway_classification, - const std::uint8_t access_classification, + const std::uint8_t highway_turn_classification, + const std::uint8_t access_turn_classification, const std::uint8_t speed) : forward(forward), backward(backward), is_split(is_split), roundabout(roundabout), circular(circular), startpoint(startpoint), restricted(restricted), - road_classification(road_classification), highway_classification(highway_classification), access_classification(access_classification), speed(speed) + road_classification(road_classification), highway_turn_classification(highway_turn_classification), access_turn_classification(access_turn_classification), speed(speed) { } diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 6d0f6027acd..f61813af405 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -608,7 +608,10 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( m_edge_based_node_container.GetAnnotation(edge_data.annotation_data).travel_mode, edge_data.flags.road_classification.IsMotorwayClass(), edge_data.flags.road_classification.IsLinkClass(), - edge_data.flags.road_classification.GetNumberOfLanes()); + edge_data.flags.road_classification.GetNumberOfLanes(), + edge_data.flags.highway_turn_classification, + edge_data.flags.access_turn_classification, + edge_data.flags.speed); } for (auto eid : node_based_edges_left) { const auto &edge_data = m_node_based_graph.GetEdgeData(eid); @@ -616,7 +619,10 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( m_edge_based_node_container.GetAnnotation(edge_data.annotation_data).travel_mode, edge_data.flags.road_classification.IsMotorwayClass(), edge_data.flags.road_classification.IsLinkClass(), - edge_data.flags.road_classification.GetNumberOfLanes()); + edge_data.flags.road_classification.GetNumberOfLanes(), + edge_data.flags.highway_turn_classification, + edge_data.flags.access_turn_classification, + edge_data.flags.speed); } ExtractionTurn extracted_turn( @@ -632,6 +638,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data1.flags.road_classification.IsMotorwayClass(), edge_data1.flags.road_classification.IsLinkClass(), edge_data1.flags.road_classification.GetNumberOfLanes(), + edge_data1.flags.highway_turn_classification, + edge_data1.flags.access_turn_classification, + edge_data1.flags.speed, edge_data2.flags.restricted, m_edge_based_node_container .GetAnnotation(edge_data2.annotation_data) @@ -639,6 +648,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data2.flags.road_classification.IsMotorwayClass(), edge_data2.flags.road_classification.IsLinkClass(), edge_data2.flags.road_classification.GetNumberOfLanes(), + edge_data2.flags.highway_turn_classification, + edge_data2.flags.access_turn_classification, + edge_data2.flags.speed, roads_on_the_right, roads_on_the_left); scripting_environment.ProcessTurn( extracted_turn); diff --git a/src/extractor/graph_compressor.cpp b/src/extractor/graph_compressor.cpp index 275b1f4901d..4a9206ed188 100644 --- a/src/extractor/graph_compressor.cpp +++ b/src/extractor/graph_compressor.cpp @@ -223,8 +223,8 @@ void GraphCompressor::Compress( std::vector roads_on_the_right; std::vector roads_on_the_left; ExtractionTurn extraction_turn(0, 2, false, true, false, - false, TRAVEL_MODE_DRIVING, false, false, 1, - false, TRAVEL_MODE_DRIVING, false, false, 1, + false, TRAVEL_MODE_DRIVING, false, false, 1, 0,0,0, + false, TRAVEL_MODE_DRIVING, false, false, 1, 0,0,0, roads_on_the_right, roads_on_the_left); scripting_environment.ProcessTurn(extraction_turn); node_duration_penalty = extraction_turn.duration * 10; diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index db16bb2c657..819788ee48e 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -684,7 +684,11 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) "is_link", &ExtractionTurnLeg::is_link, "number_of_lanes", - &ExtractionTurnLeg::number_of_lanes); + &ExtractionTurnLeg::number_of_lanes, + "highway_turn_classification", + &ExtractionTurnLeg::highway_turn_classification, + "access_turn_classification", + &ExtractionTurnLeg::access_turn_classification); context.state.new_usertype("ExtractionTurn", "angle", @@ -708,6 +712,10 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) &ExtractionTurn::source_is_link, "source_number_of_lanes", &ExtractionTurn::source_number_of_lanes, + "source_highway_turn_classification", + &ExtractionTurn::source_highway_turn_classification, + "source_access_turn_classification", + &ExtractionTurn::source_access_turn_classification, "target_restricted", &ExtractionTurn::target_restricted, @@ -719,6 +727,10 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) &ExtractionTurn::target_is_link, "target_number_of_lanes", &ExtractionTurn::target_number_of_lanes, + "target_highway_turn_classification", + &ExtractionTurn::target_highway_turn_classification, + "target_access_turn_classification", + &ExtractionTurn::target_access_turn_classification, "roads_on_the_right", From 329187c12bfb5d814615bf30974e447fe6ea7c40 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Mon, 15 Jan 2018 18:30:02 +0100 Subject: [PATCH 05/37] expose whether connection road at turn is incoming or outgoing --- include/extractor/extraction_turn.hpp | 49 ++++++---- src/extractor/edge_based_graph_factory.cpp | 100 +++++++++++---------- 2 files changed, 85 insertions(+), 64 deletions(-) diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index c93f2ff3fc9..9fcee1db194 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -12,7 +12,10 @@ namespace extractor { struct ExtractionTurnLeg { ExtractionTurnLeg(bool is_restricted, TravelMode mode, bool is_motorway, - bool is_link, int number_of_lanes, int highway_turn_classification, int access_turn_classification, int speed) + bool is_link, int number_of_lanes, + int highway_turn_classification, + int access_turn_classification, int speed, bool is_incoming, + bool is_outgoing) : is_restricted(is_restricted), mode(mode), is_motorway(is_motorway), @@ -20,7 +23,9 @@ struct ExtractionTurnLeg { number_of_lanes(number_of_lanes), highway_turn_classification(highway_turn_classification), access_turn_classification(access_turn_classification), - speed(speed) {} + speed(speed), + is_incoming(is_incoming), + is_outgoing(is_outgoing) {} const bool is_restricted; const TravelMode mode; @@ -30,26 +35,31 @@ struct ExtractionTurnLeg { const int highway_turn_classification; const int access_turn_classification; const int speed; + const bool is_incoming; + const bool is_outgoing; }; struct ExtractionTurn { - ExtractionTurn(double angle, int number_of_roads, bool is_u_turn, - bool has_traffic_light, bool is_left_hand_driving, - bool source_restricted, TravelMode source_mode, - bool source_is_motorway, bool source_is_link, - int source_number_of_lanes, - int source_highway_turn_classification, - int source_access_turn_classification, int source_speed, bool target_restricted, - TravelMode target_mode, bool target_is_motorway, - bool target_is_link, int target_number_of_lanes, - int target_highway_turn_classification, - int target_access_turn_classification, int target_speed, - std::vector &roads_on_the_right, - std::vector &roads_on_the_left) + ExtractionTurn( + double angle, int number_of_roads, bool is_u_turn, bool has_traffic_light, + // bool is_stop, bool is_give_way, + bool is_left_hand_driving, bool source_restricted, TravelMode source_mode, + bool source_is_motorway, bool source_is_link, + + int source_number_of_lanes, int source_highway_turn_classification, + int source_access_turn_classification, int source_speed, + bool target_restricted, TravelMode target_mode, bool target_is_motorway, + bool target_is_link, int target_number_of_lanes, + int target_highway_turn_classification, + int target_access_turn_classification, int target_speed, + std::vector &roads_on_the_right, + std::vector &roads_on_the_left) : angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn), has_traffic_light(has_traffic_light), + // is_stop(is_stop), + // is_give_way(is_give_way), is_left_hand_driving(is_left_hand_driving), source_restricted(source_restricted), @@ -79,14 +89,17 @@ struct ExtractionTurn { BOOST_ASSERT_MSG( !is_u_turn || roads_on_the_left.size() == 0, "there cannot be roads on the left when there is a u turn"); - BOOST_ASSERT_MSG(roads_on_the_right.size() + roads_on_the_left.size() + is_u_turn + 2 == - number_of_roads, - "number of roads at intersection do not match"); + BOOST_ASSERT_MSG( + roads_on_the_right.size() + roads_on_the_left.size() + is_u_turn + 2 == + number_of_roads, + "number of roads at intersection do not match"); } const double angle; const int number_of_roads; const bool is_u_turn; const bool has_traffic_light; + // const bool is_stop; + // const bool is_give_way; const bool is_left_hand_driving; // source info diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index f61813af405..2337f4ab9d9 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -563,8 +563,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const auto incoming_bearing, const auto &turn, const auto entry_class_id, - const auto &node_based_edges_right, - const auto &node_based_edges_left) { + const auto &intersection) { const auto node_restricted = isRestricted(node_along_road_entering, intersection_node, @@ -600,29 +599,52 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // compute weight and duration penalties auto is_traffic_light = m_traffic_lights.count(intersection_node); - std::vector roads_on_the_right; - std::vector roads_on_the_left; - for (auto eid : node_based_edges_right) { - const auto &edge_data = m_node_based_graph.GetEdgeData(eid); - roads_on_the_right.emplace_back(edge_data.flags.restricted, - m_edge_based_node_container.GetAnnotation(edge_data.annotation_data).travel_mode, - edge_data.flags.road_classification.IsMotorwayClass(), - edge_data.flags.road_classification.IsLinkClass(), - edge_data.flags.road_classification.GetNumberOfLanes(), - edge_data.flags.highway_turn_classification, - edge_data.flags.access_turn_classification, - edge_data.flags.speed); - } - for (auto eid : node_based_edges_left) { - const auto &edge_data = m_node_based_graph.GetEdgeData(eid); - roads_on_the_left.emplace_back(edge_data.flags.restricted, - m_edge_based_node_container.GetAnnotation(edge_data.annotation_data).travel_mode, - edge_data.flags.road_classification.IsMotorwayClass(), - edge_data.flags.road_classification.IsLinkClass(), - edge_data.flags.road_classification.GetNumberOfLanes(), - edge_data.flags.highway_turn_classification, - edge_data.flags.access_turn_classification, - edge_data.flags.speed); + std::vector road_legs_on_the_right; + std::vector road_legs_on_the_left; + + auto turn_iter = std::find_if(intersection.begin(), intersection.end(), [&turn](const auto &road){return road.eid == turn.eid;}); + + if (turn_iter == intersection.begin()) { + for (auto connected_edge = intersection.begin() + 1; connected_edge < intersection.end(); connected_edge++) { + const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); + road_legs_on_the_right.emplace_back(edge_data.flags.restricted, + m_edge_based_node_container.GetAnnotation(edge_data.annotation_data).travel_mode, + edge_data.flags.road_classification.IsMotorwayClass(), + edge_data.flags.road_classification.IsLinkClass(), + edge_data.flags.road_classification.GetNumberOfLanes(), + edge_data.flags.highway_turn_classification, + edge_data.flags.access_turn_classification, + edge_data.flags.speed, + !connected_edge->entry_allowed || (edge_data.flags.forward && edge_data.flags.backward), // is incoming + connected_edge->entry_allowed); + } + } else { + for (auto connected_edge = intersection.begin(); connected_edge < turn_iter; connected_edge++) { + const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); + road_legs_on_the_right.emplace_back(edge_data.flags.restricted, + m_edge_based_node_container.GetAnnotation(edge_data.annotation_data).travel_mode, + edge_data.flags.road_classification.IsMotorwayClass(), + edge_data.flags.road_classification.IsLinkClass(), + edge_data.flags.road_classification.GetNumberOfLanes(), + edge_data.flags.highway_turn_classification, + edge_data.flags.access_turn_classification, + edge_data.flags.speed, + !connected_edge->entry_allowed || (edge_data.flags.forward && edge_data.flags.backward), // is incoming + connected_edge->entry_allowed); + } + for (auto connected_edge = turn_iter + 1; connected_edge < intersection.end(); connected_edge++) { + const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); + road_legs_on_the_left.emplace_back(edge_data.flags.restricted, + m_edge_based_node_container.GetAnnotation(edge_data.annotation_data).travel_mode, + edge_data.flags.road_classification.IsMotorwayClass(), + edge_data.flags.road_classification.IsLinkClass(), + edge_data.flags.road_classification.GetNumberOfLanes(), + edge_data.flags.highway_turn_classification, + edge_data.flags.access_turn_classification, + edge_data.flags.speed, + !connected_edge->entry_allowed || (edge_data.flags.forward && edge_data.flags.backward), // is incoming + connected_edge->entry_allowed); + } } ExtractionTurn extracted_turn( @@ -640,8 +662,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data1.flags.road_classification.GetNumberOfLanes(), edge_data1.flags.highway_turn_classification, edge_data1.flags.access_turn_classification, - edge_data1.flags.speed, - edge_data2.flags.restricted, + edge_data1.flags.speed, edge_data2.flags.restricted, m_edge_based_node_container .GetAnnotation(edge_data2.annotation_data) .travel_mode, @@ -650,8 +671,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data2.flags.road_classification.GetNumberOfLanes(), edge_data2.flags.highway_turn_classification, edge_data2.flags.access_turn_classification, - edge_data2.flags.speed, - roads_on_the_right, roads_on_the_left); + edge_data2.flags.speed, road_legs_on_the_right, + road_legs_on_the_left); + scripting_environment.ProcessTurn( extracted_turn); @@ -825,17 +847,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( m_coordinates[intersection_node]); - // memory problem @CHAUTODO? - std::vector node_based_edges_right; - std::vector node_based_edges_left; - std::size_t outgoing_pos = turn - intersection.begin(); - for (std::size_t connected_road = 0; connected_road < outgoing_pos; connected_road++) { - node_based_edges_right.push_back(intersection[connected_road].eid); - } - for (std::size_t connected_road = outgoing_pos+1; connected_road < intersection.size(); connected_road++) { - node_based_edges_left.push_back(intersection[connected_road].eid); - } - // In case a way restriction starts at a given location, add a turn onto // every artificial node eminating here. // @@ -874,8 +885,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( reversed_incoming_bearing, *turn, entry_class_id, - node_based_edges_right, - node_based_edges_left); + intersection); buffer->continuous_data.edges_list.push_back( edge_with_data_and_condition.first.edge); @@ -938,8 +948,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( reversed_incoming_bearing, *turn, entry_class_id, - node_based_edges_right, - node_based_edges_left); + intersection); buffer->delayed_data.push_back( std::move(edge_with_data_and_condition.first)); @@ -974,8 +983,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( reversed_incoming_bearing, *turn, entry_class_id, - node_based_edges_right, - node_based_edges_left); + intersection); buffer->delayed_data.push_back( std::move(edge_with_data_and_condition.first)); From 2fd94426d40da9a64cbdf3d04f404b9a0633b9e7 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Wed, 17 Jan 2018 13:41:14 +0100 Subject: [PATCH 06/37] small cleanup --- profiles/car.lua | 15 ++------------- src/extractor/edge_based_graph_factory.cpp | 3 +-- src/extractor/scripting_environment_lua.cpp | 12 +++++++++++- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/profiles/car.lua b/profiles/car.lua index 128acaadd07..38cd794c53f 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -300,22 +300,11 @@ function setup() "route" }, + -- classify highway tags when necessary for turn weights highway_turn_classification = { - ['motorway'] = 0, - ['motorway_link'] = 0, - ['trunk'] = 0, - ['trunk_link'] = 0, - ['primary'] = 0, - ['primary_link'] = 0, - ['secondary'] = 1, - ['secondary_link'] = 1, - ['tertiary'] = 2, - ['tertiary_link'] = 2, - ['residential'] = 3, - ['living_street'] = 3, - ['unclassified'] = 1 }, + -- classify access tags when necessary for turn weights access_turn_classification = { } } diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 2337f4ab9d9..bb7d03bbd66 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -619,7 +619,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( connected_edge->entry_allowed); } } else { - for (auto connected_edge = intersection.begin(); connected_edge < turn_iter; connected_edge++) { + for (auto connected_edge = intersection.begin() + 1; connected_edge < turn_iter; connected_edge++) { const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); road_legs_on_the_right.emplace_back(edge_data.flags.restricted, m_edge_based_node_container.GetAnnotation(edge_data.annotation_data).travel_mode, @@ -646,7 +646,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( connected_edge->entry_allowed); } } - ExtractionTurn extracted_turn( turn.angle, m_node_based_graph.GetOutDegree(intersection_node), turn.instruction.IsUTurn(), is_traffic_light, diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index 819788ee48e..5fa141bd22b 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -688,7 +688,13 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) "highway_turn_classification", &ExtractionTurnLeg::highway_turn_classification, "access_turn_classification", - &ExtractionTurnLeg::access_turn_classification); + &ExtractionTurnLeg::access_turn_classification, + "speed", + &ExtractionTurnLeg::speed, + "is_incoming", + &ExtractionTurnLeg::is_incoming, + "is_outgoing", + &ExtractionTurnLeg::is_outgoing); context.state.new_usertype("ExtractionTurn", "angle", @@ -716,6 +722,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) &ExtractionTurn::source_highway_turn_classification, "source_access_turn_classification", &ExtractionTurn::source_access_turn_classification, + "source_speed", + &ExtractionTurn::source_speed, "target_restricted", &ExtractionTurn::target_restricted, @@ -731,6 +739,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) &ExtractionTurn::target_highway_turn_classification, "target_access_turn_classification", &ExtractionTurn::target_access_turn_classification, + "target_speed", + &ExtractionTurn::target_speed, "roads_on_the_right", From 76224ef2a81e51eda50cc5ee9bbe0232939931d1 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Wed, 17 Jan 2018 13:43:49 +0100 Subject: [PATCH 07/37] add lua tests for exposed information to turn function --- .../options/extract/turn_function.feature | 151 ++++++ features/support/hooks.js | 1 + profiles/feature/car_turnbot.lua | 483 ++++++++++++++++++ 3 files changed, 635 insertions(+) create mode 100644 features/options/extract/turn_function.feature create mode 100644 profiles/feature/car_turnbot.lua diff --git a/features/options/extract/turn_function.feature b/features/options/extract/turn_function.feature new file mode 100644 index 00000000000..8da876d4d79 --- /dev/null +++ b/features/options/extract/turn_function.feature @@ -0,0 +1,151 @@ +@routing @testbot @turn_function +Feature: Turn Function Information + + Scenario: Turns should have correct information of source and target + Given the profile file + """ + functions = require('feature/car_turnbot') + + return { + setup = functions.setup, + process_way = functions.process_way, + process_node = functions.process_node, + process_turn = functions.process_turn + } + + """ + + And the node map + """ + + a b c + + """ + And the ways + | nodes | highway | + | ab | motorway | + | bc | motorway | + And the data has been saved to disk + + When I run "osrm-extract --profile {profile_file} {osm_file}" + Then it should exit successfully + And stdout should contain "source_is_motorway true" + And stdout should contain "target_is_motorway true" + And stdout should contain "source_is_link false" + And stdout should contain "source_speed 90" + And stdout should contain "target_is_motorway true" + And stdout should contain "target_is_link false" + And stdout should contain "target_speed 90" + + + Scenario: Turns should detect when turn is leaving highway + Given the profile file + """ + functions = require('feature/car_turnbot') + + return { + setup = functions.setup, + process_way = functions.process_way, + process_node = functions.process_node, + process_turn = functions.process_turn + } + + + """ + + And the node map + """ + + a b c + + """ + And the ways + | nodes | highway | + | ab | motorway | + | bc | motorway_link | + And the data has been saved to disk + + When I run "osrm-extract --profile {profile_file} {osm_file}" + Then it should exit successfully + And stdout should contain "source_is_motorway true" + And stdout should contain "source_is_link false" + And stdout should contain "source_speed 90" + And stdout should contain "target_is_motorway false" + And stdout should contain "target_is_link true" + And stdout should contain "number_of_roads 2" + + Scenario: Turns should have correct information of other roads at intersection I + Given the profile file + """ + functions = require('feature/car_turnbot') + + return { + setup = functions.setup, + process_way = functions.process_way, + process_node = functions.process_node, + process_turn = functions.process_turn + } + + """ + + And the node map + """ + d + ^ + | + a->b->c + """ + And the ways + | nodes | highway | oneway | + | ab | primary | yes | + | bc | motorway | yes | + | bd | residential | yes | + And the data has been saved to disk + + When I run "osrm-extract --profile {profile_file} {osm_file}" + Then it should exit successfully + And stdout should contain "number_of_roads 3" + # turning abd, give information about bc + And stdout should contain "roads_on_the_right [1] speed: 90, is_incoming: false, is_outgoing: true, highway_turn_classification: 4, access_turn_classification: 0" + # turning abc, give information about bd + And stdout should contain "roads_on_the_left [1] speed: 25, is_incoming: false, is_outgoing: true, highway_turn_classification: 1, access_turn_classification: 0" + + Scenario: Turns should have correct information of other roads at intersection II + Given the profile file + """ + functions = require('feature/car_turnbot') + + return { + setup = functions.setup, + process_way = functions.process_way, + process_node = functions.process_node, + process_turn = functions.process_turn + } + + """ + + And the node map + """ + d + | + v + a->b->c + """ + And the ways + | nodes | highway | oneway | access | + | ab | secondary | yes | | + | bc | motorway | yes | | + | db | unclassified | yes | discouraged | + And the data has been saved to disk + + When I run "osrm-extract --profile {profile_file} {osm_file}" + Then it should exit successfully + And stdout should contain "number_of_roads 3" + # turning dbc, give information about about ab + And stdout should contain "roads_on_the_right [1] speed: 55, is_incoming: true, is_outgoing: false, highway_turn_classification: 3, access_turn_classification: 0" + # turning abc, give information about about db + And stdout should contain "roads_on_the_left [1] speed: 25, is_incoming: true, is_outgoing: false, highway_turn_classification: 0, access_turn_classification: 1" + + + + diff --git a/features/support/hooks.js b/features/support/hooks.js index 6b5185e9e7b..965d15fe79a 100644 --- a/features/support/hooks.js +++ b/features/support/hooks.js @@ -50,6 +50,7 @@ module.exports = function () { .defer(mkdirp, logDir) .defer(rimraf, this.scenarioLogFile) .awaitAll(callback); + console.log(" Writing logging output to " + this.scenarioLogFile) }); this.After((scenario, callback) => { diff --git a/profiles/feature/car_turnbot.lua b/profiles/feature/car_turnbot.lua new file mode 100644 index 00000000000..ee4a41cc43e --- /dev/null +++ b/profiles/feature/car_turnbot.lua @@ -0,0 +1,483 @@ +-- Adjusted car profile with print output for testing +-- at the moment used in features/options/extract/turn_function.feature + +api_version = 4 + +Set = require('lib/set') +Sequence = require('lib/sequence') +Handlers = require("lib/way_handlers") +Relations = require("lib/relations") +find_access_tag = require("lib/access").find_access_tag +limit = require("lib/maxspeed").limit +Utils = require("lib/utils") + +function setup() + return { + properties = { + max_speed_for_map_matching = 180/3.6, -- 180kmph -> m/s + -- For routing based on duration, but weighted for preferring certain roads + weight_name = 'routability', + -- For shortest duration without penalties for accessibility + -- weight_name = 'duration', + -- For shortest distance without penalties for accessibility + -- weight_name = 'distance', + process_call_tagless_node = false, + u_turn_penalty = 20, + continue_straight_at_waypoint = true, + use_turn_restrictions = true, + left_hand_driving = false, + traffic_light_penalty = 2, + }, + + default_mode = mode.driving, + default_speed = 10, + oneway_handling = true, + side_road_multiplier = 0.8, + turn_penalty = 7.5, + speed_reduction = 0.8, + turn_bias = 1.075, + cardinal_directions = false, + + -- Size of the vehicle, to be limited by physical restriction of the way + vehicle_height = 2.5, -- in metters, 2.5m is the height of van + vehicle_width = 1.9, -- in metters, ways with narrow tag are considered narrower than 2.2m + + -- a list of suffixes to suppress in name change instructions. The suffixes also include common substrings of each other + suffix_list = { + 'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East', 'Nor', 'Sou', 'We', 'Ea' + }, + + barrier_whitelist = Set { + 'cattle_grid', + 'border_control', + 'toll_booth', + 'sally_port', + 'gate', + 'lift_gate', + 'no', + 'entrance' + }, + + access_tag_whitelist = Set { + 'yes', + 'motorcar', + 'motor_vehicle', + 'vehicle', + 'permissive', + 'designated', + 'hov' + }, + + access_tag_blacklist = Set { + 'no', + 'agricultural', + 'forestry', + 'emergency', + 'psv', + 'customers', + 'private', + 'delivery', + 'destination' + }, + + restricted_access_tag_list = Set { + 'private', + 'delivery', + 'destination', + 'customers', + }, + + access_tags_hierarchy = Sequence { + 'motorcar', + 'motor_vehicle', + 'vehicle', + 'access' + }, + + service_tag_forbidden = Set { + 'emergency_access' + }, + + restrictions = Sequence { + 'motorcar', + 'motor_vehicle', + 'vehicle' + }, + + classes = Sequence { + 'toll', 'motorway', 'ferry', 'restricted' + }, + + -- classes to support for exclude flags + excludable = Sequence { + Set {'toll'}, + Set {'motorway'}, + Set {'ferry'} + }, + + avoid = Set { + 'area', + -- 'toll', -- uncomment this to avoid tolls + 'reversible', + 'impassable', + 'hov_lanes', + 'steps', + 'construction', + 'proposed' + }, + + speeds = Sequence { + highway = { + motorway = 90, + motorway_link = 45, + trunk = 85, + trunk_link = 40, + primary = 65, + primary_link = 30, + secondary = 55, + secondary_link = 25, + tertiary = 40, + tertiary_link = 20, + unclassified = 25, + residential = 25, + living_street = 10, + service = 15 + } + }, + + service_penalties = { + alley = 0.5, + parking = 0.5, + parking_aisle = 0.5, + driveway = 0.5, + ["drive-through"] = 0.5, + ["drive-thru"] = 0.5 + }, + + restricted_highway_whitelist = Set { + 'motorway', + 'motorway_link', + 'trunk', + 'trunk_link', + 'primary', + 'primary_link', + 'secondary', + 'secondary_link', + 'tertiary', + 'tertiary_link', + 'residential', + 'living_street', + 'unclassified' + }, + + construction_whitelist = Set { + 'no', + 'widening', + 'minor', + }, + + route_speeds = { + ferry = 5, + shuttle_train = 10 + }, + + bridge_speeds = { + movable = 5 + }, + + -- surface/trackype/smoothness + -- values were estimated from looking at the photos at the relevant wiki pages + + -- max speed for surfaces + surface_speeds = { + asphalt = nil, -- nil mean no limit. removing the line has the same effect + concrete = nil, + ["concrete:plates"] = nil, + ["concrete:lanes"] = nil, + paved = nil, + + cement = 80, + compacted = 80, + fine_gravel = 80, + + paving_stones = 60, + metal = 60, + bricks = 60, + + grass = 40, + wood = 40, + sett = 40, + grass_paver = 40, + gravel = 40, + unpaved = 40, + ground = 40, + dirt = 40, + pebblestone = 40, + tartan = 40, + + cobblestone = 30, + clay = 30, + + earth = 20, + stone = 20, + rocky = 20, + sand = 20, + + mud = 10 + }, + + -- max speed for tracktypes + tracktype_speeds = { + grade1 = 60, + grade2 = 40, + grade3 = 30, + grade4 = 25, + grade5 = 20 + }, + + -- max speed for smoothnesses + smoothness_speeds = { + intermediate = 80, + bad = 40, + very_bad = 20, + horrible = 10, + very_horrible = 5, + impassable = 0 + }, + + -- http://wiki.openstreetmap.org/wiki/Speed_limits + maxspeed_table_default = { + urban = 50, + rural = 90, + trunk = 110, + motorway = 130 + }, + + -- List only exceptions + maxspeed_table = { + ["at:rural"] = 100, + ["at:trunk"] = 100, + ["be:motorway"] = 120, + ["by:urban"] = 60, + ["by:motorway"] = 110, + ["ch:rural"] = 80, + ["ch:trunk"] = 100, + ["ch:motorway"] = 120, + ["cz:trunk"] = 0, + ["cz:motorway"] = 0, + ["de:living_street"] = 7, + ["de:rural"] = 100, + ["de:motorway"] = 0, + ["dk:rural"] = 80, + ["gb:nsl_single"] = (60*1609)/1000, + ["gb:nsl_dual"] = (70*1609)/1000, + ["gb:motorway"] = (70*1609)/1000, + ["nl:rural"] = 80, + ["nl:trunk"] = 100, + ['no:rural'] = 80, + ['no:motorway'] = 110, + ['pl:rural'] = 100, + ['pl:trunk'] = 120, + ['pl:motorway'] = 140, + ["ro:trunk"] = 100, + ["ru:living_street"] = 20, + ["ru:urban"] = 60, + ["ru:motorway"] = 110, + ["uk:nsl_single"] = (60*1609)/1000, + ["uk:nsl_dual"] = (70*1609)/1000, + ["uk:motorway"] = (70*1609)/1000, + ['za:urban'] = 60, + ['za:rural'] = 100, + ["none"] = 140 + }, + + relation_types = Sequence { + "route" + }, + + highway_turn_classification = { + ['motorway'] = 4, + ['motorway_link'] = 4, + ['trunk'] = 4, + ['trunk_link'] = 4, + ['primary'] = 4, + ['primary_link'] = 4, + ['secondary'] = 3, + ['secondary_link'] = 3, + ['tertiary'] = 2, + ['tertiary_link'] = 2, + ['residential'] = 1, + ['living_street'] = 1, + }, + + + access_turn_classification = { + ['discouraged'] = 1; + ['permissive'] = 1; + ['private'] = 1; + ['customers'] = 1; + ['dismount'] = 1; + } + } +end + +function process_node(profile, node, result, relations) + -- parse access and barrier tags + local access = find_access_tag(node, profile.access_tags_hierarchy) + if access then + if profile.access_tag_blacklist[access] and not profile.restricted_access_tag_list[access] then + result.barrier = true + end + else + local barrier = node:get_value_by_key("barrier") + if barrier then + -- make an exception for rising bollard barriers + local bollard = node:get_value_by_key("bollard") + local rising_bollard = bollard and "rising" == bollard + + if not profile.barrier_whitelist[barrier] and not rising_bollard then + result.barrier = true + end + end + end + + -- check if node is a traffic light + local tag = node:get_value_by_key("highway") + if "traffic_signals" == tag then + result.traffic_lights = true + end +end + +function process_way(profile, way, result, relations) + -- the intial filtering of ways based on presence of tags + -- affects processing times significantly, because all ways + -- have to be checked. + -- to increase performance, prefetching and intial tag check + -- is done in directly instead of via a handler. + + -- in general we should try to abort as soon as + -- possible if the way is not routable, to avoid doing + -- unnecessary work. this implies we should check things that + -- commonly forbids access early, and handle edge cases later. + + -- data table for storing intermediate values during processing + local data = { + -- prefetch tags + highway = way:get_value_by_key('highway'), + bridge = way:get_value_by_key('bridge'), + route = way:get_value_by_key('route') + } + + -- perform an quick initial check and abort if the way is + -- obviously not routable. + -- highway or route tags must be in data table, bridge is optional + if (not data.highway or data.highway == '') and + (not data.route or data.route == '') + then + return + end + + handlers = Sequence { + -- set the default mode for this profile. if can be changed later + -- in case it turns we're e.g. on a ferry + WayHandlers.default_mode, + + -- check various tags that could indicate that the way is not + -- routable. this includes things like status=impassable, + -- toll=yes and oneway=reversible + WayHandlers.blocked_ways, + WayHandlers.avoid_ways, + WayHandlers.handle_height, + WayHandlers.handle_width, + + -- determine access status by checking our hierarchy of + -- access tags, e.g: motorcar, motor_vehicle, vehicle + WayHandlers.access, + + -- check whether forward/backward directions are routable + WayHandlers.oneway, + + -- check a road's destination + WayHandlers.destinations, + + -- check whether we're using a special transport mode + WayHandlers.ferries, + WayHandlers.movables, + + -- handle service road restrictions + WayHandlers.service, + + -- handle hov + WayHandlers.hov, + + -- compute speed taking into account way type, maxspeed tags, etc. + WayHandlers.speed, + WayHandlers.surface, + WayHandlers.maxspeed, + WayHandlers.penalties, + + -- compute class labels + WayHandlers.classes, + + -- handle turn lanes and road classification, used for guidance + WayHandlers.turn_lanes, + WayHandlers.classification, + + -- handle various other flags + WayHandlers.roundabouts, + WayHandlers.startpoint, + WayHandlers.driving_side, + + -- set name, ref and pronunciation + WayHandlers.names, + + -- set weight properties of the way + WayHandlers.weights, + + -- set classification of ways relevant for turns + WayHandlers.way_classification_for_turn + } + + WayHandlers.run(profile, way, result, data, handlers, relations) + + if profile.cardinal_directions then + Relations.process_way_refs(way, relations, result) + end +end + + +function process_turn (profile, turn) + print ('source_restricted ' .. string.format("%s", tostring(turn.source_restricted))) + print ('source_is_motorway ' .. string.format("%s", tostring(turn.source_is_motorway))) + print ('source_is_link ' .. string.format("%s", tostring(turn.source_is_link))) + print ('source_number_of_lanes ' .. string.format("%s", tostring(turn.source_number_of_lanes))) + print ('source_highway_turn_classification ' .. string.format("%s", tostring(turn.source_highway_turn_classification))) + print ('source_access_turn_classification ' .. string.format("%s", tostring(turn.source_access_turn_classification))) + print ('source_speed ' .. string.format("%s", tostring(turn.source_speed))) + + print ('target_restricted ' .. string.format("%s", tostring(turn.target_restricted))) + print ('target_is_motorway ' .. string.format("%s", tostring(turn.target_is_motorway))) + print ('target_is_link ' .. string.format("%s", tostring(turn.target_is_link))) + print ('target_number_of_lanes ' .. string.format("%s", tostring(turn.target_number_of_lanes))) + print ('target_highway_turn_classification ' .. string.format("%s", tostring(turn.target_highway_turn_classification))) + print ('target_access_turn_classification ' .. string.format("%s", tostring(turn.target_access_turn_classification))) + print ('target_speed ' .. string.format("%s", tostring(turn.target_speed))) + + print ('number_of_roads ' .. string.format("%s", tostring(turn.number_of_roads))) + if not turn.is_u_turn then + for roadCount = 1, #turn.roads_on_the_right do + print('roads_on_the_right [' .. string.format("%s", tostring(roadCount)) .. '] speed: ' .. string.format("%s", tostring(turn.roads_on_the_right[roadCount].speed)) .. ', is_incoming: ' .. string.format("%s", tostring(turn.roads_on_the_right[roadCount].is_incoming)) .. ', is_outgoing: ' .. string.format("%s", tostring(turn.roads_on_the_right[roadCount].is_outgoing)) .. ', highway_turn_classification: ' .. string.format("%s", tostring(turn.roads_on_the_right[roadCount].highway_turn_classification)) .. ', access_turn_classification: ' .. string.format("%s", tostring(turn.roads_on_the_right[roadCount].access_turn_classification))) + end + + for roadCount = 1, #turn.roads_on_the_left do + print('roads_on_the_left [' .. string.format("%s", tostring(roadCount)) .. '] speed: ' .. string.format("%s", tostring(turn.roads_on_the_left[roadCount].speed)) .. ', is_incoming: ' .. string.format("%s", tostring(turn.roads_on_the_left[roadCount].is_incoming)) .. ', is_outgoing: ' .. string.format("%s", tostring(turn.roads_on_the_left[roadCount].is_outgoing)) .. ', highway_turn_classification: ' .. string.format("%s", tostring(turn.roads_on_the_left[roadCount].highway_turn_classification)) .. ', access_turn_classification: ' .. string.format("%s", tostring(turn.roads_on_the_left[roadCount].access_turn_classification))) + end + end +end + +return { + setup = setup, + process_way = process_way, + process_node = process_node, + process_turn = process_turn +} From 096f86d090c34562a269ec7acc54bf5be34596cb Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Wed, 17 Jan 2018 13:49:29 +0100 Subject: [PATCH 08/37] clang-format --- include/extractor/extraction_turn.hpp | 243 ++++++++++---------- include/extractor/node_based_edge.hpp | 9 +- src/extractor/edge_based_graph_factory.cpp | 121 ++++++---- src/extractor/extractor_callbacks.cpp | 3 +- src/extractor/graph_compressor.cpp | 27 ++- src/extractor/scripting_environment_lua.cpp | 155 ++++++------- 6 files changed, 302 insertions(+), 256 deletions(-) diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index 9fcee1db194..1fcc2d04552 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -7,126 +7,133 @@ #include -namespace osrm { -namespace extractor { - -struct ExtractionTurnLeg { - ExtractionTurnLeg(bool is_restricted, TravelMode mode, bool is_motorway, - bool is_link, int number_of_lanes, - int highway_turn_classification, - int access_turn_classification, int speed, bool is_incoming, - bool is_outgoing) - : is_restricted(is_restricted), - mode(mode), - is_motorway(is_motorway), - is_link(is_link), - number_of_lanes(number_of_lanes), - highway_turn_classification(highway_turn_classification), - access_turn_classification(access_turn_classification), - speed(speed), - is_incoming(is_incoming), - is_outgoing(is_outgoing) {} - - const bool is_restricted; - const TravelMode mode; - const bool is_motorway; - const bool is_link; - const int number_of_lanes; - const int highway_turn_classification; - const int access_turn_classification; - const int speed; - const bool is_incoming; - const bool is_outgoing; +namespace osrm +{ +namespace extractor +{ + +struct ExtractionTurnLeg +{ + ExtractionTurnLeg(bool is_restricted, + TravelMode mode, + bool is_motorway, + bool is_link, + int number_of_lanes, + int highway_turn_classification, + int access_turn_classification, + int speed, + bool is_incoming, + bool is_outgoing) + : is_restricted(is_restricted), mode(mode), is_motorway(is_motorway), is_link(is_link), + number_of_lanes(number_of_lanes), + highway_turn_classification(highway_turn_classification), + access_turn_classification(access_turn_classification), speed(speed), + is_incoming(is_incoming), is_outgoing(is_outgoing) + { + } + + const bool is_restricted; + const TravelMode mode; + const bool is_motorway; + const bool is_link; + const int number_of_lanes; + const int highway_turn_classification; + const int access_turn_classification; + const int speed; + const bool is_incoming; + const bool is_outgoing; }; -struct ExtractionTurn { - ExtractionTurn( - double angle, int number_of_roads, bool is_u_turn, bool has_traffic_light, - // bool is_stop, bool is_give_way, - bool is_left_hand_driving, bool source_restricted, TravelMode source_mode, - bool source_is_motorway, bool source_is_link, - - int source_number_of_lanes, int source_highway_turn_classification, - int source_access_turn_classification, int source_speed, - bool target_restricted, TravelMode target_mode, bool target_is_motorway, - bool target_is_link, int target_number_of_lanes, - int target_highway_turn_classification, - int target_access_turn_classification, int target_speed, - std::vector &roads_on_the_right, - std::vector &roads_on_the_left) - : angle(180. - angle), - number_of_roads(number_of_roads), - is_u_turn(is_u_turn), - has_traffic_light(has_traffic_light), - // is_stop(is_stop), - // is_give_way(is_give_way), - is_left_hand_driving(is_left_hand_driving), - - source_restricted(source_restricted), - source_mode(source_mode), - source_is_motorway(source_is_motorway), - source_is_link(source_is_link), - source_number_of_lanes(source_number_of_lanes), - source_highway_turn_classification(source_highway_turn_classification), - source_access_turn_classification(source_access_turn_classification), - source_speed(source_speed), - - target_restricted(target_restricted), - target_mode(target_mode), - target_is_motorway(target_is_motorway), - target_is_link(target_is_link), - target_number_of_lanes(target_number_of_lanes), - target_highway_turn_classification(target_highway_turn_classification), - target_access_turn_classification(target_access_turn_classification), - target_speed(target_speed), - - roads_on_the_right(roads_on_the_right), - roads_on_the_left(roads_on_the_left), - weight(0.), - duration(0.) - - { - BOOST_ASSERT_MSG( - !is_u_turn || roads_on_the_left.size() == 0, - "there cannot be roads on the left when there is a u turn"); - BOOST_ASSERT_MSG( - roads_on_the_right.size() + roads_on_the_left.size() + is_u_turn + 2 == - number_of_roads, - "number of roads at intersection do not match"); - } - const double angle; - const int number_of_roads; - const bool is_u_turn; - const bool has_traffic_light; - // const bool is_stop; - // const bool is_give_way; - const bool is_left_hand_driving; - - // source info - const bool source_restricted; - const TravelMode source_mode; - const bool source_is_motorway; - const bool source_is_link; - const int source_number_of_lanes; - const int source_highway_turn_classification; - const int source_access_turn_classification; - const int source_speed; - - // target info - const bool target_restricted; - const TravelMode target_mode; - const bool target_is_motorway; - const bool target_is_link; - const int target_number_of_lanes; - const int target_highway_turn_classification; - const int target_access_turn_classification; - const int target_speed; - - const std::vector roads_on_the_right; - const std::vector roads_on_the_left; - - double weight; - double duration; +struct ExtractionTurn +{ + ExtractionTurn(double angle, + int number_of_roads, + bool is_u_turn, + bool has_traffic_light, + // bool is_stop, bool is_give_way, + bool is_left_hand_driving, + bool source_restricted, + TravelMode source_mode, + bool source_is_motorway, + bool source_is_link, + + int source_number_of_lanes, + int source_highway_turn_classification, + int source_access_turn_classification, + int source_speed, + bool target_restricted, + TravelMode target_mode, + bool target_is_motorway, + bool target_is_link, + int target_number_of_lanes, + int target_highway_turn_classification, + int target_access_turn_classification, + int target_speed, + std::vector &roads_on_the_right, + std::vector &roads_on_the_left) + : angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn), + has_traffic_light(has_traffic_light), + // is_stop(is_stop), + // is_give_way(is_give_way), + is_left_hand_driving(is_left_hand_driving), + + source_restricted(source_restricted), source_mode(source_mode), + source_is_motorway(source_is_motorway), source_is_link(source_is_link), + source_number_of_lanes(source_number_of_lanes), + source_highway_turn_classification(source_highway_turn_classification), + source_access_turn_classification(source_access_turn_classification), + source_speed(source_speed), + + target_restricted(target_restricted), target_mode(target_mode), + target_is_motorway(target_is_motorway), target_is_link(target_is_link), + target_number_of_lanes(target_number_of_lanes), + target_highway_turn_classification(target_highway_turn_classification), + target_access_turn_classification(target_access_turn_classification), + target_speed(target_speed), + + roads_on_the_right(roads_on_the_right), roads_on_the_left(roads_on_the_left), weight(0.), + duration(0.) + + { + BOOST_ASSERT_MSG(!is_u_turn || roads_on_the_left.size() == 0, + "there cannot be roads on the left when there is a u turn"); + BOOST_ASSERT_MSG(roads_on_the_right.size() + roads_on_the_left.size() + is_u_turn + 2 == + number_of_roads, + "number of roads at intersection do not match"); + } + const double angle; + const int number_of_roads; + const bool is_u_turn; + const bool has_traffic_light; + // const bool is_stop; + // const bool is_give_way; + const bool is_left_hand_driving; + + // source info + const bool source_restricted; + const TravelMode source_mode; + const bool source_is_motorway; + const bool source_is_link; + const int source_number_of_lanes; + const int source_highway_turn_classification; + const int source_access_turn_classification; + const int source_speed; + + // target info + const bool target_restricted; + const TravelMode target_mode; + const bool target_is_motorway; + const bool target_is_link; + const int target_number_of_lanes; + const int target_highway_turn_classification; + const int target_access_turn_classification; + const int target_speed; + + const std::vector roads_on_the_right; + const std::vector roads_on_the_left; + + double weight; + double duration; }; } } diff --git a/include/extractor/node_based_edge.hpp b/include/extractor/node_based_edge.hpp index be2f234f44f..7ce2722b026 100644 --- a/include/extractor/node_based_edge.hpp +++ b/include/extractor/node_based_edge.hpp @@ -27,11 +27,10 @@ struct NodeBasedEdgeClassification std::uint8_t startpoint : 1; // 1 std::uint8_t restricted : 1; // 1 guidance::RoadClassification road_classification; // 16 2 - std::uint8_t highway_turn_classification; // @CHAUTODO memory? limit to 3 bits? // 8 - std::uint8_t access_turn_classification; // 3 are enough // 8 + std::uint8_t highway_turn_classification; // @CHAUTODO memory? limit to 3 bits? // 8 + std::uint8_t access_turn_classification; // 3 are enough // 8 std::uint8_t speed; // one bit could be saved here too I guess, so 7 // 8 - NodeBasedEdgeClassification(); NodeBasedEdgeClassification(const bool forward, @@ -47,7 +46,9 @@ struct NodeBasedEdgeClassification const std::uint8_t speed) : forward(forward), backward(backward), is_split(is_split), roundabout(roundabout), circular(circular), startpoint(startpoint), restricted(restricted), - road_classification(road_classification), highway_turn_classification(highway_turn_classification), access_turn_classification(access_turn_classification), speed(speed) + road_classification(road_classification), + highway_turn_classification(highway_turn_classification), + access_turn_classification(access_turn_classification), speed(speed) { } diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index bb7d03bbd66..5cbc43389b4 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -602,79 +602,99 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( std::vector road_legs_on_the_right; std::vector road_legs_on_the_left; - auto turn_iter = std::find_if(intersection.begin(), intersection.end(), [&turn](const auto &road){return road.eid == turn.eid;}); + auto turn_iter = + std::find_if(intersection.begin(), intersection.end(), [&turn](const auto &road) { + return road.eid == turn.eid; + }); - if (turn_iter == intersection.begin()) { - for (auto connected_edge = intersection.begin() + 1; connected_edge < intersection.end(); connected_edge++) { + if (turn_iter == intersection.begin()) + { + for (auto connected_edge = intersection.begin() + 1; + connected_edge < intersection.end(); + connected_edge++) + { const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); - road_legs_on_the_right.emplace_back(edge_data.flags.restricted, - m_edge_based_node_container.GetAnnotation(edge_data.annotation_data).travel_mode, - edge_data.flags.road_classification.IsMotorwayClass(), - edge_data.flags.road_classification.IsLinkClass(), - edge_data.flags.road_classification.GetNumberOfLanes(), - edge_data.flags.highway_turn_classification, - edge_data.flags.access_turn_classification, - edge_data.flags.speed, - !connected_edge->entry_allowed || (edge_data.flags.forward && edge_data.flags.backward), // is incoming - connected_edge->entry_allowed); + road_legs_on_the_right.emplace_back( + edge_data.flags.restricted, + m_edge_based_node_container.GetAnnotation(edge_data.annotation_data) + .travel_mode, + edge_data.flags.road_classification.IsMotorwayClass(), + edge_data.flags.road_classification.IsLinkClass(), + edge_data.flags.road_classification.GetNumberOfLanes(), + edge_data.flags.highway_turn_classification, + edge_data.flags.access_turn_classification, + edge_data.flags.speed, + !connected_edge->entry_allowed || + (edge_data.flags.forward && edge_data.flags.backward), // is incoming + connected_edge->entry_allowed); } - } else { - for (auto connected_edge = intersection.begin() + 1; connected_edge < turn_iter; connected_edge++) { + } + else + { + for (auto connected_edge = intersection.begin() + 1; connected_edge < turn_iter; + connected_edge++) + { const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); - road_legs_on_the_right.emplace_back(edge_data.flags.restricted, - m_edge_based_node_container.GetAnnotation(edge_data.annotation_data).travel_mode, - edge_data.flags.road_classification.IsMotorwayClass(), - edge_data.flags.road_classification.IsLinkClass(), - edge_data.flags.road_classification.GetNumberOfLanes(), - edge_data.flags.highway_turn_classification, - edge_data.flags.access_turn_classification, - edge_data.flags.speed, - !connected_edge->entry_allowed || (edge_data.flags.forward && edge_data.flags.backward), // is incoming - connected_edge->entry_allowed); + road_legs_on_the_right.emplace_back( + edge_data.flags.restricted, + m_edge_based_node_container.GetAnnotation(edge_data.annotation_data) + .travel_mode, + edge_data.flags.road_classification.IsMotorwayClass(), + edge_data.flags.road_classification.IsLinkClass(), + edge_data.flags.road_classification.GetNumberOfLanes(), + edge_data.flags.highway_turn_classification, + edge_data.flags.access_turn_classification, + edge_data.flags.speed, + !connected_edge->entry_allowed || + (edge_data.flags.forward && edge_data.flags.backward), // is incoming + connected_edge->entry_allowed); } - for (auto connected_edge = turn_iter + 1; connected_edge < intersection.end(); connected_edge++) { + for (auto connected_edge = turn_iter + 1; connected_edge < intersection.end(); + connected_edge++) + { const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); - road_legs_on_the_left.emplace_back(edge_data.flags.restricted, - m_edge_based_node_container.GetAnnotation(edge_data.annotation_data).travel_mode, - edge_data.flags.road_classification.IsMotorwayClass(), - edge_data.flags.road_classification.IsLinkClass(), - edge_data.flags.road_classification.GetNumberOfLanes(), - edge_data.flags.highway_turn_classification, - edge_data.flags.access_turn_classification, - edge_data.flags.speed, - !connected_edge->entry_allowed || (edge_data.flags.forward && edge_data.flags.backward), // is incoming - connected_edge->entry_allowed); + road_legs_on_the_left.emplace_back( + edge_data.flags.restricted, + m_edge_based_node_container.GetAnnotation(edge_data.annotation_data) + .travel_mode, + edge_data.flags.road_classification.IsMotorwayClass(), + edge_data.flags.road_classification.IsLinkClass(), + edge_data.flags.road_classification.GetNumberOfLanes(), + edge_data.flags.highway_turn_classification, + edge_data.flags.access_turn_classification, + edge_data.flags.speed, + !connected_edge->entry_allowed || + (edge_data.flags.forward && edge_data.flags.backward), // is incoming + connected_edge->entry_allowed); } } ExtractionTurn extracted_turn( - turn.angle, m_node_based_graph.GetOutDegree(intersection_node), - turn.instruction.IsUTurn(), is_traffic_light, - m_edge_based_node_container - .GetAnnotation(edge_data1.annotation_data) + turn.angle, + m_node_based_graph.GetOutDegree(intersection_node), + turn.instruction.IsUTurn(), + is_traffic_light, + m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data) .is_left_hand_driving, edge_data1.flags.restricted, - m_edge_based_node_container - .GetAnnotation(edge_data1.annotation_data) - .travel_mode, + m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data).travel_mode, edge_data1.flags.road_classification.IsMotorwayClass(), edge_data1.flags.road_classification.IsLinkClass(), edge_data1.flags.road_classification.GetNumberOfLanes(), edge_data1.flags.highway_turn_classification, edge_data1.flags.access_turn_classification, - edge_data1.flags.speed, edge_data2.flags.restricted, - m_edge_based_node_container - .GetAnnotation(edge_data2.annotation_data) - .travel_mode, + edge_data1.flags.speed, + edge_data2.flags.restricted, + m_edge_based_node_container.GetAnnotation(edge_data2.annotation_data).travel_mode, edge_data2.flags.road_classification.IsMotorwayClass(), edge_data2.flags.road_classification.IsLinkClass(), edge_data2.flags.road_classification.GetNumberOfLanes(), edge_data2.flags.highway_turn_classification, edge_data2.flags.access_turn_classification, - edge_data2.flags.speed, road_legs_on_the_right, + edge_data2.flags.speed, + road_legs_on_the_right, road_legs_on_the_left); - scripting_environment.ProcessTurn( - extracted_turn); + scripting_environment.ProcessTurn(extracted_turn); // turn penalties are limited to [-2^15, 2^15) which roughly // translates to 54 minutes and fits signed 16bit deci-seconds @@ -845,7 +865,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( OSRM_ASSERT(turn != intersection.end(), m_coordinates[intersection_node]); - // In case a way restriction starts at a given location, add a turn onto // every artificial node eminating here. // diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index 8bd5ed1d32b..b632a3c2892 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -469,8 +469,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti // @CHAUTODO parsed_way.highway_turn_classification, parsed_way.access_turn_classification, - speed - }}; + speed}}; external_memory.all_edges_list.push_back(InternalExtractorEdge( std::move(edge), backward_weight_data, backward_duration_data, {})); diff --git a/src/extractor/graph_compressor.cpp b/src/extractor/graph_compressor.cpp index 4a9206ed188..3b147b51592 100644 --- a/src/extractor/graph_compressor.cpp +++ b/src/extractor/graph_compressor.cpp @@ -222,10 +222,29 @@ void GraphCompressor::Compress( // generate an artifical turn for the turn penalty generation std::vector roads_on_the_right; std::vector roads_on_the_left; - ExtractionTurn extraction_turn(0, 2, false, true, false, - false, TRAVEL_MODE_DRIVING, false, false, 1, 0,0,0, - false, TRAVEL_MODE_DRIVING, false, false, 1, 0,0,0, - roads_on_the_right, roads_on_the_left); + ExtractionTurn extraction_turn(0, + 2, + false, + true, + false, + false, + TRAVEL_MODE_DRIVING, + false, + false, + 1, + 0, + 0, + 0, + false, + TRAVEL_MODE_DRIVING, + false, + false, + 1, + 0, + 0, + 0, + roads_on_the_right, + roads_on_the_left); scripting_environment.ProcessTurn(extraction_turn); node_duration_penalty = extraction_turn.duration * 10; node_weight_penalty = extraction_turn.weight * weight_multiplier; diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index 5fa141bd22b..a1bdae4f61f 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -674,83 +674,84 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) { case 4: { - context.state.new_usertype("ExtractionTurnLeg", - "is_restricted", - &ExtractionTurnLeg::is_restricted, - "mode", - &ExtractionTurnLeg::mode, - "is_motorway", - &ExtractionTurnLeg::is_motorway, - "is_link", - &ExtractionTurnLeg::is_link, - "number_of_lanes", - &ExtractionTurnLeg::number_of_lanes, - "highway_turn_classification", - &ExtractionTurnLeg::highway_turn_classification, - "access_turn_classification", - &ExtractionTurnLeg::access_turn_classification, - "speed", - &ExtractionTurnLeg::speed, - "is_incoming", - &ExtractionTurnLeg::is_incoming, - "is_outgoing", - &ExtractionTurnLeg::is_outgoing); - - context.state.new_usertype("ExtractionTurn", - "angle", - &ExtractionTurn::angle, - "number_of_roads", - &ExtractionTurn::number_of_roads, - "is_u_turn", - &ExtractionTurn::is_u_turn, - "has_traffic_light", - &ExtractionTurn::has_traffic_light, - "is_left_hand_driving", - &ExtractionTurn::is_left_hand_driving, - - "source_restricted", - &ExtractionTurn::source_restricted, - "source_mode", - &ExtractionTurn::source_mode, - "source_is_motorway", - &ExtractionTurn::source_is_motorway, - "source_is_link", - &ExtractionTurn::source_is_link, - "source_number_of_lanes", - &ExtractionTurn::source_number_of_lanes, - "source_highway_turn_classification", - &ExtractionTurn::source_highway_turn_classification, - "source_access_turn_classification", - &ExtractionTurn::source_access_turn_classification, - "source_speed", - &ExtractionTurn::source_speed, - - "target_restricted", - &ExtractionTurn::target_restricted, - "target_mode", - &ExtractionTurn::target_mode, - "target_is_motorway", - &ExtractionTurn::target_is_motorway, - "target_is_link", - &ExtractionTurn::target_is_link, - "target_number_of_lanes", - &ExtractionTurn::target_number_of_lanes, - "target_highway_turn_classification", - &ExtractionTurn::target_highway_turn_classification, - "target_access_turn_classification", - &ExtractionTurn::target_access_turn_classification, - "target_speed", - &ExtractionTurn::target_speed, - - - "roads_on_the_right", - &ExtractionTurn::roads_on_the_right, - "roads_on_the_left", - &ExtractionTurn::roads_on_the_left, - "weight", - &ExtractionTurn::weight, - "duration", - &ExtractionTurn::duration); + context.state.new_usertype( + "ExtractionTurnLeg", + "is_restricted", + &ExtractionTurnLeg::is_restricted, + "mode", + &ExtractionTurnLeg::mode, + "is_motorway", + &ExtractionTurnLeg::is_motorway, + "is_link", + &ExtractionTurnLeg::is_link, + "number_of_lanes", + &ExtractionTurnLeg::number_of_lanes, + "highway_turn_classification", + &ExtractionTurnLeg::highway_turn_classification, + "access_turn_classification", + &ExtractionTurnLeg::access_turn_classification, + "speed", + &ExtractionTurnLeg::speed, + "is_incoming", + &ExtractionTurnLeg::is_incoming, + "is_outgoing", + &ExtractionTurnLeg::is_outgoing); + + context.state.new_usertype( + "ExtractionTurn", + "angle", + &ExtractionTurn::angle, + "number_of_roads", + &ExtractionTurn::number_of_roads, + "is_u_turn", + &ExtractionTurn::is_u_turn, + "has_traffic_light", + &ExtractionTurn::has_traffic_light, + "is_left_hand_driving", + &ExtractionTurn::is_left_hand_driving, + + "source_restricted", + &ExtractionTurn::source_restricted, + "source_mode", + &ExtractionTurn::source_mode, + "source_is_motorway", + &ExtractionTurn::source_is_motorway, + "source_is_link", + &ExtractionTurn::source_is_link, + "source_number_of_lanes", + &ExtractionTurn::source_number_of_lanes, + "source_highway_turn_classification", + &ExtractionTurn::source_highway_turn_classification, + "source_access_turn_classification", + &ExtractionTurn::source_access_turn_classification, + "source_speed", + &ExtractionTurn::source_speed, + + "target_restricted", + &ExtractionTurn::target_restricted, + "target_mode", + &ExtractionTurn::target_mode, + "target_is_motorway", + &ExtractionTurn::target_is_motorway, + "target_is_link", + &ExtractionTurn::target_is_link, + "target_number_of_lanes", + &ExtractionTurn::target_number_of_lanes, + "target_highway_turn_classification", + &ExtractionTurn::target_highway_turn_classification, + "target_access_turn_classification", + &ExtractionTurn::target_access_turn_classification, + "target_speed", + &ExtractionTurn::target_speed, + + "roads_on_the_right", + &ExtractionTurn::roads_on_the_right, + "roads_on_the_left", + &ExtractionTurn::roads_on_the_left, + "weight", + &ExtractionTurn::weight, + "duration", + &ExtractionTurn::duration); initV2Context(); break; } From 9208fd7a58a8ded1821294656c497ff9fc6460e0 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Wed, 17 Jan 2018 14:29:39 +0100 Subject: [PATCH 09/37] remove mode in connected roads --- include/extractor/extraction_turn.hpp | 6 +----- src/extractor/edge_based_graph_factory.cpp | 6 ------ src/extractor/scripting_environment_lua.cpp | 2 -- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index 1fcc2d04552..f8036beaeea 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -15,7 +15,6 @@ namespace extractor struct ExtractionTurnLeg { ExtractionTurnLeg(bool is_restricted, - TravelMode mode, bool is_motorway, bool is_link, int number_of_lanes, @@ -24,7 +23,7 @@ struct ExtractionTurnLeg int speed, bool is_incoming, bool is_outgoing) - : is_restricted(is_restricted), mode(mode), is_motorway(is_motorway), is_link(is_link), + : is_restricted(is_restricted), is_motorway(is_motorway), is_link(is_link), number_of_lanes(number_of_lanes), highway_turn_classification(highway_turn_classification), access_turn_classification(access_turn_classification), speed(speed), @@ -33,7 +32,6 @@ struct ExtractionTurnLeg } const bool is_restricted; - const TravelMode mode; const bool is_motorway; const bool is_link; const int number_of_lanes; @@ -73,8 +71,6 @@ struct ExtractionTurn std::vector &roads_on_the_left) : angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn), has_traffic_light(has_traffic_light), - // is_stop(is_stop), - // is_give_way(is_give_way), is_left_hand_driving(is_left_hand_driving), source_restricted(source_restricted), source_mode(source_mode), diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 5cbc43389b4..14c983823d3 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -616,8 +616,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); road_legs_on_the_right.emplace_back( edge_data.flags.restricted, - m_edge_based_node_container.GetAnnotation(edge_data.annotation_data) - .travel_mode, edge_data.flags.road_classification.IsMotorwayClass(), edge_data.flags.road_classification.IsLinkClass(), edge_data.flags.road_classification.GetNumberOfLanes(), @@ -637,8 +635,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); road_legs_on_the_right.emplace_back( edge_data.flags.restricted, - m_edge_based_node_container.GetAnnotation(edge_data.annotation_data) - .travel_mode, edge_data.flags.road_classification.IsMotorwayClass(), edge_data.flags.road_classification.IsLinkClass(), edge_data.flags.road_classification.GetNumberOfLanes(), @@ -655,8 +651,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); road_legs_on_the_left.emplace_back( edge_data.flags.restricted, - m_edge_based_node_container.GetAnnotation(edge_data.annotation_data) - .travel_mode, edge_data.flags.road_classification.IsMotorwayClass(), edge_data.flags.road_classification.IsLinkClass(), edge_data.flags.road_classification.GetNumberOfLanes(), diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index a1bdae4f61f..235a0dc2546 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -678,8 +678,6 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) "ExtractionTurnLeg", "is_restricted", &ExtractionTurnLeg::is_restricted, - "mode", - &ExtractionTurnLeg::mode, "is_motorway", &ExtractionTurnLeg::is_motorway, "is_link", From 69758c7bc048e70001cf4bbbd414613f5a9c6810 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Wed, 17 Jan 2018 14:30:08 +0100 Subject: [PATCH 10/37] check lane numbers in tests --- features/options/extract/turn_function.feature | 10 +++++++--- features/support/hooks.js | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/features/options/extract/turn_function.feature b/features/options/extract/turn_function.feature index 8da876d4d79..e8069288451 100644 --- a/features/options/extract/turn_function.feature +++ b/features/options/extract/turn_function.feature @@ -60,9 +60,10 @@ Feature: Turn Function Information """ And the ways - | nodes | highway | - | ab | motorway | - | bc | motorway_link | + | nodes | highway | lanes | + | ab | motorway | 3 | + | bc | motorway_link | | + And the data has been saved to disk When I run "osrm-extract --profile {profile_file} {osm_file}" @@ -70,8 +71,11 @@ Feature: Turn Function Information And stdout should contain "source_is_motorway true" And stdout should contain "source_is_link false" And stdout should contain "source_speed 90" + And stdout should contain "source_number_of_lanes 3" And stdout should contain "target_is_motorway false" And stdout should contain "target_is_link true" + # Question @review: should number_of_lanes when untagged be 0 or 1? + And stdout should contain "target_number_of_lanes 0" And stdout should contain "number_of_roads 2" Scenario: Turns should have correct information of other roads at intersection I diff --git a/features/support/hooks.js b/features/support/hooks.js index 965d15fe79a..c8b716607b2 100644 --- a/features/support/hooks.js +++ b/features/support/hooks.js @@ -50,7 +50,8 @@ module.exports = function () { .defer(mkdirp, logDir) .defer(rimraf, this.scenarioLogFile) .awaitAll(callback); - console.log(" Writing logging output to " + this.scenarioLogFile) + // Question @review is this line nice to have here (commented, but ready to use and uncomment if needed?) + // console.log(" Writing logging output to " + this.scenarioLogFile) }); this.After((scenario, callback) => { From 5767da97c6fa803c9d9f1dc4278e582776426c26 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Wed, 17 Jan 2018 14:30:51 +0100 Subject: [PATCH 11/37] update docs about attributes in process_turn --- docs/profiles.md | 77 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/docs/profiles.md b/docs/profiles.md index dda62e921de..f23fe290d4b 100644 --- a/docs/profiles.md +++ b/docs/profiles.md @@ -208,19 +208,70 @@ The `process_turn` function is called for every possible turn in the network. Ba The following attributes can be read and set on the result in `process_turn`: -Attribute | Read/write? | Type | Notes ----------------------|-------------|---------|------------------------------------------------------ -angle | Read | Float | Angle of turn in degrees (`0-360`: `0`=u-turn, `180`=straight on) -number_of_roads | Read | Integer | Number of ways at the intersection of the turn -is_u_turn | Read | Boolean | Is the turn a u-turn? -has_traffic_light | Read | Boolean | Is a traffic light present at this turn? -source_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `process_way`) -target_restricted | Read | Boolean | Is it to a restricted access road? (See definition in `process_way`) -is_left_hand_driving | Read | Boolean | Is left-hand traffic? -weight | Read/write | Float | Penalty to be applied for this turn (routing weight) -duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds) -source_mode | Read | Enum | Travel mode before the turn. Defined in `include/extractor/travel_mode.hpp` -target_mode | Read | Enum | Travel mode after the turn. Defined in `include/extractor/travel_mode.hpp` +Attribute | Read/write? | Type | Notes +--------------------- | ------------- | --------- | ------------------------------------------------------ +angle | Read | Float | Angle of turn in degrees (`0-360`: `0`=u-turn, `180`=straight on) +number_of_roads | Read | Integer | Number of ways at the intersection of the turn +is_u_turn | Read | Boolean | Is the turn a u-turn? +has_traffic_light | Read | Boolean | Is a traffic light present at this turn? +is_left_hand_driving | Read | Boolean | Is left-hand traffic? +source_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `process_way`) +source_mode | Read | Enum | Travel mode before the turn. Defined in `include/extractor/travel_mode.hpp` +source_is_motorway | Read | Boolean | Is the source road a motorway? +source_is_link | Read | Boolean | Is the source road a link? +source_number_of_lanes | Read | Integer | How many lanes does the source road have? (default when not tagged: 0) +source_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0) +source_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0) +source_speed | Read | Integer | Speed on this source road in km/h +target_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `process_way`) +target_mode | Read | Enum | Travel mode before the turn. Defined in `include/extractor/travel_mode.hpp` +target_is_motorway | Read | Boolean | Is the target road a motorway? +target_is_link | Read | Boolean | Is the target road a link? +target_number_of_lanes | Read | Integer | How many lanes does the target road have? (default when not tagged: 0) +target_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0) +target_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0) +target_speed | Read | Integer | Speed on this target road in km/h +roads_on_the_right | Read | Vector | Vector with information about other roads on the right of the turn that are also connected at the intersection +roads_on_the_left | Read | Vector | Vector with information about other roads on the left of the turn that are also connected at the intersection +weight | Read/write | Float | Penalty to be applied for this turn (routing weight) +duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds) + +The information of `roads_on_the_right` and `roads_on_the_left` that can be read are as follows: + +Attribute | Read/write? | Type | Notes +--------------------- | ------------- | --------- | ------------------------------------------------------ +is_restricted | Read | Boolean | Is it a restricted access road? (See definition in `process_way`) +mode | Read | Enum | Travel mode before the turn. Defined in `include/extractor/travel_mode.hpp` +is_motorway | Read | Boolean | Is the road a motorway? +is_link | Read | Boolean | Is the road a link? +number_of_lanes | Read | Integer | How many lanes does the road have? (default when not tagged: 0) +highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0) +access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0) +speed | Read | Integer | Speed on this road in km/h +is_incoming | Read | Boolean | Is the road an incoming road of the intersection +is_outgoing | Read | Boolean | Is the road an outgoing road of the intersection + +The order of the roads in `roads_on_the_right` and `roads_on_the_left` are *counter clockwise*. If the turn is a u turn, all other connected roads will be in `roads_on_the_right`. + +#### Example +``` + c e + | / + | / + a ---- x ---- b + /| + / | + f d + + +``` +When turning from `a` to `b` via `x`, +* `roads_on_the_right[1]` is the road `xf` +* `roads_on_the_right[2]` is the road `xd` +* `roads_on_the_left[1]` is the road `xe` +* `roads_on_the_left[2]` is the road `xc` + +Note that indeces of arrays in lua are 1-based. ## Guidance The guidance parameters in profiles are currently a work in progress. They can and will change. From ac2846db2dc6d96f61ec031ec805ef564254ddcb Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Wed, 17 Jan 2018 15:15:07 +0100 Subject: [PATCH 12/37] add turn_classification info to docs --- docs/profiles.md | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/docs/profiles.md b/docs/profiles.md index f23fe290d4b..5ec9bb5f830 100644 --- a/docs/profiles.md +++ b/docs/profiles.md @@ -220,22 +220,24 @@ source_mode | Read | Enum | Travel mode bef source_is_motorway | Read | Boolean | Is the source road a motorway? source_is_link | Read | Boolean | Is the source road a link? source_number_of_lanes | Read | Integer | How many lanes does the source road have? (default when not tagged: 0) -source_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0) -source_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0) +source_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)) +source_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)) source_speed | Read | Integer | Speed on this source road in km/h target_restricted | Read | Boolean | Is it from a restricted access road? (See definition in `process_way`) target_mode | Read | Enum | Travel mode before the turn. Defined in `include/extractor/travel_mode.hpp` target_is_motorway | Read | Boolean | Is the target road a motorway? target_is_link | Read | Boolean | Is the target road a link? target_number_of_lanes | Read | Integer | How many lanes does the target road have? (default when not tagged: 0) -target_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0) -target_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0) +target_highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)) +target_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)) target_speed | Read | Integer | Speed on this target road in km/h roads_on_the_right | Read | Vector | Vector with information about other roads on the right of the turn that are also connected at the intersection roads_on_the_left | Read | Vector | Vector with information about other roads on the left of the turn that are also connected at the intersection weight | Read/write | Float | Penalty to be applied for this turn (routing weight) duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds) +#### `roads_on_the_right` and `roads_on_the_left` + The information of `roads_on_the_right` and `roads_on_the_left` that can be read are as follows: Attribute | Read/write? | Type | Notes @@ -245,15 +247,16 @@ mode | Read | Enum | Travel mode before the is_motorway | Read | Boolean | Is the road a motorway? is_link | Read | Boolean | Is the road a link? number_of_lanes | Read | Integer | How many lanes does the road have? (default when not tagged: 0) -highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0) -access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0) +highway_turn_classification | Read | Integer | Classification based on highway tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15) +access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15) speed | Read | Integer | Speed on this road in km/h is_incoming | Read | Boolean | Is the road an incoming road of the intersection is_outgoing | Read | Boolean | Is the road an outgoing road of the intersection The order of the roads in `roads_on_the_right` and `roads_on_the_left` are *counter clockwise*. If the turn is a u turn, all other connected roads will be in `roads_on_the_right`. -#### Example +**Example** + ``` c e | / @@ -271,7 +274,33 @@ When turning from `a` to `b` via `x`, * `roads_on_the_left[1]` is the road `xe` * `roads_on_the_left[2]` is the road `xc` -Note that indeces of arrays in lua are 1-based. +Note that indices of arrays in lua are 1-based. + +#### `highway_turn_classification` and `access_turn_classification` +When setting appropriate turn weights and duration, information about the highway and access tags of roads that are involved in the turn are necessary. The lua turn function `process_turn` does not have access to the original osrm tags anymore. However, `highway_turn_classification` and `access_turn_classification` can be set during setup. The classification set during setup can be later used in `process_turn`. + +**Example** + +In the following example we use `highway_turn_classification` to set the turn weight to `10` if the turn is on a highway and to `5` if the turn is on a primary. + +``` +function setup() + return { + highway_turn_classification = { + ['motorway'] = 2, + ['primary'] = 1 + } + } +end + +function process_turn(profile, turn) { + if turn.source_highway_turn_classification == 2 and turn.target_highway_turn_classification == 2 then + turn.weight = 10 + else if turn.source_highway_turn_classification == 1 and turn.target_highway_turn_classification == 1 then + turn.weight = 5 + end +} +``` ## Guidance The guidance parameters in profiles are currently a work in progress. They can and will change. From 3651f6b3708117ca706bd9e6a80f7463dda94c34 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Wed, 17 Jan 2018 16:15:19 +0100 Subject: [PATCH 13/37] small nitpicks and cleanup --- docs/profiles.md | 3 ++- features/support/hooks.js | 1 + include/extractor/extraction_turn.hpp | 6 ------ include/extractor/extraction_way.hpp | 4 ++-- include/extractor/node_based_edge.hpp | 6 +++--- include/partition/multi_level_partition.hpp | 2 +- profiles/lib/way_handlers.lua | 7 +++++++ src/extractor/edge_based_graph_factory.cpp | 11 +++++++++-- src/extractor/extractor_callbacks.cpp | 2 -- src/extractor/scripting_environment_lua.cpp | 6 ++++-- 10 files changed, 29 insertions(+), 19 deletions(-) diff --git a/docs/profiles.md b/docs/profiles.md index 5ec9bb5f830..6f731ea41b4 100644 --- a/docs/profiles.md +++ b/docs/profiles.md @@ -296,7 +296,8 @@ end function process_turn(profile, turn) { if turn.source_highway_turn_classification == 2 and turn.target_highway_turn_classification == 2 then turn.weight = 10 - else if turn.source_highway_turn_classification == 1 and turn.target_highway_turn_classification == 1 then + end + if turn.source_highway_turn_classification == 1 and turn.target_highway_turn_classification == 1 then turn.weight = 5 end } diff --git a/features/support/hooks.js b/features/support/hooks.js index c8b716607b2..43355e7048d 100644 --- a/features/support/hooks.js +++ b/features/support/hooks.js @@ -51,6 +51,7 @@ module.exports = function () { .defer(rimraf, this.scenarioLogFile) .awaitAll(callback); // Question @review is this line nice to have here (commented, but ready to use and uncomment if needed?) + // i think this is super useful and would love to have it here // console.log(" Writing logging output to " + this.scenarioLogFile) }); diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index f8036beaeea..dedbfda6f2e 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -48,7 +48,6 @@ struct ExtractionTurn int number_of_roads, bool is_u_turn, bool has_traffic_light, - // bool is_stop, bool is_give_way, bool is_left_hand_driving, bool source_restricted, TravelMode source_mode, @@ -93,16 +92,11 @@ struct ExtractionTurn { BOOST_ASSERT_MSG(!is_u_turn || roads_on_the_left.size() == 0, "there cannot be roads on the left when there is a u turn"); - BOOST_ASSERT_MSG(roads_on_the_right.size() + roads_on_the_left.size() + is_u_turn + 2 == - number_of_roads, - "number of roads at intersection do not match"); } const double angle; const int number_of_roads; const bool is_u_turn; const bool has_traffic_light; - // const bool is_stop; - // const bool is_give_way; const bool is_left_hand_driving; // source info diff --git a/include/extractor/extraction_way.hpp b/include/extractor/extraction_way.hpp index 04c427a7a43..29e07d0d387 100644 --- a/include/extractor/extraction_way.hpp +++ b/include/extractor/extraction_way.hpp @@ -127,8 +127,8 @@ struct ExtractionWay bool : 2; // user classifications for turn penalties - std::uint8_t highway_turn_classification; // @CHAUTODO memory? limit to 3 bits? // 8 - std::uint8_t access_turn_classification; // 3 are enough + std::uint8_t highway_turn_classification : 4; + std::uint8_t access_turn_classification : 4; }; } } diff --git a/include/extractor/node_based_edge.hpp b/include/extractor/node_based_edge.hpp index 7ce2722b026..3e98d181801 100644 --- a/include/extractor/node_based_edge.hpp +++ b/include/extractor/node_based_edge.hpp @@ -27,9 +27,9 @@ struct NodeBasedEdgeClassification std::uint8_t startpoint : 1; // 1 std::uint8_t restricted : 1; // 1 guidance::RoadClassification road_classification; // 16 2 - std::uint8_t highway_turn_classification; // @CHAUTODO memory? limit to 3 bits? // 8 - std::uint8_t access_turn_classification; // 3 are enough // 8 - std::uint8_t speed; // one bit could be saved here too I guess, so 7 // 8 + std::uint8_t highway_turn_classification : 4; // 4 + std::uint8_t access_turn_classification : 4; // 4 + std::uint8_t speed; // 8 NodeBasedEdgeClassification(); diff --git a/include/partition/multi_level_partition.hpp b/include/partition/multi_level_partition.hpp index 4fe037b7b5e..9847409aa38 100644 --- a/include/partition/multi_level_partition.hpp +++ b/include/partition/multi_level_partition.hpp @@ -148,7 +148,7 @@ template class MultiLevelPartitionImpl final auto offsets = MakeLevelOffsets(lidx_to_num_cells); auto masks = MakeLevelMasks(offsets, num_level); auto bits = MakeBitToLevel(offsets, num_level); - return std::make_unique(LevelData{num_level, offsets, masks, bits, {0}}); + return std::make_unique(LevelData{num_level, offsets, masks, bits, {{0}}}); } inline std::size_t LevelIDToIndex(LevelID l) const { return l - 1; } diff --git a/profiles/lib/way_handlers.lua b/profiles/lib/way_handlers.lua index d0ee490c363..2595eb2ba52 100644 --- a/profiles/lib/way_handlers.lua +++ b/profiles/lib/way_handlers.lua @@ -227,6 +227,13 @@ function WayHandlers.way_classification_for_turn(profile,way,result,data) local highway = way:get_value_by_key("highway") local access = way:get_value_by_key("access") + if profile.highway_turn_classification[highway] then + assert(profile.highway_turn_classification[highway] < 16, "highway_turn_classification must be smaller than 16") + end + if profile.access_turn_classification[highway] then + assert(profile.access_turn_classification[highway] < 16, "access_turn_classification must be smaller than 16") + end + if highway and profile.highway_turn_classification[highway] then result.highway_turn_classification = profile.highway_turn_classification[highway] end diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 14c983823d3..4559c2ec055 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -599,14 +599,15 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // compute weight and duration penalties auto is_traffic_light = m_traffic_lights.count(intersection_node); + std::vector road_legs_on_the_right; std::vector road_legs_on_the_left; - auto turn_iter = std::find_if(intersection.begin(), intersection.end(), [&turn](const auto &road) { return road.eid == turn.eid; }); + // if the turn is a u turn, store all information in road_legs_on_the_right if (turn_iter == intersection.begin()) { for (auto connected_edge = intersection.begin() + 1; @@ -627,6 +628,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( connected_edge->entry_allowed); } } + // otherwise split roads into the right or left side of the turn and store info else { for (auto connected_edge = intersection.begin() + 1; connected_edge < turn_iter; @@ -662,13 +664,16 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( connected_edge->entry_allowed); } } + ExtractionTurn extracted_turn( + // general info turn.angle, - m_node_based_graph.GetOutDegree(intersection_node), + intersection.size(), turn.instruction.IsUTurn(), is_traffic_light, m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data) .is_left_hand_driving, + // source info edge_data1.flags.restricted, m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data).travel_mode, edge_data1.flags.road_classification.IsMotorwayClass(), @@ -677,6 +682,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data1.flags.highway_turn_classification, edge_data1.flags.access_turn_classification, edge_data1.flags.speed, + // target info edge_data2.flags.restricted, m_edge_based_node_container.GetAnnotation(edge_data2.annotation_data).travel_mode, edge_data2.flags.road_classification.IsMotorwayClass(), @@ -685,6 +691,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data2.flags.highway_turn_classification, edge_data2.flags.access_turn_classification, edge_data2.flags.speed, + // connected roads road_legs_on_the_right, road_legs_on_the_left); diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index b632a3c2892..9f7b4f2382b 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -427,7 +427,6 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti parsed_way.is_startpoint, parsed_way.forward_restricted, road_classification, - // @CHAUTODO parsed_way.highway_turn_classification, parsed_way.access_turn_classification, speed}}; @@ -466,7 +465,6 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti parsed_way.is_startpoint, parsed_way.backward_restricted, road_classification, - // @CHAUTODO parsed_way.highway_turn_classification, parsed_way.access_turn_classification, speed}}; diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index 235a0dc2546..e446d587c6e 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -348,9 +348,11 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) sol::property([](const ExtractionWay &way) { return way.is_left_hand_driving; }, [](ExtractionWay &way, bool flag) { way.is_left_hand_driving = flag; }), "highway_turn_classification", - &ExtractionWay::highway_turn_classification, + sol::property([](const ExtractionWay &way) { return way.highway_turn_classification; }, + [](ExtractionWay &way, int flag) { way.highway_turn_classification = flag; }), "access_turn_classification", - &ExtractionWay::access_turn_classification); + sol::property([](const ExtractionWay &way) { return way.access_turn_classification; }, + [](ExtractionWay &way, int flag) { way.access_turn_classification = flag; })); auto getTypedRefBySol = [](const sol::object &obj) -> ExtractionRelation::OsmIDTyped { if (obj.is()) From 0ad7169f9d61e930043e6c1270cbf64a7b644cf5 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Thu, 18 Jan 2018 15:58:08 +0100 Subject: [PATCH 14/37] review adjustments --- docs/profiles.md | 2 +- .../options/extract/turn_function.feature | 300 ++++++++++- features/support/hooks.js | 3 +- profiles/feature/car_turnbot.lua | 483 ------------------ profiles/lib/way_handlers.lua | 9 +- src/extractor/extractor_callbacks.cpp | 4 +- 6 files changed, 282 insertions(+), 519 deletions(-) delete mode 100644 profiles/feature/car_turnbot.lua diff --git a/docs/profiles.md b/docs/profiles.md index 6f731ea41b4..8bbc8a4968c 100644 --- a/docs/profiles.md +++ b/docs/profiles.md @@ -210,7 +210,7 @@ The following attributes can be read and set on the result in `process_turn`: Attribute | Read/write? | Type | Notes --------------------- | ------------- | --------- | ------------------------------------------------------ -angle | Read | Float | Angle of turn in degrees (`0-360`: `0`=u-turn, `180`=straight on) +angle | Read | Float | Angle of turn in degrees (`[-179, 180]`: `0`=straight, `180`=u turn, `+x`=x degrees to the right, `-x`= x degrees to the left) number_of_roads | Read | Integer | Number of ways at the intersection of the turn is_u_turn | Read | Boolean | Is the turn a u-turn? has_traffic_light | Read | Boolean | Is a traffic light present at this turn? diff --git a/features/options/extract/turn_function.feature b/features/options/extract/turn_function.feature index e8069288451..1c5bea1e800 100644 --- a/features/options/extract/turn_function.feature +++ b/features/options/extract/turn_function.feature @@ -4,15 +4,78 @@ Feature: Turn Function Information Scenario: Turns should have correct information of source and target Given the profile file """ - functions = require('feature/car_turnbot') + functions = require('car') + + function test_setup() + profile = functions.setup() + profile.highway_turn_classification = { + ['motorway'] = 4, + ['motorway_link'] = 4, + ['trunk'] = 4, + ['trunk_link'] = 4, + ['primary'] = 4, + ['primary_link'] = 4, + ['secondary'] = 3, + ['secondary_link'] = 3, + ['tertiary'] = 2, + ['tertiary_link'] = 2, + ['residential'] = 1, + ['living_street'] = 1, + } + + profile.access_turn_classification = { + ['discouraged'] = 1; + ['permissive'] = 1; + ['private'] = 1; + ['customers'] = 1; + ['dismount'] = 1; + } + return profile + end + + function turn_leg_string (leg) + return 'speed: ' .. tostring(leg.speed) + .. ', is_incoming: ' .. tostring(leg.is_incoming) + .. ', is_outgoing: ' .. tostring(leg.is_outgoing) + .. ', highway_turn_classification: ' .. tostring(leg.highway_turn_classification) + .. ', access_turn_classification: ' .. tostring(leg.access_turn_classification) + end + + function print_turn (profile, turn) + print ('source_restricted ' .. string.format("%s", tostring(turn.source_restricted))) + print ('source_is_motorway ' .. string.format("%s", tostring(turn.source_is_motorway))) + print ('source_is_link ' .. string.format("%s", tostring(turn.source_is_link))) + print ('source_number_of_lanes ' .. string.format("%s", tostring(turn.source_number_of_lanes))) + print ('source_highway_turn_classification ' .. string.format("%s", tostring(turn.source_highway_turn_classification))) + print ('source_access_turn_classification ' .. string.format("%s", tostring(turn.source_access_turn_classification))) + print ('source_speed ' .. string.format("%s", tostring(turn.source_speed))) + + print ('target_restricted ' .. string.format("%s", tostring(turn.target_restricted))) + print ('target_is_motorway ' .. string.format("%s", tostring(turn.target_is_motorway))) + print ('target_is_link ' .. string.format("%s", tostring(turn.target_is_link))) + print ('target_number_of_lanes ' .. string.format("%s", tostring(turn.target_number_of_lanes))) + print ('target_highway_turn_classification ' .. string.format("%s", tostring(turn.target_highway_turn_classification))) + print ('target_access_turn_classification ' .. string.format("%s", tostring(turn.target_access_turn_classification))) + print ('target_speed ' .. string.format("%s", tostring(turn.target_speed))) + + print ('number_of_roads ' .. string.format("%s", tostring(turn.number_of_roads))) + if not turn.is_u_turn then + for roadCount, road in ipairs(turn.roads_on_the_right) do + print('roads_on_the_right [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) + end + + for roadCount, road in ipairs(turn.roads_on_the_left) do + print('roads_on_the_left [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) + end + end + end return { - setup = functions.setup, - process_way = functions.process_way, - process_node = functions.process_node, - process_turn = functions.process_turn + setup = test_setup, + process_way = functions.process_way, + process_node = functions.process_node, + process_turn = print_turn } - """ And the node map @@ -41,16 +104,78 @@ Feature: Turn Function Information Scenario: Turns should detect when turn is leaving highway Given the profile file """ - functions = require('feature/car_turnbot') + functions = require('car') - return { - setup = functions.setup, - process_way = functions.process_way, - process_node = functions.process_node, - process_turn = functions.process_turn - } + function test_setup() + profile = functions.setup() + profile.highway_turn_classification = { + ['motorway'] = 4, + ['motorway_link'] = 4, + ['trunk'] = 4, + ['trunk_link'] = 4, + ['primary'] = 4, + ['primary_link'] = 4, + ['secondary'] = 3, + ['secondary_link'] = 3, + ['tertiary'] = 2, + ['tertiary_link'] = 2, + ['residential'] = 1, + ['living_street'] = 1, + } + + profile.access_turn_classification = { + ['discouraged'] = 1; + ['permissive'] = 1; + ['private'] = 1; + ['customers'] = 1; + ['dismount'] = 1; + } + return profile + end + + function turn_leg_string (leg) + return 'speed: ' .. tostring(leg.speed) + .. ', is_incoming: ' .. tostring(leg.is_incoming) + .. ', is_outgoing: ' .. tostring(leg.is_outgoing) + .. ', highway_turn_classification: ' .. tostring(leg.highway_turn_classification) + .. ', access_turn_classification: ' .. tostring(leg.access_turn_classification) + end + function print_turn (profile, turn) + print ('source_restricted ' .. string.format("%s", tostring(turn.source_restricted))) + print ('source_is_motorway ' .. string.format("%s", tostring(turn.source_is_motorway))) + print ('source_is_link ' .. string.format("%s", tostring(turn.source_is_link))) + print ('source_number_of_lanes ' .. string.format("%s", tostring(turn.source_number_of_lanes))) + print ('source_highway_turn_classification ' .. string.format("%s", tostring(turn.source_highway_turn_classification))) + print ('source_access_turn_classification ' .. string.format("%s", tostring(turn.source_access_turn_classification))) + print ('source_speed ' .. string.format("%s", tostring(turn.source_speed))) + print ('target_restricted ' .. string.format("%s", tostring(turn.target_restricted))) + print ('target_is_motorway ' .. string.format("%s", tostring(turn.target_is_motorway))) + print ('target_is_link ' .. string.format("%s", tostring(turn.target_is_link))) + print ('target_number_of_lanes ' .. string.format("%s", tostring(turn.target_number_of_lanes))) + print ('target_highway_turn_classification ' .. string.format("%s", tostring(turn.target_highway_turn_classification))) + print ('target_access_turn_classification ' .. string.format("%s", tostring(turn.target_access_turn_classification))) + print ('target_speed ' .. string.format("%s", tostring(turn.target_speed))) + + print ('number_of_roads ' .. string.format("%s", tostring(turn.number_of_roads))) + if not turn.is_u_turn then + for roadCount, road in ipairs(turn.roads_on_the_right) do + print('roads_on_the_right [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) + end + + for roadCount, road in ipairs(turn.roads_on_the_left) do + print('roads_on_the_left [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) + end + end + end + + return { + setup = test_setup, + process_way = functions.process_way, + process_node = functions.process_node, + process_turn = print_turn + } """ And the node map @@ -74,20 +199,83 @@ Feature: Turn Function Information And stdout should contain "source_number_of_lanes 3" And stdout should contain "target_is_motorway false" And stdout should contain "target_is_link true" - # Question @review: should number_of_lanes when untagged be 0 or 1? And stdout should contain "target_number_of_lanes 0" And stdout should contain "number_of_roads 2" Scenario: Turns should have correct information of other roads at intersection I Given the profile file """ - functions = require('feature/car_turnbot') + functions = require('car') + + function test_setup() + profile = functions.setup() + profile.highway_turn_classification = { + ['motorway'] = 4, + ['motorway_link'] = 4, + ['trunk'] = 4, + ['trunk_link'] = 4, + ['primary'] = 4, + ['primary_link'] = 4, + ['secondary'] = 3, + ['secondary_link'] = 3, + ['tertiary'] = 2, + ['tertiary_link'] = 2, + ['residential'] = 1, + ['living_street'] = 1, + } + + profile.access_turn_classification = { + ['discouraged'] = 1; + ['permissive'] = 1; + ['private'] = 1; + ['customers'] = 1; + ['dismount'] = 1; + } + return profile + end + + function turn_leg_string (leg) + return 'speed: ' .. tostring(leg.speed) + .. ', is_incoming: ' .. tostring(leg.is_incoming) + .. ', is_outgoing: ' .. tostring(leg.is_outgoing) + .. ', highway_turn_classification: ' .. tostring(leg.highway_turn_classification) + .. ', access_turn_classification: ' .. tostring(leg.access_turn_classification) + end + + function print_turn (profile, turn) + print ('source_restricted ' .. string.format("%s", tostring(turn.source_restricted))) + print ('source_is_motorway ' .. string.format("%s", tostring(turn.source_is_motorway))) + print ('source_is_link ' .. string.format("%s", tostring(turn.source_is_link))) + print ('source_number_of_lanes ' .. string.format("%s", tostring(turn.source_number_of_lanes))) + print ('source_highway_turn_classification ' .. string.format("%s", tostring(turn.source_highway_turn_classification))) + print ('source_access_turn_classification ' .. string.format("%s", tostring(turn.source_access_turn_classification))) + print ('source_speed ' .. string.format("%s", tostring(turn.source_speed))) + + print ('target_restricted ' .. string.format("%s", tostring(turn.target_restricted))) + print ('target_is_motorway ' .. string.format("%s", tostring(turn.target_is_motorway))) + print ('target_is_link ' .. string.format("%s", tostring(turn.target_is_link))) + print ('target_number_of_lanes ' .. string.format("%s", tostring(turn.target_number_of_lanes))) + print ('target_highway_turn_classification ' .. string.format("%s", tostring(turn.target_highway_turn_classification))) + print ('target_access_turn_classification ' .. string.format("%s", tostring(turn.target_access_turn_classification))) + print ('target_speed ' .. string.format("%s", tostring(turn.target_speed))) + + print ('number_of_roads ' .. string.format("%s", tostring(turn.number_of_roads))) + if not turn.is_u_turn then + for roadCount, road in ipairs(turn.roads_on_the_right) do + print('roads_on_the_right [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) + end + + for roadCount, road in ipairs(turn.roads_on_the_left) do + print('roads_on_the_left [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) + end + end + end return { - setup = functions.setup, - process_way = functions.process_way, - process_node = functions.process_node, - process_turn = functions.process_turn + setup = test_setup, + process_way = functions.process_way, + process_node = functions.process_node, + process_turn = print_turn } """ @@ -117,13 +305,77 @@ Feature: Turn Function Information Scenario: Turns should have correct information of other roads at intersection II Given the profile file """ - functions = require('feature/car_turnbot') + functions = require('car') + + function test_setup() + profile = functions.setup() + profile.highway_turn_classification = { + ['motorway'] = 4, + ['motorway_link'] = 4, + ['trunk'] = 4, + ['trunk_link'] = 4, + ['primary'] = 4, + ['primary_link'] = 4, + ['secondary'] = 3, + ['secondary_link'] = 3, + ['tertiary'] = 2, + ['tertiary_link'] = 2, + ['residential'] = 1, + ['living_street'] = 1, + } + + profile.access_turn_classification = { + ['discouraged'] = 1; + ['permissive'] = 1; + ['private'] = 1; + ['customers'] = 1; + ['dismount'] = 1; + } + return profile + end + + function turn_leg_string (leg) + return 'speed: ' .. tostring(leg.speed) + .. ', is_incoming: ' .. tostring(leg.is_incoming) + .. ', is_outgoing: ' .. tostring(leg.is_outgoing) + .. ', highway_turn_classification: ' .. tostring(leg.highway_turn_classification) + .. ', access_turn_classification: ' .. tostring(leg.access_turn_classification) + end + + function print_turn (profile, turn) + print ('source_restricted ' .. string.format("%s", tostring(turn.source_restricted))) + print ('source_is_motorway ' .. string.format("%s", tostring(turn.source_is_motorway))) + print ('source_is_link ' .. string.format("%s", tostring(turn.source_is_link))) + print ('source_number_of_lanes ' .. string.format("%s", tostring(turn.source_number_of_lanes))) + print ('source_highway_turn_classification ' .. string.format("%s", tostring(turn.source_highway_turn_classification))) + print ('source_access_turn_classification ' .. string.format("%s", tostring(turn.source_access_turn_classification))) + print ('source_speed ' .. string.format("%s", tostring(turn.source_speed))) + + print ('target_restricted ' .. string.format("%s", tostring(turn.target_restricted))) + print ('target_is_motorway ' .. string.format("%s", tostring(turn.target_is_motorway))) + print ('target_is_link ' .. string.format("%s", tostring(turn.target_is_link))) + print ('target_number_of_lanes ' .. string.format("%s", tostring(turn.target_number_of_lanes))) + print ('target_highway_turn_classification ' .. string.format("%s", tostring(turn.target_highway_turn_classification))) + print ('target_access_turn_classification ' .. string.format("%s", tostring(turn.target_access_turn_classification))) + print ('target_speed ' .. string.format("%s", tostring(turn.target_speed))) + + print ('number_of_roads ' .. string.format("%s", tostring(turn.number_of_roads))) + if not turn.is_u_turn then + for roadCount, road in ipairs(turn.roads_on_the_right) do + print('roads_on_the_right [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) + end + + for roadCount, road in ipairs(turn.roads_on_the_left) do + print('roads_on_the_left [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) + end + end + end return { - setup = functions.setup, - process_way = functions.process_way, - process_node = functions.process_node, - process_turn = functions.process_turn + setup = test_setup, + process_way = functions.process_way, + process_node = functions.process_node, + process_turn = print_turn } """ diff --git a/features/support/hooks.js b/features/support/hooks.js index 43355e7048d..e58b34bfa22 100644 --- a/features/support/hooks.js +++ b/features/support/hooks.js @@ -50,8 +50,7 @@ module.exports = function () { .defer(mkdirp, logDir) .defer(rimraf, this.scenarioLogFile) .awaitAll(callback); - // Question @review is this line nice to have here (commented, but ready to use and uncomment if needed?) - // i think this is super useful and would love to have it here + // uncomment to get path to logfile // console.log(" Writing logging output to " + this.scenarioLogFile) }); diff --git a/profiles/feature/car_turnbot.lua b/profiles/feature/car_turnbot.lua deleted file mode 100644 index ee4a41cc43e..00000000000 --- a/profiles/feature/car_turnbot.lua +++ /dev/null @@ -1,483 +0,0 @@ --- Adjusted car profile with print output for testing --- at the moment used in features/options/extract/turn_function.feature - -api_version = 4 - -Set = require('lib/set') -Sequence = require('lib/sequence') -Handlers = require("lib/way_handlers") -Relations = require("lib/relations") -find_access_tag = require("lib/access").find_access_tag -limit = require("lib/maxspeed").limit -Utils = require("lib/utils") - -function setup() - return { - properties = { - max_speed_for_map_matching = 180/3.6, -- 180kmph -> m/s - -- For routing based on duration, but weighted for preferring certain roads - weight_name = 'routability', - -- For shortest duration without penalties for accessibility - -- weight_name = 'duration', - -- For shortest distance without penalties for accessibility - -- weight_name = 'distance', - process_call_tagless_node = false, - u_turn_penalty = 20, - continue_straight_at_waypoint = true, - use_turn_restrictions = true, - left_hand_driving = false, - traffic_light_penalty = 2, - }, - - default_mode = mode.driving, - default_speed = 10, - oneway_handling = true, - side_road_multiplier = 0.8, - turn_penalty = 7.5, - speed_reduction = 0.8, - turn_bias = 1.075, - cardinal_directions = false, - - -- Size of the vehicle, to be limited by physical restriction of the way - vehicle_height = 2.5, -- in metters, 2.5m is the height of van - vehicle_width = 1.9, -- in metters, ways with narrow tag are considered narrower than 2.2m - - -- a list of suffixes to suppress in name change instructions. The suffixes also include common substrings of each other - suffix_list = { - 'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East', 'Nor', 'Sou', 'We', 'Ea' - }, - - barrier_whitelist = Set { - 'cattle_grid', - 'border_control', - 'toll_booth', - 'sally_port', - 'gate', - 'lift_gate', - 'no', - 'entrance' - }, - - access_tag_whitelist = Set { - 'yes', - 'motorcar', - 'motor_vehicle', - 'vehicle', - 'permissive', - 'designated', - 'hov' - }, - - access_tag_blacklist = Set { - 'no', - 'agricultural', - 'forestry', - 'emergency', - 'psv', - 'customers', - 'private', - 'delivery', - 'destination' - }, - - restricted_access_tag_list = Set { - 'private', - 'delivery', - 'destination', - 'customers', - }, - - access_tags_hierarchy = Sequence { - 'motorcar', - 'motor_vehicle', - 'vehicle', - 'access' - }, - - service_tag_forbidden = Set { - 'emergency_access' - }, - - restrictions = Sequence { - 'motorcar', - 'motor_vehicle', - 'vehicle' - }, - - classes = Sequence { - 'toll', 'motorway', 'ferry', 'restricted' - }, - - -- classes to support for exclude flags - excludable = Sequence { - Set {'toll'}, - Set {'motorway'}, - Set {'ferry'} - }, - - avoid = Set { - 'area', - -- 'toll', -- uncomment this to avoid tolls - 'reversible', - 'impassable', - 'hov_lanes', - 'steps', - 'construction', - 'proposed' - }, - - speeds = Sequence { - highway = { - motorway = 90, - motorway_link = 45, - trunk = 85, - trunk_link = 40, - primary = 65, - primary_link = 30, - secondary = 55, - secondary_link = 25, - tertiary = 40, - tertiary_link = 20, - unclassified = 25, - residential = 25, - living_street = 10, - service = 15 - } - }, - - service_penalties = { - alley = 0.5, - parking = 0.5, - parking_aisle = 0.5, - driveway = 0.5, - ["drive-through"] = 0.5, - ["drive-thru"] = 0.5 - }, - - restricted_highway_whitelist = Set { - 'motorway', - 'motorway_link', - 'trunk', - 'trunk_link', - 'primary', - 'primary_link', - 'secondary', - 'secondary_link', - 'tertiary', - 'tertiary_link', - 'residential', - 'living_street', - 'unclassified' - }, - - construction_whitelist = Set { - 'no', - 'widening', - 'minor', - }, - - route_speeds = { - ferry = 5, - shuttle_train = 10 - }, - - bridge_speeds = { - movable = 5 - }, - - -- surface/trackype/smoothness - -- values were estimated from looking at the photos at the relevant wiki pages - - -- max speed for surfaces - surface_speeds = { - asphalt = nil, -- nil mean no limit. removing the line has the same effect - concrete = nil, - ["concrete:plates"] = nil, - ["concrete:lanes"] = nil, - paved = nil, - - cement = 80, - compacted = 80, - fine_gravel = 80, - - paving_stones = 60, - metal = 60, - bricks = 60, - - grass = 40, - wood = 40, - sett = 40, - grass_paver = 40, - gravel = 40, - unpaved = 40, - ground = 40, - dirt = 40, - pebblestone = 40, - tartan = 40, - - cobblestone = 30, - clay = 30, - - earth = 20, - stone = 20, - rocky = 20, - sand = 20, - - mud = 10 - }, - - -- max speed for tracktypes - tracktype_speeds = { - grade1 = 60, - grade2 = 40, - grade3 = 30, - grade4 = 25, - grade5 = 20 - }, - - -- max speed for smoothnesses - smoothness_speeds = { - intermediate = 80, - bad = 40, - very_bad = 20, - horrible = 10, - very_horrible = 5, - impassable = 0 - }, - - -- http://wiki.openstreetmap.org/wiki/Speed_limits - maxspeed_table_default = { - urban = 50, - rural = 90, - trunk = 110, - motorway = 130 - }, - - -- List only exceptions - maxspeed_table = { - ["at:rural"] = 100, - ["at:trunk"] = 100, - ["be:motorway"] = 120, - ["by:urban"] = 60, - ["by:motorway"] = 110, - ["ch:rural"] = 80, - ["ch:trunk"] = 100, - ["ch:motorway"] = 120, - ["cz:trunk"] = 0, - ["cz:motorway"] = 0, - ["de:living_street"] = 7, - ["de:rural"] = 100, - ["de:motorway"] = 0, - ["dk:rural"] = 80, - ["gb:nsl_single"] = (60*1609)/1000, - ["gb:nsl_dual"] = (70*1609)/1000, - ["gb:motorway"] = (70*1609)/1000, - ["nl:rural"] = 80, - ["nl:trunk"] = 100, - ['no:rural'] = 80, - ['no:motorway'] = 110, - ['pl:rural'] = 100, - ['pl:trunk'] = 120, - ['pl:motorway'] = 140, - ["ro:trunk"] = 100, - ["ru:living_street"] = 20, - ["ru:urban"] = 60, - ["ru:motorway"] = 110, - ["uk:nsl_single"] = (60*1609)/1000, - ["uk:nsl_dual"] = (70*1609)/1000, - ["uk:motorway"] = (70*1609)/1000, - ['za:urban'] = 60, - ['za:rural'] = 100, - ["none"] = 140 - }, - - relation_types = Sequence { - "route" - }, - - highway_turn_classification = { - ['motorway'] = 4, - ['motorway_link'] = 4, - ['trunk'] = 4, - ['trunk_link'] = 4, - ['primary'] = 4, - ['primary_link'] = 4, - ['secondary'] = 3, - ['secondary_link'] = 3, - ['tertiary'] = 2, - ['tertiary_link'] = 2, - ['residential'] = 1, - ['living_street'] = 1, - }, - - - access_turn_classification = { - ['discouraged'] = 1; - ['permissive'] = 1; - ['private'] = 1; - ['customers'] = 1; - ['dismount'] = 1; - } - } -end - -function process_node(profile, node, result, relations) - -- parse access and barrier tags - local access = find_access_tag(node, profile.access_tags_hierarchy) - if access then - if profile.access_tag_blacklist[access] and not profile.restricted_access_tag_list[access] then - result.barrier = true - end - else - local barrier = node:get_value_by_key("barrier") - if barrier then - -- make an exception for rising bollard barriers - local bollard = node:get_value_by_key("bollard") - local rising_bollard = bollard and "rising" == bollard - - if not profile.barrier_whitelist[barrier] and not rising_bollard then - result.barrier = true - end - end - end - - -- check if node is a traffic light - local tag = node:get_value_by_key("highway") - if "traffic_signals" == tag then - result.traffic_lights = true - end -end - -function process_way(profile, way, result, relations) - -- the intial filtering of ways based on presence of tags - -- affects processing times significantly, because all ways - -- have to be checked. - -- to increase performance, prefetching and intial tag check - -- is done in directly instead of via a handler. - - -- in general we should try to abort as soon as - -- possible if the way is not routable, to avoid doing - -- unnecessary work. this implies we should check things that - -- commonly forbids access early, and handle edge cases later. - - -- data table for storing intermediate values during processing - local data = { - -- prefetch tags - highway = way:get_value_by_key('highway'), - bridge = way:get_value_by_key('bridge'), - route = way:get_value_by_key('route') - } - - -- perform an quick initial check and abort if the way is - -- obviously not routable. - -- highway or route tags must be in data table, bridge is optional - if (not data.highway or data.highway == '') and - (not data.route or data.route == '') - then - return - end - - handlers = Sequence { - -- set the default mode for this profile. if can be changed later - -- in case it turns we're e.g. on a ferry - WayHandlers.default_mode, - - -- check various tags that could indicate that the way is not - -- routable. this includes things like status=impassable, - -- toll=yes and oneway=reversible - WayHandlers.blocked_ways, - WayHandlers.avoid_ways, - WayHandlers.handle_height, - WayHandlers.handle_width, - - -- determine access status by checking our hierarchy of - -- access tags, e.g: motorcar, motor_vehicle, vehicle - WayHandlers.access, - - -- check whether forward/backward directions are routable - WayHandlers.oneway, - - -- check a road's destination - WayHandlers.destinations, - - -- check whether we're using a special transport mode - WayHandlers.ferries, - WayHandlers.movables, - - -- handle service road restrictions - WayHandlers.service, - - -- handle hov - WayHandlers.hov, - - -- compute speed taking into account way type, maxspeed tags, etc. - WayHandlers.speed, - WayHandlers.surface, - WayHandlers.maxspeed, - WayHandlers.penalties, - - -- compute class labels - WayHandlers.classes, - - -- handle turn lanes and road classification, used for guidance - WayHandlers.turn_lanes, - WayHandlers.classification, - - -- handle various other flags - WayHandlers.roundabouts, - WayHandlers.startpoint, - WayHandlers.driving_side, - - -- set name, ref and pronunciation - WayHandlers.names, - - -- set weight properties of the way - WayHandlers.weights, - - -- set classification of ways relevant for turns - WayHandlers.way_classification_for_turn - } - - WayHandlers.run(profile, way, result, data, handlers, relations) - - if profile.cardinal_directions then - Relations.process_way_refs(way, relations, result) - end -end - - -function process_turn (profile, turn) - print ('source_restricted ' .. string.format("%s", tostring(turn.source_restricted))) - print ('source_is_motorway ' .. string.format("%s", tostring(turn.source_is_motorway))) - print ('source_is_link ' .. string.format("%s", tostring(turn.source_is_link))) - print ('source_number_of_lanes ' .. string.format("%s", tostring(turn.source_number_of_lanes))) - print ('source_highway_turn_classification ' .. string.format("%s", tostring(turn.source_highway_turn_classification))) - print ('source_access_turn_classification ' .. string.format("%s", tostring(turn.source_access_turn_classification))) - print ('source_speed ' .. string.format("%s", tostring(turn.source_speed))) - - print ('target_restricted ' .. string.format("%s", tostring(turn.target_restricted))) - print ('target_is_motorway ' .. string.format("%s", tostring(turn.target_is_motorway))) - print ('target_is_link ' .. string.format("%s", tostring(turn.target_is_link))) - print ('target_number_of_lanes ' .. string.format("%s", tostring(turn.target_number_of_lanes))) - print ('target_highway_turn_classification ' .. string.format("%s", tostring(turn.target_highway_turn_classification))) - print ('target_access_turn_classification ' .. string.format("%s", tostring(turn.target_access_turn_classification))) - print ('target_speed ' .. string.format("%s", tostring(turn.target_speed))) - - print ('number_of_roads ' .. string.format("%s", tostring(turn.number_of_roads))) - if not turn.is_u_turn then - for roadCount = 1, #turn.roads_on_the_right do - print('roads_on_the_right [' .. string.format("%s", tostring(roadCount)) .. '] speed: ' .. string.format("%s", tostring(turn.roads_on_the_right[roadCount].speed)) .. ', is_incoming: ' .. string.format("%s", tostring(turn.roads_on_the_right[roadCount].is_incoming)) .. ', is_outgoing: ' .. string.format("%s", tostring(turn.roads_on_the_right[roadCount].is_outgoing)) .. ', highway_turn_classification: ' .. string.format("%s", tostring(turn.roads_on_the_right[roadCount].highway_turn_classification)) .. ', access_turn_classification: ' .. string.format("%s", tostring(turn.roads_on_the_right[roadCount].access_turn_classification))) - end - - for roadCount = 1, #turn.roads_on_the_left do - print('roads_on_the_left [' .. string.format("%s", tostring(roadCount)) .. '] speed: ' .. string.format("%s", tostring(turn.roads_on_the_left[roadCount].speed)) .. ', is_incoming: ' .. string.format("%s", tostring(turn.roads_on_the_left[roadCount].is_incoming)) .. ', is_outgoing: ' .. string.format("%s", tostring(turn.roads_on_the_left[roadCount].is_outgoing)) .. ', highway_turn_classification: ' .. string.format("%s", tostring(turn.roads_on_the_left[roadCount].highway_turn_classification)) .. ', access_turn_classification: ' .. string.format("%s", tostring(turn.roads_on_the_left[roadCount].access_turn_classification))) - end - end -end - -return { - setup = setup, - process_way = process_way, - process_node = process_node, - process_turn = process_turn -} diff --git a/profiles/lib/way_handlers.lua b/profiles/lib/way_handlers.lua index 2595eb2ba52..b292baef978 100644 --- a/profiles/lib/way_handlers.lua +++ b/profiles/lib/way_handlers.lua @@ -227,17 +227,12 @@ function WayHandlers.way_classification_for_turn(profile,way,result,data) local highway = way:get_value_by_key("highway") local access = way:get_value_by_key("access") - if profile.highway_turn_classification[highway] then - assert(profile.highway_turn_classification[highway] < 16, "highway_turn_classification must be smaller than 16") - end - if profile.access_turn_classification[highway] then - assert(profile.access_turn_classification[highway] < 16, "access_turn_classification must be smaller than 16") - end - if highway and profile.highway_turn_classification[highway] then + assert(profile.highway_turn_classification[highway] < 16, "highway_turn_classification must be smaller than 16") result.highway_turn_classification = profile.highway_turn_classification[highway] end if access and profile.access_turn_classification[access] then + assert(profile.access_turn_classification[highway] < 16, "access_turn_classification must be smaller than 16") result.access_turn_classification = profile.access_turn_classification[access] end end diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index 9f7b4f2382b..3c8d426077d 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -406,7 +406,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti parsed_way.forward_travel_mode, parsed_way.is_left_hand_driving}); - std::uint8_t speed = parsed_way.forward_speed > 255 ? 255 : parsed_way.forward_speed; + std::uint8_t speed = std::min(parsed_way.forward_speed, 255); util::for_each_pair( nodes.cbegin(), @@ -445,7 +445,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti parsed_way.backward_travel_mode, parsed_way.is_left_hand_driving}); - std::uint8_t speed = parsed_way.backward_speed > 255 ? 255 : parsed_way.backward_speed; + std::uint8_t speed = std::min(parsed_way.backward_speed, 255); util::for_each_pair( nodes.cbegin(), nodes.cend(), From 09ff6ef8beda98409abb8cc62b8a5d8859354521 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Thu, 18 Jan 2018 18:55:01 +0100 Subject: [PATCH 15/37] remove speed from node based edge and calculate from edge length and duration instead --- include/extractor/node_based_edge.hpp | 8 +++----- src/extractor/edge_based_graph_factory.cpp | 22 +++++++++++++--------- src/extractor/extractor_callbacks.cpp | 11 ++--------- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/include/extractor/node_based_edge.hpp b/include/extractor/node_based_edge.hpp index 3e98d181801..5f2d6d94a26 100644 --- a/include/extractor/node_based_edge.hpp +++ b/include/extractor/node_based_edge.hpp @@ -29,7 +29,6 @@ struct NodeBasedEdgeClassification guidance::RoadClassification road_classification; // 16 2 std::uint8_t highway_turn_classification : 4; // 4 std::uint8_t access_turn_classification : 4; // 4 - std::uint8_t speed; // 8 NodeBasedEdgeClassification(); @@ -42,13 +41,12 @@ struct NodeBasedEdgeClassification const bool restricted, guidance::RoadClassification road_classification, const std::uint8_t highway_turn_classification, - const std::uint8_t access_turn_classification, - const std::uint8_t speed) + const std::uint8_t access_turn_classification) : forward(forward), backward(backward), is_split(is_split), roundabout(roundabout), circular(circular), startpoint(startpoint), restricted(restricted), road_classification(road_classification), highway_turn_classification(highway_turn_classification), - access_turn_classification(access_turn_classification), speed(speed) + access_turn_classification(access_turn_classification) { } @@ -191,7 +189,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM() { } -static_assert(sizeof(extractor::NodeBasedEdge) == 32, +static_assert(sizeof(extractor::NodeBasedEdge) == 28, "Size of extractor::NodeBasedEdge type is " "bigger than expected. This will influence " "memory consumption."); diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 4559c2ec055..98e81ba83d5 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -563,7 +563,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const auto incoming_bearing, const auto &turn, const auto entry_class_id, - const auto &intersection) { + const auto &intersection, + const auto &edge_geometries) { const auto node_restricted = isRestricted(node_along_road_entering, intersection_node, @@ -622,7 +623,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data.flags.road_classification.GetNumberOfLanes(), edge_data.flags.highway_turn_classification, edge_data.flags.access_turn_classification, - edge_data.flags.speed, + ((double)intersection::findEdgeLength(edge_geometries, connected_edge->eid) / edge_data.duration) * 36, !connected_edge->entry_allowed || (edge_data.flags.forward && edge_data.flags.backward), // is incoming connected_edge->entry_allowed); @@ -642,7 +643,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data.flags.road_classification.GetNumberOfLanes(), edge_data.flags.highway_turn_classification, edge_data.flags.access_turn_classification, - edge_data.flags.speed, + ((double)intersection::findEdgeLength(edge_geometries, connected_edge->eid) / edge_data.duration) * 36, !connected_edge->entry_allowed || (edge_data.flags.forward && edge_data.flags.backward), // is incoming connected_edge->entry_allowed); @@ -658,7 +659,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data.flags.road_classification.GetNumberOfLanes(), edge_data.flags.highway_turn_classification, edge_data.flags.access_turn_classification, - edge_data.flags.speed, + ((double)intersection::findEdgeLength(edge_geometries, connected_edge->eid) / edge_data.duration) * 36, !connected_edge->entry_allowed || (edge_data.flags.forward && edge_data.flags.backward), // is incoming connected_edge->entry_allowed); @@ -681,7 +682,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data1.flags.road_classification.GetNumberOfLanes(), edge_data1.flags.highway_turn_classification, edge_data1.flags.access_turn_classification, - edge_data1.flags.speed, + ((double)intersection::findEdgeLength(edge_geometries, node_based_edge_from) / edge_data1.duration) * 36, // target info edge_data2.flags.restricted, m_edge_based_node_container.GetAnnotation(edge_data2.annotation_data).travel_mode, @@ -690,7 +691,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data2.flags.road_classification.GetNumberOfLanes(), edge_data2.flags.highway_turn_classification, edge_data2.flags.access_turn_classification, - edge_data2.flags.speed, + ((double)intersection::findEdgeLength(edge_geometries, node_based_edge_to) / edge_data1.duration) * 36, // connected roads road_legs_on_the_right, road_legs_on_the_left); @@ -904,7 +905,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( reversed_incoming_bearing, *turn, entry_class_id, - intersection); + intersection, + edge_geometries); buffer->continuous_data.edges_list.push_back( edge_with_data_and_condition.first.edge); @@ -967,7 +969,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( reversed_incoming_bearing, *turn, entry_class_id, - intersection); + intersection, + edge_geometries); buffer->delayed_data.push_back( std::move(edge_with_data_and_condition.first)); @@ -1002,7 +1005,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( reversed_incoming_bearing, *turn, entry_class_id, - intersection); + intersection, + edge_geometries); buffer->delayed_data.push_back( std::move(edge_with_data_and_condition.first)); diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index 3c8d426077d..da08048e374 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -405,9 +405,6 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti forward_classes, parsed_way.forward_travel_mode, parsed_way.is_left_hand_driving}); - - std::uint8_t speed = std::min(parsed_way.forward_speed, 255); - util::for_each_pair( nodes.cbegin(), nodes.cend(), @@ -428,8 +425,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti parsed_way.forward_restricted, road_classification, parsed_way.highway_turn_classification, - parsed_way.access_turn_classification, - speed}}; + parsed_way.access_turn_classification}}; external_memory.all_edges_list.push_back(InternalExtractorEdge( std::move(edge), forward_weight_data, forward_duration_data, {})); @@ -444,8 +440,6 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti backward_classes, parsed_way.backward_travel_mode, parsed_way.is_left_hand_driving}); - - std::uint8_t speed = std::min(parsed_way.backward_speed, 255); util::for_each_pair( nodes.cbegin(), nodes.cend(), @@ -466,8 +460,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti parsed_way.backward_restricted, road_classification, parsed_way.highway_turn_classification, - parsed_way.access_turn_classification, - speed}}; + parsed_way.access_turn_classification}}; external_memory.all_edges_list.push_back(InternalExtractorEdge( std::move(edge), backward_weight_data, backward_duration_data, {})); From 73c72ffd4c2d95cb21554dd08d4c11e15705d642 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Thu, 18 Jan 2018 19:29:48 +0100 Subject: [PATCH 16/37] calculate speed by edge length and duration --- features/options/extract/turn_function.feature | 11 ++++------- profiles/lib/way_handlers.lua | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/features/options/extract/turn_function.feature b/features/options/extract/turn_function.feature index 1c5bea1e800..c67e39e6cc5 100644 --- a/features/options/extract/turn_function.feature +++ b/features/options/extract/turn_function.feature @@ -95,10 +95,8 @@ Feature: Turn Function Information And stdout should contain "source_is_motorway true" And stdout should contain "target_is_motorway true" And stdout should contain "source_is_link false" - And stdout should contain "source_speed 90" And stdout should contain "target_is_motorway true" And stdout should contain "target_is_link false" - And stdout should contain "target_speed 90" Scenario: Turns should detect when turn is leaving highway @@ -195,7 +193,6 @@ Feature: Turn Function Information Then it should exit successfully And stdout should contain "source_is_motorway true" And stdout should contain "source_is_link false" - And stdout should contain "source_speed 90" And stdout should contain "source_number_of_lanes 3" And stdout should contain "target_is_motorway false" And stdout should contain "target_is_link true" @@ -298,9 +295,9 @@ Feature: Turn Function Information Then it should exit successfully And stdout should contain "number_of_roads 3" # turning abd, give information about bc - And stdout should contain "roads_on_the_right [1] speed: 90, is_incoming: false, is_outgoing: true, highway_turn_classification: 4, access_turn_classification: 0" + And stdout should contain /roads_on_the_right \[1\] speed: [0-9]+, is_incoming: false, is_outgoing: true, highway_turn_classification: 4, access_turn_classification: 0/ # turning abc, give information about bd - And stdout should contain "roads_on_the_left [1] speed: 25, is_incoming: false, is_outgoing: true, highway_turn_classification: 1, access_turn_classification: 0" + And stdout should contain /roads_on_the_left \[1\] speed: [0-9]+, is_incoming: false, is_outgoing: true, highway_turn_classification: 1, access_turn_classification: 0/ Scenario: Turns should have correct information of other roads at intersection II Given the profile file @@ -398,9 +395,9 @@ Feature: Turn Function Information Then it should exit successfully And stdout should contain "number_of_roads 3" # turning dbc, give information about about ab - And stdout should contain "roads_on_the_right [1] speed: 55, is_incoming: true, is_outgoing: false, highway_turn_classification: 3, access_turn_classification: 0" + And stdout should contain /roads_on_the_right \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 3, access_turn_classification: 0/ # turning abc, give information about about db - And stdout should contain "roads_on_the_left [1] speed: 25, is_incoming: true, is_outgoing: false, highway_turn_classification: 0, access_turn_classification: 1" + And stdout should contain /roads_on_the_left \[1\] speed: [0-9]+, is_incoming: true, is_outgoing: false, highway_turn_classification: 0, access_turn_classification: 1/ diff --git a/profiles/lib/way_handlers.lua b/profiles/lib/way_handlers.lua index b292baef978..8da5d9d6612 100644 --- a/profiles/lib/way_handlers.lua +++ b/profiles/lib/way_handlers.lua @@ -232,7 +232,7 @@ function WayHandlers.way_classification_for_turn(profile,way,result,data) result.highway_turn_classification = profile.highway_turn_classification[highway] end if access and profile.access_turn_classification[access] then - assert(profile.access_turn_classification[highway] < 16, "access_turn_classification must be smaller than 16") + assert(profile.access_turn_classification[access] < 16, "access_turn_classification must be smaller than 16") result.access_turn_classification = profile.access_turn_classification[access] end end From 62c089e1a5594494e50b753d9025538717c28e3f Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Thu, 18 Jan 2018 21:59:21 +0100 Subject: [PATCH 17/37] split roads on the left and roads on the right before running generate_edge --- include/extractor/extraction_turn.hpp | 3 +- src/extractor/edge_based_graph_factory.cpp | 246 ++++++++++++--------- 2 files changed, 141 insertions(+), 108 deletions(-) diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index dedbfda6f2e..d46a8a9fbbf 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -69,8 +69,7 @@ struct ExtractionTurn std::vector &roads_on_the_right, std::vector &roads_on_the_left) : angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn), - has_traffic_light(has_traffic_light), - is_left_hand_driving(is_left_hand_driving), + has_traffic_light(has_traffic_light), is_left_hand_driving(is_left_hand_driving), source_restricted(source_restricted), source_mode(source_mode), source_is_motorway(source_is_motorway), source_is_link(source_is_link), diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 98e81ba83d5..f993f17554b 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -147,7 +147,8 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N // There should always be some geometry BOOST_ASSERT(0 != segment_count); - // const unsigned packed_geometry_id = m_compressed_edge_container.ZipEdges(edge_id_1, + // const unsigned packed_geometry_id = + // m_compressed_edge_container.ZipEdges(edge_id_1, // edge_id_2); NodeID current_edge_source_coordinate_id = node_u; @@ -231,7 +232,8 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment, TIMER_STOP(renumber); // Allocate memory for edge-based nodes - // In addition to the normal edges, allocate enough space for copied edges from + // In addition to the normal edges, allocate enough space for copied edges + // from // via-way-restrictions, see calculation above m_edge_based_node_container.nodes.resize(m_number_of_edge_based_nodes); @@ -267,7 +269,8 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment, /// Returns the number of edge-based nodes. unsigned EdgeBasedGraphFactory::LabelEdgeBasedNodes() { - // 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) m_edge_based_node_weights.reserve(4 * m_node_based_graph.GetNumberOfNodes()); nbe_to_ebn_mapping.resize(m_node_based_graph.GetEdgeCapacity(), SPECIAL_NODEID); @@ -295,14 +298,16 @@ unsigned EdgeBasedGraphFactory::LabelEdgeBasedNodes() return numbered_edges_count; } -/// Creates the nodes in the edge expanded graph from edges in the node-based graph. +/// Creates the nodes in the edge expanded graph from edges in the node-based +/// graph. std::vector EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_restriction_map) { std::vector mapping; util::Log() << "Generating edge expanded nodes ... "; - // indicating a normal node within the edge-based graph. This node represents an edge in the + // indicating a normal node within the edge-based graph. This node represents + // an edge in the // node-based graph { util::UnbufferedLog log; @@ -410,7 +415,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const ConditionalRestrictionMap &conditional_restriction_map, const WayRestrictionMap &way_restriction_map) { - util::Log() << "Generating edge-expanded edges "; std::size_t node_based_edge_counter = 0; @@ -472,13 +476,19 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // filled in during next stage, kept alive through following scope std::vector conditionals; - // The following block generates the edge-based-edges using a parallel processing - // pipeline. Sets of intersection IDs are batched in groups of GRAINSIZE (100) + // The following block generates the edge-based-edges using a parallel + // processing + // pipeline. Sets of intersection IDs are batched in groups of GRAINSIZE + // (100) // `generator_stage`, - // then those groups are processed in parallel `processor_stage`. Finally, results are - // appended to the various buffer vectors by the `output_stage` in the same order - // that the `generator_stage` created them in (tbb::filter::serial_in_order creates this - // guarantee). The order needs to be maintained because we depend on it later in the + // then those groups are processed in parallel `processor_stage`. Finally, + // results are + // appended to the various buffer vectors by the `output_stage` in the same + // order + // that the `generator_stage` created them in (tbb::filter::serial_in_order + // creates this + // guarantee). The order needs to be maintained because we depend on it later + // in the // processing pipeline. { util::UnbufferedLog log; @@ -488,17 +498,21 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // This counter is used to keep track of how far along we've made it std::uint64_t nodes_completed = 0; - // going over all nodes (which form the center of an intersection), we compute all + // going over all nodes (which form the center of an intersection), we + // compute all // possible turns along these intersections. NodeID current_node = 0; - // Handle intersections in sets of 100. The pipeline below has a serial bottleneck - // during the writing phase, so we want to make the parallel workers do more work + // Handle intersections in sets of 100. The pipeline below has a serial + // bottleneck + // during the writing phase, so we want to make the parallel workers do more + // work // to give the serial final stage time to complete its tasks. const constexpr unsigned GRAINSIZE = 100; - // First part of the pipeline generates iterator ranges of IDs in sets of GRAINSIZE + // First part of the pipeline generates iterator ranges of IDs in sets of + // GRAINSIZE tbb::filter_t> generator_stage( tbb::filter::serial_in_order, [&](tbb::flow_control &fc) -> tbb::blocked_range { if (current_node < node_count) @@ -515,7 +529,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( } }); - // This struct is the buffered output of the `processor_stage`. This data is + // This struct is the buffered output of the `processor_stage`. This data + // is // appended to the various output arrays/files by the `output_stage`. struct IntersectionData { @@ -526,7 +541,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( std::vector turn_data_container; }; - // same as IntersectionData, but grouped with edge to allow sorting after creating. Edges + // same as IntersectionData, but grouped with edge to allow sorting after + // creating. Edges // can be out of order struct EdgeWithData { @@ -550,8 +566,10 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( &scripting_environment, weight_multiplier, &conditional_restriction_map]( - // 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 + // 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 const auto edge_based_node_from, const auto edge_based_node_to, @@ -563,7 +581,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const auto incoming_bearing, const auto &turn, const auto entry_class_id, - const auto &intersection, + const auto roads_on_the_right, + const auto roads_on_the_left, const auto &edge_geometries) { const auto node_restricted = isRestricted(node_along_road_entering, @@ -603,73 +622,41 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( std::vector road_legs_on_the_right; std::vector road_legs_on_the_left; - auto turn_iter = - std::find_if(intersection.begin(), intersection.end(), [&turn](const auto &road) { - return road.eid == turn.eid; - }); - // if the turn is a u turn, store all information in road_legs_on_the_right - if (turn_iter == intersection.begin()) + auto get_connected_road_info = [&](auto &road_leg_vector, const auto &connected_edge) { + const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); + road_leg_vector.emplace_back( + edge_data.flags.restricted, + edge_data.flags.road_classification.IsMotorwayClass(), + edge_data.flags.road_classification.IsLinkClass(), + edge_data.flags.road_classification.GetNumberOfLanes(), + edge_data.flags.highway_turn_classification, + edge_data.flags.access_turn_classification, + ((double)intersection::findEdgeLength(edge_geometries, connected_edge->eid) / + edge_data.duration) * + 36, + !connected_edge->entry_allowed || + (edge_data.flags.forward && edge_data.flags.backward), // is incoming + connected_edge->entry_allowed); + }; + + for (auto connected_edge = roads_on_the_right.first; + connected_edge < roads_on_the_right.second; + connected_edge++) { - for (auto connected_edge = intersection.begin() + 1; - connected_edge < intersection.end(); - connected_edge++) - { - const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); - road_legs_on_the_right.emplace_back( - edge_data.flags.restricted, - edge_data.flags.road_classification.IsMotorwayClass(), - edge_data.flags.road_classification.IsLinkClass(), - edge_data.flags.road_classification.GetNumberOfLanes(), - edge_data.flags.highway_turn_classification, - edge_data.flags.access_turn_classification, - ((double)intersection::findEdgeLength(edge_geometries, connected_edge->eid) / edge_data.duration) * 36, - !connected_edge->entry_allowed || - (edge_data.flags.forward && edge_data.flags.backward), // is incoming - connected_edge->entry_allowed); - } + get_connected_road_info(road_legs_on_the_right, connected_edge); } - // otherwise split roads into the right or left side of the turn and store info - else + for (auto connected_edge = roads_on_the_left.first; + connected_edge < roads_on_the_left.second; + connected_edge++) { - for (auto connected_edge = intersection.begin() + 1; connected_edge < turn_iter; - connected_edge++) - { - const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); - road_legs_on_the_right.emplace_back( - edge_data.flags.restricted, - edge_data.flags.road_classification.IsMotorwayClass(), - edge_data.flags.road_classification.IsLinkClass(), - edge_data.flags.road_classification.GetNumberOfLanes(), - edge_data.flags.highway_turn_classification, - edge_data.flags.access_turn_classification, - ((double)intersection::findEdgeLength(edge_geometries, connected_edge->eid) / edge_data.duration) * 36, - !connected_edge->entry_allowed || - (edge_data.flags.forward && edge_data.flags.backward), // is incoming - connected_edge->entry_allowed); - } - for (auto connected_edge = turn_iter + 1; connected_edge < intersection.end(); - connected_edge++) - { - const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); - road_legs_on_the_left.emplace_back( - edge_data.flags.restricted, - edge_data.flags.road_classification.IsMotorwayClass(), - edge_data.flags.road_classification.IsLinkClass(), - edge_data.flags.road_classification.GetNumberOfLanes(), - edge_data.flags.highway_turn_classification, - edge_data.flags.access_turn_classification, - ((double)intersection::findEdgeLength(edge_geometries, connected_edge->eid) / edge_data.duration) * 36, - !connected_edge->entry_allowed || - (edge_data.flags.forward && edge_data.flags.backward), // is incoming - connected_edge->entry_allowed); - } + get_connected_road_info(road_legs_on_the_left, connected_edge); } ExtractionTurn extracted_turn( // general info turn.angle, - intersection.size(), + roads_on_the_left.second - roads_on_the_right.first + 1, turn.instruction.IsUTurn(), is_traffic_light, m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data) @@ -682,7 +669,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data1.flags.road_classification.GetNumberOfLanes(), edge_data1.flags.highway_turn_classification, edge_data1.flags.access_turn_classification, - ((double)intersection::findEdgeLength(edge_geometries, node_based_edge_from) / edge_data1.duration) * 36, + ((double)intersection::findEdgeLength(edge_geometries, node_based_edge_from) / + edge_data1.duration) * + 36, // target info edge_data2.flags.restricted, m_edge_based_node_container.GetAnnotation(edge_data2.annotation_data).travel_mode, @@ -691,7 +680,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data2.flags.road_classification.GetNumberOfLanes(), edge_data2.flags.highway_turn_classification, edge_data2.flags.access_turn_classification, - ((double)intersection::findEdgeLength(edge_geometries, node_based_edge_to) / edge_data1.duration) * 36, + ((double)intersection::findEdgeLength(edge_geometries, node_based_edge_to) / + edge_data1.duration) * + 36, // connected roads road_legs_on_the_right, road_legs_on_the_left); @@ -723,11 +714,13 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // We write out the mapping between the edge-expanded edges and // the original nodes. Since each edge represents a possible - // maneuver, external programs can use this to quickly perform updates to edge + // maneuver, external programs can use this to quickly perform updates to + // edge // weights in order to penalize certain turns. // If this edge is 'trivial' -- where the compressed edge - // corresponds exactly to an original OSM segment -- we can pull the turn's + // corresponds exactly to an original OSM segment -- we can pull the + // turn's // preceding node ID directly with `node_along_road_entering`; // otherwise, we need to look up the node immediately preceding the turn // from the compressed edge container. @@ -747,7 +740,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( conditional); }; - // 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 // each intersection tbb::filter_t, std::shared_ptr> processor_stage( tbb::filter::parallel, [&](const tbb::blocked_range &intersection_node_range) { @@ -756,7 +750,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( buffer->nodes_processed = intersection_node_range.end() - intersection_node_range.begin(); - // If we get fed a 0-length range for some reason, we can just return right away + // If we get fed a 0-length range for some reason, we can just return + // right away if (buffer->nodes_processed == 0) return buffer; @@ -782,8 +777,10 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( intersection_node); // all nodes in the graph are connected in both directions. We check all - // outgoing nodes to find the incoming edge. This is a larger search overhead, - // but the cost we need to pay to generate edges here is worth the additional + // outgoing nodes to find the incoming edge. This is a larger search + // overhead, + // but the cost we need to pay to generate edges here is worth the + // additional // search overhead. // // a -> b <-> c @@ -796,8 +793,10 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // b: a,rev=1 c,rev=0 d,rev=0 // c: b,rev=0 // - // From the flags alone, we cannot determine which nodes are connected to - // `b` by an outgoing edge. Therefore, we have to search all connected edges for + // From the flags alone, we cannot determine which nodes are connected + // to + // `b` by an outgoing edge. Therefore, we have to search all connected + // edges for // edges entering `b` for (const auto &incoming_edge : incoming_edges) @@ -867,7 +866,26 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( OSRM_ASSERT(turn != intersection.end(), m_coordinates[intersection_node]); - // In case a way restriction starts at a given location, add a turn onto + auto roads_on_the_right = + std::make_pair(intersection.end(), intersection.end()); + auto roads_on_the_left = + std::make_pair(intersection.end(), intersection.end()); + + if (turn == intersection.begin()) + { + roads_on_the_right.first = intersection.begin() + 1; + roads_on_the_right.second = intersection.end(); + } + else + { + roads_on_the_right.first = intersection.begin() + 1; + roads_on_the_right.second = turn; + roads_on_the_left.first = turn + 1; + roads_on_the_left.second = intersection.end(); + } + + // In case a way restriction starts at a given location, add a turn + // onto // every artificial node eminating here. // // e - f @@ -879,13 +897,17 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // ab via bc to cd // ab via be to ef // - // has two artifical nodes (be/bc) with restrictions starting at `ab`. + // has two artifical nodes (be/bc) with restrictions starting at + // `ab`. // Since every restriction group (abc | abe) refers to the same - // artificial node, we simply have to find a single representative for - // the turn. Here we check whether the turn in question is the start of + // artificial node, we simply have to find a single representative + // for + // the turn. Here we check whether the turn in question is the start + // of // a via way restriction. If that should be the case, we switch // the id of the edge-based-node for the target to the ID of the - // duplicated node associated with the turn. (e.g. ab via bc switches bc + // duplicated node associated with the turn. (e.g. ab via bc + // switches bc // to bc_dup) auto const target_id = way_restriction_map.RemapIfRestricted( nbe_to_ebn_mapping[outgoing_edge.edge], @@ -905,7 +927,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( reversed_incoming_bearing, *turn, entry_class_id, - intersection, + roads_on_the_right, + roads_on_the_left, edge_geometries); buffer->continuous_data.edges_list.push_back( @@ -925,9 +948,11 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( } } - // 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 - // duplicated node. This process is integrated here to avoid doing the + // duplicated node. This process is integrated here to avoid doing + // the // turn analysis multiple times. if (turning_off_via_way) { @@ -969,7 +994,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( reversed_incoming_bearing, *turn, entry_class_id, - intersection, + roads_on_the_right, + roads_on_the_left, edge_geometries); buffer->delayed_data.push_back( @@ -1005,7 +1031,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( reversed_incoming_bearing, *turn, entry_class_id, - intersection, + roads_on_the_right, + roads_on_the_left, edge_geometries); buffer->delayed_data.push_back( @@ -1037,7 +1064,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( std::vector delayed_data; - // Last part of the pipeline puts all the calculated data into the serial buffers + // Last part of the pipeline puts all the calculated data into the serial + // buffers tbb::filter_t, void> output_stage( tbb::filter::serial_in_order, [&](const std::shared_ptr buffer) { nodes_completed += buffer->nodes_processed; @@ -1076,10 +1104,14 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( delayed_data.end(), buffer->delayed_data.begin(), buffer->delayed_data.end()); }); - // Now, execute the pipeline. The value of "5" here was chosen by experimentation - // on a 16-CPU machine and seemed to give the best performance. This value needs - // to be balanced with the GRAINSIZE above - ideally, the pipeline puts as much work - // as possible in the `intersection_handler` step so that those parallel workers don't + // Now, execute the pipeline. The value of "5" here was chosen by + // experimentation + // on a 16-CPU machine and seemed to give the best performance. This value + // needs + // to be balanced with the GRAINSIZE above - ideally, the pipeline puts as + // much work + // as possible in the `intersection_handler` step so that those parallel + // workers don't // get blocked too much by the slower (io-performing) `buffer_storage` tbb::parallel_pipeline(tbb::task_scheduler_init::default_num_threads() * 5, generator_stage & processor_stage & output_stage); @@ -1116,9 +1148,11 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( } }); - // re-hash conditionals to ocnnect to their respective edge-based edges. Due to the + // re-hash conditionals to ocnnect to their respective edge-based edges. Due + // to the // ordering, we - // do not really have a choice but to index the conditional penalties and walk over all + // do not really have a choice but to index the conditional penalties and walk + // over all // edge-based-edges to find the ID of the edge auto const indexed_conditionals = IndexConditionals(std::move(conditionals)); { From d1f3146c0308d76dcb3564b3d47540661889833d Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Thu, 18 Jan 2018 22:04:26 +0100 Subject: [PATCH 18/37] comment on u turns and empty roads_on_the_left --- docs/profiles.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/profiles.md b/docs/profiles.md index 8bbc8a4968c..b2c8a3d4d25 100644 --- a/docs/profiles.md +++ b/docs/profiles.md @@ -232,7 +232,7 @@ target_highway_turn_classification | Read | Integer | Classification target_access_turn_classification | Read | Integer | Classification based on access tag defined by user during setup. (default when not set: 0, allowed classification values are: 0-15)) target_speed | Read | Integer | Speed on this target road in km/h roads_on_the_right | Read | Vector | Vector with information about other roads on the right of the turn that are also connected at the intersection -roads_on_the_left | Read | Vector | Vector with information about other roads on the left of the turn that are also connected at the intersection +roads_on_the_left | Read | Vector | Vector with information about other roads on the left of the turn that are also connected at the intersection. If turn is a u turn, this is empty. weight | Read/write | Float | Penalty to be applied for this turn (routing weight) duration | Read/write | Float | Penalty to be applied for this turn (duration in deciseconds) From 013d951f2d64cd0e90e430e26a446b7ad6cc3cb8 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Fri, 19 Jan 2018 14:45:21 +0100 Subject: [PATCH 19/37] move profile to background --- .../options/extract/turn_function.feature | 242 +----------------- 1 file changed, 7 insertions(+), 235 deletions(-) diff --git a/features/options/extract/turn_function.feature b/features/options/extract/turn_function.feature index c67e39e6cc5..897c1187cdf 100644 --- a/features/options/extract/turn_function.feature +++ b/features/options/extract/turn_function.feature @@ -1,7 +1,8 @@ @routing @testbot @turn_function Feature: Turn Function Information - Scenario: Turns should have correct information of source and target + + Background: Given the profile file """ functions = require('car') @@ -78,7 +79,8 @@ Feature: Turn Function Information } """ - And the node map + Scenario: Turns should have correct information of source and target + Given the node map """ a b c @@ -100,83 +102,7 @@ Feature: Turn Function Information Scenario: Turns should detect when turn is leaving highway - Given the profile file - """ - functions = require('car') - - function test_setup() - profile = functions.setup() - profile.highway_turn_classification = { - ['motorway'] = 4, - ['motorway_link'] = 4, - ['trunk'] = 4, - ['trunk_link'] = 4, - ['primary'] = 4, - ['primary_link'] = 4, - ['secondary'] = 3, - ['secondary_link'] = 3, - ['tertiary'] = 2, - ['tertiary_link'] = 2, - ['residential'] = 1, - ['living_street'] = 1, - } - - profile.access_turn_classification = { - ['discouraged'] = 1; - ['permissive'] = 1; - ['private'] = 1; - ['customers'] = 1; - ['dismount'] = 1; - } - return profile - end - - function turn_leg_string (leg) - return 'speed: ' .. tostring(leg.speed) - .. ', is_incoming: ' .. tostring(leg.is_incoming) - .. ', is_outgoing: ' .. tostring(leg.is_outgoing) - .. ', highway_turn_classification: ' .. tostring(leg.highway_turn_classification) - .. ', access_turn_classification: ' .. tostring(leg.access_turn_classification) - end - - function print_turn (profile, turn) - print ('source_restricted ' .. string.format("%s", tostring(turn.source_restricted))) - print ('source_is_motorway ' .. string.format("%s", tostring(turn.source_is_motorway))) - print ('source_is_link ' .. string.format("%s", tostring(turn.source_is_link))) - print ('source_number_of_lanes ' .. string.format("%s", tostring(turn.source_number_of_lanes))) - print ('source_highway_turn_classification ' .. string.format("%s", tostring(turn.source_highway_turn_classification))) - print ('source_access_turn_classification ' .. string.format("%s", tostring(turn.source_access_turn_classification))) - print ('source_speed ' .. string.format("%s", tostring(turn.source_speed))) - - print ('target_restricted ' .. string.format("%s", tostring(turn.target_restricted))) - print ('target_is_motorway ' .. string.format("%s", tostring(turn.target_is_motorway))) - print ('target_is_link ' .. string.format("%s", tostring(turn.target_is_link))) - print ('target_number_of_lanes ' .. string.format("%s", tostring(turn.target_number_of_lanes))) - print ('target_highway_turn_classification ' .. string.format("%s", tostring(turn.target_highway_turn_classification))) - print ('target_access_turn_classification ' .. string.format("%s", tostring(turn.target_access_turn_classification))) - print ('target_speed ' .. string.format("%s", tostring(turn.target_speed))) - - print ('number_of_roads ' .. string.format("%s", tostring(turn.number_of_roads))) - if not turn.is_u_turn then - for roadCount, road in ipairs(turn.roads_on_the_right) do - print('roads_on_the_right [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) - end - - for roadCount, road in ipairs(turn.roads_on_the_left) do - print('roads_on_the_left [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) - end - end - end - - return { - setup = test_setup, - process_way = functions.process_way, - process_node = functions.process_node, - process_turn = print_turn - } - """ - - And the node map + Given the node map """ a b c @@ -200,84 +126,7 @@ Feature: Turn Function Information And stdout should contain "number_of_roads 2" Scenario: Turns should have correct information of other roads at intersection I - Given the profile file - """ - functions = require('car') - - function test_setup() - profile = functions.setup() - profile.highway_turn_classification = { - ['motorway'] = 4, - ['motorway_link'] = 4, - ['trunk'] = 4, - ['trunk_link'] = 4, - ['primary'] = 4, - ['primary_link'] = 4, - ['secondary'] = 3, - ['secondary_link'] = 3, - ['tertiary'] = 2, - ['tertiary_link'] = 2, - ['residential'] = 1, - ['living_street'] = 1, - } - - profile.access_turn_classification = { - ['discouraged'] = 1; - ['permissive'] = 1; - ['private'] = 1; - ['customers'] = 1; - ['dismount'] = 1; - } - return profile - end - - function turn_leg_string (leg) - return 'speed: ' .. tostring(leg.speed) - .. ', is_incoming: ' .. tostring(leg.is_incoming) - .. ', is_outgoing: ' .. tostring(leg.is_outgoing) - .. ', highway_turn_classification: ' .. tostring(leg.highway_turn_classification) - .. ', access_turn_classification: ' .. tostring(leg.access_turn_classification) - end - - function print_turn (profile, turn) - print ('source_restricted ' .. string.format("%s", tostring(turn.source_restricted))) - print ('source_is_motorway ' .. string.format("%s", tostring(turn.source_is_motorway))) - print ('source_is_link ' .. string.format("%s", tostring(turn.source_is_link))) - print ('source_number_of_lanes ' .. string.format("%s", tostring(turn.source_number_of_lanes))) - print ('source_highway_turn_classification ' .. string.format("%s", tostring(turn.source_highway_turn_classification))) - print ('source_access_turn_classification ' .. string.format("%s", tostring(turn.source_access_turn_classification))) - print ('source_speed ' .. string.format("%s", tostring(turn.source_speed))) - - print ('target_restricted ' .. string.format("%s", tostring(turn.target_restricted))) - print ('target_is_motorway ' .. string.format("%s", tostring(turn.target_is_motorway))) - print ('target_is_link ' .. string.format("%s", tostring(turn.target_is_link))) - print ('target_number_of_lanes ' .. string.format("%s", tostring(turn.target_number_of_lanes))) - print ('target_highway_turn_classification ' .. string.format("%s", tostring(turn.target_highway_turn_classification))) - print ('target_access_turn_classification ' .. string.format("%s", tostring(turn.target_access_turn_classification))) - print ('target_speed ' .. string.format("%s", tostring(turn.target_speed))) - - print ('number_of_roads ' .. string.format("%s", tostring(turn.number_of_roads))) - if not turn.is_u_turn then - for roadCount, road in ipairs(turn.roads_on_the_right) do - print('roads_on_the_right [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) - end - - for roadCount, road in ipairs(turn.roads_on_the_left) do - print('roads_on_the_left [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) - end - end - end - - return { - setup = test_setup, - process_way = functions.process_way, - process_node = functions.process_node, - process_turn = print_turn - } - - """ - - And the node map + Given the node map """ d ^ @@ -300,84 +149,7 @@ Feature: Turn Function Information And stdout should contain /roads_on_the_left \[1\] speed: [0-9]+, is_incoming: false, is_outgoing: true, highway_turn_classification: 1, access_turn_classification: 0/ Scenario: Turns should have correct information of other roads at intersection II - Given the profile file - """ - functions = require('car') - - function test_setup() - profile = functions.setup() - profile.highway_turn_classification = { - ['motorway'] = 4, - ['motorway_link'] = 4, - ['trunk'] = 4, - ['trunk_link'] = 4, - ['primary'] = 4, - ['primary_link'] = 4, - ['secondary'] = 3, - ['secondary_link'] = 3, - ['tertiary'] = 2, - ['tertiary_link'] = 2, - ['residential'] = 1, - ['living_street'] = 1, - } - - profile.access_turn_classification = { - ['discouraged'] = 1; - ['permissive'] = 1; - ['private'] = 1; - ['customers'] = 1; - ['dismount'] = 1; - } - return profile - end - - function turn_leg_string (leg) - return 'speed: ' .. tostring(leg.speed) - .. ', is_incoming: ' .. tostring(leg.is_incoming) - .. ', is_outgoing: ' .. tostring(leg.is_outgoing) - .. ', highway_turn_classification: ' .. tostring(leg.highway_turn_classification) - .. ', access_turn_classification: ' .. tostring(leg.access_turn_classification) - end - - function print_turn (profile, turn) - print ('source_restricted ' .. string.format("%s", tostring(turn.source_restricted))) - print ('source_is_motorway ' .. string.format("%s", tostring(turn.source_is_motorway))) - print ('source_is_link ' .. string.format("%s", tostring(turn.source_is_link))) - print ('source_number_of_lanes ' .. string.format("%s", tostring(turn.source_number_of_lanes))) - print ('source_highway_turn_classification ' .. string.format("%s", tostring(turn.source_highway_turn_classification))) - print ('source_access_turn_classification ' .. string.format("%s", tostring(turn.source_access_turn_classification))) - print ('source_speed ' .. string.format("%s", tostring(turn.source_speed))) - - print ('target_restricted ' .. string.format("%s", tostring(turn.target_restricted))) - print ('target_is_motorway ' .. string.format("%s", tostring(turn.target_is_motorway))) - print ('target_is_link ' .. string.format("%s", tostring(turn.target_is_link))) - print ('target_number_of_lanes ' .. string.format("%s", tostring(turn.target_number_of_lanes))) - print ('target_highway_turn_classification ' .. string.format("%s", tostring(turn.target_highway_turn_classification))) - print ('target_access_turn_classification ' .. string.format("%s", tostring(turn.target_access_turn_classification))) - print ('target_speed ' .. string.format("%s", tostring(turn.target_speed))) - - print ('number_of_roads ' .. string.format("%s", tostring(turn.number_of_roads))) - if not turn.is_u_turn then - for roadCount, road in ipairs(turn.roads_on_the_right) do - print('roads_on_the_right [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) - end - - for roadCount, road in ipairs(turn.roads_on_the_left) do - print('roads_on_the_left [' .. tostring(roadCount) .. '] ' .. turn_leg_string(road)) - end - end - end - - return { - setup = test_setup, - process_way = functions.process_way, - process_node = functions.process_node, - process_turn = print_turn - } - - """ - - And the node map + Given the node map """ d | From 0611e55e8d54cd15e6f76ddc34eec4b34d435046 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Fri, 19 Jan 2018 16:42:29 +0100 Subject: [PATCH 20/37] move impl or setting info for connected edges --- include/extractor/extraction_turn.hpp | 4 +- src/extractor/edge_based_graph_factory.cpp | 106 ++++++++++----------- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index d46a8a9fbbf..8a2c78ee928 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -66,8 +66,8 @@ struct ExtractionTurn int target_highway_turn_classification, int target_access_turn_classification, int target_speed, - std::vector &roads_on_the_right, - std::vector &roads_on_the_left) + const std::vector &roads_on_the_right, + const std::vector &roads_on_the_left) : angle(180. - angle), number_of_roads(number_of_roads), is_u_turn(is_u_turn), has_traffic_light(has_traffic_light), is_left_hand_driving(is_left_hand_driving), diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index f993f17554b..456f478a4aa 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -580,9 +580,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const auto node_based_edge_to, const auto incoming_bearing, const auto &turn, + const auto &road_legs_on_the_right, + const auto &road_legs_on_the_left, const auto entry_class_id, - const auto roads_on_the_right, - const auto roads_on_the_left, const auto &edge_geometries) { const auto node_restricted = isRestricted(node_along_road_entering, @@ -620,43 +620,11 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // compute weight and duration penalties auto is_traffic_light = m_traffic_lights.count(intersection_node); - std::vector road_legs_on_the_right; - std::vector road_legs_on_the_left; - - auto get_connected_road_info = [&](auto &road_leg_vector, const auto &connected_edge) { - const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge->eid); - road_leg_vector.emplace_back( - edge_data.flags.restricted, - edge_data.flags.road_classification.IsMotorwayClass(), - edge_data.flags.road_classification.IsLinkClass(), - edge_data.flags.road_classification.GetNumberOfLanes(), - edge_data.flags.highway_turn_classification, - edge_data.flags.access_turn_classification, - ((double)intersection::findEdgeLength(edge_geometries, connected_edge->eid) / - edge_data.duration) * - 36, - !connected_edge->entry_allowed || - (edge_data.flags.forward && edge_data.flags.backward), // is incoming - connected_edge->entry_allowed); - }; - - for (auto connected_edge = roads_on_the_right.first; - connected_edge < roads_on_the_right.second; - connected_edge++) - { - get_connected_road_info(road_legs_on_the_right, connected_edge); - } - for (auto connected_edge = roads_on_the_left.first; - connected_edge < roads_on_the_left.second; - connected_edge++) - { - get_connected_road_info(road_legs_on_the_left, connected_edge); - } - + OSRM_ASSERT(!turn.instruction.IsUTurn() || road_legs_on_the_left.size() == 0, m_coordinates[intersection_node]); ExtractionTurn extracted_turn( // general info turn.angle, - roads_on_the_left.second - roads_on_the_right.first + 1, + road_legs_on_the_right.size() + road_legs_on_the_left.size() + 2 - turn.instruction.IsUTurn(), turn.instruction.IsUTurn(), is_traffic_light, m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data) @@ -866,22 +834,54 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( OSRM_ASSERT(turn != intersection.end(), m_coordinates[intersection_node]); - auto roads_on_the_right = - std::make_pair(intersection.end(), intersection.end()); - auto roads_on_the_left = - std::make_pair(intersection.end(), intersection.end()); - + std::vector road_legs_on_the_right; + std::vector road_legs_on_the_left; + + auto get_connected_road_info = [&](auto &road_leg_vector, + const auto &connected_edge) { + const auto &edge_data = + m_node_based_graph.GetEdgeData(connected_edge->eid); + road_leg_vector.emplace_back( + edge_data.flags.restricted, + edge_data.flags.road_classification.IsMotorwayClass(), + edge_data.flags.road_classification.IsLinkClass(), + edge_data.flags.road_classification.GetNumberOfLanes(), + edge_data.flags.highway_turn_classification, + edge_data.flags.access_turn_classification, + ((double)intersection::findEdgeLength(edge_geometries, + connected_edge->eid) / + edge_data.duration) * + 36, + !connected_edge->entry_allowed || + (edge_data.flags.forward && + edge_data.flags.backward), // is incoming + connected_edge->entry_allowed); + }; + + // all connected roads on the right of a u turn if (turn == intersection.begin()) { - roads_on_the_right.first = intersection.begin() + 1; - roads_on_the_right.second = intersection.end(); + for (auto connected_edge = intersection.begin() + 1; + connected_edge < intersection.end(); + connected_edge++) + { + get_connected_road_info(road_legs_on_the_right, connected_edge); + } } else { - roads_on_the_right.first = intersection.begin() + 1; - roads_on_the_right.second = turn; - roads_on_the_left.first = turn + 1; - roads_on_the_left.second = intersection.end(); + for (auto connected_edge = intersection.begin() + 1; + connected_edge < turn; + connected_edge++) + { + get_connected_road_info(road_legs_on_the_right, connected_edge); + } + for (auto connected_edge = turn + 1; + connected_edge < intersection.end(); + connected_edge++) + { + get_connected_road_info(road_legs_on_the_left, connected_edge); + } } // In case a way restriction starts at a given location, add a turn @@ -926,9 +926,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( outgoing_edge.edge, reversed_incoming_bearing, *turn, + road_legs_on_the_right, + road_legs_on_the_left, entry_class_id, - roads_on_the_right, - roads_on_the_left, edge_geometries); buffer->continuous_data.edges_list.push_back( @@ -993,9 +993,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( outgoing_edge.edge, reversed_incoming_bearing, *turn, + road_legs_on_the_right, + road_legs_on_the_left, entry_class_id, - roads_on_the_right, - roads_on_the_left, edge_geometries); buffer->delayed_data.push_back( @@ -1030,9 +1030,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( outgoing_edge.edge, reversed_incoming_bearing, *turn, + road_legs_on_the_right, + road_legs_on_the_left, entry_class_id, - roads_on_the_right, - roads_on_the_left, edge_geometries); buffer->delayed_data.push_back( From e51abc8642ceeaf2142e86376b4e920fb91a6de5 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Fri, 19 Jan 2018 16:43:06 +0100 Subject: [PATCH 21/37] clang-format --- src/extractor/edge_based_graph_factory.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 456f478a4aa..08df58315c5 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -620,11 +620,13 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // compute weight and duration penalties auto is_traffic_light = m_traffic_lights.count(intersection_node); - OSRM_ASSERT(!turn.instruction.IsUTurn() || road_legs_on_the_left.size() == 0, m_coordinates[intersection_node]); + OSRM_ASSERT(!turn.instruction.IsUTurn() || road_legs_on_the_left.size() == 0, + m_coordinates[intersection_node]); ExtractionTurn extracted_turn( // general info turn.angle, - road_legs_on_the_right.size() + road_legs_on_the_left.size() + 2 - turn.instruction.IsUTurn(), + road_legs_on_the_right.size() + road_legs_on_the_left.size() + 2 - + turn.instruction.IsUTurn(), turn.instruction.IsUTurn(), is_traffic_light, m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data) @@ -877,8 +879,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( get_connected_road_info(road_legs_on_the_right, connected_edge); } for (auto connected_edge = turn + 1; - connected_edge < intersection.end(); - connected_edge++) + connected_edge < intersection.end(); + connected_edge++) { get_connected_road_info(road_legs_on_the_left, connected_edge); } From 3ee0d22e2c815ad3d4398d07c12de0894cf638d6 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Fri, 19 Jan 2018 18:22:30 +0100 Subject: [PATCH 22/37] dirty commit! checking failing assertion --- src/extractor/edge_based_graph_factory.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 08df58315c5..5115ea6a4be 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -885,6 +885,16 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( get_connected_road_info(road_legs_on_the_left, connected_edge); } } + if (!(!turn->instruction.IsUTurn() || road_legs_on_the_left.size() == 0)) { + std::cout << std::endl; + std::cout << "is u turn " << turn->instruction.IsUTurn() << std::endl; + std::cout << "left size " << road_legs_on_the_left.size() << std::endl; + std::cout << "right size " << road_legs_on_the_right.size() << std::endl; + std::cout << "intersection size " << intersection.size() << std::endl; + std::cout << "turn index " << turn - intersection.begin() << std::endl; + } + OSRM_ASSERT(!turn->instruction.IsUTurn() || road_legs_on_the_left.size() == 0, + m_coordinates[intersection_node]); // In case a way restriction starts at a given location, add a turn // onto From d3391783e51dba04e1a52d97ff30cebbd830876f Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Fri, 19 Jan 2018 20:26:47 +0100 Subject: [PATCH 23/37] remove assertions for edge cases --- src/extractor/edge_based_graph_factory.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 5115ea6a4be..08df58315c5 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -885,16 +885,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( get_connected_road_info(road_legs_on_the_left, connected_edge); } } - if (!(!turn->instruction.IsUTurn() || road_legs_on_the_left.size() == 0)) { - std::cout << std::endl; - std::cout << "is u turn " << turn->instruction.IsUTurn() << std::endl; - std::cout << "left size " << road_legs_on_the_left.size() << std::endl; - std::cout << "right size " << road_legs_on_the_right.size() << std::endl; - std::cout << "intersection size " << intersection.size() << std::endl; - std::cout << "turn index " << turn - intersection.begin() << std::endl; - } - OSRM_ASSERT(!turn->instruction.IsUTurn() || road_legs_on_the_left.size() == 0, - m_coordinates[intersection_node]); // In case a way restriction starts at a given location, add a turn // onto From 430859c8842cba82c20d425cfcfdbdc7a10dbf9c Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Fri, 19 Jan 2018 20:32:12 +0100 Subject: [PATCH 24/37] less assertions --- include/extractor/extraction_turn.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index 8a2c78ee928..24624f489a6 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -89,8 +89,6 @@ struct ExtractionTurn duration(0.) { - BOOST_ASSERT_MSG(!is_u_turn || roads_on_the_left.size() == 0, - "there cannot be roads on the left when there is a u turn"); } const double angle; const int number_of_roads; From edc30b00b3107e67d377f0bc1b18077da3db725a Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Fri, 19 Jan 2018 20:44:40 +0100 Subject: [PATCH 25/37] strange clang-format glitch --- src/extractor/edge_based_graph_factory.cpp | 183 ++++++++------------- 1 file changed, 67 insertions(+), 116 deletions(-) diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 08df58315c5..20384198668 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -147,8 +147,7 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N // There should always be some geometry BOOST_ASSERT(0 != segment_count); - // const unsigned packed_geometry_id = - // m_compressed_edge_container.ZipEdges(edge_id_1, + // const unsigned packed_geometry_id = m_compressed_edge_container.ZipEdges(edge_id_1, // edge_id_2); NodeID current_edge_source_coordinate_id = node_u; @@ -232,8 +231,7 @@ void EdgeBasedGraphFactory::Run(ScriptingEnvironment &scripting_environment, TIMER_STOP(renumber); // Allocate memory for edge-based nodes - // In addition to the normal edges, allocate enough space for copied edges - // from + // In addition to the normal edges, allocate enough space for copied edges from // via-way-restrictions, see calculation above m_edge_based_node_container.nodes.resize(m_number_of_edge_based_nodes); @@ -298,16 +296,14 @@ unsigned EdgeBasedGraphFactory::LabelEdgeBasedNodes() return numbered_edges_count; } -/// Creates the nodes in the edge expanded graph from edges in the node-based -/// graph. +// Creates the nodes in the edge expanded graph from edges in the node-based graph. std::vector EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_restriction_map) { std::vector mapping; util::Log() << "Generating edge expanded nodes ... "; - // indicating a normal node within the edge-based graph. This node represents - // an edge in the + // indicating a normal node within the edge-based graph. This node represents an edge in the // node-based graph { util::UnbufferedLog log; @@ -328,8 +324,8 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re BOOST_ASSERT(nbg_node_v != SPECIAL_NODEID); BOOST_ASSERT(nbg_node_u != nbg_node_v); - // pick only every other edge, since we have every edge as an outgoing - // and incoming egde + // pick only every other edge, since we have every edge as an outgoing and incoming + // egde if (nbg_node_u >= nbg_node_v) { continue; @@ -476,20 +472,12 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // filled in during next stage, kept alive through following scope std::vector conditionals; - // The following block generates the edge-based-edges using a parallel - // processing - // pipeline. Sets of intersection IDs are batched in groups of GRAINSIZE - // (100) - // `generator_stage`, - // then those groups are processed in parallel `processor_stage`. Finally, - // results are - // appended to the various buffer vectors by the `output_stage` in the same - // order - // that the `generator_stage` created them in (tbb::filter::serial_in_order - // creates this - // guarantee). The order needs to be maintained because we depend on it later - // in the - // processing pipeline. + // The following block generates the edge-based-edges using a parallel processing pipeline. + // Sets of intersection IDs are batched in groups of GRAINSIZE (100) `generator_stage`, then + // those groups are processed in parallel `processor_stage`. Finally, results are appended to + // the various buffer vectors by the `output_stage` in the same order that the `generator_stage` + // created them in (tbb::filter::serial_in_order creates this guarantee). The order needs to be + // maintained because we depend on it later in the processing pipeline. { util::UnbufferedLog log; @@ -498,17 +486,14 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // This counter is used to keep track of how far along we've made it std::uint64_t nodes_completed = 0; - // going over all nodes (which form the center of an intersection), we - // compute all - // possible turns along these intersections. + // going over all nodes (which form the center of an intersection), we compute all possible + // turns along these intersections. NodeID current_node = 0; - // Handle intersections in sets of 100. The pipeline below has a serial - // bottleneck - // during the writing phase, so we want to make the parallel workers do more - // work - // to give the serial final stage time to complete its tasks. + // Handle intersections in sets of 100. The pipeline below has a serial bottleneck during + // the writing phase, so we want to make the parallel workers do more work to give the + // serial final stage time to complete its tasks. const constexpr unsigned GRAINSIZE = 100; // First part of the pipeline generates iterator ranges of IDs in sets of @@ -529,9 +514,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( } }); - // This struct is the buffered output of the `processor_stage`. This data - // is - // appended to the various output arrays/files by the `output_stage`. + // This struct is the buffered output of the `processor_stage`. This data is appended to + // the various output arrays/files by the `output_stage`. struct IntersectionData { std::vector turn_indexes; @@ -541,8 +525,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( std::vector turn_data_container; }; - // same as IntersectionData, but grouped with edge to allow sorting after - // creating. Edges + // same as IntersectionData, but grouped with edge to allow sorting after creating. Edges // can be out of order struct EdgeWithData { @@ -566,10 +549,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( &scripting_environment, weight_multiplier, &conditional_restriction_map]( - // 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 + // 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 const auto edge_based_node_from, const auto edge_based_node_to, @@ -620,8 +601,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // compute weight and duration penalties auto is_traffic_light = m_traffic_lights.count(intersection_node); - OSRM_ASSERT(!turn.instruction.IsUTurn() || road_legs_on_the_left.size() == 0, - m_coordinates[intersection_node]); ExtractionTurn extracted_turn( // general info turn.angle, @@ -659,8 +638,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( scripting_environment.ProcessTurn(extracted_turn); - // turn penalties are limited to [-2^15, 2^15) which roughly - // translates to 54 minutes and fits signed 16bit deci-seconds + // turn penalties are limited to [-2^15, 2^15) which roughly translates to 54 minutes + // and fits signed 16bit deci-seconds auto weight_penalty = boost::numeric_cast(extracted_turn.weight * weight_multiplier); auto duration_penalty = boost::numeric_cast(extracted_turn.duration * 10.); @@ -682,18 +661,15 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( true, false}; - // We write out the mapping between the edge-expanded edges and - // the original nodes. Since each edge represents a possible - // maneuver, external programs can use this to quickly perform updates to - // edge - // weights in order to penalize certain turns. - - // If this edge is 'trivial' -- where the compressed edge - // corresponds exactly to an original OSM segment -- we can pull the - // turn's - // preceding node ID directly with `node_along_road_entering`; - // otherwise, we need to look up the node immediately preceding the turn - // from the compressed edge container. + // We write out the mapping between the edge-expanded edges and the original nodes. + // Since each edge represents a possible maneuver, external programs can use this to + // quickly perform updates to edge weights in order to penalize certain turns. + + // If this edge is 'trivial' -- where the compressed edge corresponds exactly to an + // original OSM segment -- we can pull the turn's preceding node ID directly with + // `node_along_road_entering`; + // otherwise, we need to look up the node immediately preceding the turn from the + // compressed edge container. const bool isTrivial = m_compressed_edge_container.IsTrivial(node_based_edge_from); const auto &from_node = @@ -710,9 +686,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( conditional); }; - // Second part of the pipeline is where the intersection analysis is done - // for - // each intersection + // Second part of the pipeline is where the intersection analysis is done for each + // intersection tbb::filter_t, std::shared_ptr> processor_stage( tbb::filter::parallel, [&](const tbb::blocked_range &intersection_node_range) { @@ -720,8 +695,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( buffer->nodes_processed = intersection_node_range.end() - intersection_node_range.begin(); - // If we get fed a 0-length range for some reason, we can just return - // right away + // If we get fed a 0-length range for some reason, we can just return right away if (buffer->nodes_processed == 0) return buffer; @@ -730,8 +704,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( intersection_node < end; ++intersection_node) { - // We capture the thread-local work in these objects, then flush - // them in a controlled manner at the end of the parallel range + // We capture the thread-local work in these objects, then flush them in a + // controlled manner at the end of the parallel range const auto &incoming_edges = intersection::getIncomingEdges(m_node_based_graph, intersection_node); const auto &outgoing_edges = @@ -747,10 +721,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( intersection_node); // all nodes in the graph are connected in both directions. We check all - // outgoing nodes to find the incoming edge. This is a larger search - // overhead, - // but the cost we need to pay to generate edges here is worth the - // additional + // outgoing nodes to find the incoming edge. This is a larger search overhead, + // but the cost we need to pay to generate edges here is worth the additional // search overhead. // // a -> b <-> c @@ -763,11 +735,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // b: a,rev=1 c,rev=0 d,rev=0 // c: b,rev=0 // - // From the flags alone, we cannot determine which nodes are connected - // to - // `b` by an outgoing edge. Therefore, we have to search all connected - // edges for - // edges entering `b` + // From the flags alone, we cannot determine which nodes are connected to `b` by + // an outgoing edge. Therefore, we have to search all connected edges for edges + // entering `b` for (const auto &incoming_edge : incoming_edges) { @@ -802,9 +772,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const auto bearing_class_id = bearing_class_hash.ConcurrentFindOrAdd(turn_classification.second); - // Note - this is strictly speaking not thread safe, but we know we - // should never be touching the same element twice, so we should - // be fine. + // Note - this is strictly speaking not thread safe, but we know we should + // never be touching the same element twice, so we should be fine. bearing_class_by_node_based_node[intersection_node] = bearing_class_id; // check if we are turning off a via way @@ -886,8 +855,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( } } - // In case a way restriction starts at a given location, add a turn - // onto + // In case a way restriction starts at a given location, add a turn onto // every artificial node eminating here. // // e - f @@ -899,18 +867,13 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // ab via bc to cd // ab via be to ef // - // has two artifical nodes (be/bc) with restrictions starting at - // `ab`. + // has two artifical nodes (be/bc) with restrictions starting at `ab`. // Since every restriction group (abc | abe) refers to the same - // artificial node, we simply have to find a single representative - // for - // the turn. Here we check whether the turn in question is the start - // of - // a via way restriction. If that should be the case, we switch - // the id of the edge-based-node for the target to the ID of the - // duplicated node associated with the turn. (e.g. ab via bc - // switches bc - // to bc_dup) + // artificial node, we simply have to find a single representative for + // the turn. Here we check whether the turn in question is the start of + // a via way restriction. If that should be the case, we switch the id + // of the edge-based-node for the target to the ID of the duplicated + // node associated with the turn. (e.g. ab via bc switches bc to bc_dup) auto const target_id = way_restriction_map.RemapIfRestricted( nbe_to_ebn_mapping[outgoing_edge.edge], incoming_edge.node, @@ -950,11 +913,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( } } - // 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 - // duplicated node. This process is integrated here to avoid doing - // the + // duplicated node. This process is integrated here to avoid doing the // turn analysis multiple times. if (turning_off_via_way) { @@ -1055,19 +1016,16 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( return buffer; }); - // Because we write TurnIndexBlock data as we go, we'll - // buffer them into groups of 1000 to reduce the syscall - // count by 1000x. This doesn't need much memory, but - // greatly reduces the syscall overhead of writing lots - // of small objects + // Because we write TurnIndexBlock data as we go, we'll buffer them into groups of 1000 to + // reduce the syscall count by 1000x. This doesn't need much memory, but greatly reduces + // the syscall overhead of writing lots of small objects const constexpr int TURN_INDEX_WRITE_BUFFER_SIZE = 1000; std::vector turn_indexes_write_buffer; turn_indexes_write_buffer.reserve(TURN_INDEX_WRITE_BUFFER_SIZE); std::vector delayed_data; - // Last part of the pipeline puts all the calculated data into the serial - // buffers + // Last part of the pipeline puts all the calculated data into the serial buffers tbb::filter_t, void> output_stage( tbb::filter::serial_in_order, [&](const std::shared_ptr buffer) { nodes_completed += buffer->nodes_processed; @@ -1106,15 +1064,11 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( delayed_data.end(), buffer->delayed_data.begin(), buffer->delayed_data.end()); }); - // Now, execute the pipeline. The value of "5" here was chosen by - // experimentation - // on a 16-CPU machine and seemed to give the best performance. This value - // needs - // to be balanced with the GRAINSIZE above - ideally, the pipeline puts as - // much work - // as possible in the `intersection_handler` step so that those parallel - // workers don't - // get blocked too much by the slower (io-performing) `buffer_storage` + // Now, execute the pipeline. The value of "5" here was chosen by experimentation on a + // 16-CPU machine and seemed to give the best performance. This value needs to be balanced + // with the GRAINSIZE above - ideally, the pipeline puts as much work as possible in the + // `intersection_handler` step so that those parallel workers don't get blocked too much by + // the slower (io-performing) `buffer_storage` tbb::parallel_pipeline(tbb::task_scheduler_init::default_num_threads() * 5, generator_stage & processor_stage & output_stage); @@ -1140,8 +1094,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( } util::Log() << "Reunmbering turns"; - // Now, update the turn_id property on every EdgeBasedEdge - it will equal the - // position in the m_edge_based_edge_list array for each object. + // Now, update the turn_id property on every EdgeBasedEdge - it will equal the position in the + // m_edge_based_edge_list array for each object. tbb::parallel_for(tbb::blocked_range(0, m_edge_based_edge_list.size()), [this](const tbb::blocked_range &range) { for (auto x = range.begin(), end = range.end(); x != end; ++x) @@ -1150,11 +1104,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( } }); - // re-hash conditionals to ocnnect to their respective edge-based edges. Due - // to the - // ordering, we - // do not really have a choice but to index the conditional penalties and walk - // over all + // re-hash conditionals to ocnnect to their respective edge-based edges. Due to the ordering, we + // do not really have a choice but to index the conditional penalties and walk over all // edge-based-edges to find the ID of the edge auto const indexed_conditionals = IndexConditionals(std::move(conditionals)); { From 7898ccb426b26c71784c3f84f8270d5f8fd7ddc5 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Fri, 19 Jan 2018 21:13:22 +0100 Subject: [PATCH 26/37] adding warning if uturn and intersection dont match --- src/extractor/edge_based_graph_factory.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 20384198668..bcffc898fd0 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -855,6 +855,15 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( } } + if (turn->instruction.IsUTurn() && turn != intersection.begin()) + { + util::Log(logWARNING) + << "Turn is a u turn but is not turning in the first connected " + "edge of the intersection. Node ID " + << intersection_node << " coordinates " + << m_coordinates[intersection_node]; + } + // In case a way restriction starts at a given location, add a turn onto // every artificial node eminating here. // From 56754ea954acf84b9c574914fb4ca37d6feb7661 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Fri, 19 Jan 2018 21:34:34 +0100 Subject: [PATCH 27/37] handle u turns that do not turn into intersection[0] --- src/extractor/edge_based_graph_factory.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index bcffc898fd0..216d98db0b8 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -830,9 +830,19 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( }; // all connected roads on the right of a u turn - if (turn == intersection.begin()) + if (turn->instruction.IsUTurn()) { - for (auto connected_edge = intersection.begin() + 1; + if (turn != intersection.begin()) + { + for (auto connected_edge = intersection.begin() + 1; + connected_edge < turn; + connected_edge++) + { + get_connected_road_info(road_legs_on_the_right, + connected_edge); + } + } + for (auto connected_edge = turn + 1; connected_edge < intersection.end(); connected_edge++) { @@ -858,7 +868,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( if (turn->instruction.IsUTurn() && turn != intersection.begin()) { util::Log(logWARNING) - << "Turn is a u turn but is not turning in the first connected " + << "Turn is a u turn but not turning to the first connected " "edge of the intersection. Node ID " << intersection_node << " coordinates " << m_coordinates[intersection_node]; From 939ac0fc8a460755a0d3432e2f91ac8936fde564 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Mon, 22 Jan 2018 15:49:59 -0500 Subject: [PATCH 28/37] attempt to make travis happy --- .../extractor/intersection_analysis_tests.cpp | 281 +++++++++--------- 1 file changed, 139 insertions(+), 142 deletions(-) diff --git a/unit_tests/extractor/intersection_analysis_tests.cpp b/unit_tests/extractor/intersection_analysis_tests.cpp index 1692a1cc4e0..d51144e5950 100644 --- a/unit_tests/extractor/intersection_analysis_tests.cpp +++ b/unit_tests/extractor/intersection_analysis_tests.cpp @@ -166,150 +166,147 @@ BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity) // 0 // ↙ ↑ ↘ // 4 5 6 - const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed, bool roundabout) { - return InputEdge{ - from, - to, - 1, - 1, - GeometryID{0, false}, - !allowed, - NodeBasedEdgeClassification{true, false, false, roundabout, false, false, false, {}}, - 0}; - }; - std::vector edges = {unit_edge(0, 1, false, false), - unit_edge(0, 2, true, true), - unit_edge(0, 3, false, false), - unit_edge(0, 4, true, false), - unit_edge(0, 5, false, true), - unit_edge(0, 6, true, false), - unit_edge(1, 0, true, false), - unit_edge(2, 0, false, true), - unit_edge(3, 0, true, false), - unit_edge(4, 0, false, false), - unit_edge(5, 0, true, true), - unit_edge(6, 0, false, false)}; - IntersectionEdgeGeometries edge_geometries{ - {0, 315, 315, 10}, // 0→1 - {1, 0, 0, 10}, // 0→2 - {2, 45, 45, 10}, // 0→3 - {3, 225, 225, 10}, // 0→4 - {4, 180, 180, 10}, // 0→5 - {5, 135, 135, 10}, // 0→6 - {6, 135, 135, 10}, // 1→0 - {7, 180, 180, 10}, // 2→0 - {8, 225, 225, 10}, // 3→0 - {9, 45, 45, 10}, // 4→0 - {10, 0, 0, 10}, // 5→0 - {11, 315, 315, 10} // 6→0 - }; - - Graph graph(7, edges); - - GraphCompressor().Compress(barrier_nodes, - traffic_lights, - scripting_environment, - restrictions, - conditional_restrictions, - graph, - annotations, - container); - - REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 0), 3); - REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 0), 6); - - EdgeBasedNodeDataContainer node_data_container( - std::vector(graph.GetNumberOfEdges()), annotations); - RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia()); - - const auto connectivity_matrix = [&](NodeID node) { - std::vector result; - const auto incoming_edges = getIncomingEdges(graph, node); - const auto outgoing_edges = getOutgoingEdges(graph, node); - for (const auto incoming_edge : incoming_edges) - { - for (const auto outgoing_edge : outgoing_edges) + const auto unit_edge = + [](const NodeID from, const NodeID to, bool allowed, bool roundabout) { + return InputEdge { - result.push_back(isTurnAllowed(graph, - node_data_container, - restriction_map, - barrier_nodes, - edge_geometries, - turn_lanes_data, - incoming_edge, - outgoing_edge)); - } - } - return result; - }; - - CHECK_EQUAL_RANGE(connectivity_matrix(0), - // clang-format off + from, to, 1, 1, GeometryID{0, false}, !allowed, + NodeBasedEdgeClassification{ + true, false, false, roundabout, false, false, false, {{0}}}; + }; + std::vector edges = {unit_edge(0, 1, false, false), + unit_edge(0, 2, true, true), + unit_edge(0, 3, false, false), + unit_edge(0, 4, true, false), + unit_edge(0, 5, false, true), + unit_edge(0, 6, true, false), + unit_edge(1, 0, true, false), + unit_edge(2, 0, false, true), + unit_edge(3, 0, true, false), + unit_edge(4, 0, false, false), + unit_edge(5, 0, true, true), + unit_edge(6, 0, false, false)}; + IntersectionEdgeGeometries edge_geometries{ + {0, 315, 315, 10}, // 0→1 + {1, 0, 0, 10}, // 0→2 + {2, 45, 45, 10}, // 0→3 + {3, 225, 225, 10}, // 0→4 + {4, 180, 180, 10}, // 0→5 + {5, 135, 135, 10}, // 0→6 + {6, 135, 135, 10}, // 1→0 + {7, 180, 180, 10}, // 2→0 + {8, 225, 225, 10}, // 3→0 + {9, 45, 45, 10}, // 4→0 + {10, 0, 0, 10}, // 5→0 + {11, 315, 315, 10} // 6→0 + }; + + Graph graph(7, edges); + + GraphCompressor().Compress(barrier_nodes, + traffic_lights, + scripting_environment, + restrictions, + conditional_restrictions, + graph, + annotations, + container); + + REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 0), 3); + REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 0), 6); + + EdgeBasedNodeDataContainer node_data_container( + std::vector(graph.GetNumberOfEdges()), annotations); + RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia()); + + const auto connectivity_matrix = [&](NodeID node) { + std::vector result; + const auto incoming_edges = getIncomingEdges(graph, node); + const auto outgoing_edges = getOutgoingEdges(graph, node); + for (const auto incoming_edge : incoming_edges) + { + for (const auto outgoing_edge : outgoing_edges) + { + result.push_back(isTurnAllowed(graph, + node_data_container, + restriction_map, + barrier_nodes, + edge_geometries, + turn_lanes_data, + incoming_edge, + outgoing_edge)); + } + } + return result; + }; + + CHECK_EQUAL_RANGE(connectivity_matrix(0), + // clang-format off 0, 1, 0, 0, 0, 1, // from node 1 to nodes 2 and 6 0, 1, 0, 1, 0, 0, // from node 3 to nodes 2 and 4 0, 1, 0, 1, 0, 1 // from node 5 to nodes 2, 4 and 6 - // clang-format on - ); -} - -BOOST_AUTO_TEST_CASE(skip_degree_two_nodes) -{ - std::unordered_set barrier_nodes{1}; - std::unordered_set traffic_lights{2}; - std::vector annotations(1); - std::vector restrictions; - std::vector conditional_restrictions; - CompressedEdgeContainer container; - test::MockScriptingEnvironment scripting_environment; - - TurnLanesIndexedArray turn_lanes_data; - - // Graph - // - // 0↔1→2↔3↔4→5 7 - // ↑ ↕ ↕ - // 6 8 ↔ 9 - // - const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed) { - return InputEdge{ - from, to, 1, 1, GeometryID{0, false}, !allowed, NodeBasedEdgeClassification{}, 0}; - }; - std::vector edges = {unit_edge(0, 1, true), // 0 - unit_edge(1, 0, true), - unit_edge(1, 2, true), - unit_edge(2, 1, false), - unit_edge(2, 3, true), - unit_edge(3, 2, true), // 5 - unit_edge(3, 4, true), - unit_edge(4, 3, true), - unit_edge(4, 5, true), - unit_edge(4, 6, false), - unit_edge(5, 4, false), // 10 - unit_edge(6, 4, true), - // Circle - unit_edge(7, 8, true), // 12 - unit_edge(7, 9, true), - unit_edge(8, 7, true), - unit_edge(8, 9, true), - unit_edge(9, 7, true), - unit_edge(9, 8, true)}; - - Graph graph(10, edges); - - GraphCompressor().Compress(barrier_nodes, - traffic_lights, - scripting_environment, - restrictions, - conditional_restrictions, - graph, - annotations, - container); - - BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {0, 0}).edge), 4); - BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {4, 7}).edge), 0); - BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {5, 10}).edge), 4); - BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {6, 11}).edge), 4); - BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {7, 12}).edge), 7); -} + // clang-format on + ); + } -BOOST_AUTO_TEST_SUITE_END() + BOOST_AUTO_TEST_CASE(skip_degree_two_nodes) + { + std::unordered_set barrier_nodes{1}; + std::unordered_set traffic_lights{2}; + std::vector annotations(1); + std::vector restrictions; + std::vector conditional_restrictions; + CompressedEdgeContainer container; + test::MockScriptingEnvironment scripting_environment; + + TurnLanesIndexedArray turn_lanes_data; + + // Graph + // + // 0↔1→2↔3↔4→5 7 + // ↑ ↕ ↕ + // 6 8 ↔ 9 + // + const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed) { + return InputEdge{ + from, to, 1, 1, GeometryID{0, false}, !allowed, NodeBasedEdgeClassification{}, 0}; + }; + std::vector edges = {unit_edge(0, 1, true), // 0 + unit_edge(1, 0, true), + unit_edge(1, 2, true), + unit_edge(2, 1, false), + unit_edge(2, 3, true), + unit_edge(3, 2, true), // 5 + unit_edge(3, 4, true), + unit_edge(4, 3, true), + unit_edge(4, 5, true), + unit_edge(4, 6, false), + unit_edge(5, 4, false), // 10 + unit_edge(6, 4, true), + // Circle + unit_edge(7, 8, true), // 12 + unit_edge(7, 9, true), + unit_edge(8, 7, true), + unit_edge(8, 9, true), + unit_edge(9, 7, true), + unit_edge(9, 8, true)}; + + Graph graph(10, edges); + + GraphCompressor().Compress(barrier_nodes, + traffic_lights, + scripting_environment, + restrictions, + conditional_restrictions, + graph, + annotations, + container); + + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {0, 0}).edge), 4); + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {4, 7}).edge), 0); + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {5, 10}).edge), 4); + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {6, 11}).edge), 4); + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {7, 12}).edge), 7); + } + + BOOST_AUTO_TEST_SUITE_END() From 989f6335bf403fb54950ce26a0d0816ba22669d2 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Mon, 22 Jan 2018 15:57:41 -0500 Subject: [PATCH 29/37] try again --- .../extractor/intersection_analysis_tests.cpp | 281 +++++++++--------- 1 file changed, 142 insertions(+), 139 deletions(-) diff --git a/unit_tests/extractor/intersection_analysis_tests.cpp b/unit_tests/extractor/intersection_analysis_tests.cpp index d51144e5950..1692a1cc4e0 100644 --- a/unit_tests/extractor/intersection_analysis_tests.cpp +++ b/unit_tests/extractor/intersection_analysis_tests.cpp @@ -166,147 +166,150 @@ BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity) // 0 // ↙ ↑ ↘ // 4 5 6 - const auto unit_edge = - [](const NodeID from, const NodeID to, bool allowed, bool roundabout) { - return InputEdge + const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed, bool roundabout) { + return InputEdge{ + from, + to, + 1, + 1, + GeometryID{0, false}, + !allowed, + NodeBasedEdgeClassification{true, false, false, roundabout, false, false, false, {}}, + 0}; + }; + std::vector edges = {unit_edge(0, 1, false, false), + unit_edge(0, 2, true, true), + unit_edge(0, 3, false, false), + unit_edge(0, 4, true, false), + unit_edge(0, 5, false, true), + unit_edge(0, 6, true, false), + unit_edge(1, 0, true, false), + unit_edge(2, 0, false, true), + unit_edge(3, 0, true, false), + unit_edge(4, 0, false, false), + unit_edge(5, 0, true, true), + unit_edge(6, 0, false, false)}; + IntersectionEdgeGeometries edge_geometries{ + {0, 315, 315, 10}, // 0→1 + {1, 0, 0, 10}, // 0→2 + {2, 45, 45, 10}, // 0→3 + {3, 225, 225, 10}, // 0→4 + {4, 180, 180, 10}, // 0→5 + {5, 135, 135, 10}, // 0→6 + {6, 135, 135, 10}, // 1→0 + {7, 180, 180, 10}, // 2→0 + {8, 225, 225, 10}, // 3→0 + {9, 45, 45, 10}, // 4→0 + {10, 0, 0, 10}, // 5→0 + {11, 315, 315, 10} // 6→0 + }; + + Graph graph(7, edges); + + GraphCompressor().Compress(barrier_nodes, + traffic_lights, + scripting_environment, + restrictions, + conditional_restrictions, + graph, + annotations, + container); + + REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 0), 3); + REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 0), 6); + + EdgeBasedNodeDataContainer node_data_container( + std::vector(graph.GetNumberOfEdges()), annotations); + RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia()); + + const auto connectivity_matrix = [&](NodeID node) { + std::vector result; + const auto incoming_edges = getIncomingEdges(graph, node); + const auto outgoing_edges = getOutgoingEdges(graph, node); + for (const auto incoming_edge : incoming_edges) + { + for (const auto outgoing_edge : outgoing_edges) { - from, to, 1, 1, GeometryID{0, false}, !allowed, - NodeBasedEdgeClassification{ - true, false, false, roundabout, false, false, false, {{0}}}; - }; - std::vector edges = {unit_edge(0, 1, false, false), - unit_edge(0, 2, true, true), - unit_edge(0, 3, false, false), - unit_edge(0, 4, true, false), - unit_edge(0, 5, false, true), - unit_edge(0, 6, true, false), - unit_edge(1, 0, true, false), - unit_edge(2, 0, false, true), - unit_edge(3, 0, true, false), - unit_edge(4, 0, false, false), - unit_edge(5, 0, true, true), - unit_edge(6, 0, false, false)}; - IntersectionEdgeGeometries edge_geometries{ - {0, 315, 315, 10}, // 0→1 - {1, 0, 0, 10}, // 0→2 - {2, 45, 45, 10}, // 0→3 - {3, 225, 225, 10}, // 0→4 - {4, 180, 180, 10}, // 0→5 - {5, 135, 135, 10}, // 0→6 - {6, 135, 135, 10}, // 1→0 - {7, 180, 180, 10}, // 2→0 - {8, 225, 225, 10}, // 3→0 - {9, 45, 45, 10}, // 4→0 - {10, 0, 0, 10}, // 5→0 - {11, 315, 315, 10} // 6→0 - }; - - Graph graph(7, edges); - - GraphCompressor().Compress(barrier_nodes, - traffic_lights, - scripting_environment, - restrictions, - conditional_restrictions, - graph, - annotations, - container); - - REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 0), 3); - REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 0), 6); - - EdgeBasedNodeDataContainer node_data_container( - std::vector(graph.GetNumberOfEdges()), annotations); - RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia()); - - const auto connectivity_matrix = [&](NodeID node) { - std::vector result; - const auto incoming_edges = getIncomingEdges(graph, node); - const auto outgoing_edges = getOutgoingEdges(graph, node); - for (const auto incoming_edge : incoming_edges) - { - for (const auto outgoing_edge : outgoing_edges) - { - result.push_back(isTurnAllowed(graph, - node_data_container, - restriction_map, - barrier_nodes, - edge_geometries, - turn_lanes_data, - incoming_edge, - outgoing_edge)); - } - } - return result; - }; - - CHECK_EQUAL_RANGE(connectivity_matrix(0), - // clang-format off + result.push_back(isTurnAllowed(graph, + node_data_container, + restriction_map, + barrier_nodes, + edge_geometries, + turn_lanes_data, + incoming_edge, + outgoing_edge)); + } + } + return result; + }; + + CHECK_EQUAL_RANGE(connectivity_matrix(0), + // clang-format off 0, 1, 0, 0, 0, 1, // from node 1 to nodes 2 and 6 0, 1, 0, 1, 0, 0, // from node 3 to nodes 2 and 4 0, 1, 0, 1, 0, 1 // from node 5 to nodes 2, 4 and 6 - // clang-format on - ); - } + // clang-format on + ); +} - BOOST_AUTO_TEST_CASE(skip_degree_two_nodes) - { - std::unordered_set barrier_nodes{1}; - std::unordered_set traffic_lights{2}; - std::vector annotations(1); - std::vector restrictions; - std::vector conditional_restrictions; - CompressedEdgeContainer container; - test::MockScriptingEnvironment scripting_environment; - - TurnLanesIndexedArray turn_lanes_data; - - // Graph - // - // 0↔1→2↔3↔4→5 7 - // ↑ ↕ ↕ - // 6 8 ↔ 9 - // - const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed) { - return InputEdge{ - from, to, 1, 1, GeometryID{0, false}, !allowed, NodeBasedEdgeClassification{}, 0}; - }; - std::vector edges = {unit_edge(0, 1, true), // 0 - unit_edge(1, 0, true), - unit_edge(1, 2, true), - unit_edge(2, 1, false), - unit_edge(2, 3, true), - unit_edge(3, 2, true), // 5 - unit_edge(3, 4, true), - unit_edge(4, 3, true), - unit_edge(4, 5, true), - unit_edge(4, 6, false), - unit_edge(5, 4, false), // 10 - unit_edge(6, 4, true), - // Circle - unit_edge(7, 8, true), // 12 - unit_edge(7, 9, true), - unit_edge(8, 7, true), - unit_edge(8, 9, true), - unit_edge(9, 7, true), - unit_edge(9, 8, true)}; - - Graph graph(10, edges); - - GraphCompressor().Compress(barrier_nodes, - traffic_lights, - scripting_environment, - restrictions, - conditional_restrictions, - graph, - annotations, - container); - - BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {0, 0}).edge), 4); - BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {4, 7}).edge), 0); - BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {5, 10}).edge), 4); - BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {6, 11}).edge), 4); - BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {7, 12}).edge), 7); - } - - BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_CASE(skip_degree_two_nodes) +{ + std::unordered_set barrier_nodes{1}; + std::unordered_set traffic_lights{2}; + std::vector annotations(1); + std::vector restrictions; + std::vector conditional_restrictions; + CompressedEdgeContainer container; + test::MockScriptingEnvironment scripting_environment; + + TurnLanesIndexedArray turn_lanes_data; + + // Graph + // + // 0↔1→2↔3↔4→5 7 + // ↑ ↕ ↕ + // 6 8 ↔ 9 + // + const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed) { + return InputEdge{ + from, to, 1, 1, GeometryID{0, false}, !allowed, NodeBasedEdgeClassification{}, 0}; + }; + std::vector edges = {unit_edge(0, 1, true), // 0 + unit_edge(1, 0, true), + unit_edge(1, 2, true), + unit_edge(2, 1, false), + unit_edge(2, 3, true), + unit_edge(3, 2, true), // 5 + unit_edge(3, 4, true), + unit_edge(4, 3, true), + unit_edge(4, 5, true), + unit_edge(4, 6, false), + unit_edge(5, 4, false), // 10 + unit_edge(6, 4, true), + // Circle + unit_edge(7, 8, true), // 12 + unit_edge(7, 9, true), + unit_edge(8, 7, true), + unit_edge(8, 9, true), + unit_edge(9, 7, true), + unit_edge(9, 8, true)}; + + Graph graph(10, edges); + + GraphCompressor().Compress(barrier_nodes, + traffic_lights, + scripting_environment, + restrictions, + conditional_restrictions, + graph, + annotations, + container); + + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {0, 0}).edge), 4); + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {4, 7}).edge), 0); + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {5, 10}).edge), 4); + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {6, 11}).edge), 4); + BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {7, 12}).edge), 7); +} + +BOOST_AUTO_TEST_SUITE_END() From 106874d9b02a4d153a391f6e428997af42a1816d Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Mon, 22 Jan 2018 16:01:47 -0500 Subject: [PATCH 30/37] fix mismatch of arguments --- unit_tests/extractor/intersection_analysis_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unit_tests/extractor/intersection_analysis_tests.cpp b/unit_tests/extractor/intersection_analysis_tests.cpp index 1692a1cc4e0..0c1a961dacf 100644 --- a/unit_tests/extractor/intersection_analysis_tests.cpp +++ b/unit_tests/extractor/intersection_analysis_tests.cpp @@ -174,7 +174,7 @@ BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity) 1, GeometryID{0, false}, !allowed, - NodeBasedEdgeClassification{true, false, false, roundabout, false, false, false, {}}, + NodeBasedEdgeClassification{true, false, false, roundabout, false, false, false, {}, 0, 0}, 0}; }; std::vector edges = {unit_edge(0, 1, false, false), From 98ca8290bee75bc5fa23835a0de5e8c63201c48a Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Fri, 19 Jan 2018 16:41:55 +0100 Subject: [PATCH 31/37] add changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2665836cf81..b131602a23f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Changes from 5.15.0: - Profile: - FIXED: `highway=service` will now be used for restricted access, `access=private` is still disabled for snapping. + - ADDED #4775: Exposes more information to the turn function, now being able to set turn weights with highway and access information of the turn as well as other roads at the intersection [#4775](https://github.com/Project-OSRM/osrm-backend/issues/4775) # 5.15.0 - Changes from 5.14.3: @@ -701,4 +702,4 @@ - `properties.traffic_signal_penalty` - `properties.use_turn_restrictions` - `properties.u_turn_penalty` - - `properties.allow_u_turn_at_via` + - `properties.allow_u_turn_at_via` \ No newline at end of file From 271915ec404563719f27c479d16e3a49e9663328 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Fri, 19 Jan 2018 16:41:55 +0100 Subject: [PATCH 32/37] add changelog --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b131602a23f..531269a71f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,6 @@ - FIXED #4804: Ignore no_*_on_red turn restrictions - Guidance: - CHANGED #4706: Guidance refactoring step to decouple intersection connectivity analysis and turn instructions generation [#4706](https://github.com/Project-OSRM/osrm-backend/pull/4706) - - CHANGED #3491: Refactor `isThroughStreet`/Intersection options - Profile: - ADDED: `tunnel` as a new class in car profile so that sections of the route with tunnel tags will be marked as such From 12629cd50728acf2113877044fdecfd07d483477 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Tue, 23 Jan 2018 15:06:35 -0500 Subject: [PATCH 33/37] fix changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 531269a71f2..b131602a23f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - FIXED #4804: Ignore no_*_on_red turn restrictions - Guidance: - CHANGED #4706: Guidance refactoring step to decouple intersection connectivity analysis and turn instructions generation [#4706](https://github.com/Project-OSRM/osrm-backend/pull/4706) + - CHANGED #3491: Refactor `isThroughStreet`/Intersection options - Profile: - ADDED: `tunnel` as a new class in car profile so that sections of the route with tunnel tags will be marked as such From dd61ce8c60587d2640fbedb14e6cddda5c77d56a Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Tue, 23 Jan 2018 15:20:00 -0500 Subject: [PATCH 34/37] clang-format --- .../extractor/intersection_analysis_tests.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/unit_tests/extractor/intersection_analysis_tests.cpp b/unit_tests/extractor/intersection_analysis_tests.cpp index 0c1a961dacf..48ec29a42e4 100644 --- a/unit_tests/extractor/intersection_analysis_tests.cpp +++ b/unit_tests/extractor/intersection_analysis_tests.cpp @@ -167,15 +167,15 @@ BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity) // ↙ ↑ ↘ // 4 5 6 const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed, bool roundabout) { - return InputEdge{ - from, - to, - 1, - 1, - GeometryID{0, false}, - !allowed, - NodeBasedEdgeClassification{true, false, false, roundabout, false, false, false, {}, 0, 0}, - 0}; + return InputEdge{from, + to, + 1, + 1, + GeometryID{0, false}, + !allowed, + NodeBasedEdgeClassification{ + true, false, false, roundabout, false, false, false, {}, 0, 0}, + 0}; }; std::vector edges = {unit_edge(0, 1, false, false), unit_edge(0, 2, true, true), From a3de95c9ee57ac055185957259c2f66658c7de35 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Wed, 24 Jan 2018 10:37:24 -0500 Subject: [PATCH 35/37] fix typo and used std::transform instead of loop --- src/extractor/edge_based_graph_factory.cpp | 46 ++++++---------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 216d98db0b8..5c9e3414e86 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -630,7 +630,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( edge_data2.flags.highway_turn_classification, edge_data2.flags.access_turn_classification, ((double)intersection::findEdgeLength(edge_geometries, node_based_edge_to) / - edge_data1.duration) * + edge_data2.duration) * 36, // connected roads road_legs_on_the_right, @@ -808,25 +808,23 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( std::vector road_legs_on_the_right; std::vector road_legs_on_the_left; - auto get_connected_road_info = [&](auto &road_leg_vector, - const auto &connected_edge) { + auto get_connected_road_info = [&](const auto &connected_edge) { const auto &edge_data = - m_node_based_graph.GetEdgeData(connected_edge->eid); - road_leg_vector.emplace_back( - edge_data.flags.restricted, + m_node_based_graph.GetEdgeData(connected_edge.eid); + return ExtractionTurnLeg(edge_data.flags.restricted, edge_data.flags.road_classification.IsMotorwayClass(), edge_data.flags.road_classification.IsLinkClass(), edge_data.flags.road_classification.GetNumberOfLanes(), edge_data.flags.highway_turn_classification, edge_data.flags.access_turn_classification, ((double)intersection::findEdgeLength(edge_geometries, - connected_edge->eid) / + connected_edge.eid) / edge_data.duration) * 36, - !connected_edge->entry_allowed || + !connected_edge.entry_allowed || (edge_data.flags.forward && edge_data.flags.backward), // is incoming - connected_edge->entry_allowed); + connected_edge.entry_allowed); }; // all connected roads on the right of a u turn @@ -834,35 +832,15 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( { if (turn != intersection.begin()) { - for (auto connected_edge = intersection.begin() + 1; - connected_edge < turn; - connected_edge++) - { - get_connected_road_info(road_legs_on_the_right, - connected_edge); - } - } - for (auto connected_edge = turn + 1; - connected_edge < intersection.end(); - connected_edge++) - { - get_connected_road_info(road_legs_on_the_right, connected_edge); + std::transform(intersection.begin() + 1, turn, std::back_inserter(road_legs_on_the_right), get_connected_road_info); } + + std::transform(turn + 1, intersection.end(), std::back_inserter(road_legs_on_the_right), get_connected_road_info); } else { - for (auto connected_edge = intersection.begin() + 1; - connected_edge < turn; - connected_edge++) - { - get_connected_road_info(road_legs_on_the_right, connected_edge); - } - for (auto connected_edge = turn + 1; - connected_edge < intersection.end(); - connected_edge++) - { - get_connected_road_info(road_legs_on_the_left, connected_edge); - } + std::transform(intersection.begin() + 1, turn, std::back_inserter(road_legs_on_the_right), get_connected_road_info); + std::transform(turn + 1, intersection.end(), std::back_inserter(road_legs_on_the_left), get_connected_road_info); } if (turn->instruction.IsUTurn() && turn != intersection.begin()) From 9eb80ca3fb30b1e90002d00a697d927a29d76a00 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Wed, 24 Jan 2018 10:59:25 -0500 Subject: [PATCH 36/37] split OSM link generation in an accessible coordinate function --- include/util/assert.hpp | 4 +-- include/util/coordinate.hpp | 17 +++++++++++++ src/extractor/edge_based_graph_factory.cpp | 29 ++++++++++++++++------ 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/include/util/assert.hpp b/include/util/assert.hpp index d4cd00c22b4..ac4b80797d5 100644 --- a/include/util/assert.hpp +++ b/include/util/assert.hpp @@ -20,9 +20,7 @@ if (!static_cast(cond)) \ { \ ::osrm::util::FloatCoordinate c_(loc); \ - std::cerr << "[Location] " \ - << "http://www.openstreetmap.org/?mlat=" << c_.lat << "&mlon=" << c_.lon \ - << "#map=19/" << c_.lat << "/" << c_.lon << '\n'; \ + std::cerr << "[Location] " << c_.toOSMLink() << '\n'; \ } \ BOOST_ASSERT_MSG(cond, msg); \ } while (0) diff --git a/include/util/coordinate.hpp b/include/util/coordinate.hpp index 3ff309ba90d..525727f6313 100644 --- a/include/util/coordinate.hpp +++ b/include/util/coordinate.hpp @@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include //for std::ostream +#include #include #include @@ -216,6 +217,14 @@ struct Coordinate friend bool operator==(const Coordinate lhs, const Coordinate rhs); friend bool operator!=(const Coordinate lhs, const Coordinate rhs); friend std::ostream &operator<<(std::ostream &out, const Coordinate coordinate); + + std::string toOSMLink() const + { + std::stringstream link; + link << "http://www.openstreetmap.org/?mlat=" << lat << "&mlon=" << lon << "#map=19/" << lat + << "/" << lon; + return link.str(); + } }; /** @@ -257,6 +266,14 @@ struct FloatCoordinate friend bool operator==(const FloatCoordinate lhs, const FloatCoordinate rhs); friend bool operator!=(const FloatCoordinate lhs, const FloatCoordinate rhs); friend std::ostream &operator<<(std::ostream &out, const FloatCoordinate coordinate); + + std::string toOSMLink() const + { + std::stringstream link; + link << "http://www.openstreetmap.org/?mlat=" << lat << "&mlon=" << lon << "#map=19/" << lat + << "/" << lon; + return link.str(); + } }; bool operator==(const Coordinate lhs, const Coordinate rhs); diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 5c9e3414e86..f983209efce 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -811,7 +811,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( auto get_connected_road_info = [&](const auto &connected_edge) { const auto &edge_data = m_node_based_graph.GetEdgeData(connected_edge.eid); - return ExtractionTurnLeg(edge_data.flags.restricted, + return ExtractionTurnLeg( + edge_data.flags.restricted, edge_data.flags.road_classification.IsMotorwayClass(), edge_data.flags.road_classification.IsLinkClass(), edge_data.flags.road_classification.GetNumberOfLanes(), @@ -832,24 +833,36 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( { if (turn != intersection.begin()) { - std::transform(intersection.begin() + 1, turn, std::back_inserter(road_legs_on_the_right), get_connected_road_info); + std::transform(intersection.begin() + 1, + turn, + std::back_inserter(road_legs_on_the_right), + get_connected_road_info); } - std::transform(turn + 1, intersection.end(), std::back_inserter(road_legs_on_the_right), get_connected_road_info); + std::transform(turn + 1, + intersection.end(), + std::back_inserter(road_legs_on_the_right), + get_connected_road_info); } else { - std::transform(intersection.begin() + 1, turn, std::back_inserter(road_legs_on_the_right), get_connected_road_info); - std::transform(turn + 1, intersection.end(), std::back_inserter(road_legs_on_the_left), get_connected_road_info); + std::transform(intersection.begin() + 1, + turn, + std::back_inserter(road_legs_on_the_right), + get_connected_road_info); + std::transform(turn + 1, + intersection.end(), + std::back_inserter(road_legs_on_the_left), + get_connected_road_info); } if (turn->instruction.IsUTurn() && turn != intersection.begin()) { util::Log(logWARNING) << "Turn is a u turn but not turning to the first connected " - "edge of the intersection. Node ID " - << intersection_node << " coordinates " - << m_coordinates[intersection_node]; + "edge of the intersection. Node ID: " + << intersection_node << ", OSM link: " + << m_coordinates[intersection_node].toOSMLink(); } // In case a way restriction starts at a given location, add a turn onto From 5550f760b0a516ffb6db01866e61fc6810f75281 Mon Sep 17 00:00:00 2001 From: Huyen Chau Nguyen Date: Wed, 24 Jan 2018 12:27:28 -0500 Subject: [PATCH 37/37] guard transform when begin iterator is bigger than end iterator --- include/util/coordinate.hpp | 5 +++-- src/extractor/edge_based_graph_factory.cpp | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/include/util/coordinate.hpp b/include/util/coordinate.hpp index 525727f6313..21ba703f81c 100644 --- a/include/util/coordinate.hpp +++ b/include/util/coordinate.hpp @@ -221,8 +221,9 @@ struct Coordinate std::string toOSMLink() const { std::stringstream link; - link << "http://www.openstreetmap.org/?mlat=" << lat << "&mlon=" << lon << "#map=19/" << lat - << "/" << lon; + link << "http://www.openstreetmap.org/?mlat=" << toFloating(lat) + << "&mlon=" << toFloating(lon) << "#map=19/" << toFloating(lat) << "/" + << toFloating(lon); return link.str(); } }; diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index f983209efce..62682654b99 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -846,10 +846,13 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( } else { - std::transform(intersection.begin() + 1, - turn, - std::back_inserter(road_legs_on_the_right), - get_connected_road_info); + if (intersection.begin() != turn) + { + std::transform(intersection.begin() + 1, + turn, + std::back_inserter(road_legs_on_the_right), + get_connected_road_info); + } std::transform(turn + 1, intersection.end(), std::back_inserter(road_legs_on_the_left), @@ -864,6 +867,13 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( << intersection_node << ", OSM link: " << m_coordinates[intersection_node].toOSMLink(); } + else if (turn == intersection.begin() && !turn->instruction.IsUTurn()) + { + util::Log(logWARNING) + << "Turn is a u turn but not classified as a u turn. Node ID: " + << intersection_node << ", OSM link: " + << m_coordinates[intersection_node].toOSMLink(); + } // In case a way restriction starts at a given location, add a turn onto // every artificial node eminating here.