[map][search] Show more icons for search results.

This commit is contained in:
tatiana-yan 2018-11-14 19:32:49 +03:00 committed by mpimenov
parent 7ce4d3ece7
commit 67a4781b8e
4 changed files with 269 additions and 115 deletions

View file

@ -1663,7 +1663,7 @@ void Framework::FillSearchResultsMarks(search::Results::ConstIter begin,
if (r.m_metadata.m_isSponsoredHotel)
{
mark->SetMarkType(SearchMarkType::Booking);
mark->SetBookingType(isFeature && m_localAdsManager.Contains(r.GetFeatureID()) /* hasLocalAds */);
mark->SetRating(r.m_metadata.m_hotelRating);
mark->SetPricing(r.m_metadata.m_hotelPricing);
}
@ -1673,45 +1673,15 @@ void Framework::FillSearchResultsMarks(search::Results::ConstIter begin,
auto const type = r.GetFeatureType();
if (product.m_ugcRating != search::ProductInfo::kInvalidRating)
{
mark->SetMarkType(SearchMarkType::UGC);
mark->SetUGCType();
mark->SetRating(product.m_ugcRating);
}
else
{
auto const cafeType = ftypes::IsEatChecker::Instance().GetType(type);
switch (cafeType)
{
case ftypes::IsEatChecker::Type::Cafe:
mark->SetMarkType(SearchMarkType::Cafe);
break;
case ftypes::IsEatChecker::Type::Bakery:
mark->SetMarkType(SearchMarkType::Bakery);
break;
case ftypes::IsEatChecker::Type::FastFood:
mark->SetMarkType(SearchMarkType::FastFood);
break;
case ftypes::IsEatChecker::Type::Restaurant:
mark->SetMarkType(SearchMarkType::Restaurant);
break;
case ftypes::IsEatChecker::Type::Bar:
mark->SetMarkType(SearchMarkType::Bar);
break;
case ftypes::IsEatChecker::Type::Pub:
case ftypes::IsEatChecker::Type::Biergarten:
mark->SetMarkType(SearchMarkType::Pub);
break;
case ftypes::IsEatChecker::Type::Count:
break;
}
mark->SetFromType(type, m_localAdsManager.Contains(r.GetFeatureID()));
}
}
if (isFeature && m_localAdsManager.Contains(r.GetFeatureID()))
{
mark->SetMarkType(r.m_metadata.m_isSponsoredHotel ? SearchMarkType::LocalAdsBooking
: SearchMarkType::LocalAds);
}
if (fn)
fn(*mark);
}

View file

@ -7,42 +7,98 @@
#include "platform/platform.hpp"
#include "base/stl_helpers.hpp"
#include <algorithm>
#include <array>
#include <limits>
namespace
{
std::vector<std::string> const kSymbols =
enum class SearchMarkType
{
"search-result", // Default.
"coloredmark-default-l", // Booking.
"search-adv", // Local Ads.
"searchbookingadv-default-l", // Local Ads + Booking.
"coloredmark-default-l", // UGC.
"search-result-cafe", // Cafe.
"search-result-bakery", // Bakery.
"search-result-bar", // Bar.
"search-result-pub", // Pub.
"search-result-restaurant", // Restaurant.
"search-result-fastfood", // FastFood.
Default = 0,
Booking,
UGC,
Cafe,
Bakery,
Bar,
Pub,
Restaurant,
FastFood,
Casino,
Cinema,
Marketplace,
Nightclub,
Playground,
ShopAlcohol,
ShopButcher,
ShopClothes,
ShopConfectionery,
ShopConvenience,
ShopCosmetics,
ShopDepartmentStore,
ShopGift,
ShopGreengrocer,
ShopJewelry,
ShopMall,
ShopSeafood,
ShopShoes,
ShopSports,
ShopSupermarket,
ShopToys,
ThemePark,
WaterPark,
Zoo,
"non-found-search-result", // NotFound.
NotFound, // Service value used in developer tools.
Count
};
std::vector<std::string> const kPreparingSymbols =
{
"search-result", // Default.
"coloredmark-inactive", // Booking.
"search-adv", // Local Ads.
"searchbookingadv-default-l", // Local Ads + Booking.
"coloredmark-inactive", // UGC.
"search-result-cafe", // Cafe.
"search-result-bakery", // Bakery.
"search-result-bar", // Bar.
"search-result-pub", // Pub.
"search-result-restaurant", // Restaurant.
"search-result-fastfood", // FastFood.
static_assert(static_cast<uint32_t>(SearchMarkType::Count) <= std::numeric_limits<uint8_t>::max(),
"Change SearchMarkPoint::m_type type.");
"non-found-search-result", // NotFound.
SearchMarkType SMT(uint8_t type)
{
return static_cast<SearchMarkType>(type);
}
std::array<std::string, static_cast<size_t>(SearchMarkType::Count)> const kSymbols = {
"search-result", // Default.
"coloredmark-default-l", // Booking.
"coloredmark-default-l", // UGC.
"search-result-cafe", // Cafe.
"search-result-bakery", // Bakery.
"search-result-bar", // Bar.
"search-result-pub", // Pub.
"search-result-restaurant", // Restaurant.
"search-result-fastfood", // FastFood.
"search-result-casino", // Casino.
"search-result-cinema", // Cinema.
"search-result-marketplace", // Marketplace.
"search-result-nightclub", // Nightclub.
"search-result-playground", // Playground.
"search-result-shop-alcohol", // ShopAlcohol.
"search-result-shop-butcher", // ShopButcher.
"search-result-shop-clothes", // ShopClothes.
"search-result-shop-confectionery", // ShopConfectionery.
"search-result-shop-convenience", // ShopConvenience.
"search-result-shop-cosmetics", // ShopCosmetics.
"search-result-shop-department_store", // ShopDepartmentStore.
"search-result-shop-gift", // ShopGift.
"search-result-shop-greengrocer", // ShopGreengrocer.
"search-result-shop-jewelry", // ShopJewelry.
"search-result-shop-mall", // ShopMall.
"search-result-shop-seafood", // ShopSeafood.
"search-result-shop-shoes", // ShopShoes.
"search-result-shop-sports", // ShopSports.
"search-result-shop-supermarket", // ShopSupermarket.
"search-result-shop-toys", // ShopToys.
"search-result-theme-park", // ThemePark.
"search-result-water-park", // WaterPark.
"search-result-zoo", // Zoo.
"non-found-search-result", // NotFound.
};
std::string const kSaleBadgeName = "searchbooking-sale-1";
@ -81,13 +137,131 @@ bool NeedShowBookingBadge(float rating, int pricing)
return metric >= kMetricThreshold;
}
std::string GetBookingSmallIcon(SearchMarkType type)
std::string GetBookingSmallIcon(SearchMarkType type, bool hasLocalAds)
{
if (type == SearchMarkType::Booking)
return "coloredmark-default-s";
if (type == SearchMarkType::LocalAdsBooking)
return "search-adv";
return {};
if (type != SearchMarkType::Booking)
return {};
return hasLocalAds ? "search-adv" : "coloredmark-default-s";
}
std::string GetSymbol(SearchMarkType searchMarkType, bool hasLocalAds)
{
auto const index = static_cast<size_t>(searchMarkType);
ASSERT_LESS(index, kSymbols.size(), ());
if (!hasLocalAds)
return kSymbols[index];
if (searchMarkType == SearchMarkType::Booking)
return "searchbookingadv-default-l";
return "local_ads-" + kSymbols[index];
}
bool HasLocalAdsVariant(SearchMarkType searchMarkType)
{
if (searchMarkType == SearchMarkType::UGC || searchMarkType == SearchMarkType::NotFound)
return false;
return true;
}
std::string GetPreparingSymbol(SearchMarkType searchMarkType, bool hasLocalAds)
{
if (!hasLocalAds &&
(searchMarkType == SearchMarkType::Booking || searchMarkType == SearchMarkType::UGC))
{
return "coloredmark-inactive";
}
return GetSymbol(searchMarkType, hasLocalAds);
}
m2::PointD GetSize(SearchMarkType searchMarkType, bool hasLocalAds, ScreenBase const & modelView)
{
if (!SearchMarks::HaveSizes())
return {};
auto const pixelSize =
SearchMarks::GetSize(GetSymbol(searchMarkType, hasLocalAds)).get_value_or({});
double const pixelToMercator = modelView.GetScale();
return {pixelToMercator * pixelSize.x, pixelToMercator * pixelSize.y};
}
class SearchMarkTypeChecker
{
public:
static SearchMarkTypeChecker & Instance()
{
static SearchMarkTypeChecker checker;
return checker;
}
SearchMarkType GetSearchMarkType(uint32_t type) const
{
auto const it = std::lower_bound(m_searchMarkTypes.cbegin(), m_searchMarkTypes.cend(),
Type(type, SearchMarkType::Count), base::LessBy(&Type::first));
if (it == m_searchMarkTypes.cend() || it->first != type)
return SearchMarkType::Default;
return it->second;
}
private:
using Type = std::pair<uint32_t, SearchMarkType>;
SearchMarkTypeChecker()
{
auto const & c = classif();
std::vector<std::pair<std::vector<std::string>, SearchMarkType>> const table = {
{{"amenity", "cafe"}, SearchMarkType::Cafe},
{{"shop", "bakery"}, SearchMarkType::Bakery},
{{"amenity", "bar"}, SearchMarkType::Bar},
{{"amenity", "pub"}, SearchMarkType::Pub},
{{"amenity", "biergarten"}, SearchMarkType::Pub},
{{"amenity", "restaurant"}, SearchMarkType::Restaurant},
{{"amenity", "fast_food"}, SearchMarkType::FastFood},
{{"amenity", "casino"}, SearchMarkType::Casino},
{{"amenity", "cinema"}, SearchMarkType::Cinema},
{{"amenity", "marketplace"}, SearchMarkType::Marketplace},
{{"amenity", "nightclub"}, SearchMarkType::Nightclub},
{{"leisure", "playground"}, SearchMarkType::Playground},
{{"shop", "alcohol"}, SearchMarkType::ShopAlcohol},
{{"shop", "beverages"}, SearchMarkType::ShopAlcohol},
{{"shop", "wine"}, SearchMarkType::ShopAlcohol},
{{"shop", "butcher"}, SearchMarkType::ShopButcher},
{{"shop", "clothes"}, SearchMarkType::ShopClothes},
{{"shop", "confectionery"}, SearchMarkType::ShopConfectionery},
{{"shop", "convenience"}, SearchMarkType::ShopConvenience},
{{"shop", "variety_store"}, SearchMarkType::ShopConvenience},
{{"shop", "cosmetics"}, SearchMarkType::ShopCosmetics},
{{"shop", "department_store"}, SearchMarkType::ShopDepartmentStore},
{{"shop", "gift"}, SearchMarkType::ShopGift},
{{"shop", "greengrocer"}, SearchMarkType::ShopGreengrocer},
{{"shop", "jewelry"}, SearchMarkType::ShopJewelry},
{{"shop", "mall"}, SearchMarkType::ShopMall},
{{"shop", "seafood"}, SearchMarkType::ShopSeafood},
{{"shop", "shoes"}, SearchMarkType::ShopShoes},
{{"shop", "sports"}, SearchMarkType::ShopSports},
{{"shop", "supermarket"}, SearchMarkType::ShopSupermarket},
{{"shop", "toys"}, SearchMarkType::ShopToys},
{{"tourism", "theme_park"}, SearchMarkType::ThemePark},
{{"leisure", "water_park"}, SearchMarkType::WaterPark},
{{"tourism", "zoo"}, SearchMarkType::Zoo}
};
m_searchMarkTypes.reserve(table.size());
for (auto const & p : table)
m_searchMarkTypes.push_back({c.GetTypeByPath(p.first), p.second});
std::sort(m_searchMarkTypes.begin(), m_searchMarkTypes.end(), base::LessBy(&Type::first));
}
std::vector<Type> m_searchMarkTypes;
};
SearchMarkType GetSearchMarkType(uint32_t type)
{
auto const & checker = SearchMarkTypeChecker::Instance();
return checker.GetSearchMarkType(type);
}
} // namespace
@ -103,25 +277,26 @@ SearchMarkPoint::SearchMarkPoint(m2::PointD const & ptOrg)
drape_ptr<df::UserPointMark::SymbolNameZoomInfo> SearchMarkPoint::GetSymbolNames() const
{
std::string name;
if (m_type >= SearchMarkType::Count)
if (m_type >= static_cast<uint8_t>(SearchMarkType::Count))
{
ASSERT(false, ("Unknown search mark symbol."));
name = kSymbols[static_cast<size_t>(SearchMarkType::Default)];
name = GetSymbol(SearchMarkType::Default, false /* hasLocalAds */);
}
else if (m_isPreparing)
{
name = kPreparingSymbols[static_cast<size_t>(m_type)];
name = GetPreparingSymbol(SMT(m_type), m_hasLocalAds);
}
else
{
name = kSymbols[static_cast<size_t>(m_type)];
name = GetSymbol(SMT(m_type), m_hasLocalAds);
}
auto symbol = make_unique_dp<SymbolNameZoomInfo>();
if (IsMarkWithRating())
{
symbol->insert(std::make_pair(1 /* zoomLevel */, m_rating < kRatingThreshold ?
GetBookingSmallIcon(m_type) : name));
symbol->insert(std::make_pair(
1 /* zoomLevel */,
m_rating < kRatingThreshold ? GetBookingSmallIcon(SMT(m_type), m_hasLocalAds) : name));
symbol->insert(std::make_pair(17 /* zoomLevel */, name));
}
else
@ -157,7 +332,7 @@ drape_ptr<df::UserPointMark::SymbolOffsets> SearchMarkPoint::GetSymbolOffsets()
if (badgeName.empty() || !SearchMarks::GetSize(badgeName))
return nullptr;
auto const name = kSymbols[static_cast<size_t>(SearchMarkType::Booking)];
auto const name = GetSymbol(SearchMarkType::Booking, false /* hasLocalAds */);
auto const iconSz = SearchMarks::GetSize(name).get_value_or({});
SymbolOffsets offsets(scales::UPPER_STYLE_SCALE);
@ -175,7 +350,7 @@ df::ColorConstant SearchMarkPoint::GetColorConstant() const
if (!IsMarkWithRating())
return {};
if (m_type == SearchMarkType::LocalAdsBooking)
if (SMT(m_type) == SearchMarkType::Booking && m_hasLocalAds)
return "RatingLocalAds";
if (HasNoRating(m_rating))
@ -223,9 +398,28 @@ void SearchMarkPoint::SetMatchedName(std::string const & name)
SetAttributeValue(m_matchedName, name);
}
void SearchMarkPoint::SetMarkType(SearchMarkType type)
void SearchMarkPoint::SetFromType(uint32_t type, bool hasLocalAds)
{
SetAttributeValue(m_type, type);
SetAttributeValue(m_hasLocalAds, hasLocalAds);
SetAttributeValue(m_type, static_cast<uint8_t>(GetSearchMarkType(type)));
}
void SearchMarkPoint::SetBookingType(bool hasLocalAds)
{
SetAttributeValue(m_hasLocalAds, hasLocalAds);
SetAttributeValue(m_type, static_cast<uint8_t>(SearchMarkType::Booking));
}
void SearchMarkPoint::SetUGCType()
{
SetAttributeValue(m_hasLocalAds, false);
SetAttributeValue(m_type, static_cast<uint8_t>(SearchMarkType::UGC));
}
void SearchMarkPoint::SetNotFoundType()
{
SetAttributeValue(m_hasLocalAds, false);
SetAttributeValue(m_type, static_cast<uint8_t>(SearchMarkType::NotFound));
}
void SearchMarkPoint::SetPreparing(bool isPreparing)
@ -251,13 +445,12 @@ void SearchMarkPoint::SetSale(bool hasSale)
bool SearchMarkPoint::IsBookingSpecialMark() const
{
return (m_type == SearchMarkType::Booking || m_type == SearchMarkType::LocalAdsBooking) &&
!m_isPreparing;
return (SMT(m_type) == SearchMarkType::Booking) && !m_isPreparing;
}
bool SearchMarkPoint::IsUGCMark() const
{
return m_type == SearchMarkType::UGC;
return SMT(m_type) == SearchMarkType::UGC;
}
bool SearchMarkPoint::IsMarkWithRating() const
@ -279,7 +472,16 @@ void SearchMarks::SetDrapeEngine(ref_ptr<df::DrapeEngine> engine)
return;
std::vector<std::string> symbols;
symbols.insert(symbols.end(), kSymbols.begin(), kSymbols.end());
auto const searchMarkTypesCount = static_cast<size_t>(SearchMarkType::Count);
symbols.reserve(searchMarkTypesCount * 2);
for (size_t t = 0; t < searchMarkTypesCount; ++t)
{
auto const searchMarkType = SMT(t);
symbols.push_back(GetSymbol(searchMarkType, false /* hasLocalAds */));
if (HasLocalAdsVariant(searchMarkType))
symbols.push_back(GetSymbol(searchMarkType, true /* hasLocalAds */));
}
for (int pricing = 1; pricing <= 3; pricing++)
symbols.push_back(GetBookingBadgeName(pricing));
symbols.push_back(kSaleBadgeName);
@ -304,25 +506,18 @@ double SearchMarks::GetMaxDimension(ScreenBase const & modelView) const
double dimension = 0.0;
for (size_t i = 0; i < static_cast<size_t>(SearchMarkType::Count); ++i)
{
m2::PointD const markSize = GetSize(static_cast<SearchMarkType>(i), modelView);
auto const searchMarkType = SMT(i);
m2::PointD markSize = ::GetSize(searchMarkType, false /* hasLocalAds */, modelView);
dimension = std::max(dimension, std::max(markSize.x, markSize.y));
if (HasLocalAdsVariant(searchMarkType))
{
markSize = ::GetSize(searchMarkType, true /* hasLocalAds */, modelView);
dimension = std::max(dimension, std::max(markSize.x, markSize.y));
}
}
return dimension;
}
// static
m2::PointD SearchMarks::GetSize(SearchMarkType searchMarkType, ScreenBase const & modelView)
{
if (m_searchMarksSizes.empty())
return {};
auto const index = static_cast<size_t>(searchMarkType);
ASSERT_LESS(index, kSymbols.size(), ());
auto const pixelSize = GetSize(kSymbols[index]).get_value_or({});
double const pixelToMercator = modelView.GetScale();
return {pixelToMercator * pixelSize.x, pixelToMercator * pixelSize.y};
}
// static
boost::optional<m2::PointD> SearchMarks::GetSize(std::string const & symbolName)
{

View file

@ -11,28 +11,12 @@
#include <boost/optional.hpp>
#include <cstdint>
#include <functional>
#include <map>
#include <string>
#include <vector>
enum class SearchMarkType
{
Default = 0,
Booking,
LocalAds,
LocalAdsBooking,
UGC,
Cafe,
Bakery,
Bar,
Pub,
Restaurant,
FastFood,
NotFound, // Service value used in developer tools.
Count
};
class BookmarkManager;
class SearchMarkPoint : public UserMark
@ -55,7 +39,11 @@ public:
std::string const & GetMatchedName() const { return m_matchedName; }
void SetMatchedName(std::string const & name);
void SetMarkType(SearchMarkType type);
void SetFromType(uint32_t type, bool hasLocalAds);
void SetBookingType(bool hasLocalAds);
void SetUGCType();
void SetNotFoundType();
void SetPreparing(bool isPreparing);
void SetRating(float rating);
void SetPricing(int pricing);
@ -75,7 +63,8 @@ protected:
bool IsUGCMark() const;
bool IsMarkWithRating() const;
SearchMarkType m_type = SearchMarkType::Default;
uint8_t m_type = 0;
bool m_hasLocalAds = false;
FeatureID m_featureID;
// Used to pass exact search result matched string into a place page.
std::string m_matchedName;
@ -102,7 +91,7 @@ public:
// NOTE: Vector of features must be sorted.
void SetSales(std::vector<FeatureID> const & features, bool hasSale);
static m2::PointD GetSize(SearchMarkType searchMarkType, ScreenBase const & modelView);
static bool HaveSizes() { return !m_searchMarksSizes.empty(); };
static boost::optional<m2::PointD> GetSize(std::string const & symbolName);
private:

View file

@ -280,7 +280,7 @@ void SampleView::ShowNonFoundResultsMarks(std::vector<search::Sample::Result> co
continue;
auto * mark = editSession.CreateUserMark<SearchMarkPoint>(result.m_pos);
mark->SetMarkType(SearchMarkType::NotFound);
mark->SetNotFoundType();
}
}