osrm-backend/src/extractor/guidance/turn_analysis.cpp

191 lines
7.6 KiB
C++
Raw Normal View History

#include "extractor/guidance/turn_analysis.hpp"
2016-07-26 09:00:58 -04:00
#include "extractor/guidance/constants.hpp"
#include "extractor/guidance/road_classification.hpp"
2016-03-03 09:36:03 -05:00
#include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp"
2016-02-26 11:33:18 -05:00
#include <cstddef>
#include <set>
#include <unordered_set>
#include <utility>
2016-02-26 11:33:18 -05:00
using osrm::extractor::guidance::getTurnDirection;
namespace osrm
{
namespace extractor
{
2016-03-01 16:30:31 -05:00
namespace guidance
{
using EdgeData = util::NodeBasedDynamicGraph::EdgeData;
bool requiresAnnouncement(const EdgeData &from, const EdgeData &to)
2016-03-04 06:17:06 -05:00
{
return !from.CanCombineWith(to);
2016-03-04 06:17:06 -05:00
}
2016-03-08 06:40:45 -05:00
TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
const std::vector<QueryNode> &node_info_list,
const RestrictionMap &restriction_map,
const std::unordered_set<NodeID> &barrier_nodes,
const CompressedEdgeContainer &compressed_edge_container,
2016-04-22 05:31:46 -04:00
const util::NameTable &name_table,
const SuffixTable &street_name_suffix_table,
const ProfileProperties &profile_properties)
: node_based_graph(node_based_graph), intersection_generator(node_based_graph,
restriction_map,
barrier_nodes,
node_info_list,
compressed_edge_container),
intersection_normalizer(node_based_graph,
node_info_list,
name_table,
street_name_suffix_table,
intersection_generator),
roundabout_handler(node_based_graph,
node_info_list,
compressed_edge_container,
name_table,
street_name_suffix_table,
2016-08-15 06:43:26 -04:00
profile_properties,
intersection_generator),
motorway_handler(node_based_graph,
node_info_list,
name_table,
street_name_suffix_table,
intersection_generator),
turn_handler(node_based_graph,
node_info_list,
name_table,
street_name_suffix_table,
intersection_generator),
2016-07-04 06:19:49 -04:00
sliproad_handler(intersection_generator,
node_based_graph,
node_info_list,
name_table,
street_name_suffix_table)
2016-03-07 08:52:26 -05:00
{
}
Intersection TurnAnalysis::operator()(const NodeID node_prior_to_intersection,
const EdgeID entering_via_edge) const
{
TurnAnalysis::ShapeResult shape_result =
ComputeIntersectionShapes(node_based_graph.GetTarget(entering_via_edge));
// assign valid flags to normalised_shape
const auto intersection_view = intersection_generator.TransformIntersectionShapeIntoView(
node_prior_to_intersection,
entering_via_edge,
shape_result.normalised_intersection_shape,
shape_result.intersection_shape,
shape_result.merging_map);
// assign the turn types to the intersection
return AssignTurnTypes(node_prior_to_intersection, entering_via_edge, intersection_view);
}
Intersection TurnAnalysis::AssignTurnTypes(const NodeID node_prior_to_intersection,
const EdgeID entering_via_edge,
const IntersectionView &intersection_view) const
{
// Roundabouts are a main priority. If there is a roundabout instruction present, we process the
// turn as a roundabout
// the following lines create a partly invalid intersection object. We might want to refactor
// this at some point
Intersection intersection;
intersection.reserve(intersection_view.size());
std::transform(intersection_view.begin(),
intersection_view.end(),
std::back_inserter(intersection),
[&](const IntersectionViewData &data) {
return ConnectedRoad(data,
{TurnType::Invalid, DirectionModifier::UTurn},
INVALID_LANE_DATAID);
});
if (roundabout_handler.canProcess(node_prior_to_intersection, entering_via_edge, intersection))
{
intersection = roundabout_handler(
node_prior_to_intersection, entering_via_edge, std::move(intersection));
2016-03-07 08:52:26 -05:00
}
else
{
// 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(
node_prior_to_intersection, entering_via_edge, intersection))
{
intersection = motorway_handler(
node_prior_to_intersection, entering_via_edge, std::move(intersection));
}
else
{
BOOST_ASSERT(turn_handler.canProcess(
node_prior_to_intersection, entering_via_edge, intersection));
intersection = turn_handler(
node_prior_to_intersection, entering_via_edge, std::move(intersection));
}
2016-03-07 08:52:26 -05:00
}
// Handle sliproads
if (sliproad_handler.canProcess(node_prior_to_intersection, entering_via_edge, intersection))
intersection = sliproad_handler(
node_prior_to_intersection, entering_via_edge, std::move(intersection));
2016-06-15 08:25:22 -04:00
// Turn On Ramps Into Off Ramps, if we come from a motorway-like road
if (node_based_graph.GetEdgeData(entering_via_edge).road_classification.IsMotorwayClass())
2016-06-15 08:25:22 -04:00
{
std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) {
if (road.instruction.type == TurnType::OnRamp)
road.instruction.type = TurnType::OffRamp;
2016-06-15 08:25:22 -04:00
});
}
2016-05-13 13:18:00 -04:00
return intersection;
}
TurnAnalysis::ShapeResult
TurnAnalysis::ComputeIntersectionShapes(const NodeID node_at_center_of_intersection) const
2016-05-13 13:18:00 -04:00
{
ShapeResult intersection_shape;
intersection_shape.intersection_shape =
intersection_generator.ComputeIntersectionShape(node_at_center_of_intersection);
std::tie(intersection_shape.normalised_intersection_shape, intersection_shape.merging_map) =
intersection_normalizer(node_at_center_of_intersection,
intersection_shape.intersection_shape);
return intersection_shape;
}
// Sets basic turn types as fallback for otherwise unhandled turns
Intersection TurnAnalysis::setTurnTypes(const NodeID node_prior_to_intersection,
const EdgeID,
Intersection intersection) const
2016-02-26 11:33:18 -05:00
{
for (auto &road : intersection)
2016-02-26 11:33:18 -05:00
{
if (!road.entry_allowed)
2016-02-26 11:33:18 -05:00
continue;
2016-03-03 09:36:03 -05:00
const EdgeID onto_edge = road.eid;
const NodeID to_nid = node_based_graph.GetTarget(onto_edge);
2016-02-26 11:33:18 -05:00
road.instruction = {TurnType::Turn,
(node_prior_to_intersection == to_nid) ? DirectionModifier::UTurn
: getTurnDirection(road.angle)};
2016-03-04 06:17:06 -05:00
}
return intersection;
2016-03-04 06:17:06 -05:00
}
const IntersectionGenerator &TurnAnalysis::GetIntersectionGenerator() const
{
return intersection_generator;
}
2016-05-13 13:18:00 -04:00
2016-03-01 16:30:31 -05:00
} // namespace guidance
} // namespace extractor
2016-02-26 11:33:18 -05:00
} // namespace osrm