diff --git a/routing/directions_engine.cpp b/routing/directions_engine.cpp index 869e3a6a74..38f94b44e5 100644 --- a/routing/directions_engine.cpp +++ b/routing/directions_engine.cpp @@ -323,10 +323,14 @@ void DirectionsEngine::MakeTurnAnnotation(IndexRoadGraph::EdgeVector const & rou CHECK_GREATER_OR_EQUAL(loadedSegment.m_segments.size(), 1, ()); CHECK_EQUAL(loadedSegment.m_segments.size() + 1, loadedSegment.m_path.size(), ()); + auto rni = loadedSegment.m_roadNameInfo; + for (size_t i = 0; i < loadedSegment.m_segments.size() - 1; ++i) { auto const & junction = loadedSegment.m_path[i + 1]; - routeSegments.emplace_back(loadedSegment.m_segments[i], TurnItem(), junction, RouteSegment::RoadNameInfo()); + routeSegments.emplace_back(loadedSegment.m_segments[i], TurnItem(), junction, rni); + if (i == 0) + rni = {"","","","", "", loadedSegment.m_isLink}; } // For the last segment of current loadedSegment put info about turn @@ -340,8 +344,7 @@ void DirectionsEngine::MakeTurnAnnotation(IndexRoadGraph::EdgeVector const & rou else --skipTurnSegments; - routeSegments.emplace_back(loadedSegment.m_segments.back(), turnItem, - loadedSegment.m_path.back(), loadedSegment.m_roadNameInfo); + routeSegments.emplace_back(loadedSegment.m_segments.back(), turnItem, loadedSegment.m_path.back(), rni); } ASSERT_EQUAL(routeSegments.front().GetJunction(), result.GetStartPoint(), ()); diff --git a/routing/route.cpp b/routing/route.cpp index e8dee2b0d4..fe5b5fcf1a 100644 --- a/routing/route.cpp +++ b/routing/route.cpp @@ -196,11 +196,10 @@ void Route::GetNextTurnStreetName(RouteSegment::RoadNameInfo & roadNameInfo) con // Usually |destination:ref| = |ref| in such cases, or only 1st part of |destination:ref| can match. void Route::GetClosestStreetNameAfterIdx(size_t segIdx, RouteSegment::RoadNameInfo & roadNameInfo) const { + roadNameInfo = {}; + if (!IsValid()) - { - roadNameInfo = {}; return; - } // Info about 1st segment with existing basic (non-link) info after link. RouteSegment::RoadNameInfo roadNameInfoNext; @@ -219,10 +218,15 @@ void Route::GetClosestStreetNameAfterIdx(size_t segIdx, RouteSegment::RoadNameIn roadNameInfo = r; break; } - else if (r.HasExitInfo() && !roadNameInfo.HasExitInfo()) - roadNameInfo = r; + else if (r.HasExitTextInfo() || i == segIdx) + { + ASSERT(!roadNameInfo.HasBasicTextInfo(), ()); + if (!roadNameInfo.HasExitTextInfo()) + roadNameInfo = r; + } + // For exit wait for non-exit. - else if (roadNameInfo.HasExitInfo() && !r.m_isLink) + if (roadNameInfo.HasExitInfo() && r.m_isLink) continue; // For non-exits check only during first |kSteetNameLinkMeters|. diff --git a/routing/route.hpp b/routing/route.hpp index 1a8e306e21..13bba5ba3a 100644 --- a/routing/route.hpp +++ b/routing/route.hpp @@ -77,9 +77,10 @@ public: bool m_isLink = false; bool HasBasicTextInfo() const { return !m_ref.empty() || !m_name.empty(); } - bool HasExitInfo() const + bool HasExitInfo() const { return m_isLink || HasExitTextInfo(); } + bool HasExitTextInfo() const { - return m_isLink || !m_junction_ref.empty() || !m_destination_ref.empty() || !m_destination.empty(); + return !m_junction_ref.empty() || !m_destination_ref.empty() || !m_destination.empty(); } friend std::string DebugPrint(RoadNameInfo const & rni); diff --git a/routing/routing_integration_tests/turn_test.cpp b/routing/routing_integration_tests/turn_test.cpp index 43bcea409c..612c7470db 100644 --- a/routing/routing_integration_tests/turn_test.cpp +++ b/routing/routing_integration_tests/turn_test.cpp @@ -1213,3 +1213,72 @@ UNIT_TEST(Russia_Moscow_OnlyUTurnTest1WithDirection_TurnTest) integration::GetNthTurn(route, 0).TestValid().TestDirection(CarDirection::UTurnLeft); } */ + +// Slight turn to the long link which is followed by another link. +UNIT_TEST(USA_California_Cupertino_TurnTestNextRoad) +{ + TRouteResult const routeResult = + integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Car), + mercator::FromLatLon(37.5031583, -122.3317724), {0., 0.}, + mercator::FromLatLon(37.5110368, -122.3317238)); + + Route const & route = *routeResult.first; + RouterResultCode const result = routeResult.second; + + TEST_EQUAL(result, RouterResultCode::NoError, ()); + + double d; + TurnItem turn; + route.GetNearestTurn(d, turn); + TEST_EQUAL(turn.m_turn, CarDirection::TurnSlightRight, ()); + RouteSegment::RoadNameInfo ri; + route.GetNextTurnStreetName(ri); + TEST_EQUAL(ri.m_destination, "San Mateo; Hayward; Belmont", ()); + TEST_EQUAL(ri.m_destination_ref, "CA 92 East", ()); +} + +// Take destination from link and destination_ref from the next road. +UNIT_TEST(Cyprus_Governors_Beach_TurnTestNextRoad) +{ + TRouteResult const routeResult = + integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Car), + mercator::FromLatLon(34.7247792, 33.2719482), {0., 0.}, + mercator::FromLatLon(34.7230031, 33.2727327)); + + Route const & route = *routeResult.first; + RouterResultCode const result = routeResult.second; + + TEST_EQUAL(result, RouterResultCode::NoError, ()); + + double d; + TurnItem turn; + route.GetNearestTurn(d, turn); + TEST_EQUAL(turn.m_turn, CarDirection::ExitHighwayToLeft, ()); + RouteSegment::RoadNameInfo ri; + route.GetNextTurnStreetName(ri); + TEST_EQUAL(ri.m_destination, "Governer's Beach; Pentakomo", ()); + TEST_EQUAL(ri.m_destination_ref, "B1", ()); +} + +// Exit which is marked as non-link, but has link tags m_destination_ref and m_destination. +UNIT_TEST(Cyprus_A1_A5_TurnTestNextRoad) +{ + TRouteResult const routeResult = + integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Car), + mercator::FromLatLon(34.83254, 33.3835), {0., 0.}, + mercator::FromLatLon(34.83793, 33.3926)); + + Route const & route = *routeResult.first; + RouterResultCode const result = routeResult.second; + + TEST_EQUAL(result, RouterResultCode::NoError, ()); + + double d; + TurnItem turn; + route.GetNearestTurn(d, turn); + TEST_EQUAL(turn.m_turn, CarDirection::TurnSlightLeft, ()); + RouteSegment::RoadNameInfo ri; + route.GetNextTurnStreetName(ri); + TEST_EQUAL(ri.m_destination, "Larnaka; Kefinou; Airport", ()); + TEST_EQUAL(ri.m_destination_ref, "A5", ()); +}