enter and exit roundabout feature - currently not showing turn
This commit is contained in:
committed by
Patrick Niklaus
parent
daf2bbf991
commit
d8af074ff6
@@ -85,7 +85,7 @@ std::string modeToString(const extractor::TravelMode mode)
|
||||
token = "river downstream";
|
||||
break;
|
||||
case TRAVEL_MODE_ROUTE:
|
||||
token = "rout";
|
||||
token = "route";
|
||||
break;
|
||||
default:
|
||||
token = "other";
|
||||
@@ -106,8 +106,8 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver)
|
||||
step_maneuver.values["location"] = detail::coordinateToLonLat(maneuver.location);
|
||||
step_maneuver.values["bearing_before"] = maneuver.bearing_before;
|
||||
step_maneuver.values["bearing_after"] = maneuver.bearing_after;
|
||||
if( maneuver.exit != 0 )
|
||||
step_maneuver.values["exit"] = maneuver.exit;
|
||||
if (maneuver.exit != 0)
|
||||
step_maneuver.values["exit"] = maneuver.exit;
|
||||
return step_maneuver;
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ util::json::Array makeRouteLegs(std::vector<guidance::RouteLeg> legs,
|
||||
|
||||
return json_legs;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace json
|
||||
} // namespace api
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
@@ -84,8 +84,8 @@ void print(const std::vector<std::vector<PathData>> &leg_data)
|
||||
|
||||
std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>> leg_data)
|
||||
{
|
||||
if( leg_data.empty() )
|
||||
return leg_data;
|
||||
if (leg_data.empty())
|
||||
return leg_data;
|
||||
|
||||
#define PRINT_DEBUG 0
|
||||
unsigned carry_exit = 0;
|
||||
@@ -98,19 +98,19 @@ std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>
|
||||
bool on_roundabout = false;
|
||||
for (auto &path_data : leg_data)
|
||||
{
|
||||
if( not path_data.empty() )
|
||||
path_data[0].exit = carry_exit;
|
||||
if (not path_data.empty())
|
||||
path_data[0].exit = carry_exit;
|
||||
|
||||
for (std::size_t data_index = 0; data_index + 1 < path_data.size(); ++data_index)
|
||||
{
|
||||
if (entersRoundabout(path_data[data_index].turn_instruction) )
|
||||
if (entersRoundabout(path_data[data_index].turn_instruction))
|
||||
{
|
||||
path_data[data_index].exit += 1;
|
||||
on_roundabout = true;
|
||||
}
|
||||
|
||||
if (isSilent(path_data[data_index].turn_instruction) &&
|
||||
path_data[data_index].turn_instruction != TurnInstruction::NO_TURN())
|
||||
path_data[data_index].turn_instruction != TurnInstruction::NO_TURN())
|
||||
{
|
||||
path_data[data_index].exit += 1;
|
||||
}
|
||||
@@ -118,7 +118,7 @@ std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>
|
||||
{
|
||||
if (!on_roundabout)
|
||||
{
|
||||
BOOST_ASSERT(leg_data[0][0].turn_instruction.type == TurnType::NO_TURN() );
|
||||
BOOST_ASSERT(leg_data[0][0].turn_instruction.type == TurnType::NO_TURN());
|
||||
if (path_data[data_index].turn_instruction.type == ExitRoundabout)
|
||||
leg_data[0][0].turn_instruction.type = TurnType::EnterRoundabout;
|
||||
if (path_data[data_index].turn_instruction.type == ExitRotary)
|
||||
@@ -160,15 +160,16 @@ std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>
|
||||
{
|
||||
if (entersRoundabout(path_data[data_index - 1].turn_instruction))
|
||||
{
|
||||
if( !on_roundabout )
|
||||
path_data[data_index-1].exit = 0;
|
||||
if (!on_roundabout && !leavesRoundabout(path_data[data_index - 1].turn_instruction))
|
||||
path_data[data_index - 1].exit = 0;
|
||||
on_roundabout = false;
|
||||
}
|
||||
if (on_roundabout)
|
||||
{
|
||||
path_data[data_index - 2].exit = path_data[data_index - 1].exit;
|
||||
}
|
||||
if (leavesRoundabout(path_data[data_index - 1].turn_instruction))
|
||||
if (leavesRoundabout(path_data[data_index - 1].turn_instruction) &&
|
||||
!entersRoundabout(path_data[data_index - 1].turn_instruction))
|
||||
{
|
||||
path_data[data_index - 2].exit = path_data[data_index - 1].exit;
|
||||
on_roundabout = true;
|
||||
@@ -191,7 +192,8 @@ std::vector<std::vector<PathData>> postProcess(std::vector<std::vector<PathData>
|
||||
{
|
||||
for (auto &data : path_data)
|
||||
{
|
||||
if (isSilent(data.turn_instruction) || leavesRoundabout(data.turn_instruction))
|
||||
if (isSilent(data.turn_instruction) || (leavesRoundabout(data.turn_instruction) &&
|
||||
!entersRoundabout(data.turn_instruction)))
|
||||
{
|
||||
data.turn_instruction = TurnInstruction::NO_TURN();
|
||||
data.exit = 0;
|
||||
|
||||
+122
-10
@@ -43,6 +43,7 @@ using engine::guidance::isSlightTurn;
|
||||
using engine::guidance::isSlightModifier;
|
||||
using engine::guidance::mirrorDirectionModifier;
|
||||
|
||||
#define PRINT_DEBUG_CANDIDATES 0
|
||||
std::vector<TurnCandidate>
|
||||
getTurns(const NodeID from,
|
||||
const EdgeID via_edge,
|
||||
@@ -52,12 +53,36 @@ getTurns(const NodeID from,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const CompressedEdgeContainer &compressed_edge_container)
|
||||
{
|
||||
auto turn_candidates = turn_analysis::getTurnCandidates(
|
||||
from, via_edge, node_based_graph, node_info_list, restriction_map, barrier_nodes,
|
||||
compressed_edge_container);
|
||||
auto turn_candidates =
|
||||
detail::getTurnCandidates(from, via_edge, node_based_graph, node_info_list, restriction_map,
|
||||
barrier_nodes, compressed_edge_container);
|
||||
|
||||
// main priority: roundabouts
|
||||
const auto &in_edge_data = node_based_graph->GetEdgeData(via_edge);
|
||||
bool on_roundabout = in_edge_data.roundabout;
|
||||
bool can_enter_roundabout = false;
|
||||
bool can_exit_roundabout = false;
|
||||
for (const auto &candidate : turn_candidates)
|
||||
{
|
||||
if (node_based_graph->GetEdgeData(candidate.eid).roundabout)
|
||||
{
|
||||
can_enter_roundabout = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
can_exit_roundabout = true;
|
||||
}
|
||||
}
|
||||
if (on_roundabout || can_enter_roundabout)
|
||||
{
|
||||
return detail::handleRoundabouts(from, via_edge, on_roundabout, can_enter_roundabout,
|
||||
can_exit_roundabout, std::move(turn_candidates),
|
||||
node_based_graph);
|
||||
}
|
||||
|
||||
turn_candidates =
|
||||
turn_analysis::setTurnTypes(from, via_edge, std::move(turn_candidates), node_based_graph);
|
||||
#define PRINT_DEBUG_CANDIDATES 0
|
||||
detail::setTurnTypes(from, via_edge, std::move(turn_candidates), node_based_graph);
|
||||
|
||||
#if PRINT_DEBUG_CANDIDATES
|
||||
std::cout << "Initial Candidates:\n";
|
||||
for (auto tc : turn_candidates)
|
||||
@@ -65,8 +90,8 @@ getTurns(const NodeID from,
|
||||
<< (int)node_based_graph->GetEdgeData(tc.eid).road_classification.road_class
|
||||
<< std::endl;
|
||||
#endif
|
||||
turn_candidates = turn_analysis::optimizeCandidates(via_edge, std::move(turn_candidates),
|
||||
node_based_graph, node_info_list);
|
||||
turn_candidates = detail::optimizeCandidates(via_edge, std::move(turn_candidates),
|
||||
node_based_graph, node_info_list);
|
||||
#if PRINT_DEBUG_CANDIDATES
|
||||
std::cout << "Optimized Candidates:\n";
|
||||
for (auto tc : turn_candidates)
|
||||
@@ -74,8 +99,7 @@ getTurns(const NodeID from,
|
||||
<< (int)node_based_graph->GetEdgeData(tc.eid).road_classification.road_class
|
||||
<< std::endl;
|
||||
#endif
|
||||
turn_candidates =
|
||||
turn_analysis::suppressTurns(via_edge, std::move(turn_candidates), node_based_graph);
|
||||
turn_candidates = detail::suppressTurns(via_edge, std::move(turn_candidates), node_based_graph);
|
||||
#if PRINT_DEBUG_CANDIDATES
|
||||
std::cout << "Suppressed Candidates:\n";
|
||||
for (auto tc : turn_candidates)
|
||||
@@ -86,6 +110,93 @@ getTurns(const NodeID from,
|
||||
return turn_candidates;
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
std::vector<TurnCandidate>
|
||||
handleRoundabouts(const NodeID from,
|
||||
const EdgeID via_edge,
|
||||
const bool on_roundabout,
|
||||
const bool can_enter_roundabout,
|
||||
const bool can_exit_roundabout,
|
||||
std::vector<TurnCandidate> turn_candidates,
|
||||
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph)
|
||||
{
|
||||
(void)from;
|
||||
// TODO requires differentiation between roundabouts and rotaries
|
||||
NodeID node_v = node_based_graph->GetTarget(via_edge);
|
||||
if (on_roundabout)
|
||||
{
|
||||
// Shoule hopefully have only a single exit and continue
|
||||
// at least for cars. How about bikes?
|
||||
for (auto &candidate : turn_candidates)
|
||||
{
|
||||
const auto &out_data = node_based_graph->GetEdgeData(candidate.eid);
|
||||
if (out_data.roundabout)
|
||||
{
|
||||
// TODO can forks happen in roundabouts? E.g. required lane changes
|
||||
if (1 == node_based_graph->GetDirectedOutDegree(node_v))
|
||||
{
|
||||
// No turn possible.
|
||||
candidate.instruction = TurnInstruction::NO_TURN();
|
||||
}
|
||||
else
|
||||
{
|
||||
candidate.instruction =
|
||||
TurnInstruction::REMAIN_ROUNDABOUT(getTurnDirection(candidate.angle));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
candidate.instruction =
|
||||
TurnInstruction::EXIT_ROUNDABOUT(getTurnDirection(candidate.angle));
|
||||
}
|
||||
}
|
||||
#if PRINT_DEBUG_CANDIDATES
|
||||
std::cout << "On Roundabout Candidates:\n";
|
||||
for (auto tc : turn_candidates)
|
||||
std::cout << "\t" << tc.toString() << " "
|
||||
<< (int)node_based_graph->GetEdgeData(tc.eid).road_classification.road_class
|
||||
<< std::endl;
|
||||
#endif
|
||||
return turn_candidates;
|
||||
}
|
||||
else
|
||||
{
|
||||
(void)can_enter_roundabout;
|
||||
BOOST_ASSERT(can_enter_roundabout);
|
||||
for (auto &candidate : turn_candidates)
|
||||
{
|
||||
const auto &out_data = node_based_graph->GetEdgeData(candidate.eid);
|
||||
if (out_data.roundabout)
|
||||
{
|
||||
candidate.instruction =
|
||||
TurnInstruction::ENTER_ROUNDABOUT(getTurnDirection(candidate.angle));
|
||||
if (can_exit_roundabout)
|
||||
{
|
||||
if (candidate.instruction.type == TurnType::EnterRotary)
|
||||
candidate.instruction.type = TurnType::EnterRotaryAtExit;
|
||||
if (candidate.instruction.type == TurnType::EnterRoundabout)
|
||||
candidate.instruction.type = TurnType::EnterRoundaboutAtExit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
candidate.instruction = {TurnType::EnterAndExitRoundabout,
|
||||
getTurnDirection(candidate.angle)};
|
||||
}
|
||||
}
|
||||
#if PRINT_DEBUG_CANDIDATES
|
||||
std::cout << "Into Roundabout Candidates:\n";
|
||||
for (auto tc : turn_candidates)
|
||||
std::cout << "\t" << tc.toString() << " "
|
||||
<< (int)node_based_graph->GetEdgeData(tc.eid).road_classification.road_class
|
||||
<< std::endl;
|
||||
#endif
|
||||
return turn_candidates;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<TurnCandidate>
|
||||
setTurnTypes(const NodeID from,
|
||||
const EdgeID via_edge,
|
||||
@@ -839,6 +950,7 @@ AnalyzeTurn(const NodeID node_u,
|
||||
return {TurnType::Turn, getTurnDirection(angle)};
|
||||
}
|
||||
|
||||
} // anemspace detail
|
||||
} // namespace turn_analysis
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
} // nameNspace osrm
|
||||
|
||||
Reference in New Issue
Block a user