diff --git a/generator/generator_tests_support/test_feature.cpp b/generator/generator_tests_support/test_feature.cpp index 6ed96a717b..999802e1d8 100644 --- a/generator/generator_tests_support/test_feature.cpp +++ b/generator/generator_tests_support/test_feature.cpp @@ -66,6 +66,12 @@ TestFeature::TestFeature(m2::PointD const & center, string const & name, string Init(); } +TestFeature::TestFeature(m2::PointD const & center, StringUtf8Multilang const & name) + : m_id(GenUniqueId()), m_center(center), m_type(Type::Point), m_names(name) +{ + Init(); +} + TestFeature::TestFeature(vector const & boundary, string const & name, string const & lang) : m_id(GenUniqueId()), m_boundary(boundary), m_type(Type::Area) @@ -182,6 +188,11 @@ TestCity::TestCity(m2::PointD const & center, string const & name, string const { } +TestCity::TestCity(m2::PointD const & center, StringUtf8Multilang const & name, uint8_t rank) + : TestFeature(center, name), m_rank(rank) +{ +} + TestCity::TestCity(vector const & boundary, string const & name, string const & lang, uint8_t rank) : TestFeature(boundary, name, lang), m_rank(rank) diff --git a/generator/generator_tests_support/test_feature.hpp b/generator/generator_tests_support/test_feature.hpp index 57900b9172..12e4837a5c 100644 --- a/generator/generator_tests_support/test_feature.hpp +++ b/generator/generator_tests_support/test_feature.hpp @@ -66,6 +66,7 @@ protected: TestFeature(std::string const & name, std::string const & lang); TestFeature(StringUtf8Multilang const & name); TestFeature(m2::PointD const & center, std::string const & name, std::string const & lang); + TestFeature(m2::PointD const & center, StringUtf8Multilang const & name); TestFeature(std::vector const & boundary, std::string const & name, std::string const & lang); @@ -106,6 +107,7 @@ class TestCity : public TestFeature public: TestCity(m2::PointD const & center, std::string const & name, std::string const & lang, uint8_t rank); + TestCity(m2::PointD const & center, StringUtf8Multilang const & name, uint8_t rank); TestCity(std::vector const & boundary, std::string const & name, std::string const & lang, uint8_t rank); diff --git a/search/ranker.cpp b/search/ranker.cpp index 86a7e66daa..e2d473f406 100644 --- a/search/ranker.cpp +++ b/search/ranker.cpp @@ -157,22 +157,22 @@ pair GetNameScores(FeatureType & ft, Geocoder::Params const return make_pair(bestScores, matchedLength); } -pair MatchTokenRange(FeatureType & ft, Geocoder::Params const & params, - TokenRange const & range, Model::Type type) +void MatchTokenRange(FeatureType & ft, Geocoder::Params const & params, TokenRange const & range, + Model::Type type, ErrorsMade & errorsMade, size_t & matchedLength, + bool & isAltOrOldName) { auto const scores = GetNameScores(ft, params, range, type); - auto errorsMade = scores.first.m_errorsMade; - auto matchedLength = scores.second; + errorsMade = scores.first.m_errorsMade; + isAltOrOldName = scores.first.m_isAltOrOldName; + matchedLength = scores.second; if (errorsMade.IsValid()) - return make_pair(errorsMade, matchedLength); + return; for (auto const token : range) { errorsMade += ErrorsMade{GetMaxErrorsForToken(params.GetToken(token).GetOriginal())}; matchedLength += params.GetToken(token).GetOriginal().size(); } - - return make_pair(errorsMade, matchedLength); } void RemoveDuplicatingLinear(vector & results) @@ -382,6 +382,7 @@ class RankerResultMaker auto nameScore = scores.first.m_nameScore; auto errorsMade = scores.first.m_errorsMade; + bool isAltOrOldName = scores.first.m_isAltOrOldName; auto matchedLength = scores.second; if (info.m_type != Model::TYPE_STREET && @@ -397,6 +398,8 @@ class RankerResultMaker nameScore = min(nameScore, streetScores.first.m_nameScore); errorsMade += streetScores.first.m_errorsMade; + if (streetScores.first.m_isAltOrOldName) + isAltOrOldName = true; matchedLength += streetScores.second; } } @@ -410,9 +413,15 @@ class RankerResultMaker { auto const type = Model::TYPE_SUBURB; auto const & range = preInfo.m_tokenRanges[type]; - auto const matchingResult = MatchTokenRange(*suburb, m_params, range, type); - errorsMade += matchingResult.first; - matchedLength += matchingResult.second; + ErrorsMade suburbErrors; + size_t suburbMatchedLength = 0; + bool suburbNameIsAltNameOrOldName = false; + MatchTokenRange(*suburb, m_params, range, type, suburbErrors, suburbMatchedLength, + suburbNameIsAltNameOrOldName); + errorsMade += suburbErrors; + matchedLength += suburbMatchedLength; + if (suburbNameIsAltNameOrOldName) + isAltOrOldName = true; } } @@ -423,9 +432,15 @@ class RankerResultMaker { auto const type = Model::TYPE_CITY; auto const & range = preInfo.m_tokenRanges[type]; - auto const matchingResult = MatchTokenRange(*city, m_params, range, type); - errorsMade += matchingResult.first; - matchedLength += matchingResult.second; + ErrorsMade cityErrors; + size_t cityMatchedLength = 0; + bool cityNameIsAltNameOrOldName = false; + MatchTokenRange(*city, m_params, range, type, cityErrors, cityMatchedLength, + cityNameIsAltNameOrOldName); + errorsMade += cityErrors; + matchedLength += cityMatchedLength; + if (cityNameIsAltNameOrOldName) + isAltOrOldName = true; } } @@ -435,6 +450,7 @@ class RankerResultMaker info.m_nameScore = nameScore; info.m_errorsMade = errorsMade; + info.m_isAltOrOldName = isAltOrOldName; info.m_matchedFraction = totalLength == 0 ? 1.0 : static_cast(matchedLength) / static_cast(totalLength); diff --git a/search/ranking_info.cpp b/search/ranking_info.cpp index f2a35cf817..e45d7376c6 100644 --- a/search/ranking_info.cpp +++ b/search/ranking_info.cpp @@ -188,6 +188,7 @@ string DebugPrint(RankingInfo const & info) << "]"; os << ", m_nameScore:" << DebugPrint(info.m_nameScore); os << ", m_errorsMade:" << DebugPrint(info.m_errorsMade); + os << ", m_isAltOrOldName: " << info.m_isAltOrOldName; os << ", m_numTokens:" << info.m_numTokens; os << ", m_matchedFraction:" << info.m_matchedFraction; os << ", m_type:" << DebugPrint(info.m_type); diff --git a/search/ranking_info.hpp b/search/ranking_info.hpp index 6d4a922b13..e0ff5e6622 100644 --- a/search/ranking_info.hpp +++ b/search/ranking_info.hpp @@ -68,6 +68,9 @@ struct RankingInfo // Number of misprints. ErrorsMade m_errorsMade; + // alt_name or old_name is used. + bool m_isAltOrOldName = false; + // Query tokens number. size_t m_numTokens = 0; diff --git a/search/search_integration_tests/processor_test.cpp b/search/search_integration_tests/processor_test.cpp index 87d95b2660..046778c2a9 100644 --- a/search/search_integration_tests/processor_test.cpp +++ b/search/search_integration_tests/processor_test.cpp @@ -2998,5 +2998,85 @@ UNIT_CLASS_TEST(ProcessorTest, AltAndOldName) TEST(ResultsMatch("old", rules), ()); } } + +UNIT_CLASS_TEST(ProcessorTest, TestRankingInfo_IsAltOrOldName) +{ + string const countryName = "Wonderland"; + + StringUtf8Multilang cityName; + cityName.AddString("default", "Санкт-Петербург"); + cityName.AddString("alt_name", "Питер"); + cityName.AddString("old_name", "Ленинград"); + TestCity city(m2::PointD(0.0, 0.0), cityName, 100 /* rank */); + + StringUtf8Multilang streetName; + streetName.AddString("default", "Большой проспект Васильевского Острова"); + streetName.AddString("alt_name", "Большой проспект В. О."); + streetName.AddString("old_name", "проспект Пролетарской Победы"); + TestStreet street( + vector{m2::PointD(0.0, -0.5), m2::PointD(0.0, 0.0), m2::PointD(0.0, 0.5)}, + streetName); + + TestMultilingualPOI poi(m2::PointD(0.0, 0.0), "KFC", + {{"alt_name", "Kentucky Fried Chicken"}, {"old_name", "Ростикс"}}); + + auto worldId = BuildWorld([&](TestMwmBuilder & builder) { builder.Add(city); }); + + auto wonderlandId = BuildCountry(countryName, [&](TestMwmBuilder & builder) { + builder.Add(city); + builder.Add(street); + builder.Add(poi); + }); + + SetViewport(m2::RectD(-1, -1, 1, 1)); + + auto checkIsAltOrOldName = [&](string const & query, bool isAltOrOldName) { + auto request = MakeRequest(query, "ru"); + auto const & results = request->Results(); + + Rules rules{ExactMatch(wonderlandId, poi)}; + bool found = false; + for (auto const & result : results) + { + if (ResultsMatch({result}, rules)) + { + found = true; + TEST_EQUAL(result.GetRankingInfo().m_nameScore, NAME_SCORE_FULL_MATCH, (query, result)); + TEST_EQUAL(result.GetRankingInfo().m_isAltOrOldName, isAltOrOldName, (query, result)); + } + } + TEST(found, (query)); + }; + + checkIsAltOrOldName("Санкт-Петербург Большой проспект Васильевского Острова KFC", false); + checkIsAltOrOldName("Питер Большой проспект Васильевского Острова KFC", true); + checkIsAltOrOldName("Ленинград Большой проспект Васильевского Острова KFC", true); + checkIsAltOrOldName("Санкт-Петербург Большой проспект В. О. KFC", true); + checkIsAltOrOldName("Питер Большой проспект В. О. KFC", true); + checkIsAltOrOldName("Ленинград Большой проспект В. О. KFC", true); + checkIsAltOrOldName("Санкт-Петербург проспект Пролетарской Победы KFC", true); + checkIsAltOrOldName("Питер проспект Пролетарской Победы KFC", true); + checkIsAltOrOldName("Ленинград проспект Пролетарской Победы KFC", true); + checkIsAltOrOldName( + "Санкт-Петербург Большой проспект Васильевского Острова Kentucky Fried Chicken", true); + checkIsAltOrOldName("Питер Большой проспект Васильевского Острова Kentucky Fried Chicken", true); + checkIsAltOrOldName("Ленинград Большой проспект Васильевского Острова Kentucky Fried Chicken", + true); + checkIsAltOrOldName("Санкт-Петербург Большой проспект В. О. Kentucky Fried Chicken", true); + checkIsAltOrOldName("Питер Большой проспект В. О. Kentucky Fried Chicken", true); + checkIsAltOrOldName("Ленинград Большой проспект В. О. Kentucky Fried Chicken", true); + checkIsAltOrOldName("Санкт-Петербург проспект Пролетарской Победы Kentucky Fried Chicken", true); + checkIsAltOrOldName("Питер проспект Пролетарской Победы Kentucky Fried Chicken", true); + checkIsAltOrOldName("Ленинград проспект Пролетарской Победы Kentucky Fried Chicken", true); + checkIsAltOrOldName("Санкт-Петербург Большой проспект Васильевского Острова Ростикс", true); + checkIsAltOrOldName("Питер Большой проспект Васильевского Острова Ростикс", true); + checkIsAltOrOldName("Ленинград Большой проспект Васильевского Острова Ростикс", true); + checkIsAltOrOldName("Санкт-Петербург Большой проспект В. О. Ростикс", true); + checkIsAltOrOldName("Питер Большой проспект В. О. Ростикс", true); + checkIsAltOrOldName("Ленинград Большой проспект В. О. Ростикс", true); + checkIsAltOrOldName("Санкт-Петербург проспект Пролетарской Победы Ростикс", true); + checkIsAltOrOldName("Питер проспект Пролетарской Победы Ростикс", true); + checkIsAltOrOldName("Ленинград проспект Пролетарской Победы Ростикс", true); +} } // namespace } // namespace search