| 622 | } |
| 623 | |
| 624 | bool Router::ReconstructPath(std::vector<Edge> & edges, Path & path) |
| 625 | { |
| 626 | CHECK_GREATER_OR_EQUAL(m_points.size(), 2, ()); |
| 627 | |
| 628 | using EdgeIt = std::vector<Edge>::iterator; |
| 629 | using EdgeItRev = std::vector<Edge>::reverse_iterator; |
| 630 | |
| 631 | double const kFakeCoverageThreshold = 0.5; |
| 632 | |
| 633 | base::EraseIf(edges, [](auto && e) { return e.IsSpecial(); }); |
| 634 | |
| 635 | { |
| 636 | auto toPair = [](auto && e) { return e.ToPair(); }; |
| 637 | size_t const n = FindPrefixLengthToConsume(make_transform_iterator(edges.begin(), toPair), |
| 638 | make_transform_iterator(edges.end(), toPair), m_positiveOffsetM); |
| 639 | CHECK_LESS_OR_EQUAL(n, edges.size(), ()); |
| 640 | edges.erase(edges.begin(), edges.begin() + n); |
| 641 | } |
| 642 | |
| 643 | { |
| 644 | auto toPairRev = [](auto && e) { return e.ToPairRev(); }; |
| 645 | size_t const n = FindPrefixLengthToConsume(make_transform_iterator(edges.rbegin(), toPairRev), |
| 646 | make_transform_iterator(edges.rend(), toPairRev), m_negativeOffsetM); |
| 647 | CHECK_LESS_OR_EQUAL(n, edges.size(), ()); |
| 648 | edges.erase(edges.begin() + edges.size() - n, edges.end()); |
| 649 | } |
| 650 | |
| 651 | double frontEdgeScore = -1.0; |
| 652 | routing::Edge frontEdge; |
| 653 | ForStagePrefix(edges.begin(), edges.end(), 0, [&](EdgeIt e) |
| 654 | { |
| 655 | ForEachNonFakeEdge(e->m_u, false /* outgoing */, m_points[0].m_lfrcnp, [&](routing::Edge const & edge) |
| 656 | { |
| 657 | auto toPairRev = [](auto && e) { return e.ToPairRev(); }; |
| 658 | double const score = GetMatchingScore(edge.GetEndJunction().GetPoint(), edge.GetStartJunction().GetPoint(), |
| 659 | make_transform_iterator(EdgeItRev(e), toPairRev), |
| 660 | make_transform_iterator(edges.rend(), toPairRev)); |
| 661 | if (score > frontEdgeScore) |
| 662 | { |
| 663 | frontEdgeScore = score; |
| 664 | frontEdge = edge.GetReverseEdge(); |
| 665 | } |
| 666 | }); |
| 667 | }); |
| 668 | |
| 669 | double backEdgeScore = -1.0; |
| 670 | routing::Edge backEdge; |
| 671 | ForStagePrefix(edges.rbegin(), edges.rend(), m_points.size() - 2 /* stage */, [&](EdgeItRev e) |
| 672 | { |
| 673 | ForEachNonFakeEdge(e->m_v, true /* outgoing */, m_points[m_points.size() - 2].m_lfrcnp, |
| 674 | [&](routing::Edge const & edge) |
| 675 | { |
| 676 | auto toPair = [](auto && e) { return e.ToPair(); }; |
| 677 | double const score = |
| 678 | GetMatchingScore(edge.GetStartJunction().GetPoint(), edge.GetEndJunction().GetPoint(), |
| 679 | make_transform_iterator(e.base(), toPair), make_transform_iterator(edges.end(), toPair)); |
| 680 | if (score > backEdgeScore) |
| 681 | { |
nothing calls this directly
no test coverage detected