improved fork handling
This commit is contained in:
parent
c337d55d45
commit
a1f1da4c16
@ -221,6 +221,17 @@ AnalyzeTurn(const NodeID node_u,
|
||||
const double angle,
|
||||
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
|
||||
|
||||
// Assignment of specific turn types
|
||||
void assignFork(const EdgeID via_edge,
|
||||
TurnCandidate &left,
|
||||
TurnCandidate &right,
|
||||
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
|
||||
void assignFork(const EdgeID via_edge,
|
||||
TurnCandidate &left,
|
||||
TurnCandidate ¢er,
|
||||
TurnCandidate &right,
|
||||
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
|
||||
|
||||
} // namespace detail
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "util/coordinate.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@ -29,6 +30,11 @@ const unsigned constexpr INVALID_NAME_ID = 0;
|
||||
|
||||
using EdgeData = util::NodeBasedDynamicGraph::EdgeData;
|
||||
|
||||
bool requiresAnnouncedment(const EdgeData &from, const EdgeData &to)
|
||||
{
|
||||
return !from.IsCompatibleTo(to);
|
||||
}
|
||||
|
||||
struct Localizer
|
||||
{
|
||||
const std::vector<QueryNode> *node_info_list = nullptr;
|
||||
@ -282,7 +288,6 @@ inline std::vector<TurnCandidate> fallbackTurnAssignmentMotorway(
|
||||
std::vector<TurnCandidate> turn_candidates,
|
||||
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph)
|
||||
{
|
||||
util::SimpleLogger().Write(logWARNING) << "Fallback turn assignment";
|
||||
for (auto &candidate : turn_candidates)
|
||||
{
|
||||
const auto &out_data = node_based_graph->GetEdgeData(candidate.eid);
|
||||
@ -390,8 +395,7 @@ handleFromMotorway(const NodeID from,
|
||||
// splitting ramp at the end of a highway
|
||||
if (turn_candidates[1].valid && turn_candidates[2].valid)
|
||||
{
|
||||
turn_candidates[1].instruction = {TurnType::Fork, DirectionModifier::SlightRight};
|
||||
turn_candidates[2].instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
|
||||
assignFork(via_edge, turn_candidates[2], turn_candidates[1], node_based_graph);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -404,11 +408,13 @@ handleFromMotorway(const NodeID from,
|
||||
getTurnDirection(turn_candidates[2].angle)};
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (countValid(turn_candidates)) // check whether turns exist at all
|
||||
{
|
||||
// FALLBACK, this should hopefully never be reached
|
||||
auto coord = localizer(node_based_graph->GetTarget(via_edge));
|
||||
util::SimpleLogger().Write(logWARNING)
|
||||
<< "Fallback reached from motorway, no continue angle, " << turn_candidates.size()
|
||||
<< "Fallback reached from motorway at " << toFloating(coord.lat) << " "
|
||||
<< toFloating(coord.lon) << ", no continue angle, " << turn_candidates.size()
|
||||
<< " candidates, " << countValid(turn_candidates) << " valid ones.";
|
||||
fallbackTurnAssignmentMotorway(turn_candidates, node_based_graph);
|
||||
}
|
||||
@ -486,21 +492,71 @@ handleFromMotorway(const NodeID from,
|
||||
turn_candidates[1].instruction =
|
||||
getInstructionForObvious(from, via_edge, turn_candidates[1], node_based_graph);
|
||||
util::SimpleLogger().Write(logWARNING)
|
||||
<< "Disable U-Turn on a freeway at "
|
||||
<< "Disabled U-Turn on a freeway at "
|
||||
<< localizer(node_based_graph->GetTarget(via_edge));
|
||||
turn_candidates[0].valid = false; // UTURN on the freeway
|
||||
}
|
||||
else if (exiting_motorways != 2 || turn_candidates.size() != 3)
|
||||
else if (exiting_motorways == 2)
|
||||
{
|
||||
util::SimpleLogger().Write(logWARNING) << "Found motorway junction with more than "
|
||||
"2 exiting motorways or additional ramps!"
|
||||
<< std::endl;
|
||||
fallbackTurnAssignmentMotorway(turn_candidates, node_based_graph);
|
||||
// standard fork
|
||||
std::size_t first_valid = std::numeric_limits<std::size_t>::max(),
|
||||
second_valid = std::numeric_limits<std::size_t>::max();
|
||||
for (std::size_t i = 0; i < turn_candidates.size(); ++i)
|
||||
{
|
||||
if (turn_candidates[i].valid &&
|
||||
isMotorwayClass(turn_candidates[i].eid, node_based_graph))
|
||||
{
|
||||
if (first_valid < turn_candidates.size())
|
||||
{
|
||||
second_valid = i;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_valid = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
assignFork(via_edge, turn_candidates[second_valid], turn_candidates[first_valid],
|
||||
node_based_graph);
|
||||
}
|
||||
else if (exiting_motorways == 3)
|
||||
{
|
||||
// triple fork
|
||||
std::size_t first_valid = std::numeric_limits<std::size_t>::max(),
|
||||
second_valid = std::numeric_limits<std::size_t>::max(),
|
||||
third_valid = std::numeric_limits<std::size_t>::max();
|
||||
for (std::size_t i = 0; i < turn_candidates.size(); ++i)
|
||||
{
|
||||
if (turn_candidates[i].valid &&
|
||||
isMotorwayClass(turn_candidates[i].eid, node_based_graph))
|
||||
{
|
||||
if (second_valid < turn_candidates.size())
|
||||
{
|
||||
third_valid = i;
|
||||
break;
|
||||
}
|
||||
else if (first_valid < turn_candidates.size())
|
||||
{
|
||||
second_valid = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_valid = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
assignFork(via_edge, turn_candidates[third_valid], turn_candidates[second_valid],
|
||||
turn_candidates[first_valid], node_based_graph);
|
||||
}
|
||||
else
|
||||
{
|
||||
turn_candidates[1].instruction = {TurnType::Fork, DirectionModifier::SlightRight};
|
||||
turn_candidates[2].instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
|
||||
auto coord = localizer(node_based_graph->GetTarget(via_edge));
|
||||
util::SimpleLogger().Write(logWARNING)
|
||||
<< "Found motorway junction with more than "
|
||||
"2 exiting motorways or additional ramps at " << toFloating(coord.lat) << " "
|
||||
<< toFloating(coord.lon);
|
||||
fallbackTurnAssignmentMotorway(turn_candidates, node_based_graph);
|
||||
}
|
||||
} // done for more than one highway exit
|
||||
}
|
||||
@ -596,8 +652,8 @@ handleMotorwayRamp(const NodeID from,
|
||||
if (isMotorwayClass(turn_candidates[1].eid, node_based_graph) &&
|
||||
isMotorwayClass(turn_candidates[2].eid, node_based_graph))
|
||||
{
|
||||
turn_candidates[1].instruction = {TurnType::Merge, DirectionModifier::SlightRight};
|
||||
turn_candidates[2].instruction = {TurnType::Merge, DirectionModifier::SlightLeft};
|
||||
assignFork(via_edge, turn_candidates[2], turn_candidates[1],
|
||||
node_based_graph);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -743,11 +799,13 @@ bool isMotorwayJunction(const NodeID from,
|
||||
angularDeviation(candidate.angle, 180) > 35) ||
|
||||
(candidate.valid && angularDeviation(candidate.angle, 0) < 35))
|
||||
return false;
|
||||
else if (candidate.valid &&
|
||||
(out_data.road_classification.road_class == FunctionalRoadClass::MOTORWAY ||
|
||||
out_data.road_classification.road_class == FunctionalRoadClass::TRUNK))
|
||||
has_motorway = true;
|
||||
else if (candidate.valid && !isRampClass(out_data.road_classification.road_class))
|
||||
else if (out_data.road_classification.road_class == FunctionalRoadClass::MOTORWAY ||
|
||||
out_data.road_classification.road_class == FunctionalRoadClass::TRUNK)
|
||||
{
|
||||
if (candidate.valid)
|
||||
has_motorway = true;
|
||||
}
|
||||
else if (!isRampClass(out_data.road_classification.road_class))
|
||||
has_normal_roads = true;
|
||||
}
|
||||
|
||||
@ -1906,6 +1964,77 @@ handleConflicts(const NodeID from,
|
||||
return turn_candidates;
|
||||
}
|
||||
|
||||
void assignFork(const EdgeID via_edge,
|
||||
TurnCandidate &left,
|
||||
TurnCandidate &right,
|
||||
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph)
|
||||
{
|
||||
const auto &in_data = node_based_graph->GetEdgeData(via_edge);
|
||||
{ // left fork
|
||||
const auto &out_data = node_based_graph->GetEdgeData(left.eid);
|
||||
if (angularDeviation(left.angle, 180) < FUZZY_ANGLE_DIFFERENCE)
|
||||
{
|
||||
if (requiresAnnouncedment(in_data, out_data))
|
||||
{
|
||||
left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
|
||||
}
|
||||
else
|
||||
{
|
||||
left.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
|
||||
}
|
||||
}
|
||||
{ // right fork
|
||||
const auto &out_data = node_based_graph->GetEdgeData(right.eid);
|
||||
if (angularDeviation(right.angle, 180) < FUZZY_ANGLE_DIFFERENCE)
|
||||
{
|
||||
if (requiresAnnouncedment(in_data, out_data))
|
||||
{
|
||||
right.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
|
||||
}
|
||||
else
|
||||
{
|
||||
right.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
right.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void assignFork(const EdgeID via_edge,
|
||||
TurnCandidate &left,
|
||||
TurnCandidate ¢er,
|
||||
TurnCandidate &right,
|
||||
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph)
|
||||
{
|
||||
left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
|
||||
if (angularDeviation(center.angle, 180) < FUZZY_ANGLE_DIFFERENCE)
|
||||
{
|
||||
const auto &in_data = node_based_graph->GetEdgeData(via_edge);
|
||||
const auto &out_data = node_based_graph->GetEdgeData(center.eid);
|
||||
if (requiresAnnouncedment(in_data, out_data))
|
||||
{
|
||||
center.instruction = {TurnType::Fork, DirectionModifier::Straight};
|
||||
}
|
||||
else
|
||||
{
|
||||
center.instruction = {TurnType::Suppressed, DirectionModifier::Straight};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
center.instruction = {TurnType::Fork, DirectionModifier::Straight};
|
||||
}
|
||||
right.instruction = {TurnType::Fork, DirectionModifier::SlightRight};
|
||||
}
|
||||
|
||||
} // anemspace detail
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
|
Loading…
Reference in New Issue
Block a user