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 double angle,
|
||||||
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph);
|
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 detail
|
||||||
} // namespace guidance
|
} // namespace guidance
|
||||||
} // namespace extractor
|
} // namespace extractor
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
@ -29,6 +30,11 @@ const unsigned constexpr INVALID_NAME_ID = 0;
|
|||||||
|
|
||||||
using EdgeData = util::NodeBasedDynamicGraph::EdgeData;
|
using EdgeData = util::NodeBasedDynamicGraph::EdgeData;
|
||||||
|
|
||||||
|
bool requiresAnnouncedment(const EdgeData &from, const EdgeData &to)
|
||||||
|
{
|
||||||
|
return !from.IsCompatibleTo(to);
|
||||||
|
}
|
||||||
|
|
||||||
struct Localizer
|
struct Localizer
|
||||||
{
|
{
|
||||||
const std::vector<QueryNode> *node_info_list = nullptr;
|
const std::vector<QueryNode> *node_info_list = nullptr;
|
||||||
@ -282,7 +288,6 @@ inline std::vector<TurnCandidate> fallbackTurnAssignmentMotorway(
|
|||||||
std::vector<TurnCandidate> turn_candidates,
|
std::vector<TurnCandidate> turn_candidates,
|
||||||
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph)
|
const std::shared_ptr<const util::NodeBasedDynamicGraph> node_based_graph)
|
||||||
{
|
{
|
||||||
util::SimpleLogger().Write(logWARNING) << "Fallback turn assignment";
|
|
||||||
for (auto &candidate : turn_candidates)
|
for (auto &candidate : turn_candidates)
|
||||||
{
|
{
|
||||||
const auto &out_data = node_based_graph->GetEdgeData(candidate.eid);
|
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
|
// 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)
|
||||||
{
|
{
|
||||||
turn_candidates[1].instruction = {TurnType::Fork, DirectionModifier::SlightRight};
|
assignFork(via_edge, turn_candidates[2], turn_candidates[1], node_based_graph);
|
||||||
turn_candidates[2].instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -404,11 +408,13 @@ handleFromMotorway(const NodeID from,
|
|||||||
getTurnDirection(turn_candidates[2].angle)};
|
getTurnDirection(turn_candidates[2].angle)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (countValid(turn_candidates)) // check whether turns exist at all
|
||||||
{
|
{
|
||||||
// FALLBACK, this should hopefully never be reached
|
// FALLBACK, this should hopefully never be reached
|
||||||
|
auto coord = localizer(node_based_graph->GetTarget(via_edge));
|
||||||
util::SimpleLogger().Write(logWARNING)
|
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.";
|
<< " candidates, " << countValid(turn_candidates) << " valid ones.";
|
||||||
fallbackTurnAssignmentMotorway(turn_candidates, node_based_graph);
|
fallbackTurnAssignmentMotorway(turn_candidates, node_based_graph);
|
||||||
}
|
}
|
||||||
@ -486,21 +492,71 @@ handleFromMotorway(const NodeID from,
|
|||||||
turn_candidates[1].instruction =
|
turn_candidates[1].instruction =
|
||||||
getInstructionForObvious(from, via_edge, turn_candidates[1], node_based_graph);
|
getInstructionForObvious(from, via_edge, turn_candidates[1], node_based_graph);
|
||||||
util::SimpleLogger().Write(logWARNING)
|
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));
|
<< localizer(node_based_graph->GetTarget(via_edge));
|
||||||
turn_candidates[0].valid = false; // UTURN on the freeway
|
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 "
|
// standard fork
|
||||||
"2 exiting motorways or additional ramps!"
|
std::size_t first_valid = std::numeric_limits<std::size_t>::max(),
|
||||||
<< std::endl;
|
second_valid = std::numeric_limits<std::size_t>::max();
|
||||||
fallbackTurnAssignmentMotorway(turn_candidates, node_based_graph);
|
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
|
else
|
||||||
{
|
{
|
||||||
turn_candidates[1].instruction = {TurnType::Fork, DirectionModifier::SlightRight};
|
auto coord = localizer(node_based_graph->GetTarget(via_edge));
|
||||||
turn_candidates[2].instruction = {TurnType::Fork, DirectionModifier::SlightLeft};
|
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
|
} // done for more than one highway exit
|
||||||
}
|
}
|
||||||
@ -596,8 +652,8 @@ handleMotorwayRamp(const NodeID from,
|
|||||||
if (isMotorwayClass(turn_candidates[1].eid, node_based_graph) &&
|
if (isMotorwayClass(turn_candidates[1].eid, node_based_graph) &&
|
||||||
isMotorwayClass(turn_candidates[2].eid, node_based_graph))
|
isMotorwayClass(turn_candidates[2].eid, node_based_graph))
|
||||||
{
|
{
|
||||||
turn_candidates[1].instruction = {TurnType::Merge, DirectionModifier::SlightRight};
|
assignFork(via_edge, turn_candidates[2], turn_candidates[1],
|
||||||
turn_candidates[2].instruction = {TurnType::Merge, DirectionModifier::SlightLeft};
|
node_based_graph);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -743,11 +799,13 @@ bool isMotorwayJunction(const NodeID from,
|
|||||||
angularDeviation(candidate.angle, 180) > 35) ||
|
angularDeviation(candidate.angle, 180) > 35) ||
|
||||||
(candidate.valid && angularDeviation(candidate.angle, 0) < 35))
|
(candidate.valid && angularDeviation(candidate.angle, 0) < 35))
|
||||||
return false;
|
return false;
|
||||||
else if (candidate.valid &&
|
else if (out_data.road_classification.road_class == FunctionalRoadClass::MOTORWAY ||
|
||||||
(out_data.road_classification.road_class == FunctionalRoadClass::MOTORWAY ||
|
out_data.road_classification.road_class == FunctionalRoadClass::TRUNK)
|
||||||
out_data.road_classification.road_class == FunctionalRoadClass::TRUNK))
|
{
|
||||||
has_motorway = true;
|
if (candidate.valid)
|
||||||
else if (candidate.valid && !isRampClass(out_data.road_classification.road_class))
|
has_motorway = true;
|
||||||
|
}
|
||||||
|
else if (!isRampClass(out_data.road_classification.road_class))
|
||||||
has_normal_roads = true;
|
has_normal_roads = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1906,6 +1964,77 @@ handleConflicts(const NodeID from,
|
|||||||
return turn_candidates;
|
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
|
} // anemspace detail
|
||||||
} // namespace guidance
|
} // namespace guidance
|
||||||
} // namespace extractor
|
} // namespace extractor
|
||||||
|
Loading…
Reference in New Issue
Block a user