encapsulated into class
This commit is contained in:
parent
06aa6dedab
commit
eb3f550e26
@ -45,175 +45,161 @@ struct TurnCandidate
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// the entry into the turn analysis
|
class TurnAnalysis
|
||||||
std::vector<TurnCandidate> getTurns(const NodeID from_node,
|
|
||||||
const EdgeID via_eid,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
|
||||||
const std::vector<QueryNode> &node_info_list,
|
|
||||||
const RestrictionMap &restriction_map,
|
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
|
||||||
const CompressedEdgeContainer &compressed_edge_container);
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
// Check for restrictions/barriers and generate a list of valid and invalid turns present at the
|
TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
// node reached
|
|
||||||
// from `from_node` via `via_eid`
|
|
||||||
// The resulting candidates have to be analysed for their actual instructions later on.
|
|
||||||
std::vector<TurnCandidate>
|
|
||||||
getTurnCandidates(const NodeID from_node,
|
|
||||||
const EdgeID via_eid,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
|
||||||
const std::vector<QueryNode> &node_info_list,
|
const std::vector<QueryNode> &node_info_list,
|
||||||
const RestrictionMap &restriction_map,
|
const RestrictionMap &restriction_map,
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
const CompressedEdgeContainer &compressed_edge_container);
|
const CompressedEdgeContainer &compressed_edge_container);
|
||||||
|
|
||||||
// Merge segregated roads to omit invalid turns in favor of treating segregated roads as one.
|
// the entry into the turn analysis
|
||||||
// This function combines roads the following way:
|
std::vector<TurnCandidate> getTurns(const NodeID from_node, const EdgeID via_eid) const;
|
||||||
//
|
|
||||||
// * *
|
private:
|
||||||
// * is converted to *
|
const util::NodeBasedDynamicGraph &node_based_graph;
|
||||||
// v ^ +
|
const std::vector<QueryNode> &node_info_list;
|
||||||
// v ^ +
|
const RestrictionMap &restriction_map;
|
||||||
//
|
const std::unordered_set<NodeID> &barrier_nodes;
|
||||||
// The treatment results in a straight turn angle of 180º rather than a turn angle of approx 160
|
const CompressedEdgeContainer &compressed_edge_container;
|
||||||
std::vector<TurnCandidate>
|
|
||||||
mergeSegregatedRoads(const NodeID from_node,
|
// 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<TurnCandidate> getTurnCandidates(const NodeID from_node,
|
||||||
|
const EdgeID via_eid) const;
|
||||||
|
|
||||||
|
// 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<TurnCandidate>
|
||||||
|
mergeSegregatedRoads(const NodeID from_node,
|
||||||
const EdgeID via_eid,
|
const EdgeID via_eid,
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
std::vector<TurnCandidate> turn_candidates) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// TODO distinguish roundabouts and rotaries
|
// TODO distinguish roundabouts and rotaries
|
||||||
// TODO handle bike/walk cases that allow crossing a roundabout!
|
// TODO handle bike/walk cases that allow crossing a roundabout!
|
||||||
|
|
||||||
// Processing of roundabouts
|
// Processing of roundabouts
|
||||||
// Produces instructions to enter/exit a roundabout or to stay on it.
|
// Produces instructions to enter/exit a roundabout or to stay on it.
|
||||||
// Performs the distinction between roundabout and rotaries.
|
// Performs the distinction between roundabout and rotaries.
|
||||||
std::vector<TurnCandidate> handleRoundabouts(const NodeID from,
|
std::vector<TurnCandidate> handleRoundabouts(const NodeID from,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
const bool on_roundabout,
|
const bool on_roundabout,
|
||||||
const bool can_enter_roundabout,
|
const bool can_enter_roundabout,
|
||||||
const bool can_exit_roundabout,
|
const bool can_exit_roundabout,
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
std::vector<TurnCandidate> turn_candidates) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Indicates a Junction containing a motoryway
|
// Indicates a Junction containing a motoryway
|
||||||
bool isMotorwayJunction(const NodeID from,
|
bool isMotorwayJunction(const NodeID from,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
const std::vector<TurnCandidate> &turn_candidates,
|
const std::vector<TurnCandidate> &turn_candidates) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Decide whether a turn is a turn or a ramp access
|
// Decide whether a turn is a turn or a ramp access
|
||||||
TurnType findBasicTurnType(const EdgeID via_edge,
|
TurnType findBasicTurnType(const EdgeID via_edge, const TurnCandidate &candidate) const;
|
||||||
const TurnCandidate &candidate,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Get the Instruction for an obvious turn
|
// Get the Instruction for an obvious turn
|
||||||
// Instruction will be a silent instruction
|
// Instruction will be a silent instruction
|
||||||
TurnInstruction getInstructionForObvious(const std::size_t number_of_candidates,
|
TurnInstruction getInstructionForObvious(const std::size_t number_of_candidates,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
const TurnCandidate &candidate,
|
const TurnCandidate &candidate) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Helper Function that decides between NoTurn or NewName
|
// Helper Function that decides between NoTurn or NewName
|
||||||
TurnInstruction noTurnOrNewName(const NodeID from,
|
TurnInstruction
|
||||||
|
noTurnOrNewName(const NodeID from, const EdgeID via_edge, const TurnCandidate &candidate) const;
|
||||||
|
|
||||||
|
// Basic Turn Handling
|
||||||
|
|
||||||
|
// Dead end.
|
||||||
|
std::vector<TurnCandidate> handleOneWayTurn(const NodeID from,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
const TurnCandidate &candidate,
|
std::vector<TurnCandidate> turn_candidates) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Basic Turn Handling
|
// Mode Changes, new names...
|
||||||
|
std::vector<TurnCandidate> handleTwoWayTurn(const NodeID from,
|
||||||
// Dead end.
|
|
||||||
std::vector<TurnCandidate> handleOneWayTurn(const NodeID from,
|
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
std::vector<TurnCandidate> turn_candidates) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Mode Changes, new names...
|
// Forks, T intersections and similar
|
||||||
std::vector<TurnCandidate> handleTwoWayTurn(const NodeID from,
|
std::vector<TurnCandidate> handleThreeWayTurn(const NodeID from,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
std::vector<TurnCandidate> turn_candidates) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Forks, T intersections and similar
|
// Normal Intersection. Can still contain forks...
|
||||||
std::vector<TurnCandidate> handleThreeWayTurn(const NodeID from,
|
std::vector<TurnCandidate> handleFourWayTurn(const NodeID from,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
std::vector<TurnCandidate> turn_candidates) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Normal Intersection. Can still contain forks...
|
// Fallback for turns of high complexion
|
||||||
std::vector<TurnCandidate> handleFourWayTurn(const NodeID from,
|
std::vector<TurnCandidate> handleComplexTurn(const NodeID from,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
std::vector<TurnCandidate> turn_candidates) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Fallback for turns of high complexion
|
// Any Junction containing motorways
|
||||||
std::vector<TurnCandidate> handleComplexTurn(const NodeID from,
|
std::vector<TurnCandidate> handleMotorwayJunction(
|
||||||
|
const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const;
|
||||||
|
|
||||||
|
std::vector<TurnCandidate> handleFromMotorway(
|
||||||
|
const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const;
|
||||||
|
|
||||||
|
std::vector<TurnCandidate> handleMotorwayRamp(
|
||||||
|
const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const;
|
||||||
|
|
||||||
|
// Utility function, setting basic turn types. Prepares for normal turn handling.
|
||||||
|
std::vector<TurnCandidate> setTurnTypes(const NodeID from,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
std::vector<TurnCandidate> turn_candidates) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Any Junction containing motorways
|
// Utility function to handle direction modifier conflicts if reasonably possible
|
||||||
std::vector<TurnCandidate>
|
std::vector<TurnCandidate> handleConflicts(const NodeID from,
|
||||||
handleMotorwayJunction(const NodeID from,
|
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
std::vector<TurnCandidate> turn_candidates) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Utility function, setting basic turn types. Prepares for normal turn handling.
|
// Old fallbacks, to be removed
|
||||||
std::vector<TurnCandidate> setTurnTypes(const NodeID from,
|
std::vector<TurnCandidate> optimizeRamps(const EdgeID via_edge,
|
||||||
const EdgeID via_edge,
|
std::vector<TurnCandidate> turn_candidates) const;
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Utility function to handle direction modifier conflicts if reasonably possible
|
std::vector<TurnCandidate> optimizeCandidates(const EdgeID via_eid,
|
||||||
std::vector<TurnCandidate> handleConflicts(const NodeID from,
|
std::vector<TurnCandidate> turn_candidates) const;
|
||||||
const EdgeID via_edge,
|
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Old fallbacks, to be removed
|
bool isObviousChoice(const EdgeID via_eid,
|
||||||
std::vector<TurnCandidate> optimizeRamps(const EdgeID via_edge,
|
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
std::vector<TurnCandidate> optimizeCandidates(const EdgeID via_eid,
|
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
|
||||||
const std::vector<QueryNode> &node_info_list);
|
|
||||||
|
|
||||||
bool isObviousChoice(const EdgeID via_eid,
|
|
||||||
const std::size_t turn_index,
|
const std::size_t turn_index,
|
||||||
const std::vector<TurnCandidate> &turn_candidates,
|
const std::vector<TurnCandidate> &turn_candidates) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
std::vector<TurnCandidate> suppressTurns(const EdgeID via_eid,
|
std::vector<TurnCandidate> suppressTurns(const EdgeID via_eid,
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
std::vector<TurnCandidate> turn_candidates) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// node_u -- (edge_1) --> node_v -- (edge_2) --> node_w
|
// node_u -- (edge_1) --> node_v -- (edge_2) --> node_w
|
||||||
TurnInstruction AnalyzeTurn(const NodeID node_u,
|
TurnInstruction AnalyzeTurn(const NodeID node_u,
|
||||||
const EdgeID edge1,
|
const EdgeID edge1,
|
||||||
const NodeID node_v,
|
const NodeID node_v,
|
||||||
const EdgeID edge2,
|
const EdgeID edge2,
|
||||||
const NodeID node_w,
|
const NodeID node_w,
|
||||||
const double angle,
|
const double angle) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
|
||||||
// Assignment of specific turn types
|
// Assignment of specific turn types
|
||||||
void assignFork(const EdgeID via_edge,
|
void assignFork(const EdgeID via_edge, TurnCandidate &left, TurnCandidate &right) const;
|
||||||
TurnCandidate &left,
|
void assignFork(const EdgeID via_edge,
|
||||||
TurnCandidate &right,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
void assignFork(const EdgeID via_edge,
|
|
||||||
TurnCandidate &left,
|
TurnCandidate &left,
|
||||||
TurnCandidate ¢er,
|
TurnCandidate ¢er,
|
||||||
TurnCandidate &right,
|
TurnCandidate &right) const;
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph);
|
|
||||||
|
//Type specific fallbacks
|
||||||
|
std::vector<TurnCandidate>
|
||||||
|
fallbackTurnAssignmentMotorway(std::vector<TurnCandidate> turn_candidates) const;
|
||||||
|
|
||||||
|
}; // class TurnAnalysis
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
} // namespace guidance
|
} // namespace guidance
|
||||||
} // namespace extractor
|
} // namespace extractor
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
@ -305,6 +305,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
// Three nested loop look super-linear, but we are dealing with a (kind of)
|
// Three nested loop look super-linear, but we are dealing with a (kind of)
|
||||||
// linear number of turns only.
|
// linear number of turns only.
|
||||||
util::Percent progress(m_node_based_graph->GetNumberOfNodes());
|
util::Percent progress(m_node_based_graph->GetNumberOfNodes());
|
||||||
|
guidance::TurnAnalysis turn_analysis( *m_node_based_graph, m_node_info_list,
|
||||||
|
*m_restriction_map, m_barrier_nodes, m_compressed_edge_container );
|
||||||
for (const auto node_u : util::irange(0u, m_node_based_graph->GetNumberOfNodes()))
|
for (const auto node_u : util::irange(0u, m_node_based_graph->GetNumberOfNodes()))
|
||||||
{
|
{
|
||||||
// progress.printStatus(node_u);
|
// progress.printStatus(node_u);
|
||||||
@ -316,9 +318,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
}
|
}
|
||||||
|
|
||||||
++node_based_edge_counter;
|
++node_based_edge_counter;
|
||||||
auto turn_candidates =
|
auto turn_candidates = turn_analysis.getTurns(node_u, edge_from_u);
|
||||||
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);
|
const NodeID node_v = m_node_based_graph->GetTarget(edge_from_u);
|
||||||
|
|
||||||
|
@ -53,19 +53,42 @@ struct Localizer
|
|||||||
|
|
||||||
static Localizer localizer;
|
static Localizer localizer;
|
||||||
|
|
||||||
#define PRINT_DEBUG_CANDIDATES 0
|
TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||||
std::vector<TurnCandidate> getTurns(const NodeID from,
|
|
||||||
const EdgeID via_edge,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
|
||||||
const std::vector<QueryNode> &node_info_list,
|
const std::vector<QueryNode> &node_info_list,
|
||||||
const RestrictionMap &restriction_map,
|
const RestrictionMap &restriction_map,
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
const std::unordered_set<NodeID> &barrier_nodes,
|
||||||
const CompressedEdgeContainer &compressed_edge_container)
|
const CompressedEdgeContainer &compressed_edge_container)
|
||||||
|
: node_based_graph(node_based_graph), node_info_list(node_info_list),
|
||||||
|
restriction_map(restriction_map), barrier_nodes(barrier_nodes),
|
||||||
|
compressed_edge_container(compressed_edge_container)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
inline bool isMotorwayClass(FunctionalRoadClass road_class)
|
||||||
|
{
|
||||||
|
return road_class == FunctionalRoadClass::MOTORWAY || road_class == FunctionalRoadClass::TRUNK;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isMotorwayClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_based_graph)
|
||||||
|
{
|
||||||
|
return isMotorwayClass(node_based_graph.GetEdgeData(eid).road_classification.road_class);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isRampClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_based_graph)
|
||||||
|
{
|
||||||
|
return isRampClass(node_based_graph.GetEdgeData(eid).road_classification.road_class);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
#define PRINT_DEBUG_CANDIDATES 0
|
||||||
|
std::vector<TurnCandidate> TurnAnalysis::getTurns(const NodeID from, const EdgeID via_edge) const
|
||||||
{
|
{
|
||||||
localizer.node_info_list = &node_info_list;
|
localizer.node_info_list = &node_info_list;
|
||||||
auto turn_candidates =
|
auto turn_candidates = getTurnCandidates(from, via_edge);
|
||||||
detail::getTurnCandidates(from, via_edge, node_based_graph, node_info_list, restriction_map,
|
|
||||||
barrier_nodes, compressed_edge_container);
|
|
||||||
|
|
||||||
const auto &in_edge_data = node_based_graph.GetEdgeData(via_edge);
|
const auto &in_edge_data = node_based_graph.GetEdgeData(via_edge);
|
||||||
|
|
||||||
@ -91,51 +114,42 @@ std::vector<TurnCandidate> getTurns(const NodeID from,
|
|||||||
}
|
}
|
||||||
if (on_roundabout || can_enter_roundabout)
|
if (on_roundabout || can_enter_roundabout)
|
||||||
{
|
{
|
||||||
return detail::handleRoundabouts(from, via_edge, on_roundabout, can_enter_roundabout,
|
return handleRoundabouts(from, via_edge, on_roundabout, can_enter_roundabout,
|
||||||
can_exit_roundabout, std::move(turn_candidates),
|
can_exit_roundabout, std::move(turn_candidates));
|
||||||
node_based_graph);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set initial defaults for normal turns and modifier based on angle
|
// set initial defaults for normal turns and modifier based on angle
|
||||||
turn_candidates =
|
turn_candidates = setTurnTypes(from, via_edge, std::move(turn_candidates));
|
||||||
detail::setTurnTypes(from, via_edge, std::move(turn_candidates), node_based_graph);
|
|
||||||
|
|
||||||
if (detail::isMotorwayJunction(from, via_edge, turn_candidates, node_based_graph))
|
if (isMotorwayJunction(from, via_edge, turn_candidates))
|
||||||
{
|
{
|
||||||
return detail::handleMotorwayJunction(from, via_edge, std::move(turn_candidates),
|
return handleMotorwayJunction(from, via_edge, std::move(turn_candidates));
|
||||||
node_based_graph);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (turn_candidates.size() <= 4) // TODO change when larger junctions are handled
|
if (turn_candidates.size() <= 4) // TODO change when larger junctions are handled
|
||||||
{
|
{
|
||||||
if (turn_candidates.size() == 1)
|
if (turn_candidates.size() == 1)
|
||||||
{
|
{
|
||||||
turn_candidates = detail::handleOneWayTurn(from, via_edge, std::move(turn_candidates),
|
turn_candidates = handleOneWayTurn(from, via_edge, std::move(turn_candidates));
|
||||||
node_based_graph);
|
|
||||||
}
|
}
|
||||||
else if (turn_candidates.size() == 2)
|
else if (turn_candidates.size() == 2)
|
||||||
{
|
{
|
||||||
turn_candidates = detail::handleTwoWayTurn(from, via_edge, std::move(turn_candidates),
|
turn_candidates = handleTwoWayTurn(from, via_edge, std::move(turn_candidates));
|
||||||
node_based_graph);
|
|
||||||
}
|
}
|
||||||
else if (turn_candidates.size() == 3)
|
else if (turn_candidates.size() == 3)
|
||||||
{
|
{
|
||||||
turn_candidates = detail::handleThreeWayTurn(from, via_edge, std::move(turn_candidates),
|
turn_candidates = handleThreeWayTurn(from, via_edge, std::move(turn_candidates));
|
||||||
node_based_graph);
|
|
||||||
}
|
}
|
||||||
else if (turn_candidates.size() == 4)
|
else if (turn_candidates.size() == 4)
|
||||||
{
|
{
|
||||||
turn_candidates = detail::handleFourWayTurn(from, via_edge, std::move(turn_candidates),
|
turn_candidates = handleFourWayTurn(from, via_edge, std::move(turn_candidates));
|
||||||
node_based_graph);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
turn_candidates = detail::handleComplexTurn(from, via_edge, std::move(turn_candidates),
|
turn_candidates = handleComplexTurn(from, via_edge, std::move(turn_candidates));
|
||||||
node_based_graph);
|
|
||||||
}
|
}
|
||||||
// complex intersection, potentially requires conflict resolution
|
// complex intersection, potentially requires conflict resolution
|
||||||
return detail::handleConflicts(from, via_edge, std::move(turn_candidates),
|
return handleConflicts(from, via_edge, std::move(turn_candidates));
|
||||||
node_based_graph);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PRINT_DEBUG_CANDIDATES
|
#if PRINT_DEBUG_CANDIDATES
|
||||||
@ -145,8 +159,7 @@ std::vector<TurnCandidate> getTurns(const NodeID from,
|
|||||||
<< (int)node_based_graph.GetEdgeData(tc.eid).road_classification.road_class
|
<< (int)node_based_graph.GetEdgeData(tc.eid).road_classification.road_class
|
||||||
<< " name: " << node_based_graph.GetEdgeData(tc.eid).name_id << std::endl;
|
<< " name: " << node_based_graph.GetEdgeData(tc.eid).name_id << std::endl;
|
||||||
#endif
|
#endif
|
||||||
turn_candidates = detail::optimizeCandidates(via_edge, std::move(turn_candidates),
|
turn_candidates = optimizeCandidates(via_edge, std::move(turn_candidates));
|
||||||
node_based_graph, node_info_list);
|
|
||||||
#if PRINT_DEBUG_CANDIDATES
|
#if PRINT_DEBUG_CANDIDATES
|
||||||
std::cout << "Optimized Candidates:\n";
|
std::cout << "Optimized Candidates:\n";
|
||||||
for (auto tc : turn_candidates)
|
for (auto tc : turn_candidates)
|
||||||
@ -154,7 +167,7 @@ std::vector<TurnCandidate> getTurns(const NodeID from,
|
|||||||
<< (int)node_based_graph.GetEdgeData(tc.eid).road_classification.road_class
|
<< (int)node_based_graph.GetEdgeData(tc.eid).road_classification.road_class
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
turn_candidates = detail::suppressTurns(via_edge, std::move(turn_candidates), node_based_graph);
|
turn_candidates = suppressTurns(via_edge, std::move(turn_candidates));
|
||||||
#if PRINT_DEBUG_CANDIDATES
|
#if PRINT_DEBUG_CANDIDATES
|
||||||
std::cout << "Suppressed Candidates:\n";
|
std::cout << "Suppressed Candidates:\n";
|
||||||
for (auto tc : turn_candidates)
|
for (auto tc : turn_candidates)
|
||||||
@ -165,9 +178,6 @@ std::vector<TurnCandidate> getTurns(const NodeID from,
|
|||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
inline std::size_t countValid(const std::vector<TurnCandidate> &turn_candidates)
|
inline std::size_t countValid(const std::vector<TurnCandidate> &turn_candidates)
|
||||||
{
|
{
|
||||||
return std::count_if(turn_candidates.begin(), turn_candidates.end(),
|
return std::count_if(turn_candidates.begin(), turn_candidates.end(),
|
||||||
@ -177,13 +187,13 @@ inline std::size_t countValid(const std::vector<TurnCandidate> &turn_candidates)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate> handleRoundabouts(const NodeID from,
|
std::vector<TurnCandidate>
|
||||||
|
TurnAnalysis::handleRoundabouts(const NodeID from,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
const bool on_roundabout,
|
const bool on_roundabout,
|
||||||
const bool can_enter_roundabout,
|
const bool can_enter_roundabout,
|
||||||
const bool can_exit_roundabout,
|
const bool can_exit_roundabout,
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
std::vector<TurnCandidate> turn_candidates) const
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
(void)from;
|
(void)from;
|
||||||
// TODO requires differentiation between roundabouts and rotaries
|
// TODO requires differentiation between roundabouts and rotaries
|
||||||
@ -263,24 +273,8 @@ std::vector<TurnCandidate> handleRoundabouts(const NodeID from,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isMotorwayClass(FunctionalRoadClass road_class)
|
std::vector<TurnCandidate>
|
||||||
{
|
TurnAnalysis::fallbackTurnAssignmentMotorway(std::vector<TurnCandidate> turn_candidates) const
|
||||||
return road_class == FunctionalRoadClass::MOTORWAY || road_class == FunctionalRoadClass::TRUNK;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isMotorwayClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
|
||||||
return isMotorwayClass(node_based_graph.GetEdgeData(eid).road_classification.road_class);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isRampClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
|
||||||
return isRampClass(node_based_graph.GetEdgeData(eid).road_classification.road_class);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::vector<TurnCandidate>
|
|
||||||
fallbackTurnAssignmentMotorway(std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
for (auto &candidate : turn_candidates)
|
for (auto &candidate : turn_candidates)
|
||||||
{
|
{
|
||||||
@ -294,7 +288,8 @@ fallbackTurnAssignmentMotorway(std::vector<TurnCandidate> turn_candidates,
|
|||||||
if (!candidate.valid)
|
if (!candidate.valid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto type = isMotorwayClass(out_data.road_classification.road_class) ? TurnType::Merge
|
const auto type = detail::isMotorwayClass(out_data.road_classification.road_class)
|
||||||
|
? TurnType::Merge
|
||||||
: TurnType::Turn;
|
: TurnType::Turn;
|
||||||
if (angularDeviation(candidate.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE)
|
if (angularDeviation(candidate.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE)
|
||||||
candidate.instruction = {type, DirectionModifier::Straight};
|
candidate.instruction = {type, DirectionModifier::Straight};
|
||||||
@ -309,50 +304,47 @@ fallbackTurnAssignmentMotorway(std::vector<TurnCandidate> turn_candidates,
|
|||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
std::vector<TurnCandidate> TurnAnalysis::handleFromMotorway(
|
||||||
const EdgeID via_edge,
|
const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
(void)from;
|
(void)from;
|
||||||
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
|
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
|
||||||
BOOST_ASSERT(isMotorwayClass(in_data.road_classification.road_class));
|
BOOST_ASSERT(detail::isMotorwayClass(in_data.road_classification.road_class));
|
||||||
|
|
||||||
const auto countExitingMotorways =
|
const auto countExitingMotorways = [this](const std::vector<TurnCandidate> &turn_candidates)
|
||||||
[&node_based_graph](const std::vector<TurnCandidate> &turn_candidates)
|
|
||||||
{
|
{
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
for (const auto &candidate : turn_candidates)
|
for (const auto &candidate : turn_candidates)
|
||||||
{
|
{
|
||||||
if (candidate.valid && isMotorwayClass(candidate.eid, node_based_graph))
|
if (candidate.valid && detail::isMotorwayClass(candidate.eid, node_based_graph))
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
};
|
};
|
||||||
|
|
||||||
// find the angle that continues on our current highway
|
// find the angle that continues on our current highway
|
||||||
const auto getContinueAngle =
|
const auto getContinueAngle = [this, in_data](const std::vector<TurnCandidate> &turn_candidates)
|
||||||
[in_data, &node_based_graph](const std::vector<TurnCandidate> &turn_candidates)
|
|
||||||
{
|
{
|
||||||
for (const auto &candidate : turn_candidates)
|
for (const auto &candidate : turn_candidates)
|
||||||
{
|
{
|
||||||
const auto &out_data = node_based_graph.GetEdgeData(candidate.eid);
|
const auto &out_data = node_based_graph.GetEdgeData(candidate.eid);
|
||||||
if (candidate.angle != 0 && in_data.name_id == out_data.name_id &&
|
if (candidate.angle != 0 && in_data.name_id == out_data.name_id &&
|
||||||
in_data.name_id != 0 && isMotorwayClass(out_data.road_classification.road_class))
|
in_data.name_id != 0 &&
|
||||||
|
detail::isMotorwayClass(out_data.road_classification.road_class))
|
||||||
return candidate.angle;
|
return candidate.angle;
|
||||||
}
|
}
|
||||||
return turn_candidates[0].angle;
|
return turn_candidates[0].angle;
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto getMostLikelyContinue =
|
const auto getMostLikelyContinue =
|
||||||
[in_data, &node_based_graph](const std::vector<TurnCandidate> &turn_candidates)
|
[this, in_data](const std::vector<TurnCandidate> &turn_candidates)
|
||||||
{
|
{
|
||||||
double angle = turn_candidates[0].angle;
|
double angle = turn_candidates[0].angle;
|
||||||
double best = 180;
|
double best = 180;
|
||||||
for (const auto &candidate : turn_candidates)
|
for (const auto &candidate : turn_candidates)
|
||||||
{
|
{
|
||||||
const auto &out_data = node_based_graph.GetEdgeData(candidate.eid);
|
const auto &out_data = node_based_graph.GetEdgeData(candidate.eid);
|
||||||
if (isMotorwayClass(out_data.road_classification.road_class) &&
|
if (detail::isMotorwayClass(out_data.road_classification.road_class) &&
|
||||||
angularDeviation(candidate.angle, STRAIGHT_ANGLE) < best)
|
angularDeviation(candidate.angle, STRAIGHT_ANGLE) < best)
|
||||||
{
|
{
|
||||||
best = angularDeviation(candidate.angle, STRAIGHT_ANGLE);
|
best = angularDeviation(candidate.angle, STRAIGHT_ANGLE);
|
||||||
@ -388,7 +380,7 @@ std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
|||||||
// splitting ramp at the end of a highway
|
// splitting ramp at the end of a highway
|
||||||
if (turn_candidates[1].valid && turn_candidates[2].valid)
|
if (turn_candidates[1].valid && turn_candidates[2].valid)
|
||||||
{
|
{
|
||||||
assignFork(via_edge, turn_candidates[2], turn_candidates[1], node_based_graph);
|
assignFork(via_edge, turn_candidates[2], turn_candidates[1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -410,7 +402,7 @@ std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
|||||||
<< toFloating(coord.lat) << " " << toFloating(coord.lon) << ", no continue angle, "
|
<< toFloating(coord.lat) << " " << toFloating(coord.lon) << ", no continue angle, "
|
||||||
<< turn_candidates.size() << " candidates, " << countValid(turn_candidates)
|
<< turn_candidates.size() << " candidates, " << countValid(turn_candidates)
|
||||||
<< " valid ones.";
|
<< " valid ones.";
|
||||||
fallbackTurnAssignmentMotorway(turn_candidates, node_based_graph);
|
fallbackTurnAssignmentMotorway(turn_candidates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -424,7 +416,7 @@ std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
|||||||
{
|
{
|
||||||
if (candidate.valid)
|
if (candidate.valid)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(isRampClass(candidate.eid, node_based_graph));
|
BOOST_ASSERT(detail::isRampClass(candidate.eid, node_based_graph));
|
||||||
candidate.instruction =
|
candidate.instruction =
|
||||||
TurnInstruction::SUPPRESSED(getTurnDirection(candidate.angle));
|
TurnInstruction::SUPPRESSED(getTurnDirection(candidate.angle));
|
||||||
}
|
}
|
||||||
@ -435,10 +427,10 @@ std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
|||||||
// normal motorway passing some ramps or mering onto another motorway
|
// normal motorway passing some ramps or mering onto another motorway
|
||||||
if (turn_candidates.size() == 2)
|
if (turn_candidates.size() == 2)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!isRampClass(turn_candidates[1].eid, node_based_graph));
|
BOOST_ASSERT(!detail::isRampClass(turn_candidates[1].eid, node_based_graph));
|
||||||
|
|
||||||
turn_candidates[1].instruction = getInstructionForObvious(
|
turn_candidates[1].instruction =
|
||||||
turn_candidates.size(), via_edge, turn_candidates[1], node_based_graph);
|
getInstructionForObvious(turn_candidates.size(), via_edge, turn_candidates[1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -462,7 +454,7 @@ std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
|||||||
else if (candidate.angle < continue_angle)
|
else if (candidate.angle < continue_angle)
|
||||||
{
|
{
|
||||||
candidate.instruction = {
|
candidate.instruction = {
|
||||||
isRampClass(candidate.eid, node_based_graph) ? TurnType::Ramp
|
detail::isRampClass(candidate.eid, node_based_graph) ? TurnType::Ramp
|
||||||
: TurnType::Turn,
|
: TurnType::Turn,
|
||||||
(candidate.angle < 145) ? DirectionModifier::Right
|
(candidate.angle < 145) ? DirectionModifier::Right
|
||||||
: DirectionModifier::SlightRight};
|
: DirectionModifier::SlightRight};
|
||||||
@ -470,7 +462,7 @@ std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
|||||||
else if (candidate.angle > continue_angle)
|
else if (candidate.angle > continue_angle)
|
||||||
{
|
{
|
||||||
candidate.instruction = {
|
candidate.instruction = {
|
||||||
isRampClass(candidate.eid, node_based_graph) ? TurnType::Ramp
|
detail::isRampClass(candidate.eid, node_based_graph) ? TurnType::Ramp
|
||||||
: TurnType::Turn,
|
: TurnType::Turn,
|
||||||
(candidate.angle > 215) ? DirectionModifier::Left
|
(candidate.angle > 215) ? DirectionModifier::Left
|
||||||
: DirectionModifier::SlightLeft};
|
: DirectionModifier::SlightLeft};
|
||||||
@ -483,8 +475,8 @@ std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
|||||||
{
|
{
|
||||||
if (exiting_motorways == 2 && turn_candidates.size() == 2)
|
if (exiting_motorways == 2 && turn_candidates.size() == 2)
|
||||||
{
|
{
|
||||||
turn_candidates[1].instruction = getInstructionForObvious(
|
turn_candidates[1].instruction =
|
||||||
turn_candidates.size(), via_edge, turn_candidates[1], node_based_graph);
|
getInstructionForObvious(turn_candidates.size(), via_edge, turn_candidates[1]);
|
||||||
util::SimpleLogger().Write(logWARNING)
|
util::SimpleLogger().Write(logWARNING)
|
||||||
<< "Disabled U-Turn on a freeway at "
|
<< "Disabled U-Turn on a freeway at "
|
||||||
<< localizer(node_based_graph.GetTarget(via_edge));
|
<< localizer(node_based_graph.GetTarget(via_edge));
|
||||||
@ -498,7 +490,7 @@ std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
|||||||
for (std::size_t i = 0; i < turn_candidates.size(); ++i)
|
for (std::size_t i = 0; i < turn_candidates.size(); ++i)
|
||||||
{
|
{
|
||||||
if (turn_candidates[i].valid &&
|
if (turn_candidates[i].valid &&
|
||||||
isMotorwayClass(turn_candidates[i].eid, node_based_graph))
|
detail::isMotorwayClass(turn_candidates[i].eid, node_based_graph))
|
||||||
{
|
{
|
||||||
if (first_valid < turn_candidates.size())
|
if (first_valid < turn_candidates.size())
|
||||||
{
|
{
|
||||||
@ -511,8 +503,7 @@ std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assignFork(via_edge, turn_candidates[second_valid], turn_candidates[first_valid],
|
assignFork(via_edge, turn_candidates[second_valid], turn_candidates[first_valid]);
|
||||||
node_based_graph);
|
|
||||||
}
|
}
|
||||||
else if (exiting_motorways == 3)
|
else if (exiting_motorways == 3)
|
||||||
{
|
{
|
||||||
@ -523,7 +514,7 @@ std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
|||||||
for (std::size_t i = 0; i < turn_candidates.size(); ++i)
|
for (std::size_t i = 0; i < turn_candidates.size(); ++i)
|
||||||
{
|
{
|
||||||
if (turn_candidates[i].valid &&
|
if (turn_candidates[i].valid &&
|
||||||
isMotorwayClass(turn_candidates[i].eid, node_based_graph))
|
detail::isMotorwayClass(turn_candidates[i].eid, node_based_graph))
|
||||||
{
|
{
|
||||||
if (second_valid < turn_candidates.size())
|
if (second_valid < turn_candidates.size())
|
||||||
{
|
{
|
||||||
@ -541,7 +532,7 @@ std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
assignFork(via_edge, turn_candidates[third_valid], turn_candidates[second_valid],
|
assignFork(via_edge, turn_candidates[third_valid], turn_candidates[second_valid],
|
||||||
turn_candidates[first_valid], node_based_graph);
|
turn_candidates[first_valid]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -550,7 +541,7 @@ std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
|||||||
<< "Found motorway junction with more than "
|
<< "Found motorway junction with more than "
|
||||||
"2 exiting motorways or additional ramps at " << std::setprecision(12)
|
"2 exiting motorways or additional ramps at " << std::setprecision(12)
|
||||||
<< toFloating(coord.lat) << " " << toFloating(coord.lon);
|
<< toFloating(coord.lat) << " " << toFloating(coord.lon);
|
||||||
fallbackTurnAssignmentMotorway(turn_candidates, node_based_graph);
|
fallbackTurnAssignmentMotorway(turn_candidates);
|
||||||
}
|
}
|
||||||
} // done for more than one highway exit
|
} // done for more than one highway exit
|
||||||
}
|
}
|
||||||
@ -565,10 +556,8 @@ std::vector<TurnCandidate> handleFromMotorway(const NodeID from,
|
|||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate> handleMotorwayRamp(const NodeID from,
|
std::vector<TurnCandidate> TurnAnalysis::handleMotorwayRamp(
|
||||||
const EdgeID via_edge,
|
const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
(void)from;
|
(void)from;
|
||||||
auto num_valid_turns = countValid(turn_candidates);
|
auto num_valid_turns = countValid(turn_candidates);
|
||||||
@ -576,10 +565,10 @@ std::vector<TurnCandidate> handleMotorwayRamp(const NodeID from,
|
|||||||
if (turn_candidates.size() == 2 && num_valid_turns == 1)
|
if (turn_candidates.size() == 2 && num_valid_turns == 1)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(!turn_candidates[0].valid);
|
BOOST_ASSERT(!turn_candidates[0].valid);
|
||||||
BOOST_ASSERT(isMotorwayClass(turn_candidates[1].eid, node_based_graph));
|
BOOST_ASSERT(detail::isMotorwayClass(turn_candidates[1].eid, node_based_graph));
|
||||||
|
|
||||||
turn_candidates[1].instruction = getInstructionForObvious(
|
turn_candidates[1].instruction =
|
||||||
turn_candidates.size(), via_edge, turn_candidates[1], node_based_graph);
|
getInstructionForObvious(turn_candidates.size(), via_edge, turn_candidates[1]);
|
||||||
}
|
}
|
||||||
else if (turn_candidates.size() == 3)
|
else if (turn_candidates.size() == 3)
|
||||||
{
|
{
|
||||||
@ -597,7 +586,7 @@ std::vector<TurnCandidate> handleMotorwayRamp(const NodeID from,
|
|||||||
// 0
|
// 0
|
||||||
if (turn_candidates[1].valid)
|
if (turn_candidates[1].valid)
|
||||||
{
|
{
|
||||||
if (isMotorwayClass(turn_candidates[1].eid, node_based_graph))
|
if (detail::isMotorwayClass(turn_candidates[1].eid, node_based_graph))
|
||||||
{
|
{
|
||||||
// circular order indicates a merge to the left (0-3 onto 4
|
// circular order indicates a merge to the left (0-3 onto 4
|
||||||
if (angularDeviation(turn_candidates[1].angle, STRAIGHT_ANGLE) <
|
if (angularDeviation(turn_candidates[1].angle, STRAIGHT_ANGLE) <
|
||||||
@ -610,12 +599,12 @@ std::vector<TurnCandidate> handleMotorwayRamp(const NodeID from,
|
|||||||
}
|
}
|
||||||
else // passing by the end of a motorway
|
else // passing by the end of a motorway
|
||||||
turn_candidates[1].instruction = getInstructionForObvious(
|
turn_candidates[1].instruction = getInstructionForObvious(
|
||||||
turn_candidates.size(), via_edge, turn_candidates[1], node_based_graph);
|
turn_candidates.size(), via_edge, turn_candidates[1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(turn_candidates[2].valid);
|
BOOST_ASSERT(turn_candidates[2].valid);
|
||||||
if (isMotorwayClass(turn_candidates[2].eid, node_based_graph))
|
if (detail::isMotorwayClass(turn_candidates[2].eid, node_based_graph))
|
||||||
{
|
{
|
||||||
// circular order (5-0) onto 4
|
// circular order (5-0) onto 4
|
||||||
if (angularDeviation(turn_candidates[2].angle, STRAIGHT_ANGLE) <
|
if (angularDeviation(turn_candidates[2].angle, STRAIGHT_ANGLE) <
|
||||||
@ -628,7 +617,7 @@ std::vector<TurnCandidate> handleMotorwayRamp(const NodeID from,
|
|||||||
}
|
}
|
||||||
else // passing the end of a highway
|
else // passing the end of a highway
|
||||||
turn_candidates[1].instruction = getInstructionForObvious(
|
turn_candidates[1].instruction = getInstructionForObvious(
|
||||||
turn_candidates.size(), via_edge, turn_candidates[1], node_based_graph);
|
turn_candidates.size(), via_edge, turn_candidates[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -643,10 +632,10 @@ std::vector<TurnCandidate> handleMotorwayRamp(const NodeID from,
|
|||||||
// \ /
|
// \ /
|
||||||
// |
|
// |
|
||||||
// R
|
// R
|
||||||
if (isMotorwayClass(turn_candidates[1].eid, node_based_graph) &&
|
if (detail::isMotorwayClass(turn_candidates[1].eid, node_based_graph) &&
|
||||||
isMotorwayClass(turn_candidates[2].eid, node_based_graph))
|
detail::isMotorwayClass(turn_candidates[2].eid, node_based_graph))
|
||||||
{
|
{
|
||||||
assignFork(via_edge, turn_candidates[2], turn_candidates[1], node_based_graph);
|
assignFork(via_edge, turn_candidates[2], turn_candidates[1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -655,7 +644,7 @@ std::vector<TurnCandidate> handleMotorwayRamp(const NodeID from,
|
|||||||
// M R
|
// M R
|
||||||
// | /
|
// | /
|
||||||
// R
|
// R
|
||||||
if (isMotorwayClass(node_based_graph.GetEdgeData(turn_candidates[1].eid)
|
if (detail::isMotorwayClass(node_based_graph.GetEdgeData(turn_candidates[1].eid)
|
||||||
.road_classification.road_class))
|
.road_classification.road_class))
|
||||||
{
|
{
|
||||||
turn_candidates[1].instruction = {TurnType::Merge,
|
turn_candidates[1].instruction = {TurnType::Merge,
|
||||||
@ -680,11 +669,12 @@ std::vector<TurnCandidate> handleMotorwayRamp(const NodeID from,
|
|||||||
for (auto &candidate : turn_candidates)
|
for (auto &candidate : turn_candidates)
|
||||||
{
|
{
|
||||||
const auto &edge_data = node_based_graph.GetEdgeData(candidate.eid);
|
const auto &edge_data = node_based_graph.GetEdgeData(candidate.eid);
|
||||||
if (!candidate.valid && isMotorwayClass(edge_data.road_classification.road_class))
|
if (!candidate.valid &&
|
||||||
|
detail::isMotorwayClass(edge_data.road_classification.road_class))
|
||||||
{
|
{
|
||||||
passed_highway_entry = true;
|
passed_highway_entry = true;
|
||||||
}
|
}
|
||||||
else if (isMotorwayClass(edge_data.road_classification.road_class))
|
else if (detail::isMotorwayClass(edge_data.road_classification.road_class))
|
||||||
{
|
{
|
||||||
candidate.instruction = {TurnType::Merge,
|
candidate.instruction = {TurnType::Merge,
|
||||||
passed_highway_entry ? DirectionModifier::SlightRight
|
passed_highway_entry ? DirectionModifier::SlightRight
|
||||||
@ -702,7 +692,7 @@ std::vector<TurnCandidate> handleMotorwayRamp(const NodeID from,
|
|||||||
util::SimpleLogger().Write(logWARNING) << "Reached fallback on motorway ramp with "
|
util::SimpleLogger().Write(logWARNING) << "Reached fallback on motorway ramp with "
|
||||||
<< turn_candidates.size() << " candidates and "
|
<< turn_candidates.size() << " candidates and "
|
||||||
<< countValid(turn_candidates) << " valid turns.";
|
<< countValid(turn_candidates) << " valid turns.";
|
||||||
fallbackTurnAssignmentMotorway(turn_candidates, node_based_graph);
|
fallbackTurnAssignmentMotorway(turn_candidates);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PRINT_DEBUG_CANDIDATES
|
#if PRINT_DEBUG_CANDIDATES
|
||||||
@ -715,11 +705,8 @@ std::vector<TurnCandidate> handleMotorwayRamp(const NodeID from,
|
|||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate>
|
std::vector<TurnCandidate> TurnAnalysis::handleMotorwayJunction(
|
||||||
handleMotorwayJunction(const NodeID from,
|
const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const
|
||||||
const EdgeID via_edge,
|
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
(void)from;
|
(void)from;
|
||||||
// BOOST_ASSERT(!turn_candidates[0].valid); //This fails due to @themarex handling of dead end
|
// BOOST_ASSERT(!turn_candidates[0].valid); //This fails due to @themarex handling of dead end
|
||||||
@ -727,21 +714,20 @@ handleMotorwayJunction(const NodeID from,
|
|||||||
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
|
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
|
||||||
|
|
||||||
// coming from motorway
|
// coming from motorway
|
||||||
if (isMotorwayClass(in_data.road_classification.road_class))
|
if (detail::isMotorwayClass(in_data.road_classification.road_class))
|
||||||
{
|
{
|
||||||
return handleFromMotorway(from, via_edge, std::move(turn_candidates), node_based_graph);
|
return handleFromMotorway(from, via_edge, std::move(turn_candidates));
|
||||||
}
|
}
|
||||||
else // coming from a ramp
|
else // coming from a ramp
|
||||||
{
|
{
|
||||||
return handleMotorwayRamp(from, via_edge, std::move(turn_candidates), node_based_graph);
|
return handleMotorwayRamp(from, via_edge, std::move(turn_candidates));
|
||||||
// ramp merging straight onto motorway
|
// ramp merging straight onto motorway
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isMotorwayJunction(const NodeID from,
|
bool TurnAnalysis::isMotorwayJunction(const NodeID from,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
const std::vector<TurnCandidate> &turn_candidates,
|
const std::vector<TurnCandidate> &turn_candidates) const
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
(void)from;
|
(void)from;
|
||||||
|
|
||||||
@ -775,9 +761,8 @@ bool isMotorwayJunction(const NodeID from,
|
|||||||
in_data.road_classification.road_class == FunctionalRoadClass::TRUNK;
|
in_data.road_classification.road_class == FunctionalRoadClass::TRUNK;
|
||||||
}
|
}
|
||||||
|
|
||||||
TurnType findBasicTurnType(const EdgeID via_edge,
|
TurnType TurnAnalysis::findBasicTurnType(const EdgeID via_edge,
|
||||||
const TurnCandidate &candidate,
|
const TurnCandidate &candidate) const
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
|
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
|
||||||
@ -798,12 +783,11 @@ TurnType findBasicTurnType(const EdgeID via_edge,
|
|||||||
return TurnType::Turn;
|
return TurnType::Turn;
|
||||||
}
|
}
|
||||||
|
|
||||||
TurnInstruction getInstructionForObvious(const std::size_t num_candidates,
|
TurnInstruction TurnAnalysis::getInstructionForObvious(const std::size_t num_candidates,
|
||||||
const EdgeID via_edge,
|
const EdgeID via_edge,
|
||||||
const TurnCandidate &candidate,
|
const TurnCandidate &candidate) const
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
const auto type = findBasicTurnType(via_edge, candidate, node_based_graph);
|
const auto type = findBasicTurnType(via_edge, candidate);
|
||||||
if (type == TurnType::Ramp)
|
if (type == TurnType::Ramp)
|
||||||
{
|
{
|
||||||
return {TurnType::Ramp, getTurnDirection(candidate.angle)};
|
return {TurnType::Ramp, getTurnDirection(candidate.angle)};
|
||||||
@ -828,13 +812,11 @@ TurnInstruction getInstructionForObvious(const std::size_t num_candidates,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate> handleOneWayTurn(const NodeID from,
|
std::vector<TurnCandidate> TurnAnalysis::handleOneWayTurn(
|
||||||
const EdgeID via_edge,
|
const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(turn_candidates[0].angle < 0.001);
|
BOOST_ASSERT(turn_candidates[0].angle < 0.001);
|
||||||
(void)from, (void)via_edge, (void)node_based_graph;
|
(void)from, (void)via_edge;
|
||||||
if (!turn_candidates[0].valid)
|
if (!turn_candidates[0].valid)
|
||||||
{
|
{
|
||||||
util::SimpleLogger().Write(logWARNING)
|
util::SimpleLogger().Write(logWARNING)
|
||||||
@ -851,15 +833,13 @@ std::vector<TurnCandidate> handleOneWayTurn(const NodeID from,
|
|||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate> handleTwoWayTurn(const NodeID from,
|
std::vector<TurnCandidate> TurnAnalysis::handleTwoWayTurn(
|
||||||
const EdgeID via_edge,
|
const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(turn_candidates[0].angle < 0.001);
|
BOOST_ASSERT(turn_candidates[0].angle < 0.001);
|
||||||
(void)from;
|
(void)from;
|
||||||
turn_candidates[1].instruction = getInstructionForObvious(turn_candidates.size(), via_edge,
|
turn_candidates[1].instruction =
|
||||||
turn_candidates[1], node_based_graph);
|
getInstructionForObvious(turn_candidates.size(), via_edge, turn_candidates[1]);
|
||||||
|
|
||||||
if (turn_candidates[1].instruction.type == TurnType::Suppressed)
|
if (turn_candidates[1].instruction.type == TurnType::Suppressed)
|
||||||
turn_candidates[1].instruction.type = TurnType::NoTurn;
|
turn_candidates[1].instruction.type = TurnType::NoTurn;
|
||||||
@ -874,10 +854,8 @@ std::vector<TurnCandidate> handleTwoWayTurn(const NodeID from,
|
|||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate> handleThreeWayTurn(const NodeID from,
|
std::vector<TurnCandidate> TurnAnalysis::handleThreeWayTurn(
|
||||||
const EdgeID via_edge,
|
const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(turn_candidates[0].angle < 0.001);
|
BOOST_ASSERT(turn_candidates[0].angle < 0.001);
|
||||||
(void)from;
|
(void)from;
|
||||||
@ -901,16 +879,16 @@ std::vector<TurnCandidate> handleThreeWayTurn(const NodeID from,
|
|||||||
{
|
{
|
||||||
if (turn_candidates[1].valid && turn_candidates[2].valid)
|
if (turn_candidates[1].valid && turn_candidates[2].valid)
|
||||||
{
|
{
|
||||||
assignFork(via_edge, turn_candidates[2], turn_candidates[1], node_based_graph);
|
assignFork(via_edge, turn_candidates[2], turn_candidates[1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (turn_candidates[1].valid)
|
if (turn_candidates[1].valid)
|
||||||
turn_candidates[1].instruction = getInstructionForObvious(
|
turn_candidates[1].instruction =
|
||||||
turn_candidates.size(), via_edge, turn_candidates[1], node_based_graph);
|
getInstructionForObvious(turn_candidates.size(), via_edge, turn_candidates[1]);
|
||||||
if (turn_candidates[2].valid)
|
if (turn_candidates[2].valid)
|
||||||
turn_candidates[2].instruction = getInstructionForObvious(
|
turn_candidates[2].instruction =
|
||||||
turn_candidates.size(), via_edge, turn_candidates[2], node_based_graph);
|
getInstructionForObvious(turn_candidates.size(), via_edge, turn_candidates[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* T Intersection
|
/* T Intersection
|
||||||
@ -927,14 +905,15 @@ std::vector<TurnCandidate> handleThreeWayTurn(const NodeID from,
|
|||||||
{
|
{
|
||||||
if (turn_candidates[1].valid)
|
if (turn_candidates[1].valid)
|
||||||
{
|
{
|
||||||
if (TurnType::Ramp != findBasicTurnType(via_edge, turn_candidates[1], node_based_graph))
|
if (TurnType::Ramp != findBasicTurnType(via_edge, turn_candidates[1]))
|
||||||
turn_candidates[1].instruction = {TurnType::EndOfRoad, DirectionModifier::Right};
|
turn_candidates[1].instruction = {TurnType::EndOfRoad, DirectionModifier::Right};
|
||||||
else
|
else
|
||||||
turn_candidates[1].instruction = {TurnType::Ramp, DirectionModifier::Right};
|
turn_candidates[1].instruction = {TurnType::Ramp, DirectionModifier::Right};
|
||||||
}
|
}
|
||||||
if (turn_candidates[2].valid)
|
if (turn_candidates[2].valid)
|
||||||
{
|
{
|
||||||
if (TurnType::Ramp != findBasicTurnType(via_edge, turn_candidates[2], node_based_graph))
|
if (TurnType::Ramp != findBasicTurnType(via_edge, turn_candidates[2]))
|
||||||
|
|
||||||
turn_candidates[2].instruction = {TurnType::EndOfRoad, DirectionModifier::Left};
|
turn_candidates[2].instruction = {TurnType::EndOfRoad, DirectionModifier::Left};
|
||||||
else
|
else
|
||||||
turn_candidates[2].instruction = {TurnType::Ramp, DirectionModifier::Left};
|
turn_candidates[2].instruction = {TurnType::Ramp, DirectionModifier::Left};
|
||||||
@ -953,16 +932,15 @@ std::vector<TurnCandidate> handleThreeWayTurn(const NodeID from,
|
|||||||
{
|
{
|
||||||
if (turn_candidates[1].valid)
|
if (turn_candidates[1].valid)
|
||||||
{
|
{
|
||||||
if (TurnType::Ramp != findBasicTurnType(via_edge, turn_candidates[1], node_based_graph))
|
if (TurnType::Ramp != findBasicTurnType(via_edge, turn_candidates[1]))
|
||||||
turn_candidates[1].instruction = getInstructionForObvious(
|
turn_candidates[1].instruction =
|
||||||
turn_candidates.size(), via_edge, turn_candidates[1], node_based_graph);
|
getInstructionForObvious(turn_candidates.size(), via_edge, turn_candidates[1]);
|
||||||
else
|
else
|
||||||
turn_candidates[1].instruction = {TurnType::Ramp, DirectionModifier::Straight};
|
turn_candidates[1].instruction = {TurnType::Ramp, DirectionModifier::Straight};
|
||||||
}
|
}
|
||||||
if (turn_candidates[2].valid)
|
if (turn_candidates[2].valid)
|
||||||
{
|
{
|
||||||
turn_candidates[2].instruction = {
|
turn_candidates[2].instruction = {findBasicTurnType(via_edge, turn_candidates[2]),
|
||||||
findBasicTurnType(via_edge, turn_candidates[2], node_based_graph),
|
|
||||||
DirectionModifier::Left};
|
DirectionModifier::Left};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -979,11 +957,10 @@ std::vector<TurnCandidate> handleThreeWayTurn(const NodeID from,
|
|||||||
NARROW_TURN_ANGLE)
|
NARROW_TURN_ANGLE)
|
||||||
{
|
{
|
||||||
if (turn_candidates[2].valid)
|
if (turn_candidates[2].valid)
|
||||||
turn_candidates[2].instruction = getInstructionForObvious(
|
turn_candidates[2].instruction =
|
||||||
turn_candidates.size(), via_edge, turn_candidates[2], node_based_graph);
|
getInstructionForObvious(turn_candidates.size(), via_edge, turn_candidates[2]);
|
||||||
if (turn_candidates[1].valid)
|
if (turn_candidates[1].valid)
|
||||||
turn_candidates[1].instruction = {
|
turn_candidates[1].instruction = {findBasicTurnType(via_edge, turn_candidates[1]),
|
||||||
findBasicTurnType(via_edge, turn_candidates[1], node_based_graph),
|
|
||||||
DirectionModifier::Right};
|
DirectionModifier::Right};
|
||||||
}
|
}
|
||||||
// merge onto a through street
|
// merge onto a through street
|
||||||
@ -1086,10 +1063,8 @@ std::vector<TurnCandidate> handleThreeWayTurn(const NodeID from,
|
|||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate> handleFourWayTurn(const NodeID from,
|
std::vector<TurnCandidate> TurnAnalysis::handleFourWayTurn(
|
||||||
const EdgeID via_edge,
|
const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
(void)from;
|
(void)from;
|
||||||
static int fallback_count = 0;
|
static int fallback_count = 0;
|
||||||
@ -1101,15 +1076,15 @@ std::vector<TurnCandidate> handleFourWayTurn(const NodeID from,
|
|||||||
angularDeviation(turn_candidates[3].angle, turn_candidates[0].angle) > NARROW_TURN_ANGLE)
|
angularDeviation(turn_candidates[3].angle, turn_candidates[0].angle) > NARROW_TURN_ANGLE)
|
||||||
{
|
{
|
||||||
{ // Right
|
{ // Right
|
||||||
const auto type = findBasicTurnType(via_edge, turn_candidates[1], node_based_graph);
|
const auto type = findBasicTurnType(via_edge, turn_candidates[1]);
|
||||||
turn_candidates[1].instruction = {type, DirectionModifier::Right};
|
turn_candidates[1].instruction = {type, DirectionModifier::Right};
|
||||||
}
|
}
|
||||||
{ // Straight
|
{ // Straight
|
||||||
turn_candidates[2].instruction = getInstructionForObvious(
|
turn_candidates[2].instruction =
|
||||||
turn_candidates.size(), via_edge, turn_candidates[2], node_based_graph);
|
getInstructionForObvious(turn_candidates.size(), via_edge, turn_candidates[2]);
|
||||||
}
|
}
|
||||||
{ // Left
|
{ // Left
|
||||||
const auto type = findBasicTurnType(via_edge, turn_candidates[3], node_based_graph);
|
const auto type = findBasicTurnType(via_edge, turn_candidates[3]);
|
||||||
turn_candidates[3].instruction = {type, DirectionModifier::Left};
|
turn_candidates[3].instruction = {type, DirectionModifier::Left};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1121,7 +1096,7 @@ std::vector<TurnCandidate> handleFourWayTurn(const NodeID from,
|
|||||||
{
|
{
|
||||||
for (std::size_t i = 1; i < turn_candidates.size(); ++i)
|
for (std::size_t i = 1; i < turn_candidates.size(); ++i)
|
||||||
{
|
{
|
||||||
const auto type = findBasicTurnType(via_edge, turn_candidates[i], node_based_graph);
|
const auto type = findBasicTurnType(via_edge, turn_candidates[i]);
|
||||||
turn_candidates[i].instruction = {type, getTurnDirection(turn_candidates[i].angle)};
|
turn_candidates[i].instruction = {type, getTurnDirection(turn_candidates[i].angle)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1177,10 +1152,8 @@ std::vector<TurnCandidate> handleFourWayTurn(const NodeID from,
|
|||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate> handleComplexTurn(const NodeID from,
|
std::vector<TurnCandidate> TurnAnalysis::handleComplexTurn(
|
||||||
const EdgeID via_edge,
|
const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
(void)from; // FIXME unused
|
(void)from; // FIXME unused
|
||||||
(void)via_edge; // FIXME unused
|
(void)via_edge; // FIXME unused
|
||||||
@ -1195,10 +1168,8 @@ std::vector<TurnCandidate> handleComplexTurn(const NodeID from,
|
|||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate> setTurnTypes(const NodeID from,
|
std::vector<TurnCandidate> TurnAnalysis::setTurnTypes(
|
||||||
const EdgeID via_edge,
|
const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
NodeID turn_node = node_based_graph.GetTarget(via_edge);
|
NodeID turn_node = node_based_graph.GetTarget(via_edge);
|
||||||
|
|
||||||
@ -1209,8 +1180,7 @@ std::vector<TurnCandidate> setTurnTypes(const NodeID from,
|
|||||||
const EdgeID onto_edge = candidate.eid;
|
const EdgeID onto_edge = candidate.eid;
|
||||||
const NodeID to_node = node_based_graph.GetTarget(onto_edge);
|
const NodeID to_node = node_based_graph.GetTarget(onto_edge);
|
||||||
|
|
||||||
auto turn = AnalyzeTurn(from, via_edge, turn_node, onto_edge, to_node, candidate.angle,
|
auto turn = AnalyzeTurn(from, via_edge, turn_node, onto_edge, to_node, candidate.angle);
|
||||||
node_based_graph);
|
|
||||||
|
|
||||||
auto confidence = getTurnConfidence(candidate.angle, turn);
|
auto confidence = getTurnConfidence(candidate.angle, turn);
|
||||||
candidate.instruction = turn;
|
candidate.instruction = turn;
|
||||||
@ -1219,9 +1189,8 @@ std::vector<TurnCandidate> setTurnTypes(const NodeID from,
|
|||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate> optimizeRamps(const EdgeID via_edge,
|
std::vector<TurnCandidate>
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
TurnAnalysis::optimizeRamps(const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
EdgeID continue_eid = SPECIAL_EDGEID;
|
EdgeID continue_eid = SPECIAL_EDGEID;
|
||||||
double continue_angle = 0;
|
double continue_angle = 0;
|
||||||
@ -1266,10 +1235,9 @@ std::vector<TurnCandidate> optimizeRamps(const EdgeID via_edge,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// requires sorted candidates
|
// requires sorted candidates
|
||||||
std::vector<TurnCandidate> optimizeCandidates(const EdgeID via_eid,
|
std::vector<TurnCandidate>
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
TurnAnalysis::optimizeCandidates(const EdgeID via_eid,
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
std::vector<TurnCandidate> turn_candidates) const
|
||||||
const std::vector<QueryNode> &node_info_list)
|
|
||||||
{
|
{
|
||||||
BOOST_ASSERT_MSG(std::is_sorted(turn_candidates.begin(), turn_candidates.end(),
|
BOOST_ASSERT_MSG(std::is_sorted(turn_candidates.begin(), turn_candidates.end(),
|
||||||
[](const TurnCandidate &left, const TurnCandidate &right)
|
[](const TurnCandidate &left, const TurnCandidate &right)
|
||||||
@ -1280,7 +1248,7 @@ std::vector<TurnCandidate> optimizeCandidates(const EdgeID via_eid,
|
|||||||
if (turn_candidates.size() <= 1)
|
if (turn_candidates.size() <= 1)
|
||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
|
|
||||||
turn_candidates = optimizeRamps(via_eid, std::move(turn_candidates), node_based_graph);
|
turn_candidates = optimizeRamps(via_eid, std::move(turn_candidates));
|
||||||
|
|
||||||
const auto getLeft = [&turn_candidates](std::size_t index)
|
const auto getLeft = [&turn_candidates](std::size_t index)
|
||||||
{
|
{
|
||||||
@ -1466,10 +1434,9 @@ std::vector<TurnCandidate> optimizeCandidates(const EdgeID via_eid,
|
|||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isObviousChoice(const EdgeID via_eid,
|
bool TurnAnalysis::isObviousChoice(const EdgeID via_eid,
|
||||||
const std::size_t turn_index,
|
const std::size_t turn_index,
|
||||||
const std::vector<TurnCandidate> &turn_candidates,
|
const std::vector<TurnCandidate> &turn_candidates) const
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
const auto getLeft = [&turn_candidates](std::size_t index)
|
const auto getLeft = [&turn_candidates](std::size_t index)
|
||||||
{
|
{
|
||||||
@ -1529,9 +1496,8 @@ bool isObviousChoice(const EdgeID via_eid,
|
|||||||
angularDeviation(candidate.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE / 2);
|
angularDeviation(candidate.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate> suppressTurns(const EdgeID via_eid,
|
std::vector<TurnCandidate>
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
TurnAnalysis::suppressTurns(const EdgeID via_eid, std::vector<TurnCandidate> turn_candidates) const
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
if (turn_candidates.size() == 3)
|
if (turn_candidates.size() == 3)
|
||||||
{
|
{
|
||||||
@ -1600,7 +1566,7 @@ std::vector<TurnCandidate> suppressTurns(const EdgeID via_eid,
|
|||||||
{
|
{
|
||||||
if (node_based_graph.GetEdgeData(turn_candidates[turn_index].eid).name_id ==
|
if (node_based_graph.GetEdgeData(turn_candidates[turn_index].eid).name_id ==
|
||||||
in_data.name_id &&
|
in_data.name_id &&
|
||||||
isObviousChoice(via_eid, turn_index, turn_candidates, node_based_graph))
|
isObviousChoice(via_eid, turn_index, turn_candidates))
|
||||||
{
|
{
|
||||||
has_obvious_with_same_name = true;
|
has_obvious_with_same_name = true;
|
||||||
obvious_with_same_name_angle = turn_candidates[turn_index].angle;
|
obvious_with_same_name_angle = turn_candidates[turn_index].angle;
|
||||||
@ -1641,7 +1607,7 @@ std::vector<TurnCandidate> suppressTurns(const EdgeID via_eid,
|
|||||||
if (in_data.travel_mode ==
|
if (in_data.travel_mode ==
|
||||||
out_data.travel_mode) // make sure to always announce mode changes
|
out_data.travel_mode) // make sure to always announce mode changes
|
||||||
{
|
{
|
||||||
if (isObviousChoice(via_eid, turn_index, turn_candidates, node_based_graph))
|
if (isObviousChoice(via_eid, turn_index, turn_candidates))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (in_data.name_id == out_data.name_id) // same road
|
if (in_data.name_id == out_data.name_id) // same road
|
||||||
@ -1685,14 +1651,8 @@ std::vector<TurnCandidate> suppressTurns(const EdgeID via_eid,
|
|||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate>
|
std::vector<TurnCandidate> TurnAnalysis::getTurnCandidates(const NodeID from_node,
|
||||||
getTurnCandidates(const NodeID from_node,
|
const EdgeID via_eid) const
|
||||||
const EdgeID via_eid,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
|
||||||
const std::vector<QueryNode> &node_info_list,
|
|
||||||
const RestrictionMap &restriction_map,
|
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
|
||||||
const CompressedEdgeContainer &compressed_edge_container)
|
|
||||||
{
|
{
|
||||||
std::vector<TurnCandidate> turn_candidates;
|
std::vector<TurnCandidate> turn_candidates;
|
||||||
const NodeID turn_node = node_based_graph.GetTarget(via_eid);
|
const NodeID turn_node = node_based_graph.GetTarget(via_eid);
|
||||||
@ -1780,13 +1740,11 @@ getTurnCandidates(const NodeID from_node,
|
|||||||
};
|
};
|
||||||
std::sort(std::begin(turn_candidates), std::end(turn_candidates), ByAngle);
|
std::sort(std::begin(turn_candidates), std::end(turn_candidates), ByAngle);
|
||||||
|
|
||||||
return mergeSegregatedRoads(from_node, via_eid, std::move(turn_candidates), node_based_graph);
|
return mergeSegregatedRoads(from_node, via_eid, std::move(turn_candidates));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate> mergeSegregatedRoads(const NodeID from_node,
|
std::vector<TurnCandidate> TurnAnalysis::mergeSegregatedRoads(
|
||||||
const EdgeID via_eid,
|
const NodeID from_node, const EdgeID via_eid, std::vector<TurnCandidate> turn_candidates) const
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
(void)from_node; // FIXME
|
(void)from_node; // FIXME
|
||||||
(void)via_eid; // FIXME
|
(void)via_eid; // FIXME
|
||||||
@ -1913,13 +1871,12 @@ std::vector<TurnCandidate> mergeSegregatedRoads(const NodeID from_node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// node_u -- (edge_1) --> node_v -- (edge_2) --> node_w
|
// node_u -- (edge_1) --> node_v -- (edge_2) --> node_w
|
||||||
TurnInstruction AnalyzeTurn(const NodeID node_u,
|
TurnInstruction TurnAnalysis::AnalyzeTurn(const NodeID node_u,
|
||||||
const EdgeID edge1,
|
const EdgeID edge1,
|
||||||
const NodeID node_v,
|
const NodeID node_v,
|
||||||
const EdgeID edge2,
|
const EdgeID edge2,
|
||||||
const NodeID node_w,
|
const NodeID node_w,
|
||||||
const double angle,
|
const double angle) const
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
(void)node_v;
|
(void)node_v;
|
||||||
const EdgeData &data1 = node_based_graph.GetEdgeData(edge1);
|
const EdgeData &data1 = node_based_graph.GetEdgeData(edge1);
|
||||||
@ -1940,14 +1897,11 @@ TurnInstruction AnalyzeTurn(const NodeID node_u,
|
|||||||
return {TurnType::Turn, getTurnDirection(angle)};
|
return {TurnType::Turn, getTurnDirection(angle)};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<TurnCandidate> handleConflicts(const NodeID from,
|
std::vector<TurnCandidate> TurnAnalysis::handleConflicts(
|
||||||
const EdgeID via_edge,
|
const NodeID from, const EdgeID via_edge, std::vector<TurnCandidate> turn_candidates) const
|
||||||
std::vector<TurnCandidate> turn_candidates,
|
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
(void)from; // FIXME
|
(void)from; // FIXME
|
||||||
(void)via_edge; // FIXME
|
(void)via_edge; // FIXME
|
||||||
(void)node_based_graph; // FIXME
|
|
||||||
const auto isConflict = [](const TurnCandidate &left, const TurnCandidate &right)
|
const auto isConflict = [](const TurnCandidate &left, const TurnCandidate &right)
|
||||||
{
|
{
|
||||||
// most obvious, same instructions conflict
|
// most obvious, same instructions conflict
|
||||||
@ -1968,10 +1922,9 @@ std::vector<TurnCandidate> handleConflicts(const NodeID from,
|
|||||||
return turn_candidates;
|
return turn_candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
void assignFork(const EdgeID via_edge,
|
void TurnAnalysis::assignFork(const EdgeID via_edge,
|
||||||
TurnCandidate &left,
|
TurnCandidate &left,
|
||||||
TurnCandidate &right,
|
TurnCandidate &right) const
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
|
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
|
||||||
const bool low_priority_left = isLowPriorityRoadClass(
|
const bool low_priority_left = isLowPriorityRoadClass(
|
||||||
@ -1986,8 +1939,7 @@ void assignFork(const EdgeID via_edge,
|
|||||||
if (requiresAnnouncement(in_data, out_data))
|
if (requiresAnnouncement(in_data, out_data))
|
||||||
{
|
{
|
||||||
if (low_priority_right && !low_priority_left)
|
if (low_priority_right && !low_priority_left)
|
||||||
left.instruction =
|
left.instruction = getInstructionForObvious(3, via_edge, left);
|
||||||
getInstructionForObvious(3, via_edge, left, node_based_graph);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (low_priority_left && !low_priority_right)
|
if (low_priority_left && !low_priority_right)
|
||||||
@ -2022,8 +1974,7 @@ void assignFork(const EdgeID via_edge,
|
|||||||
if (requiresAnnouncement(in_data, out_data))
|
if (requiresAnnouncement(in_data, out_data))
|
||||||
{
|
{
|
||||||
if (low_priority_left && !low_priority_right)
|
if (low_priority_left && !low_priority_right)
|
||||||
right.instruction =
|
right.instruction = getInstructionForObvious(3, via_edge, right);
|
||||||
getInstructionForObvious(3, via_edge, right, node_based_graph);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (low_priority_right && !low_priority_left)
|
if (low_priority_right && !low_priority_left)
|
||||||
@ -2052,11 +2003,10 @@ void assignFork(const EdgeID via_edge,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void assignFork(const EdgeID via_edge,
|
void TurnAnalysis::assignFork(const EdgeID via_edge,
|
||||||
TurnCandidate &left,
|
TurnCandidate &left,
|
||||||
TurnCandidate ¢er,
|
TurnCandidate ¢er,
|
||||||
TurnCandidate &right,
|
TurnCandidate &right) const
|
||||||
const util::NodeBasedDynamicGraph &node_based_graph)
|
|
||||||
{
|
{
|
||||||
left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
|
left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
|
||||||
if (angularDeviation(center.angle, 180) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION)
|
if (angularDeviation(center.angle, 180) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION)
|
||||||
@ -2079,7 +2029,6 @@ void assignFork(const EdgeID via_edge,
|
|||||||
right.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
|
right.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anemspace detail
|
|
||||||
} // namespace guidance
|
} // namespace guidance
|
||||||
} // namespace extractor
|
} // namespace extractor
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
Loading…
Reference in New Issue
Block a user