Added driveway handler
This commit is contained in:
parent
09df8d47a5
commit
df4f0d043a
48
features/guidance/driveway.feature
Normal file
48
features/guidance/driveway.feature
Normal 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 |
|
41
include/extractor/guidance/driveway_handler.hpp
Normal file
41
include/extractor/guidance/driveway_handler.hpp
Normal 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 */
|
@ -114,6 +114,8 @@ class IntersectionHandler
|
|||||||
// For this scenario returns intersection at `b` and `b`.
|
// For this scenario returns intersection at `b` and `b`.
|
||||||
boost::optional<IntersectionHandler::IntersectionViewAndNode>
|
boost::optional<IntersectionHandler::IntersectionViewAndNode>
|
||||||
getNextIntersection(const NodeID at, const EdgeID via) const;
|
getNextIntersection(const NodeID at, const EdgeID via) const;
|
||||||
|
|
||||||
|
bool isSameName(const EdgeID source_edge_id, const EdgeID target_edge_id) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Impl.
|
// Impl.
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define OSRM_EXTRACTOR_TURN_ANALYSIS
|
#define OSRM_EXTRACTOR_TURN_ANALYSIS
|
||||||
|
|
||||||
#include "extractor/compressed_edge_container.hpp"
|
#include "extractor/compressed_edge_container.hpp"
|
||||||
|
#include "extractor/guidance/driveway_handler.hpp"
|
||||||
#include "extractor/guidance/intersection.hpp"
|
#include "extractor/guidance/intersection.hpp"
|
||||||
#include "extractor/guidance/intersection_generator.hpp"
|
#include "extractor/guidance/intersection_generator.hpp"
|
||||||
#include "extractor/guidance/intersection_normalization_operation.hpp"
|
#include "extractor/guidance/intersection_normalization_operation.hpp"
|
||||||
@ -87,6 +88,7 @@ class TurnAnalysis
|
|||||||
const TurnHandler turn_handler;
|
const TurnHandler turn_handler;
|
||||||
const SliproadHandler sliproad_handler;
|
const SliproadHandler sliproad_handler;
|
||||||
const SuppressModeHandler suppress_mode_handler;
|
const SuppressModeHandler suppress_mode_handler;
|
||||||
|
const DrivewayHandler driveway_handler;
|
||||||
|
|
||||||
// Utility function, setting basic turn types. Prepares for normal turn handling.
|
// Utility function, setting basic turn types. Prepares for normal turn handling.
|
||||||
Intersection
|
Intersection
|
||||||
|
75
src/extractor/guidance/driveway_handler.cpp
Normal file
75
src/extractor/guidance/driveway_handler.cpp
Normal 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
|
@ -436,6 +436,19 @@ IntersectionHandler::getNextIntersection(const NodeID at, const EdgeID via) cons
|
|||||||
IntersectionViewAndNode{std::move(intersection), intersection_node});
|
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 guidance
|
||||||
} // namespace extractor
|
} // namespace extractor
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
@ -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.
|
// 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)
|
if (sliproad_found && main_road.instruction.type == TurnType::Fork)
|
||||||
{
|
{
|
||||||
const auto &source_edge_data = node_based_graph.GetEdgeData(source_edge_id);
|
if (isSameName(source_edge_id, main_road.eid))
|
||||||
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 (angularDeviation(main_road.angle, STRAIGHT_ANGLE) < 5)
|
if (angularDeviation(main_road.angle, STRAIGHT_ANGLE) < 5)
|
||||||
intersection[*obvious].instruction.type = TurnType::Suppressed;
|
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 =
|
intersection[*obvious].instruction.direction_modifier =
|
||||||
getTurnDirection(intersection[*obvious].angle);
|
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.type = TurnType::NewName;
|
||||||
intersection[*obvious].instruction.direction_modifier =
|
intersection[*obvious].instruction.direction_modifier =
|
||||||
|
@ -68,7 +68,12 @@ TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
|
|||||||
node_based_graph,
|
node_based_graph,
|
||||||
coordinates,
|
coordinates,
|
||||||
name_table,
|
name_table,
|
||||||
street_name_suffix_table)
|
street_name_suffix_table),
|
||||||
|
driveway_handler(intersection_generator,
|
||||||
|
node_based_graph,
|
||||||
|
coordinates,
|
||||||
|
name_table,
|
||||||
|
street_name_suffix_table)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,8 +137,14 @@ Intersection TurnAnalysis::AssignTurnTypes(const NodeID node_prior_to_intersecti
|
|||||||
// set initial defaults for normal turns and modifier based on angle
|
// set initial defaults for normal turns and modifier based on angle
|
||||||
intersection =
|
intersection =
|
||||||
setTurnTypes(node_prior_to_intersection, entering_via_edge, std::move(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))
|
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(
|
intersection = motorway_handler(
|
||||||
node_prior_to_intersection, entering_via_edge, std::move(intersection));
|
node_prior_to_intersection, entering_via_edge, std::move(intersection));
|
||||||
|
Loading…
Reference in New Issue
Block a user