diff --git a/android/jni/com/mapswithme/maps/SearchEngine.cpp b/android/jni/com/mapswithme/maps/SearchEngine.cpp index 60e6f2673c..f4e3c2300d 100644 --- a/android/jni/com/mapswithme/maps/SearchEngine.cpp +++ b/android/jni/com/mapswithme/maps/SearchEngine.cpp @@ -345,6 +345,7 @@ jobject ToJavaResult(Result & result, search::ProductInfo const & productInfo, b jni::TScopedLocalRef cuisine(env, jni::ToJavaString(env, result.GetCuisine())); jni::TScopedLocalRef brand(env, jni::ToJavaString(env, result.GetBrand())); jni::TScopedLocalRef airportIata(env, jni::ToJavaString(env, result.GetAirportIata())); + jni::TScopedLocalRef roadShields(env, jni::ToJavaString(env, result.GetRoadShields())); jni::TScopedLocalRef pricing(env, jni::ToJavaString(env, result.GetHotelApproximatePricing())); @@ -356,7 +357,7 @@ jobject ToJavaResult(Result & result, search::ProductInfo const & productInfo, b jni::TScopedLocalRef desc(env, env->NewObject(g_descriptionClass, g_descriptionConstructor, featureId.get(), featureType.get(), address.get(), dist.get(), cuisine.get(), brand.get(), airportIata.get(), - pricing.get(), rating, + roadShields.get(), pricing.get(), rating, result.GetStarsCount(), static_cast(result.IsOpenNow()), static_cast(popularityHasHigherPriority))); @@ -655,7 +656,7 @@ extern "C" "(Lcom/mapswithme/maps/bookmarks/data/FeatureId;" "Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;" "Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;" - "Ljava/lang/String;FIIZ)V"); + "Ljava/lang/String;Ljava/lang/String;FIIZ)V"); g_popularityClass = jni::GetGlobalClassRef(env, "com/mapswithme/maps/search/Popularity"); g_popularityConstructor = jni::GetConstructorID(env, g_popularityClass, "(I)V"); diff --git a/android/src/com/mapswithme/maps/search/SearchAdapter.java b/android/src/com/mapswithme/maps/search/SearchAdapter.java index 904a626581..dc1b242b67 100644 --- a/android/src/com/mapswithme/maps/search/SearchAdapter.java +++ b/android/src/com/mapswithme/maps/search/SearchAdapter.java @@ -234,6 +234,10 @@ class SearchAdapter extends RecyclerView.Adapter GetLocalizedCuisines(TypesHolder const & types) } return localized; } + +vector GetRoadShieldsNames(string const & rawRoadNumber) +{ + vector names; + for (auto const & shield : ftypes::GetRoadShields(rawRoadNumber)) + names.push_back(shield.m_name); + + return names; +} } // namespace feature diff --git a/indexer/feature_utils.hpp b/indexer/feature_utils.hpp index b99ac0516d..eec689ac20 100644 --- a/indexer/feature_utils.hpp +++ b/indexer/feature_utils.hpp @@ -83,4 +83,7 @@ namespace feature // Returns vector of cuisines names localized by platform. std::vector GetLocalizedCuisines(TypesHolder const & types); + + // Returns names of feature road shields. Applicable for road features. + std::vector GetRoadShieldsNames(std::string const & rawRoadNumber); } // namespace feature diff --git a/indexer/map_object.cpp b/indexer/map_object.cpp index 26cfba6a02..eab8e0fae1 100644 --- a/indexer/map_object.cpp +++ b/indexer/map_object.cpp @@ -75,6 +75,7 @@ void MapObject::SetFromFeatureType(FeatureType & ft) m_types = feature::TypesHolder(ft); m_metadata = ft.GetMetadata(); m_houseNumber = ft.GetHouseNumber(); + m_roadNumber = ft.GetRoadNumber(); m_postcode = ft.GetPostcode(); m_featureID = ft.GetID(); m_geomType = ft.GetGeomType(); @@ -178,6 +179,16 @@ vector MapObject::GetLocalizedCuisines() const string MapObject::FormatCuisines() const { return strings::JoinStrings(GetLocalizedCuisines(), " • "); } +vector MapObject::GetRoadShields() const +{ + return feature::GetRoadShieldsNames(m_roadNumber); +} + +string MapObject::FormatRoadShields() const +{ + return strings::JoinStrings(GetRoadShields(), " • "); +} + string MapObject::GetOpeningHours() const { return m_metadata.Get(feature::Metadata::FMD_OPEN_HOURS); diff --git a/indexer/map_object.hpp b/indexer/map_object.hpp index f606f7d57b..6c4ba974b8 100644 --- a/indexer/map_object.hpp +++ b/indexer/map_object.hpp @@ -85,6 +85,8 @@ public: std::vector GetLocalizedCuisines() const; /// @returns translated and formatted cuisines. std::string FormatCuisines() const; + std::vector GetRoadShields() const; + std::string FormatRoadShields() const; std::string GetOpeningHours() const; std::string GetOperator() const; int GetStars() const; @@ -120,6 +122,7 @@ protected: StringUtf8Multilang m_name; std::string m_houseNumber; + std::string m_roadNumber; std::string m_postcode; feature::TypesHolder m_types; feature::Metadata m_metadata; diff --git a/indexer/road_shields_parser.cpp b/indexer/road_shields_parser.cpp index 9bb8504791..06ef82b62a 100644 --- a/indexer/road_shields_parser.cpp +++ b/indexer/road_shields_parser.cpp @@ -581,6 +581,15 @@ std::set GetRoadShields(FeatureType & f) return SimpleRoadShieldParser(roadNumber, SimpleRoadShieldParser::ShieldTypes()).GetRoadShields(); } +std::set GetRoadShields(std::string const & rawRoadNumber) +{ + if (rawRoadNumber.empty()) + return {}; + + return SimpleRoadShieldParser(rawRoadNumber, SimpleRoadShieldParser::ShieldTypes()) + .GetRoadShields(); +} + std::string DebugPrint(RoadShieldType shieldType) { using ftypes::RoadShieldType; diff --git a/indexer/road_shields_parser.hpp b/indexer/road_shields_parser.hpp index 0d406e2a7c..14b83d8079 100644 --- a/indexer/road_shields_parser.hpp +++ b/indexer/road_shields_parser.hpp @@ -52,7 +52,12 @@ struct RoadShield } }; +// Use specific country road shield styles based on mwm feature belongs to. std::set GetRoadShields(FeatureType & f); + +// Simple parsing without specific country styles. +std::set GetRoadShields(std::string const & rawRoadNumber); + std::string DebugPrint(RoadShieldType shieldType); std::string DebugPrint(RoadShield const & shield); } // namespace ftypes diff --git a/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.mm b/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.mm index 4fcf80bcad..7f7a6d327f 100644 --- a/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.mm +++ b/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.mm @@ -74,6 +74,7 @@ bool PopularityHasHigherPriority(bool hasPosition, double distanceInMeters) NSUInteger const starsCount = result.GetStarsCount(); NSString * cuisine = @(result.GetCuisine().c_str()).capitalizedString; NSString * airportIata = @(result.GetAirportIata().c_str()); + NSString * roadShields = @(result.GetRoadShields().c_str()); NSString * brand = @""; if (!result.GetBrand().empty()) brand = @(platform::GetLocalizedBrandName(result.GetBrand()).c_str()); @@ -82,6 +83,8 @@ bool PopularityHasHigherPriority(bool hasPosition, double distanceInMeters) [self setInfoRating:starsCount]; else if (airportIata.length > 0) [self setInfoText:airportIata]; + else if (roadShields.length > 0) + [self setInfoText:roadShields]; else if (brand.length > 0 && cuisine.length > 0) [self setInfoText:[NSString stringWithFormat:@"%@ • %@", brand, cuisine]]; else if (brand.length > 0) diff --git a/map/place_page_info.cpp b/map/place_page_info.cpp index 81caeed7f5..4f7ef8ca1f 100644 --- a/map/place_page_info.cpp +++ b/map/place_page_info.cpp @@ -118,6 +118,11 @@ std::string Info::FormatSubtitle(bool withType) const if (!iata.empty()) subtitle.push_back(iata); + // Road numbers/ids. + std::string const roadShields = FormatRoadShields(); + if (!roadShields.empty()) + subtitle.push_back(roadShields); + // Stars. std::string const stars = FormatStars(); if (!stars.empty()) diff --git a/search/intermediate_result.cpp b/search/intermediate_result.cpp index 032b39f959..09513fdef6 100644 --- a/search/intermediate_result.cpp +++ b/search/intermediate_result.cpp @@ -281,6 +281,9 @@ void FillDetails(FeatureType & ft, Result::Details & details) auto const cuisines = feature::GetLocalizedCuisines(feature::TypesHolder(ft)); details.m_cuisine = strings::JoinStrings(cuisines, " • "); + auto const roadShields = feature::GetRoadShieldsNames(ft.GetRoadNumber()); + details.m_roadShields = strings::JoinStrings(roadShields, " • "); + details.m_isInitialized = true; } diff --git a/search/result.hpp b/search/result.hpp index a43d66058e..ba29fcfbae 100644 --- a/search/result.hpp +++ b/search/result.hpp @@ -53,6 +53,9 @@ public: // Valid only if not empty, used for brand name. std::string m_brand; + // Valid only if not empty, used for roads. + std::string m_roadShields; + // Following fields are used for hotels only. int m_hotelPricing = 0; std::string m_hotelApproximatePricing; @@ -93,6 +96,7 @@ public: std::string const & GetCuisine() const { return m_details.m_cuisine; } std::string const & GetAirportIata() const { return m_details.m_airportIata; } std::string const & GetBrand() const { return m_details.m_brand; } + std::string const & GetRoadShields() const { return m_details.m_roadShields; } float GetHotelRating() const { return m_details.m_hotelRating; } std::string const & GetHotelApproximatePricing() const {