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

150 lines
5.4 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"
#include "util/guidance/toolkit.hpp"
2016-03-23 08:04:23 -04:00
#include "util/simple_logger.hpp"
2016-02-26 11:33:18 -05:00
#include <cstddef>
2016-03-04 09:10:33 -05:00
#include <iomanip>
2016-03-23 08:04:23 -04:00
#include <limits>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
2016-02-26 11:33:18 -05:00
using osrm::util::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.IsCompatibleTo(to);
}
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),
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
{
}
2016-05-13 13:18:00 -04:00
Intersection TurnAnalysis::assignTurnTypes(const NodeID from_nid,
const EdgeID via_eid,
Intersection intersection) const
{
// Roundabouts are a main priority. If there is a roundabout instruction present, we process the
// turn as a roundabout
if (roundabout_handler.canProcess(from_nid, via_eid, intersection))
{
intersection = roundabout_handler(from_nid, via_eid, 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(from_nid, via_eid, std::move(intersection));
if (motorway_handler.canProcess(from_nid, via_eid, intersection))
{
intersection = motorway_handler(from_nid, via_eid, std::move(intersection));
}
else
{
BOOST_ASSERT(turn_handler.canProcess(from_nid, via_eid, intersection));
intersection = turn_handler(from_nid, via_eid, std::move(intersection));
}
2016-03-07 08:52:26 -05:00
}
// Handle sliproads
2016-07-04 06:19:49 -04:00
intersection = sliproad_handler(from_nid, via_eid, 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
2016-07-26 09:00:58 -04:00
if (node_based_graph.GetEdgeData(via_eid).road_classification.IsMotorwayClass())
2016-06-15 08:25:22 -04:00
{
std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) {
if (road.turn.instruction.type == TurnType::OnRamp)
road.turn.instruction.type = TurnType::OffRamp;
});
}
2016-05-13 13:18:00 -04:00
return intersection;
}
std::vector<TurnOperation>
TurnAnalysis::transformIntersectionIntoTurns(const Intersection &intersection) const
{
std::vector<TurnOperation> turns;
for (auto road : intersection)
if (road.entry_allowed)
turns.emplace_back(road.turn);
return turns;
}
Intersection TurnAnalysis::getIntersection(const NodeID from_nid, const EdgeID via_eid) const
{
return intersection_generator(from_nid, via_eid);
}
// Sets basic turn types as fallback for otherwise unhandled turns
2016-04-11 06:51:06 -04:00
Intersection
TurnAnalysis::setTurnTypes(const NodeID from_nid, 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.turn.eid;
const NodeID to_nid = node_based_graph.GetTarget(onto_edge);
2016-02-26 11:33:18 -05:00
2016-05-27 15:05:04 -04:00
road.turn.instruction = {TurnType::Turn,
(from_nid == to_nid) ? DirectionModifier::UTurn
: getTurnDirection(road.turn.angle)};
2016-03-04 06:17:06 -05:00
}
return intersection;
2016-03-04 06:17:06 -05:00
}
2016-05-13 13:18:00 -04:00
const IntersectionGenerator &TurnAnalysis::getGenerator() const { return intersection_generator; }
2016-03-01 16:30:31 -05:00
} // namespace guidance
} // namespace extractor
2016-02-26 11:33:18 -05:00
} // namespace osrm