diff --git a/features/options/extract/turn_function.feature b/features/options/extract/turn_function.feature index 897c1187cdf..66af011d125 100644 --- a/features/options/extract/turn_function.feature +++ b/features/options/extract/turn_function.feature @@ -43,6 +43,7 @@ Feature: Turn Function Information end function print_turn (profile, turn) + print ('is_stop ' .. string.format("%s", tostring(turn.is_stop))) 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))) @@ -173,4 +174,67 @@ Feature: Turn Function Information + Scenario: Turns should show if intersection node is tagged with highway=stop stop=all + Given the node map + """ + a->b->c + """ + And the ways + | nodes | oneway | + | ab | yes | + | bc | yes | + And the nodes + | node | highway | stop | + | b | stop | all | + + 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 "is_stop true" + + + Scenario: Turns should not claim there is stop if there is not + Given the node map + """ + a-b-c + """ + And the ways + | nodes | oneway | + | ab | yes | + | bc | yes | + And the nodes + | node | highway | + | b | - | + + 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 "is_stop false" + + + Scenario: Turn should show correct stops if intersection node is tagged with highway=stop stop=minor + Given the node map + """ + d + | + v + a->b->c + """ + And the ways + | nodes | oneway | highway | + | ab | yes | primary | + | bc | yes | primary | + | db | yes | tertiary | + And the nodes + | node | highway | stop | + | b | stop | minor | + + 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 "is_stop true" + And stdout should contain "is_stop false" diff --git a/features/support/hooks.js b/features/support/hooks.js index e58b34bfa22..ee4c4c573f9 100644 --- a/features/support/hooks.js +++ b/features/support/hooks.js @@ -51,7 +51,7 @@ module.exports = function () { .defer(rimraf, this.scenarioLogFile) .awaitAll(callback); // uncomment to get path to logfile - // console.log(" Writing logging output to " + this.scenarioLogFile) + console.log(" Writing logging output to " + this.scenarioLogFile) }); this.After((scenario, callback) => { diff --git a/include/extractor/edge_based_graph_factory.hpp b/include/extractor/edge_based_graph_factory.hpp index 37c0e39c491..48061f08b43 100644 --- a/include/extractor/edge_based_graph_factory.hpp +++ b/include/extractor/edge_based_graph_factory.hpp @@ -73,6 +73,8 @@ class EdgeBasedGraphFactory const CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, const std::unordered_set &traffic_lights, + const std::unordered_set &all_way_stops, + const std::unordered_set &minor_stops, const std::vector &coordinates, const util::NameTable &name_table, const std::unordered_set &segregated_edges, @@ -155,6 +157,8 @@ class EdgeBasedGraphFactory const std::unordered_set &m_barrier_nodes; const std::unordered_set &m_traffic_lights; + const std::unordered_set &m_all_way_stops; + const std::unordered_set &m_minor_stops; const CompressedEdgeContainer &m_compressed_edge_container; const util::NameTable &name_table; diff --git a/include/extractor/extraction_containers.hpp b/include/extractor/extraction_containers.hpp index 55c6bd49803..268da24b3bc 100644 --- a/include/extractor/extraction_containers.hpp +++ b/include/extractor/extraction_containers.hpp @@ -42,6 +42,8 @@ class ExtractionContainers std::vector barrier_nodes; std::vector traffic_signals; + std::vector all_way_stops; + std::vector minor_stops; NodeIDVector used_node_id_list; NodeVector all_nodes_list; EdgeVector all_edges_list; diff --git a/include/extractor/extraction_node.hpp b/include/extractor/extraction_node.hpp index e82f298ba54..ab58986d3a1 100644 --- a/include/extractor/extraction_node.hpp +++ b/include/extractor/extraction_node.hpp @@ -8,10 +8,16 @@ namespace extractor struct ExtractionNode { - ExtractionNode() : traffic_lights(false), barrier(false) {} - void clear() { traffic_lights = barrier = false; } + ExtractionNode() + : traffic_lights(false), barrier(false), is_all_way_stop(false), is_minor_stop(false) + { + } + void clear() { traffic_lights = barrier = is_all_way_stop = is_minor_stop = false; } bool traffic_lights; bool barrier; + + bool is_all_way_stop; + bool is_minor_stop; }; } } diff --git a/include/extractor/extraction_turn.hpp b/include/extractor/extraction_turn.hpp index 24624f489a6..0ef36ef2573 100644 --- a/include/extractor/extraction_turn.hpp +++ b/include/extractor/extraction_turn.hpp @@ -49,11 +49,11 @@ struct ExtractionTurn bool is_u_turn, bool has_traffic_light, bool is_left_hand_driving, + bool is_stop, 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, @@ -70,6 +70,7 @@ struct ExtractionTurn 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), + is_stop(is_stop), source_restricted(source_restricted), source_mode(source_mode), source_is_motorway(source_is_motorway), source_is_link(source_is_link), @@ -95,6 +96,7 @@ struct ExtractionTurn const bool is_u_turn; const bool has_traffic_light; const bool is_left_hand_driving; + const bool is_stop; // source info const bool source_restricted; diff --git a/include/extractor/extractor.hpp b/include/extractor/extractor.hpp index 9dcd93916ae..17072ec35ce 100644 --- a/include/extractor/extractor.hpp +++ b/include/extractor/extractor.hpp @@ -69,6 +69,8 @@ class Extractor const CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, const std::unordered_set &traffic_lights, + const std::unordered_set &all_way_stops, + const std::unordered_set &minor_stops, const std::vector &turn_restrictions, const std::vector &conditional_turn_restrictions, const std::unordered_set &segregated_edges, diff --git a/include/extractor/node_based_graph_factory.hpp b/include/extractor/node_based_graph_factory.hpp index 07facfdbe36..dd981be825f 100644 --- a/include/extractor/node_based_graph_factory.hpp +++ b/include/extractor/node_based_graph_factory.hpp @@ -44,6 +44,8 @@ class NodeBasedGraphFactory auto const &GetGraph() const { return compressed_output_graph; } auto const &GetBarriers() const { return barriers; } auto const &GetTrafficSignals() const { return traffic_signals; } + auto const &GetAllWayStops() const { return all_way_stops; } + auto const &GetMinorStops() const { return minor_stops; } auto const &GetCompressedEdges() const { return compressed_edge_container; } auto const &GetCoordinates() const { return coordinates; } auto const &GetAnnotationData() const { return annotation_data; } @@ -89,6 +91,8 @@ class NodeBasedGraphFactory // General Information about the graph, not used outside of extractor std::unordered_set barriers; std::unordered_set traffic_signals; + std::unordered_set all_way_stops; + std::unordered_set minor_stops; std::vector coordinates; diff --git a/include/util/graph_loader.hpp b/include/util/graph_loader.hpp index 2eca54a9e12..17b0ff93d75 100644 --- a/include/util/graph_loader.hpp +++ b/include/util/graph_loader.hpp @@ -36,10 +36,12 @@ namespace util * - traffic lights * - nodes indexed by their internal (non-osm) id */ -template +template NodeID loadNodesFromFile(storage::io::FileReader &file_reader, BarrierOutIter barriers, TrafficSignalsOutIter traffic_signals, + AllWayStopsOutIter all_way_stops, + MinorStopsOutIter minor_stops, std::vector &coordinates, extractor::PackedOSMIDs &osm_node_ids) { @@ -71,6 +73,18 @@ NodeID loadNodesFromFile(storage::io::FileReader &file_reader, *traffic_signals++ = file_reader.ReadOne(); } + auto num_all_way_stops = file_reader.ReadElementCount64(); + for (auto index = 0UL; index < num_all_way_stops; ++index) + { + *all_way_stops++ = file_reader.ReadOne(); + } + + auto num_minor_stops = file_reader.ReadElementCount64(); + for (auto index = 0UL; index < num_minor_stops; ++index) + { + *minor_stops++ = file_reader.ReadOne(); + } + return number_of_nodes; } diff --git a/profiles/car.lua b/profiles/car.lua index 38cd794c53f..37dfea3a59a 100644 --- a/profiles/car.lua +++ b/profiles/car.lua @@ -335,6 +335,26 @@ function process_node(profile, node, result, relations) if "traffic_signals" == tag then result.traffic_lights = true end + + print('bla') + + -- @CHAUTODO sure this should be here? This shouldn't be here + local stop = node:get_value_by_key("stop") + if tag == "stop" then + if stop == "all" then + result.is_all_way_stop = true + print('tag ' .. tag) + print('stop ' .. stop) + print('set all way stop') + else + if stop == "minor" then + result.is_minor_stop = true + print('tag ' .. tag) + print('stop ' .. stop) + print('set minor stop') + end + end + end end function process_way(profile, way, result, relations) diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 62682654b99..9617fbf6871 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -67,13 +67,15 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory( const CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, const std::unordered_set &traffic_lights, + const std::unordered_set &all_way_stops, + const std::unordered_set &minor_stops, const std::vector &coordinates, const util::NameTable &name_table, const std::unordered_set &segregated_edges, guidance::LaneDescriptionMap &lane_description_map) : m_edge_based_node_container(node_data_container), m_number_of_edge_based_nodes(0), m_coordinates(coordinates), m_node_based_graph(std::move(node_based_graph)), - m_barrier_nodes(barrier_nodes), m_traffic_lights(traffic_lights), + m_barrier_nodes(barrier_nodes), m_traffic_lights(traffic_lights), m_all_way_stops(all_way_stops), m_minor_stops(minor_stops), m_compressed_edge_container(compressed_edge_container), name_table(name_table), segregated_edges(segregated_edges), lane_description_map(lane_description_map) { @@ -564,7 +566,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const auto &road_legs_on_the_right, const auto &road_legs_on_the_left, const auto entry_class_id, - const auto &edge_geometries) { + const auto &edge_geometries, + const auto is_minor) { const auto node_restricted = isRestricted(node_along_road_entering, intersection_node, @@ -601,6 +604,11 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // compute weight and duration penalties auto is_traffic_light = m_traffic_lights.count(intersection_node); + //@CHAUTODO + bool is_stop = m_all_way_stops.count(intersection_node) > 0 || (m_minor_stops.count(intersection_node) > 0 && is_minor); + std::cout << "Creating turn at " << intersection_node << " " << m_all_way_stops.count(intersection_node) << std::endl; + + ExtractionTurn extracted_turn( // general info turn.angle, @@ -610,6 +618,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( is_traffic_light, m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data) .is_left_hand_driving, + is_stop, // source info edge_data1.flags.restricted, m_edge_based_node_container.GetAnnotation(edge_data1.annotation_data).travel_mode, @@ -875,6 +884,14 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( << m_coordinates[intersection_node].toOSMLink(); } + + + guidance::RoadPriorityClass::Enum from_priority = m_node_based_graph.GetEdgeData(incoming_edge.edge).flags.road_classification.GetPriority(); + bool is_minor = std::any_of( + intersection.begin(), intersection.end(), [&](auto connected_road) { + return m_node_based_graph.GetEdgeData(connected_road.eid).flags.road_classification.GetPriority() < from_priority; + }); + // In case a way restriction starts at a given location, add a turn onto // every artificial node eminating here. // @@ -914,7 +931,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( road_legs_on_the_right, road_legs_on_the_left, entry_class_id, - edge_geometries); + edge_geometries, + is_minor); buffer->continuous_data.edges_list.push_back( edge_with_data_and_condition.first.edge); @@ -979,7 +997,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( road_legs_on_the_right, road_legs_on_the_left, entry_class_id, - edge_geometries); + edge_geometries, + is_minor); buffer->delayed_data.push_back( std::move(edge_with_data_and_condition.first)); @@ -1016,7 +1035,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( road_legs_on_the_right, road_legs_on_the_left, entry_class_id, - edge_geometries); + edge_geometries, + is_minor); buffer->delayed_data.push_back( std::move(edge_with_data_and_condition.first)); diff --git a/src/extractor/extraction_containers.cpp b/src/extractor/extraction_containers.cpp index 86e440fa067..ec95fefc257 100644 --- a/src/extractor/extraction_containers.cpp +++ b/src/extractor/extraction_containers.cpp @@ -648,6 +648,42 @@ void ExtractionContainers::WriteNodes(storage::io::FileWriter &file_out) const log << "ok, after " << TIMER_SEC(write_nodes) << "s"; } + { + util::UnbufferedLog log; + log << "Writing all way stop nodes ... "; + TIMER_START(write_nodes); + std::vector internal_all_way_stops; + for (const auto osm_id : all_way_stops) + { + const auto node_id = mapExternalToInternalNodeID( + used_node_id_list.begin(), used_node_id_list.end(), osm_id); + if (node_id != SPECIAL_NODEID) + { + internal_all_way_stops.push_back(node_id); + } + } + storage::serialization::write(file_out, internal_all_way_stops); + log << "ok, after " << TIMER_SEC(write_nodes) << "s"; + } + + { + util::UnbufferedLog log; + log << "Writing minor stop nodes ... "; + TIMER_START(write_nodes); + std::vector internal_minor_stops; + for (const auto osm_id : minor_stops) + { + const auto node_id = mapExternalToInternalNodeID( + used_node_id_list.begin(), used_node_id_list.end(), osm_id); + if (node_id != SPECIAL_NODEID) + { + internal_minor_stops.push_back(node_id); + } + } + storage::serialization::write(file_out, internal_minor_stops); + log << "ok, after " << TIMER_SEC(write_nodes) << "s"; + } + util::Log() << "Processed " << max_internal_node_id << " nodes"; } diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp index 2abfe84431d..3646f99d704 100644 --- a/src/extractor/extractor.cpp +++ b/src/extractor/extractor.cpp @@ -263,6 +263,8 @@ int Extractor::run(ScriptingEnvironment &scripting_environment) const auto &barrier_nodes = node_based_graph_factory.GetBarriers(); const auto &traffic_signals = node_based_graph_factory.GetTrafficSignals(); + const auto &all_way_stops = node_based_graph_factory.GetAllWayStops(); + const auto &minor_stops = node_based_graph_factory.GetMinorStops(); // stealing the annotation data from the node-based graph edge_based_nodes_container = EdgeBasedNodeDataContainer({}, std::move(node_based_graph_factory.GetAnnotationData())); @@ -278,6 +280,8 @@ int Extractor::run(ScriptingEnvironment &scripting_environment) node_based_graph_factory.GetCompressedEdges(), barrier_nodes, traffic_signals, + all_way_stops, + minor_stops, turn_restrictions, conditional_turn_restrictions, segregated_edges, @@ -667,6 +671,8 @@ EdgeID Extractor::BuildEdgeExpandedGraph( const CompressedEdgeContainer &compressed_edge_container, const std::unordered_set &barrier_nodes, const std::unordered_set &traffic_signals, + const std::unordered_set &all_way_stops, + const std::unordered_set &minor_stops, const std::vector &turn_restrictions, const std::vector &conditional_turn_restrictions, const std::unordered_set &segregated_edges, @@ -689,6 +695,8 @@ EdgeID Extractor::BuildEdgeExpandedGraph( compressed_edge_container, barrier_nodes, traffic_signals, + all_way_stops, + minor_stops, coordinates, name_table, segregated_edges, diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index da08048e374..918596b88b8 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -71,6 +71,15 @@ void ExtractorCallbacks::ProcessNode(const osmium::Node &input_node, { external_memory.traffic_signals.push_back(id); } + std::cout << "STOPS " << id << " " << result_node.is_all_way_stop << " " << result_node.is_minor_stop << std::endl; + if (result_node.is_all_way_stop) + { + external_memory.all_way_stops.push_back(id); + } + if (result_node.is_minor_stop) + { + external_memory.minor_stops.push_back(id); + } } void ExtractorCallbacks::ProcessRestriction(const InputConditionalTurnRestriction &restriction) diff --git a/src/extractor/graph_compressor.cpp b/src/extractor/graph_compressor.cpp index 3b147b51592..603e93b8770 100644 --- a/src/extractor/graph_compressor.cpp +++ b/src/extractor/graph_compressor.cpp @@ -228,6 +228,7 @@ void GraphCompressor::Compress( true, false, false, + false, TRAVEL_MODE_DRIVING, false, false, diff --git a/src/extractor/node_based_graph_factory.cpp b/src/extractor/node_based_graph_factory.cpp index 8fc7b9d24ec..f0a69a714ff 100644 --- a/src/extractor/node_based_graph_factory.cpp +++ b/src/extractor/node_based_graph_factory.cpp @@ -37,9 +37,11 @@ void NodeBasedGraphFactory::LoadDataFromFile(const boost::filesystem::path &inpu auto barriers_iter = inserter(barriers, end(barriers)); auto traffic_signals_iter = inserter(traffic_signals, end(traffic_signals)); + auto all_way_stops_iter = inserter(all_way_stops, end(all_way_stops)); + auto minor_stops_iter = inserter(minor_stops, end(minor_stops)); const auto number_of_node_based_nodes = util::loadNodesFromFile( - file_reader, barriers_iter, traffic_signals_iter, coordinates, osm_node_ids); + file_reader, barriers_iter, traffic_signals_iter, all_way_stops_iter, minor_stops_iter, coordinates, osm_node_ids); std::vector edge_list; util::loadEdgesFromFile(file_reader, edge_list); diff --git a/src/extractor/scripting_environment_lua.cpp b/src/extractor/scripting_environment_lua.cpp index e446d587c6e..c210862b313 100644 --- a/src/extractor/scripting_environment_lua.cpp +++ b/src/extractor/scripting_environment_lua.cpp @@ -261,7 +261,11 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) "traffic_lights", &ExtractionNode::traffic_lights, "barrier", - &ExtractionNode::barrier); + &ExtractionNode::barrier, + "is_all_way_stop", + &ExtractionNode::is_all_way_stop, + "is_minor_stop", + &ExtractionNode::is_minor_stop); context.state.new_usertype( "RoadClassification", @@ -709,6 +713,8 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) &ExtractionTurn::has_traffic_light, "is_left_hand_driving", &ExtractionTurn::is_left_hand_driving, + "is_stop", + &ExtractionTurn::is_stop, "source_restricted", &ExtractionTurn::source_restricted, diff --git a/src/tools/components.cpp b/src/tools/components.cpp index 5a7c2ca6232..05b00923b36 100644 --- a/src/tools/components.cpp +++ b/src/tools/components.cpp @@ -43,7 +43,7 @@ std::size_t loadGraph(const std::string &path, auto nop = boost::make_function_output_iterator([](auto) {}); const auto number_of_nodes = - util::loadNodesFromFile(file_reader, nop, nop, coordinate_list, osm_node_ids); + util::loadNodesFromFile(file_reader, nop, nop, nop, nop, coordinate_list, osm_node_ids); util::loadEdgesFromFile(file_reader, edge_list);