diff --git a/openlr/graph.cpp b/openlr/graph.cpp index 5bfacb254f..6b76b6e418 100644 --- a/openlr/graph.cpp +++ b/openlr/graph.cpp @@ -81,9 +81,4 @@ void Graph::GetFeatureTypes(FeatureID const & featureId, feature::TypesHolder & { m_graph.GetFeatureTypes(featureId, types); } - -std::string Graph::GetName(FeatureID const & featureId) const -{ - return m_graph.GetName(featureId); -} } // namespace openlr diff --git a/openlr/graph.hpp b/openlr/graph.hpp index af226e0e94..483ead2921 100644 --- a/openlr/graph.hpp +++ b/openlr/graph.hpp @@ -51,7 +51,6 @@ public: void ResetFakes() { m_graph.ResetFakes(); } void GetFeatureTypes(FeatureID const & featureId, feature::TypesHolder & types) const; - std::string GetName(FeatureID const & featureId) const; private: routing::FeaturesRoadGraph m_graph; diff --git a/openlr/openlr_decoder.cpp b/openlr/openlr_decoder.cpp index a521f0eba6..151b89bcbf 100644 --- a/openlr/openlr_decoder.cpp +++ b/openlr/openlr_decoder.cpp @@ -556,6 +556,7 @@ void OpenLRDecoder::Decode(vector const & segments, } }; + base::Timer timer; vector stats(numThreads); vector workers; for (size_t i = 1; i < numThreads; ++i) @@ -570,5 +571,6 @@ void OpenLRDecoder::Decode(vector const & segments, allStats.Add(s); allStats.Report(); + LOG(LINFO, ("Matching tool:", timer.ElapsedSeconds(), "seconds.")); } } // namespace openlr diff --git a/openlr/score_paths_connector.cpp b/openlr/score_paths_connector.cpp index 33bcdec7e7..42943c4ba7 100644 --- a/openlr/score_paths_connector.cpp +++ b/openlr/score_paths_connector.cpp @@ -22,6 +22,72 @@ namespace openlr { namespace { +class Uniformity +{ +public: + struct Field + { + bool m_field = false; + bool m_isTheSame = true; + }; + + explicit Uniformity(Graph const & graph) : m_graph(graph) {} + + void NextEdge(Graph::Edge const & edge) + { + CHECK(!edge.IsFake(), ()); + + feature::TypesHolder types; + m_graph.GetFeatureTypes(edge.GetFeatureId(), types); + + if (m_minHwClass == ftypes::HighwayClass::Undefined) + { + m_minHwClass = ftypes::GetHighwayClass(types); + m_maxHwClass = m_minHwClass; + m_oneWay.m_field = ftypes::IsOneWayChecker::Instance()(types); + m_roundabout.m_field = ftypes::IsRoundAboutChecker::Instance()(types); + m_link.m_field = ftypes::IsLinkChecker::Instance()(types); + } + else + { + ftypes::HighwayClass const hwClass = ftypes::GetHighwayClass(types); + m_minHwClass = static_cast( + min(static_cast(m_minHwClass), static_cast(hwClass))); + m_maxHwClass = static_cast( + max(static_cast(m_maxHwClass), static_cast(hwClass))); + + if (m_oneWay.m_isTheSame && m_oneWay.m_field != ftypes::IsOneWayChecker::Instance()(types)) + m_oneWay.m_isTheSame = false; + if (m_roundabout.m_isTheSame && m_roundabout.m_field != ftypes::IsRoundAboutChecker::Instance()(types)) + m_roundabout.m_isTheSame = false; + if (m_link.m_isTheSame && m_link.m_field != ftypes::IsLinkChecker::Instance()(types)) + m_link.m_isTheSame = false; + } + } + + uint8_t GetHighwayClassDiff() const + { + CHECK_NOT_EQUAL(m_minHwClass, ftypes::HighwayClass::Undefined, ()); + CHECK_GREATER_OR_EQUAL(m_maxHwClass, m_minHwClass, ()); + + uint8_t const hwClassDiff = static_cast(m_maxHwClass) - static_cast(m_minHwClass); + return hwClassDiff; + } + + bool IsOneWayTheSame() const { return m_oneWay.m_isTheSame; } + bool IsRoundaboutTheSame() const { return m_roundabout.m_isTheSame; } + bool IsLinkTheSame() const { return m_link.m_isTheSame; } + +private: + Graph const & m_graph; + + ftypes::HighwayClass m_minHwClass = ftypes::HighwayClass::Undefined; + ftypes::HighwayClass m_maxHwClass = ftypes::HighwayClass::Undefined; + Field m_oneWay; + Field m_roundabout; + Field m_link; +}; + /// \returns true if |path| may be used as a candidate. In that case |lenScore| is filled /// with score of this candidate based on length. The closer length of the |path| to /// |distanceToNextPoint| the more score. @@ -180,8 +246,8 @@ bool ScorePathsConnector::FindShortestPath(Graph::Edge const & from, Graph::Edge if (u == to) { for (auto e = u; e != from; e = links[e]) - path.push_back(e); - path.push_back(from); + path.emplace_back(e); + path.emplace_back(from); reverse(begin(path), end(path)); return true; } @@ -215,7 +281,6 @@ bool ScorePathsConnector::ConnectAdjacentCandidateLines(Graph::EdgeVector const FunctionalRoadClass lowestFrcToNextPoint, double distanceToNextPoint, Graph::EdgeVector & resultPath) - { CHECK(!to.empty(), ()); @@ -228,7 +293,7 @@ bool ScorePathsConnector::ConnectAdjacentCandidateLines(Graph::EdgeVector const return true; } - CHECK(from.back() != to.front(), ()); + CHECK_NOT_EQUAL(from, to, ()); Graph::EdgeVector shortestPath; auto const found = @@ -248,57 +313,11 @@ bool ScorePathsConnector::ConnectAdjacentCandidateLines(Graph::EdgeVector const Score ScorePathsConnector::GetScoreForUniformity(Graph::EdgeVector const & path) { - ftypes::HighwayClass minHwClass = ftypes::HighwayClass::Undefined; - ftypes::HighwayClass maxHwClass = ftypes::HighwayClass::Undefined; - bool oneWay = false; - bool oneWayIsTheSame = true; - bool roundabout = false; - bool roundaboutIsTheSame = true; - bool link = false; - bool linkIsTheSame = true; - string name; - bool nameIsTheSame = true; - - for (auto const & p : path) - { - CHECK(!p.IsFake(), ()); - - feature::TypesHolder types; - m_graph.GetFeatureTypes(p.GetFeatureId(), types); - - string name; - if (minHwClass == ftypes::HighwayClass::Undefined) - { - minHwClass = ftypes::GetHighwayClass(types); - maxHwClass = minHwClass; - oneWay = ftypes::IsOneWayChecker::Instance()(types); - roundabout = ftypes::IsRoundAboutChecker::Instance()(types); - link = ftypes::IsLinkChecker::Instance()(types); - name = m_graph.GetName(p.GetFeatureId()); - } - else - { - ftypes::HighwayClass const hwClass = ftypes::GetHighwayClass(types); - minHwClass = static_cast( - min(static_cast(minHwClass), static_cast(hwClass))); - maxHwClass = static_cast( - max(static_cast(maxHwClass), static_cast(hwClass))); - - if (oneWayIsTheSame && oneWay != ftypes::IsOneWayChecker::Instance()(types)) - oneWayIsTheSame = false; - if (roundaboutIsTheSame && roundabout != ftypes::IsRoundAboutChecker::Instance()(types)) - roundaboutIsTheSame = false; - if (linkIsTheSame && link != ftypes::IsLinkChecker::Instance()(types)) - linkIsTheSame = false; - if (nameIsTheSame && name != m_graph.GetName(p.GetFeatureId())) - nameIsTheSame = false; - } - } - CHECK_NOT_EQUAL(minHwClass, ftypes::HighwayClass::Undefined, ()); - - uint8_t const hwClassDiff = static_cast(maxHwClass) - static_cast(minHwClass); - CHECK_GREATER_OR_EQUAL(hwClassDiff, 0, ()); + Uniformity uniformity(m_graph); + for (auto const & edge : path) + uniformity.NextEdge(edge); + auto const hwClassDiff = uniformity.GetHighwayClassDiff(); Score constexpr kScoreForTheSameHwClass = 40; Score constexpr kScoreForNeighboringHwClasses = 15; Score const hwClassScore = hwClassDiff == 0 @@ -308,11 +327,9 @@ Score ScorePathsConnector::GetScoreForUniformity(Graph::EdgeVector const & path) Score constexpr kScoreForOneWayOnly = 17; Score constexpr kScoreForRoundaboutOnly = 18; Score constexpr kScoreForLinkOnly = 10; - Score constexpr kScoreForTheSameName = 10; - Score const theSameTypeScore = (oneWayIsTheSame ? kScoreForOneWayOnly : 0) + - (roundaboutIsTheSame ? kScoreForRoundaboutOnly : 0) + - (linkIsTheSame ? kScoreForLinkOnly : 0) + - (nameIsTheSame && !name.empty() ? kScoreForTheSameName : 0); + Score const theSameTypeScore = (uniformity.IsOneWayTheSame() ? kScoreForOneWayOnly : 0) + + (uniformity.IsRoundaboutTheSame() ? kScoreForRoundaboutOnly : 0) + + (uniformity.IsLinkTheSame() ? kScoreForLinkOnly : 0); return hwClassScore + theSameTypeScore; } diff --git a/openlr/score_types.hpp b/openlr/score_types.hpp index 9652fa9590..041f34e576 100644 --- a/openlr/score_types.hpp +++ b/openlr/score_types.hpp @@ -41,7 +41,7 @@ struct ScoreEdge { ScoreEdge(Score score, Edge const & edge) : m_score(score), m_edge(edge) {} - Score m_score = 0; + Score m_score; Edge m_edge; }; @@ -51,7 +51,7 @@ struct ScorePath { ScorePath(Score score, EdgeVector && path) : m_score(score), m_path(move(path)) {} - Score m_score = 0; + Score m_score; EdgeVector m_path; }; diff --git a/routing/features_road_graph.cpp b/routing/features_road_graph.cpp index 5ad4286c15..4a02bc8a56 100644 --- a/routing/features_road_graph.cpp +++ b/routing/features_road_graph.cpp @@ -206,19 +206,6 @@ void FeaturesRoadGraph::GetFeatureTypes(FeatureID const & featureId, feature::Ty types = feature::TypesHolder(*ft); } -string FeaturesRoadGraph::GetName(FeatureID const & featureId) const -{ - FeaturesLoaderGuard loader(m_dataSource, featureId.m_mwmId); - auto ft = loader.GetFeatureByIndex(featureId.m_index); - if (!ft) - return string(); - - ASSERT_EQUAL(ft->GetFeatureType(), feature::GEOM_LINE, ()); - string name; - ft->GetReadableName(name); - return name; -} - void FeaturesRoadGraph::GetJunctionTypes(Junction const & junction, feature::TypesHolder & types) const { types = feature::TypesHolder(); diff --git a/routing/features_road_graph.hpp b/routing/features_road_graph.hpp index eeca2758e8..84297e0919 100644 --- a/routing/features_road_graph.hpp +++ b/routing/features_road_graph.hpp @@ -79,7 +79,6 @@ public: void FindClosestEdges(m2::PointD const & point, uint32_t count, std::vector> & vicinities) const override; void GetFeatureTypes(FeatureID const & featureId, feature::TypesHolder & types) const override; - std::string GetName(FeatureID const & featureId) const override; void GetJunctionTypes(Junction const & junction, feature::TypesHolder & types) const override; IRoadGraph::Mode GetMode() const override; void ClearState() override; diff --git a/routing/road_graph.hpp b/routing/road_graph.hpp index fdcb73fdcf..ad9b9d64c3 100644 --- a/routing/road_graph.hpp +++ b/routing/road_graph.hpp @@ -299,7 +299,6 @@ public: /// @return Types for the specified feature virtual void GetFeatureTypes(FeatureID const & featureId, feature::TypesHolder & types) const = 0; - virtual std::string GetName(FeatureID const & featureId) const = 0; /// @return Types for the specified edge virtual void GetEdgeTypes(Edge const & edge, feature::TypesHolder & types) const override;