From cd03877c90ccd240d47da9ae0948da8bcbbf3397 Mon Sep 17 00:00:00 2001 From: Moritz Kobitzsch Date: Thu, 3 Nov 2016 10:18:27 +0100 Subject: [PATCH] link ConnectedRoad and TurnOperation via class hierarchy and empower intersection by adding basic functionality to pod type refactor extractor/toolkit into intersection --- include/engine/guidance/toolkit.hpp | 26 ++ include/extractor/guidance/intersection.hpp | 52 ++-- include/extractor/guidance/toolkit.hpp | 69 +---- include/server/service_handler.hpp | 6 +- include/util/debug.hpp | 3 +- src/engine/guidance/assemble_overview.cpp | 7 +- src/engine/guidance/lane_processing.cpp | 4 +- src/engine/guidance/post_processing.cpp | 6 +- src/extractor/edge_based_graph_factory.cpp | 5 +- src/extractor/geojson_debug_policies.cpp | 7 +- src/extractor/guidance/intersection.cpp | 106 +++++-- .../guidance/intersection_generator.cpp | 112 ++++---- .../guidance/intersection_handler.cpp | 224 +++++++-------- .../intersection_scenario_three_way.cpp | 6 +- src/extractor/guidance/motorway_handler.cpp | 186 ++++++------- .../guidance/node_based_graph_walker.cpp | 14 +- src/extractor/guidance/roundabout_handler.cpp | 14 +- src/extractor/guidance/sliproad_handler.cpp | 69 +++-- src/extractor/guidance/turn_analysis.cpp | 14 +- .../guidance/turn_classification.cpp | 14 +- src/extractor/guidance/turn_discovery.cpp | 14 +- src/extractor/guidance/turn_handler.cpp | 263 +++++++++--------- .../guidance/turn_lane_augmentation.cpp | 12 +- src/extractor/guidance/turn_lane_handler.cpp | 49 ++-- src/extractor/guidance/turn_lane_matcher.cpp | 41 ++- src/server/request_handler.cpp | 3 +- 26 files changed, 665 insertions(+), 661 deletions(-) diff --git a/include/engine/guidance/toolkit.hpp b/include/engine/guidance/toolkit.hpp index 98b7f2a6b..ca3a41498 100644 --- a/include/engine/guidance/toolkit.hpp +++ b/include/engine/guidance/toolkit.hpp @@ -75,6 +75,32 @@ template inline Fn forEachRoundabout(Iter first, It return fn; } +LaneID inline numLanesToTheRight(const engine::guidance::RouteStep &step) +{ + return step.intersections.front().lanes.first_lane_from_the_right; +} + +LaneID inline numLanesToTheLeft(const engine::guidance::RouteStep &step) +{ + LaneID const total = step.intersections.front().lane_description.size(); + return total - (step.intersections.front().lanes.lanes_in_turn + + step.intersections.front().lanes.first_lane_from_the_right); +} + +auto inline lanesToTheLeft(const engine::guidance::RouteStep &step) +{ + const auto &description = step.intersections.front().lane_description; + LaneID num_lanes_left = numLanesToTheLeft(step); + return boost::make_iterator_range(description.begin(), description.begin() + num_lanes_left); +} + +auto inline lanesToTheRight(const engine::guidance::RouteStep &step) +{ + const auto &description = step.intersections.front().lane_description; + LaneID num_lanes_right = numLanesToTheRight(step); + return boost::make_iterator_range(description.end() - num_lanes_right, description.end()); +} + } // namespace guidance } // namespace engine } // namespace osrm diff --git a/include/extractor/guidance/intersection.hpp b/include/extractor/guidance/intersection.hpp index 54bdec19d..02dbe62ff 100644 --- a/include/extractor/guidance/intersection.hpp +++ b/include/extractor/guidance/intersection.hpp @@ -6,6 +6,7 @@ #include "extractor/guidance/turn_instruction.hpp" #include "util/guidance/toolkit.hpp" +#include "util/node_based_graph.hpp" #include "util/typedefs.hpp" // EdgeID namespace osrm @@ -18,7 +19,7 @@ namespace guidance // Every Turn Operation describes a way of switching onto a segment, indicated by an EdgeID. The // associated turn is described by an angle and an instruction that is used to announce it. // The Turn Operation indicates what is exposed to the outside of the turn analysis. -struct TurnOperation final +struct TurnOperation { EdgeID eid; double angle; @@ -48,13 +49,23 @@ struct TurnOperation final // aaaaaaaa // // We would perceive a->c as a sharp turn, a->b as a slight turn, and b->c as a slight turn. -struct ConnectedRoad final +struct ConnectedRoad final : public TurnOperation { + using Base = TurnOperation; + ConnectedRoad(const TurnOperation turn, const bool entry_allowed = false); // a turn may be relevant to good instructions, even if we cannot enter the road bool entry_allowed; - TurnOperation turn; + + // used to sort the set of connected roads (we require sorting throughout turn handling) + bool compareByAngle(const ConnectedRoad &other) const; + + // make a left turn into an equivalent right turn and vice versa + void mirror(); + + OSRM_ATTR_WARN_UNUSED + ConnectedRoad getMirroredCopy() const; }; // small helper function to print the content of a connected road @@ -64,25 +75,24 @@ struct Intersection final : public std::vector { using Base = std::vector; - inline Base::iterator findClosestTurn(double angle) - { - return std::min_element(this->begin(), - this->end(), - [angle](const ConnectedRoad &lhs, const ConnectedRoad &rhs) { - return util::guidance::angularDeviation(lhs.turn.angle, angle) < - util::guidance::angularDeviation(rhs.turn.angle, angle); - }); - } + /* + * find the turn whose angle offers the least angularDeviation to the specified angle + * E.g. for turn angles [0,90,260] and a query of 180 we return the 260 degree turn (difference + * 80 over the difference of 90 to the 90 degree turn) + */ + Base::iterator findClosestTurn(double angle); + Base::const_iterator findClosestTurn(double angle) const; - inline Base::const_iterator findClosestTurn(double angle) const - { - return std::min_element(this->begin(), - this->end(), - [angle](const ConnectedRoad &lhs, const ConnectedRoad &rhs) { - return util::guidance::angularDeviation(lhs.turn.angle, angle) < - util::guidance::angularDeviation(rhs.turn.angle, angle); - }); - } + /* + * Check validity of the intersection object. We assume a few basic properties every set of + * connected roads should follow throughout guidance pre-processing. This utility function + * allows checking intersections for validity + */ + bool valid() const; + + // given all possible turns, which is the highest connected number of lanes per turn. This value + // is used, for example, during generation of intersections. + std::uint8_t getHighestConnectedLaneCount(const util::NodeBasedDynamicGraph &) const; }; Intersection::const_iterator findClosestTurn(const Intersection &intersection, const double angle); diff --git a/include/extractor/guidance/toolkit.hpp b/include/extractor/guidance/toolkit.hpp index b21e7159e..dc496edaa 100644 --- a/include/extractor/guidance/toolkit.hpp +++ b/include/extractor/guidance/toolkit.hpp @@ -18,12 +18,9 @@ #include "extractor/guidance/road_classification.hpp" #include "extractor/guidance/turn_instruction.hpp" -#include "engine/guidance/route_step.hpp" - #include #include #include -#include #include #include #include @@ -51,26 +48,6 @@ using util::guidance::leavesRoundabout; // To simplify handling of Left/Right hand turns, we can mirror turns and write an intersection // handler only for one side. The mirror function turns a left-hand turn in a equivalent right-hand // turn and vice versa. -OSRM_ATTR_WARN_UNUSED -inline ConnectedRoad mirror(ConnectedRoad road) -{ - const constexpr DirectionModifier::Enum mirrored_modifiers[] = {DirectionModifier::UTurn, - DirectionModifier::SharpLeft, - DirectionModifier::Left, - DirectionModifier::SlightLeft, - DirectionModifier::Straight, - DirectionModifier::SlightRight, - DirectionModifier::Right, - DirectionModifier::SharpRight}; - - if (angularDeviation(road.turn.angle, 0) > std::numeric_limits::epsilon()) - { - road.turn.angle = 360 - road.turn.angle; - road.turn.instruction.direction_modifier = - mirrored_modifiers[road.turn.instruction.direction_modifier]; - } - return road; -} inline bool hasRoundaboutType(const TurnInstruction instruction) { @@ -184,42 +161,6 @@ inline std::string applyAccessTokens(std::string lane_string, const std::string return result_string; } -LaneID inline numLanesToTheRight(const engine::guidance::RouteStep &step) -{ - return step.intersections.front().lanes.first_lane_from_the_right; -} - -LaneID inline numLanesToTheLeft(const engine::guidance::RouteStep &step) -{ - LaneID const total = step.intersections.front().lane_description.size(); - return total - (step.intersections.front().lanes.lanes_in_turn + - step.intersections.front().lanes.first_lane_from_the_right); -} - -auto inline lanesToTheLeft(const engine::guidance::RouteStep &step) -{ - const auto &description = step.intersections.front().lane_description; - LaneID num_lanes_left = numLanesToTheLeft(step); - return boost::make_iterator_range(description.begin(), description.begin() + num_lanes_left); -} - -auto inline lanesToTheRight(const engine::guidance::RouteStep &step) -{ - const auto &description = step.intersections.front().lane_description; - LaneID num_lanes_right = numLanesToTheRight(step); - return boost::make_iterator_range(description.end() - num_lanes_right, description.end()); -} - -inline std::uint8_t getLaneCountAtIntersection(const NodeID intersection_node, - const util::NodeBasedDynamicGraph &node_based_graph) -{ - std::uint8_t lanes = 0; - for (const EdgeID onto_edge : node_based_graph.GetAdjacentEdgeRange(intersection_node)) - lanes = std::max( - lanes, node_based_graph.GetEdgeData(onto_edge).road_classification.GetNumberOfLanes()); - return lanes; -} - inline bool obviousByRoadClass(const RoadClassification in_classification, const RoadClassification obvious_candidate, const RoadClassification compare_candidate) @@ -282,6 +223,16 @@ leastSquareRegression(const std::vector &coordinates) return {regression_first, regression_end}; } +inline std::uint8_t getLaneCountAtIntersection(const NodeID intersection_node, + const util::NodeBasedDynamicGraph &node_based_graph) +{ + std::uint8_t lanes = 0; + for (const EdgeID onto_edge : node_based_graph.GetAdjacentEdgeRange(intersection_node)) + lanes = std::max( + lanes, node_based_graph.GetEdgeData(onto_edge).road_classification.GetNumberOfLanes()); + return lanes; +} + } // namespace guidance } // namespace extractor } // namespace osrm diff --git a/include/server/service_handler.hpp b/include/server/service_handler.hpp index 25c7d0302..bc96c316c 100644 --- a/include/server/service_handler.hpp +++ b/include/server/service_handler.hpp @@ -23,12 +23,12 @@ namespace api struct ParsedURL; } - class ServiceHandlerInterface { -public: + public: virtual ~ServiceHandlerInterface() {} - virtual engine::Status RunQuery(api::ParsedURL parsed_url, service::BaseService::ResultT & result) = 0; + virtual engine::Status RunQuery(api::ParsedURL parsed_url, + service::BaseService::ResultT &result) = 0; }; class ServiceHandler final : public ServiceHandlerInterface diff --git a/include/util/debug.hpp b/include/util/debug.hpp index aa5b2ec4f..a3f706985 100644 --- a/include/util/debug.hpp +++ b/include/util/debug.hpp @@ -73,8 +73,7 @@ inline void print(const NodeBasedDynamicGraph &node_based_graph, for (const auto &road : intersection) { std::cout << "\t" << toString(road) << "\n"; - std::cout << "\t\t" - << node_based_graph.GetEdgeData(road.turn.eid).road_classification.ToString() + std::cout << "\t\t" << node_based_graph.GetEdgeData(road.eid).road_classification.ToString() << "\n"; } std::cout << std::flush; diff --git a/src/engine/guidance/assemble_overview.cpp b/src/engine/guidance/assemble_overview.cpp index 33921be04..97d3d694c 100644 --- a/src/engine/guidance/assemble_overview.cpp +++ b/src/engine/guidance/assemble_overview.cpp @@ -42,7 +42,6 @@ unsigned calculateOverviewZoomLevel(const std::vector &leg_geometri return util::viewport::getFittedZoom(south_west, north_east); } - } std::vector assembleOverview(const std::vector &leg_geometries, @@ -62,7 +61,8 @@ std::vector assembleOverview(const std::vector &l using GeometryIter = decltype(overview_geometry)::const_iterator; auto leg_reverse_index = leg_geometries.size(); - const auto insert_without_overlap = [&leg_reverse_index, &overview_geometry](GeometryIter begin, GeometryIter end) { + const auto insert_without_overlap = [&leg_reverse_index, &overview_geometry](GeometryIter begin, + GeometryIter end) { // not the last leg if (leg_reverse_index > 1) { @@ -77,7 +77,8 @@ std::vector assembleOverview(const std::vector &l const auto zoom_level = std::min(18u, calculateOverviewZoomLevel(leg_geometries)); for (const auto &geometry : leg_geometries) { - const auto simplified = douglasPeucker(geometry.locations.begin(), geometry.locations.end(), zoom_level); + const auto simplified = + douglasPeucker(geometry.locations.begin(), geometry.locations.end(), zoom_level); insert_without_overlap(simplified.begin(), simplified.end()); } } diff --git a/src/engine/guidance/lane_processing.cpp b/src/engine/guidance/lane_processing.cpp index 6512b8a9f..0ea94f3a3 100644 --- a/src/engine/guidance/lane_processing.cpp +++ b/src/engine/guidance/lane_processing.cpp @@ -2,7 +2,7 @@ #include "util/group_by.hpp" #include "util/guidance/toolkit.hpp" -#include "extractor/guidance/toolkit.hpp" +#include "engine/guidance/toolkit.hpp" #include "extractor/guidance/turn_instruction.hpp" #include "engine/guidance/post_processing.hpp" @@ -16,8 +16,6 @@ namespace DirectionModifier = osrm::extractor::guidance::DirectionModifier; using osrm::util::guidance::isLeftTurn; using osrm::util::guidance::isRightTurn; -using osrm::extractor::guidance::numLanesToTheRight; -using osrm::extractor::guidance::numLanesToTheLeft; namespace osrm { diff --git a/src/engine/guidance/post_processing.cpp b/src/engine/guidance/post_processing.cpp index 23be6f354..e347ccc08 100644 --- a/src/engine/guidance/post_processing.cpp +++ b/src/engine/guidance/post_processing.cpp @@ -1,7 +1,7 @@ #include "engine/guidance/post_processing.hpp" #include "extractor/guidance/constants.hpp" -#include "extractor/guidance/toolkit.hpp" #include "extractor/guidance/turn_instruction.hpp" +#include "engine/guidance/toolkit.hpp" #include "engine/guidance/assemble_steps.hpp" #include "engine/guidance/lane_processing.hpp" @@ -1599,13 +1599,13 @@ std::vector collapseUseLane(std::vector steps) // the lane description is given left to right, lanes are counted from the right. // Therefore we access the lane description using the reverse iterator - auto right_most_lanes = extractor::guidance::lanesToTheRight(step); + auto right_most_lanes = lanesToTheRight(step); if (!right_most_lanes.empty() && containsTag(right_most_lanes.front(), (extractor::guidance::TurnLaneType::straight | extractor::guidance::TurnLaneType::none))) return false; - auto left_most_lanes = extractor::guidance::lanesToTheLeft(step); + auto left_most_lanes = lanesToTheLeft(step); if (!left_most_lanes.empty() && containsTag(left_most_lanes.back(), (extractor::guidance::TurnLaneType::straight | extractor::guidance::TurnLaneType::none))) diff --git a/src/extractor/edge_based_graph_factory.cpp b/src/extractor/edge_based_graph_factory.cpp index 446f74355..2e6b9a69f 100644 --- a/src/extractor/edge_based_graph_factory.cpp +++ b/src/extractor/edge_based_graph_factory.cpp @@ -376,6 +376,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( const NodeID node_v = m_node_based_graph->GetTarget(edge_from_u); ++node_based_edge_counter; auto intersection = turn_analysis.getIntersection(node_u, edge_from_u); + BOOST_ASSERT(intersection.valid()); intersection = turn_analysis.assignTurnTypes(node_u, edge_from_u, std::move(intersection)); intersection = @@ -462,7 +463,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( turn_instruction, entry_class_id, edge_data1.travel_mode, - util::guidance::TurnBearing(intersection[0].turn.bearing), + util::guidance::TurnBearing(intersection[0].bearing), util::guidance::TurnBearing(turn.bearing)); } else if (is_encoded_backwards) @@ -476,7 +477,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( turn_instruction, entry_class_id, edge_data1.travel_mode, - util::guidance::TurnBearing(intersection[0].turn.bearing), + util::guidance::TurnBearing(intersection[0].bearing), util::guidance::TurnBearing(turn.bearing)); } diff --git a/src/extractor/geojson_debug_policies.cpp b/src/extractor/geojson_debug_policies.cpp index 22b172ef0..adf93c6b8 100644 --- a/src/extractor/geojson_debug_policies.cpp +++ b/src/extractor/geojson_debug_policies.cpp @@ -24,8 +24,7 @@ operator()(const NodeID intersection_node, { // request the number of lanes. This process needs to be in sync with what happens over at // intersection_generator - const auto intersection_lanes = - extractor::guidance::getLaneCountAtIntersection(intersection_node, node_based_graph); + const auto intersection_lanes = intersection.getHighestConnectedLaneCount(node_based_graph); std::vector coordinates; coordinates.reserve(intersection.size()); @@ -33,9 +32,9 @@ operator()(const NodeID intersection_node, const auto road_to_coordinate = [&](const extractor::guidance::ConnectedRoad &connected_road) { const constexpr auto FORWARD = false; - const auto to_node = node_based_graph.GetTarget(connected_road.turn.eid); + const auto to_node = node_based_graph.GetTarget(connected_road.eid); return coordinate_extractor.GetCoordinateAlongRoad( - intersection_node, connected_road.turn.eid, FORWARD, to_node, intersection_lanes); + intersection_node, connected_road.eid, FORWARD, to_node, intersection_lanes); }; std::transform(intersection.begin(), diff --git a/src/extractor/guidance/intersection.cpp b/src/extractor/guidance/intersection.cpp index 2755bcbcd..65189032c 100644 --- a/src/extractor/guidance/intersection.cpp +++ b/src/extractor/guidance/intersection.cpp @@ -1,6 +1,13 @@ #include "extractor/guidance/intersection.hpp" #include "extractor/guidance/toolkit.hpp" +#include +#include + +#include +#include +#include + namespace osrm { namespace extractor @@ -9,44 +16,101 @@ namespace guidance { ConnectedRoad::ConnectedRoad(const TurnOperation turn, const bool entry_allowed) - : entry_allowed(entry_allowed), turn(turn) + : TurnOperation(turn), entry_allowed(entry_allowed) { } +bool ConnectedRoad::compareByAngle(const ConnectedRoad &other) const { return angle < other.angle; } + +void ConnectedRoad::mirror() +{ + const constexpr DirectionModifier::Enum mirrored_modifiers[] = {DirectionModifier::UTurn, + DirectionModifier::SharpLeft, + DirectionModifier::Left, + DirectionModifier::SlightLeft, + DirectionModifier::Straight, + DirectionModifier::SlightRight, + DirectionModifier::Right, + DirectionModifier::SharpRight}; + + static_assert(sizeof(mirrored_modifiers) / sizeof(DirectionModifier::Enum) == + DirectionModifier::MaxDirectionModifier, + "The list of mirrored modifiers needs to match the available modifiers in size."); + + if (angularDeviation(angle, 0) > std::numeric_limits::epsilon()) + { + angle = 360 - angle; + instruction.direction_modifier = mirrored_modifiers[instruction.direction_modifier]; + } +} + +ConnectedRoad ConnectedRoad::getMirroredCopy() const +{ + ConnectedRoad copy(*this); + copy.mirror(); + return copy; +} + std::string toString(const ConnectedRoad &road) { std::string result = "[connection] "; - result += std::to_string(road.turn.eid); + result += std::to_string(road.eid); result += " allows entry: "; result += std::to_string(road.entry_allowed); result += " angle: "; - result += std::to_string(road.turn.angle); + result += std::to_string(road.angle); result += " bearing: "; - result += std::to_string(road.turn.bearing); + result += std::to_string(road.bearing); result += " instruction: "; - result += std::to_string(static_cast(road.turn.instruction.type)) + " " + - std::to_string(static_cast(road.turn.instruction.direction_modifier)) + - " " + std::to_string(static_cast(road.turn.lane_data_id)); + result += std::to_string(static_cast(road.instruction.type)) + " " + + std::to_string(static_cast(road.instruction.direction_modifier)) + " " + + std::to_string(static_cast(road.lane_data_id)); return result; } -Intersection::iterator findClosestTurn(Intersection &intersection, const double angle) +Intersection::Base::iterator Intersection::findClosestTurn(double angle) { - return std::min_element(intersection.begin(), - intersection.end(), - [angle](const ConnectedRoad &lhs, const ConnectedRoad &rhs) { - return angularDeviation(lhs.turn.angle, angle) < - angularDeviation(rhs.turn.angle, angle); - }); + // use the const operator to avoid code duplication + return begin() + + std::distance(cbegin(), static_cast(this)->findClosestTurn(angle)); } -Intersection::const_iterator findClosestTurn(const Intersection &intersection, const double angle) + +Intersection::Base::const_iterator Intersection::findClosestTurn(double angle) const { - return std::min_element(intersection.cbegin(), - intersection.cend(), - [angle](const ConnectedRoad &lhs, const ConnectedRoad &rhs) { - return angularDeviation(lhs.turn.angle, angle) < - angularDeviation(rhs.turn.angle, angle); - }); + return std::min_element( + begin(), end(), [angle](const ConnectedRoad &lhs, const ConnectedRoad &rhs) { + return util::guidance::angularDeviation(lhs.angle, angle) < + util::guidance::angularDeviation(rhs.angle, angle); + }); +} + +bool Intersection::valid() const +{ + return !empty() && + std::is_sorted(begin(), end(), std::mem_fn(&ConnectedRoad::compareByAngle)) && + operator[](0).angle < std::numeric_limits::epsilon(); +} + +std::uint8_t Intersection::getHighestConnectedLaneCount( + const util::NodeBasedDynamicGraph &node_based_graph) const +{ + BOOST_ASSERT(valid()); // non empty() + std::vector test; + const auto to_lane_count = [&](const ConnectedRoad &road) { + return node_based_graph.GetEdgeData(road.eid).road_classification.GetNumberOfLanes(); + }; + + // boost::range::transformed sadly does not work with lamdas since they are not copy + // constructable. We need to work around this :( + std::uint8_t max_lanes = 0; + const auto extract_maximal_value = [&max_lanes](std::uint8_t value) { + max_lanes = std::max(max_lanes, value); + return false; + }; + + const auto view = test | boost::adaptors::transformed(to_lane_count); + boost::range::find_if(view, extract_maximal_value); + return max_lanes; } } // namespace guidance diff --git a/src/extractor/guidance/intersection_generator.cpp b/src/extractor/guidance/intersection_generator.cpp index c74250389..b63a43390 100644 --- a/src/extractor/guidance/intersection_generator.cpp +++ b/src/extractor/guidance/intersection_generator.cpp @@ -3,6 +3,7 @@ #include "extractor/guidance/toolkit.hpp" #include +#include #include #include #include @@ -179,13 +180,12 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node, false}); } - const auto ByAngle = [](const ConnectedRoad &first, const ConnectedRoad second) { - return first.turn.angle < second.turn.angle; - }; - std::sort(std::begin(intersection), std::end(intersection), ByAngle); + std::sort(std::begin(intersection), + std::end(intersection), + std::mem_fn(&ConnectedRoad::compareByAngle)); - BOOST_ASSERT(intersection[0].turn.angle >= 0. && - intersection[0].turn.angle < std::numeric_limits::epsilon()); + BOOST_ASSERT(intersection[0].angle >= 0. && + intersection[0].angle < std::numeric_limits::epsilon()); const auto valid_count = boost::count_if(intersection, [](const ConnectedRoad &road) { return road.entry_allowed; }); @@ -196,13 +196,13 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node, // that was inserted together with setting uturn_could_be_valid flag std::size_t self_u_turn = 0; while (self_u_turn < intersection.size() && - intersection[self_u_turn].turn.angle < std::numeric_limits::epsilon() && - from_node != node_based_graph.GetTarget(intersection[self_u_turn].turn.eid)) + intersection[self_u_turn].angle < std::numeric_limits::epsilon() && + from_node != node_based_graph.GetTarget(intersection[self_u_turn].eid)) { ++self_u_turn; } - BOOST_ASSERT(from_node == node_based_graph.GetTarget(intersection[self_u_turn].turn.eid)); + BOOST_ASSERT(from_node == node_based_graph.GetTarget(intersection[self_u_turn].eid)); intersection[self_u_turn].entry_allowed = true; } return intersection; @@ -215,8 +215,8 @@ bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection, std::size_t first_index, std::size_t second_index) const { - const auto &first_data = node_based_graph.GetEdgeData(intersection[first_index].turn.eid); - const auto &second_data = node_based_graph.GetEdgeData(intersection[second_index].turn.eid); + const auto &first_data = node_based_graph.GetEdgeData(intersection[first_index].eid); + const auto &second_data = node_based_graph.GetEdgeData(intersection[second_index].eid); // only merge named ids if (first_data.name_id == EMPTY_NAMEID) @@ -245,18 +245,17 @@ bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection, return false; // mergeable if the angle is not too big - const auto angle_between = angularDeviation(intersection[first_index].turn.angle, - intersection[second_index].turn.angle); + const auto angle_between = + angularDeviation(intersection[first_index].angle, intersection[second_index].angle); - const auto intersection_lanes = - getLaneCountAtIntersection(node_at_intersection, node_based_graph); + const auto intersection_lanes = intersection.getHighestConnectedLaneCount(node_based_graph); - const auto coordinate_at_in_edge = coordinate_extractor.GetCoordinateAlongRoad( - node_at_intersection, - intersection[0].turn.eid, - !INVERT, - node_based_graph.GetTarget(intersection[0].turn.eid), - intersection_lanes); + const auto coordinate_at_in_edge = + coordinate_extractor.GetCoordinateAlongRoad(node_at_intersection, + intersection[0].eid, + !INVERT, + node_based_graph.GetTarget(intersection[0].eid), + intersection_lanes); const auto coordinate_at_intersection = node_info_list[node_at_intersection]; @@ -272,7 +271,7 @@ bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection, const auto GetActualTarget = [&](const std::size_t index) { EdgeID last_in_edge_id; GetActualNextIntersection( - node_at_intersection, intersection[index].turn.eid, nullptr, &last_in_edge_id); + node_at_intersection, intersection[index].eid, nullptr, &last_in_edge_id); return node_based_graph.GetTarget(last_in_edge_id); }; @@ -292,12 +291,11 @@ bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection, const bool becomes_narrower = angularDeviation(turn_angle, other_turn_angle) < NARROW_TURN_ANGLE && angularDeviation(turn_angle, other_turn_angle) <= - angularDeviation(intersection[index].turn.angle, - intersection[other_index].turn.angle); + angularDeviation(intersection[index].angle, intersection[other_index].angle); const bool has_same_deviation = - std::abs(angularDeviation(intersection[index].turn.angle, STRAIGHT_ANGLE) - - angularDeviation(intersection[other_index].turn.angle, STRAIGHT_ANGLE)) < + std::abs(angularDeviation(intersection[index].angle, STRAIGHT_ANGLE) - + angularDeviation(intersection[other_index].angle, STRAIGHT_ANGLE)) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION; return becomes_narrower || has_same_deviation; @@ -330,17 +328,14 @@ bool IntersectionGenerator::CanMerge(const NodeID node_at_intersection, }(); // needs to be same road coming in - if (node_based_graph.GetEdgeData(intersection[third_index].turn.eid).name_id != - first_data.name_id) + if (node_based_graph.GetEdgeData(intersection[third_index].eid).name_id != first_data.name_id) return false; // we only allow collapsing of a Y like fork. So the angle to the third index has to be // roughly equal: - const auto y_angle_difference = - angularDeviation(angularDeviation(intersection[third_index].turn.angle, - intersection[first_index].turn.angle), - angularDeviation(intersection[third_index].turn.angle, - intersection[second_index].turn.angle)); + const auto y_angle_difference = angularDeviation( + angularDeviation(intersection[third_index].angle, intersection[first_index].angle), + angularDeviation(intersection[third_index].angle, intersection[second_index].angle)); // Allow larger angles if its three roads only of the same name // This is a heuristic and might need to be revised. @@ -403,10 +398,10 @@ Intersection IntersectionGenerator::MergeSegregatedRoads(const NodeID intersecti const auto merge = [combineAngles](const ConnectedRoad &first, const ConnectedRoad &second) -> ConnectedRoad { ConnectedRoad result = first.entry_allowed ? first : second; - result.turn.angle = combineAngles(first.turn.angle, second.turn.angle); - result.turn.bearing = combineAngles(first.turn.bearing, second.turn.bearing); - BOOST_ASSERT(0 <= result.turn.angle && result.turn.angle <= 360.0); - BOOST_ASSERT(0 <= result.turn.bearing && result.turn.bearing <= 360.0); + result.angle = combineAngles(first.angle, second.angle); + result.bearing = combineAngles(first.bearing, second.bearing); + BOOST_ASSERT(0 <= result.angle && result.angle <= 360.0); + BOOST_ASSERT(0 <= result.bearing && result.bearing <= 360.0); return result; }; @@ -416,7 +411,7 @@ Intersection IntersectionGenerator::MergeSegregatedRoads(const NodeID intersecti const bool is_connected_to_roundabout = [this, &intersection]() { for (const auto &road : intersection) { - if (node_based_graph.GetEdgeData(road.turn.eid).roundabout) + if (node_based_graph.GetEdgeData(road.eid).roundabout) return true; } return false; @@ -459,26 +454,25 @@ Intersection IntersectionGenerator::MergeSegregatedRoads(const NodeID intersecti { merged_first = true; // moving `a` to the left - const double correction_factor = - (360 - intersection[intersection.size() - 1].turn.angle) / 2; + const double correction_factor = (360 - intersection[intersection.size() - 1].angle) / 2; for (std::size_t i = 1; i + 1 < intersection.size(); ++i) - intersection[i].turn.angle += correction_factor; + intersection[i].angle += correction_factor; // FIXME if we have a left-sided country, we need to switch this off and enable it // below intersection[0] = merge(intersection.front(), intersection.back()); - intersection[0].turn.angle = 0; + intersection[0].angle = 0; intersection.pop_back(); } else if (CanMerge(intersection_node, intersection, 0, 1)) { merged_first = true; // moving `a` to the right - const double correction_factor = (intersection[1].turn.angle) / 2; + const double correction_factor = (intersection[1].angle) / 2; for (std::size_t i = 2; i < intersection.size(); ++i) - intersection[i].turn.angle -= correction_factor; + intersection[i].angle -= correction_factor; intersection[0] = merge(intersection[0], intersection[1]); - intersection[0].turn.angle = 0; + intersection[0].angle = 0; intersection.erase(intersection.begin() + 1); } @@ -510,10 +504,9 @@ Intersection IntersectionGenerator::MergeSegregatedRoads(const NodeID intersecti } } - const auto ByAngle = [](const ConnectedRoad &first, const ConnectedRoad second) { - return first.turn.angle < second.turn.angle; - }; - std::sort(std::begin(intersection), std::end(intersection), ByAngle); + std::sort(std::begin(intersection), + std::end(intersection), + std::mem_fn(&ConnectedRoad::compareByAngle)); return intersection; } @@ -552,13 +545,12 @@ Intersection IntersectionGenerator::AdjustForJoiningRoads(const NodeID node_at_i // to find out about the above situation, we need to look at the next intersection (at d in // the example). If the initial road can be merged to the left/right, we are about to adjust // the angle. - const auto next_intersection_along_road = - GetConnectedRoads(node_at_intersection, road.turn.eid); + const auto next_intersection_along_road = GetConnectedRoads(node_at_intersection, road.eid); if (next_intersection_along_road.size() <= 1) continue; - const auto node_at_next_intersection = node_based_graph.GetTarget(road.turn.eid); + const auto node_at_next_intersection = node_based_graph.GetTarget(road.eid); const util::Coordinate coordinate_at_next_intersection = node_info_list[node_at_next_intersection]; if (util::coordinate_calculation::haversineDistance(coordinate_at_intersection, @@ -580,7 +572,7 @@ Intersection IntersectionGenerator::AdjustForJoiningRoads(const NodeID node_at_i // the order does not matter const auto get_offset = [](const ConnectedRoad &lhs, const ConnectedRoad &rhs) { - return 0.5 * angularDeviation(lhs.turn.angle, rhs.turn.angle); + return 0.5 * angularDeviation(lhs.angle, rhs.angle); }; // When offsetting angles in our turns, we don't want to get past the next turn. This @@ -590,7 +582,7 @@ Intersection IntersectionGenerator::AdjustForJoiningRoads(const NodeID node_at_i const ConnectedRoad &road, const ConnectedRoad &next_road_in_offset_direction) { const auto offset_limit = - angularDeviation(road.turn.angle, next_road_in_offset_direction.turn.angle); + angularDeviation(road.angle, next_road_in_offset_direction.angle); // limit the offset with an additional buffer return (offset + MAXIMAL_ALLOWED_NO_TURN_DEVIATION > offset_limit) ? 0.5 * offset_limit : offset; @@ -608,8 +600,8 @@ Intersection IntersectionGenerator::AdjustForJoiningRoads(const NodeID node_at_i get_corrected_offset(offset, road, intersection[(index + 1) % intersection.size()]); // at the target intersection, we merge to the right, so we need to shift the current // angle to the left - road.turn.angle = adjustAngle(road.turn.angle, corrected_offset); - road.turn.bearing = adjustAngle(road.turn.bearing, corrected_offset); + road.angle = adjustAngle(road.angle, corrected_offset); + road.bearing = adjustAngle(road.bearing, corrected_offset); } else if (CanMerge(node_at_next_intersection, next_intersection_along_road, @@ -624,8 +616,8 @@ Intersection IntersectionGenerator::AdjustForJoiningRoads(const NodeID node_at_i get_corrected_offset(offset, road, intersection[index - 1]); // at the target intersection, we merge to the left, so we need to shift the current // angle to the right - road.turn.angle = adjustAngle(road.turn.angle, -corrected_offset); - road.turn.bearing = adjustAngle(road.turn.bearing, -corrected_offset); + road.angle = adjustAngle(road.angle, -corrected_offset); + road.bearing = adjustAngle(road.bearing, -corrected_offset); } } return intersection; @@ -653,11 +645,11 @@ IntersectionGenerator::GetActualNextIntersection(const NodeID starting_node, while (visited_nodes.count(node_at_intersection) == 0 && (result.size() == 2 && node_based_graph.GetEdgeData(via_edge).IsCompatibleTo( - node_based_graph.GetEdgeData(result[1].turn.eid)))) + node_based_graph.GetEdgeData(result[1].eid)))) { visited_nodes.insert(node_at_intersection); node_at_intersection = node_based_graph.GetTarget(incoming_edge); - incoming_edge = result[1].turn.eid; + incoming_edge = result[1].eid; result = GetConnectedRoads(node_at_intersection, incoming_edge); // When looping back to the original node, we obviously are in a loop. Stop there. diff --git a/src/extractor/guidance/intersection_handler.cpp b/src/extractor/guidance/intersection_handler.cpp index 9b2322ca1..3cd2fd3a2 100644 --- a/src/extractor/guidance/intersection_handler.cpp +++ b/src/extractor/guidance/intersection_handler.cpp @@ -50,7 +50,7 @@ TurnType::Enum IntersectionHandler::findBasicTurnType(const EdgeID via_edge, { const auto &in_data = node_based_graph.GetEdgeData(via_edge); - const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid); + const auto &out_data = node_based_graph.GetEdgeData(road.eid); bool on_ramp = in_data.road_classification.IsRampClass(); @@ -75,20 +75,20 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t const auto type = findBasicTurnType(via_edge, road); // handle travel modes: const auto in_mode = node_based_graph.GetEdgeData(via_edge).travel_mode; - const auto out_mode = node_based_graph.GetEdgeData(road.turn.eid).travel_mode; + const auto out_mode = node_based_graph.GetEdgeData(road.eid).travel_mode; if (type == TurnType::OnRamp) { - return {TurnType::OnRamp, getTurnDirection(road.turn.angle)}; + return {TurnType::OnRamp, getTurnDirection(road.angle)}; } - if (angularDeviation(road.turn.angle, 0) < 0.01) + if (angularDeviation(road.angle, 0) < 0.01) { return {TurnType::Turn, DirectionModifier::UTurn}; } if (type == TurnType::Turn) { const auto &in_data = node_based_graph.GetEdgeData(via_edge); - const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid); + const auto &out_data = node_based_graph.GetEdgeData(road.eid); if (in_data.name_id != out_data.name_id && util::guidance::requiresNameAnnounced(name_table.GetNameForID(in_data.name_id), name_table.GetRefForID(in_data.name_id), @@ -104,8 +104,8 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t // that could potentially also offer different choices if (out_data.road_classification.IsMotorwayClass()) return {TurnType::Merge, - road.turn.angle > STRAIGHT_ANGLE ? DirectionModifier::SlightRight - : DirectionModifier::SlightLeft}; + road.angle > STRAIGHT_ANGLE ? DirectionModifier::SlightRight + : DirectionModifier::SlightLeft}; else if (in_data.road_classification.IsRampClass() && out_data.road_classification.IsRampClass()) { @@ -113,7 +113,7 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t // cannot reach this, since all ramps are exposing the same travel type. But we // could see toll-type at some point. return {in_mode == out_mode ? TurnType::Suppressed : TurnType::Notification, - getTurnDirection(road.turn.angle)}; + getTurnDirection(road.angle)}; } else { @@ -129,40 +129,40 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t // precalculated distance value. const auto distance = util::coordinate_calculation::haversineDistance( node_info_list[node_based_graph.GetTarget(via_edge)], - node_info_list[node_based_graph.GetTarget(road.turn.eid)]); - return {TurnType::Turn, - (angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < - FUZZY_ANGLE_DIFFERENCE || - distance > 2 * MAX_COLLAPSE_DISTANCE) - ? DirectionModifier::Straight - : getTurnDirection(road.turn.angle)}; + node_info_list[node_based_graph.GetTarget(road.eid)]); + return { + TurnType::Turn, + (angularDeviation(road.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE || + distance > 2 * MAX_COLLAPSE_DISTANCE) + ? DirectionModifier::Straight + : getTurnDirection(road.angle)}; } } else { return {in_mode == out_mode ? TurnType::NewName : TurnType::Notification, - getTurnDirection(road.turn.angle)}; + getTurnDirection(road.angle)}; } } // name has not changed, suppress a turn here or indicate mode change else { return {in_mode == out_mode ? TurnType::Suppressed : TurnType::Notification, - getTurnDirection(road.turn.angle)}; + getTurnDirection(road.angle)}; } } BOOST_ASSERT(type == TurnType::Continue); if (in_mode != out_mode) { - return {TurnType::Notification, getTurnDirection(road.turn.angle)}; + return {TurnType::Notification, getTurnDirection(road.angle)}; } if (num_roads > 2) { - return {TurnType::Suppressed, getTurnDirection(road.turn.angle)}; + return {TurnType::Suppressed, getTurnDirection(road.angle)}; } else { - return {TurnType::NoTurn, getTurnDirection(road.turn.angle)}; + return {TurnType::NoTurn, getTurnDirection(road.angle)}; } } @@ -172,107 +172,105 @@ void IntersectionHandler::assignFork(const EdgeID via_edge, { const auto &in_data = node_based_graph.GetEdgeData(via_edge); const bool low_priority_left = - node_based_graph.GetEdgeData(left.turn.eid).road_classification.IsLowPriorityRoadClass(); + node_based_graph.GetEdgeData(left.eid).road_classification.IsLowPriorityRoadClass(); const bool low_priority_right = - node_based_graph.GetEdgeData(right.turn.eid).road_classification.IsLowPriorityRoadClass(); - if ((angularDeviation(left.turn.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION && - angularDeviation(right.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE)) + node_based_graph.GetEdgeData(right.eid).road_classification.IsLowPriorityRoadClass(); + if ((angularDeviation(left.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION && + angularDeviation(right.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE)) { // left side is actually straight - const auto &out_data = node_based_graph.GetEdgeData(left.turn.eid); + const auto &out_data = node_based_graph.GetEdgeData(left.eid); if (detail::requiresAnnouncement(in_data, out_data)) { if (low_priority_right && !low_priority_left) { - left.turn.instruction = getInstructionForObvious(3, via_edge, false, left); - right.turn.instruction = {findBasicTurnType(via_edge, right), - DirectionModifier::SlightRight}; + left.instruction = getInstructionForObvious(3, via_edge, false, left); + right.instruction = {findBasicTurnType(via_edge, right), + DirectionModifier::SlightRight}; } else { if (low_priority_left && !low_priority_right) { - left.turn.instruction = {findBasicTurnType(via_edge, left), - DirectionModifier::SlightLeft}; - right.turn.instruction = {findBasicTurnType(via_edge, right), - DirectionModifier::SlightRight}; + left.instruction = {findBasicTurnType(via_edge, left), + DirectionModifier::SlightLeft}; + right.instruction = {findBasicTurnType(via_edge, right), + DirectionModifier::SlightRight}; } else { - left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft}; - right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight}; + left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft}; + right.instruction = {TurnType::Fork, DirectionModifier::SlightRight}; } } } else { - left.turn.instruction = {TurnType::Suppressed, DirectionModifier::Straight}; - right.turn.instruction = {findBasicTurnType(via_edge, right), - DirectionModifier::SlightRight}; + left.instruction = {TurnType::Suppressed, DirectionModifier::Straight}; + right.instruction = {findBasicTurnType(via_edge, right), + DirectionModifier::SlightRight}; } } - else if (angularDeviation(right.turn.angle, STRAIGHT_ANGLE) < - MAXIMAL_ALLOWED_NO_TURN_DEVIATION && - angularDeviation(left.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE) + else if (angularDeviation(right.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION && + angularDeviation(left.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE) { // right side is actually straight - const auto &out_data = node_based_graph.GetEdgeData(right.turn.eid); - if (angularDeviation(right.turn.angle, STRAIGHT_ANGLE) < - MAXIMAL_ALLOWED_NO_TURN_DEVIATION && - angularDeviation(left.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE) + const auto &out_data = node_based_graph.GetEdgeData(right.eid); + if (angularDeviation(right.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION && + angularDeviation(left.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE) { if (detail::requiresAnnouncement(in_data, out_data)) { if (low_priority_left && !low_priority_right) { - left.turn.instruction = {findBasicTurnType(via_edge, left), - DirectionModifier::SlightLeft}; - right.turn.instruction = getInstructionForObvious(3, via_edge, false, right); + left.instruction = {findBasicTurnType(via_edge, left), + DirectionModifier::SlightLeft}; + right.instruction = getInstructionForObvious(3, via_edge, false, right); } else { if (low_priority_right && !low_priority_left) { - left.turn.instruction = {findBasicTurnType(via_edge, left), - DirectionModifier::SlightLeft}; - right.turn.instruction = {findBasicTurnType(via_edge, right), - DirectionModifier::SlightRight}; + left.instruction = {findBasicTurnType(via_edge, left), + DirectionModifier::SlightLeft}; + right.instruction = {findBasicTurnType(via_edge, right), + DirectionModifier::SlightRight}; } else { - right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight}; - left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft}; + right.instruction = {TurnType::Fork, DirectionModifier::SlightRight}; + left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft}; } } } else { - right.turn.instruction = {TurnType::Suppressed, DirectionModifier::Straight}; - left.turn.instruction = {findBasicTurnType(via_edge, left), - DirectionModifier::SlightLeft}; + right.instruction = {TurnType::Suppressed, DirectionModifier::Straight}; + left.instruction = {findBasicTurnType(via_edge, left), + DirectionModifier::SlightLeft}; } } } // left side of fork if (low_priority_right && !low_priority_left) - left.turn.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft}; + left.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft}; else { if (low_priority_left && !low_priority_right) - left.turn.instruction = {TurnType::Turn, DirectionModifier::SlightLeft}; + left.instruction = {TurnType::Turn, DirectionModifier::SlightLeft}; else - left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft}; + left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft}; } // right side of fork if (low_priority_left && !low_priority_right) - right.turn.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft}; + right.instruction = {TurnType::Suppressed, DirectionModifier::SlightLeft}; else { if (low_priority_right && !low_priority_left) - right.turn.instruction = {TurnType::Turn, DirectionModifier::SlightRight}; + right.instruction = {TurnType::Turn, DirectionModifier::SlightRight}; else - right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight}; + right.instruction = {TurnType::Fork, DirectionModifier::SlightRight}; } } @@ -284,25 +282,25 @@ void IntersectionHandler::assignFork(const EdgeID via_edge, // TODO handle low priority road classes in a reasonable way if (left.entry_allowed && center.entry_allowed && right.entry_allowed) { - left.turn.instruction = {TurnType::Fork, DirectionModifier::SlightLeft}; - if (angularDeviation(center.turn.angle, 180) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION) + left.instruction = {TurnType::Fork, DirectionModifier::SlightLeft}; + if (angularDeviation(center.angle, 180) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION) { const auto &in_data = node_based_graph.GetEdgeData(via_edge); - const auto &out_data = node_based_graph.GetEdgeData(center.turn.eid); + const auto &out_data = node_based_graph.GetEdgeData(center.eid); if (detail::requiresAnnouncement(in_data, out_data)) { - center.turn.instruction = {TurnType::Fork, DirectionModifier::Straight}; + center.instruction = {TurnType::Fork, DirectionModifier::Straight}; } else { - center.turn.instruction = {TurnType::Suppressed, DirectionModifier::Straight}; + center.instruction = {TurnType::Suppressed, DirectionModifier::Straight}; } } else { - center.turn.instruction = {TurnType::Fork, DirectionModifier::Straight}; + center.instruction = {TurnType::Fork, DirectionModifier::Straight}; } - right.turn.instruction = {TurnType::Fork, DirectionModifier::SlightRight}; + right.instruction = {TurnType::Fork, DirectionModifier::SlightRight}; } else if (left.entry_allowed) { @@ -311,22 +309,20 @@ void IntersectionHandler::assignFork(const EdgeID via_edge, else if (center.entry_allowed) assignFork(via_edge, left, center); else - left.turn.instruction = {findBasicTurnType(via_edge, left), - getTurnDirection(left.turn.angle)}; + left.instruction = {findBasicTurnType(via_edge, left), getTurnDirection(left.angle)}; } else if (right.entry_allowed) { if (center.entry_allowed) assignFork(via_edge, center, right); else - right.turn.instruction = {findBasicTurnType(via_edge, right), - getTurnDirection(right.turn.angle)}; + right.instruction = {findBasicTurnType(via_edge, right), getTurnDirection(right.angle)}; } else { if (center.entry_allowed) - center.turn.instruction = {findBasicTurnType(via_edge, center), - getTurnDirection(center.turn.angle)}; + center.instruction = {findBasicTurnType(via_edge, center), + getTurnDirection(center.angle)}; } } @@ -337,18 +333,17 @@ void IntersectionHandler::assignTrivialTurns(const EdgeID via_eid, { for (std::size_t index = begin; index != end; ++index) if (intersection[index].entry_allowed) - intersection[index].turn.instruction = { - findBasicTurnType(via_eid, intersection[index]), - getTurnDirection(intersection[index].turn.angle)}; + intersection[index].instruction = {findBasicTurnType(via_eid, intersection[index]), + getTurnDirection(intersection[index].angle)}; } bool IntersectionHandler::isThroughStreet(const std::size_t index, const Intersection &intersection) const { - if (node_based_graph.GetEdgeData(intersection[index].turn.eid).name_id == EMPTY_NAMEID) + if (node_based_graph.GetEdgeData(intersection[index].eid).name_id == EMPTY_NAMEID) return false; - const auto &data_at_index = node_based_graph.GetEdgeData(intersection[index].turn.eid); + const auto &data_at_index = node_based_graph.GetEdgeData(intersection[index].eid); // a through street cannot start at our own position -> index 1 for (std::size_t road_index = 1; road_index < intersection.size(); ++road_index) @@ -357,12 +352,11 @@ bool IntersectionHandler::isThroughStreet(const std::size_t index, continue; const auto &road = intersection[road_index]; - const auto &road_data = node_based_graph.GetEdgeData(road.turn.eid); + const auto &road_data = node_based_graph.GetEdgeData(road.eid); // roads have a near straight angle (180 degree) - const bool is_nearly_straight = - angularDeviation(road.turn.angle, intersection[index].turn.angle) > - (STRAIGHT_ANGLE - FUZZY_ANGLE_DIFFERENCE); + const bool is_nearly_straight = angularDeviation(road.angle, intersection[index].angle) > + (STRAIGHT_ANGLE - FUZZY_ANGLE_DIFFERENCE); const bool have_same_name = data_at_index.name_id == road_data.name_id; const bool have_same_category = @@ -397,13 +391,13 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, for (std::size_t i = 1; i < intersection.size(); ++i) { - const double deviation = angularDeviation(intersection[i].turn.angle, STRAIGHT_ANGLE); + const double deviation = angularDeviation(intersection[i].angle, STRAIGHT_ANGLE); if (!intersection[i].entry_allowed) continue; - const auto out_data = node_based_graph.GetEdgeData(intersection[i].turn.eid); + const auto out_data = node_based_graph.GetEdgeData(intersection[i].eid); const auto continue_class = - node_based_graph.GetEdgeData(intersection[best_continue].turn.eid).road_classification; + node_based_graph.GetEdgeData(intersection[best_continue].eid).road_classification; if (out_data.name_id == in_data.name_id && (best_continue == 0 || @@ -419,7 +413,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, } const auto current_best_class = - node_based_graph.GetEdgeData(intersection[best_continue].turn.eid).road_classification; + node_based_graph.GetEdgeData(intersection[best_continue].eid).road_classification; // don't prefer low priority classes if (best != 0 && out_data.road_classification.IsLowPriorityRoadClass() && @@ -459,7 +453,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, for (std::size_t i = 1; i < intersection.size(); ++i) { const auto &road = intersection[i]; - if ((in_data.name_id == node_based_graph.GetEdgeData(road.turn.eid).name_id)) + if ((in_data.name_id == node_based_graph.GetEdgeData(road.eid).name_id)) { ++count; if (road.entry_allowed) @@ -471,10 +465,10 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, }(); if (0 != best_continue && best != best_continue && - angularDeviation(intersection[best].turn.angle, STRAIGHT_ANGLE) < + angularDeviation(intersection[best].angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION && - node_based_graph.GetEdgeData(intersection[best_continue].turn.eid).road_classification == - node_based_graph.GetEdgeData(intersection[best].turn.eid).road_classification) + node_based_graph.GetEdgeData(intersection[best_continue].eid).road_classification == + node_based_graph.GetEdgeData(intersection[best].eid).road_classification) { // if the best angle is going straight but the road is turning, we don't name anything // obvious @@ -487,14 +481,13 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, return std::count_if( intersection.begin() + 1, intersection.end(), [&](const ConnectedRoad &road) { - return (in_data.name_id == - node_based_graph.GetEdgeData(road.turn.eid).name_id) && - angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE; + return (in_data.name_id == node_based_graph.GetEdgeData(road.eid).name_id) && + angularDeviation(road.angle, STRAIGHT_ANGLE) < NARROW_TURN_ANGLE; }) == num_continue_names.first; }(); // has no obvious continued road - const auto &best_data = node_based_graph.GetEdgeData(intersection[best].turn.eid); + const auto &best_data = node_based_graph.GetEdgeData(intersection[best].eid); const auto check_non_continue = [&]() { // no continue road exists @@ -512,8 +505,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, return true; // continue data now most certainly exists - const auto &continue_data = - node_based_graph.GetEdgeData(intersection[best_continue].turn.eid); + const auto &continue_data = node_based_graph.GetEdgeData(intersection[best_continue].eid); if (obviousByRoadClass(in_data.road_classification, continue_data.road_classification, @@ -550,7 +542,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, if (index_candidate == 0) return index_candidate; const auto &candidate_data = - node_based_graph.GetEdgeData(intersection[index_candidate].turn.eid); + node_based_graph.GetEdgeData(intersection[index_candidate].eid); if (obviousByRoadClass(in_data.road_classification, best_data.road_classification, candidate_data.road_classification)) @@ -565,7 +557,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, if (index_candidate == 0) return index_candidate; const auto candidate_data = - node_based_graph.GetEdgeData(intersection[index_candidate].turn.eid); + node_based_graph.GetEdgeData(intersection[index_candidate].eid); if (obviousByRoadClass(in_data.road_classification, best_data.road_classification, candidate_data.road_classification)) @@ -575,16 +567,16 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, }(); const double left_deviation = - angularDeviation(intersection[left_index].turn.angle, STRAIGHT_ANGLE); + angularDeviation(intersection[left_index].angle, STRAIGHT_ANGLE); const double right_deviation = - angularDeviation(intersection[right_index].turn.angle, STRAIGHT_ANGLE); + angularDeviation(intersection[right_index].angle, STRAIGHT_ANGLE); if (best_deviation < MAXIMAL_ALLOWED_NO_TURN_DEVIATION && std::min(left_deviation, right_deviation) > FUZZY_ANGLE_DIFFERENCE) return best; - const auto &left_data = node_based_graph.GetEdgeData(intersection[left_index].turn.eid); - const auto &right_data = node_based_graph.GetEdgeData(intersection[right_index].turn.eid); + const auto &left_data = node_based_graph.GetEdgeData(intersection[left_index].eid); + const auto &right_data = node_based_graph.GetEdgeData(intersection[right_index].eid); const bool obvious_to_left = left_index == 0 || obviousByRoadClass(in_data.road_classification, @@ -598,7 +590,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, // if the best turn isn't narrow, but there is a nearly straight turn, we don't consider the // turn obvious const auto check_narrow = [&intersection, best_deviation](const std::size_t index) { - return angularDeviation(intersection[index].turn.angle, STRAIGHT_ANGLE) <= + return angularDeviation(intersection[index].angle, STRAIGHT_ANGLE) <= FUZZY_ANGLE_DIFFERENCE && (best_deviation > NARROW_TURN_ANGLE || intersection[index].entry_allowed); }; @@ -624,7 +616,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, // a bit less obvious are road classes else if (in_data.road_classification == best_data.road_classification && best_data.road_classification.GetPriority() < - node_based_graph.GetEdgeData(intersection[index].turn.eid) + node_based_graph.GetEdgeData(intersection[index].eid) .road_classification.GetPriority()) return 0.8 * DISTINCTION_RATIO; // if road classes are the same, we use the full ratio @@ -644,9 +636,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, else { const double deviation = - angularDeviation(intersection[best_continue].turn.angle, STRAIGHT_ANGLE); - const auto &continue_data = - node_based_graph.GetEdgeData(intersection[best_continue].turn.eid); + angularDeviation(intersection[best_continue].angle, STRAIGHT_ANGLE); + const auto &continue_data = node_based_graph.GetEdgeData(intersection[best_continue].eid); if (std::abs(deviation) < 1) return best_continue; @@ -656,7 +647,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, if (i == best_continue || !intersection[i].entry_allowed) continue; - const auto &turn_data = node_based_graph.GetEdgeData(intersection[i].turn.eid); + const auto &turn_data = node_based_graph.GetEdgeData(intersection[i].eid); const bool is_obvious_by_road_class = obviousByRoadClass(in_data.road_classification, continue_data.road_classification, @@ -672,8 +663,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, continue; // perfectly straight turns prevent obviousness - const auto turn_deviation = - angularDeviation(intersection[i].turn.angle, STRAIGHT_ANGLE); + const auto turn_deviation = angularDeviation(intersection[i].angle, STRAIGHT_ANGLE); if (turn_deviation < FUZZY_ANGLE_DIFFERENCE) return 0; @@ -708,7 +698,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, const auto node_at_intersection = node_based_graph.GetTarget(via_edge); const util::Coordinate coordinate_at_intersection = node_info_list[node_at_intersection]; - const auto node_at_u_turn = node_based_graph.GetTarget(intersection[0].turn.eid); + const auto node_at_u_turn = node_based_graph.GetTarget(intersection[0].eid); const util::Coordinate coordinate_at_u_turn = node_info_list[node_at_u_turn]; const double constexpr MAX_COLLAPSE_DISTANCE = 30; @@ -720,7 +710,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, // try to find whether there is a turn going to the opposite direction of our obvious // turn, this should be alright. const auto previous_intersection = intersection_generator.GetActualNextIntersection( - node_at_intersection, intersection[0].turn.eid, nullptr, nullptr); + node_at_intersection, intersection[0].eid, nullptr, nullptr); const auto continue_road = intersection[best_continue]; for (const auto &comparison_road : previous_intersection) @@ -729,9 +719,9 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, // actually represents a near 180 degree different in bearings between the two // roads. So if there is a road that is enterable in the opposite direction just // prior, a turn is not obvious - const auto &turn_data = node_based_graph.GetEdgeData(comparison_road.turn.eid); - if (angularDeviation(comparison_road.turn.angle, STRAIGHT_ANGLE) > GROUP_ANGLE && - angularDeviation(comparison_road.turn.angle, continue_road.turn.angle) < + const auto &turn_data = node_based_graph.GetEdgeData(comparison_road.eid); + if (angularDeviation(comparison_road.angle, STRAIGHT_ANGLE) > GROUP_ANGLE && + angularDeviation(comparison_road.angle, continue_road.angle) < FUZZY_ANGLE_DIFFERENCE && !turn_data.reversed && continue_data.CanCombineWith(turn_data)) return 0; diff --git a/src/extractor/guidance/intersection_scenario_three_way.cpp b/src/extractor/guidance/intersection_scenario_three_way.cpp index d85e7df76..dce8c017b 100644 --- a/src/extractor/guidance/intersection_scenario_three_way.cpp +++ b/src/extractor/guidance/intersection_scenario_three_way.cpp @@ -17,9 +17,9 @@ bool isEndOfRoad(const ConnectedRoad &, const ConnectedRoad &possible_right_turn, const ConnectedRoad &possible_left_turn) { - return angularDeviation(possible_right_turn.turn.angle, 90) < NARROW_TURN_ANGLE && - angularDeviation(possible_left_turn.turn.angle, 270) < NARROW_TURN_ANGLE && - angularDeviation(possible_right_turn.turn.angle, possible_left_turn.turn.angle) > + return angularDeviation(possible_right_turn.angle, 90) < NARROW_TURN_ANGLE && + angularDeviation(possible_left_turn.angle, 270) < NARROW_TURN_ANGLE && + angularDeviation(possible_right_turn.angle, possible_left_turn.angle) > 2 * NARROW_TURN_ANGLE; } diff --git a/src/extractor/guidance/motorway_handler.cpp b/src/extractor/guidance/motorway_handler.cpp index 935c3fb5d..c007e1663 100644 --- a/src/extractor/guidance/motorway_handler.cpp +++ b/src/extractor/guidance/motorway_handler.cpp @@ -30,7 +30,7 @@ inline bool isMotorwayClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_ inline RoadClassification roadClass(const ConnectedRoad &road, const util::NodeBasedDynamicGraph &graph) { - return graph.GetEdgeData(road.turn.eid).road_classification; + return graph.GetEdgeData(road.eid).road_classification; } inline bool isRampClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_based_graph) @@ -63,14 +63,14 @@ bool MotorwayHandler::canProcess(const NodeID, for (const auto &road : intersection) { // not merging or forking? - if (road.entry_allowed && angularDeviation(road.turn.angle, STRAIGHT_ANGLE) > 60) + if (road.entry_allowed && angularDeviation(road.angle, STRAIGHT_ANGLE) > 60) return false; - else if (isMotorwayClass(road.turn.eid, node_based_graph)) + else if (isMotorwayClass(road.eid, node_based_graph)) { if (road.entry_allowed) has_motorway = true; } - else if (!isRampClass(road.turn.eid, node_based_graph)) + else if (!isRampClass(road.eid, node_based_graph)) has_normal_roads = true; } @@ -88,8 +88,8 @@ operator()(const NodeID, const EdgeID via_eid, Intersection intersection) const { intersection = fromMotorway(via_eid, std::move(intersection)); std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) { - if (road.turn.instruction.type == TurnType::OnRamp) - road.turn.instruction.type = TurnType::OffRamp; + if (road.instruction.type == TurnType::OnRamp) + road.instruction.type = TurnType::OffRamp; }); return intersection; } @@ -109,7 +109,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in unsigned count = 0; for (const auto &road : intersection) { - if (road.entry_allowed && isMotorwayClass(road.turn.eid, node_based_graph)) + if (road.entry_allowed && isMotorwayClass(road.eid, node_based_graph)) ++count; } return count; @@ -119,24 +119,24 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in const auto getContinueAngle = [this, in_data](const Intersection &intersection) { for (const auto &road : intersection) { - 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 && isMotorwayClass(road.turn.eid, node_based_graph)) - return road.turn.angle; + const auto &out_data = node_based_graph.GetEdgeData(road.eid); + if (road.angle != 0 && in_data.name_id == out_data.name_id && + in_data.name_id != EMPTY_NAMEID && isMotorwayClass(road.eid, node_based_graph)) + return road.angle; } - return intersection[0].turn.angle; + return intersection[0].angle; }; const auto getMostLikelyContinue = [this, in_data](const Intersection &intersection) { - double angle = intersection[0].turn.angle; + double angle = intersection[0].angle; double best = 180; for (const auto &road : intersection) { - if (isMotorwayClass(road.turn.eid, node_based_graph) && - angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < best) + if (isMotorwayClass(road.eid, node_based_graph) && + angularDeviation(road.angle, STRAIGHT_ANGLE) < best) { - best = angularDeviation(road.turn.angle, STRAIGHT_ANGLE); - angle = road.turn.angle; + best = angularDeviation(road.angle, STRAIGHT_ANGLE); + angle = road.angle; } } return angle; @@ -144,7 +144,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in const auto findBestContinue = [&]() { const double continue_angle = getContinueAngle(intersection); - if (continue_angle != intersection[0].turn.angle) + if (continue_angle != intersection[0].angle) return continue_angle; else return getMostLikelyContinue(intersection); @@ -153,13 +153,13 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in // find continue angle const double continue_angle = findBestContinue(); // highway does not continue and has no obvious choice - if (continue_angle == intersection[0].turn.angle) + if (continue_angle == intersection[0].angle) { if (intersection.size() == 2) { // do not announce ramps at the end of a highway - intersection[1].turn.instruction = {TurnType::NoTurn, - getTurnDirection(intersection[1].turn.angle)}; + intersection[1].instruction = {TurnType::NoTurn, + getTurnDirection(intersection[1].angle)}; } else if (intersection.size() == 3) { @@ -172,11 +172,11 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in { // ending in a passing ramp if (intersection[1].entry_allowed) - intersection[1].turn.instruction = { - TurnType::NoTurn, getTurnDirection(intersection[1].turn.angle)}; + intersection[1].instruction = {TurnType::NoTurn, + getTurnDirection(intersection[1].angle)}; else - intersection[2].turn.instruction = { - TurnType::NoTurn, getTurnDirection(intersection[2].turn.angle)}; + intersection[2].instruction = {TurnType::NoTurn, + getTurnDirection(intersection[2].angle)}; } } else if (intersection.size() == 4 && @@ -209,9 +209,8 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in { if (road.entry_allowed) { - BOOST_ASSERT(isRampClass(road.turn.eid, node_based_graph)); - road.turn.instruction = - TurnInstruction::SUPPRESSED(getTurnDirection(road.turn.angle)); + BOOST_ASSERT(isRampClass(road.eid, node_based_graph)); + road.instruction = TurnInstruction::SUPPRESSED(getTurnDirection(road.angle)); } } } @@ -220,9 +219,9 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in // normal motorway passing some ramps or mering onto another motorway if (intersection.size() == 2) { - BOOST_ASSERT(!isRampClass(intersection[1].turn.eid, node_based_graph)); + BOOST_ASSERT(!isRampClass(intersection[1].eid, node_based_graph)); - intersection[1].turn.instruction = + intersection[1].instruction = getInstructionForObvious(intersection.size(), via_eid, isThroughStreet(1, intersection), @@ -237,26 +236,26 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in if (!road.entry_allowed) continue; - if (road.turn.angle == continue_angle) + if (road.angle == continue_angle) { - road.turn.instruction = getInstructionForObvious( + road.instruction = getInstructionForObvious( intersection.size(), via_eid, isThroughStreet(1, intersection), road); } - else if (road.turn.angle < continue_angle) + else if (road.angle < continue_angle) { - road.turn.instruction = { - isRampClass(road.turn.eid, node_based_graph) ? TurnType::OffRamp - : TurnType::Turn, - (road.turn.angle < 145) ? DirectionModifier::Right - : DirectionModifier::SlightRight}; + road.instruction = {isRampClass(road.eid, node_based_graph) + ? TurnType::OffRamp + : TurnType::Turn, + (road.angle < 145) ? DirectionModifier::Right + : DirectionModifier::SlightRight}; } - else if (road.turn.angle > continue_angle) + else if (road.angle > continue_angle) { - road.turn.instruction = { - isRampClass(road.turn.eid, node_based_graph) ? TurnType::OffRamp - : TurnType::Turn, - (road.turn.angle > 215) ? DirectionModifier::Left - : DirectionModifier::SlightLeft}; + road.instruction = {isRampClass(road.eid, node_based_graph) + ? TurnType::OffRamp + : TurnType::Turn, + (road.angle > 215) ? DirectionModifier::Left + : DirectionModifier::SlightLeft}; } } } @@ -266,7 +265,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in { if (exiting_motorways == 2 && intersection.size() == 2) { - intersection[1].turn.instruction = + intersection[1].instruction = getInstructionForObvious(intersection.size(), via_eid, isThroughStreet(1, intersection), @@ -282,7 +281,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in for (std::size_t i = 0; i < intersection.size(); ++i) { if (intersection[i].entry_allowed && - isMotorwayClass(intersection[i].turn.eid, node_based_graph)) + isMotorwayClass(intersection[i].eid, node_based_graph)) { if (first_valid < intersection.size()) { @@ -306,7 +305,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in for (std::size_t i = 0; i < intersection.size(); ++i) { if (intersection[i].entry_allowed && - isMotorwayClass(intersection[i].turn.eid, node_based_graph)) + isMotorwayClass(intersection[i].eid, node_based_graph)) { if (second_valid < intersection.size()) { @@ -346,9 +345,9 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters if (intersection.size() == 2 && num_valid_turns == 1) { BOOST_ASSERT(!intersection[0].entry_allowed); - BOOST_ASSERT(isMotorwayClass(intersection[1].turn.eid, node_based_graph)); + BOOST_ASSERT(isMotorwayClass(intersection[1].eid, node_based_graph)); - intersection[1].turn.instruction = getInstructionForObvious( + intersection[1].instruction = getInstructionForObvious( intersection.size(), via_eid, isThroughStreet(1, intersection), intersection[1]); } else if (intersection.size() == 3) @@ -367,24 +366,23 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters // 0 if (intersection[1].entry_allowed) { - if (isMotorwayClass(intersection[1].turn.eid, node_based_graph) && - node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id != - EMPTY_NAMEID && - node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id == - node_based_graph.GetEdgeData(intersection[1].turn.eid).name_id) + if (isMotorwayClass(intersection[1].eid, node_based_graph) && + node_based_graph.GetEdgeData(intersection[2].eid).name_id != EMPTY_NAMEID && + node_based_graph.GetEdgeData(intersection[2].eid).name_id == + node_based_graph.GetEdgeData(intersection[1].eid).name_id) { // circular order indicates a merge to the left (0-3 onto 4 - if (angularDeviation(intersection[1].turn.angle, STRAIGHT_ANGLE) < + if (angularDeviation(intersection[1].angle, STRAIGHT_ANGLE) < 2 * NARROW_TURN_ANGLE) - intersection[1].turn.instruction = {TurnType::Merge, - DirectionModifier::SlightLeft}; + intersection[1].instruction = {TurnType::Merge, + DirectionModifier::SlightLeft}; else // fallback - intersection[1].turn.instruction = { - TurnType::Merge, getTurnDirection(intersection[1].turn.angle)}; + intersection[1].instruction = {TurnType::Merge, + getTurnDirection(intersection[1].angle)}; } else // passing by the end of a motorway { - intersection[1].turn.instruction = + intersection[1].instruction = getInstructionForObvious(intersection.size(), via_eid, isThroughStreet(1, intersection), @@ -394,24 +392,23 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters else { BOOST_ASSERT(intersection[2].entry_allowed); - if (isMotorwayClass(intersection[2].turn.eid, node_based_graph) && - node_based_graph.GetEdgeData(intersection[1].turn.eid).name_id != - EMPTY_NAMEID && - node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id == - node_based_graph.GetEdgeData(intersection[1].turn.eid).name_id) + if (isMotorwayClass(intersection[2].eid, node_based_graph) && + node_based_graph.GetEdgeData(intersection[1].eid).name_id != EMPTY_NAMEID && + node_based_graph.GetEdgeData(intersection[2].eid).name_id == + node_based_graph.GetEdgeData(intersection[1].eid).name_id) { // circular order (5-0) onto 4 - if (angularDeviation(intersection[2].turn.angle, STRAIGHT_ANGLE) < + if (angularDeviation(intersection[2].angle, STRAIGHT_ANGLE) < 2 * NARROW_TURN_ANGLE) - intersection[2].turn.instruction = {TurnType::Merge, - DirectionModifier::SlightRight}; + intersection[2].instruction = {TurnType::Merge, + DirectionModifier::SlightRight}; else // fallback - intersection[2].turn.instruction = { - TurnType::Merge, getTurnDirection(intersection[2].turn.angle)}; + intersection[2].instruction = {TurnType::Merge, + getTurnDirection(intersection[2].angle)}; } else // passing the end of a highway { - intersection[2].turn.instruction = + intersection[2].instruction = getInstructionForObvious(intersection.size(), via_eid, isThroughStreet(2, intersection), @@ -431,8 +428,8 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters // \ / // | // R - if (isMotorwayClass(intersection[1].turn.eid, node_based_graph) && - isMotorwayClass(intersection[2].turn.eid, node_based_graph)) + if (isMotorwayClass(intersection[1].eid, node_based_graph) && + isMotorwayClass(intersection[2].eid, node_based_graph)) { assignFork(via_eid, intersection[2], intersection[1]); } @@ -443,12 +440,11 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters // M R // | / // R - if (isMotorwayClass(intersection[1].turn.eid, node_based_graph)) + if (isMotorwayClass(intersection[1].eid, node_based_graph)) { - intersection[1].turn.instruction = {TurnType::Turn, - DirectionModifier::SlightRight}; - intersection[2].turn.instruction = {TurnType::Continue, - DirectionModifier::SlightLeft}; + intersection[1].instruction = {TurnType::Turn, DirectionModifier::SlightRight}; + intersection[2].instruction = {TurnType::Continue, + DirectionModifier::SlightLeft}; } else { @@ -463,20 +459,20 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters bool passed_highway_entry = false; for (auto &road : intersection) { - if (!road.entry_allowed && isMotorwayClass(road.turn.eid, node_based_graph)) + if (!road.entry_allowed && isMotorwayClass(road.eid, node_based_graph)) { passed_highway_entry = true; } - else if (isMotorwayClass(road.turn.eid, node_based_graph)) + else if (isMotorwayClass(road.eid, node_based_graph)) { - road.turn.instruction = {TurnType::Merge, - passed_highway_entry ? DirectionModifier::SlightRight - : DirectionModifier::SlightLeft}; + road.instruction = {TurnType::Merge, + passed_highway_entry ? DirectionModifier::SlightRight + : DirectionModifier::SlightLeft}; } else { - BOOST_ASSERT(isRampClass(road.turn.eid, node_based_graph)); - road.turn.instruction = {TurnType::OffRamp, getTurnDirection(road.turn.angle)}; + BOOST_ASSERT(isRampClass(road.eid, node_based_graph)); + road.instruction = {TurnType::OffRamp, getTurnDirection(road.angle)}; } } } @@ -498,26 +494,24 @@ Intersection MotorwayHandler::fallback(Intersection intersection) const continue; const auto type = - isMotorwayClass(road.turn.eid, node_based_graph) ? TurnType::Merge : TurnType::Turn; + isMotorwayClass(road.eid, node_based_graph) ? TurnType::Merge : TurnType::Turn; if (type == TurnType::Turn) { - if (angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE) - road.turn.instruction = {type, DirectionModifier::Straight}; + if (angularDeviation(road.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE) + road.instruction = {type, DirectionModifier::Straight}; else { - road.turn.instruction = {type, - road.turn.angle > STRAIGHT_ANGLE - ? DirectionModifier::SlightLeft - : DirectionModifier::SlightRight}; + road.instruction = {type, + road.angle > STRAIGHT_ANGLE ? DirectionModifier::SlightLeft + : DirectionModifier::SlightRight}; } } else { - road.turn.instruction = {type, - road.turn.angle < STRAIGHT_ANGLE - ? DirectionModifier::SlightLeft - : DirectionModifier::SlightRight}; + road.instruction = {type, + road.angle < STRAIGHT_ANGLE ? DirectionModifier::SlightLeft + : DirectionModifier::SlightRight}; } } return intersection; diff --git a/src/extractor/guidance/node_based_graph_walker.cpp b/src/extractor/guidance/node_based_graph_walker.cpp index 9351c6c63..1a489e0c5 100644 --- a/src/extractor/guidance/node_based_graph_walker.cpp +++ b/src/extractor/guidance/node_based_graph_walker.cpp @@ -29,13 +29,11 @@ bool LengthLimitedCoordinateAccumulator::terminate() { return accumulated_length // update the accumulator void LengthLimitedCoordinateAccumulator::update(const NodeID from_node, const EdgeID via_edge, - const NodeID to_node) + const NodeID /*to_node*/) { - const util::NodeBasedEdgeData &edge_data = node_based_graph.GetEdgeData(via_edge); - - const auto current_coordinates = coordinate_extractor.GetForwardCoordinatesAlongRoad( - from_node, via_edge); + const auto current_coordinates = + coordinate_extractor.GetForwardCoordinatesAlongRoad(from_node, via_edge); const auto length = util::coordinate_calculation::getLength( coordinates, util::coordinate_calculation::haversineDistance); @@ -77,10 +75,10 @@ operator()(const NodeID /*nid*/, result_score += 360.; // 180 for undesired name-ids - if (desired_name_id != node_based_graph.GetEdgeData(road.turn.eid).name_id) + if (desired_name_id != node_based_graph.GetEdgeData(road.eid).name_id) result_score += 180; - return result_score + angularDeviation(road.turn.angle, STRAIGHT_ANGLE); + return result_score + angularDeviation(road.angle, STRAIGHT_ANGLE); }; return score(lhs) < score(rhs); @@ -92,7 +90,7 @@ operator()(const NodeID /*nid*/, if (min_element == intersection.end() || (requires_entry && !min_element->entry_allowed)) return {}; else - return min_element->turn.eid; + return (*min_element).eid; } } // namespace guidance diff --git a/src/extractor/guidance/roundabout_handler.cpp b/src/extractor/guidance/roundabout_handler.cpp index 55cf94e08..f9fbcd238 100644 --- a/src/extractor/guidance/roundabout_handler.cpp +++ b/src/extractor/guidance/roundabout_handler.cpp @@ -77,7 +77,7 @@ detail::RoundaboutFlags RoundaboutHandler::getRoundaboutFlags( ++cnt, idx += step) { const auto &road = intersection[idx]; - const auto &edge_data = node_based_graph.GetEdgeData(road.turn.eid); + const auto &edge_data = node_based_graph.GetEdgeData(road.eid); // only check actual outgoing edges if (edge_data.reversed || !road.entry_allowed) continue; @@ -93,7 +93,7 @@ detail::RoundaboutFlags RoundaboutHandler::getRoundaboutFlags( // the roundabout. // The sorting of the angles represents a problem for left-sided driving, though. // FIXME requires consideration of crossing the roundabout - else if (node_based_graph.GetTarget(road.turn.eid) != from_nid && !can_enter_roundabout) + else if (node_based_graph.GetTarget(road.eid) != from_nid && !can_enter_roundabout) { can_exit_roundabout_separately = true; } @@ -116,7 +116,7 @@ void RoundaboutHandler::invalidateExitAgainstDirection(const NodeID from_nid, ++cnt, idx += step) { auto &road = intersection[idx]; - const auto &edge_data = node_based_graph.GetEdgeData(road.turn.eid); + const auto &edge_data = node_based_graph.GetEdgeData(road.eid); // only check actual outgoing edges if (edge_data.reversed) { @@ -131,7 +131,7 @@ void RoundaboutHandler::invalidateExitAgainstDirection(const NodeID from_nid, // This workaround handles cases in which an exit precedes and entry. The resulting // u-turn against the roundabout direction is invalidated. // The sorting of the angles represents a problem for left-sided driving, though. - if (!edge_data.roundabout && node_based_graph.GetTarget(road.turn.eid) != from_nid && + if (!edge_data.roundabout && node_based_graph.GetTarget(road.eid) != from_nid && past_roundabout_angle) { road.entry_allowed = false; @@ -379,8 +379,8 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou ++cnt, idx += step) { auto &road = intersection[idx]; - auto &turn = road.turn; - const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid); + auto &turn = road; + const auto &out_data = node_based_graph.GetEdgeData(road.eid); if (out_data.roundabout) { // TODO can forks happen in roundabouts? E.g. required lane changes @@ -419,7 +419,7 @@ Intersection RoundaboutHandler::handleRoundabouts(const RoundaboutType roundabou auto &road = intersection[idx]; if (!road.entry_allowed) continue; - auto &turn = road.turn; + auto &turn = road; const auto &out_data = node_based_graph.GetEdgeData(turn.eid); if (out_data.roundabout) { diff --git a/src/extractor/guidance/sliproad_handler.cpp b/src/extractor/guidance/sliproad_handler.cpp index 96bebd3ca..b6a7de632 100644 --- a/src/extractor/guidance/sliproad_handler.cpp +++ b/src/extractor/guidance/sliproad_handler.cpp @@ -53,8 +53,8 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection) const auto findNextIntersectionForRoad = [&](const NodeID at_node, const ConnectedRoad &road, NodeID &output_node) { - auto intersection = intersection_generator(at_node, road.turn.eid); - auto in_edge = road.turn.eid; + auto intersection = intersection_generator(at_node, road.eid); + auto in_edge = road.eid; // skip over traffic lights // to prevent ending up in an endless loop, we remember all visited nodes. This is // necessary, since merging of roads can actually create enterable loops of degree two @@ -71,7 +71,7 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection) intersection.clear(); return intersection; } - in_edge = intersection[1].turn.eid; + in_edge = intersection[1].eid; output_node = node_based_graph.GetTarget(in_edge); intersection = intersection_generator(node, in_edge); } @@ -87,8 +87,7 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection) const auto index = findObviousTurn(source_edge_id, intersection); if (index != 0) return index; - else if (intersection.size() == 3 && - intersection[1].turn.instruction.type == TurnType::Fork) + else if (intersection.size() == 3 && intersection[1].instruction.type == TurnType::Fork) { // Forks themselves do not contain a `obvious` turn index. If we look at a fork that has // a one-sided sliproad, however, the non-sliproad can be considered `obvious`. Here we @@ -136,10 +135,10 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection) const auto &next_road = intersection[obvious_turn_index]; const auto linkTest = [this, next_road](const ConnectedRoad &road) { - return !node_based_graph.GetEdgeData(road.turn.eid).roundabout && road.entry_allowed && - angularDeviation(road.turn.angle, STRAIGHT_ANGLE) <= 2 * NARROW_TURN_ANGLE && - !hasRoundaboutType(road.turn.instruction) && - angularDeviation(next_road.turn.angle, road.turn.angle) > + return !node_based_graph.GetEdgeData(road.eid).roundabout && road.entry_allowed && + angularDeviation(road.angle, STRAIGHT_ANGLE) <= 2 * NARROW_TURN_ANGLE && + !hasRoundaboutType(road.instruction) && + angularDeviation(next_road.angle, road.angle) > std::numeric_limits::epsilon(); }; @@ -151,7 +150,7 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection) const auto source_edge_data = node_based_graph.GetEdgeData(source_edge_id); // check whether the continue road is valid const auto check_valid = [this, source_edge_data](const ConnectedRoad &road) { - const auto road_edge_data = node_based_graph.GetEdgeData(road.turn.eid); + const auto road_edge_data = node_based_graph.GetEdgeData(road.eid); // Test to see if the source edge and the one we're looking at are the same road return road_edge_data.road_classification == source_edge_data.road_classification && road_edge_data.name_id != EMPTY_NAMEID && @@ -165,13 +164,13 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection) const auto coordinate_extractor = intersection_generator.GetCoordinateExtractor(); const auto next_road_length = util::coordinate_calculation::getLength( coordinate_extractor.GetForwardCoordinatesAlongRoad( - node_based_graph.GetTarget(source_edge_id), next_road.turn.eid), + node_based_graph.GetTarget(source_edge_id), next_road.eid), &util::coordinate_calculation::haversineDistance); if (next_road_length > MAX_SLIPROAD_THRESHOLD) { return intersection; } - auto next_intersection_node = node_based_graph.GetTarget(next_road.turn.eid); + auto next_intersection_node = node_based_graph.GetTarget(next_road.eid); const auto next_road_next_intersection = findNextIntersectionForRoad(intersection_node_id, next_road, next_intersection_node); @@ -187,7 +186,7 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection) for (const auto &road : next_road_next_intersection) { - const auto &target_data = node_based_graph.GetEdgeData(road.turn.eid); + const auto &target_data = node_based_graph.GetEdgeData(road.eid); target_road_names.insert(target_data.name_id); } @@ -195,20 +194,20 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection) { if (linkTest(road)) { - EdgeID candidate_in = road.turn.eid; + EdgeID candidate_in = road.eid; const auto target_intersection = [&](NodeID node) { auto intersection = intersection_generator(node, candidate_in); // skip over traffic lights if (intersection.size() == 2) { node = node_based_graph.GetTarget(candidate_in); - candidate_in = intersection[1].turn.eid; + candidate_in = intersection[1].eid; intersection = intersection_generator(node, candidate_in); } return intersection; }(intersection_node_id); - const auto link_data = node_based_graph.GetEdgeData(road.turn.eid); + const auto link_data = node_based_graph.GetEdgeData(road.eid); // Check if the road continues here const bool is_through_street = !target_intersection.empty() && @@ -216,7 +215,7 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection) std::find_if(target_intersection.begin() + 1, target_intersection.end(), [this, &link_data](const ConnectedRoad &road) { - return node_based_graph.GetEdgeData(road.turn.eid).name_id == + return node_based_graph.GetEdgeData(road.eid).name_id == link_data.name_id; }); @@ -226,26 +225,24 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection) for (const auto &candidate_road : target_intersection) { - const auto &candidate_data = node_based_graph.GetEdgeData(candidate_road.turn.eid); + const auto &candidate_data = node_based_graph.GetEdgeData(candidate_road.eid); if (target_road_names.count(candidate_data.name_id) > 0) { - if (node_based_graph.GetTarget(candidate_road.turn.eid) == - next_intersection_node) + if (node_based_graph.GetTarget(candidate_road.eid) == next_intersection_node) { - road.turn.instruction.type = TurnType::Sliproad; + road.instruction.type = TurnType::Sliproad; break; } else { const auto skip_traffic_light_intersection = intersection_generator( - node_based_graph.GetTarget(candidate_in), candidate_road.turn.eid); + node_based_graph.GetTarget(candidate_in), candidate_road.eid); if (skip_traffic_light_intersection.size() == 2 && - node_based_graph.GetTarget( - skip_traffic_light_intersection[1].turn.eid) == + node_based_graph.GetTarget(skip_traffic_light_intersection[1].eid) == next_intersection_node) { - road.turn.instruction.type = TurnType::Sliproad; + road.instruction.type = TurnType::Sliproad; break; } } @@ -254,27 +251,27 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection) } } - if (next_road.turn.instruction.type == TurnType::Fork) + if (next_road.instruction.type == TurnType::Fork) { - const auto &next_data = node_based_graph.GetEdgeData(next_road.turn.eid); + const auto &next_data = node_based_graph.GetEdgeData(next_road.eid); if (next_data.name_id == source_edge_data.name_id) { - if (angularDeviation(next_road.turn.angle, STRAIGHT_ANGLE) < 5) - intersection[obvious_turn_index].turn.instruction.type = TurnType::Suppressed; + if (angularDeviation(next_road.angle, STRAIGHT_ANGLE) < 5) + intersection[obvious_turn_index].instruction.type = TurnType::Suppressed; else - intersection[obvious_turn_index].turn.instruction.type = TurnType::Continue; - intersection[obvious_turn_index].turn.instruction.direction_modifier = - getTurnDirection(intersection[obvious_turn_index].turn.angle); + intersection[obvious_turn_index].instruction.type = TurnType::Continue; + intersection[obvious_turn_index].instruction.direction_modifier = + getTurnDirection(intersection[obvious_turn_index].angle); } else if (next_data.name_id != EMPTY_NAMEID) { - intersection[obvious_turn_index].turn.instruction.type = TurnType::NewName; - intersection[obvious_turn_index].turn.instruction.direction_modifier = - getTurnDirection(intersection[obvious_turn_index].turn.angle); + intersection[obvious_turn_index].instruction.type = TurnType::NewName; + intersection[obvious_turn_index].instruction.direction_modifier = + getTurnDirection(intersection[obvious_turn_index].angle); } else { - intersection[obvious_turn_index].turn.instruction.type = TurnType::Suppressed; + intersection[obvious_turn_index].instruction.type = TurnType::Suppressed; } } diff --git a/src/extractor/guidance/turn_analysis.cpp b/src/extractor/guidance/turn_analysis.cpp index 3237d5a8b..b59d9bc15 100644 --- a/src/extractor/guidance/turn_analysis.cpp +++ b/src/extractor/guidance/turn_analysis.cpp @@ -101,8 +101,8 @@ Intersection TurnAnalysis::assignTurnTypes(const NodeID from_nid, if (node_based_graph.GetEdgeData(via_eid).road_classification.IsMotorwayClass()) { std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) { - if (road.turn.instruction.type == TurnType::OnRamp) - road.turn.instruction.type = TurnType::OffRamp; + if (road.instruction.type == TurnType::OnRamp) + road.instruction.type = TurnType::OffRamp; }); } return intersection; @@ -114,7 +114,7 @@ TurnAnalysis::transformIntersectionIntoTurns(const Intersection &intersection) c std::vector turns; for (auto road : intersection) if (road.entry_allowed) - turns.emplace_back(road.turn); + turns.emplace_back(road); return turns; } @@ -133,12 +133,12 @@ TurnAnalysis::setTurnTypes(const NodeID from_nid, const EdgeID, Intersection int if (!road.entry_allowed) continue; - const EdgeID onto_edge = road.turn.eid; + const EdgeID onto_edge = road.eid; const NodeID to_nid = node_based_graph.GetTarget(onto_edge); - road.turn.instruction = {TurnType::Turn, - (from_nid == to_nid) ? DirectionModifier::UTurn - : getTurnDirection(road.turn.angle)}; + road.instruction = {TurnType::Turn, + (from_nid == to_nid) ? DirectionModifier::UTurn + : getTurnDirection(road.angle)}; } return intersection; } diff --git a/src/extractor/guidance/turn_classification.cpp b/src/extractor/guidance/turn_classification.cpp index 5ca003266..aeb34179d 100644 --- a/src/extractor/guidance/turn_classification.cpp +++ b/src/extractor/guidance/turn_classification.cpp @@ -35,7 +35,7 @@ classifyIntersection(Intersection intersection) std::sort(intersection.begin(), intersection.end(), [](const ConnectedRoad &left, const ConnectedRoad &right) { - return left.turn.bearing < right.turn.bearing; + return left.bearing < right.bearing; }); util::guidance::EntryClass entry_class; @@ -46,11 +46,11 @@ classifyIntersection(Intersection intersection) return true; DiscreteBearing last_discrete_bearing = util::guidance::BearingClass::getDiscreteBearing( - std::round(intersection.back().turn.bearing)); + std::round(intersection.back().bearing)); for (const auto road : intersection) { const DiscreteBearing discrete_bearing = - util::guidance::BearingClass::getDiscreteBearing(std::round(road.turn.bearing)); + util::guidance::BearingClass::getDiscreteBearing(std::round(road.bearing)); if (discrete_bearing == last_discrete_bearing) return false; last_discrete_bearing = discrete_bearing; @@ -62,8 +62,8 @@ classifyIntersection(Intersection intersection) std::size_t number = 0; if (canBeDiscretized) { - if (util::guidance::BearingClass::getDiscreteBearing(intersection.back().turn.bearing) < - util::guidance::BearingClass::getDiscreteBearing(intersection.front().turn.bearing)) + if (util::guidance::BearingClass::getDiscreteBearing(intersection.back().bearing) < + util::guidance::BearingClass::getDiscreteBearing(intersection.front().bearing)) { intersection.insert(intersection.begin(), intersection.back()); intersection.pop_back(); @@ -73,7 +73,7 @@ classifyIntersection(Intersection intersection) if (road.entry_allowed) entry_class.activate(number); auto discrete_bearing_class = - util::guidance::BearingClass::getDiscreteBearing(std::round(road.turn.bearing)); + util::guidance::BearingClass::getDiscreteBearing(std::round(road.bearing)); bearing_class.add(std::round(discrete_bearing_class * util::guidance::BearingClass::discrete_step_size)); ++number; @@ -85,7 +85,7 @@ classifyIntersection(Intersection intersection) { if (road.entry_allowed) entry_class.activate(number); - bearing_class.add(std::round(road.turn.bearing)); + bearing_class.add(std::round(road.bearing)); ++number; } } diff --git a/src/extractor/guidance/turn_discovery.cpp b/src/extractor/guidance/turn_discovery.cpp index 26b9b432e..c9a12caa7 100644 --- a/src/extractor/guidance/turn_discovery.cpp +++ b/src/extractor/guidance/turn_discovery.cpp @@ -48,28 +48,28 @@ bool findPreviousIntersection(const NodeID node_v, // Node -> Via_Edge -> Intersection[0 == UTURN] -> reverse_of(via_edge) -> Intersection at node // (looking at the reverse direction). const auto node_w = node_based_graph.GetTarget(via_edge); - const auto u_turn_at_node_w = intersection[0].turn.eid; + const auto u_turn_at_node_w = intersection[0].eid; const auto node_v_reverse_intersection = turn_analysis.getIntersection(node_w, u_turn_at_node_w); // Continue along the straightmost turn. If there is no straight turn, we cannot find a valid // previous intersection. const auto straightmost_at_v_in_reverse = - findClosestTurn(node_v_reverse_intersection, STRAIGHT_ANGLE); + node_v_reverse_intersection.findClosestTurn(STRAIGHT_ANGLE); // TODO evaluate if narrow turn is the right criterion here... Might be that other angles are // valid - if (angularDeviation(straightmost_at_v_in_reverse->turn.angle, STRAIGHT_ANGLE) > GROUP_ANGLE) + if (angularDeviation(straightmost_at_v_in_reverse->angle, STRAIGHT_ANGLE) > GROUP_ANGLE) return false; - const auto node_u = node_based_graph.GetTarget(straightmost_at_v_in_reverse->turn.eid); + const auto node_u = node_based_graph.GetTarget(straightmost_at_v_in_reverse->eid); const auto node_u_reverse_intersection = - turn_analysis.getIntersection(node_v, straightmost_at_v_in_reverse->turn.eid); + turn_analysis.getIntersection(node_v, straightmost_at_v_in_reverse->eid); // now check that the u-turn at the given intersection connects to via-edge // The u-turn at the now found intersection should, hopefully, represent the previous edge. result_node = node_u; - result_via_edge = node_u_reverse_intersection[0].turn.eid; + result_via_edge = node_u_reverse_intersection[0].eid; // if the edge is not traversable, we obviously don't have a previous intersection or couldn't // find it. @@ -85,7 +85,7 @@ bool findPreviousIntersection(const NodeID node_v, result_intersection.end() != std::find_if(result_intersection.begin(), result_intersection.end(), - [via_edge](const ConnectedRoad &road) { return road.turn.eid == via_edge; }); + [via_edge](const ConnectedRoad &road) { return road.eid == via_edge; }); if (!check_via_edge) { diff --git a/src/extractor/guidance/turn_handler.cpp b/src/extractor/guidance/turn_handler.cpp index f2ee0496f..53f1f320c 100644 --- a/src/extractor/guidance/turn_handler.cpp +++ b/src/extractor/guidance/turn_handler.cpp @@ -47,8 +47,8 @@ operator()(const NodeID, const EdgeID via_edge, Intersection intersection) const if (intersection[0].entry_allowed) { - intersection[0].turn.instruction = {findBasicTurnType(via_edge, intersection[0]), - DirectionModifier::UTurn}; + intersection[0].instruction = {findBasicTurnType(via_edge, intersection[0]), + DirectionModifier::UTurn}; } if (intersection.size() == 2) @@ -62,14 +62,14 @@ operator()(const NodeID, const EdgeID via_edge, Intersection intersection) const Intersection TurnHandler::handleOneWayTurn(Intersection intersection) const { - BOOST_ASSERT(intersection[0].turn.angle < 0.001); + BOOST_ASSERT(intersection[0].angle < 0.001); return intersection; } Intersection TurnHandler::handleTwoWayTurn(const EdgeID via_edge, Intersection intersection) const { - BOOST_ASSERT(intersection[0].turn.angle < 0.001); - intersection[1].turn.instruction = + BOOST_ASSERT(intersection[0].angle < 0.001); + intersection[1].instruction = getInstructionForObvious(intersection.size(), via_edge, false, intersection[1]); return intersection; @@ -81,8 +81,8 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge, { const auto &in_data = node_based_graph.GetEdgeData(via_edge); - const auto &first_data = node_based_graph.GetEdgeData(road.turn.eid); - const auto &second_data = node_based_graph.GetEdgeData(other.turn.eid); + const auto &first_data = node_based_graph.GetEdgeData(road.eid); + const auto &second_data = node_based_graph.GetEdgeData(other.eid); const auto &first_classification = first_data.road_classification; const auto &second_classification = second_data.road_classification; const bool is_ramp = first_classification.IsRampClass(); @@ -107,19 +107,18 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge, return false; const bool turn_is_perfectly_straight = - angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < std::numeric_limits::epsilon(); + angularDeviation(road.angle, STRAIGHT_ANGLE) < std::numeric_limits::epsilon(); if (turn_is_perfectly_straight && in_data.name_id != EMPTY_NAMEID && - in_data.name_id == node_based_graph.GetEdgeData(road.turn.eid).name_id) + in_data.name_id == node_based_graph.GetEdgeData(road.eid).name_id) return true; const bool is_much_narrower_than_other = - angularDeviation(other.turn.angle, STRAIGHT_ANGLE) / - angularDeviation(road.turn.angle, STRAIGHT_ANGLE) > + angularDeviation(other.angle, STRAIGHT_ANGLE) / + angularDeviation(road.angle, STRAIGHT_ANGLE) > INCREASES_BY_FOURTY_PERCENT && - angularDeviation(angularDeviation(other.turn.angle, STRAIGHT_ANGLE), - angularDeviation(road.turn.angle, STRAIGHT_ANGLE)) > - FUZZY_ANGLE_DIFFERENCE; + angularDeviation(angularDeviation(other.angle, STRAIGHT_ANGLE), + angularDeviation(road.angle, STRAIGHT_ANGLE)) > FUZZY_ANGLE_DIFFERENCE; return is_much_narrower_than_other; } @@ -127,7 +126,7 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge, Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection intersection) const { const auto obvious_index = findObviousTurn(via_edge, intersection); - BOOST_ASSERT(intersection[0].turn.angle < 0.001); + BOOST_ASSERT(intersection[0].angle < 0.001); /* Two nearly straight turns -> FORK OOOOOOO / @@ -151,26 +150,26 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection if (intersection[1].entry_allowed) { if (TurnType::OnRamp != findBasicTurnType(via_edge, intersection[1])) - intersection[1].turn.instruction = {TurnType::EndOfRoad, DirectionModifier::Right}; + intersection[1].instruction = {TurnType::EndOfRoad, DirectionModifier::Right}; else - intersection[1].turn.instruction = {TurnType::OnRamp, DirectionModifier::Right}; + intersection[1].instruction = {TurnType::OnRamp, DirectionModifier::Right}; } if (intersection[2].entry_allowed) { if (TurnType::OnRamp != findBasicTurnType(via_edge, intersection[2])) - intersection[2].turn.instruction = {TurnType::EndOfRoad, DirectionModifier::Left}; + intersection[2].instruction = {TurnType::EndOfRoad, DirectionModifier::Left}; else - intersection[2].turn.instruction = {TurnType::OnRamp, DirectionModifier::Left}; + intersection[2].instruction = {TurnType::OnRamp, DirectionModifier::Left}; } } else if (obvious_index != 0) // has an obvious continuing road/obvious turn { - const auto direction_at_one = getTurnDirection(intersection[1].turn.angle); - const auto direction_at_two = getTurnDirection(intersection[2].turn.angle); + const auto direction_at_one = getTurnDirection(intersection[1].angle); + const auto direction_at_two = getTurnDirection(intersection[2].angle); if (obvious_index == 1) { - intersection[1].turn.instruction = getInstructionForObvious( + intersection[1].instruction = getInstructionForObvious( 3, via_edge, isThroughStreet(1, intersection), intersection[1]); const auto second_direction = (direction_at_one == direction_at_two && @@ -178,13 +177,13 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection ? DirectionModifier::SlightLeft : direction_at_two; - intersection[2].turn.instruction = {findBasicTurnType(via_edge, intersection[2]), - second_direction}; + intersection[2].instruction = {findBasicTurnType(via_edge, intersection[2]), + second_direction}; } else { BOOST_ASSERT(obvious_index == 2); - intersection[2].turn.instruction = getInstructionForObvious( + intersection[2].instruction = getInstructionForObvious( 3, via_edge, isThroughStreet(2, intersection), intersection[2]); const auto first_direction = (direction_at_one == direction_at_two && @@ -192,16 +191,16 @@ Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection ? DirectionModifier::SlightRight : direction_at_one; - intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]), - first_direction}; + intersection[1].instruction = {findBasicTurnType(via_edge, intersection[1]), + first_direction}; } } else // basic turn assignment { - intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]), - getTurnDirection(intersection[1].turn.angle)}; - intersection[2].turn.instruction = {findBasicTurnType(via_edge, intersection[2]), - getTurnDirection(intersection[2].turn.angle)}; + intersection[1].instruction = {findBasicTurnType(via_edge, intersection[1]), + getTurnDirection(intersection[1].angle)}; + intersection[2].instruction = {findBasicTurnType(via_edge, intersection[2]), + getTurnDirection(intersection[2].angle)}; } return intersection; } @@ -214,7 +213,7 @@ Intersection TurnHandler::handleComplexTurn(const EdgeID via_edge, Intersection double straightmost_deviation = 180; for (std::size_t i = 0; i < intersection.size(); ++i) { - const double deviation = angularDeviation(intersection[i].turn.angle, STRAIGHT_ANGLE); + const double deviation = angularDeviation(intersection[i].angle, STRAIGHT_ANGLE); if (deviation < straightmost_deviation) { straightmost_deviation = deviation; @@ -225,7 +224,7 @@ Intersection TurnHandler::handleComplexTurn(const EdgeID via_edge, Intersection // check whether the obvious choice is actually a through street if (obvious_index != 0) { - intersection[obvious_index].turn.instruction = + intersection[obvious_index].instruction = getInstructionForObvious(intersection.size(), via_edge, isThroughStreet(obvious_index, intersection), @@ -242,24 +241,24 @@ Intersection TurnHandler::handleComplexTurn(const EdgeID via_edge, Intersection auto &left = intersection[fork_range.second]; auto &right = intersection[fork_range.first]; const auto left_classification = - node_based_graph.GetEdgeData(left.turn.eid).road_classification; + node_based_graph.GetEdgeData(left.eid).road_classification; const auto right_classification = - node_based_graph.GetEdgeData(right.turn.eid).road_classification; + node_based_graph.GetEdgeData(right.eid).road_classification; if (canBeSeenAsFork(left_classification, right_classification)) assignFork(via_edge, left, right); else if (left_classification.GetPriority() > right_classification.GetPriority()) { - right.turn.instruction = + right.instruction = getInstructionForObvious(intersection.size(), via_edge, false, right); - left.turn.instruction = {findBasicTurnType(via_edge, left), - DirectionModifier::SlightLeft}; + left.instruction = {findBasicTurnType(via_edge, left), + DirectionModifier::SlightLeft}; } else { - left.turn.instruction = + left.instruction = getInstructionForObvious(intersection.size(), via_edge, false, left); - right.turn.instruction = {findBasicTurnType(via_edge, right), - DirectionModifier::SlightRight}; + right.instruction = {findBasicTurnType(via_edge, right), + DirectionModifier::SlightRight}; } } else if (fork_range.second - fork_range.first == 2) @@ -281,13 +280,13 @@ Intersection TurnHandler::handleComplexTurn(const EdgeID via_edge, Intersection intersection = assignRightTurns(via_edge, std::move(intersection), straightmost_turn); } // no straight turn - else if (intersection[straightmost_turn].turn.angle > 180) + else if (intersection[straightmost_turn].angle > 180) { // at most three turns on either side intersection = assignLeftTurns(via_edge, std::move(intersection), straightmost_turn); intersection = assignRightTurns(via_edge, std::move(intersection), straightmost_turn); } - else if (intersection[straightmost_turn].turn.angle < 180) + else if (intersection[straightmost_turn].angle < 180) { intersection = assignLeftTurns(via_edge, std::move(intersection), straightmost_turn + 1); intersection = assignRightTurns(via_edge, std::move(intersection), straightmost_turn + 1); @@ -312,7 +311,7 @@ Intersection TurnHandler::assignLeftTurns(const EdgeID via_edge, BOOST_ASSERT(!intersection.empty()); for (auto &road : intersection) - road = mirror(std::move(road)); + road.mirror(); std::reverse(intersection.begin() + 1, intersection.end()); }; @@ -349,8 +348,8 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge, // Handle Turns 1-3 else if (up_to == 3) { - const auto first_direction = getTurnDirection(intersection[1].turn.angle); - const auto second_direction = getTurnDirection(intersection[2].turn.angle); + const auto first_direction = getTurnDirection(intersection[1].angle); + const auto second_direction = getTurnDirection(intersection[2].angle); if (first_direction == second_direction) { // conflict @@ -364,9 +363,9 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge, // Handle Turns 1-4 else if (up_to == 4) { - const auto first_direction = getTurnDirection(intersection[1].turn.angle); - const auto second_direction = getTurnDirection(intersection[2].turn.angle); - const auto third_direction = getTurnDirection(intersection[3].turn.angle); + const auto first_direction = getTurnDirection(intersection[1].angle); + const auto second_direction = getTurnDirection(intersection[2].angle); + const auto third_direction = getTurnDirection(intersection[3].angle); if (first_direction != second_direction && second_direction != third_direction) { // due to the circular order, the turn directions are unique @@ -395,28 +394,26 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge, // triggered 2>= ...) // // Conflicting Turns, but at least farther than what we call a narrow turn - else if (angularDeviation(intersection[1].turn.angle, intersection[2].turn.angle) >= + else if (angularDeviation(intersection[1].angle, intersection[2].angle) >= NARROW_TURN_ANGLE && - angularDeviation(intersection[2].turn.angle, intersection[3].turn.angle) >= + angularDeviation(intersection[2].angle, intersection[3].angle) >= NARROW_TURN_ANGLE) { BOOST_ASSERT(intersection[1].entry_allowed && intersection[2].entry_allowed && intersection[3].entry_allowed); - intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]), - DirectionModifier::SharpRight}; - intersection[2].turn.instruction = {findBasicTurnType(via_edge, intersection[2]), - DirectionModifier::Right}; - intersection[3].turn.instruction = {findBasicTurnType(via_edge, intersection[3]), - DirectionModifier::SlightRight}; + intersection[1].instruction = {findBasicTurnType(via_edge, intersection[1]), + DirectionModifier::SharpRight}; + intersection[2].instruction = {findBasicTurnType(via_edge, intersection[2]), + DirectionModifier::Right}; + intersection[3].instruction = {findBasicTurnType(via_edge, intersection[3]), + DirectionModifier::SlightRight}; } else if (((first_direction == second_direction && second_direction == third_direction) || (first_direction == second_direction && - angularDeviation(intersection[2].turn.angle, intersection[3].turn.angle) < - GROUP_ANGLE) || + angularDeviation(intersection[2].angle, intersection[3].angle) < GROUP_ANGLE) || (second_direction == third_direction && - angularDeviation(intersection[1].turn.angle, intersection[2].turn.angle) < - GROUP_ANGLE))) + angularDeviation(intersection[1].angle, intersection[2].angle) < GROUP_ANGLE))) { BOOST_ASSERT(intersection[1].entry_allowed && intersection[2].entry_allowed && intersection[3].entry_allowed); @@ -424,26 +421,23 @@ Intersection TurnHandler::assignRightTurns(const EdgeID via_edge, assignTrivialTurns(via_edge, intersection, 1, up_to); } else if (((first_direction == second_direction && - angularDeviation(intersection[2].turn.angle, intersection[3].turn.angle) >= - GROUP_ANGLE) || + angularDeviation(intersection[2].angle, intersection[3].angle) >= GROUP_ANGLE) || (second_direction == third_direction && - angularDeviation(intersection[1].turn.angle, intersection[2].turn.angle) >= - GROUP_ANGLE))) + angularDeviation(intersection[1].angle, intersection[2].angle) >= GROUP_ANGLE))) { BOOST_ASSERT(intersection[1].entry_allowed && intersection[2].entry_allowed && intersection[3].entry_allowed); - if (angularDeviation(intersection[2].turn.angle, intersection[3].turn.angle) >= - GROUP_ANGLE) + if (angularDeviation(intersection[2].angle, intersection[3].angle) >= GROUP_ANGLE) { handleDistinctConflict(via_edge, intersection[2], intersection[1]); - intersection[3].turn.instruction = {findBasicTurnType(via_edge, intersection[3]), - third_direction}; + intersection[3].instruction = {findBasicTurnType(via_edge, intersection[3]), + third_direction}; } else { - intersection[1].turn.instruction = {findBasicTurnType(via_edge, intersection[1]), - first_direction}; + intersection[1].instruction = {findBasicTurnType(via_edge, intersection[1]), + first_direction}; handleDistinctConflict(via_edge, intersection[3], intersection[2]); } } @@ -469,7 +463,7 @@ std::pair TurnHandler::findFork(const EdgeID via_edge, // TODO handle road classes for (std::size_t i = 1; i < intersection.size(); ++i) { - const double deviation = angularDeviation(intersection[i].turn.angle, STRAIGHT_ANGLE); + const double deviation = angularDeviation(intersection[i].angle, STRAIGHT_ANGLE); if (intersection[i].entry_allowed && deviation < best_deviation) { best_deviation = deviation; @@ -479,20 +473,19 @@ std::pair TurnHandler::findFork(const EdgeID via_edge, if (best_deviation <= NARROW_TURN_ANGLE) { std::size_t left = best, right = best; - while (left + 1 < intersection.size() && - (angularDeviation(intersection[left + 1].turn.angle, STRAIGHT_ANGLE) <= - NARROW_TURN_ANGLE || - (angularDeviation(intersection[left].turn.angle, - intersection[left + 1].turn.angle) <= NARROW_TURN_ANGLE && - angularDeviation(intersection[left].turn.angle, STRAIGHT_ANGLE) <= GROUP_ANGLE))) + while ( + left + 1 < intersection.size() && + (angularDeviation(intersection[left + 1].angle, STRAIGHT_ANGLE) <= NARROW_TURN_ANGLE || + (angularDeviation(intersection[left].angle, intersection[left + 1].angle) <= + NARROW_TURN_ANGLE && + angularDeviation(intersection[left].angle, STRAIGHT_ANGLE) <= GROUP_ANGLE))) ++left; while ( right > 1 && - (angularDeviation(intersection[right - 1].turn.angle, STRAIGHT_ANGLE) <= - NARROW_TURN_ANGLE || - (angularDeviation(intersection[right].turn.angle, intersection[right - 1].turn.angle) < + (angularDeviation(intersection[right - 1].angle, STRAIGHT_ANGLE) <= NARROW_TURN_ANGLE || + (angularDeviation(intersection[right].angle, intersection[right - 1].angle) < NARROW_TURN_ANGLE && - angularDeviation(intersection[right - 1].turn.angle, STRAIGHT_ANGLE) <= GROUP_ANGLE))) + angularDeviation(intersection[right - 1].angle, STRAIGHT_ANGLE) <= GROUP_ANGLE))) --right; if (left == right) @@ -500,12 +493,11 @@ std::pair TurnHandler::findFork(const EdgeID via_edge, const bool valid_indices = 0 < right && right < left; const bool separated_at_left_side = - angularDeviation(intersection[left].turn.angle, - intersection[(left + 1) % intersection.size()].turn.angle) >= - GROUP_ANGLE; + angularDeviation(intersection[left].angle, + intersection[(left + 1) % intersection.size()].angle) >= GROUP_ANGLE; const bool separated_at_right_side = right > 0 && - angularDeviation(intersection[right].turn.angle, intersection[right - 1].turn.angle) >= + angularDeviation(intersection[right].angle, intersection[right - 1].angle) >= GROUP_ANGLE; const bool not_more_than_three = (left - right) <= 2; @@ -527,28 +519,27 @@ std::pair TurnHandler::findFork(const EdgeID via_edge, // A fork can only happen between edges of similar types where none of the ones is obvious const bool has_compatible_classes = [&]() { - const bool ramp_class = node_based_graph.GetEdgeData(intersection[right].turn.eid) + const bool ramp_class = node_based_graph.GetEdgeData(intersection[right].eid) .road_classification.IsLinkClass(); for (std::size_t index = right + 1; index <= left; ++index) if (ramp_class != - node_based_graph.GetEdgeData(intersection[index].turn.eid) + node_based_graph.GetEdgeData(intersection[index].eid) .road_classification.IsLinkClass()) return false; const auto in_classification = - node_based_graph.GetEdgeData(intersection[0].turn.eid).road_classification; + node_based_graph.GetEdgeData(intersection[0].eid).road_classification; for (std::size_t base_index = right; base_index <= left; ++base_index) { const auto base_classification = - node_based_graph.GetEdgeData(intersection[base_index].turn.eid) - .road_classification; + node_based_graph.GetEdgeData(intersection[base_index].eid).road_classification; for (std::size_t compare_index = right; compare_index <= left; ++compare_index) { if (base_index == compare_index) continue; const auto compare_classification = - node_based_graph.GetEdgeData(intersection[compare_index].turn.eid) + node_based_graph.GetEdgeData(intersection[compare_index].eid) .road_classification; if (obviousByRoadClass( in_classification, base_classification, compare_classification)) @@ -589,25 +580,22 @@ void TurnHandler::handleDistinctConflict(const EdgeID via_edge, { // single turn of both is valid (don't change the valid one) // or multiple identical angles -> bad OSM intersection - if ((!left.entry_allowed || !right.entry_allowed) || (left.turn.angle == right.turn.angle)) + if ((!left.entry_allowed || !right.entry_allowed) || (left.angle == right.angle)) { if (left.entry_allowed) - left.turn.instruction = {findBasicTurnType(via_edge, left), - getTurnDirection(left.turn.angle)}; + left.instruction = {findBasicTurnType(via_edge, left), getTurnDirection(left.angle)}; if (right.entry_allowed) - right.turn.instruction = {findBasicTurnType(via_edge, right), - getTurnDirection(right.turn.angle)}; + right.instruction = {findBasicTurnType(via_edge, right), getTurnDirection(right.angle)}; return; } - if (getTurnDirection(left.turn.angle) == DirectionModifier::Straight || - getTurnDirection(left.turn.angle) == DirectionModifier::SlightLeft || - getTurnDirection(right.turn.angle) == DirectionModifier::SlightRight) + if (getTurnDirection(left.angle) == DirectionModifier::Straight || + getTurnDirection(left.angle) == DirectionModifier::SlightLeft || + getTurnDirection(right.angle) == DirectionModifier::SlightRight) { - const auto left_classification = - node_based_graph.GetEdgeData(left.turn.eid).road_classification; + const auto left_classification = node_based_graph.GetEdgeData(left.eid).road_classification; const auto right_classification = - node_based_graph.GetEdgeData(right.turn.eid).road_classification; + node_based_graph.GetEdgeData(right.eid).road_classification; if (canBeSeenAsFork(left_classification, right_classification)) assignFork(via_edge, left, right); else if (left_classification.GetPriority() > right_classification.GetPriority()) @@ -616,9 +604,8 @@ void TurnHandler::handleDistinctConflict(const EdgeID via_edge, // here we don't know about the intersection size. To be on the save side, // we declare it // as complex (at least size 4) - right.turn.instruction = getInstructionForObvious(4, via_edge, false, right); - left.turn.instruction = {findBasicTurnType(via_edge, left), - DirectionModifier::SlightLeft}; + right.instruction = getInstructionForObvious(4, via_edge, false, right); + left.instruction = {findBasicTurnType(via_edge, left), DirectionModifier::SlightLeft}; } else { @@ -626,81 +613,81 @@ void TurnHandler::handleDistinctConflict(const EdgeID via_edge, // here we don't know about the intersection size. To be on the save side, // we declare it // as complex (at least size 4) - left.turn.instruction = getInstructionForObvious(4, via_edge, false, left); - right.turn.instruction = {findBasicTurnType(via_edge, right), - DirectionModifier::SlightRight}; + left.instruction = getInstructionForObvious(4, via_edge, false, left); + right.instruction = {findBasicTurnType(via_edge, right), + DirectionModifier::SlightRight}; } } const auto left_type = findBasicTurnType(via_edge, left); const auto right_type = findBasicTurnType(via_edge, right); // Two Right Turns - if (angularDeviation(left.turn.angle, 90) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION) + if (angularDeviation(left.angle, 90) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION) { // Keep left perfect, shift right - left.turn.instruction = {left_type, DirectionModifier::Right}; - right.turn.instruction = {right_type, DirectionModifier::SharpRight}; + left.instruction = {left_type, DirectionModifier::Right}; + right.instruction = {right_type, DirectionModifier::SharpRight}; return; } - if (angularDeviation(right.turn.angle, 90) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION) + if (angularDeviation(right.angle, 90) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION) { // Keep Right perfect, shift left - left.turn.instruction = {left_type, DirectionModifier::SlightRight}; - right.turn.instruction = {right_type, DirectionModifier::Right}; + left.instruction = {left_type, DirectionModifier::SlightRight}; + right.instruction = {right_type, DirectionModifier::Right}; return; } // Two Right Turns - if (angularDeviation(left.turn.angle, 270) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION) + if (angularDeviation(left.angle, 270) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION) { // Keep left perfect, shift right - left.turn.instruction = {left_type, DirectionModifier::Left}; - right.turn.instruction = {right_type, DirectionModifier::SlightLeft}; + left.instruction = {left_type, DirectionModifier::Left}; + right.instruction = {right_type, DirectionModifier::SlightLeft}; return; } - if (angularDeviation(right.turn.angle, 270) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION) + if (angularDeviation(right.angle, 270) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION) { // Keep Right perfect, shift left - left.turn.instruction = {left_type, DirectionModifier::SharpLeft}; - right.turn.instruction = {right_type, DirectionModifier::Left}; + left.instruction = {left_type, DirectionModifier::SharpLeft}; + right.instruction = {right_type, DirectionModifier::Left}; return; } // Shift the lesser penalty - if (getTurnDirection(left.turn.angle) == DirectionModifier::SharpLeft) + if (getTurnDirection(left.angle) == DirectionModifier::SharpLeft) { - left.turn.instruction = {left_type, DirectionModifier::SharpLeft}; - right.turn.instruction = {right_type, DirectionModifier::Left}; + left.instruction = {left_type, DirectionModifier::SharpLeft}; + right.instruction = {right_type, DirectionModifier::Left}; return; } - if (getTurnDirection(right.turn.angle) == DirectionModifier::SharpRight) + if (getTurnDirection(right.angle) == DirectionModifier::SharpRight) { - left.turn.instruction = {left_type, DirectionModifier::Right}; - right.turn.instruction = {right_type, DirectionModifier::SharpRight}; + left.instruction = {left_type, DirectionModifier::Right}; + right.instruction = {right_type, DirectionModifier::SharpRight}; return; } - if (getTurnDirection(left.turn.angle) == DirectionModifier::Right) + if (getTurnDirection(left.angle) == DirectionModifier::Right) { - if (angularDeviation(left.turn.angle, 85) >= angularDeviation(right.turn.angle, 85)) + if (angularDeviation(left.angle, 85) >= angularDeviation(right.angle, 85)) { - left.turn.instruction = {left_type, DirectionModifier::Right}; - right.turn.instruction = {right_type, DirectionModifier::SharpRight}; + left.instruction = {left_type, DirectionModifier::Right}; + right.instruction = {right_type, DirectionModifier::SharpRight}; } else { - left.turn.instruction = {left_type, DirectionModifier::SlightRight}; - right.turn.instruction = {right_type, DirectionModifier::Right}; + left.instruction = {left_type, DirectionModifier::SlightRight}; + right.instruction = {right_type, DirectionModifier::Right}; } } else { - if (angularDeviation(left.turn.angle, 265) >= angularDeviation(right.turn.angle, 265)) + if (angularDeviation(left.angle, 265) >= angularDeviation(right.angle, 265)) { - left.turn.instruction = {left_type, DirectionModifier::SharpLeft}; - right.turn.instruction = {right_type, DirectionModifier::Left}; + left.instruction = {left_type, DirectionModifier::SharpLeft}; + right.instruction = {right_type, DirectionModifier::Left}; } else { - left.turn.instruction = {left_type, DirectionModifier::Left}; - right.turn.instruction = {right_type, DirectionModifier::SlightLeft}; + left.instruction = {left_type, DirectionModifier::Left}; + right.instruction = {right_type, DirectionModifier::SlightLeft}; } } } diff --git a/src/extractor/guidance/turn_lane_augmentation.cpp b/src/extractor/guidance/turn_lane_augmentation.cpp index 3939489cc..950355bb6 100644 --- a/src/extractor/guidance/turn_lane_augmentation.cpp +++ b/src/extractor/guidance/turn_lane_augmentation.cpp @@ -113,11 +113,11 @@ LaneDataVector augmentMultiple(const std::size_t none_index, if (intersection[intersection_index].entry_allowed) { // FIXME this probably can be only a subset of these turns here? - lane_data.push_back({tag_by_modifier[intersection[intersection_index] - .turn.instruction.direction_modifier], - lane_data[none_index].from, - lane_data[none_index].to, - false}); + lane_data.push_back( + {tag_by_modifier[intersection[intersection_index].instruction.direction_modifier], + lane_data[none_index].from, + lane_data[none_index].to, + false}); } } lane_data.erase(lane_data.begin() + none_index); @@ -162,7 +162,7 @@ LaneDataVector handleRenamingSituations(const std::size_t none_index, if (!road.entry_allowed) continue; - const auto modifier = road.turn.instruction.direction_modifier; + const auto modifier = road.instruction.direction_modifier; has_right |= modifier == DirectionModifier::Right; has_right |= modifier == DirectionModifier::SlightRight; has_right |= modifier == DirectionModifier::SharpRight; diff --git a/src/extractor/guidance/turn_lane_handler.cpp b/src/extractor/guidance/turn_lane_handler.cpp index d6b278da8..7587fe627 100644 --- a/src/extractor/guidance/turn_lane_handler.cpp +++ b/src/extractor/guidance/turn_lane_handler.cpp @@ -167,8 +167,8 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at, (intersection.size() == 2 && ((lane_description_id != INVALID_LANE_DESCRIPTIONID && lane_description_id == - node_based_graph.GetEdgeData(intersection[1].turn.eid).lane_description_id) || - angularDeviation(intersection[1].turn.angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE)); + node_based_graph.GetEdgeData(intersection[1].eid).lane_description_id) || + angularDeviation(intersection[1].angle, STRAIGHT_ANGLE) < FUZZY_ANGLE_DIFFERENCE)); if (is_going_straight_and_turns_continue) return TurnLaneScenario::NONE; @@ -201,9 +201,9 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at, const auto &road = previous_intersection[road_index]; // in case of a sliproad that is connected to road of simlar angle, we handle the // turn as a combined turn - if (road.turn.instruction.type == TurnType::Sliproad) + if (road.instruction.type == TurnType::Sliproad) { - if (via_edge == road.turn.eid) + if (via_edge == road.eid) return TurnLaneScenario::SLIPROAD; const auto &closest_road = [&]() { @@ -217,16 +217,16 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at, BOOST_ASSERT(road_index + 1 < previous_intersection.size()); return previous_intersection[road_index + 1]; } - else if (angularDeviation(road.turn.angle, - previous_intersection.at(road_index - 1).turn.angle) < - angularDeviation(road.turn.angle, - previous_intersection.at(road_index + 1).turn.angle)) + else if (angularDeviation(road.angle, + previous_intersection.at(road_index - 1).angle) < + angularDeviation(road.angle, + previous_intersection.at(road_index + 1).angle)) return previous_intersection[road_index - 1]; else return previous_intersection[road_index + 1]; }(); - if (via_edge == closest_road.turn.eid) + if (via_edge == closest_road.eid) return TurnLaneScenario::SLIPROAD; } } @@ -482,8 +482,8 @@ bool TurnLaneHandler::isSimpleIntersection(const LaneDataVector &lane_data, all_simple &= (best_match->entry_allowed || // check for possible u-turn match on non-reversed edge ((match_index == 0 || match_index + 1 == intersection.size()) && - !node_based_graph.GetEdgeData(best_match->turn.eid).reversed)); - all_simple &= isValidMatch(data.tag, best_match->turn.instruction); + !node_based_graph.GetEdgeData(best_match->eid).reversed)); + all_simple &= isValidMatch(data.tag, best_match->instruction); } // either all indices are matched, or we have a single none-value @@ -527,7 +527,7 @@ std::pair TurnLaneHandler::partitionLaneData( // Try and maitch lanes to available turns. For Turns that are not directly matchable, check // whether we can match them at the upcoming intersection. - const auto straightmost = findClosestTurn(intersection, STRAIGHT_ANGLE); + const auto straightmost = intersection.findClosestTurn(STRAIGHT_ANGLE); BOOST_ASSERT(straightmost < intersection.cend()); @@ -540,9 +540,9 @@ std::pair TurnLaneHandler::partitionLaneData( // find out about the next intersection. To check for valid matches, we also need the turn // types - auto next_intersection = turn_analysis.getIntersection(at, straightmost->turn.eid); + auto next_intersection = turn_analysis.getIntersection(at, straightmost->eid); next_intersection = - turn_analysis.assignTurnTypes(at, straightmost->turn.eid, std::move(next_intersection)); + turn_analysis.assignTurnTypes(at, straightmost->eid, std::move(next_intersection)); // check where we can match turn lanes std::size_t straightmost_tag_index = turn_lane_data.size(); @@ -554,7 +554,7 @@ std::pair TurnLaneHandler::partitionLaneData( const auto best_match = findBestMatch(turn_lane_data[lane].tag, intersection); if (best_match->entry_allowed && - isValidMatch(turn_lane_data[lane].tag, best_match->turn.instruction)) + isValidMatch(turn_lane_data[lane].tag, best_match->instruction)) { matched_at_first[lane] = true; @@ -565,8 +565,7 @@ std::pair TurnLaneHandler::partitionLaneData( const auto best_match_at_next_intersection = findBestMatch(turn_lane_data[lane].tag, next_intersection); if (best_match_at_next_intersection->entry_allowed && - isValidMatch(turn_lane_data[lane].tag, - best_match_at_next_intersection->turn.instruction)) + isValidMatch(turn_lane_data[lane].tag, best_match_at_next_intersection->instruction)) { if (!matched_at_first[lane] || turn_lane_data[lane].tag == TurnLaneType::straight || getMatchingQuality(turn_lane_data[lane].tag, *best_match) > @@ -679,7 +678,7 @@ Intersection TurnLaneHandler::handleSliproadTurn(Intersection intersection, std::find_if(previous_intersection.begin(), previous_intersection.end(), [](const ConnectedRoad &road) { - return road.turn.instruction.type == TurnType::Sliproad; + return road.instruction.type == TurnType::Sliproad; })); BOOST_ASSERT(sliproad_index <= previous_intersection.size()); @@ -697,18 +696,18 @@ Intersection TurnLaneHandler::handleSliproadTurn(Intersection intersection, BOOST_ASSERT(sliproad_index + 1 < previous_intersection.size()); return previous_intersection[sliproad_index + 1]; } - else if (angularDeviation(sliproad.turn.angle, - previous_intersection.at(sliproad_index - 1).turn.angle) < - angularDeviation(sliproad.turn.angle, - previous_intersection.at(sliproad_index + 1).turn.angle)) + else if (angularDeviation(sliproad.angle, + previous_intersection.at(sliproad_index - 1).angle) < + angularDeviation(sliproad.angle, + previous_intersection.at(sliproad_index + 1).angle)) return previous_intersection[sliproad_index - 1]; else return previous_intersection[sliproad_index + 1]; }(); const auto main_description_id = - node_based_graph.GetEdgeData(main_road.turn.eid).lane_description_id; + node_based_graph.GetEdgeData(main_road.eid).lane_description_id; const auto sliproad_description_id = - node_based_graph.GetEdgeData(sliproad.turn.eid).lane_description_id; + node_based_graph.GetEdgeData(sliproad.eid).lane_description_id; if (main_description_id == INVALID_LANE_DESCRIPTIONID || sliproad_description_id == INVALID_LANE_DESCRIPTIONID) @@ -716,7 +715,7 @@ Intersection TurnLaneHandler::handleSliproadTurn(Intersection intersection, TurnLaneDescription combined_description; // is the sliproad going off to the right? - if (main_road.turn.angle > sliproad.turn.angle) + if (main_road.angle > sliproad.angle) { combined_description.insert( combined_description.end(), diff --git a/src/extractor/guidance/turn_lane_matcher.cpp b/src/extractor/guidance/turn_lane_matcher.cpp index 9a064e3d8..f6aee06bc 100644 --- a/src/extractor/guidance/turn_lane_matcher.cpp +++ b/src/extractor/guidance/turn_lane_matcher.cpp @@ -109,7 +109,7 @@ double getMatchingQuality(const TurnLaneType::Mask tag, const ConnectedRoad &roa BOOST_ASSERT(static_cast(modifier) < sizeof(idealized_turn_angles) / sizeof(*idealized_turn_angles)); const auto idealized_angle = idealized_turn_angles[modifier]; - return angularDeviation(idealized_angle, road.turn.angle); + return angularDeviation(idealized_angle, road.angle); } // Every tag is somewhat idealized in form of the expected angle. A through lane should go straight @@ -123,9 +123,9 @@ typename Intersection::const_iterator findBestMatch(const TurnLaneType::Mask tag intersection.end(), [tag](const ConnectedRoad &lhs, const ConnectedRoad &rhs) { // prefer valid matches - if (isValidMatch(tag, lhs.turn.instruction) != - isValidMatch(tag, rhs.turn.instruction)) - return isValidMatch(tag, lhs.turn.instruction); + if (isValidMatch(tag, lhs.instruction) != + isValidMatch(tag, rhs.instruction)) + return isValidMatch(tag, lhs.instruction); // if the entry allowed flags don't match, we select the one with // entry allowed set to true @@ -154,8 +154,8 @@ typename Intersection::const_iterator findBestMatchForReverse(const TurnLaneType intersection.end(), [tag](const ConnectedRoad &lhs, const ConnectedRoad &rhs) { // prefer valid matches - if (isValidMatch(tag, lhs.turn.instruction) != isValidMatch(tag, rhs.turn.instruction)) - return isValidMatch(tag, lhs.turn.instruction); + if (isValidMatch(tag, lhs.instruction) != isValidMatch(tag, rhs.instruction)) + return isValidMatch(tag, lhs.instruction); // if the entry allowed flags don't match, we select the one with // entry allowed set to true @@ -182,7 +182,7 @@ bool canMatchTrivially(const Intersection &intersection, const LaneDataVector &l if (intersection[road_index].entry_allowed) { BOOST_ASSERT(lane_data[lane].from != INVALID_LANEID); - if (!isValidMatch(lane_data[lane].tag, intersection[road_index].turn.instruction)) + if (!isValidMatch(lane_data[lane].tag, intersection[road_index].instruction)) return false; if (findBestMatch(lane_data[lane].tag, intersection) != @@ -216,7 +216,7 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection, lane_data_id = it->second; // set lane id instead after the switch: - road.turn.lane_data_id = lane_data_id; + road.lane_data_id = lane_data_id; }; if (!lane_data.empty() && lane_data.front().tag == TurnLaneType::uturn) @@ -225,11 +225,10 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection, if (intersection[0].entry_allowed) { std::size_t u_turn = 0; - if (node_based_graph.GetEdgeData(intersection[0].turn.eid).reversed) + if (node_based_graph.GetEdgeData(intersection[0].eid).reversed) { if (intersection.size() <= 1 || !intersection[1].entry_allowed || - intersection[1].turn.instruction.direction_modifier != - DirectionModifier::SharpRight) + intersection[1].instruction.direction_modifier != DirectionModifier::SharpRight) { // cannot match u-turn in a valid way return intersection; @@ -238,8 +237,8 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection, road_index = 2; } intersection[u_turn].entry_allowed = true; - intersection[u_turn].turn.instruction.type = TurnType::Turn; - intersection[u_turn].turn.instruction.direction_modifier = DirectionModifier::UTurn; + intersection[u_turn].instruction.type = TurnType::Turn; + intersection[u_turn].instruction.direction_modifier = DirectionModifier::UTurn; matchRoad(intersection[u_turn], lane_data.back()); // continue with the first lane @@ -254,14 +253,13 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection, if (intersection[road_index].entry_allowed) { BOOST_ASSERT(lane_data[lane].from != INVALID_LANEID); - BOOST_ASSERT( - isValidMatch(lane_data[lane].tag, intersection[road_index].turn.instruction)); + BOOST_ASSERT(isValidMatch(lane_data[lane].tag, intersection[road_index].instruction)); BOOST_ASSERT(findBestMatch(lane_data[lane].tag, intersection) == intersection.begin() + road_index); - if (TurnType::Suppressed == intersection[road_index].turn.instruction.type && + if (TurnType::Suppressed == intersection[road_index].instruction.type && !lane_data[lane].suppress_assignment) - intersection[road_index].turn.instruction.type = TurnType::UseLane; + intersection[road_index].instruction.type = TurnType::UseLane; matchRoad(intersection[road_index], lane_data[lane]); ++lane; @@ -272,11 +270,10 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection, if (lane + 1 == lane_data.size() && lane_data.back().tag == TurnLaneType::uturn) { std::size_t u_turn = 0; - if (node_based_graph.GetEdgeData(intersection[0].turn.eid).reversed) + if (node_based_graph.GetEdgeData(intersection[0].eid).reversed) { if (!intersection.back().entry_allowed || - intersection.back().turn.instruction.direction_modifier != - DirectionModifier::SharpLeft) + intersection.back().instruction.direction_modifier != DirectionModifier::SharpLeft) { // cannot match u-turn in a valid way return intersection; @@ -284,8 +281,8 @@ Intersection triviallyMatchLanesToTurns(Intersection intersection, u_turn = intersection.size() - 1; } intersection[u_turn].entry_allowed = true; - intersection[u_turn].turn.instruction.type = TurnType::Turn; - intersection[u_turn].turn.instruction.direction_modifier = DirectionModifier::UTurn; + intersection[u_turn].instruction.type = TurnType::Turn; + intersection[u_turn].instruction.direction_modifier = DirectionModifier::UTurn; matchRoad(intersection[u_turn], lane_data.back()); } diff --git a/src/server/request_handler.cpp b/src/server/request_handler.cpp index ca10769f4..4497060da 100644 --- a/src/server/request_handler.cpp +++ b/src/server/request_handler.cpp @@ -30,7 +30,8 @@ namespace osrm namespace server { -void RequestHandler::RegisterServiceHandler(std::unique_ptr service_handler_) +void RequestHandler::RegisterServiceHandler( + std::unique_ptr service_handler_) { service_handler = std::move(service_handler_); }