From 428a1ed653ae4c7a1213623f8edd8ae734ef8f83 Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Fri, 9 Sep 2022 09:37:30 +0300 Subject: [PATCH] [search] Added Shop POI type for ranking. Signed-off-by: Viktor Govako --- .../test_with_custom_mwms.cpp | 11 ++-- indexer/ftypes_matcher.cpp | 8 ++- indexer/ftypes_matcher.hpp | 10 ++- search/ranking_info.cpp | 5 ++ search/ranking_info.hpp | 2 + .../search_quality_tests/real_mwm_tests.cpp | 63 ++++++++++--------- 6 files changed, 64 insertions(+), 35 deletions(-) diff --git a/generator/generator_tests_support/test_with_custom_mwms.cpp b/generator/generator_tests_support/test_with_custom_mwms.cpp index cfea1dbbc0..1c0385829c 100644 --- a/generator/generator_tests_support/test_with_custom_mwms.cpp +++ b/generator/generator_tests_support/test_with_custom_mwms.cpp @@ -62,10 +62,13 @@ void TestWithCustomMwms::RegisterLocalMapsInViewport(m2::RectD const & viewport) continue; auto const res = m_dataSource.RegisterMap(file); - CHECK_EQUAL(res.second, MwmSet::RegResult::Success, ()); - - auto const & info = res.first.GetInfo(); - OnMwmBuilt(*info); + if (res.second == MwmSet::RegResult::Success) + { + auto const & info = res.first.GetInfo(); + OnMwmBuilt(*info); + } + else + CHECK_EQUAL(res.second, MwmSet::RegResult::VersionAlreadyExists, ()); } } diff --git a/indexer/ftypes_matcher.cpp b/indexer/ftypes_matcher.cpp index c5b6e9ec41..916a86d38e 100644 --- a/indexer/ftypes_matcher.cpp +++ b/indexer/ftypes_matcher.cpp @@ -696,12 +696,16 @@ IsWifiChecker::IsWifiChecker() m_types.push_back(classif().GetTypeByPath({"internet_access", "wlan"})); } +IsShopChecker::IsShopChecker() : BaseChecker(1) +{ + m_types.push_back(classif().GetTypeByPath({"shop"})); +} + IsEatChecker::IsEatChecker() { // The order should be the same as in "enum class Type" declaration. - /// @todo Should we include shops like: confectionery and pastry, because bakery is already present? + /// @todo amenity=ice_cream if we already have biergarten :) base::StringIL const types[] = {{"amenity", "cafe"}, - {"shop", "bakery"}, {"amenity", "fast_food"}, {"amenity", "restaurant"}, {"amenity", "bar"}, diff --git a/indexer/ftypes_matcher.hpp b/indexer/ftypes_matcher.hpp index 5a30f24c5e..30b3e1ec9f 100644 --- a/indexer/ftypes_matcher.hpp +++ b/indexer/ftypes_matcher.hpp @@ -426,13 +426,21 @@ public: uint32_t GetType() const { return m_types[0]; } }; +class IsShopChecker : public BaseChecker +{ +public: + DECLARE_CHECKER_INSTANCE(IsShopChecker); + +private: + IsShopChecker(); +}; + class IsEatChecker : public BaseChecker { public: // enum class Type // { // Cafe = 0, -// Bakery, // FastFood, // Restaurant, // Bar, diff --git a/search/ranking_info.cpp b/search/ranking_info.cpp index 7d11da4d68..f1d560c795 100644 --- a/search/ranking_info.cpp +++ b/search/ranking_info.cpp @@ -72,6 +72,7 @@ double constexpr kPoiType[] = { 0.01 /* TransportLocal */, 0.01 /* Eat */, 0.01 /* Hotel */, + 0.01 /* Shop */, 0.01 /* Attraction */, -0.01 /* Service */, 0 /* General */ @@ -341,6 +342,9 @@ PoiType GetPoiType(feature::TypesHolder const & th) return PoiType::Eat; if (IsHotelChecker::Instance()(th)) return PoiType::Hotel; + if (IsShopChecker::Instance()(th)) + return PoiType::Shop; + if (IsRailwayStationChecker::Instance()(th) || IsSubwayStationChecker::Instance()(th) || IsAirportChecker::Instance()(th)) @@ -374,6 +378,7 @@ string DebugPrint(PoiType type) case PoiType::TransportLocal: return "TransportLocal"; case PoiType::Eat: return "Eat"; case PoiType::Hotel: return "Hotel"; + case PoiType::Shop: return "Shop"; case PoiType::Attraction: return "Attraction"; case PoiType::Service: return "Service"; case PoiType::General: return "General"; diff --git a/search/ranking_info.hpp b/search/ranking_info.hpp index 06925fb38f..5bfdf6e4ec 100644 --- a/search/ranking_info.hpp +++ b/search/ranking_info.hpp @@ -24,6 +24,8 @@ enum class PoiType : uint8_t Eat, // Hotels. Hotel, + // Shops. + Shop, // Attractions. Attraction, // Service types: power lines and substations, barrier-fence, etc. 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 006865cf6a..a1652d1f8e 100644 --- a/search/search_quality/search_quality_tests/real_mwm_tests.cpp +++ b/search/search_quality/search_quality_tests/real_mwm_tests.cpp @@ -15,6 +15,8 @@ public: // Default top POIs count to check types or distances. static size_t constexpr kTopPoiResultsCount = 5; + static size_t constexpr kPopularPoiResultsCount = 10; + // Feature's centers table is created with low coordinates precision for better compression, // so distance-to-pivot is not precise and real meters distance may differ. static double constexpr kDistanceEpsilon = 5; @@ -72,15 +74,19 @@ public: return res; } + static bool EqualClassifType(uint32_t checkType, uint32_t ethalonType) + { + ftype::TruncValue(checkType, ftype::GetLevel(ethalonType)); + return checkType == ethalonType; + } + static void EqualClassifType(Range const & results, std::vector const & types) { for (auto const & r : results) { auto const it = std::find_if(types.begin(), types.end(), [type = r.GetFeatureType()](uint32_t inType) { - uint32_t t = type; - ftype::TruncValue(t, ftype::GetLevel(inType)); - return t == inType; + return EqualClassifType(type, inType); }); TEST(it != types.end(), (r)); @@ -125,12 +131,10 @@ UNIT_CLASS_TEST(MwmTestsFixture, Berlin_Rewe) auto request = MakeRequest("rewe"); auto const & results = request->Results(); - TEST_GREATER(results.size(), kTopPoiResultsCount, ()); + TEST_GREATER(results.size(), kPopularPoiResultsCount, ()); - TEST_EQUAL(results[0].GetFeatureType(), classif().GetTypeByPath({"amenity", "fast_food"}), ()); - - Range const range(results, 1); - EqualClassifType(range, GetClassifTypes({{"shop"}})); + Range const range(results, 0, kPopularPoiResultsCount); + EqualClassifType(range, GetClassifTypes({{"shop"}, {"amenity", "fast_food"}})); double const dist = SortedByDistance(range, center); TEST_LESS(dist, 1000, ()); } @@ -144,12 +148,12 @@ UNIT_CLASS_TEST(MwmTestsFixture, Madrid_Carrefour) auto request = MakeRequest("carrefour"); auto const & results = request->Results(); - TEST_GREATER(results.size(), 10, ()); + TEST_GREATER(results.size(), kPopularPoiResultsCount, ()); /// @todo 'Carrefour' city in Haiti :) TEST_EQUAL(results[0].GetFeatureType(), classif().GetTypeByPath({"place", "city", "capital", "3"}), ()); - Range const range(results, 1, 10); + Range const range(results, 1, kPopularPoiResultsCount); EqualClassifType(range, GetClassifTypes({{"shop"}})); double const dist = SortedByDistance(range, center); TEST_LESS(dist, 500, ()); @@ -203,7 +207,7 @@ UNIT_CLASS_TEST(MwmTestsFixture, NY_Subway) // + Some noname cities LIKE("Subway", 1 error) in the World. auto request = MakeRequest("subway"); auto const & results = request->Results(); - TEST_GREATER(results.size(), kTopPoiResultsCount, ()); + TEST_GREATER(results.size(), kPopularPoiResultsCount, ()); Range const range(results, 0, 3); EqualClassifType(range, GetClassifTypes({{"amenity", "fast_food"}})); @@ -211,22 +215,25 @@ UNIT_CLASS_TEST(MwmTestsFixture, NY_Subway) TEST_LESS(dist, 1000, ()); } +// https://github.com/organicmaps/organicmaps/issues/3249 // https://github.com/organicmaps/organicmaps/issues/1997 UNIT_CLASS_TEST(MwmTestsFixture, London_Asda) { // London - ms::LatLon const center(51.50295, 0.00325); - SetViewportAndLoadMaps(center); + ms::LatLon const arrPivots[] = { {51.50295, 0.00325}, {51.47890,0.01062} }; + for (auto const & center : arrPivots) + { + SetViewportAndLoadMaps(center); - auto request = MakeRequest("asda"); - auto const & results = request->Results(); - TEST_GREATER(results.size(), kTopPoiResultsCount, ()); + auto request = MakeRequest("asda"); + auto const & results = request->Results(); + TEST_GREATER(results.size(), kTopPoiResultsCount, ()); - /// @todo 3 only because cafe is better than fuel, despite fuel is closer. - Range const range(results, 0, 3); - EqualClassifType(range, GetClassifTypes({{"shop"}, {"amenity"}})); - double const dist = SortedByDistance(range, center); - TEST_LESS(dist, 2000, ()); + Range const range(results); + EqualClassifType(range, GetClassifTypes({{"shop"}, {"amenity"}})); + double const dist = SortedByDistance(range, center); + TEST_LESS(dist, 2000, ()); + } } // https://github.com/organicmaps/organicmaps/issues/3103 @@ -238,7 +245,7 @@ UNIT_CLASS_TEST(MwmTestsFixture, Lyon_Aldi) auto request = MakeRequest("aldi"); auto const & results = request->Results(); - TEST_GREATER(results.size(), kTopPoiResultsCount, ()); + TEST_GREATER(results.size(), kPopularPoiResultsCount, ()); Range const range(results); EqualClassifType(range, GetClassifTypes({{"shop", "supermarket"}})); @@ -255,11 +262,9 @@ UNIT_CLASS_TEST(MwmTestsFixture, NY_BarnesNoble) auto request = MakeRequest("barne's & noble"); auto const & results = request->Results(); - TEST_GREATER(results.size(), 10, ()); + TEST_GREATER(results.size(), kPopularPoiResultsCount, ()); - TEST_EQUAL(results[0].GetFeatureType(), classif().GetTypeByPath({"amenity", "cafe"}), ()); - - Range const range(results, 1); + Range const range(results); EqualClassifType(range, GetClassifTypes({{"shop", "books"}})); double const dist = SortedByDistance(range, center); TEST_LESS(dist, 2000, ()); @@ -270,14 +275,16 @@ UNIT_CLASS_TEST(MwmTestsFixture, Hamburg_Park) { // Hamburg ms::LatLon const center(53.5503410, 10.0006540); + // Bremen-Munster should also be downloaded. SetViewportAndLoadMaps(center); auto request = MakeRequest("Heide-Park"); auto const & results = request->Results(); TEST_GREATER(results.size(), kTopPoiResultsCount, ()); - Range const range(results, 0, 3); - EqualClassifType(range, GetClassifTypes({{"tourism"}, {"amenity", "fast_food"}, {"highway", "bus_stop"}})); + Range const range(results); + EqualClassifType(range, GetClassifTypes( + {{"tourism"}, {"shop", "gift"}, {"amenity", "fast_food"}, {"highway", "bus_stop"}})); NameStartsWith(range, {"Heide Park", "Heide-Park"}); double const dist = SortedByDistance(range, center); TEST_LESS(dist, 100000, ());