diff --git a/features/guidance/collapse.feature b/features/guidance/collapse.feature index 42b7bc8fc..e3ff32917 100644 --- a/features/guidance/collapse.feature +++ b/features/guidance/collapse.feature @@ -338,10 +338,10 @@ Feature: Collapse Given the node map """ a f g - - b e - - + | | . ' + b-e ' + / / + / / c d """ @@ -353,13 +353,13 @@ Feature: Collapse | ge | primary | second | no | When I route I should get - | waypoints | route | turns | - | d,c | first,first,first | depart,continue uturn,arrive | - | a,f | first,first,first | depart,continue uturn,arrive | - | a,g | first,second,second | depart,turn left,arrive | - | d,g | first,second,second | depart,turn right,arrive | - | g,f | second,first,first | depart,turn right,arrive | - | g,c | second,first,first | depart,end of road left,arrive | + | waypoints | route | turns | + | d,c | first,first,first | depart,continue uturn,arrive | + | a,f | first,first,first | depart,continue uturn,arrive | + | a,g | first,second,second | depart,turn left,arrive | + | d,g | first,second,second | depart,turn right,arrive | + | g,f | second,first,first | depart,turn right,arrive | + | g,c | second,first,first | depart,turn left,arrive | Scenario: Do not collapse turning roads Given the node map diff --git a/include/engine/datafacade/process_memory_datafacade.hpp b/include/engine/datafacade/process_memory_datafacade.hpp index 58d2f780b..ded1fa506 100644 --- a/include/engine/datafacade/process_memory_datafacade.hpp +++ b/include/engine/datafacade/process_memory_datafacade.hpp @@ -3,8 +3,8 @@ // implements all data storage when shared memory is _NOT_ used -#include "engine/datafacade/contiguous_internalmem_datafacade_base.hpp" #include "storage/storage.hpp" +#include "engine/datafacade/contiguous_internalmem_datafacade_base.hpp" namespace osrm { diff --git a/include/extractor/extraction_way.hpp b/include/extractor/extraction_way.hpp index 3fe1673be..d98f08c42 100644 --- a/include/extractor/extraction_way.hpp +++ b/include/extractor/extraction_way.hpp @@ -15,19 +15,18 @@ namespace extractor { namespace detail { - inline void maybeSetString(std::string &str, const char* value) +inline void maybeSetString(std::string &str, const char *value) +{ + if (value == nullptr) { - if (value == nullptr) - { - str.clear(); - } - else - { - str = std::string(value); - } + str.clear(); + } + else + { + str = std::string(value); } } - +} /** * This struct is the direct result of the call to ```way_function``` @@ -67,18 +66,24 @@ struct ExtractionWay TravelMode get_backward_mode() const { return backward_travel_mode; } // wrappers to allow assigning nil (nullptr) to string values - void SetName(const char* value) { detail::maybeSetString(name, value); } - const char* GetName() const { return name.c_str(); } - void SetRef(const char* value) { detail::maybeSetString(ref, value); } - const char* GetRef() const { return ref.c_str(); } - void SetDestinations(const char* value) { detail::maybeSetString(destinations, value); } - const char* GetDestinations() const { return destinations.c_str(); } - void SetPronunciation(const char* value) { detail::maybeSetString(pronunciation, value); } - const char* GetPronunciation() const { return pronunciation.c_str(); } - void SetTurnLanesForward(const char* value) { detail::maybeSetString(turn_lanes_forward, value); } - const char* GetTurnLanesForward() const { return turn_lanes_forward.c_str(); } - void SetTurnLanesBackward(const char* value) { detail::maybeSetString(turn_lanes_backward, value); } - const char* GetTurnLanesBackward() const { return turn_lanes_backward.c_str(); } + void SetName(const char *value) { detail::maybeSetString(name, value); } + const char *GetName() const { return name.c_str(); } + void SetRef(const char *value) { detail::maybeSetString(ref, value); } + const char *GetRef() const { return ref.c_str(); } + void SetDestinations(const char *value) { detail::maybeSetString(destinations, value); } + const char *GetDestinations() const { return destinations.c_str(); } + void SetPronunciation(const char *value) { detail::maybeSetString(pronunciation, value); } + const char *GetPronunciation() const { return pronunciation.c_str(); } + void SetTurnLanesForward(const char *value) + { + detail::maybeSetString(turn_lanes_forward, value); + } + const char *GetTurnLanesForward() const { return turn_lanes_forward.c_str(); } + void SetTurnLanesBackward(const char *value) + { + detail::maybeSetString(turn_lanes_backward, value); + } + const char *GetTurnLanesBackward() const { return turn_lanes_backward.c_str(); } double forward_speed; double backward_speed; diff --git a/include/extractor/guidance/coordinate_extractor.hpp b/include/extractor/guidance/coordinate_extractor.hpp index f7982882d..c6cb17b12 100644 --- a/include/extractor/guidance/coordinate_extractor.hpp +++ b/include/extractor/guidance/coordinate_extractor.hpp @@ -1,6 +1,7 @@ #ifndef OSRM_EXTRACTOR_COORDINATE_EXTRACTOR_HPP_ #define OSRM_EXTRACTOR_COORDINATE_EXTRACTOR_HPP_ +#include #include #include "extractor/compressed_edge_container.hpp" @@ -28,6 +29,7 @@ class CoordinateExtractor /* Find a interpolated coordinate a long the compressed geometries. The desired coordinate * should be in a certain distance. This method is dedicated to find representative coordinates * at turns. + * Since we are computing the length of the segment anyhow, we also return it. */ OSRM_ATTR_WARN_UNUSED util::Coordinate GetCoordinateAlongRoad(const NodeID intersection_node, @@ -36,12 +38,23 @@ class CoordinateExtractor const NodeID to_node, const std::uint8_t number_of_in_lanes) const; - // instead of finding only a single coordinate, we can also list all coordinates along a road. + // same as above, only with precomputed coordinate vector (move it in) OSRM_ATTR_WARN_UNUSED - std::vector GetCoordinatesAlongRoad(const NodeID intersection_node, - const EdgeID turn_edge, - const bool traversed_in_reverse, - const NodeID to_node) const; + util::Coordinate + ExtractRepresentativeCoordinate(const NodeID intersection_node, + const EdgeID turn_edge, + const bool traversed_in_reverse, + const NodeID to_node, + const std::uint8_t intersection_lanes, + std::vector coordinates) const; + + // instead of finding only a single coordinate, we can also list all coordinates along a + // road. + OSRM_ATTR_WARN_UNUSED std::vector + GetCoordinatesAlongRoad(const NodeID intersection_node, + const EdgeID turn_edge, + const bool traversed_in_reverse, + const NodeID to_node) const; // wrapper in case of normal forward edges (traversed_in_reverse = false, to_node = // node_based_graph.GetTarget(turn_edge) diff --git a/include/extractor/guidance/intersection.hpp b/include/extractor/guidance/intersection.hpp index 02dbe62ff..74783970d 100644 --- a/include/extractor/guidance/intersection.hpp +++ b/include/extractor/guidance/intersection.hpp @@ -9,6 +9,8 @@ #include "util/node_based_graph.hpp" #include "util/typedefs.hpp" // EdgeID +#include + namespace osrm { namespace extractor @@ -53,10 +55,13 @@ struct ConnectedRoad final : public TurnOperation { using Base = TurnOperation; - ConnectedRoad(const TurnOperation turn, const bool entry_allowed = false); + ConnectedRoad(const TurnOperation turn, + const bool entry_allowed = false, + const boost::optional segment_length = {}); // a turn may be relevant to good instructions, even if we cannot enter the road bool entry_allowed; + boost::optional segment_length; // used to sort the set of connected roads (we require sorting throughout turn handling) bool compareByAngle(const ConnectedRoad &other) const; diff --git a/include/extractor/guidance/turn_analysis.hpp b/include/extractor/guidance/turn_analysis.hpp index dd4f8f5f7..c99fef1fe 100644 --- a/include/extractor/guidance/turn_analysis.hpp +++ b/include/extractor/guidance/turn_analysis.hpp @@ -68,6 +68,9 @@ class TurnAnalysis std::vector transformIntersectionIntoTurns(const Intersection &intersection) const; + Intersection + assignTurnTypes(const NodeID from_node, const EdgeID via_eid, Intersection intersection) const; + const IntersectionGenerator &GetIntersectionGenerator() const; private: @@ -79,9 +82,6 @@ class TurnAnalysis const TurnHandler turn_handler; const SliproadHandler sliproad_handler; - Intersection - assignTurnTypes(const NodeID from_node, const EdgeID via_eid, Intersection intersection) const; - // Utility function, setting basic turn types. Prepares for normal turn handling. Intersection setTurnTypes(const NodeID from, const EdgeID via_edge, Intersection intersection) const; diff --git a/include/extractor/guidance/turn_discovery.hpp b/include/extractor/guidance/turn_discovery.hpp index 725b6fa25..fefdfc454 100644 --- a/include/extractor/guidance/turn_discovery.hpp +++ b/include/extractor/guidance/turn_discovery.hpp @@ -22,7 +22,7 @@ namespace lanes bool findPreviousIntersection( const NodeID node, const EdgeID via_edge, - const Intersection intersection, + const Intersection &intersection, const IntersectionGenerator &intersection_generator, const util::NodeBasedDynamicGraph &node_based_graph, // query edge data // output parameters, will be in an arbitrary state on failure diff --git a/include/storage/shared_datatype.hpp b/include/storage/shared_datatype.hpp index f47ac73c2..a2a2e0627 100644 --- a/include/storage/shared_datatype.hpp +++ b/include/storage/shared_datatype.hpp @@ -134,11 +134,11 @@ struct DataLayout // Interface Similar to [ptr.align] but omits space computation. // The method can be removed and changed directly to an std::align // function call after dropping gcc < 5 support. - inline void* align(std::size_t align, std::size_t , void*& ptr) const noexcept + inline void *align(std::size_t align, std::size_t, void *&ptr) const noexcept { const auto intptr = reinterpret_cast(ptr); const auto aligned = (intptr - 1u + align) & -align; - return ptr = reinterpret_cast(aligned); + return ptr = reinterpret_cast(aligned); } inline void *GetAlignedBlockPtr(void *ptr, BlockID bid) const diff --git a/src/engine/plugins/match.cpp b/src/engine/plugins/match.cpp index 67a1f2c90..aa23b4a87 100644 --- a/src/engine/plugins/match.cpp +++ b/src/engine/plugins/match.cpp @@ -19,7 +19,8 @@ #include #include -static double search_radius_for_gps_radius(double gps_radius) { +static double search_radius_for_gps_radius(double gps_radius) +{ // For a given GPS radius, determine the radius we need to search for candidate street segments // to have a 99.9% chance of finding the correct segment. // For more detail, see the analysis at https://github.com/Project-OSRM/osrm-backend/pull/3184 diff --git a/src/extractor/guidance/coordinate_extractor.cpp b/src/extractor/guidance/coordinate_extractor.cpp index 5a0c893ae..101a33623 100644 --- a/src/extractor/guidance/coordinate_extractor.cpp +++ b/src/extractor/guidance/coordinate_extractor.cpp @@ -56,13 +56,29 @@ CoordinateExtractor::GetCoordinateAlongRoad(const NodeID intersection_node, const NodeID to_node, const std::uint8_t intersection_lanes) const { - const auto considered_lanes = - (intersection_lanes == 0) ? ASSUMED_LANE_COUNT : intersection_lanes; - // we first extract all coordinates from the road auto coordinates = GetCoordinatesAlongRoad(intersection_node, turn_edge, traversed_in_reverse, to_node); + return ExtractRepresentativeCoordinate(intersection_node, + turn_edge, + traversed_in_reverse, + to_node, + intersection_lanes, + std::move(coordinates)); +} + +util::Coordinate CoordinateExtractor::ExtractRepresentativeCoordinate( + const NodeID intersection_node, + const EdgeID turn_edge, + const bool traversed_in_reverse, + const NodeID to_node, + const std::uint8_t intersection_lanes, + std::vector coordinates) const +{ + const auto considered_lanes = + (intersection_lanes == 0) ? ASSUMED_LANE_COUNT : intersection_lanes; + /* if we are looking at a straight line, we don't care where exactly the coordinate * is. Simply return the final coordinate. Turn angles/turn vectors are the same no matter which * coordinate we look at. @@ -406,10 +422,12 @@ CoordinateExtractor::GetCoordinatesAlongRoad(const NodeID intersection_node, geometry.rend(), std::back_inserter(result), compressedGeometryToCoordinate); + BOOST_ASSERT(intersection_node < node_coordinates.size()); result.push_back(node_coordinates[intersection_node]); } else { + BOOST_ASSERT(intersection_node < node_coordinates.size()); result.push_back(node_coordinates[intersection_node]); std::transform(geometry.begin(), geometry.end(), diff --git a/src/extractor/guidance/intersection.cpp b/src/extractor/guidance/intersection.cpp index 53a6a618d..b23e703b9 100644 --- a/src/extractor/guidance/intersection.cpp +++ b/src/extractor/guidance/intersection.cpp @@ -17,8 +17,10 @@ namespace extractor namespace guidance { -ConnectedRoad::ConnectedRoad(const TurnOperation turn, const bool entry_allowed) - : TurnOperation(turn), entry_allowed(entry_allowed) +ConnectedRoad::ConnectedRoad(const TurnOperation turn, + const bool entry_allowed, + boost::optional segment_length) + : TurnOperation(turn), entry_allowed(entry_allowed), segment_length(segment_length) { } diff --git a/src/extractor/guidance/intersection_generator.cpp b/src/extractor/guidance/intersection_generator.cpp index 0fb648010..4ceb2e5a2 100644 --- a/src/extractor/guidance/intersection_generator.cpp +++ b/src/extractor/guidance/intersection_generator.cpp @@ -99,6 +99,19 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node, from_node, via_eid, traversed_in_reverse, to_node, intersection_lanes); }; + // The first coordinate (the origin) can depend on the number of lanes turning onto, + // just as the target coordinate can. Here we compute the corrected coordinate for the + // incoming edge + + // to compute the length along the path + const auto in_segment_length = [&]() { + const auto in_coordinates = + coordinate_extractor.GetCoordinatesAlongRoad(from_node, via_eid, INVERT, turn_node); + return util::coordinate_calculation::getLength( + in_coordinates, util::coordinate_calculation::haversineDistance); + }(); + const auto first_coordinate = extract_coordinate(from_node, via_eid, INVERT, turn_node); + for (const EdgeID onto_edge : node_based_graph.GetAdjacentEdgeRange(turn_node)) { BOOST_ASSERT(onto_edge != SPECIAL_EDGEID); @@ -117,14 +130,7 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node, // the turn is not restricted !restriction_map.CheckIfTurnIsRestricted(from_node, turn_node, to_node); - auto angle = 0.; - double bearing = 0.; - - // The first coordinate (the origin) can depend on the number of lanes turning onto, - // just as the target coordinate can. Here we compute the corrected coordinate for the - // incoming edge. - const auto first_coordinate = extract_coordinate(from_node, via_eid, INVERT, turn_node); - + double bearing = 0., out_segment_length = 0., angle = 0.; if (from_node == to_node) { bearing = util::coordinate_calculation::bearing(turn_coordinate, first_coordinate); @@ -150,14 +156,21 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node, } } has_uturn_edge = true; + out_segment_length = in_segment_length; BOOST_ASSERT(angle >= 0. && angle < std::numeric_limits::epsilon()); } else { // the default distance we lookahead on a road. This distance prevents small mapping // errors to impact the turn angles. - const auto third_coordinate = - extract_coordinate(turn_node, onto_edge, !INVERT, to_node); + { + // segment of out segment + const auto out_coordinates = coordinate_extractor.GetCoordinatesAlongRoad( + turn_node, onto_edge, !INVERT, to_node); + out_segment_length = util::coordinate_calculation::getLength( + out_coordinates, util::coordinate_calculation::haversineDistance); + } + const auto third_coordinate = extract_coordinate(turn_node, onto_edge, !INVERT, to_node); angle = util::coordinate_calculation::computeAngle( first_coordinate, turn_coordinate, third_coordinate); @@ -173,7 +186,8 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node, bearing, {TurnType::Invalid, DirectionModifier::UTurn}, INVALID_LANE_DATAID}, - turn_is_valid)); + turn_is_valid, + out_segment_length)); } // We hit the case of a street leading into nothing-ness. Since the code here assumes @@ -181,7 +195,6 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node, // will never happen we add an artificial invalid uturn in this case. if (!has_uturn_edge) { - const auto first_coordinate = extract_coordinate(from_node, via_eid, INVERT, turn_node); const double bearing = util::coordinate_calculation::bearing(turn_coordinate, first_coordinate); @@ -190,7 +203,8 @@ Intersection IntersectionGenerator::GetConnectedRoads(const NodeID from_node, bearing, {TurnType::Invalid, DirectionModifier::UTurn}, INVALID_LANE_DATAID}, - false}); + false, + in_segment_length}); } std::sort(std::begin(intersection), @@ -227,41 +241,41 @@ IntersectionGenerator::GetActualNextIntersection(const NodeID starting_node, NodeID *resulting_from_node = nullptr, EdgeID *resulting_via_edge = nullptr) const { - // This function skips over traffic lights/graph compression issues and similar to find the next - // actual intersection - Intersection result = GetConnectedRoads(starting_node, via_edge); + NodeID query_node = starting_node; + EdgeID query_edge = via_edge; - // Skip over stuff that has not been compressed due to barriers/parallel edges - NodeID node_at_intersection = starting_node; - EdgeID incoming_edge = via_edge; + const auto get_next_edge = [this](const NodeID from, const EdgeID via) { + const NodeID new_node = node_based_graph.GetTarget(via); + BOOST_ASSERT(node_based_graph.GetOutDegree(new_node) == 2); + const EdgeID begin_edges_new_node = node_based_graph.BeginEdges(new_node); + return (node_based_graph.GetTarget(begin_edges_new_node) == from) ? begin_edges_new_node + 1 + : begin_edges_new_node; + }; - // to prevent endless loops - const auto termination_node = node_based_graph.GetTarget(via_edge); - - // using a maximum lookahead, we make sure not to end up in some form of loop std::unordered_set visited_nodes; - while (visited_nodes.count(node_at_intersection) == 0 && - (result.size() == 2 && - node_based_graph.GetEdgeData(via_edge).IsCompatibleTo( - node_based_graph.GetEdgeData(result[1].eid)))) + // skip trivial nodes without generating the intersection in between, stop at the very first + // intersection of degree > 2 + while (0 == visited_nodes.count(query_node) && + 2 == node_based_graph.GetOutDegree(node_based_graph.GetTarget(query_edge))) { - visited_nodes.insert(node_at_intersection); - node_at_intersection = node_based_graph.GetTarget(incoming_edge); - 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. - if (termination_node == node_based_graph.GetTarget(incoming_edge)) + visited_nodes.insert(query_node); + const auto next_node = node_based_graph.GetTarget(query_edge); + const auto next_edge = get_next_edge(query_node, query_edge); + if (!node_based_graph.GetEdgeData(query_edge) + .IsCompatibleTo(node_based_graph.GetEdgeData(next_edge)) || + node_based_graph.GetTarget(next_edge) == starting_node) break; + + query_node = next_node; + query_edge = next_edge; } - // return output if requested if (resulting_from_node) - *resulting_from_node = node_at_intersection; + *resulting_from_node = query_node; if (resulting_via_edge) - *resulting_via_edge = incoming_edge; + *resulting_via_edge = query_edge; - return result; + return GetConnectedRoads(query_node, query_edge); } const CoordinateExtractor &IntersectionGenerator::GetCoordinateExtractor() const diff --git a/src/extractor/guidance/intersection_handler.cpp b/src/extractor/guidance/intersection_handler.cpp index 2e4d304e4..fad091116 100644 --- a/src/extractor/guidance/intersection_handler.cpp +++ b/src/extractor/guidance/intersection_handler.cpp @@ -1,5 +1,5 @@ -#include "extractor/guidance/constants.hpp" #include "extractor/guidance/intersection_handler.hpp" +#include "extractor/guidance/constants.hpp" #include "extractor/guidance/toolkit.hpp" #include "util/coordinate_calculation.hpp" @@ -473,8 +473,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, std::abs(best_option_deviation - straightest_data_deviation) > FUZZY_ANGLE_DIFFERENCE; const auto not_ramp_class = !straightest_data.road_classification.IsRampClass(); const auto not_link_class = !straightest_data.road_classification.IsLinkClass(); - if (deviation_diff && !IsLowPriority(straightest_data) && not_ramp_class && not_link_class && - !IsContinueRoad(best_option_data)) + if (deviation_diff && !IsLowPriority(straightest_data) && not_ramp_class && + not_link_class && !IsContinueRoad(best_option_data)) { best_option = std::distance(begin(intersection), straightest); best_option_deviation = @@ -489,7 +489,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, auto best_continue_it = std::min_element(begin(intersection), end(intersection), RoadCompareSameName); const auto best_continue_data = node_based_graph.GetEdgeData(best_continue_it->eid); - if (IsContinueRoad(best_continue_data) || (in_way_data.name_id == EMPTY_NAMEID && best_continue_data.name_id == EMPTY_NAMEID)) + if (IsContinueRoad(best_continue_data) || + (in_way_data.name_id == EMPTY_NAMEID && best_continue_data.name_id == EMPTY_NAMEID)) { best_continue = std::distance(begin(intersection), best_continue_it); best_continue_deviation = @@ -754,29 +755,36 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge, const util::Coordinate coordinate_at_u_turn = node_info_list[node_at_u_turn]; const double constexpr MAX_COLLAPSE_DISTANCE = 30; - if (util::coordinate_calculation::haversineDistance( - coordinate_at_intersection, coordinate_at_u_turn) < MAX_COLLAPSE_DISTANCE) + const auto distance_at_u_turn = intersection[0].segment_length + ? *intersection[0].segment_length + : util::coordinate_calculation::haversineDistance( + coordinate_at_intersection, coordinate_at_u_turn); + if (distance_at_u_turn < MAX_COLLAPSE_DISTANCE) { // this request here actually goes against the direction of the ingoing edgeid. This can // even reverse the direction. Since we don't want to compute actual turns but simply // try to find whether there is a turn going to the opposite direction of our obvious // turn, this should be alright. + NodeID new_node; const auto previous_intersection = intersection_generator.GetActualNextIntersection( - node_at_intersection, intersection[0].eid, nullptr, nullptr); + node_at_intersection, intersection[0].eid, &new_node, nullptr); - const auto continue_road = intersection[best_continue]; - for (const auto &comparison_road : previous_intersection) + if (new_node != node_at_intersection) { - // since we look at the intersection in the wrong direction, a similar angle - // 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.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; + const auto continue_road = intersection[best_continue]; + for (const auto &comparison_road : previous_intersection) + { + // since we look at the intersection in the wrong direction, a similar angle + // 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.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_normalizer.cpp b/src/extractor/guidance/intersection_normalizer.cpp index 6f19d6a4b..85a150c14 100644 --- a/src/extractor/guidance/intersection_normalizer.cpp +++ b/src/extractor/guidance/intersection_normalizer.cpp @@ -365,11 +365,17 @@ Intersection IntersectionNormalizer::AdjustForJoiningRoads(const NodeID node_at_ if (intersection.size() <= 1) return intersection; - const util::Coordinate coordinate_at_intersection = node_coordinates[node_at_intersection]; + // we don't adjust any road that is longer than 30 meters (between centers of intersections), + // since the road is probably too long otherwise to impact perception. + const double constexpr PRUNING_DISTANCE = 30; // never adjust u-turns for (std::size_t index = 1; index < intersection.size(); ++index) { auto &road = intersection[index]; + // only consider roads that are close + if (road.segment_length && *(road.segment_length) > PRUNING_DISTANCE) + continue; + // 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. @@ -380,11 +386,6 @@ Intersection IntersectionNormalizer::AdjustForJoiningRoads(const NodeID node_at_ continue; const auto node_at_next_intersection = node_based_graph.GetTarget(road.eid); - const util::Coordinate coordinate_at_next_intersection = - node_coordinates[node_at_next_intersection]; - if (util::coordinate_calculation::haversineDistance(coordinate_at_intersection, - coordinate_at_next_intersection) > 30) - continue; const auto adjustAngle = [](double angle, double offset) { angle += offset; diff --git a/src/extractor/guidance/turn_discovery.cpp b/src/extractor/guidance/turn_discovery.cpp index 275a1a8d6..1951fc2d7 100644 --- a/src/extractor/guidance/turn_discovery.cpp +++ b/src/extractor/guidance/turn_discovery.cpp @@ -19,7 +19,7 @@ const constexpr bool USE_LOW_PRECISION_MODE = true; bool findPreviousIntersection(const NodeID node_v, const EdgeID via_edge, - const Intersection intersection, + const Intersection &intersection, const IntersectionGenerator &intersection_generator, const util::NodeBasedDynamicGraph &node_based_graph, // output parameters @@ -55,6 +55,14 @@ bool findPreviousIntersection(const NodeID node_v, // (looking at the reverse direction). const auto node_w = node_based_graph.GetTarget(via_edge); const auto u_turn_at_node_w = intersection[0].eid; + // make sure the ID is actually valid + BOOST_ASSERT(node_based_graph.BeginEdges(node_w) <= u_turn_at_node_w && + u_turn_at_node_w <= node_based_graph.EndEdges(node_w)); + + // if we can't find the correct road, stop + if (node_based_graph.GetTarget(u_turn_at_node_w) != node_v) + return false; + const auto node_v_reverse_intersection = intersection_generator.GetConnectedRoads(node_w, u_turn_at_node_w, USE_LOW_PRECISION_MODE); @@ -77,6 +85,8 @@ bool findPreviousIntersection(const NodeID node_v, // 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].eid; + if (node_based_graph.GetTarget(result_via_edge) != node_v) + return false; // if the edge is not traversable, we obviously don't have a previous intersection or couldn't // find it. diff --git a/src/extractor/guidance/turn_lane_handler.cpp b/src/extractor/guidance/turn_lane_handler.cpp index e000c35bc..ac9a82932 100644 --- a/src/extractor/guidance/turn_lane_handler.cpp +++ b/src/extractor/guidance/turn_lane_handler.cpp @@ -196,7 +196,7 @@ TurnLaneScenario TurnLaneHandler::deduceScenario(const NodeID at, previous_intersection)) { extractLaneData(previous_via_edge, previous_description_id, previous_lane_data); - previous_intersection = turn_analysis.PostProcess( + previous_intersection = turn_analysis.assignTurnTypes( previous_node, previous_via_edge, std::move(previous_intersection)); for (std::size_t road_index = 0; road_index < previous_intersection.size(); ++road_index) { @@ -541,8 +541,9 @@ std::pair TurnLaneHandler::partitionLaneData( std::vector matched_at_second(turn_lane_data.size(), false); // find out about the next intersection. To check for valid matches, we also need the turn - // types - const auto next_intersection = turn_analysis(at, straightmost->eid); + // types. We can skip merging/angle adjustments, though + const auto next_intersection = turn_analysis.assignTurnTypes( + at, straightmost->eid, turn_analysis.GetIntersectionGenerator()(at, straightmost->eid)); // check where we can match turn lanes std::size_t straightmost_tag_index = turn_lane_data.size(); diff --git a/src/server/request_handler.cpp b/src/server/request_handler.cpp index 012b60481..4a3a013e1 100644 --- a/src/server/request_handler.cpp +++ b/src/server/request_handler.cpp @@ -8,8 +8,8 @@ #include "util/json_renderer.hpp" #include "util/simple_logger.hpp" #include "util/string_util.hpp" -#include "util/typedefs.hpp" #include "util/timing_util.hpp" +#include "util/typedefs.hpp" #include "engine/status.hpp" #include "osrm/osrm.hpp" @@ -146,11 +146,11 @@ void RequestHandler::HandleRequest(const http::request ¤t_request, http::r << 1900 + time_stamp->tm_year << " " << (time_stamp->tm_hour < 10 ? "0" : "") << time_stamp->tm_hour << ":" << (time_stamp->tm_min < 10 ? "0" : "") << time_stamp->tm_min << ":" << (time_stamp->tm_sec < 10 ? "0" : "") - << time_stamp->tm_sec << " " - << TIMER_MSEC(request_duration) << "ms " << current_request.endpoint.to_string() << " " - << current_request.referrer << (0 == current_request.referrer.length() ? "- " : " ") - << current_request.agent << (0 == current_request.agent.length() ? "- " : " ") - << current_reply.status << " " // + << time_stamp->tm_sec << " " << TIMER_MSEC(request_duration) << "ms " + << current_request.endpoint.to_string() << " " << current_request.referrer + << (0 == current_request.referrer.length() ? "- " : " ") << current_request.agent + << (0 == current_request.agent.length() ? "- " : " ") << current_reply.status + << " " // << request_string; } }