[search] Using cities' popularity rank.

Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
This commit is contained in:
Viktor Govako 2024-01-27 12:38:13 -03:00
parent 94f2d8a47c
commit 2741099054
4 changed files with 50 additions and 28 deletions

View file

@ -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<int>(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<int>(rank * 1.7), 0, 0xFF);
return rank * 1.7;
// Fallthrough like "STATE" for cities without info.
} [[fallthrough]];

View file

@ -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()];

View file

@ -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;

View file

@ -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<ms::LatLon> arrCenters;
arrCenters.resize(count);
std::set<std::string> const notCapital = { "San Francisco", "Las Vegas", "Zurich" };
std::vector<ms::LatLon> 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, ());
}