Added driveway handler

This commit is contained in:
Michael Krasnyk 2017-06-13 15:17:13 +02:00 committed by Patrick Niklaus
parent 09df8d47a5
commit df4f0d043a
8 changed files with 196 additions and 14 deletions

View File

@ -0,0 +1,48 @@
@driveway @guidance
Feature: Driveways intersections
Background:
Given the profile "car"
Given a grid size of 5 meters
Scenario: Road with a turn to service road
Given the node map
"""
a
~.
b----c----d
|
e
"""
And the ways
| nodes | highway | name | oneway |
| abc | trunk | first | yes |
| cd | trunk | second | yes |
| be | service | parking | yes |
When I route I should get
| waypoints | route | turns | locations |
| a,d | first,second | depart,arrive | a,d |
Scenario: Turn Instead of Ramp
Given the node map
"""
a
~.
b----c----d
|
e
"""
And the ways
| nodes | highway | name | oneway |
| ab | trunk | | yes |
| bc | trunk | | yes |
| cd | trunk | second | yes |
| be | service | parking | yes |
When I route I should get
| waypoints | route | turns | locations |
| a,d | ,second | depart,arrive | a,d |

View File

@ -0,0 +1,41 @@
#ifndef OSRM_EXTRACTOR_GUIDANCE_DRIVEWAY_HANDLER_HPP
#define OSRM_EXTRACTOR_GUIDANCE_DRIVEWAY_HANDLER_HPP
#include "extractor/guidance/intersection_handler.hpp"
namespace osrm
{
namespace extractor
{
namespace guidance
{
// Intersection handlers deal with all issues related to intersections.
// They assign appropriate turn operations to the TurnOperations.
class DrivewayHandler final : public IntersectionHandler
{
public:
DrivewayHandler(const IntersectionGenerator &intersection_generator,
const util::NodeBasedDynamicGraph &node_based_graph,
const std::vector<util::Coordinate> &coordinates,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table);
~DrivewayHandler() override final = default;
// check whether the handler can actually handle the intersection
bool canProcess(const NodeID nid,
const EdgeID via_eid,
const Intersection &intersection) const override final;
// process the intersection
Intersection operator()(const NodeID nid,
const EdgeID via_eid,
Intersection intersection) const override final;
};
} // namespace guidance
} // namespace extractor
} // namespace osrm
#endif /* OSRM_EXTRACTOR_GUIDANCE_DRIVEWAY_HANDLER_HPP */

View File

@ -114,6 +114,8 @@ class IntersectionHandler
// For this scenario returns intersection at `b` and `b`.
boost::optional<IntersectionHandler::IntersectionViewAndNode>
getNextIntersection(const NodeID at, const EdgeID via) const;
bool isSameName(const EdgeID source_edge_id, const EdgeID target_edge_id) const;
};
// Impl.

View File

@ -2,6 +2,7 @@
#define OSRM_EXTRACTOR_TURN_ANALYSIS
#include "extractor/compressed_edge_container.hpp"
#include "extractor/guidance/driveway_handler.hpp"
#include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/intersection_generator.hpp"
#include "extractor/guidance/intersection_normalization_operation.hpp"
@ -87,6 +88,7 @@ class TurnAnalysis
const TurnHandler turn_handler;
const SliproadHandler sliproad_handler;
const SuppressModeHandler suppress_mode_handler;
const DrivewayHandler driveway_handler;
// Utility function, setting basic turn types. Prepares for normal turn handling.
Intersection

View File

@ -0,0 +1,75 @@
#include "extractor/guidance/driveway_handler.hpp"
#include "util/assert.hpp"
using osrm::extractor::guidance::getTurnDirection;
using osrm::util::angularDeviation;
namespace osrm
{
namespace extractor
{
namespace guidance
{
DrivewayHandler::DrivewayHandler(const IntersectionGenerator &intersection_generator,
const util::NodeBasedDynamicGraph &node_based_graph,
const std::vector<util::Coordinate> &coordinates,
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table)
: IntersectionHandler(node_based_graph,
coordinates,
name_table,
street_name_suffix_table,
intersection_generator)
{
}
// The intersection without major roads needs to pass by service roads (bd, be)
// d
// .
// a--->b--->c
// .
// e
bool DrivewayHandler::canProcess(const NodeID /*nid*/,
const EdgeID /*via_eid*/,
const Intersection &intersection) const
{
const auto from_eid = intersection.front().eid;
if (intersection.size() <= 2 ||
node_based_graph.GetEdgeData(from_eid).road_classification.IsLowPriorityRoadClass())
return false;
auto low_priority_count =
std::count_if(intersection.begin(), intersection.end(), [this](const auto &road) {
return node_based_graph.GetEdgeData(road.eid)
.road_classification.IsLowPriorityRoadClass();
});
// Process intersection if it has two edges with normal priority and one is the entry edge,
// and also has at least one edge with lower priority
return static_cast<std::size_t>(low_priority_count) + 2 == intersection.size();
}
Intersection DrivewayHandler::
operator()(const NodeID nid, const EdgeID source_edge_id, Intersection intersection) const
{
auto road =
std::find_if(intersection.begin() + 1, intersection.end(), [this](const auto &road) {
return !node_based_graph.GetEdgeData(road.eid)
.road_classification.IsLowPriorityRoadClass();
});
(void)nid;
OSRM_ASSERT(road != intersection.end(), coordinates[nid]);
road->instruction.type =
isSameName(source_edge_id, road->eid) ? TurnType::NoTurn : TurnType::NewName;
return intersection;
}
} // namespace guidance
} // namespace extractor
} // namespace osrm

View File

@ -436,6 +436,19 @@ IntersectionHandler::getNextIntersection(const NodeID at, const EdgeID via) cons
IntersectionViewAndNode{std::move(intersection), intersection_node});
}
bool IntersectionHandler::isSameName(const EdgeID source_edge_id, const EdgeID target_edge_id) const
{
const auto &source_edge_data = node_based_graph.GetEdgeData(source_edge_id);
const auto &target_edge_data = node_based_graph.GetEdgeData(target_edge_id);
return source_edge_data.name_id != EMPTY_NAMEID && //
target_edge_data.name_id != EMPTY_NAMEID && //
!util::guidance::requiresNameAnnounced(source_edge_data.name_id,
target_edge_data.name_id,
name_table,
street_name_suffix_table); //
}
} // namespace guidance
} // namespace extractor
} // namespace osrm

View File

@ -473,17 +473,7 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
// In those cases the obvious non-Sliproad is now obvious and we discard the Fork turn type.
if (sliproad_found && main_road.instruction.type == TurnType::Fork)
{
const auto &source_edge_data = node_based_graph.GetEdgeData(source_edge_id);
const auto &main_road_data = node_based_graph.GetEdgeData(main_road.eid);
const auto same_name = source_edge_data.name_id != EMPTY_NAMEID && //
main_road_data.name_id != EMPTY_NAMEID && //
!util::guidance::requiresNameAnnounced(source_edge_data.name_id,
main_road_data.name_id,
name_table,
street_name_suffix_table); //
if (same_name)
if (isSameName(source_edge_id, main_road.eid))
{
if (angularDeviation(main_road.angle, STRAIGHT_ANGLE) < 5)
intersection[*obvious].instruction.type = TurnType::Suppressed;
@ -492,7 +482,7 @@ operator()(const NodeID /*nid*/, const EdgeID source_edge_id, Intersection inter
intersection[*obvious].instruction.direction_modifier =
getTurnDirection(intersection[*obvious].angle);
}
else if (main_road_data.name_id != EMPTY_NAMEID)
else if (node_based_graph.GetEdgeData(main_road.eid).name_id != EMPTY_NAMEID)
{
intersection[*obvious].instruction.type = TurnType::NewName;
intersection[*obvious].instruction.direction_modifier =

View File

@ -65,6 +65,11 @@ TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
name_table,
street_name_suffix_table),
suppress_mode_handler(intersection_generator,
node_based_graph,
coordinates,
name_table,
street_name_suffix_table),
driveway_handler(intersection_generator,
node_based_graph,
coordinates,
name_table,
@ -132,7 +137,13 @@ Intersection TurnAnalysis::AssignTurnTypes(const NodeID node_prior_to_intersecti
// set initial defaults for normal turns and modifier based on angle
intersection =
setTurnTypes(node_prior_to_intersection, entering_via_edge, std::move(intersection));
if (motorway_handler.canProcess(
if (driveway_handler.canProcess(
node_prior_to_intersection, entering_via_edge, intersection))
{
intersection = driveway_handler(
node_prior_to_intersection, entering_via_edge, std::move(intersection));
}
else if (motorway_handler.canProcess(
node_prior_to_intersection, entering_via_edge, intersection))
{
intersection = motorway_handler(