refactor guidance
This commit is contained in:
parent
e04baef3bb
commit
d770c35245
@ -389,7 +389,6 @@ Feature: Simple Turns
|
||||
| waypoints | route | turns |
|
||||
| a,d | abc,bd,bd | depart,turn left,arrive |
|
||||
|
||||
@bug @pr2275
|
||||
Scenario: Left Turn Assignment (6)
|
||||
Given the node map
|
||||
| d | | | | |
|
||||
@ -511,7 +510,6 @@ Feature: Simple Turns
|
||||
| waypoints | route | turns |
|
||||
| a,d | abc,bd,bd | depart,turn right,arrive |
|
||||
|
||||
@bug @pr2275
|
||||
Scenario: Right Turn Assignment (6)
|
||||
Given the node map
|
||||
| | | e | | |
|
||||
@ -569,7 +567,7 @@ Feature: Simple Turns
|
||||
|
||||
Scenario: Right Turn Assignment Two Turns (2)
|
||||
Given the node map
|
||||
| | | f | c | |
|
||||
| | | f | | c |
|
||||
| a | | b | | |
|
||||
| | | | | e |
|
||||
| | | | d | |
|
||||
@ -667,7 +665,6 @@ Feature: Simple Turns
|
||||
| d,e | dbe,dbe | depart,arrive |
|
||||
| e,d | dbe,dbe | depart,arrive |
|
||||
|
||||
@bug @pr2275
|
||||
Scenario: Slight Turn involving Oneways
|
||||
Given the node map
|
||||
| | | | a | |
|
||||
|
@ -61,6 +61,19 @@ class IntersectionHandler
|
||||
ConnectedRoad ¢er,
|
||||
ConnectedRoad &right) const;
|
||||
|
||||
// Trivial Turns use findBasicTurnType and getTurnDirection as only criteria
|
||||
void assignTrivialTurns(const EdgeID via_eid,
|
||||
Intersection &intersection,
|
||||
const std::size_t begin,
|
||||
const std::size_t end) const;
|
||||
|
||||
// Counting Turns are Essentially unseparable turns. Begin > end is a valid input
|
||||
void assignCountingTurns(const EdgeID via_eid,
|
||||
Intersection &intersection,
|
||||
const std::size_t begin,
|
||||
const std::size_t end,
|
||||
const DirectionModifier modifier) const;
|
||||
|
||||
bool isThroughStreet(const std::size_t index, const Intersection &intersection) const;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,27 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_SCENARIO_THREE_WAY_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_SCENARIO_THREE_WAY_HPP_
|
||||
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
// possible fork
|
||||
bool isFork(const ConnectedRoad &uturn,
|
||||
const ConnectedRoad &possible_right_fork,
|
||||
const ConnectedRoad &possible_left_fork);
|
||||
|
||||
// Ending in a T-Intersection
|
||||
bool isEndOfRoad(const ConnectedRoad &uturn,
|
||||
const ConnectedRoad &possible_right_turn,
|
||||
const ConnectedRoad &possible_left_turn);
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
#endif /*OSRM_EXTRACTOR_GUIDANCE_INTERSECTION_SCENARIO_THREE_WAY_HPP_*/
|
@ -1,8 +1,8 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_MOTORWAY_HANDLER_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_MOTORWAY_HANDLER_HPP_
|
||||
|
||||
#include "extractor/guidance/intersection_handler.hpp"
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/intersection_handler.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
|
||||
#include "util/name_table.hpp"
|
||||
|
@ -42,13 +42,19 @@ class RoundaboutHandler : public IntersectionHandler
|
||||
~RoundaboutHandler() override final;
|
||||
|
||||
// check whether the handler can actually handle the intersection
|
||||
bool canProcess(const NodeID from_nid, const EdgeID via_eid, const Intersection &intersection) const override final;
|
||||
bool canProcess(const NodeID from_nid,
|
||||
const EdgeID via_eid,
|
||||
const Intersection &intersection) const override final;
|
||||
|
||||
// process the intersection
|
||||
Intersection operator()(const NodeID from_nid, const EdgeID via_eid, Intersection intersection) const override final;
|
||||
Intersection operator()(const NodeID from_nid,
|
||||
const EdgeID via_eid,
|
||||
Intersection intersection) const override final;
|
||||
|
||||
private:
|
||||
detail::RoundaboutFlags getRoundaboutFlags(const NodeID from_nid, const EdgeID via_eid, const Intersection &intersection) const;
|
||||
detail::RoundaboutFlags getRoundaboutFlags(const NodeID from_nid,
|
||||
const EdgeID via_eid,
|
||||
const Intersection &intersection) const;
|
||||
|
||||
// decide whether we lookk at a roundabout or a rotary
|
||||
bool isRotary(const NodeID nid) const;
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "extractor/guidance/classification_data.hpp"
|
||||
#include "extractor/guidance/discrete_angle.hpp"
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
@ -397,6 +398,25 @@ inline bool canBeSeenAsFork(const FunctionalRoadClass first, const FunctionalRoa
|
||||
return std::abs(getPriority(first) - getPriority(second)) <= 1;
|
||||
}
|
||||
|
||||
// To simplify handling of Left/Right hand turns, we can mirror turns and write an intersection
|
||||
// handler only for one side. The mirror function turns a left-hand turn in a equivalent right-hand
|
||||
// turn and vice versa.
|
||||
inline ConnectedRoad mirror(ConnectedRoad road)
|
||||
{
|
||||
const constexpr DirectionModifier mirrored_modifiers[] = {
|
||||
DirectionModifier::UTurn, DirectionModifier::SharpLeft, DirectionModifier::Left,
|
||||
DirectionModifier::SlightLeft, DirectionModifier::Straight, DirectionModifier::SlightRight,
|
||||
DirectionModifier::Right, DirectionModifier::SharpRight};
|
||||
|
||||
if (angularDeviation(road.turn.angle, 0) > std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
road.turn.angle = 360 - road.turn.angle;
|
||||
road.turn.instruction.direction_modifier =
|
||||
mirrored_modifiers[road.turn.instruction.direction_modifier];
|
||||
}
|
||||
return road;
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
@ -4,10 +4,10 @@
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/intersection_generator.hpp"
|
||||
#include "extractor/guidance/motorway_handler.hpp"
|
||||
#include "extractor/guidance/roundabout_handler.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
#include "extractor/guidance/turn_classification.hpp"
|
||||
#include "extractor/guidance/roundabout_handler.hpp"
|
||||
#include "extractor/guidance/motorway_handler.hpp"
|
||||
#include "extractor/guidance/turn_handler.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/restriction_map.hpp"
|
||||
|
@ -3,9 +3,9 @@
|
||||
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
@ -84,8 +84,7 @@ classifyIntersection(NodeID nid,
|
||||
}
|
||||
|
||||
std::sort(turns.begin(), turns.end(),
|
||||
[](const TurnPossibility left, const TurnPossibility right)
|
||||
{
|
||||
[](const TurnPossibility left, const TurnPossibility right) {
|
||||
return left.angle < right.angle;
|
||||
});
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
#ifndef OSRM_EXTRACTOR_GUIDANCE_TURN_HANDLER_HPP_
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_TURN_HANDLER_HPP_
|
||||
|
||||
#include "extractor/guidance/intersection_handler.hpp"
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/intersection_handler.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
|
||||
#include "util/name_table.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
|
@ -13,8 +13,7 @@ namespace guidance
|
||||
FunctionalRoadClass functionalRoadClassFromTag(std::string const &value)
|
||||
{
|
||||
// FIXME at some point this should be part of the profiles
|
||||
const static auto class_hash = []
|
||||
{
|
||||
const static auto class_hash = [] {
|
||||
std::unordered_map<std::string, FunctionalRoadClass> hash;
|
||||
hash["motorway"] = FunctionalRoadClass::MOTORWAY;
|
||||
hash["motorway_link"] = FunctionalRoadClass::MOTORWAY_LINK;
|
||||
|
@ -14,11 +14,12 @@ namespace extractor
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
IntersectionGenerator::IntersectionGenerator(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const RestrictionMap &restriction_map,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
const CompressedEdgeContainer &compressed_edge_container)
|
||||
IntersectionGenerator::IntersectionGenerator(
|
||||
const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const RestrictionMap &restriction_map,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
const CompressedEdgeContainer &compressed_edge_container)
|
||||
: node_based_graph(node_based_graph), restriction_map(restriction_map),
|
||||
barrier_nodes(barrier_nodes), node_info_list(node_info_list),
|
||||
compressed_edge_container(compressed_edge_container)
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include "extractor/guidance/intersection_handler.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
|
||||
#include "util/simple_logger.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using EdgeData = osrm::util::NodeBasedDynamicGraph::EdgeData;
|
||||
@ -283,6 +285,47 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
|
||||
}
|
||||
}
|
||||
|
||||
void IntersectionHandler::assignTrivialTurns(const EdgeID via_eid,
|
||||
Intersection &intersection,
|
||||
const std::size_t begin,
|
||||
const std::size_t end) const
|
||||
{
|
||||
for (std::size_t index = begin; index != end; ++index)
|
||||
if (intersection[index].entry_allowed)
|
||||
intersection[index].turn.instruction = {
|
||||
findBasicTurnType(via_eid, intersection[index]),
|
||||
getTurnDirection(intersection[index].turn.angle)};
|
||||
}
|
||||
|
||||
void IntersectionHandler::assignCountingTurns(const EdgeID via_eid,
|
||||
Intersection &intersection,
|
||||
const std::size_t begin,
|
||||
const std::size_t end,
|
||||
const DirectionModifier modifier) const
|
||||
{
|
||||
const constexpr TurnType turns[] = {TurnType::FirstTurn, TurnType::SecondTurn,
|
||||
TurnType::ThirdTurn, TurnType::FourthTurn};
|
||||
const constexpr TurnType ramps[] = {TurnType::FirstRamp, TurnType::SecondRamp,
|
||||
TurnType::ThirdRamp, TurnType::FourthRamp};
|
||||
|
||||
const std::size_t length = end > begin ? end - begin : begin - end;
|
||||
if (length > 4)
|
||||
{
|
||||
util::SimpleLogger().Write(logDEBUG) << "Counting Turn assignment called for " << length
|
||||
<< " turns. Supports at most four turns.";
|
||||
}
|
||||
|
||||
// counting turns varies whether we consider left/right turns
|
||||
for (std::size_t index = begin, count = 0; index != end;
|
||||
count++, begin < end ? ++index : --index)
|
||||
{
|
||||
if (TurnType::Ramp == findBasicTurnType(via_eid, intersection[index]))
|
||||
intersection[index].turn.instruction = {ramps[count], modifier};
|
||||
else
|
||||
intersection[index].turn.instruction = {turns[count], modifier};
|
||||
}
|
||||
}
|
||||
|
||||
bool IntersectionHandler::isThroughStreet(const std::size_t index,
|
||||
const Intersection &intersection) const
|
||||
{
|
||||
|
32
src/extractor/guidance/intersection_scenario_three_way.cpp
Normal file
32
src/extractor/guidance/intersection_scenario_three_way.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include "extractor/guidance/constants.hpp"
|
||||
#include "extractor/guidance/intersection_scenario_three_way.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
bool isFork(const ConnectedRoad &,
|
||||
const ConnectedRoad &possible_right_fork,
|
||||
const ConnectedRoad &possible_left_fork)
|
||||
{
|
||||
return angularDeviation(possible_right_fork.turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE &&
|
||||
angularDeviation(possible_left_fork.turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE;
|
||||
}
|
||||
|
||||
bool isEndOfRoad(const ConnectedRoad &,
|
||||
const ConnectedRoad &possible_right_turn,
|
||||
const ConnectedRoad &possible_left_turn)
|
||||
{
|
||||
return angularDeviation(possible_right_turn.turn.angle, 90) < NARROW_TURN_ANGLE &&
|
||||
angularDeviation(possible_left_turn.turn.angle, 270) < NARROW_TURN_ANGLE &&
|
||||
angularDeviation(possible_right_turn.turn.angle, possible_left_turn.turn.angle) >
|
||||
2 * NARROW_TURN_ANGLE;
|
||||
}
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
@ -222,7 +222,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
|
||||
|
||||
intersection[1].turn.instruction =
|
||||
getInstructionForObvious(intersection.size(), via_eid,
|
||||
isThroughStreet(1,intersection), intersection[1]);
|
||||
isThroughStreet(1, intersection), intersection[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -236,7 +236,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
|
||||
if (road.turn.angle == continue_angle)
|
||||
{
|
||||
road.turn.instruction = getInstructionForObvious(
|
||||
intersection.size(), via_eid, isThroughStreet(1,intersection), road);
|
||||
intersection.size(), via_eid, isThroughStreet(1, intersection), road);
|
||||
}
|
||||
else if (road.turn.angle < continue_angle)
|
||||
{
|
||||
@ -264,7 +264,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
|
||||
{
|
||||
intersection[1].turn.instruction =
|
||||
getInstructionForObvious(intersection.size(), via_eid,
|
||||
isThroughStreet(1,intersection), intersection[1]);
|
||||
isThroughStreet(1, intersection), intersection[1]);
|
||||
util::SimpleLogger().Write(logDEBUG) << "Disabled U-Turn on a freeway";
|
||||
intersection[0].entry_allowed = false; // UTURN on the freeway
|
||||
}
|
||||
@ -341,7 +341,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
|
||||
BOOST_ASSERT(detail::isMotorwayClass(intersection[1].turn.eid, node_based_graph));
|
||||
|
||||
intersection[1].turn.instruction = getInstructionForObvious(
|
||||
intersection.size(), via_eid, isThroughStreet(1,intersection), intersection[1]);
|
||||
intersection.size(), via_eid, isThroughStreet(1, intersection), intersection[1]);
|
||||
}
|
||||
else if (intersection.size() == 3)
|
||||
{
|
||||
@ -378,7 +378,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
|
||||
{
|
||||
intersection[1].turn.instruction =
|
||||
getInstructionForObvious(intersection.size(), via_eid,
|
||||
isThroughStreet(1,intersection), intersection[1]);
|
||||
isThroughStreet(1, intersection), intersection[1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -403,7 +403,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
|
||||
{
|
||||
intersection[2].turn.instruction =
|
||||
getInstructionForObvious(intersection.size(), via_eid,
|
||||
isThroughStreet(2,intersection), intersection[2]);
|
||||
isThroughStreet(2, intersection), intersection[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,9 +76,8 @@ std::vector<TurnOperation> TurnAnalysis::getTurns(const NodeID from_nid, const E
|
||||
}
|
||||
|
||||
// Sets basic turn types as fallback for otherwise unhandled turns
|
||||
Intersection TurnAnalysis::setTurnTypes(const NodeID from_nid,
|
||||
const EdgeID,
|
||||
Intersection intersection) const
|
||||
Intersection
|
||||
TurnAnalysis::setTurnTypes(const NodeID from_nid, const EdgeID, Intersection intersection) const
|
||||
{
|
||||
for (auto &road : intersection)
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "extractor/guidance/constants.hpp"
|
||||
#include "extractor/guidance/intersection_scenario_three_way.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
#include "extractor/guidance/turn_handler.hpp"
|
||||
|
||||
@ -90,25 +91,37 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
|
||||
const auto isObviousOfTwo = [this](const ConnectedRoad road, const ConnectedRoad other) {
|
||||
const auto first_class =
|
||||
node_based_graph.GetEdgeData(road.turn.eid).road_classification.road_class;
|
||||
const bool is_ramp = isRampClass(first_class);
|
||||
|
||||
const auto second_class =
|
||||
node_based_graph.GetEdgeData(other.turn.eid).road_classification.road_class;
|
||||
const bool is_narrow_turn =
|
||||
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE;
|
||||
const bool other_turn_is_at_least_orthogonal =
|
||||
angularDeviation(other.turn.angle, STRAIGHT_ANGLE) > 85;
|
||||
const bool turn_is_perfectly_straight = angularDeviation(road.turn.angle, STRAIGHT_ANGLE) <
|
||||
std::numeric_limits<double>::epsilon();
|
||||
|
||||
const bool is_ramp = isRampClass(first_class);
|
||||
const bool is_obvious_by_road_class =
|
||||
(!is_ramp && (2 * getPriority(first_class) < getPriority(second_class))) ||
|
||||
(!isLowPriorityRoadClass(first_class) && isLowPriorityRoadClass(second_class));
|
||||
|
||||
if (is_obvious_by_road_class)
|
||||
return true;
|
||||
|
||||
const bool other_is_obvious_by_road_flass =
|
||||
(!isRampClass(second_class) &&
|
||||
(2 * getPriority(second_class) < getPriority(first_class))) ||
|
||||
(!isLowPriorityRoadClass(second_class) && isLowPriorityRoadClass(first_class));
|
||||
|
||||
if (other_is_obvious_by_road_flass)
|
||||
return false;
|
||||
|
||||
const bool turn_is_perfectly_straight = angularDeviation(road.turn.angle, STRAIGHT_ANGLE) <
|
||||
std::numeric_limits<double>::epsilon();
|
||||
|
||||
if (turn_is_perfectly_straight)
|
||||
return true;
|
||||
|
||||
const bool is_much_narrower_than_other =
|
||||
angularDeviation(other.turn.angle, STRAIGHT_ANGLE) /
|
||||
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) >
|
||||
INCREASES_BY_FOURTY_PERCENT;
|
||||
return (is_narrow_turn && other_turn_is_at_least_orthogonal) ||
|
||||
turn_is_perfectly_straight || is_much_narrower_than_other ||
|
||||
is_obvious_by_road_class;
|
||||
return is_much_narrower_than_other;
|
||||
};
|
||||
|
||||
/* Two nearly straight turns -> FORK
|
||||
@ -118,8 +131,7 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
|
||||
\
|
||||
OOOOOOO
|
||||
*/
|
||||
if (angularDeviation(intersection[1].turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE &&
|
||||
angularDeviation(intersection[2].turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE)
|
||||
if (isFork(intersection[0], intersection[1], intersection[2]))
|
||||
{
|
||||
if (intersection[1].entry_allowed && intersection[2].entry_allowed)
|
||||
{
|
||||
@ -170,10 +182,7 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
|
||||
I
|
||||
I
|
||||
*/
|
||||
else if (angularDeviation(intersection[1].turn.angle, 90) < NARROW_TURN_ANGLE &&
|
||||
angularDeviation(intersection[2].turn.angle, 270) < NARROW_TURN_ANGLE &&
|
||||
angularDeviation(intersection[1].turn.angle, intersection[2].turn.angle) >
|
||||
NARROW_TURN_ANGLE)
|
||||
else if (isEndOfRoad(intersection[0], intersection[1], intersection[2]))
|
||||
{
|
||||
if (intersection[1].entry_allowed)
|
||||
{
|
||||
@ -191,113 +200,12 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
|
||||
intersection[2].turn.instruction = {TurnType::Ramp, DirectionModifier::Left};
|
||||
}
|
||||
}
|
||||
/* T Intersection, Cross left
|
||||
O
|
||||
O
|
||||
O
|
||||
IIIIIIII - OOOOOOOOOO
|
||||
*/
|
||||
else if (angularDeviation(intersection[1].turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE &&
|
||||
angularDeviation(intersection[2].turn.angle, 270) < NARROW_TURN_ANGLE &&
|
||||
angularDeviation(intersection[1].turn.angle, intersection[2].turn.angle) >
|
||||
NARROW_TURN_ANGLE)
|
||||
{
|
||||
if (intersection[1].entry_allowed)
|
||||
{
|
||||
if (TurnType::Ramp != findBasicTurnType(via_edge, intersection[1]))
|
||||
intersection[1].turn.instruction =
|
||||
getInstructionForObvious(intersection.size(), via_edge, false, intersection[1]);
|
||||
else
|
||||
intersection[1].turn.instruction = {TurnType::Ramp, DirectionModifier::Straight};
|
||||
}
|
||||
if (intersection[2].entry_allowed)
|
||||
{
|
||||
intersection[2].turn.instruction = {findBasicTurnType(via_edge, intersection[2]),
|
||||
DirectionModifier::Left};
|
||||
}
|
||||
}
|
||||
/* T Intersection, Cross right
|
||||
|
||||
IIIIIIII T OOOOOOOOOO
|
||||
O
|
||||
O
|
||||
O
|
||||
*/
|
||||
else if (angularDeviation(intersection[2].turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE &&
|
||||
angularDeviation(intersection[1].turn.angle, 90) < NARROW_TURN_ANGLE &&
|
||||
angularDeviation(intersection[1].turn.angle, intersection[2].turn.angle) >
|
||||
NARROW_TURN_ANGLE)
|
||||
{
|
||||
if (intersection[2].entry_allowed)
|
||||
intersection[2].turn.instruction =
|
||||
getInstructionForObvious(intersection.size(), via_edge, false, intersection[2]);
|
||||
if (intersection[1].entry_allowed)
|
||||
intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]),
|
||||
DirectionModifier::Right};
|
||||
}
|
||||
// merge onto a through street
|
||||
else if (INVALID_NAME_ID != node_based_graph.GetEdgeData(intersection[1].turn.eid).name_id &&
|
||||
node_based_graph.GetEdgeData(intersection[1].turn.eid).name_id ==
|
||||
node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id)
|
||||
{
|
||||
const auto findTurn = [isObviousOfTwo](const ConnectedRoad turn,
|
||||
const ConnectedRoad other) -> TurnInstruction {
|
||||
if (isObviousOfTwo(turn, other))
|
||||
{
|
||||
return {TurnType::Merge, turn.turn.angle < STRAIGHT_ANGLE
|
||||
? DirectionModifier::SlightLeft
|
||||
: DirectionModifier::SlightRight};
|
||||
}
|
||||
else
|
||||
{
|
||||
return {TurnType::Turn, getTurnDirection(turn.turn.angle)};
|
||||
}
|
||||
};
|
||||
intersection[1].turn.instruction = findTurn(intersection[1], intersection[2]);
|
||||
intersection[2].turn.instruction = findTurn(intersection[2], intersection[1]);
|
||||
}
|
||||
// other street merges from the left
|
||||
else if (INVALID_NAME_ID != node_based_graph.GetEdgeData(via_edge).name_id &&
|
||||
node_based_graph.GetEdgeData(via_edge).name_id ==
|
||||
node_based_graph.GetEdgeData(intersection[1].turn.eid).name_id)
|
||||
{
|
||||
if (isObviousOfTwo(intersection[1], intersection[2]))
|
||||
{
|
||||
intersection[1].turn.instruction =
|
||||
TurnInstruction::SUPPRESSED(DirectionModifier::Straight);
|
||||
}
|
||||
else
|
||||
{
|
||||
intersection[1].turn.instruction = {TurnType::Continue,
|
||||
getTurnDirection(intersection[1].turn.angle)};
|
||||
}
|
||||
intersection[2].turn.instruction = {findBasicTurnType(via_edge, intersection[2]),
|
||||
getTurnDirection(intersection[2].turn.angle)};
|
||||
}
|
||||
// other street merges from the right
|
||||
else if (INVALID_NAME_ID != node_based_graph.GetEdgeData(via_edge).name_id &&
|
||||
node_based_graph.GetEdgeData(via_edge).name_id ==
|
||||
node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id)
|
||||
{
|
||||
if (isObviousOfTwo(intersection[2], intersection[1]))
|
||||
{
|
||||
intersection[2].turn.instruction =
|
||||
TurnInstruction::SUPPRESSED(DirectionModifier::Straight);
|
||||
}
|
||||
else
|
||||
{
|
||||
intersection[2].turn.instruction = {TurnType::Continue,
|
||||
getTurnDirection(intersection[2].turn.angle)};
|
||||
}
|
||||
intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]),
|
||||
getTurnDirection(intersection[1].turn.angle)};
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isObviousOfTwo(intersection[1], intersection[2]))
|
||||
{
|
||||
intersection[1].turn.instruction =
|
||||
getInstructionForObvious(3, via_edge, false, intersection[1]);
|
||||
intersection[1].turn.instruction = getInstructionForObvious(
|
||||
3, via_edge, isThroughStreet(1, intersection), intersection[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -307,8 +215,8 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection
|
||||
|
||||
if (isObviousOfTwo(intersection[2], intersection[1]))
|
||||
{
|
||||
intersection[2].turn.instruction =
|
||||
getInstructionForObvious(3, via_edge, false, intersection[2]);
|
||||
intersection[2].turn.instruction = getInstructionForObvious(
|
||||
3, via_edge, isThroughStreet(2, intersection), intersection[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -339,9 +247,9 @@ Intersection TurnHandler::handleComplexTurn(const EdgeID via_edge, Intersection
|
||||
// check whether the obvious choice is actually a through street
|
||||
if (obvious_index != 0)
|
||||
{
|
||||
intersection[obvious_index].turn.instruction =
|
||||
getInstructionForObvious(intersection.size(), via_edge, isThroughStreet(obvious_index,intersection),
|
||||
intersection[obvious_index]);
|
||||
intersection[obvious_index].turn.instruction = getInstructionForObvious(
|
||||
intersection.size(), via_edge, isThroughStreet(obvious_index, intersection),
|
||||
intersection[obvious_index]);
|
||||
|
||||
// assign left/right turns
|
||||
intersection = assignLeftTurns(via_edge, std::move(intersection), obvious_index + 1);
|
||||
@ -493,8 +401,11 @@ std::size_t TurnHandler::findObviousTurn(const EdgeID via_edge,
|
||||
return 0;
|
||||
|
||||
// Well distinct turn that is nearly straight
|
||||
if (left_deviation / best_deviation >= DISTINCTION_RATIO &&
|
||||
right_deviation / best_deviation >= DISTINCTION_RATIO)
|
||||
if ((left_deviation / best_deviation >= DISTINCTION_RATIO ||
|
||||
(left_deviation > best_deviation &&
|
||||
!intersection[(best + 1) % intersection.size()].entry_allowed)) &&
|
||||
(right_deviation / best_deviation >= DISTINCTION_RATIO ||
|
||||
(right_deviation > best_deviation && !intersection[best - 1].entry_allowed)))
|
||||
{
|
||||
return best;
|
||||
}
|
||||
@ -503,253 +414,31 @@ std::size_t TurnHandler::findObviousTurn(const EdgeID via_edge,
|
||||
return 0; // no obvious turn
|
||||
}
|
||||
|
||||
// Can only assign three turns
|
||||
// Assignment of left turns hands of to right turns.
|
||||
// To do so, we mirror every road segment and reverse the order.
|
||||
// After the mirror and reversal / we assign right turns and
|
||||
// mirror again and restore the original order.
|
||||
Intersection TurnHandler::assignLeftTurns(const EdgeID via_edge,
|
||||
Intersection intersection,
|
||||
const std::size_t starting_at) const
|
||||
{
|
||||
const auto count_valid = [&intersection, starting_at]() {
|
||||
std::size_t count = 0;
|
||||
for (std::size_t i = starting_at; i < intersection.size(); ++i)
|
||||
if (intersection[i].entry_allowed)
|
||||
++count;
|
||||
return count;
|
||||
};
|
||||
if (starting_at == intersection.size() || count_valid() == 0)
|
||||
return intersection;
|
||||
// handle single turn
|
||||
if (intersection.size() - starting_at == 1)
|
||||
{
|
||||
if (!intersection[starting_at].entry_allowed)
|
||||
return intersection;
|
||||
BOOST_ASSERT(!intersection.empty());
|
||||
BOOST_ASSERT(starting_at <= intersection.size());
|
||||
for (auto &road : intersection)
|
||||
road = mirror(road);
|
||||
|
||||
if (angularDeviation(intersection[starting_at].turn.angle, STRAIGHT_ANGLE) >
|
||||
NARROW_TURN_ANGLE &&
|
||||
angularDeviation(intersection[starting_at].turn.angle, 0) > NARROW_TURN_ANGLE)
|
||||
{
|
||||
// assign left turn
|
||||
intersection[starting_at].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at]), DirectionModifier::Left};
|
||||
}
|
||||
else if (angularDeviation(intersection[starting_at].turn.angle, STRAIGHT_ANGLE) <=
|
||||
NARROW_TURN_ANGLE)
|
||||
{
|
||||
intersection[starting_at].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at]),
|
||||
DirectionModifier::SlightLeft};
|
||||
}
|
||||
else
|
||||
{
|
||||
intersection[starting_at].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at]),
|
||||
DirectionModifier::SharpLeft};
|
||||
}
|
||||
}
|
||||
// two turns on at the side
|
||||
else if (intersection.size() - starting_at == 2)
|
||||
{
|
||||
const auto first_direction = getTurnDirection(intersection[starting_at].turn.angle);
|
||||
const auto second_direction = getTurnDirection(intersection[starting_at + 1].turn.angle);
|
||||
if (first_direction == second_direction)
|
||||
{
|
||||
// conflict
|
||||
handleDistinctConflict(via_edge, intersection[starting_at + 1],
|
||||
intersection[starting_at]);
|
||||
}
|
||||
else
|
||||
{
|
||||
intersection[starting_at].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at]), first_direction};
|
||||
intersection[starting_at + 1].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at + 1]), second_direction};
|
||||
}
|
||||
}
|
||||
else if (intersection.size() - starting_at == 3)
|
||||
{
|
||||
const auto first_direction = getTurnDirection(intersection[starting_at].turn.angle);
|
||||
const auto second_direction = getTurnDirection(intersection[starting_at + 1].turn.angle);
|
||||
const auto third_direction = getTurnDirection(intersection[starting_at + 2].turn.angle);
|
||||
if (first_direction != second_direction && second_direction != third_direction)
|
||||
{
|
||||
// implies first != third, based on the angles and clockwise order
|
||||
if (intersection[starting_at].entry_allowed)
|
||||
intersection[starting_at].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at]), first_direction};
|
||||
if (intersection[starting_at + 1].entry_allowed)
|
||||
intersection[starting_at + 1].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at + 1]), second_direction};
|
||||
if (intersection[starting_at + 2].entry_allowed)
|
||||
intersection[starting_at + 2].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at + 2]), third_direction};
|
||||
}
|
||||
else if (2 >= (intersection[starting_at].entry_allowed +
|
||||
intersection[starting_at + 1].entry_allowed +
|
||||
intersection[starting_at + 2].entry_allowed))
|
||||
{
|
||||
std::reverse(intersection.begin() + 1, intersection.end());
|
||||
|
||||
// at least one invalid turn
|
||||
if (!intersection[starting_at].entry_allowed)
|
||||
{
|
||||
handleDistinctConflict(via_edge, intersection[starting_at + 2],
|
||||
intersection[starting_at + 1]);
|
||||
}
|
||||
else if (!intersection[starting_at + 1].entry_allowed)
|
||||
{
|
||||
handleDistinctConflict(via_edge, intersection[starting_at + 2],
|
||||
intersection[starting_at]);
|
||||
}
|
||||
else
|
||||
{
|
||||
handleDistinctConflict(via_edge, intersection[starting_at + 1],
|
||||
intersection[starting_at]);
|
||||
}
|
||||
}
|
||||
else if (intersection[starting_at].entry_allowed &&
|
||||
intersection[starting_at + 1].entry_allowed &&
|
||||
intersection[starting_at + 2].entry_allowed &&
|
||||
angularDeviation(intersection[starting_at].turn.angle,
|
||||
intersection[starting_at + 1].turn.angle) >= NARROW_TURN_ANGLE &&
|
||||
angularDeviation(intersection[starting_at + 1].turn.angle,
|
||||
intersection[starting_at + 2].turn.angle) >= NARROW_TURN_ANGLE)
|
||||
{
|
||||
intersection[starting_at].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at]),
|
||||
DirectionModifier::SlightLeft};
|
||||
intersection[starting_at + 1].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at + 1]),
|
||||
DirectionModifier::Left};
|
||||
intersection[starting_at + 2].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at + 2]),
|
||||
DirectionModifier::SharpLeft};
|
||||
}
|
||||
else if (intersection[starting_at].entry_allowed &&
|
||||
intersection[starting_at + 1].entry_allowed &&
|
||||
intersection[starting_at + 2].entry_allowed &&
|
||||
((first_direction == second_direction && second_direction == third_direction) ||
|
||||
(third_direction == second_direction &&
|
||||
angularDeviation(intersection[starting_at].turn.angle,
|
||||
intersection[starting_at + 1].turn.angle) < GROUP_ANGLE) ||
|
||||
(second_direction == first_direction &&
|
||||
angularDeviation(intersection[starting_at + 1].turn.angle,
|
||||
intersection[starting_at + 2].turn.angle) < GROUP_ANGLE)))
|
||||
{
|
||||
intersection[starting_at].turn.instruction = {
|
||||
detail::isRampClass(intersection[starting_at].turn.eid, node_based_graph)
|
||||
? FirstRamp
|
||||
: FirstTurn,
|
||||
second_direction};
|
||||
intersection[starting_at + 1].turn.instruction = {
|
||||
detail::isRampClass(intersection[starting_at + 1].turn.eid, node_based_graph)
|
||||
? SecondRamp
|
||||
: SecondTurn,
|
||||
second_direction};
|
||||
intersection[starting_at + 2].turn.instruction = {
|
||||
detail::isRampClass(intersection[starting_at + 2].turn.eid, node_based_graph)
|
||||
? ThirdRamp
|
||||
: ThirdTurn,
|
||||
second_direction};
|
||||
}
|
||||
else if (intersection[starting_at].entry_allowed &&
|
||||
intersection[starting_at + 1].entry_allowed &&
|
||||
intersection[starting_at + 2].entry_allowed &&
|
||||
((third_direction == second_direction &&
|
||||
angularDeviation(intersection[starting_at].turn.angle,
|
||||
intersection[starting_at + 1].turn.angle) >= GROUP_ANGLE) ||
|
||||
(second_direction == first_direction &&
|
||||
angularDeviation(intersection[starting_at + 1].turn.angle,
|
||||
intersection[starting_at + 2].turn.angle) >= GROUP_ANGLE)))
|
||||
{
|
||||
// conflict one side with an additional very sharp turn
|
||||
if (angularDeviation(intersection[starting_at + 1].turn.angle,
|
||||
intersection[starting_at + 2].turn.angle) >= GROUP_ANGLE)
|
||||
{
|
||||
handleDistinctConflict(via_edge, intersection[starting_at + 1],
|
||||
intersection[starting_at]);
|
||||
intersection[starting_at + 2].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at + 2]), third_direction};
|
||||
}
|
||||
else
|
||||
{
|
||||
intersection[starting_at].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at]), first_direction};
|
||||
handleDistinctConflict(via_edge, intersection[starting_at + 2],
|
||||
intersection[starting_at + 1]);
|
||||
}
|
||||
}
|
||||
else if ((first_direction == second_direction &&
|
||||
intersection[starting_at].entry_allowed !=
|
||||
intersection[starting_at + 1].entry_allowed) ||
|
||||
(second_direction == third_direction &&
|
||||
intersection[starting_at + 1].entry_allowed !=
|
||||
intersection[starting_at + 2].entry_allowed))
|
||||
{
|
||||
// no conflict, due to conflict being restricted to valid/invalid
|
||||
if (intersection[starting_at].entry_allowed)
|
||||
intersection[starting_at].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at]), first_direction};
|
||||
if (intersection[starting_at + 1].entry_allowed)
|
||||
intersection[starting_at + 1].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at + 1]), second_direction};
|
||||
if (intersection[starting_at + 2].entry_allowed)
|
||||
intersection[starting_at + 2].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[starting_at + 2]), third_direction};
|
||||
}
|
||||
else
|
||||
{
|
||||
util::SimpleLogger().Write(logWARNING) << "Reached fallback for left turns, size 3";
|
||||
for (const auto road : intersection)
|
||||
{
|
||||
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
|
||||
util::SimpleLogger().Write(logWARNING)
|
||||
<< "\troad: " << toString(road) << " Name: " << out_data.name_id
|
||||
<< " Road Class: " << (int)out_data.road_classification.road_class;
|
||||
}
|
||||
// account for the u-turn in the beginning
|
||||
const auto count = intersection.size() - starting_at + 1;
|
||||
|
||||
intersection = assignRightTurns(via_edge, std::move(intersection), count);
|
||||
|
||||
std::reverse(intersection.begin() + 1, intersection.end());
|
||||
|
||||
for (auto &road : intersection)
|
||||
road = mirror(road);
|
||||
|
||||
for (std::size_t i = starting_at; i < intersection.size(); ++i)
|
||||
if (intersection[i].entry_allowed)
|
||||
intersection[i].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[i]),
|
||||
getTurnDirection(intersection[i].turn.angle)};
|
||||
}
|
||||
}
|
||||
else if (intersection.size() - starting_at == 4)
|
||||
{
|
||||
if (intersection[starting_at].entry_allowed)
|
||||
intersection[starting_at].turn.instruction = {
|
||||
detail::isRampClass(intersection[starting_at].turn.eid, node_based_graph)
|
||||
? FirstRamp
|
||||
: FirstTurn,
|
||||
DirectionModifier::Left};
|
||||
if (intersection[starting_at + 1].entry_allowed)
|
||||
intersection[starting_at + 1].turn.instruction = {
|
||||
detail::isRampClass(intersection[starting_at + 1].turn.eid, node_based_graph)
|
||||
? SecondRamp
|
||||
: SecondTurn,
|
||||
DirectionModifier::Left};
|
||||
if (intersection[starting_at + 2].entry_allowed)
|
||||
intersection[starting_at + 2].turn.instruction = {
|
||||
detail::isRampClass(intersection[starting_at + 2].turn.eid, node_based_graph)
|
||||
? ThirdRamp
|
||||
: ThirdTurn,
|
||||
DirectionModifier::Left};
|
||||
if (intersection[starting_at + 3].entry_allowed)
|
||||
intersection[starting_at + 3].turn.instruction = {
|
||||
detail::isRampClass(intersection[starting_at + 3].turn.eid, node_based_graph)
|
||||
? FourthRamp
|
||||
: FourthTurn,
|
||||
DirectionModifier::Left};
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto &road : intersection)
|
||||
{
|
||||
if (!road.entry_allowed)
|
||||
continue;
|
||||
road.turn.instruction = {detail::isRampClass(road.turn.eid, node_based_graph) ? Ramp
|
||||
: Turn,
|
||||
getTurnDirection(road.turn.angle)};
|
||||
}
|
||||
}
|
||||
return intersection;
|
||||
}
|
||||
|
||||
@ -771,24 +460,9 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
|
||||
// handle single turn
|
||||
if (up_to == 2)
|
||||
{
|
||||
if (angularDeviation(intersection[1].turn.angle, STRAIGHT_ANGLE) > NARROW_TURN_ANGLE &&
|
||||
angularDeviation(intersection[1].turn.angle, 0) > NARROW_TURN_ANGLE)
|
||||
{
|
||||
// assign left turn
|
||||
intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]),
|
||||
DirectionModifier::Right};
|
||||
}
|
||||
else if (angularDeviation(intersection[1].turn.angle, STRAIGHT_ANGLE) <= NARROW_TURN_ANGLE)
|
||||
{
|
||||
intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]),
|
||||
DirectionModifier::SlightRight};
|
||||
}
|
||||
else
|
||||
{
|
||||
intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]),
|
||||
DirectionModifier::SharpRight};
|
||||
}
|
||||
assignTrivialTurns(via_edge, intersection, 1, up_to);
|
||||
}
|
||||
// Handle Turns 1-3
|
||||
else if (up_to == 3)
|
||||
{
|
||||
const auto first_direction = getTurnDirection(intersection[1].turn.angle);
|
||||
@ -800,12 +474,10 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
|
||||
}
|
||||
else
|
||||
{
|
||||
intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]),
|
||||
first_direction};
|
||||
intersection[2].turn.instruction = {findBasicTurnType(via_edge, intersection[2]),
|
||||
second_direction};
|
||||
assignTrivialTurns(via_edge, intersection, 1, up_to);
|
||||
}
|
||||
}
|
||||
// Handle Turns 1-4
|
||||
else if (up_to == 4)
|
||||
{
|
||||
const auto first_direction = getTurnDirection(intersection[1].turn.angle);
|
||||
@ -813,15 +485,10 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
|
||||
const auto third_direction = getTurnDirection(intersection[3].turn.angle);
|
||||
if (first_direction != second_direction && second_direction != third_direction)
|
||||
{
|
||||
if (intersection[1].entry_allowed)
|
||||
intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]),
|
||||
first_direction};
|
||||
if (intersection[2].entry_allowed)
|
||||
intersection[2].turn.instruction = {findBasicTurnType(via_edge, intersection[2]),
|
||||
second_direction};
|
||||
if (intersection[3].entry_allowed)
|
||||
intersection[3].turn.instruction = {findBasicTurnType(via_edge, intersection[3]),
|
||||
third_direction};
|
||||
// due to the circular order, the turn directions are unique
|
||||
// first_direction != third_direction is implied
|
||||
BOOST_ASSERT(first_direction != third_direction);
|
||||
assignTrivialTurns(via_edge, intersection, 1, up_to);
|
||||
}
|
||||
else if (2 >= (intersection[1].entry_allowed + intersection[2].entry_allowed +
|
||||
intersection[3].entry_allowed))
|
||||
@ -840,13 +507,18 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
|
||||
handleDistinctConflict(via_edge, intersection[3], intersection[1]);
|
||||
}
|
||||
}
|
||||
else if (intersection[1].entry_allowed && intersection[2].entry_allowed &&
|
||||
intersection[3].entry_allowed &&
|
||||
angularDeviation(intersection[1].turn.angle, intersection[2].turn.angle) >=
|
||||
// From here on out, intersection[1-3].entry_allowed has to be true (Otherwise we would have
|
||||
// triggered 2>= ...)
|
||||
//
|
||||
// Conflicting Turns, but at least farther than what we call a narrow turn
|
||||
else if (angularDeviation(intersection[1].turn.angle, intersection[2].turn.angle) >=
|
||||
NARROW_TURN_ANGLE &&
|
||||
angularDeviation(intersection[2].turn.angle, intersection[3].turn.angle) >=
|
||||
NARROW_TURN_ANGLE)
|
||||
{
|
||||
BOOST_ASSERT(intersection[1].entry_allowed && intersection[2].entry_allowed &&
|
||||
intersection[3].entry_allowed);
|
||||
|
||||
intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]),
|
||||
DirectionModifier::SharpRight};
|
||||
intersection[2].turn.instruction = {findBasicTurnType(via_edge, intersection[2]),
|
||||
@ -854,9 +526,7 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
|
||||
intersection[3].turn.instruction = {findBasicTurnType(via_edge, intersection[3]),
|
||||
DirectionModifier::SlightRight};
|
||||
}
|
||||
else if (intersection[1].entry_allowed && intersection[2].entry_allowed &&
|
||||
intersection[3].entry_allowed &&
|
||||
((first_direction == second_direction && second_direction == third_direction) ||
|
||||
else if (((first_direction == second_direction && second_direction == third_direction) ||
|
||||
(first_direction == second_direction &&
|
||||
angularDeviation(intersection[2].turn.angle, intersection[3].turn.angle) <
|
||||
GROUP_ANGLE) ||
|
||||
@ -864,28 +534,22 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
|
||||
angularDeviation(intersection[1].turn.angle, intersection[2].turn.angle) <
|
||||
GROUP_ANGLE)))
|
||||
{
|
||||
intersection[1].turn.instruction = {
|
||||
detail::isRampClass(intersection[1].turn.eid, node_based_graph) ? ThirdRamp
|
||||
: ThirdTurn,
|
||||
second_direction};
|
||||
intersection[2].turn.instruction = {
|
||||
detail::isRampClass(intersection[2].turn.eid, node_based_graph) ? SecondRamp
|
||||
: SecondTurn,
|
||||
second_direction};
|
||||
intersection[3].turn.instruction = {
|
||||
detail::isRampClass(intersection[3].turn.eid, node_based_graph) ? FirstRamp
|
||||
: FirstTurn,
|
||||
second_direction};
|
||||
|
||||
BOOST_ASSERT(intersection[1].entry_allowed && intersection[2].entry_allowed &&
|
||||
intersection[3].entry_allowed);
|
||||
// count backwards from the slightest turn
|
||||
assignCountingTurns(via_edge, intersection, 3, 0, second_direction);
|
||||
}
|
||||
else if (intersection[1].entry_allowed && intersection[2].entry_allowed &&
|
||||
intersection[3].entry_allowed &&
|
||||
((first_direction == second_direction &&
|
||||
else if (((first_direction == second_direction &&
|
||||
angularDeviation(intersection[2].turn.angle, intersection[3].turn.angle) >=
|
||||
GROUP_ANGLE) ||
|
||||
(second_direction == third_direction &&
|
||||
angularDeviation(intersection[1].turn.angle, intersection[2].turn.angle) >=
|
||||
GROUP_ANGLE)))
|
||||
{
|
||||
BOOST_ASSERT(intersection[1].entry_allowed && intersection[2].entry_allowed &&
|
||||
intersection[3].entry_allowed);
|
||||
|
||||
if (angularDeviation(intersection[2].turn.angle, intersection[3].turn.angle) >=
|
||||
GROUP_ANGLE)
|
||||
{
|
||||
@ -900,21 +564,6 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
|
||||
handleDistinctConflict(via_edge, intersection[3], intersection[2]);
|
||||
}
|
||||
}
|
||||
else if ((first_direction == second_direction &&
|
||||
intersection[1].entry_allowed != intersection[2].entry_allowed) ||
|
||||
(second_direction == third_direction &&
|
||||
intersection[2].entry_allowed != intersection[3].entry_allowed))
|
||||
{
|
||||
if (intersection[1].entry_allowed)
|
||||
intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]),
|
||||
first_direction};
|
||||
if (intersection[2].entry_allowed)
|
||||
intersection[2].turn.instruction = {findBasicTurnType(via_edge, intersection[2]),
|
||||
second_direction};
|
||||
if (intersection[3].entry_allowed)
|
||||
intersection[3].turn.instruction = {findBasicTurnType(via_edge, intersection[3]),
|
||||
third_direction};
|
||||
}
|
||||
else
|
||||
{
|
||||
util::SimpleLogger().Write(logWARNING)
|
||||
@ -929,47 +578,18 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge,
|
||||
<< " Road Class: " << (int)out_data.road_classification.road_class;
|
||||
}
|
||||
|
||||
for (std::size_t i = 1; i < up_to; ++i)
|
||||
if (intersection[i].entry_allowed)
|
||||
intersection[i].turn.instruction = {
|
||||
findBasicTurnType(via_edge, intersection[i]),
|
||||
getTurnDirection(intersection[i].turn.angle)};
|
||||
assignTrivialTurns(via_edge, intersection, 1, up_to);
|
||||
}
|
||||
}
|
||||
else if (up_to == 5)
|
||||
{
|
||||
if (intersection[4].entry_allowed)
|
||||
intersection[4].turn.instruction = {
|
||||
detail::isRampClass(intersection[4].turn.eid, node_based_graph) ? FirstRamp
|
||||
: FirstTurn,
|
||||
DirectionModifier::Right};
|
||||
if (intersection[3].entry_allowed)
|
||||
intersection[3].turn.instruction = {
|
||||
detail::isRampClass(intersection[3].turn.eid, node_based_graph) ? SecondRamp
|
||||
: SecondTurn,
|
||||
DirectionModifier::Right};
|
||||
if (intersection[2].entry_allowed)
|
||||
intersection[2].turn.instruction = {
|
||||
detail::isRampClass(intersection[2].turn.eid, node_based_graph) ? ThirdRamp
|
||||
: ThirdTurn,
|
||||
DirectionModifier::Right};
|
||||
if (intersection[1].entry_allowed)
|
||||
intersection[1].turn.instruction = {
|
||||
detail::isRampClass(intersection[1].turn.eid, node_based_graph) ? FourthRamp
|
||||
: FourthTurn,
|
||||
DirectionModifier::Right};
|
||||
|
||||
// count backwards from the slightest turn
|
||||
assignCountingTurns(via_edge, intersection, 4, 0, DirectionModifier::Right);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::size_t i = 1; i < up_to; ++i)
|
||||
{
|
||||
auto &road = intersection[i];
|
||||
if (!road.entry_allowed)
|
||||
continue;
|
||||
road.turn.instruction = {detail::isRampClass(road.turn.eid, node_based_graph) ? Ramp
|
||||
: Turn,
|
||||
getTurnDirection(road.turn.angle)};
|
||||
}
|
||||
assignTrivialTurns(via_edge, intersection, 1, up_to);
|
||||
}
|
||||
return intersection;
|
||||
}
|
||||
@ -993,7 +613,7 @@ std::pair<std::size_t, std::size_t> TurnHandler::findFork(const Intersection &in
|
||||
if (best_deviation <= NARROW_TURN_ANGLE)
|
||||
{
|
||||
std::size_t left = best, right = best;
|
||||
if (intersection[left].turn.angle >= 180)
|
||||
if (intersection[best].turn.angle >= 180)
|
||||
{
|
||||
// due to best > 1, we can safely decrement right
|
||||
--right;
|
||||
@ -1018,12 +638,11 @@ std::pair<std::size_t, std::size_t> TurnHandler::findFork(const Intersection &in
|
||||
--right;
|
||||
|
||||
// TODO check whether 2*NARROW_TURN is too large
|
||||
if (right < left &&
|
||||
if (0 < right && right < left &&
|
||||
angularDeviation(intersection[left].turn.angle,
|
||||
intersection[(left + 1) % intersection.size()].turn.angle) >=
|
||||
2 * NARROW_TURN_ANGLE &&
|
||||
intersection[(left + 1) % intersection.size()].turn.angle) >= 60 &&
|
||||
angularDeviation(intersection[right].turn.angle, intersection[right - 1].turn.angle) >=
|
||||
2 * NARROW_TURN_ANGLE)
|
||||
60)
|
||||
return std::make_pair(right, left);
|
||||
}
|
||||
return std::make_pair(std::size_t{0}, std::size_t{0});
|
||||
|
Loading…
Reference in New Issue
Block a user