diff --git a/search/ranker.cpp b/search/ranker.cpp index a2ec62a523..f901e5d93c 100644 --- a/search/ranker.cpp +++ b/search/ranker.cpp @@ -625,7 +625,7 @@ private: info.m_falseCats = categoriesInfo.IsFalseCategories(); } - uint8_t NormalizeRank(uint8_t rank, Model::Type type, m2::PointD const & center, + uint16_t NormalizeRank(uint16_t rank, Model::Type type, m2::PointD const & center, string const & country, bool isCapital, bool isRelaxed) { // Do not prioritize objects with population < 800. Same as RankToPopulation(rank) < 800, but faster. @@ -642,7 +642,7 @@ private: { /// @todo Tried to reduce more (1.5), but important Famous_Cities_Rank test fails. if (isCapital || m_ranker.m_params.m_viewport.IsPointInside(center)) - return base::Clamp(static_cast(rank * 1.8), 0, 0xFF); + return rank * 1.8; storage::CountryInfo info; if (country.empty()) @@ -650,7 +650,7 @@ private: else m_infoGetter.GetRegionInfo(country, info); if (info.IsNotEmpty() && info.m_name == m_ranker.m_params.m_pivotRegion) - return base::Clamp(static_cast(rank * 1.7), 0, 0xFF); + return rank * 1.7; // Fallthrough like "STATE" for cities without info. } [[fallthrough]]; diff --git a/search/ranking_info.cpp b/search/ranking_info.cpp index 00b1bdb446..7573d1d0bb 100644 --- a/search/ranking_info.cpp +++ b/search/ranking_info.cpp @@ -34,9 +34,9 @@ double constexpr AbsPenaltyPerKm() return - kDistanceToPivot * 1000.0 / RankingInfo::kMaxDistMeters; } -// This constant is very important and checked in Famous_Cities_Rank test. +// These constants are very important and checked in Famous_Cities_Rank test. double constexpr kRank = 0.23; -double constexpr kPopularity = 1.0000000; +double constexpr kPopularity = 0.42; double constexpr kErrorsMade = -0.4; double constexpr kMatchedFraction = 0.1876736; @@ -61,7 +61,7 @@ double constexpr kType[] = { 0.007, // Building, to compensate max(kStreetType), see Arbat_Address test. 0, // Street 0, // Suburb - -0.02, // Unclassified + -0.025, // Unclassified 0, // Village 0.01, // City 0.0233254, // State @@ -334,10 +334,13 @@ double RankingInfo::GetLinearModelRank() const { result += kDistanceToPivot * distanceToPivot; result += kRank * rank; - result += kPopularity * popularity; if (m_falseCats) result += kFalseCats; + /// @todo Make also for POIs? + if (Model::IsLocalityType(m_type)) + result += kPopularity * popularity; + ASSERT(m_type < Model::TYPE_COUNT, ()); result += kType[GetTypeScore()]; diff --git a/search/ranking_info.hpp b/search/ranking_info.hpp index 494f517abe..a8f73d52fe 100644 --- a/search/ranking_info.hpp +++ b/search/ranking_info.hpp @@ -106,8 +106,8 @@ struct RankingInfo : public StoredRankingInfo // Number of misprints. ErrorsMade m_errorsMade; - // Rank of the feature. - uint8_t m_rank = 0; + // Rank of the feature. Store uint16_t because of possible 'normalization'. + uint16_t m_rank = 0; // Popularity rank of the feature. uint8_t m_popularity = 0; diff --git a/search/search_quality/search_quality_tests/real_mwm_tests.cpp b/search/search_quality/search_quality_tests/real_mwm_tests.cpp index 18042e3830..a5c75c243e 100644 --- a/search/search_quality/search_quality_tests/real_mwm_tests.cpp +++ b/search/search_quality/search_quality_tests/real_mwm_tests.cpp @@ -687,14 +687,14 @@ UNIT_CLASS_TEST(MwmTestsFixture, Famous_Cities_Rank) { auto const & cl = classif(); uint32_t const capitalType = cl.GetTypeByPath({"place", "city", "capital"}); + uint32_t const cityType = cl.GetTypeByPath({"place", "city"}); std::string arrCities[] = { "Buenos Aires", "Rio de Janeiro", "New York", - /// @todo After popularity. - //"San Francisco", - //"Las Vegas", + "San Francisco", // not a capital + "Las Vegas", // not a capital "Los Angeles", "Toronto", "Lisboa", @@ -702,7 +702,7 @@ UNIT_CLASS_TEST(MwmTestsFixture, Famous_Cities_Rank) "Barcelona", "London", "Paris", - //"Zurich", + "Zurich", // not a capital "Rome", "Milan", "Venezia", @@ -722,11 +722,14 @@ UNIT_CLASS_TEST(MwmTestsFixture, Famous_Cities_Rank) }; size_t const count = std::size(arrCities); - std::vector arrCenters; - arrCenters.resize(count); + std::set const notCapital = { "San Francisco", "Las Vegas", "Zurich" }; + + std::vector arrCenters(count); // Buenos Aires like starting point :) arrCenters[0] = {-34.60649, -58.43540}; + size_t errorsNum = 0; + // For DEBUG. // bool isGoGo = false; for (size_t i = 0; i < count; ++i) @@ -736,10 +739,7 @@ UNIT_CLASS_TEST(MwmTestsFixture, Famous_Cities_Rank) // if (i > 0 && !isGoGo) // continue; - /// @todo Temporary, USA has a lot of similar close cities (Berlin). - size_t topNumber = 3; - if (arrCities[i] == "New York") - topNumber = 5; + size_t constexpr kTopNumber = 3; LOG(LINFO, ("=== Processing:", arrCities[i])); SetViewportAndLoadMaps(arrCenters[i]); @@ -751,20 +751,38 @@ UNIT_CLASS_TEST(MwmTestsFixture, Famous_Cities_Rank) TEST(!results.empty(), (arrCities[i], arrCities[j])); // Check that needed city is in top. - auto const iEnd = results.begin() + std::min(topNumber, results.size()); - auto const it = std::find_if(results.begin(), iEnd, [capitalType](search::Result const & r) + auto const iEnd = results.begin() + std::min(kTopNumber, results.size()); + auto const it = std::find_if(results.begin(), iEnd, [&](search::Result const & r) { + // Should make this complex check to ensure that we got a needed city. uint32_t type = r.GetFeatureType(); - ftype::TruncValue(type, 3); - return (type == capitalType); + if (notCapital.count(arrCities[j]) > 0) + { + ftype::TruncValue(type, 2); + return (type == cityType); + } + else + { + ftype::TruncValue(type, 3); + return (type == capitalType); + } }); - TEST(it != iEnd, (arrCities[i], arrCities[j])); - // Fill centers table while processing first city. - if (i == 0 && i != j) - arrCenters[j] = mercator::ToLatLon(results[0].GetFeatureCenter()); + if (it == iEnd) + { + LOG(LWARNING, ("Not matched:", arrCities[i], ":", arrCities[j])); + ++errorsNum; + } + else + { + // Fill centers table while processing first city. + if (!arrCenters[j].IsValid()) + arrCenters[j] = mercator::ToLatLon(it->GetFeatureCenter()); + } } } + + TEST_LESS(errorsNum, 10, ()); } UNIT_CLASS_TEST(MwmTestsFixture, Conscription_HN) @@ -1083,8 +1101,9 @@ UNIT_CLASS_TEST(MwmTestsFixture, Pois_Rank) size_t constexpr kResultsCount = 20; TEST_GREATER(results.size(), kResultsCount, ()); + // result[0] - 'Rimini' city in Italy // First 2 results - nearest supermarkets. - Range range(results, 0, 2); + Range range(results, 1, 3); EqualClassifType(range, GetClassifTypes({{"shop", "supermarket"}})); TEST_LESS(SortedByDistance(range, center).second, 1500, ()); }