handle steep off-ramps

This commit is contained in:
Moritz Kobitzsch 2016-06-15 14:25:22 +02:00 committed by Patrick Niklaus
parent 27a94f3ca6
commit 3c8781855e
No known key found for this signature in database
GPG Key ID: E426891B5F978B1B
4 changed files with 47 additions and 18 deletions

View File

@ -216,3 +216,21 @@ Feature: Motorway Guidance
| waypoints | route | turns |
| d,c | db,abc,abc | depart,merge slight left,arrive |
| e,c | eb,abc,abc | depart,merge slight right,arrive |
Scenario: Handle 90 degree off ramps correctly
Given the node map
| a | | | | |
| x | b | | c | y |
| | | | d | |
And the ways
| nodes | name | highway | oneway |
| ab | On | motorway_link | yes |
| xb | Hwy | motorway | |
| bc | Hwy | motorway | |
| cd | Off | motorway_link | yes |
| cy | Hwy | motorway | |
When I route I should get
| waypoints | route | turns |
| a,d | On,Hwy,Off,Off | depart,merge slight right,off ramp right,arrive |

View File

@ -58,6 +58,12 @@ inline bool isLinkClass(const FunctionalRoadClass road_class)
road_class == FunctionalRoadClass::TERTIARY_LINK;
}
// check wheter a class is a motorway like class
inline bool isMotorwayClass(const FunctionalRoadClass road_class)
{
return road_class == FunctionalRoadClass::MOTORWAY || road_class == FunctionalRoadClass::TRUNK;
}
// TODO augment this with all data required for guidance generation
struct RoadClassificationData
{

View File

@ -1,5 +1,6 @@
#include "extractor/guidance/motorway_handler.hpp"
#include "extractor/guidance/classification_data.hpp"
#include "extractor/guidance/constants.hpp"
#include "extractor/guidance/motorway_handler.hpp"
#include "extractor/guidance/toolkit.hpp"
#include "util/guidance/toolkit.hpp"
@ -21,10 +22,6 @@ namespace guidance
{
namespace detail
{
inline bool isMotorwayClass(const FunctionalRoadClass road_class)
{
return road_class == FunctionalRoadClass::MOTORWAY || road_class == FunctionalRoadClass::TRUNK;
}
inline bool isMotorwayClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_based_graph)
{
@ -92,7 +89,7 @@ operator()(const NodeID, const EdgeID via_eid, Intersection intersection) const
const auto &in_data = node_based_graph.GetEdgeData(via_eid);
// coming from motorway
if (detail::isMotorwayClass(in_data.road_classification.road_class))
if (isMotorwayClass(in_data.road_classification.road_class))
{
intersection = fromMotorway(via_eid, std::move(intersection));
std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) {
@ -111,7 +108,7 @@ operator()(const NodeID, const EdgeID via_eid, Intersection intersection) const
Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection intersection) const
{
const auto &in_data = node_based_graph.GetEdgeData(via_eid);
BOOST_ASSERT(detail::isMotorwayClass(in_data.road_classification.road_class));
BOOST_ASSERT(isMotorwayClass(in_data.road_classification.road_class));
const auto countExitingMotorways = [this](const Intersection &intersection) {
unsigned count = 0;
@ -130,7 +127,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
if (road.turn.angle != 0 && in_data.name_id == out_data.name_id &&
in_data.name_id != EMPTY_NAMEID &&
detail::isMotorwayClass(out_data.road_classification.road_class))
isMotorwayClass(out_data.road_classification.road_class))
return road.turn.angle;
}
return intersection[0].turn.angle;
@ -142,7 +139,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
for (const auto &road : intersection)
{
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
if (detail::isMotorwayClass(out_data.road_classification.road_class) &&
if (isMotorwayClass(out_data.road_classification.road_class) &&
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < best)
{
best = angularDeviation(road.turn.angle, STRAIGHT_ANGLE);
@ -385,7 +382,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
{
// circular order indicates a merge to the left (0-3 onto 4
if (angularDeviation(intersection[1].turn.angle, STRAIGHT_ANGLE) <
2*NARROW_TURN_ANGLE)
2 * NARROW_TURN_ANGLE)
intersection[1].turn.instruction = {TurnType::Merge,
DirectionModifier::SlightLeft};
else // fallback
@ -453,8 +450,8 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
// M R
// | /
// R
if (detail::isMotorwayClass(node_based_graph.GetEdgeData(intersection[1].turn.eid)
.road_classification.road_class))
if (isMotorwayClass(node_based_graph.GetEdgeData(intersection[1].turn.eid)
.road_classification.road_class))
{
intersection[1].turn.instruction = {TurnType::Turn,
DirectionModifier::SlightRight};
@ -475,12 +472,11 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
for (auto &road : intersection)
{
const auto &edge_data = node_based_graph.GetEdgeData(road.turn.eid);
if (!road.entry_allowed &&
detail::isMotorwayClass(edge_data.road_classification.road_class))
if (!road.entry_allowed && isMotorwayClass(edge_data.road_classification.road_class))
{
passed_highway_entry = true;
}
else if (detail::isMotorwayClass(edge_data.road_classification.road_class))
else if (isMotorwayClass(edge_data.road_classification.road_class))
{
road.turn.instruction = {TurnType::Merge,
passed_highway_entry ? DirectionModifier::SlightRight
@ -516,9 +512,8 @@ Intersection MotorwayHandler::fallback(Intersection intersection) const
if (!road.entry_allowed)
continue;
const auto type = detail::isMotorwayClass(out_data.road_classification.road_class)
? TurnType::Merge
: TurnType::Turn;
const auto type = isMotorwayClass(out_data.road_classification.road_class) ? TurnType::Merge
: TurnType::Turn;
if (type == TurnType::Turn)
{

View File

@ -1,5 +1,6 @@
#include "extractor/guidance/constants.hpp"
#include "extractor/guidance/turn_analysis.hpp"
#include "extractor/guidance/classification_data.hpp"
#include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp"
@ -84,6 +85,15 @@ std::vector<TurnOperation> TurnAnalysis::getTurns(const NodeID from_nid, const E
// Handle sliproads
intersection = handleSliproads(via_eid, std::move(intersection));
// Turn On Ramps Into Off Ramps, if we come from a motorway-like road
if (isMotorwayClass(node_based_graph.GetEdgeData(via_eid).road_classification.road_class))
{
std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) {
if (road.turn.instruction.type == TurnType::OnRamp)
road.turn.instruction.type = TurnType::OffRamp;
});
}
std::vector<TurnOperation> turns;
for (auto road : intersection)
if (road.entry_allowed)