diff --git a/openlr/openlr_simple_decoder.cpp b/openlr/openlr_simple_decoder.cpp index 0beb2781d8..8a23202bfb 100644 --- a/openlr/openlr_simple_decoder.cpp +++ b/openlr/openlr_simple_decoder.cpp @@ -40,6 +40,7 @@ struct alignas(kCacheLineSize) Stats m_zeroCanditates += rhs.m_zeroCanditates; m_moreThanOneCandidate += rhs.m_moreThanOneCandidate; m_routeIsNotCalculated += rhs.m_routeIsNotCalculated; + m_tightOffsets += rhs.m_tightOffsets; m_total += rhs.m_total; } @@ -47,6 +48,7 @@ struct alignas(kCacheLineSize) Stats uint32_t m_zeroCanditates = 0; uint32_t m_moreThanOneCandidate = 0; uint32_t m_routeIsNotCalculated = 0; + uint32_t m_tightOffsets = 0; uint32_t m_total = 0; }; @@ -119,6 +121,8 @@ OpenLRSimpleDecoder::OpenLRSimpleDecoder(string const & dataFilename, vector segments; @@ -144,8 +148,8 @@ void OpenLRSimpleDecoder::Decode(string const & outputFilename, int const segmen size_t constexpr kBatchSize = my::LCM(a, b); size_t constexpr kProgressFrequency = 100; - auto worker = [&segments, &paths, kBatchSize, kProgressFrequency, numThreads, this]( - size_t threadNum, Index const & index, Stats & stats) { + auto worker = [&segments, &paths, kBatchSize, kProgressFrequency, kOffsetToleranceM, numThreads, + this](size_t threadNum, Index const & index, Stats & stats) { FeaturesRoadGraph roadGraph(index, IRoadGraph::Mode::ObeyOnewayTag, make_unique()); RoadInfoGetter roadInfoGetter(index); @@ -192,6 +196,14 @@ void OpenLRSimpleDecoder::Decode(string const & outputFilename, int const segmen ++stats.m_routeIsNotCalculated; continue; } + + if (positiveOffsetM + negativeOffsetM + kOffsetToleranceM >= expectedLength) + { + LOG(LINFO, ("Too tight positive and negative offsets, setting them to zero.")); + positiveOffsetM = 0; + negativeOffsetM = 0; + ++stats.m_tightOffsets; + } } auto & path = paths[j]; @@ -224,10 +236,11 @@ void OpenLRSimpleDecoder::Decode(string const & outputFilename, int const segmen for (auto const & s : stats) allStats.Add(s); - LOG(LINFO, ("Parsed segments:", allStats.m_total, - "Routes failed:", allStats.m_routeIsNotCalculated, - "Short routes:", allStats.m_shortRoutes, - "Ambiguous routes:", allStats.m_moreThanOneCandidate, - "Path is not reconstructed:", allStats.m_zeroCanditates)); + LOG(LINFO, ("Parsed segments:", allStats.m_total)); + LOG(LINFO, ("Routes failed:", allStats.m_routeIsNotCalculated)); + LOG(LINFO, ("Tight offsets:", allStats.m_tightOffsets)); + LOG(LINFO, ("Short routes:", allStats.m_shortRoutes)); + LOG(LINFO, ("Ambiguous routes:", allStats.m_moreThanOneCandidate)); + LOG(LINFO, ("Path is not reconstructed:", allStats.m_zeroCanditates)); } } // namespace openlr diff --git a/openlr/router.cpp b/openlr/router.cpp index 746cdf2869..48ac41e73c 100644 --- a/openlr/router.cpp +++ b/openlr/router.cpp @@ -42,7 +42,7 @@ class Score final { public: // A weight for total length of true fake edges. - static const int kTrueFakeCoeff = 3; + static const int kTrueFakeCoeff = 10; // A weight for total length of fake edges that are parts of some // real edges. @@ -578,11 +578,12 @@ template double Router::GetCoverage(m2::PointD const & u, m2::PointD const & v, It b, It e) { double const kEps = 1e-5; + double const kLengthThresholdM = 1; m2::PointD const uv = v - u; double const sqlen = u.SquareLength(v); - if (sqlen < kEps) + if (MercatorBounds::DistanceOnEarth(u, v) < kLengthThresholdM) return 0; std::vector> covs; @@ -709,7 +710,7 @@ bool Router::ReconstructPath(std::vector & edges, vector & if (score > frontEdgeScore) { frontEdgeScore = score; - frontEdge = edge; + frontEdge = edge.GetReverseEdge(); } }); }); @@ -738,10 +739,10 @@ bool Router::ReconstructPath(std::vector & edges, vector & path.push_back(e.m_raw); } - if (frontEdgeScore >= kFakeCoverageThreshold) + if (frontEdgeScore >= kFakeCoverageThreshold && !path.empty() && path.front() != frontEdge) path.insert(path.begin(), frontEdge); - if (backEdgeScore >= kFakeCoverageThreshold) + if (backEdgeScore >= kFakeCoverageThreshold && !path.empty() && path.back() != backEdge) path.insert(path.end(), backEdge); if (path.empty()) @@ -753,9 +754,11 @@ bool Router::ReconstructPath(std::vector & edges, vector & return !path.empty(); } -void Router::FindSingleEdgeApproximation(std::vector const & edges, std::vector & path) +void Router::FindSingleEdgeApproximation(std::vector const & edges, + std::vector & path) { - double const kThreshold = 0.95; + double const kThreshold = 0.8; + double const kCoverageThreshold = 0.5; CHECK(all_of(edges.begin(), edges.end(), mem_fn(&Edge::IsFake)), ()); @@ -793,7 +796,7 @@ void Router::FindSingleEdgeApproximation(std::vector const & edges, std::v ForEachNonFakeClosestEdge(v, m_points[stage].m_lfrcnp, checkEdge); } - if (bestCoverage >= expectedLength * kThreshold) + if (bestCoverage >= expectedLength * kCoverageThreshold) path = {bestEdge}; } } // namespace openlr diff --git a/routing/road_graph.hpp b/routing/road_graph.hpp index e2bccc2812..4924e22bf2 100644 --- a/routing/road_graph.hpp +++ b/routing/road_graph.hpp @@ -75,6 +75,7 @@ public: bool SameRoadSegmentAndDirection(Edge const & r) const; bool operator==(Edge const & r) const; + bool operator!=(Edge const & r) const { return !(*this == r); } bool operator<(Edge const & r) const; private: