diff --git a/routing/base/astar_progress.cpp b/routing/base/astar_progress.cpp index 5622705deb..7512d4b8d5 100644 --- a/routing/base/astar_progress.cpp +++ b/routing/base/astar_progress.cpp @@ -1,6 +1,6 @@ #include "routing/base/astar_progress.hpp" -#include "geometry/distance_on_sphere.hpp" +#include "coding/point_coding.hpp" #include "base/assert.hpp" #include "base/math.hpp" @@ -10,7 +10,14 @@ namespace routing { -// AStarSubProgress ---------------------------------------------------------------------- + +double AStarSubProgress::CalcDistance(ms::LatLon const & from, ms::LatLon const & to) +{ + // Use very simple, naive and fast distance for progress, because the honest ms::DistanceOnEarth + // is very time-consuming and *on top* of routing calculation, taking into account frequent progress calls. + // We even added distance cache into RoadGeometry. + return fabs(from.m_lon - to.m_lon) + fabs(from.m_lat - to.m_lat); +} AStarSubProgress::AStarSubProgress(ms::LatLon const & start, ms::LatLon const & finish, double contributionCoef) @@ -18,7 +25,7 @@ AStarSubProgress::AStarSubProgress(ms::LatLon const & start, ms::LatLon const & { ASSERT_GREATER(m_contributionCoef, 0.0, ()); - m_fullDistance = ms::DistanceOnEarth(start, finish); + m_fullDistance = CalcDistance(start, finish); m_forwardDistance = m_fullDistance; m_backwardDistance = m_fullDistance; } @@ -32,10 +39,10 @@ AStarSubProgress::AStarSubProgress(double contributionCoef) double AStarSubProgress::UpdateProgress(ms::LatLon const & current, ms::LatLon const & finish) { // to avoid 0/0 - if (m_fullDistance < 1.0E-6) + if (m_fullDistance < kMwmPointAccuracy) return m_currentProgress; - double const dist = ms::DistanceOnEarth(current, finish); + double const dist = CalcDistance(current, finish); double & toUpdate = finish == m_finishPoint ? m_forwardDistance : m_backwardDistance; toUpdate = std::min(toUpdate, dist); diff --git a/routing/base/astar_progress.hpp b/routing/base/astar_progress.hpp index 2462fbcc90..c371087690 100644 --- a/routing/base/astar_progress.hpp +++ b/routing/base/astar_progress.hpp @@ -24,6 +24,8 @@ public: double GetMaxContribution() const; private: + static double CalcDistance(ms::LatLon const & from, ms::LatLon const & to); + double m_currentProgress = 0.0; double m_contributionCoef = 0.0; double m_fullDistance = 0.0; diff --git a/routing/index_graph_starter.cpp b/routing/index_graph_starter.cpp index 030e98cf1f..3b0fe9270c 100644 --- a/routing/index_graph_starter.cpp +++ b/routing/index_graph_starter.cpp @@ -270,18 +270,18 @@ RouteWeight IndexGraphStarter::CalcSegmentWeight(Segment const & segment, Segment real; if (m_fake.FindReal(segment, real)) { - auto const partLen = ms::DistanceOnEarth(vertex.GetPointFrom(), vertex.GetPointTo()); - auto const fullLen = - ms::DistanceOnEarth(GetPoint(real, false /* front */), GetPoint(real, true /* front */)); + double const partLen = ms::DistanceOnEarth(vertex.GetPointFrom(), vertex.GetPointTo()); + + if (IsRegionsGraphMode()) + return RouteWeight(partLen); + + double const fullLen = ms::DistanceOnEarth(GetPoint(real, false), GetPoint(real, true)); // Note 1. |fullLen| == 0.0 in case of Segment(s) with the same ends. // Note 2. There is the following logic behind |return 0.0 * m_graph.CalcSegmentWeight(real, ...);|: // it's necessary to return a instance of the structure |RouteWeight| with zero wight. // Theoretically it may be differ from |RouteWeight(0)| because some road access block // may be kept in it and it is up to |RouteWeight| to know how to multiply by zero. - if (IsRegionsGraphMode()) - return RouteWeight(partLen); - Weight weight; if (IsGuidesSegment(real)) weight = CalcGuidesSegmentWeight(real, purpose); @@ -386,12 +386,13 @@ void IndexGraphStarter::AddEnding(FakeEnding const & thisEnding) auto const it = otherSegments.find(projection.m_segment); if (it != otherSegments.end()) { - LatLonWithAltitude otherJunction = it->second[0]; - double distBackToOther = - ms::DistanceOnEarth(backJunction.GetLatLon(), otherJunction.GetLatLon()); + ASSERT(!it->second.empty(), ()); + + LatLonWithAltitude otherJunction; + double distBackToOther = 1.0E8; for (auto const & coord : it->second) { - double curDist = ms::DistanceOnEarth(backJunction.GetLatLon(), coord.GetLatLon()); + double const curDist = ms::DistanceOnEarth(backJunction.GetLatLon(), coord.GetLatLon()); if (curDist < distBackToOther) { distBackToOther = curDist; @@ -399,8 +400,7 @@ void IndexGraphStarter::AddEnding(FakeEnding const & thisEnding) } } - auto const distBackToThis = - ms::DistanceOnEarth(backJunction.GetLatLon(), projection.m_junction.GetLatLon()); + double const distBackToThis = ms::DistanceOnEarth(backJunction.GetLatLon(), projection.m_junction.GetLatLon()); if (distBackToThis < distBackToOther) frontJunction = otherJunction; diff --git a/routing/index_router.cpp b/routing/index_router.cpp index e0d6021e87..0d1675508d 100644 --- a/routing/index_router.cpp +++ b/routing/index_router.cpp @@ -64,7 +64,7 @@ uint32_t constexpr kVisitPeriodForLeaps = 10; uint32_t constexpr kVisitPeriod = 40; double constexpr kLeapsStageContribution = 0.15; -double constexpr kCandidatesStageContribution = 0.5; +double constexpr kCandidatesStageContribution = 0.55; double constexpr kAlmostZeroContribution = 1e-7; // If user left the route within this range(meters), adjust the route. Else full rebuild. @@ -880,28 +880,32 @@ RouterResultCode IndexRouter::CalculateSubrouteLeapsOnlyMode( starter.GetGraph().SetMode(WorldGraphMode::JointSingleMwm); RoutesCalculator calculator(starter, delegate); - - double const candidateContribution = kCandidatesStageContribution / (2 * candidates.size()); - - // Select best candidate by calculating start/end sub-routes and using candidateMidWeights. RoutingResultT const * bestC = nullptr; - RouteWeight bestW = GetAStarWeightMax(); - for (size_t i = 0; i < candidates.size(); ++i) + { - auto const & c = candidates[i]; - LOG(LDEBUG, ("Process leaps:", c.m_distance, c.m_path)); + SCOPE_GUARD(progressGuard, [&progress]() { progress->PushAndDropLastSubProgress(); }); + progress->AppendSubProgress(AStarSubProgress(kCandidatesStageContribution)); + double const candidateContribution = kCandidatesStageContribution / (2 * candidates.size()); - size_t const sz = c.m_path.size(); - auto const * r1 = calculator.Calc(c.m_path[0], c.m_path[1], progress, candidateContribution); - auto const * r2 = calculator.Calc(c.m_path[sz-2], c.m_path[sz-1], progress, candidateContribution); - - if (r1 && r2) + // Select best candidate by calculating start/end sub-routes and using candidateMidWeights. + RouteWeight bestW = GetAStarWeightMax(); + for (size_t i = 0; i < candidates.size(); ++i) { - RouteWeight const w = r1->m_distance + candidateMidWeights[i] + r2->m_distance; - if (w < bestW) + auto const & c = candidates[i]; + LOG(LDEBUG, ("Process leaps:", c.m_distance, c.m_path)); + + size_t const sz = c.m_path.size(); + auto const * r1 = calculator.Calc(c.m_path[0], c.m_path[1], progress, candidateContribution); + auto const * r2 = calculator.Calc(c.m_path[sz-2], c.m_path[sz-1], progress, candidateContribution); + + if (r1 && r2) { - bestW = w; - bestC = &c; + RouteWeight const w = r1->m_distance + candidateMidWeights[i] + r2->m_distance; + if (w < bestW) + { + bestW = w; + bestC = &c; + } } } }