From b08b360f38446cb60cdf6939f4844add57f6abd7 Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Tue, 1 Mar 2016 22:30:31 +0100 Subject: [PATCH] Big Restructuring / Cleanup --- CMakeLists.txt | 8 +- include/engine/api/json_factory.hpp | 6 +- include/engine/api/match_api.hpp | 3 +- include/engine/api/route_api.hpp | 1 + include/engine/api/trip_api.hpp | 2 +- include/engine/datafacade/datafacade_base.hpp | 4 +- .../engine/datafacade/internal_datafacade.hpp | 6 +- .../engine/datafacade/shared_datafacade.hpp | 10 +- include/engine/guidance/assemble_geometry.hpp | 4 +- include/engine/guidance/assemble_steps.hpp | 41 ++-- include/engine/guidance/post_processing.hpp | 2 +- include/engine/guidance/step_maneuver.hpp | 4 +- include/engine/guidance/toolkit.hpp | 62 ++++++ include/engine/internal_route_result.hpp | 4 +- include/engine/plugins/plugin_base.hpp | 4 +- .../routing_algorithms/routing_base.hpp | 12 +- .../extractor/edge_based_graph_factory.hpp | 20 +- include/extractor/extraction_way.hpp | 3 - .../guidance/classification_data.hpp | 44 ++--- include/extractor/guidance/discrete_angle.hpp | 16 ++ .../guidance/toolkit.hpp} | 179 +++++------------- .../{ => guidance}/turn_analysis.hpp | 75 +++++--- .../guidance/turn_classification.hpp | 27 ++- .../guidance/turn_instruction.hpp | 61 +----- include/extractor/internal_extractor_edge.hpp | 10 +- include/extractor/node_based_edge.hpp | 13 +- include/extractor/original_edge_data.hpp | 8 +- include/util/coordinate_calculation.hpp | 4 +- include/util/node_based_graph.hpp | 12 +- src/contractor/contractor.cpp | 2 +- src/engine/api/json_factory.cpp | 40 +++- src/engine/guidance/classification_data.cpp | 23 --- src/engine/guidance/post_processing.cpp | 16 +- src/engine/plugins/trip.cpp | 12 +- src/extractor/edge_based_graph_factory.cpp | 74 +------- src/extractor/extractor.cpp | 1 - src/extractor/extractor_callbacks.cpp | 14 +- .../{ => guidance}/turn_analysis.cpp | 86 ++++----- src/storage/storage.cpp | 8 +- src/util/coordinate_calculation.cpp | 9 +- 40 files changed, 419 insertions(+), 511 deletions(-) create mode 100644 include/engine/guidance/toolkit.hpp rename include/{engine => extractor}/guidance/classification_data.hpp (73%) create mode 100644 include/extractor/guidance/discrete_angle.hpp rename include/{engine/guidance/guidance_toolkit.hpp => extractor/guidance/toolkit.hpp} (65%) rename include/extractor/{ => guidance}/turn_analysis.hpp (79%) rename include/{engine => extractor}/guidance/turn_classification.hpp (81%) rename include/{engine => extractor}/guidance/turn_instruction.hpp (60%) delete mode 100644 src/engine/guidance/classification_data.cpp rename src/extractor/{ => guidance}/turn_analysis.cpp (96%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c4ad407a..fbb717f3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,12 +55,11 @@ configure_file( ${CMAKE_CURRENT_BINARY_DIR}/include/util/version.hpp ) file(GLOB UtilGlob src/util/*.cpp) -file(GLOB ExtractorGlob src/extractor/*.cpp src/engine/guidance/classification_data.cpp) +file(GLOB ExtractorGlob src/extractor/*.cpp src/extractor/*/*.cpp) file(GLOB ContractorGlob src/contractor/*.cpp) file(GLOB StorageGlob src/storage/*.cpp) file(GLOB ServerGlob src/server/*.cpp src/server/**/*.cpp) file(GLOB EngineGlob src/engine/*.cpp src/engine/**/*.cpp) -file(GLOB GuidanceGlob src/guidance/*.cpp src/guidance/**/*.cpp) file(GLOB ExtractorTestsGlob unit_tests/extractor/*.cpp) file(GLOB EngineTestsGlob unit_tests/engine/*.cpp) file(GLOB UtilTestsGlob unit_tests/util/*.cpp) @@ -72,7 +71,6 @@ add_library(EXTRACTOR OBJECT ${ExtractorGlob}) add_library(CONTRACTOR OBJECT ${ContractorGlob}) add_library(STORAGE OBJECT ${StorageGlob}) add_library(ENGINE OBJECT ${EngineGlob}) -add_library(GUIDANCE OBJECT ${GuidanceGlob}) add_library(SERVER OBJECT ${ServerGlob}) add_dependencies(UTIL FingerPrintConfigure) @@ -82,8 +80,8 @@ add_executable(osrm-extract src/tools/extract.cpp) add_executable(osrm-contract src/tools/contract.cpp) add_executable(osrm-routed src/tools/routed.cpp $ $) add_executable(osrm-datastore src/tools/store.cpp $) -add_library(osrm src/osrm/osrm.cpp $ $ $) -add_library(osrm_extract $ $ $) +add_library(osrm src/osrm/osrm.cpp $ $) +add_library(osrm_extract $ $) add_library(osrm_contract $ $) add_library(osrm_store $ $) diff --git a/include/engine/api/json_factory.hpp b/include/engine/api/json_factory.hpp index e2801c7c6..49e81f22b 100644 --- a/include/engine/api/json_factory.hpp +++ b/include/engine/api/json_factory.hpp @@ -1,7 +1,7 @@ #ifndef ENGINE_RESPONSE_OBJECTS_HPP_ #define ENGINE_RESPONSE_OBJECTS_HPP_ -#include "engine/guidance/turn_instruction.hpp" +#include "extractor/guidance/turn_instruction.hpp" #include "extractor/travel_mode.hpp" #include "engine/polyline_compressor.hpp" #include "engine/guidance/route_step.hpp" @@ -32,8 +32,8 @@ namespace json namespace detail { -std::string instructionTypeToString(guidance::TurnType type); -std::string instructionModifierToString(guidance::DirectionModifier modifier); +std::string instructionTypeToString(extractor::guidance::TurnType type); +std::string instructionModifierToString(extractor::guidance::DirectionModifier modifier); util::json::Array coordinateToLonLat(const util::Coordinate coordinate); diff --git a/include/engine/api/match_api.hpp b/include/engine/api/match_api.hpp index 860a945c4..9d2edbd7f 100644 --- a/include/engine/api/match_api.hpp +++ b/include/engine/api/match_api.hpp @@ -39,8 +39,7 @@ class MatchAPI final : public RouteAPI auto route = MakeRoute(sub_routes[index].segment_end_coordinates, sub_routes[index].unpacked_path_segments, sub_routes[index].source_traversed_in_reverse, - sub_routes[index].target_traversed_in_reverse, - nullptr); + sub_routes[index].target_traversed_in_reverse, nullptr); route.values["confidence"] = sub_matchings[index].confidence; routes.values.push_back(std::move(route)); } diff --git a/include/engine/api/route_api.hpp b/include/engine/api/route_api.hpp index 1b35e02e5..38d136978 100644 --- a/include/engine/api/route_api.hpp +++ b/include/engine/api/route_api.hpp @@ -152,6 +152,7 @@ class RouteAPI : public BaseAPI leg_geometry.locations.begin() + step.geometry_end)); }); } + return json::makeRoute(route, json::makeRouteLegs(std::move(legs), std::move(step_geometries)), std::move(json_overview)); diff --git a/include/engine/api/trip_api.hpp b/include/engine/api/trip_api.hpp index fa1351eb5..d95f15b39 100644 --- a/include/engine/api/trip_api.hpp +++ b/include/engine/api/trip_api.hpp @@ -29,7 +29,7 @@ class TripAPI final : public RouteAPI const std::vector &sub_routes, const std::vector &phantoms, util::json::Object &response, - const std::vector> * const coordinates) const + const std::vector> *const coordinates) const { auto number_of_routes = sub_trips.size(); util::json::Array routes; diff --git a/include/engine/datafacade/datafacade_base.hpp b/include/engine/datafacade/datafacade_base.hpp index 3c736b8ea..7fb17c786 100644 --- a/include/engine/datafacade/datafacade_base.hpp +++ b/include/engine/datafacade/datafacade_base.hpp @@ -7,7 +7,7 @@ #include "extractor/external_memory_node.hpp" #include "contractor/query_edge.hpp" #include "engine/phantom_node.hpp" -#include "engine/guidance/turn_instruction.hpp" +#include "extractor/guidance/turn_instruction.hpp" #include "util/integer_range.hpp" #include "util/exception.hpp" #include "util/string_util.hpp" @@ -76,7 +76,7 @@ class BaseDataFacade virtual void GetUncompressedWeights(const EdgeID id, std::vector &result_weights) const = 0; - virtual guidance::TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const = 0; + virtual extractor::guidance::TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const = 0; virtual extractor::TravelMode GetTravelModeForEdgeID(const unsigned id) const = 0; diff --git a/include/engine/datafacade/internal_datafacade.hpp b/include/engine/datafacade/internal_datafacade.hpp index 1346b9a5b..7d12a5166 100644 --- a/include/engine/datafacade/internal_datafacade.hpp +++ b/include/engine/datafacade/internal_datafacade.hpp @@ -5,6 +5,8 @@ #include "engine/datafacade/datafacade_base.hpp" +#include "extractor/guidance/turn_instruction.hpp" + #include "engine/geospatial_query.hpp" #include "extractor/original_edge_data.hpp" #include "extractor/query_node.hpp" @@ -68,7 +70,7 @@ class InternalDataFacade final : public BaseDataFacade std::shared_ptr::vector> m_coordinate_list; util::ShM::vector m_via_node_list; util::ShM::vector m_name_ID_list; - util::ShM::vector m_turn_instruction_list; + util::ShM::vector m_turn_instruction_list; util::ShM::vector m_travel_mode_list; util::ShM::vector m_names_char_list; util::ShM::vector m_geometry_indices; @@ -327,7 +329,7 @@ class InternalDataFacade final : public BaseDataFacade return m_coordinate_list->at(id); } - guidance::TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const override final + extractor::guidance::TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const override final { return m_turn_instruction_list.at(id); } diff --git a/include/engine/datafacade/shared_datafacade.hpp b/include/engine/datafacade/shared_datafacade.hpp index e7000a6c7..fbf367f42 100644 --- a/include/engine/datafacade/shared_datafacade.hpp +++ b/include/engine/datafacade/shared_datafacade.hpp @@ -7,6 +7,8 @@ #include "storage/shared_datatype.hpp" #include "storage/shared_memory.hpp" +#include "extractor/guidance/turn_instruction.hpp" + #include "engine/geospatial_query.hpp" #include "util/range_table.hpp" #include "util/static_graph.hpp" @@ -70,7 +72,7 @@ class SharedDataFacade final : public BaseDataFacade std::shared_ptr::vector> m_coordinate_list; util::ShM::vector m_via_node_list; util::ShM::vector m_name_ID_list; - util::ShM::vector m_turn_instruction_list; + util::ShM::vector m_turn_instruction_list; util::ShM::vector m_travel_mode_list; util::ShM::vector m_names_char_list; util::ShM::vector m_name_begin_indices; @@ -145,9 +147,9 @@ class SharedDataFacade final : public BaseDataFacade travel_mode_list_ptr, data_layout->num_entries[storage::SharedDataLayout::TRAVEL_MODE]); m_travel_mode_list = std::move(travel_mode_list); - auto turn_instruction_list_ptr = data_layout->GetBlockPtr( + auto turn_instruction_list_ptr = data_layout->GetBlockPtr( shared_memory, storage::SharedDataLayout::TURN_INSTRUCTION); - typename util::ShM::vector turn_instruction_list( + typename util::ShM::vector turn_instruction_list( turn_instruction_list_ptr, data_layout->num_entries[storage::SharedDataLayout::TURN_INSTRUCTION]); m_turn_instruction_list = std::move(turn_instruction_list); @@ -398,7 +400,7 @@ class SharedDataFacade final : public BaseDataFacade return m_via_node_list.at(id); } - guidance::TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const override final + extractor::guidance::TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const override final { return m_turn_instruction_list.at(id); } diff --git a/include/engine/guidance/assemble_geometry.hpp b/include/engine/guidance/assemble_geometry.hpp index bc8d1a77d..27e3bf3c1 100644 --- a/include/engine/guidance/assemble_geometry.hpp +++ b/include/engine/guidance/assemble_geometry.hpp @@ -7,7 +7,7 @@ #include "engine/guidance/leg_geometry.hpp" #include "util/coordinate_calculation.hpp" #include "util/coordinate.hpp" -#include "engine/guidance/turn_instruction.hpp" +#include "extractor/guidance/turn_instruction.hpp" #include "extractor/travel_mode.hpp" #include @@ -49,7 +49,7 @@ LegGeometry assembleGeometry(const DataFacadeT &facade, current_distance += util::coordinate_calculation::haversineDistance(prev_coordinate, coordinate); - if (path_point.turn_instruction != TurnInstruction::NO_TURN()) + if (path_point.turn_instruction != extractor::guidance::TurnInstruction::NO_TURN()) { geometry.segment_distances.push_back(current_distance); geometry.segment_offsets.push_back(geometry.locations.size()); diff --git a/include/engine/guidance/assemble_steps.hpp b/include/engine/guidance/assemble_steps.hpp index e8d085fc7..bc459ebdc 100644 --- a/include/engine/guidance/assemble_steps.hpp +++ b/include/engine/guidance/assemble_steps.hpp @@ -4,8 +4,8 @@ #include "engine/guidance/route_step.hpp" #include "engine/guidance/step_maneuver.hpp" #include "engine/guidance/leg_geometry.hpp" -#include "engine/guidance/guidance_toolkit.hpp" -#include "engine/guidance/turn_instruction.hpp" +#include "engine/guidance/toolkit.hpp" +#include "extractor/guidance/turn_instruction.hpp" #include "engine/internal_route_result.hpp" #include "engine/phantom_node.hpp" #include "util/coordinate_calculation.hpp" @@ -25,7 +25,7 @@ namespace guidance namespace detail { // FIXME move implementation to cpp -inline StepManeuver stepManeuverFromGeometry(TurnInstruction instruction, +inline StepManeuver stepManeuverFromGeometry(extractor::guidance::TurnInstruction instruction, const LegGeometry &leg_geometry, const std::size_t segment_index, const unsigned exit) @@ -59,7 +59,6 @@ std::vector assembleSteps(const DataFacadeT &facade, boost::optional source_location, boost::optional target_location) { - (void) source_location; const auto source_duration = (source_traversed_in_reverse ? source_node.GetReverseWeightPlusOffset() : source_node.GetForwardWeightPlusOffset()) / @@ -80,22 +79,28 @@ std::vector assembleSteps(const DataFacadeT &facade, steps.reserve(number_of_segments); std::size_t segment_index = 0; + const auto initial_modifier = + (source_location && leg_geometry.locations.size() >= 2) + ? angleToDirectionModifier(util::coordinate_calculation::computeAngle( + source_location.get(), *(leg_geometry.locations.begin()), + *(leg_geometry.locations.begin() + 1))) + : extractor::guidance::DirectionModifier::UTurn; + if (leg_data.size() > 0) { StepManeuver maneuver = detail::stepManeuverFromGeometry( - TurnInstruction{TurnType::Location, DirectionModifier::UTurn}, leg_geometry, - segment_index, INVALID_EXIT_NR); - maneuver.instruction.direction_modifier = bearingToDirectionModifier(maneuver.bearing_before); + extractor::guidance::TurnInstruction{extractor::guidance::TurnType::Location, + initial_modifier}, + leg_geometry, segment_index, INVALID_EXIT_NR); - // TODO fix this: it makes no sense // PathData saves the information we need of the segment _before_ the turn, // but a RouteStep is with regard to the segment after the turn. // We need to skip the first segment because it is already covered by the // initial start of a route for (const auto &path_point : leg_data) { - if (path_point.turn_instruction != TurnInstruction::NO_TURN()) + if (path_point.turn_instruction != extractor::guidance::TurnInstruction::NO_TURN()) { const auto name = facade.get_name_for_id(path_point.name_id); const auto distance = leg_geometry.segment_distances[segment_index]; @@ -108,7 +113,6 @@ std::vector assembleSteps(const DataFacadeT &facade, segment_index++; } } - // TODO remove this hack const auto distance = leg_geometry.segment_distances[segment_index]; steps.push_back(RouteStep{target_node.name_id, facade.get_name_for_id(target_node.name_id), target_duration, distance, target_mode, maneuver, @@ -123,9 +127,9 @@ std::vector assembleSteps(const DataFacadeT &facade, // x---*---*---*---z compressed edge // |-------| duration StepManeuver maneuver = {source_node.location, 0., 0., - TurnInstruction{TurnType::Location, DirectionModifier::UTurn}, + extractor::guidance::TurnInstruction{ + extractor::guidance::TurnType::Location, initial_modifier}, INVALID_EXIT_NR}; - maneuver.instruction.direction_modifier = bearingToDirectionModifier(maneuver.bearing_before); steps.push_back(RouteStep{source_node.name_id, facade.get_name_for_id(source_node.name_id), target_duration - source_duration, @@ -136,15 +140,18 @@ std::vector assembleSteps(const DataFacadeT &facade, BOOST_ASSERT(segment_index == number_of_segments - 1); const auto final_modifier = - target_location ? angleToDirectionModifier(util::coordinate_calculation::computeAngle( - *(leg_geometry.locations.end() - 3), - *(leg_geometry.locations.end() - 1), target_location.get())) - : DirectionModifier::UTurn; + (target_location && leg_geometry.locations.size() >= 2) + ? angleToDirectionModifier(util::coordinate_calculation::computeAngle( + *(leg_geometry.locations.end() - 2), *(leg_geometry.locations.end() - 1), + target_location.get())) + : extractor::guidance::DirectionModifier::UTurn; // This step has length zero, the only reason we need it is the target location steps.push_back(RouteStep{ target_node.name_id, facade.get_name_for_id(target_node.name_id), 0., 0., target_mode, StepManeuver{target_node.location, 0., 0., - TurnInstruction{TurnType::Location, final_modifier}, INVALID_EXIT_NR}, + extractor::guidance::TurnInstruction{extractor::guidance::TurnType::Location, + final_modifier}, + INVALID_EXIT_NR}, leg_geometry.locations.size(), leg_geometry.locations.size()}); return steps; diff --git a/include/engine/guidance/post_processing.hpp b/include/engine/guidance/post_processing.hpp index c66e997f2..9714f1db3 100644 --- a/include/engine/guidance/post_processing.hpp +++ b/include/engine/guidance/post_processing.hpp @@ -12,7 +12,7 @@ namespace engine namespace guidance { -std::vector> postProcess( std::vector> path_data ); +std::vector> postProcess(std::vector> path_data); } // namespace guidance } // namespace engine diff --git a/include/engine/guidance/step_maneuver.hpp b/include/engine/guidance/step_maneuver.hpp index 070b60f7d..dd8795422 100644 --- a/include/engine/guidance/step_maneuver.hpp +++ b/include/engine/guidance/step_maneuver.hpp @@ -2,7 +2,7 @@ #define ENGINE_GUIDANCE_STEP_MANEUVER_HPP #include "util/coordinate.hpp" -#include "engine/guidance/turn_instruction.hpp" +#include "extractor/guidance/turn_instruction.hpp" namespace osrm { @@ -16,7 +16,7 @@ struct StepManeuver util::Coordinate location; double bearing_before; double bearing_after; - TurnInstruction instruction; + extractor::guidance::TurnInstruction instruction; unsigned exit; }; } // namespace guidance diff --git a/include/engine/guidance/toolkit.hpp b/include/engine/guidance/toolkit.hpp new file mode 100644 index 000000000..000382823 --- /dev/null +++ b/include/engine/guidance/toolkit.hpp @@ -0,0 +1,62 @@ +#ifndef OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_ +#define OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_ + +#include "extractor/guidance/turn_instruction.hpp" +#include "util/bearing.hpp" + +namespace osrm +{ +namespace engine +{ +namespace guidance +{ + +// Silent Turn Instructions are not to be mentioned to the outside world but +inline bool isSilent(const extractor::guidance::TurnInstruction instruction) +{ + return instruction.type == extractor::guidance::TurnType::NoTurn || instruction.type == extractor::guidance::TurnType::Suppressed || + instruction.type == extractor::guidance::TurnType::StayOnRoundabout; +} + +inline bool entersRoundabout(const extractor::guidance::TurnInstruction instruction) +{ + return (instruction.type == extractor::guidance::TurnType::EnterRoundabout || + instruction.type == extractor::guidance::TurnType::EnterRotary || + instruction.type == extractor::guidance::TurnType::EnterRoundaboutAtExit || + instruction.type == extractor::guidance::TurnType::EnterRotaryAtExit || + instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout || + instruction.type == extractor::guidance::TurnType::EnterAndExitRotary); +} + +inline bool leavesRoundabout(const extractor::guidance::TurnInstruction instruction) +{ + return (instruction.type == extractor::guidance::TurnType::ExitRoundabout || + instruction.type == extractor::guidance::TurnType::ExitRotary || + instruction.type == extractor::guidance::TurnType::EnterAndExitRoundabout || + instruction.type == extractor::guidance::TurnType::EnterAndExitRotary); +} + +inline bool staysOnRoundabout(const extractor::guidance::TurnInstruction instruction) +{ + return instruction.type == extractor::guidance::TurnType::StayOnRoundabout; +} + +inline extractor::guidance::DirectionModifier angleToDirectionModifier(const double bearing) +{ + if (bearing < 135) + { + return extractor::guidance::DirectionModifier::Right; + } + + if (bearing <= 225) + { + return extractor::guidance::DirectionModifier::Straight; + } + return extractor::guidance::DirectionModifier::Left; +} + +} // namespace guidance +} // namespace engine +} // namespace osrm + +#endif /* OSRM_UTIL_GUIDANCE_TOOLKIT_HPP_ */ diff --git a/include/engine/internal_route_result.hpp b/include/engine/internal_route_result.hpp index 0faba9594..820d5dff3 100644 --- a/include/engine/internal_route_result.hpp +++ b/include/engine/internal_route_result.hpp @@ -3,7 +3,7 @@ #include "engine/phantom_node.hpp" #include "extractor/travel_mode.hpp" -#include "guidance/turn_instruction.hpp" +#include "extractor/guidance/turn_instruction.hpp" #include "util/typedefs.hpp" #include "osrm/coordinate.hpp" @@ -26,7 +26,7 @@ struct PathData // duration that is traveled on the segment until the turn is reached EdgeWeight duration_until_turn; // instruction to execute at the turn - guidance::TurnInstruction turn_instruction; + extractor::guidance::TurnInstruction turn_instruction; // travel mode of the street that leads to the turn extractor::TravelMode travel_mode : 4; // exit ID of highway exit, roundabout exit, intersection nr diff --git a/include/engine/plugins/plugin_base.hpp b/include/engine/plugins/plugin_base.hpp index cb1b4c4e9..d80832088 100644 --- a/include/engine/plugins/plugin_base.hpp +++ b/include/engine/plugins/plugin_base.hpp @@ -203,7 +203,7 @@ class BasePlugin } } - // we didn't found a fitting node, return error + // we didn't find a fitting node, return error if (phantom_nodes[i].empty()) { break; @@ -264,7 +264,7 @@ class BasePlugin } } - // we didn't found a fitting node, return error + // we didn't find a fitting node, return error if (!phantom_node_pairs[i].first.IsValid(facade.GetNumberOfNodes())) { //TODO document why? diff --git a/include/engine/routing_algorithms/routing_base.hpp b/include/engine/routing_algorithms/routing_base.hpp index 0337162ae..fbd035cde 100644 --- a/include/engine/routing_algorithms/routing_base.hpp +++ b/include/engine/routing_algorithms/routing_base.hpp @@ -4,7 +4,7 @@ #include "util/coordinate_calculation.hpp" #include "engine/internal_route_result.hpp" #include "engine/search_engine_data.hpp" -#include "engine/guidance/turn_instruction.hpp" +#include "extractor/guidance/turn_instruction.hpp" #include "util/typedefs.hpp" #include @@ -283,7 +283,7 @@ template class BasicRoutingInterface { BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut"); unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id); - const guidance::TurnInstruction turn_instruction = + const auto turn_instruction = facade->GetTurnInstructionForEdgeID(ed.id); const extractor::TravelMode travel_mode = (unpacked_path.empty() && start_traversed_in_reverse) @@ -320,9 +320,9 @@ template class BasicRoutingInterface BOOST_ASSERT(start_index < end_index); for (std::size_t i = start_index; i < end_index; ++i) { - unpacked_path.push_back(PathData{id_vector[i], name_index, weight_vector[i], - guidance::TurnInstruction::NO_TURN(), - travel_mode, INVALID_EXIT_NR}); + unpacked_path.push_back(PathData{id_vector[i], name_index, weight_vector[i], + extractor::guidance::TurnInstruction::NO_TURN(), + travel_mode, INVALID_EXIT_NR}); } BOOST_ASSERT(unpacked_path.size() > 0); unpacked_path.back().turn_instruction = turn_instruction; @@ -365,7 +365,7 @@ template class BasicRoutingInterface BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0); unpacked_path.emplace_back(PathData{ id_vector[i], phantom_node_pair.target_phantom.name_id, 0, - guidance::TurnInstruction::NO_TURN(), + extractor::guidance::TurnInstruction::NO_TURN(), target_traversed_in_reverse ? phantom_node_pair.target_phantom.backward_travel_mode : phantom_node_pair.target_phantom.forward_travel_mode, INVALID_EXIT_NR}); diff --git a/include/extractor/edge_based_graph_factory.hpp b/include/extractor/edge_based_graph_factory.hpp index be43fe76e..4e448ebf3 100644 --- a/include/extractor/edge_based_graph_factory.hpp +++ b/include/extractor/edge_based_graph_factory.hpp @@ -10,9 +10,9 @@ #include "extractor/edge_based_node.hpp" #include "extractor/original_edge_data.hpp" #include "extractor/query_node.hpp" -#include "extractor/turn_analysis.hpp" +#include "extractor/guidance/turn_analysis.hpp" -#include "engine/guidance/turn_instruction.hpp" +#include "extractor/guidance/turn_instruction.hpp" #include "util/node_based_graph.hpp" #include "util/typedefs.hpp" @@ -71,12 +71,12 @@ class EdgeBasedGraphFactory // with known angle. // Handles special cases like u-turns and roundabouts // For basic turns, the turn based on the angle-classification is returned - engine::guidance::TurnInstruction AnalyzeTurn(const NodeID u, - const EdgeID e1, - const NodeID v, - const EdgeID e2, - const NodeID w, - const double angle) const; + guidance::TurnInstruction AnalyzeTurn(const NodeID u, + const EdgeID e1, + const NodeID v, + const EdgeID e2, + const NodeID w, + const double angle) const; std::int32_t GetTurnPenalty(double angle, lua_State *lua_state) const; @@ -129,10 +129,6 @@ class EdgeBasedGraphFactory void FlushVectorToStream(std::ofstream &edge_data_file, std::vector &original_edge_data_vector) const; - // Use In Order to generate base turns - std::vector getTurns(const NodeID from, const EdgeID via_edge); - // cannot be const due to the counters... - std::size_t restricted_turns_counter; std::size_t skipped_uturns_counter; std::size_t skipped_barrier_turns_counter; diff --git a/include/extractor/extraction_way.hpp b/include/extractor/extraction_way.hpp index 878c24d44..f82787d96 100644 --- a/include/extractor/extraction_way.hpp +++ b/include/extractor/extraction_way.hpp @@ -3,7 +3,6 @@ #include "extractor/travel_mode.hpp" #include "util/typedefs.hpp" -#include "engine/guidance/classification_data.hpp" #include #include @@ -34,7 +33,6 @@ struct ExtractionWay name.clear(); forward_travel_mode = TRAVEL_MODE_INACCESSIBLE; backward_travel_mode = TRAVEL_MODE_INACCESSIBLE; - road_classification_data.invalidate(); } // These accessors exists because it's not possible to take the address of a bitfield, @@ -53,7 +51,6 @@ struct ExtractionWay bool is_startpoint; TravelMode forward_travel_mode : 4; TravelMode backward_travel_mode : 4; - engine::guidance::RoadClassificationData road_classification_data; }; } } diff --git a/include/engine/guidance/classification_data.hpp b/include/extractor/guidance/classification_data.hpp similarity index 73% rename from include/engine/guidance/classification_data.hpp rename to include/extractor/guidance/classification_data.hpp index 0eaf6ba75..212ad0cdf 100644 --- a/include/engine/guidance/classification_data.hpp +++ b/include/extractor/guidance/classification_data.hpp @@ -1,13 +1,11 @@ -#ifndef OSRM_GUIDANCE_CLASSIFICATION_DATA_HPP_ -#define OSRM_GUIDANCE_CLASSIFICATION_DATA_HPP_ +#ifndef OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_ +#define OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_ + +#include "util/simple_logger.hpp" #include #include -#include //TODO remove - -#include "util/simple_logger.hpp" - // Forward Declaration to allow usage of external osmium::Way namespace osmium { @@ -16,13 +14,14 @@ class Way; namespace osrm { -namespace engine +namespace extractor { namespace guidance { -enum FunctionalRoadClass +enum class FunctionalRoadClass : short { + UNKNOWN = 0, MOTORWAY, MOTORWAY_LINK, TRUNK, @@ -37,12 +36,12 @@ enum FunctionalRoadClass RESIDENTIAL, SERVICE, LIVING_STREET, - LOW_PRIORITY_ROAD, // a road simply included for connectivity. Should be avoided at all cost - UNKNOWN + LOW_PRIORITY_ROAD // a road simply included for connectivity. Should be avoided at all cost }; inline FunctionalRoadClass functionalRoadClassFromTag(std::string const &value) { + //FIXME at some point this should be part of the profiles const static auto initializeClassHash = []() { std::unordered_map hash; @@ -84,36 +83,25 @@ inline FunctionalRoadClass functionalRoadClassFromTag(std::string const &value) inline bool isRampClass(const FunctionalRoadClass road_class) { // Primary Roads and down are usually too small to announce their links as ramps - return road_class == MOTORWAY_LINK || road_class == TRUNK_LINK; - //|| road_class == PRIMARY_LINK || - // road_class == SECONDARY_LINK || road_class == TERTIARY_LINK; + return road_class == FunctionalRoadClass::MOTORWAY_LINK || + road_class == FunctionalRoadClass::TRUNK_LINK; } // TODO augment this with all data required for guidance generation struct RoadClassificationData { - FunctionalRoadClass road_class; + FunctionalRoadClass road_class = FunctionalRoadClass::UNKNOWN; void augment(const osmium::Way &way); - - // reset to a defined but invalid state - void invalidate(); - - static RoadClassificationData INVALID() - { - RoadClassificationData tmp; - tmp.invalidate(); - return tmp; - }; }; -inline bool operator==( const RoadClassificationData lhs, const RoadClassificationData rhs ) +inline bool operator==(const RoadClassificationData lhs, const RoadClassificationData rhs) { - return lhs.road_class == rhs.road_class; + return lhs.road_class == rhs.road_class; } } // namespace guidance -} // namespace engine +} // namespace extractor } // namespace osrm -#endif // OSRM_GUIDANCE_CLASSIFICATION_DATA_HPP_ +#endif // OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_ diff --git a/include/extractor/guidance/discrete_angle.hpp b/include/extractor/guidance/discrete_angle.hpp new file mode 100644 index 000000000..f7ff0f862 --- /dev/null +++ b/include/extractor/guidance/discrete_angle.hpp @@ -0,0 +1,16 @@ +#ifndef OSRM_EXTRACTOR_GUIDANCE_DISCRETE_ANGLE +#define OSRM_EXTRACTOR_GUIDANCE_DISCRETE_ANGLE + +namespace osrm +{ +namespace extractor +{ +namespace guidance +{ + +typedef uint8_t DiscreteAngle; +} // namespace guidance +} // namespace extractor +} // namespace osrm + +#endif /* OSRM_EXTRACTOR_GUIDANCE_DISCRETE_ANGLE */ diff --git a/include/engine/guidance/guidance_toolkit.hpp b/include/extractor/guidance/toolkit.hpp similarity index 65% rename from include/engine/guidance/guidance_toolkit.hpp rename to include/extractor/guidance/toolkit.hpp index 5f68e3574..3c8e15f46 100644 --- a/include/engine/guidance/guidance_toolkit.hpp +++ b/include/extractor/guidance/toolkit.hpp @@ -1,5 +1,5 @@ -#ifndef OSRM_GUIDANCE_GUIDANCE_TOOLKIT_HPP_ -#define OSRM_GUIDANCE_GUIDANCE_TOOLKIT_HPP_ +#ifndef OSRM_GUIDANCE_TOOLKIT_HPP_ +#define OSRM_GUIDANCE_TOOLKIT_HPP_ #include "util/bearing.hpp" #include "util/coordinate.hpp" @@ -8,15 +8,16 @@ #include "extractor/compressed_edge_container.hpp" #include "extractor/query_node.hpp" -#include "engine/guidance/classification_data.hpp" -#include "engine/guidance/turn_instruction.hpp" +#include "extractor/guidance/discrete_angle.hpp" +#include "extractor/guidance/classification_data.hpp" +#include "extractor/guidance/turn_instruction.hpp" #include #include namespace osrm { -namespace engine +namespace extractor { namespace guidance { @@ -26,15 +27,10 @@ namespace detail const constexpr double DESIRED_SEGMENT_LENGTH = 10.0; const constexpr bool shiftable_ccw[] = {false, true, true, false, false, true, true, false}; const constexpr bool shiftable_cw[] = {false, false, true, true, false, false, true, true}; -// direction modifier bounds in 360./256. degrees -const constexpr uint8_t modifier_bounds[num_direction_modifiers] = {0, 36, 93, 121, - 136, 163, 220, 255}; - +const constexpr uint8_t modifier_bounds[detail::num_direction_modifiers] = { + 0, 36, 93, 121, 136, 163, 220, 255}; const constexpr double discrete_angle_step_size = 360. / 256.; -} // namespace detail -namespace detail -{ template util::Coordinate getCoordinateFromCompressedRange(util::Coordinate current_coordinate, @@ -136,13 +132,15 @@ getRepresentativeCoordinate(const NodeID from_node, } // shift an instruction around the degree circle in CCW order -inline DirectionModifier forcedShiftCCW(const DirectionModifier modifier) +inline DirectionModifier +forcedShiftCCW(const DirectionModifier modifier) { - return static_cast((static_cast(modifier) + 1) % - detail::num_direction_modifiers); + return static_cast( + (static_cast(modifier) + 1) % detail::num_direction_modifiers); } -inline DirectionModifier shiftCCW(const DirectionModifier modifier) +inline DirectionModifier +shiftCCW(const DirectionModifier modifier) { if (detail::shiftable_ccw[static_cast(modifier)]) return forcedShiftCCW(modifier); @@ -151,14 +149,16 @@ inline DirectionModifier shiftCCW(const DirectionModifier modifier) } // shift an instruction around the degree circle in CW order -inline DirectionModifier forcedShiftCW(const DirectionModifier modifier) +inline DirectionModifier +forcedShiftCW(const DirectionModifier modifier) { return static_cast( (static_cast(modifier) + detail::num_direction_modifiers - 1) % detail::num_direction_modifiers); } -inline DirectionModifier shiftCW(const DirectionModifier modifier) +inline DirectionModifier +shiftCW(const DirectionModifier modifier) { if (detail::shiftable_cw[static_cast(modifier)]) return forcedShiftCW(modifier); @@ -166,60 +166,21 @@ inline DirectionModifier shiftCW(const DirectionModifier modifier) return modifier; } -inline bool entersRoundabout(const TurnInstruction instruction) -{ - return (instruction.type == TurnType::EnterRoundabout || - instruction.type == TurnType::EnterRotary || - instruction.type == TurnType::EnterRoundaboutAtExit || - instruction.type == TurnType::EnterRotaryAtExit || - instruction.type == TurnType::EnterAndExitRoundabout || - instruction.type == TurnType::EnterAndExitRotary); -} - -inline bool leavesRoundabout(const TurnInstruction instruction) -{ - return (instruction.type == TurnType::ExitRoundabout || - instruction.type == TurnType::ExitRotary || - instruction.type == TurnType::EnterAndExitRoundabout || - instruction.type == TurnType::EnterAndExitRotary); -} - -inline bool staysOnRoundabout(const TurnInstruction instruction) -{ - return instruction.type == TurnType::StayOnRoundabout; -} - -inline bool isOnRoundabout(const TurnInstruction instruction) -{ - return staysOnRoundabout(instruction) || leavesRoundabout(instruction); -} - -inline bool isTurnNecessary(const TurnInstruction instruction) -{ - return instruction.type != TurnType::NoTurn && instruction.type != TurnType::Suppressed; -} - -inline bool isLeftRight(const DirectionModifier modifier) -{ - return DirectionModifier::Right == modifier || DirectionModifier::Left == modifier; -} - -inline bool isSlightLeftRight(const DirectionModifier modifier) -{ - return DirectionModifier::SlightRight == modifier || DirectionModifier::SlightLeft == modifier; -} - inline bool isBasic(const TurnType type) { - return type == TurnType::Turn || type == TurnType::EndOfRoad; + return type == TurnType::Turn || + type == TurnType::EndOfRoad; } inline bool isUturn(const TurnInstruction instruction) { - return isBasic(instruction.type) && instruction.direction_modifier == DirectionModifier::UTurn; + return isBasic(instruction.type) && + instruction.direction_modifier == DirectionModifier::UTurn; } -inline bool resolve(TurnInstruction &to_resolve, const TurnInstruction neighbor, bool resolve_cw) +inline bool resolve(TurnInstruction &to_resolve, + const TurnInstruction neighbor, + bool resolve_cw) { const auto shifted_turn = resolve_cw ? shiftCW(to_resolve.direction_modifier) : shiftCCW(to_resolve.direction_modifier); @@ -262,8 +223,9 @@ inline bool isSlightModifier(const DirectionModifier direction_modifier) inline bool isSharpTurn(const TurnInstruction turn) { - return isBasic(turn.type) && (turn.direction_modifier == DirectionModifier::SharpLeft || - turn.direction_modifier == DirectionModifier::SharpRight); + return isBasic(turn.type) && + (turn.direction_modifier == DirectionModifier::SharpLeft || + turn.direction_modifier == DirectionModifier::SharpRight); } inline bool isStraight(const TurnInstruction turn) @@ -272,30 +234,18 @@ inline bool isStraight(const TurnInstruction turn) turn.direction_modifier == DirectionModifier::Straight; } -inline bool isConflict(const TurnInstruction first, const TurnInstruction second) +inline bool isConflict(const TurnInstruction first, + const TurnInstruction second) { return (first.type == second.type && first.direction_modifier == second.direction_modifier) || (isStraight(first) && isStraight(second)); } -inline DirectionModifier discreteAngleToDircetionModifier(const DiscreteAngle angle) -{ - auto modifier = DirectionModifier::UTurn; - DiscreteAngle bound(detail::modifier_bounds[modifier]); - do - { - if (angle <= bound) - return modifier; - modifier = forcedShiftCW(modifier); - bound = static_cast(detail::modifier_bounds[modifier]); - } while (modifier != DirectionModifier::UTurn); - return modifier; -} - inline DiscreteAngle discretizeAngle(const double angle) { BOOST_ASSERT(angle >= 0. && angle <= 360.); - return DiscreteAngle(static_cast(angle / detail::discrete_angle_step_size)); + return DiscreteAngle( + static_cast(angle / detail::discrete_angle_step_size)); } inline double angleFromDiscreteAngle(const DiscreteAngle angle) @@ -319,7 +269,8 @@ inline double getTurnConfidence(const double angle, TurnInstruction instruction) { // special handling of U-Turns and Roundabout - if (!isBasic(instruction.type) || instruction.direction_modifier == DirectionModifier::UTurn) + if (!isBasic(instruction.type) || + instruction.direction_modifier == DirectionModifier::UTurn) return 1.0; const double deviations[] = {0, 45, 50, 35, 10, 35, 50, 45}; @@ -352,57 +303,19 @@ inline DirectionModifier getTurnDirection(const double angle) return DirectionModifier::UTurn; } -inline DirectionModifier angleToDirectionModifier(const double bearing) -{ - if (bearing < 135) - { - return DirectionModifier::Right; - } - - if (bearing <= 225) - { - return DirectionModifier::Straight; - } - return DirectionModifier::Left; -} - -inline DirectionModifier bearingToDirectionModifier(const std::string &bearing) -{ - const static auto buildHash = []() - { - std::map hash; - hash["N"] = DirectionModifier::Straight; - hash["NE"] = DirectionModifier::SlightRight; - hash["E"] = DirectionModifier::Right; - hash["SE"] = DirectionModifier::SharpRight; - hash["S"] = DirectionModifier::UTurn; - hash["SW"] = DirectionModifier::SharpLeft; - hash["W"] = DirectionModifier::Left; - hash["NW"] = DirectionModifier::SlightLeft; - return hash; - }; - - const static std::map hash = buildHash(); - return hash.find(bearing)->second; -} - -inline DirectionModifier bearingToDirectionModifier(const double angle) -{ - return bearingToDirectionModifier(util::bearing::get(angle)); -} - -inline bool isHighway(FunctionalRoadClass road_class) -{ - return road_class == FunctionalRoadClass::MOTORWAY || road_class == FunctionalRoadClass::TRUNK; -} - // swaps left <-> right modifier types -inline DirectionModifier mirrorDirectionModifier(const DirectionModifier modifier) +inline DirectionModifier +mirrorDirectionModifier(const DirectionModifier modifier) { const constexpr DirectionModifier results[] = { - DirectionModifier::UTurn, DirectionModifier::SharpLeft, DirectionModifier::Left, - DirectionModifier::SlightLeft, DirectionModifier::Straight, DirectionModifier::SlightRight, - DirectionModifier::Right, DirectionModifier::SharpRight}; + DirectionModifier::UTurn, + DirectionModifier::SharpLeft, + DirectionModifier::Left, + DirectionModifier::SlightLeft, + DirectionModifier::Straight, + DirectionModifier::SlightRight, + DirectionModifier::Right, + DirectionModifier::SharpRight}; return results[modifier]; } @@ -420,7 +333,7 @@ inline bool isLowPriorityRoadClass(const FunctionalRoadClass road_class) } } // namespace guidance -} // namespace engine +} // namespace extractor } // namespace osrm -#endif // OSRM_GUIDANCE_GUIDANCE_TOOLKIT_HPP_ +#endif // OSRM_GUIDANCE_TOOLKIT_HPP_ diff --git a/include/extractor/turn_analysis.hpp b/include/extractor/guidance/turn_analysis.hpp similarity index 79% rename from include/extractor/turn_analysis.hpp rename to include/extractor/guidance/turn_analysis.hpp index 0c7f3aaf0..29be643fe 100644 --- a/include/extractor/turn_analysis.hpp +++ b/include/extractor/guidance/turn_analysis.hpp @@ -1,9 +1,8 @@ #ifndef OSRM_EXTRACTOR_TURN_ANALYSIS #define OSRM_EXTRACTOR_TURN_ANALYSIS -#include "engine/guidance/turn_classification.hpp" -#include "engine/guidance/guidance_toolkit.hpp" - +#include "extractor/guidance/turn_classification.hpp" +#include "extractor/guidance/toolkit.hpp" #include "extractor/restriction_map.hpp" #include "extractor/compressed_edge_container.hpp" @@ -13,14 +12,16 @@ namespace osrm { namespace extractor { +namespace guidance +{ struct TurnCandidate { EdgeID eid; // the id of the arc bool valid; // a turn may be relevant to good instructions, even if we cannot take the road double angle; // the approximated angle of the turn - engine::guidance::TurnInstruction instruction; // a proposed instruction - double confidence; // how close to the border is the turn? + TurnInstruction instruction; // a proposed instruction + double confidence; // how close to the border is the turn? std::string toString() const { @@ -38,8 +39,6 @@ struct TurnCandidate return result; } }; -namespace turn_analysis -{ // the entry into the turn analysis std::vector @@ -57,6 +56,7 @@ namespace detail // Check for restrictions/barriers and generate a list of valid and invalid turns present at the // node reached // from `from_node` via `via_eid` +// The resulting candidates have to be analysed for their actual instructions later on. std::vector getTurnCandidates(const NodeID from_node, const EdgeID via_eid, @@ -66,16 +66,27 @@ getTurnCandidates(const NodeID from_node, const std::unordered_set &barrier_nodes, const CompressedEdgeContainer &compressed_edge_container); -// merge segregated roads to omit invalid turns in favor of treating segregated roads as one +// Merge segregated roads to omit invalid turns in favor of treating segregated roads as one. +// This function combines roads the following way: +// +// * * +// * is converted to * +// v ^ + +// v ^ + +// +// The treatment results in a straight turn angle of 180ยบ rather than a turn angle of approx 160 std::vector mergeSegregatedRoads(const NodeID from_node, const EdgeID via_eid, std::vector turn_candidates, const std::shared_ptr node_based_graph); -// handle roundabouts // TODO distinguish roundabouts and rotaries // TODO handle bike/walk cases that allow crossing a roundabout! + +// Processing of roundabouts +// Produces instructions to enter/exit a roundabout or to stay on it. +// Performs the distinction between roundabout and rotaries. std::vector handleRoundabouts(const NodeID from, const EdgeID via_edge, @@ -85,79 +96,100 @@ handleRoundabouts(const NodeID from, std::vector turn_candidates, const std::shared_ptr node_based_graph); +// A Basic junction is a junction not requiring special treatment. It cannot contain anything +// but streets of lesser priority than trunks and ramps (of any type). No roundabouts or motorway +// like types. bool isBasicJunction(const NodeID from, const EdgeID via_edge, const std::vector &turn_candidates, const std::shared_ptr node_based_graph); +// Indicates a Junction containing a motoryway bool isMotorwayJunction(const NodeID from, const EdgeID via_edge, const std::vector &turn_candidates, const std::shared_ptr node_based_graph); // Decide whether a turn is a turn or a ramp access -engine::guidance::TurnType -turnOrRamp(const NodeID from, - const EdgeID via_edge, - const TurnCandidate &candidate, - const std::shared_ptr node_based_graph); +TurnType turnOrRamp(const NodeID from, + const EdgeID via_edge, + const TurnCandidate &candidate, + const std::shared_ptr node_based_graph); // Get the Instruction for an obvious turn -engine::guidance::TurnInstruction +// Instruction will be a silent instruction +TurnInstruction getInstructionForObvious(const NodeID from, const EdgeID via_edge, const TurnCandidate &candidate, const std::shared_ptr node_based_graph); -engine::guidance::TurnInstruction +// Helper Function that decides between NoTurn or NewName +TurnInstruction noTurnOrNewName(const NodeID from, const EdgeID via_edge, const TurnCandidate &candidate, const std::shared_ptr node_based_graph); -// handle basic intersections +// Basic Turn Handling + +// Dead end. std::vector handleOneWayTurn(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); +// Mode Changes, new names... std::vector handleTwoWayTurn(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); +// Forks, T intersections and similar std::vector handleThreeWayTurn(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); +// Normal Intersection. Can still contain forks... std::vector handleFourWayTurn(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); +// Fallback for turns of high complexion std::vector handleComplexTurn(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); +// Any Junction containing motorways std::vector handleMotorwayJunction(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); +// Utility function, setting basic turn types. Prepares for normal turn handling. std::vector setTurnTypes(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); +// Utility function to handle direction modifier conflicts if reasonably possible +std::vector +handleConflicts(const NodeID from, + const EdgeID via_edge, + std::vector turn_candidates, + const std::shared_ptr node_based_graph); + +// Old fallbacks, to be removed std::vector optimizeRamps(const EdgeID via_edge, std::vector turn_candidates, @@ -180,7 +212,7 @@ suppressTurns(const EdgeID via_eid, const std::shared_ptr node_based_graph); // node_u -- (edge_1) --> node_v -- (edge_2) --> node_w -engine::guidance::TurnInstruction +TurnInstruction AnalyzeTurn(const NodeID node_u, const EdgeID edge1, const NodeID node_v, @@ -189,13 +221,8 @@ AnalyzeTurn(const NodeID node_u, const double angle, const std::shared_ptr node_based_graph); -std::vector -handleConflicts(const NodeID from, - const EdgeID via_edge, - std::vector turn_candidates, - const std::shared_ptr node_based_graph); } // namespace detail -} // namespace turn_analysis +} // namespace guidance } // namespace extractor } // namespace osrm diff --git a/include/engine/guidance/turn_classification.hpp b/include/extractor/guidance/turn_classification.hpp similarity index 81% rename from include/engine/guidance/turn_classification.hpp rename to include/extractor/guidance/turn_classification.hpp index cd870f7f2..58f76666e 100644 --- a/include/engine/guidance/turn_classification.hpp +++ b/include/extractor/guidance/turn_classification.hpp @@ -1,8 +1,7 @@ #ifndef OSRM_GUIDANCE_TURN_CLASSIFICATION_HPP_ #define OSRM_GUIDANCE_TURN_CLASSIFICATION_HPP_ -#include "engine/guidance/turn_instruction.hpp" -#include "engine/guidance/guidance_toolkit.hpp" +#include "extractor/guidance/toolkit.hpp" #include "util/typedefs.hpp" #include "util/coordinate.hpp" @@ -17,7 +16,7 @@ namespace osrm { -namespace engine +namespace extractor { namespace guidance { @@ -35,6 +34,26 @@ struct TurnPossibility EdgeID edge_id; }; +struct CompareTurnPossibilities +{ + bool operator()(const std::vector &left, + const std::vector &right) const + { + if (left.size() < right.size()) + return true; + if (left.size() > right.size()) + return false; + for (std::size_t i = 0; i < left.size(); ++i) + { + if ((((int)left[i].angle + 16) % 256) / 32 < (((int)right[i].angle + 16) % 256) / 32) + return true; + if ((((int)left[i].angle + 16) % 256) / 32 > (((int)right[i].angle + 16) % 256) / 32) + return false; + } + return false; + } +}; + inline std::vector classifyIntersection(NodeID nid, const util::NodeBasedDynamicGraph &graph, @@ -98,7 +117,7 @@ classifyIntersection(NodeID nid, } } // namespace guidance -} // namespace engine +} // namespace extractor } // namespace osrm #endif // OSRM_GUIDANCE_TURN_CLASSIFICATION_HPP_ diff --git a/include/engine/guidance/turn_instruction.hpp b/include/extractor/guidance/turn_instruction.hpp similarity index 60% rename from include/engine/guidance/turn_instruction.hpp rename to include/extractor/guidance/turn_instruction.hpp index 69b4b354b..7bd713c51 100644 --- a/include/engine/guidance/turn_instruction.hpp +++ b/include/extractor/guidance/turn_instruction.hpp @@ -7,7 +7,7 @@ namespace osrm { -namespace engine +namespace extractor { namespace guidance { @@ -33,17 +33,6 @@ enum DirectionModifier SharpLeft }; -const constexpr char *modifier_names[detail::num_direction_modifiers] = { - "uturn", "sharp right", "right", "slight right", - "straight", "slight left", "left", "sharp left"}; - -enum LocationType -{ - Start, - Intermediate, - Destination -}; - // enum class TurnType : unsigned char enum TurnType // at the moment we can support 32 turn types, without increasing memory consumption { @@ -71,42 +60,7 @@ enum TurnType // at the moment we can support 32 turn types, without increasing Notification // Travel Mode Changes` }; -inline bool isValidModifier( const TurnType type, const DirectionModifier modifier ) -{ - if( type == TurnType::Location && - modifier != DirectionModifier::Left - && modifier != DirectionModifier::Straight - && modifier != DirectionModifier::Right ) - return false; - return true; -} - -const constexpr char *turn_type_names[] = {"invalid", - "no turn", - "waypoint", - "invalid", - "new name", - "continue", - "turn", - "merge", - "ramp", - "fork", - "end of road", - "roundabout", - "invalid", - "roundabout", - "invalid", - "traffic circle", - "invalid", - "traffic circle", - "invalid", - "invalid", - "restriction", - "notification"}; - // turn angle in 1.40625 degree -> 128 == 180 degree -typedef uint8_t DiscreteAngle; - struct TurnInstruction { TurnInstruction(const TurnType type = TurnType::Invalid, @@ -135,7 +89,7 @@ struct TurnInstruction static TurnInstruction ENTER_ROUNDABOUT(const DirectionModifier modifier) { - return TurnInstruction(TurnType::EnterRoundabout, modifier); + return TurnInstruction(TurnType::EnterRoundabout, modifier); } static TurnInstruction EXIT_ROUNDABOUT(const DirectionModifier modifier) @@ -145,7 +99,7 @@ struct TurnInstruction static TurnInstruction SUPPRESSED(const DirectionModifier modifier) { - return TurnInstruction{TurnType::Suppressed,modifier}; + return TurnInstruction{TurnType::Suppressed, modifier}; } }; @@ -159,15 +113,8 @@ inline bool operator==(const TurnInstruction lhs, const TurnInstruction rhs) return lhs.type == rhs.type && lhs.direction_modifier == rhs.direction_modifier; } -// Silent Turn Instructions are not to be mentioned to the outside world -inline bool isSilent(const TurnInstruction instruction) -{ - return instruction.type == TurnType::NoTurn || instruction.type == TurnType::Suppressed || - instruction.type == TurnType::StayOnRoundabout; -} - } // namespace guidance -} // namespace engine +} // namespace extractor } // namespace osrm #endif // OSRM_GUIDANCE_TURN_INSTRUCTION_HPP_ diff --git a/include/extractor/internal_extractor_edge.hpp b/include/extractor/internal_extractor_edge.hpp index 404144755..2ccdb2c2d 100644 --- a/include/extractor/internal_extractor_edge.hpp +++ b/include/extractor/internal_extractor_edge.hpp @@ -9,7 +9,7 @@ #include "osrm/coordinate.hpp" #include -#include "engine/guidance/classification_data.hpp" +#include "extractor/guidance/classification_data.hpp" namespace osrm { @@ -52,7 +52,7 @@ struct InternalExtractorEdge true, TRAVEL_MODE_INACCESSIBLE, false, - engine::guidance::RoadClassificationData::INVALID()) + guidance::RoadClassificationData()) { } @@ -67,7 +67,7 @@ struct InternalExtractorEdge bool startpoint, TravelMode travel_mode, bool is_split, - engine::guidance::RoadClassificationData road_classification) + guidance::RoadClassificationData road_classification) : result(OSMNodeID(source), OSMNodeID(target), name_id, @@ -96,13 +96,13 @@ struct InternalExtractorEdge { return InternalExtractorEdge(MIN_OSM_NODEID, MIN_OSM_NODEID, 0, WeightData(), false, false, false, false, true, TRAVEL_MODE_INACCESSIBLE, false, - engine::guidance::RoadClassificationData::INVALID()); + guidance::RoadClassificationData()); } static InternalExtractorEdge max_osm_value() { return InternalExtractorEdge(MAX_OSM_NODEID, MAX_OSM_NODEID, 0, WeightData(), false, false, false, false, true, TRAVEL_MODE_INACCESSIBLE, false, - engine::guidance::RoadClassificationData::INVALID()); + guidance::RoadClassificationData()); } static InternalExtractorEdge min_internal_value() diff --git a/include/extractor/node_based_edge.hpp b/include/extractor/node_based_edge.hpp index 4ca658f53..47090e6f7 100644 --- a/include/extractor/node_based_edge.hpp +++ b/include/extractor/node_based_edge.hpp @@ -4,7 +4,7 @@ #include "extractor/travel_mode.hpp" #include "util/typedefs.hpp" -#include "engine/guidance/classification_data.hpp" +#include "extractor/guidance/classification_data.hpp" namespace osrm { @@ -26,7 +26,7 @@ struct NodeBasedEdge bool startpoint, TravelMode travel_mode, bool is_split, - engine::guidance::RoadClassificationData road_classification); + guidance::RoadClassificationData road_classification); bool operator<(const NodeBasedEdge &other) const; @@ -41,7 +41,7 @@ struct NodeBasedEdge bool startpoint : 1; bool is_split : 1; TravelMode travel_mode : 4; - engine::guidance::RoadClassificationData road_classification; + guidance::RoadClassificationData road_classification; }; struct NodeBasedEdgeWithOSM : NodeBasedEdge @@ -57,7 +57,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge bool startpoint, TravelMode travel_mode, bool is_split, - engine::guidance::RoadClassificationData road_classification); + guidance::RoadClassificationData road_classification); OSMNodeID osm_source_id; OSMNodeID osm_target_id; @@ -70,7 +70,6 @@ inline NodeBasedEdge::NodeBasedEdge() backward(false), roundabout(false), access_restricted(false), startpoint(true), is_split(false), travel_mode(false) { - road_classification.invalidate(); } inline NodeBasedEdge::NodeBasedEdge(NodeID source, @@ -84,7 +83,7 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source, bool startpoint, TravelMode travel_mode, bool is_split, - engine::guidance::RoadClassificationData road_classification) + guidance::RoadClassificationData road_classification) : source(source), target(target), name_id(name_id), weight(weight), forward(forward), backward(backward), roundabout(roundabout), access_restricted(access_restricted), startpoint(startpoint), is_split(is_split), travel_mode(travel_mode), @@ -121,7 +120,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM( bool startpoint, TravelMode travel_mode, bool is_split, - engine::guidance::RoadClassificationData road_classification) + guidance::RoadClassificationData road_classification) : NodeBasedEdge(SPECIAL_NODEID, SPECIAL_NODEID, name_id, diff --git a/include/extractor/original_edge_data.hpp b/include/extractor/original_edge_data.hpp index c4e2b37ea..17d234af9 100644 --- a/include/extractor/original_edge_data.hpp +++ b/include/extractor/original_edge_data.hpp @@ -2,7 +2,7 @@ #define ORIGINAL_EDGE_DATA_HPP #include "extractor/travel_mode.hpp" -#include "engine/guidance/turn_instruction.hpp" +#include "extractor/guidance/turn_instruction.hpp" #include "util/typedefs.hpp" #include @@ -16,7 +16,7 @@ struct OriginalEdgeData { explicit OriginalEdgeData(NodeID via_node, unsigned name_id, - engine::guidance::TurnInstruction turn_instruction, + guidance::TurnInstruction turn_instruction, TravelMode travel_mode) : via_node(via_node), name_id(name_id), turn_instruction(turn_instruction), travel_mode(travel_mode) @@ -26,14 +26,14 @@ struct OriginalEdgeData OriginalEdgeData() : via_node(std::numeric_limits::max()), name_id(std::numeric_limits::max()), - turn_instruction(engine::guidance::TurnInstruction::INVALID()), + turn_instruction(guidance::TurnInstruction::INVALID()), travel_mode(TRAVEL_MODE_INACCESSIBLE) { } NodeID via_node; unsigned name_id; - engine::guidance::TurnInstruction turn_instruction; + guidance::TurnInstruction turn_instruction; TravelMode travel_mode; }; } diff --git a/include/util/coordinate_calculation.hpp b/include/util/coordinate_calculation.hpp index cd91067f2..759434a27 100644 --- a/include/util/coordinate_calculation.hpp +++ b/include/util/coordinate_calculation.hpp @@ -58,7 +58,9 @@ double bearing(const Coordinate first_coordinate, const Coordinate second_coordi // Get angle of line segment (A,C)->(C,B) double computeAngle(const Coordinate first, const Coordinate second, const Coordinate third); -Coordinate interpolateLinear( double factor, const Coordinate from, const Coordinate to ); +// factor in [0,1]. Returns point along the straight line between from and to. 0 returns from, 1 +// returns to +Coordinate interpolateLinear(double factor, const Coordinate from, const Coordinate to); namespace mercator { diff --git a/include/util/node_based_graph.hpp b/include/util/node_based_graph.hpp index 8405a0063..463fbb1b3 100644 --- a/include/util/node_based_graph.hpp +++ b/include/util/node_based_graph.hpp @@ -4,7 +4,7 @@ #include "util/dynamic_graph.hpp" #include "extractor/node_based_edge.hpp" #include "util/graph_utils.hpp" -#include "engine/guidance/classification_data.hpp" +#include "extractor/guidance/classification_data.hpp" #include @@ -46,13 +46,15 @@ struct NodeBasedEdgeData bool roundabout : 1; bool startpoint : 1; extractor::TravelMode travel_mode : 4; - engine::guidance::RoadClassificationData road_classification; + extractor::guidance::RoadClassificationData road_classification; bool IsCompatibleTo(const NodeBasedEdgeData &other) const { - //TODO roundabout/startpoint/access_restricted should all be part of this?? - return (reversed == other.reversed) && (name_id == other.name_id) && - (travel_mode == other.travel_mode && road_classification == other.road_classification); + return (name_id == other.name_id) && (reversed == other.reversed) && + (roundabout == other.roundabout) && (startpoint == other.startpoint) && + (access_restricted == other.access_restricted) && + (travel_mode == other.travel_mode) && + (road_classification == other.road_classification); } }; diff --git a/src/contractor/contractor.cpp b/src/contractor/contractor.cpp index 7a259d055..8df0f9237 100644 --- a/src/contractor/contractor.cpp +++ b/src/contractor/contractor.cpp @@ -52,7 +52,7 @@ int Contractor::Run() #ifdef WIN32 #pragma message("Memory consumption on Windows can be higher due to different bit packing") #else - static_assert(sizeof(extractor::NodeBasedEdge) == 24, + static_assert(sizeof(extractor::NodeBasedEdge) == 20, "changing extractor::NodeBasedEdge type has influence on memory consumption!"); static_assert(sizeof(extractor::EdgeBasedEdge) == 16, "changing EdgeBasedEdge type has influence on memory consumption!"); diff --git a/src/engine/api/json_factory.cpp b/src/engine/api/json_factory.cpp index 23f4807d1..41e9f33f9 100644 --- a/src/engine/api/json_factory.cpp +++ b/src/engine/api/json_factory.cpp @@ -13,6 +13,10 @@ #include #include +using TurnType = osrm::extractor::guidance::TurnType; +using DirectionModifier = osrm::extractor::guidance::DirectionModifier; +using TurnInstruction = osrm::extractor::guidance::TurnInstruction; + namespace osrm { namespace engine @@ -24,14 +28,36 @@ namespace json namespace detail { -std::string instructionTypeToString(guidance::TurnType type) +const constexpr char *modifier_names[] = {"uturn", "sharp right", "right", "slight right", + "straight", "slight left", "left", "sharp left"}; + +// translations of TurnTypes. Not all types are exposed to the outside world. +// invalid types should never be returned as part of the API +const constexpr char *turn_type_names[] = { + "invalid", "no turn", "waypoint", "invalid", "new name", "continue", + "turn", "merge", "ramp", "fork", "end of road", "roundabout", + "invalid", "roundabout", "invalid", "traffic circle", "invalid", "traffic circle", + "invalid", "invalid", "restriction", "notification"}; + +// Check whether to include a modifier in the result of the API +inline bool isValidModifier(const TurnType type, + const DirectionModifier modifier) { - return guidance::turn_type_names[static_cast(type)]; + if (type == TurnType::Location && modifier != DirectionModifier::Left && + modifier != DirectionModifier::Straight && + modifier != DirectionModifier::Right) + return false; + return true; } -std::string instructionModifierToString(guidance::DirectionModifier modifier) +std::string instructionTypeToString(TurnType type) { - return guidance::modifier_names[static_cast(modifier)]; + return turn_type_names[static_cast(type)]; +} + +std::string instructionModifierToString(DirectionModifier modifier) +{ + return modifier_names[static_cast(modifier)]; } util::json::Array coordinateToLonLat(const util::Coordinate coordinate) @@ -100,9 +126,9 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver) { util::json::Object step_maneuver; step_maneuver.values["type"] = detail::instructionTypeToString(maneuver.instruction.type); - if( guidance::isValidModifier( maneuver.instruction.type, maneuver.instruction.direction_modifier ) ) - step_maneuver.values["modifier"] = - detail::instructionModifierToString(maneuver.instruction.direction_modifier); + if (detail::isValidModifier(maneuver.instruction.type, maneuver.instruction.direction_modifier)) + step_maneuver.values["modifier"] = + detail::instructionModifierToString(maneuver.instruction.direction_modifier); step_maneuver.values["location"] = detail::coordinateToLonLat(maneuver.location); step_maneuver.values["bearing_before"] = maneuver.bearing_before; step_maneuver.values["bearing_after"] = maneuver.bearing_after; diff --git a/src/engine/guidance/classification_data.cpp b/src/engine/guidance/classification_data.cpp deleted file mode 100644 index a40e89a84..000000000 --- a/src/engine/guidance/classification_data.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "engine/guidance/classification_data.hpp" - -#include - -#include - -namespace osrm -{ -namespace engine -{ -namespace guidance -{ -void RoadClassificationData::invalidate() { road_class = FunctionalRoadClass::UNKNOWN; } - -void RoadClassificationData::augment(const osmium::Way &way) -{ - const char *data = way.get_value_by_key("highway"); - if (data) - road_class = functionalRoadClassFromTag(data); -} -} // namespace guidance -} // namespace engine -} // namespace osrm diff --git a/src/engine/guidance/post_processing.cpp b/src/engine/guidance/post_processing.cpp index 17abc1976..7cb016097 100644 --- a/src/engine/guidance/post_processing.cpp +++ b/src/engine/guidance/post_processing.cpp @@ -1,10 +1,15 @@ #include "engine/guidance/post_processing.hpp" -#include "engine/guidance/turn_instruction.hpp" -#include "engine/guidance/guidance_toolkit.hpp" +#include "extractor/guidance/turn_instruction.hpp" + +#include "engine/guidance/toolkit.hpp" #include #include +using TurnInstruction = osrm::extractor::guidance::TurnInstruction; +using TurnType = osrm::extractor::guidance::TurnType; +using DirectionModifier = osrm::extractor::guidance::DirectionModifier; + namespace osrm { namespace engine @@ -118,10 +123,11 @@ std::vector> postProcess(std::vector { if (!on_roundabout) { - BOOST_ASSERT(leg_data[0][0].turn_instruction.type == TurnInstruction::NO_TURN()); - if (path_data[data_index].turn_instruction.type == ExitRoundabout) + BOOST_ASSERT(leg_data[0][0].turn_instruction.type == + TurnInstruction::NO_TURN()); + if (path_data[data_index].turn_instruction.type == TurnType::ExitRoundabout) leg_data[0][0].turn_instruction.type = TurnType::EnterRoundabout; - if (path_data[data_index].turn_instruction.type == ExitRotary) + if (path_data[data_index].turn_instruction.type == TurnType::ExitRotary) leg_data[0][0].turn_instruction.type = TurnType::EnterRotary; path_data[data_index].exit += 1; } diff --git a/src/engine/plugins/trip.cpp b/src/engine/plugins/trip.cpp index 01a7c6070..b9776a795 100644 --- a/src/engine/plugins/trip.cpp +++ b/src/engine/plugins/trip.cpp @@ -140,9 +140,9 @@ InternalRouteResult TripPlugin::ComputeRoute(const std::vector &sna { uturns.resize(trip.size() + 1); std::transform(trip.begin(), trip.end(), uturns.begin(), [¶meters](const NodeID idx) - { - return parameters.uturns[idx]; - }); + { + return parameters.uturns[idx]; + }); BOOST_ASSERT(uturns.size() > 0); uturns.back() = parameters.uturns[trip.front()]; } @@ -248,9 +248,9 @@ Status TripPlugin::HandleRequest(const api::TripParameters ¶meters, for (const auto &trip : trips) { routes.push_back(ComputeRoute(snapped_phantoms, parameters, trip)); - ordered_coordinates.push_back( std::vector() ); - for( const auto nid : trip ) - ordered_coordinates.back().push_back( parameters.coordinates[nid] ); + ordered_coordinates.push_back(std::vector()); + for (const auto nid : trip) + ordered_coordinates.back().push_back(parameters.coordinates[nid]); } api::TripAPI trip_api{BasePlugin::facade, parameters}; diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 3abdbba36..4a1ece193 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -1,6 +1,5 @@ #include "extractor/edge_based_edge.hpp" #include "extractor/edge_based_graph_factory.hpp" -#include "extractor/turn_analysis.hpp" #include "util/coordinate.hpp" #include "util/coordinate_calculation.hpp" #include "util/percent.hpp" @@ -10,8 +9,7 @@ #include "util/timing_util.hpp" #include "util/exception.hpp" -#include "engine/guidance/turn_classification.hpp" -#include "engine/guidance/guidance_toolkit.hpp" +#include "extractor/guidance/toolkit.hpp" #include #include @@ -307,56 +305,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( // Three nested loop look super-linear, but we are dealing with a (kind of) // linear number of turns only. util::Percent progress(m_node_based_graph->GetNumberOfNodes()); - - struct CompareTurnPossibilities - { - bool operator()(const std::vector &left, - const std::vector &right) const - { - if (left.size() < right.size()) - return true; - if (left.size() > right.size()) - return false; - for (std::size_t i = 0; i < left.size(); ++i) - { - if ((((int)left[i].angle + 16) % 256) / 32 < - (((int)right[i].angle + 16) % 256) / 32) - return true; - if ((((int)left[i].angle + 16) % 256) / 32 > - (((int)right[i].angle + 16) % 256) / 32) - return false; - } - return false; - } - }; - -// temporary switch to allow display of turn types -#define SHOW_TURN_TYPES 0 -#if SHOW_TURN_TYPES - std::map, - std::vector, CompareTurnPossibilities> turn_types; -#endif - for (const auto node_u : util::irange(0u, m_node_based_graph->GetNumberOfNodes())) { -#if SHOW_TURN_TYPES - auto turn_possibilities = classifyIntersection( - node_u, *m_node_based_graph, m_compressed_edge_container, m_node_info_list); - if (turn_possibilities.empty()) - continue; - auto set = turn_types.find(turn_possibilities); - if (set != turn_types.end()) - { - if (set->second.size() < 5) - set->second.emplace_back(m_node_info_list[node_u].lat, - m_node_info_list[node_u].lon); - } - else - { - turn_types[turn_possibilities] = std::vector( - 1, {m_node_info_list[node_u].lat, m_node_info_list[node_u].lon}); - } -#endif // progress.printStatus(node_u); for (const EdgeID edge_from_u : m_node_based_graph->GetAdjacentEdgeRange(node_u)) { @@ -366,8 +316,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( } ++node_based_edge_counter; - auto turn_candidates = turn_analysis::getTurns(node_u, edge_from_u, m_node_based_graph, m_node_info_list, m_restriction_map, m_barrier_nodes, - m_compressed_edge_container); + auto turn_candidates = guidance::getTurns( + node_u, edge_from_u, m_node_based_graph, m_node_info_list, m_restriction_map, + m_barrier_nodes, m_compressed_edge_container); const NodeID node_v = m_node_based_graph->GetTarget(edge_from_u); @@ -396,7 +347,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const int turn_penalty = GetTurnPenalty(turn_angle, lua_state); const auto turn_instruction = turn.instruction; - if (isUturn(turn_instruction)) + if (guidance::isUturn(turn_instruction)) { distance += speed_profile.u_turn_penalty; } @@ -471,21 +422,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( } } } -#if SHOW_TURN_TYPES - std::cout << "[info] found " << turn_types.size() << " turn types." << std::endl; - for (const auto &tt : turn_types) - { - std::cout << tt.second.size(); - for (auto coord : tt.second) - std::cout << " " << coord.lat << " " << coord.lon; - - std::cout << " " << tt.first.size(); - for (auto tte : tt.first) - std::cout << " " << (int)tte.angle; - - std::cout << std::endl; - } -#endif FlushVectorToStream(edge_data_file, original_edge_data_vector); diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp index 67950f8aa..10f0fa6f4 100644 --- a/src/extractor/extractor.cpp +++ b/src/extractor/extractor.cpp @@ -188,7 +188,6 @@ int Extractor::run() local_state, "way_function", boost::cref(static_cast(*entity)), boost::ref(result_way)); - result_way.road_classification_data.augment(static_cast(*entity)); resulting_ways.push_back(std::make_pair(x, result_way)); break; case osmium::item_type::relation: diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index 1915f2744..a289ec63f 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -128,6 +128,14 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti return; } + // FIXME this need to be moved into the profiles + const char *data = input_way.get_value_by_key("highway"); + guidance::RoadClassificationData road_classification; + if (data) + { + road_classification.road_class = guidance::functionalRoadClassFromTag(data); + } + // Get the unique identifier for the street name const auto &string_map_iterator = string_map.find(parsed_way.name); unsigned name_id = external_memory.name_lengths.size(); @@ -173,7 +181,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti name_id, backward_weight_data, true, false, parsed_way.roundabout, parsed_way.is_access_restricted, parsed_way.is_startpoint, parsed_way.backward_travel_mode, - false,parsed_way.road_classification_data)); + false, road_classification)); }); external_memory.way_start_end_id_list.push_back( @@ -193,7 +201,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti name_id, forward_weight_data, true, !forward_only, parsed_way.roundabout, parsed_way.is_access_restricted, parsed_way.is_startpoint, parsed_way.forward_travel_mode, - split_edge,parsed_way.road_classification_data)); + split_edge, road_classification)); }); if (split_edge) { @@ -206,7 +214,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti OSMNodeID(first_node.ref()), OSMNodeID(last_node.ref()), name_id, backward_weight_data, false, true, parsed_way.roundabout, parsed_way.is_access_restricted, parsed_way.is_startpoint, - parsed_way.backward_travel_mode, true,parsed_way.road_classification_data)); + parsed_way.backward_travel_mode, true, road_classification)); }); } diff --git a/src/extractor/turn_analysis.cpp b/src/extractor/guidance/turn_analysis.cpp similarity index 96% rename from src/extractor/turn_analysis.cpp rename to src/extractor/guidance/turn_analysis.cpp index 8c65280a0..14afbac26 100644 --- a/src/extractor/turn_analysis.cpp +++ b/src/extractor/guidance/turn_analysis.cpp @@ -1,4 +1,4 @@ -#include "extractor/turn_analysis.hpp" +#include "extractor/guidance/turn_analysis.hpp" #include "util/simple_logger.hpp" @@ -8,8 +8,7 @@ namespace osrm { namespace extractor { - -namespace turn_analysis +namespace guidance { // configuration of turn classification const bool constexpr INVERT = true; @@ -29,26 +28,6 @@ const unsigned constexpr INVALID_NAME_ID = 0; using EdgeData = util::NodeBasedDynamicGraph::EdgeData; -using engine::guidance::TurnPossibility; -using engine::guidance::TurnInstruction; -using engine::guidance::DirectionModifier; -using engine::guidance::TurnType; -using engine::guidance::FunctionalRoadClass; - -using engine::guidance::classifyIntersection; -using engine::guidance::isLowPriorityRoadClass; -using engine::guidance::angularDeviation; -using engine::guidance::getTurnDirection; -using engine::guidance::getRepresentativeCoordinate; -using engine::guidance::isBasic; -using engine::guidance::isRampClass; -using engine::guidance::isUturn; -using engine::guidance::isConflict; -using engine::guidance::isSlightTurn; -using engine::guidance::isSlightModifier; -using engine::guidance::mirrorDirectionModifier; -using engine::guidance::canBeSuppressed; - #define PRINT_DEBUG_CANDIDATES 0 std::vector getTurns(const NodeID from, @@ -419,7 +398,8 @@ handleFromMotorway(const NodeID from, if (candidate.valid) { BOOST_ASSERT(isRampClass(candidate.eid, node_based_graph)); - candidate.instruction = TurnInstruction::SUPPRESSED(getTurnDirection(candidate.angle)); + candidate.instruction = + TurnInstruction::SUPPRESSED(getTurnDirection(candidate.angle)); } } } @@ -447,27 +427,26 @@ handleFromMotorway(const NodeID from, if (candidate.angle == continue_angle) { if (continues) - candidate.instruction = TurnInstruction::SUPPRESSED(DirectionModifier::Straight); + candidate.instruction = + TurnInstruction::SUPPRESSED(DirectionModifier::Straight); else // TODO handle turn direction correctly candidate.instruction = {TurnType::Merge, DirectionModifier::Straight}; } else if (candidate.angle < continue_angle) { - BOOST_ASSERT(isRampClass(node_based_graph->GetEdgeData(candidate.eid) - .road_classification.road_class)); - candidate.instruction = {TurnType::Ramp, - (candidate.angle < 145) - ? DirectionModifier::Right - : DirectionModifier::SlightRight}; + candidate.instruction = { + isRampClass(candidate.eid, node_based_graph) ? TurnType::Ramp + : TurnType::Turn, + (candidate.angle < 145) ? DirectionModifier::Right + : DirectionModifier::SlightRight}; } else if (candidate.angle > continue_angle) { - BOOST_ASSERT(isRampClass(node_based_graph->GetEdgeData(candidate.eid) - .road_classification.road_class)); - candidate.instruction = {TurnType::Ramp, - (candidate.angle > 215) - ? DirectionModifier::Left - : DirectionModifier::SlightLeft}; + candidate.instruction = { + isRampClass(candidate.eid, node_based_graph) ? TurnType::Ramp + : TurnType::Turn, + (candidate.angle > 215) ? DirectionModifier::Left + : DirectionModifier::SlightLeft}; } } } @@ -633,7 +612,8 @@ handleMotorwayJunction(const NodeID from, const std::shared_ptr node_based_graph) { (void)from; - BOOST_ASSERT(!turn_candidates[0].valid); + // BOOST_ASSERT(!turn_candidates[0].valid); //This fails due to @themarex handling of dead end + // streets const auto &in_data = node_based_graph->GetEdgeData(via_edge); // coming from motorway @@ -766,6 +746,7 @@ handleOneWayTurn(const NodeID from, std::vector turn_candidates, const std::shared_ptr node_based_graph) { + BOOST_ASSERT(turn_candidates[0].angle < 0.001); (void)from, (void)via_edge, (void)node_based_graph; if (!turn_candidates[0].valid) { @@ -773,8 +754,6 @@ handleOneWayTurn(const NodeID from, << "Graph Broken. Dead end without exit found or missing reverse edge."; } - BOOST_ASSERT(turn_candidates[0].instruction.type == TurnType::Turn && - turn_candidates[0].instruction.direction_modifier == DirectionModifier::UTurn); #if PRINT_DEBUG_CANDIDATES std::cout << "Basic (one) Turn Candidates:\n"; for (auto tc : turn_candidates) @@ -791,8 +770,7 @@ handleTwoWayTurn(const NodeID from, std::vector turn_candidates, const std::shared_ptr node_based_graph) { - BOOST_ASSERT(turn_candidates[0].instruction.type == TurnType::Turn && - turn_candidates[0].instruction.direction_modifier == DirectionModifier::UTurn); + BOOST_ASSERT(turn_candidates[0].angle < 0.001); turn_candidates[1].instruction = getInstructionForObvious(from, via_edge, turn_candidates[1], node_based_graph); @@ -813,6 +791,7 @@ handleThreeWayTurn(const NodeID from, std::vector turn_candidates, const std::shared_ptr node_based_graph) { + BOOST_ASSERT(turn_candidates[0].angle < 0.001); const auto isObviousOfTwo = [](const TurnCandidate turn, const TurnCandidate other) { return (angularDeviation(turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE && @@ -971,7 +950,8 @@ handleThreeWayTurn(const NodeID from, { if (isObviousOfTwo(turn_candidates[1], turn_candidates[2])) { - turn_candidates[1].instruction = TurnInstruction::SUPPRESSED(DirectionModifier::Straight); + turn_candidates[1].instruction = + TurnInstruction::SUPPRESSED(DirectionModifier::Straight); } else { @@ -988,7 +968,8 @@ handleThreeWayTurn(const NodeID from, { if (isObviousOfTwo(turn_candidates[2], turn_candidates[1])) { - turn_candidates[2].instruction = TurnInstruction::SUPPRESSED(DirectionModifier::Straight); + turn_candidates[2].instruction = + TurnInstruction::SUPPRESSED(DirectionModifier::Straight); } else { @@ -1199,8 +1180,7 @@ optimizeCandidates(const EdgeID via_eid, for (std::size_t turn_index = 0; turn_index < turn_candidates.size(); ++turn_index) { auto &turn = turn_candidates[turn_index]; - if (!isBasic(turn.instruction.type) || isUturn(turn.instruction) || - isOnRoundabout(turn.instruction)) + if (!isBasic(turn.instruction.type) || isUturn(turn.instruction)) continue; auto &left = turn_candidates[getLeft(turn_index)]; if (turn.angle == left.angle) @@ -1393,8 +1373,7 @@ bool isObviousChoice(const EdgeID via_eid, node_based_graph->GetEdgeData(candidate.eid).road_classification.road_class)) { bool is_only_normal_road = true; - BOOST_ASSERT(turn_candidates[0].instruction.type == TurnType::Turn && - turn_candidates[0].instruction.direction_modifier == DirectionModifier::UTurn); + // TODO find out why this can also be reached for non-u-turns for (size_t i = 0; i < turn_candidates.size(); ++i) { if (i == turn_index || turn_candidates[i].angle == 0) // skip self and u-turn @@ -1554,7 +1533,7 @@ suppressTurns(const EdgeID via_eid, } else { - if (engine::guidance::canBeSuppressed(candidate.instruction.type)) + if (canBeSuppressed(candidate.instruction.type)) candidate.instruction.type = TurnType::NewName; } } @@ -1841,21 +1820,20 @@ handleConflicts(const NodeID from, (void)from; (void)via_edge; (void)node_based_graph; - const auto isConflict = []( const TurnCandidate &left, const TurnCandidate &right ) + const auto isConflict = [](const TurnCandidate &left, const TurnCandidate &right) { // most obvious, same instructions conflict - if( left.instruction == right.instruction ) - return true; + if (left.instruction == right.instruction) + return true; return left.instruction.direction_modifier != DirectionModifier::UTurn && left.instruction.direction_modifier == right.instruction.direction_modifier; }; - return turn_candidates; } } // anemspace detail -} // namespace turn_analysis +} // namespace guidance } // namespace extractor } // namespace osrm diff --git a/src/storage/storage.cpp b/src/storage/storage.cpp index a725625ee..1cb72797a 100644 --- a/src/storage/storage.cpp +++ b/src/storage/storage.cpp @@ -8,7 +8,7 @@ #include "util/static_rtree.hpp" #include "engine/datafacade/datafacade_base.hpp" #include "extractor/travel_mode.hpp" -#include "engine/guidance/turn_instruction.hpp" +#include "extractor/guidance/turn_instruction.hpp" #include "storage/storage.hpp" #include "storage/shared_datatype.hpp" #include "storage/shared_barriers.hpp" @@ -225,7 +225,7 @@ int Storage::Run() number_of_original_edges); shared_layout_ptr->SetBlockSize(SharedDataLayout::TRAVEL_MODE, number_of_original_edges); - shared_layout_ptr->SetBlockSize( + shared_layout_ptr->SetBlockSize( SharedDataLayout::TURN_INSTRUCTION, number_of_original_edges); boost::filesystem::ifstream hsgr_input_stream(hsgr_path, std::ios::binary); @@ -390,8 +390,8 @@ int Storage::Run() shared_layout_ptr->GetBlockPtr(shared_memory_ptr, SharedDataLayout::TRAVEL_MODE); - engine::guidance::TurnInstruction *turn_instructions_ptr = - shared_layout_ptr->GetBlockPtr( + extractor::guidance::TurnInstruction *turn_instructions_ptr = + shared_layout_ptr->GetBlockPtr( shared_memory_ptr, SharedDataLayout::TURN_INSTRUCTION); extractor::OriginalEdgeData current_edge_data; diff --git a/src/util/coordinate_calculation.cpp b/src/util/coordinate_calculation.cpp index 6c32b9ed8..203159e14 100644 --- a/src/util/coordinate_calculation.cpp +++ b/src/util/coordinate_calculation.cpp @@ -260,10 +260,11 @@ double computeAngle(const Coordinate first, const Coordinate second, const Coord Coordinate interpolateLinear(double factor, const Coordinate from, const Coordinate to) { BOOST_ASSERT(0 <= factor && factor <= 1.0); - return {from.lon + toFixed(FloatLongitude( - factor * static_cast(toFloating(to.lon - from.lon)))), - from.lat + toFixed(FloatLatitude( - factor * static_cast(toFloating(to.lat - from.lat))))}; + return { + from.lon + + toFixed(FloatLongitude(factor * static_cast(toFloating(to.lon - from.lon)))), + from.lat + + toFixed(FloatLatitude(factor * static_cast(toFloating(to.lat - from.lat))))}; } namespace mercator