| 779 | } // namespace |
| 780 | |
| 781 | RouterResultCode IndexRouter::CalculateSubrouteLeapsOnlyMode(Checkpoints const & checkpoints, size_t subrouteIdx, |
| 782 | IndexGraphStarter & starter, |
| 783 | RouterDelegate const & delegate, |
| 784 | shared_ptr<AStarProgress> const & progress, |
| 785 | vector<Segment> & subroute) |
| 786 | { |
| 787 | using Vertex = LeapsGraph::Vertex; |
| 788 | using Edge = LeapsGraph::Edge; |
| 789 | using Weight = LeapsGraph::Weight; |
| 790 | |
| 791 | // Get cross-mwm routes-candidates. |
| 792 | std::vector<RoutingResultT> candidates; |
| 793 | std::vector<RouteWeight> candidateMidWeights; |
| 794 | |
| 795 | { |
| 796 | LeapsGraph leapsGraph(starter, MwmHierarchyHandler(m_numMwmIds, m_countryParentNameGetterFn)); |
| 797 | |
| 798 | AStarSubProgress leapsProgress(mercator::ToLatLon(checkpoints.GetPoint(subrouteIdx)), |
| 799 | mercator::ToLatLon(checkpoints.GetPoint(subrouteIdx + 1)), kLeapsStageContribution); |
| 800 | SCOPE_GUARD(progressGuard, [&progress]() { progress->PushAndDropLastSubProgress(); }); |
| 801 | progress->AppendSubProgress(leapsProgress); |
| 802 | |
| 803 | // No need to call CheckLength in cross-mwm routine, thus we avoid calling GetRoadGeometry(). |
| 804 | struct AlwaysTrue |
| 805 | { |
| 806 | bool operator()(Weight const &) const { return true; } |
| 807 | }; |
| 808 | |
| 809 | using Visitor = JunctionVisitor<LeapsGraph>; |
| 810 | AStarAlgorithm<Vertex, Edge, Weight>::Params<Visitor, AlwaysTrue> params( |
| 811 | leapsGraph, leapsGraph.GetStartSegment(), leapsGraph.GetFinishSegment(), delegate.GetCancellable(), |
| 812 | Visitor(leapsGraph, delegate, kVisitPeriodForLeaps, progress), AlwaysTrue()); |
| 813 | |
| 814 | params.m_badReducedWeight = [](Weight const &, Weight const &) |
| 815 | { |
| 816 | /// @see CrossMwmConnector::GetTransition comment. |
| 817 | /// Unfortunately, reduced weight invariant in LeapsOnly mode doesn't work with the workaround above. |
| 818 | return false; |
| 819 | }; |
| 820 | |
| 821 | // Use Feature's index as a key to avoid multiple vertices with the same feature but a bit different segment. |
| 822 | using EdgeKeyT = std::array<uint32_t, 2>; |
| 823 | vector<RoutingResultT> routes; |
| 824 | set<EdgeKeyT> edges; |
| 825 | set<uint32_t> keys[2]; // 0 - end vertex of the first edge; 1 - beg vertex of the last edge |
| 826 | |
| 827 | auto const getBegEnd = [](RoutingResultT const & r) -> EdgeKeyT |
| 828 | { |
| 829 | size_t const pathSize = r.m_path.size(); |
| 830 | ASSERT_GREATER(pathSize, 2, ()); |
| 831 | return {r.m_path[1].GetFeatureId(), r.m_path[pathSize - 2].GetFeatureId()}; |
| 832 | }; |
| 833 | |
| 834 | /// @todo Looks like there is no big deal in this constant due to the bidirectional search. |
| 835 | /// But still Zalau -> Tiburg lasts 2 minutes, so set some reasonable timeout. |
| 836 | size_t constexpr kMaxVertices = 15; |
| 837 | uint64_t constexpr kTimeoutMilliS = 30 * 1000; |
| 838 | base::Timer timer; |
nothing calls this directly
no test coverage detected