#ifndef OSRM_EXTRACTOR_TURN_ANALYSIS #define OSRM_EXTRACTOR_TURN_ANALYSIS #include "engine/guidance/turn_classification.hpp" #include "engine/guidance/guidance_toolkit.hpp" #include "extractor/restriction_map.hpp" #include "extractor/compressed_edge_container.hpp" #include namespace osrm { namespace extractor { 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? std::string toString() const { std::string result = "[turn] "; result += std::to_string(eid); result += " valid: "; result += std::to_string(valid); result += " angle: "; result += std::to_string(angle); result += " instruction: "; result += std::to_string(static_cast(instruction.type)) + " " + std::to_string(static_cast(instruction.direction_modifier)); result += " confidence: "; result += std::to_string(confidence); return result; } }; namespace turn_analysis { // the entry into the turn analysis std::vector getTurns(const NodeID from_node, const EdgeID via_eid, const std::shared_ptr node_based_graph, const std::vector &node_info_list, const std::shared_ptr restriction_map, const std::unordered_set &barrier_nodes, const CompressedEdgeContainer &compressed_edge_container); 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` std::vector getTurnCandidates(const NodeID from_node, const EdgeID via_eid, const std::shared_ptr node_based_graph, const std::vector &node_info_list, const std::shared_ptr restriction_map, 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 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! std::vector handleRoundabouts(const NodeID from, const EdgeID via_edge, const bool on_roundabout, const bool can_enter_roundabout, const bool can_exit_roundabout, std::vector turn_candidates, const std::shared_ptr node_based_graph); bool isBasicJunction(const NodeID from, const EdgeID via_edge, const std::vector &turn_candidates, const std::shared_ptr node_based_graph); 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); // Get the Instruction for an obvious turn engine::guidance::TurnInstruction getInstructionForObvious(const NodeID from, const EdgeID via_edge, const TurnCandidate &candidate, const std::shared_ptr node_based_graph); engine::guidance::TurnInstruction noTurnOrNewName(const NodeID from, const EdgeID via_edge, const TurnCandidate &candidate, const std::shared_ptr node_based_graph); // handle basic intersections std::vector handleOneWayTurn(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); std::vector handleTwoWayTurn(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); std::vector handleThreeWayTurn(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); std::vector handleFourWayTurn(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); std::vector handleComplexTurn(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); std::vector handleMotorwayJunction(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); std::vector setTurnTypes(const NodeID from, const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); std::vector optimizeRamps(const EdgeID via_edge, std::vector turn_candidates, const std::shared_ptr node_based_graph); std::vector optimizeCandidates(const EdgeID via_eid, std::vector turn_candidates, const std::shared_ptr node_based_graph, const std::vector &node_info_list); bool isObviousChoice(const EdgeID via_eid, const std::size_t turn_index, const std::vector &turn_candidates, const std::shared_ptr node_based_graph); std::vector suppressTurns(const EdgeID via_eid, std::vector turn_candidates, const std::shared_ptr node_based_graph); // node_u -- (edge_1) --> node_v -- (edge_2) --> node_w engine::guidance::TurnInstruction AnalyzeTurn(const NodeID node_u, const EdgeID edge1, const NodeID node_v, const EdgeID edge2, const NodeID node_w, const double angle, const std::shared_ptr node_based_graph); } // namespace detail } // namespace turn_analysis } // namespace extractor } // namespace osrm #endif // OSRM_EXTRACTOR_TURN_ANALYSIS