diff --git a/routing/osrm_router.cpp b/routing/osrm_router.cpp index df35245358..7a36f21aef 100644 --- a/routing/osrm_router.cpp +++ b/routing/osrm_router.cpp @@ -183,21 +183,23 @@ OsrmRouter::ResultCode OsrmRouter::MakeRouteFromCrossesPath(TCheckedPath const & points.pop_back(); turnsDir.pop_back(); times.pop_back(); + if (streets.back().first >= points.size()) + streets.pop_back(); } // Get annotated route. - Route::TTurns mwmturnsDir; + Route::TTurns mwmTurnsDir; Route::TTimes mwmTimes; Route::TStreets mwmStreets; vector mwmPoints; - if (MakeTurnAnnotation(routingResult, mwmMapping, delegate, mwmPoints, mwmturnsDir, mwmTimes, mwmStreets) != NoError) + if (MakeTurnAnnotation(routingResult, mwmMapping, delegate, mwmPoints, mwmTurnsDir, mwmTimes, mwmStreets) != NoError) { LOG(LWARNING, ("Can't load road path data from disk for", mwmMapping->GetCountryName())); return RouteNotFound; } // Connect annotated route. auto const pSize = static_cast(points.size()); - for (auto turn : mwmturnsDir) + for (auto turn : mwmTurnsDir) { if (turn.m_index == 0) continue; @@ -205,6 +207,8 @@ OsrmRouter::ResultCode OsrmRouter::MakeRouteFromCrossesPath(TCheckedPath const & turnsDir.push_back(turn); } + if (!mwmStreets.empty() && !streets.empty() && mwmStreets.front().second == streets.back().second) + mwmStreets.erase(mwmStreets.begin()); for (auto street : mwmStreets) { if (street.first == 0) @@ -472,6 +476,10 @@ OsrmRouter::ResultCode OsrmRouter::MakeTurnAnnotation( // ETA information. double const nodeTimeSeconds = loadedSegment.m_weight * kOSRMWeightToSecondsMultiplier; + // Street names. I put empty names too, to avoid freezing old street name while riding on + // unnamed street. + streets.emplace_back(max(points.size(), (size_t)1) - 1, loadedSegment.m_name); + // Turns information. if (segmentIndex > 0 && !points.empty() && skipTurnSegments == 0) { diff --git a/routing/route.cpp b/routing/route.cpp index a0e172d133..b1a8ceb130 100644 --- a/routing/route.cpp +++ b/routing/route.cpp @@ -19,7 +19,7 @@ namespace { double constexpr kLocationTimeThreshold = 60.0 * 1.0; double constexpr kOnEndToleranceM = 10.0; - +double constexpr kSteetNameLinkMeters = 400.; } // namespace Route::Route(string const & router, vector const & points, string const & name) @@ -39,6 +39,7 @@ void Route::Swap(Route & rhs) swap(m_currentTime, rhs.m_currentTime); swap(m_turns, rhs.m_turns); swap(m_times, rhs.m_times); + swap(m_streets, rhs.m_streets); m_absentCountries.swap(rhs.m_absentCountries); } @@ -150,6 +151,52 @@ Route::TTurns::const_iterator Route::GetCurrentTurn() const }); } +void Route::GetCurrentStreetName(string & name) const +{ + auto it = GetCurrentStreetNameIterAfter(m_poly.GetCurrentIter()); + if (it == m_streets.cend()) + name.clear(); + name = it->second; +} + +void Route::GetStreetNameAfterIdx(uint32_t idx, string & name) const +{ + name.clear(); + auto polyIter = m_poly.GetIterToIndex(idx); + auto it = GetCurrentStreetNameIterAfter(polyIter); + if (it == m_streets.cend()) + return; + for (;it != m_streets.cend(); ++it) + if (!it->second.empty()) + { + if (m_poly.GetDistanceM(polyIter, m_poly.GetIterToIndex(it->first)) < kSteetNameLinkMeters) + name = it->second; + return; + } +} + +Route::TStreets::const_iterator Route::GetCurrentStreetNameIterAfter(FollowedPolyline::Iter iter) const +{ + if (m_streets.empty()) + { + ASSERT(false, ()); + return m_streets.cend(); + } + + TStreets::const_iterator curIter = m_streets.cbegin(); + TStreets::const_iterator prevIter = curIter; + curIter++; + + while (curIter->first<=iter.m_ind) + { + ++prevIter; + ++curIter; + if (curIter==m_streets.cend()) + return curIter; + } + return prevIter; +} + bool Route::GetCurrentTurn(double & distanceToTurnMeters, turns::TurnItem & turn) const { auto it = GetCurrentTurn(); diff --git a/routing/route.hpp b/routing/route.hpp index dbbec4d4b9..b47acef439 100644 --- a/routing/route.hpp +++ b/routing/route.hpp @@ -86,6 +86,12 @@ public: /// \param turn is information about the nearest turn. bool GetCurrentTurn(double & distanceToTurnMeters, turns::TurnItem & turn) const; + /// \brief Returns a name of a street where the user rides at this moment. + void GetCurrentStreetName(string &) const; + + /// \brief Returns a name of a street next to idx point of the path. Function avoids short unnamed links. + void GetStreetNameAfterIdx(uint32_t idx, string &) const; + /// @return true if GetNextTurn() returns a valid result in parameters, false otherwise. /// \param distanceToTurnMeters is a distance from current position to the second turn. /// \param turn is information about the second turn. @@ -122,6 +128,7 @@ private: void Update(); double GetPolySegAngle(size_t ind) const; TTurns::const_iterator GetCurrentTurn() const; + TStreets::const_iterator GetCurrentStreetNameIterAfter(FollowedPolyline::Iter iter) const; private: friend string DebugPrint(Route const & r); diff --git a/routing/routing_session.cpp b/routing/routing_session.cpp index 36115d69fa..d522b609e1 100644 --- a/routing/routing_session.cpp +++ b/routing/routing_session.cpp @@ -288,8 +288,8 @@ void RoutingSession::GetRouteFollowingInfo(FollowingInfo & info) const info.m_exitNum = turn.m_exitNum; info.m_time = max(kMinimumETASec, m_route.GetCurrentTimeToEndSec()); - info.m_sourceName = turn.m_sourceName; - info.m_targetName = turn.m_targetName; + m_route.GetCurrentStreetName(info.m_sourceName); + m_route.GetStreetNameAfterIdx(turn.m_index, info.m_targetName); info.m_completionPercent = GetCompletionPercent(); // Lane information. if (distanceToTurnMeters < kShowLanesDistInMeters)