diff --git a/generator/osm2meta.cpp b/generator/osm2meta.cpp index a782c97377..c5a32f4550 100644 --- a/generator/osm2meta.cpp +++ b/generator/osm2meta.cpp @@ -281,7 +281,7 @@ string MetadataTagProcessorImpl::ValidateAndFormat_airport_iata(string const & v string MetadataTagProcessorImpl::ValidateAndFormat_duration(string const & v) const { - if (!ftypes::IsFerryChecker::Instance()(m_params.m_types)) + if (!ftypes::IsWayWithDurationChecker::Instance()(m_params.m_types)) return {}; auto const format = [](double hours) -> string { diff --git a/generator/tag_admixer.hpp b/generator/tag_admixer.hpp index bf1c98962e..bf0c8e94b8 100644 --- a/generator/tag_admixer.hpp +++ b/generator/tag_admixer.hpp @@ -119,6 +119,7 @@ public: return; // Exclude ferry routes. + /// @todo This routine is not used but anyway: what about railway-rail-motor_vehicle or route-shuttle_train? static OsmElement::Tag const kFerryTag = {"route", "ferry"}; auto const & tags = element.Tags(); if (!base::IsExist(tags, kFerryTag)) diff --git a/indexer/ftypes_matcher.cpp b/indexer/ftypes_matcher.cpp index d1a310460e..1eec355d5c 100644 --- a/indexer/ftypes_matcher.cpp +++ b/indexer/ftypes_matcher.cpp @@ -16,6 +16,8 @@ #include #include +namespace ftypes +{ using namespace std; namespace @@ -94,8 +96,6 @@ char const * HighwayClassToString(ftypes::HighwayClass const cls) } } // namespace -namespace ftypes -{ string DebugPrint(HighwayClass const cls) { stringstream out; @@ -289,28 +289,27 @@ IsSquareChecker::IsSquareChecker() IsSuburbChecker::IsSuburbChecker() { Classificator const & c = classif(); - auto const residentialType = c.GetTypeByPath({"landuse", "residential"}); - auto const neighbourhoodType = c.GetTypeByPath({"place", "neighbourhood"}); - auto const suburbType = c.GetTypeByPath({"place", "suburb"}); - m_types.push_back(residentialType); - m_types.push_back(neighbourhoodType); - m_types.push_back(suburbType); - CHECK(m_types[static_cast(SuburbType::Residential)] == residentialType, ()); - CHECK(m_types[static_cast(SuburbType::Neighbourhood)] == neighbourhoodType, ()); - CHECK(m_types[static_cast(SuburbType::Suburb)] == suburbType, ()); + base::StringIL const types[] = {{"landuse", "residential"}, + {"place", "neighbourhood"}, + {"place", "suburb"}}; + for (auto const & e : types) + m_types.push_back(c.GetTypeByPath(e)); + + // `types` order should match next indices. + static_assert(static_cast(SuburbType::Residential) == 0, ""); + static_assert(static_cast(SuburbType::Neighbourhood) == 1, ""); + static_assert(static_cast(SuburbType::Suburb) == 2, ""); } SuburbType IsSuburbChecker::GetType(uint32_t t) const { ftype::TruncValue(t, 2); - for (size_t i = 0; i < m_types.size(); ++i) { if (m_types[i] == t) return static_cast(i); } - - return SuburbType::None; + return SuburbType::Count; } SuburbType IsSuburbChecker::GetType(feature::TypesHolder const & types) const @@ -319,14 +318,10 @@ SuburbType IsSuburbChecker::GetType(feature::TypesHolder const & types) const for (uint32_t t : types) { auto const type = GetType(t); - if (type != SuburbType::None && type < smallestType) + if (type < smallestType) smallestType = type; } - - if (smallestType != SuburbType::Count) - return smallestType; - - return SuburbType::None; + return smallestType; } SuburbType IsSuburbChecker::GetType(FeatureType & f) const @@ -341,28 +336,28 @@ IsWayChecker::IsWayChecker() // data/categories.txt, so, it's worth it to generate or parse it // from that file. Classificator const & c = classif(); - char const * arr[][2] = {{"highway", "living_street"}, - {"highway", "footway"}, - {"highway", "cycleway"}, - {"highway", "motorway"}, - {"highway", "motorway_link"}, - {"highway", "path"}, - {"highway", "pedestrian"}, - {"highway", "primary"}, - {"highway", "primary_link"}, - {"highway", "residential"}, - {"highway", "road"}, - {"highway", "secondary"}, - {"highway", "secondary_link"}, - {"highway", "service"}, - {"highway", "tertiary"}, - {"highway", "tertiary_link"}, - {"highway", "track"}, - {"highway", "trunk"}, - {"highway", "trunk_link"}, - {"highway", "unclassified"}}; - for (auto const & p : arr) - m_types.push_back(c.GetTypeByPath({p[0], p[1]})); + base::StringIL const types[] = { {"highway", "living_street"}, + {"highway", "footway"}, + {"highway", "cycleway"}, + {"highway", "motorway"}, + {"highway", "motorway_link"}, + {"highway", "path"}, + {"highway", "pedestrian"}, + {"highway", "primary"}, + {"highway", "primary_link"}, + {"highway", "residential"}, + {"highway", "road"}, + {"highway", "secondary"}, + {"highway", "secondary_link"}, + {"highway", "service"}, + {"highway", "tertiary"}, + {"highway", "tertiary_link"}, + {"highway", "track"}, + {"highway", "trunk"}, + {"highway", "trunk_link"}, + {"highway", "unclassified"}}; + for (auto const & e : types) + m_types.push_back(c.GetTypeByPath(e)); } IsStreetOrSquareChecker::IsStreetOrSquareChecker() @@ -388,10 +383,8 @@ IsVillageChecker::IsVillageChecker() // data/categories.txt, so, it's worth it to generate or parse it // from that file. Classificator const & c = classif(); - char const * arr[][2] = {{"place", "village"}, {"place", "hamlet"}}; - - for (auto const & p : arr) - m_types.push_back(c.GetTypeByPath({p[0], p[1]})); + m_types.push_back(c.GetTypeByPath({"place", "village"})); + m_types.push_back(c.GetTypeByPath({"place", "hamlet"})); } IsOneWayChecker::IsOneWayChecker() @@ -409,14 +402,14 @@ IsRoundAboutChecker::IsRoundAboutChecker() IsLinkChecker::IsLinkChecker() { Classificator const & c = classif(); - char const * arr[][2] = {{"highway", "motorway_link"}, - {"highway", "trunk_link"}, - {"highway", "primary_link"}, - {"highway", "secondary_link"}, - {"highway", "tertiary_link"}}; + base::StringIL const types[] = {{"highway", "motorway_link"}, + {"highway", "trunk_link"}, + {"highway", "primary_link"}, + {"highway", "secondary_link"}, + {"highway", "tertiary_link"}}; - for (size_t i = 0; i < ARRAY_SIZE(arr); ++i) - m_types.push_back(c.GetTypeByPath(vector(arr[i], arr[i] + 2))); + for (auto const & e : types) + m_types.push_back(c.GetTypeByPath(e)); } IsBuildingChecker::IsBuildingChecker() : BaseChecker(1 /* level */) @@ -502,24 +495,24 @@ AttractionsChecker::AttractionsChecker() : BaseChecker(2 /* level */) {"waterway", "waterfall"}, }; - base::StringIL const additionalAttractionTypes[] = { - {"tourism", "viewpoint"}, - {"tourism", "attraction"}, - }; - Classificator const & c = classif(); - for (auto const & t : primaryAttractionTypes) + for (auto const & e : primaryAttractionTypes) { - auto const type = c.GetTypeByPath(t); + auto const type = c.GetTypeByPath(e); m_types.push_back(type); m_primaryTypes.push_back(type); } sort(m_primaryTypes.begin(), m_primaryTypes.end()); - for (auto const & t : additionalAttractionTypes) + base::StringIL const additionalAttractionTypes[] = { + {"tourism", "viewpoint"}, + {"tourism", "attraction"}, + }; + + for (auto const & e : additionalAttractionTypes) { - auto const type = c.GetTypeByPath(t); + auto const type = c.GetTypeByPath(e); m_types.push_back(type); m_additionalTypes.push_back(type); } @@ -610,14 +603,9 @@ unsigned IsHotelChecker::GetHotelTypesMask(FeatureType & ft) const IsIslandChecker::IsIslandChecker() { - base::StringIL const types[] = { - {"place", "island"}, - {"place", "islet"}, - }; - Classificator const & c = classif(); - for (auto const & t : types) - m_types.push_back(c.GetTypeByPath(t)); + m_types.push_back(c.GetTypeByPath({"place", "island"})); + m_types.push_back(c.GetTypeByPath({"place", "islet"})); } IsLandChecker::IsLandChecker() @@ -689,33 +677,34 @@ IsWifiChecker::IsWifiChecker() IsEatChecker::IsEatChecker() { + // The order should be the same as in "enum class Type" declaration. + base::StringIL const types[] = {{"amenity", "cafe"}, + {"shop", "bakery"}, + {"amenity", "fast_food"}, + {"amenity", "restaurant"}, + {"amenity", "bar"}, + {"amenity", "pub"}, + {"amenity", "biergarten"}}; + Classificator const & c = classif(); - map> const descriptions = {{Type::Cafe, {"amenity", "cafe"}}, - {Type::Bakery, {"shop", "bakery"}}, - {Type::FastFood, {"amenity", "fast_food"}}, - {Type::Restaurant, {"amenity", "restaurant"}}, - {Type::Bar, {"amenity", "bar"}}, - {Type::Pub, {"amenity", "pub"}}, - {Type::Biergarten, {"amenity", "biergarten"}}}; - - for (auto const & desc : descriptions) +// size_t i = 0; + for (auto const & e : types) { - auto const type = c.GetTypeByPath(desc.second); + auto const type = c.GetTypeByPath(e); m_types.push_back(type); - m_sortedTypes[static_cast(desc.first)] = {type, desc.first}; +// m_eat2clType[i++] = type; } } -IsEatChecker::Type IsEatChecker::GetType(uint32_t t) const -{ - for (auto type : m_sortedTypes) - { - if (type.first == t) - return type.second; - } - - return IsEatChecker::Type::Count; -} +//IsEatChecker::Type IsEatChecker::GetType(uint32_t t) const +//{ +// for (size_t i = 0; i < m_eat2clType.size(); ++i) +// { +// if (m_eat2clType[i] == t) +// return static_cast(i); +// } +// return IsEatChecker::Type::Count; +//} IsCuisineChecker::IsCuisineChecker() : BaseChecker(1 /* level */) { @@ -751,10 +740,14 @@ IsMotorwayJunctionChecker::IsMotorwayJunctionChecker() m_types.push_back(c.GetTypeByPath({"highway", "motorway_junction"})); } -IsFerryChecker::IsFerryChecker() +IsWayWithDurationChecker::IsWayWithDurationChecker() : BaseChecker(3 /* level */) { + base::StringIL const types[] = {{"route", "ferry"}, + {"railway", "rail", "motor_vehicle"}, + {"route", "shuttle_train"}}; Classificator const & c = classif(); - m_types.push_back(c.GetTypeByPath({"route", "ferry"})); + for (auto const & e : types) + m_types.push_back(c.GetTypeByPath(e)); } IsLocalityChecker::IsLocalityChecker() @@ -762,7 +755,7 @@ IsLocalityChecker::IsLocalityChecker() Classificator const & c = classif(); // Note! The order should be equal with constants in Type enum (add other villages to the end). - char const * arr[][2] = { + base::StringIL const types[] = { { "place", "country" }, { "place", "state" }, { "place", "city" }, @@ -771,8 +764,8 @@ IsLocalityChecker::IsLocalityChecker() { "place", "hamlet" } }; - for (size_t i = 0; i < ARRAY_SIZE(arr); ++i) - m_types.push_back(c.GetTypeByPath(vector(arr[i], arr[i] + 2))); + for (auto const & e : types) + m_types.push_back(c.GetTypeByPath(e)); } LocalityType IsLocalityChecker::GetType(uint32_t t) const @@ -830,8 +823,8 @@ IsCityTownOrVillageChecker::IsCityTownOrVillageChecker() }; Classificator const & c = classif(); - for (auto const & t : types) - m_types.push_back(c.GetTypeByPath(t)); + for (auto const & e : types) + m_types.push_back(c.GetTypeByPath(e)); } IsEntranceChecker::IsEntranceChecker() : BaseChecker(1 /* level */) diff --git a/indexer/ftypes_matcher.hpp b/indexer/ftypes_matcher.hpp index 7a7717bdeb..a295999b33 100644 --- a/indexer/ftypes_matcher.hpp +++ b/indexer/ftypes_matcher.hpp @@ -183,7 +183,6 @@ public: // Suburb > Neighbourhood > Residential enum class SuburbType { - None = -1, Residential = 0, Neighbourhood, Suburb, @@ -243,6 +242,8 @@ class IsOneWayChecker : public BaseChecker IsOneWayChecker(); public: DECLARE_CHECKER_INSTANCE(IsOneWayChecker); + + uint32_t GetType() const { return m_types[0]; } }; class IsRoundAboutChecker : public BaseChecker @@ -411,27 +412,27 @@ public: class IsEatChecker : public BaseChecker { public: - enum class Type - { - Cafe, - Bakery, - FastFood, - Restaurant, - Bar, - Pub, - Biergarten, +// enum class Type +// { +// Cafe = 0, +// Bakery, +// FastFood, +// Restaurant, +// Bar, +// Pub, +// Biergarten, - Count - }; +// Count +// }; DECLARE_CHECKER_INSTANCE(IsEatChecker); - Type GetType(uint32_t t) const; +// Type GetType(uint32_t t) const; private: IsEatChecker(); - std::array, base::Underlying(Type::Count)> m_sortedTypes; +// std::array m_eat2clType; }; class IsCuisineChecker : public BaseChecker @@ -478,11 +479,14 @@ public: DECLARE_CHECKER_INSTANCE(IsMotorwayJunctionChecker); }; -class IsFerryChecker : public BaseChecker +/// Exotic OSM ways that potentially have "duration" tag. +class IsWayWithDurationChecker : public BaseChecker { - IsFerryChecker(); + IsWayWithDurationChecker(); public: - DECLARE_CHECKER_INSTANCE(IsFerryChecker); + DECLARE_CHECKER_INSTANCE(IsWayWithDurationChecker); + + uint32_t GetMotorVehicleRailway() const { return m_types[1]; } }; /// Type of locality (do not change values and order - they have detalization order) diff --git a/routing/geometry.cpp b/routing/geometry.cpp index f3818c350d..cc9f125ece 100644 --- a/routing/geometry.cpp +++ b/routing/geometry.cpp @@ -35,8 +35,7 @@ double CalcFerryDurationHours(string_view durationHours, double roadLenKm) CHECK(strings::to_double(durationHours, durationH), (durationHours)); // See: https://confluence.mail.ru/download/attachments/249123157/image2019-8-22_16-15-53.png - // Shortly: we drop some points: (x: lengthKm, y: durationH), that are upper or lower these two - // lines. + // Shortly: we drop some points: (x: lengthKm, y: durationH), that are upper or lower these two lines. double constexpr kUpperBoundIntercept = 4.0; double constexpr kUpperBoundSlope = 0.037; if (kUpperBoundIntercept + kUpperBoundSlope * roadLenKm - durationH < 0) diff --git a/routing_common/vehicle_model.cpp b/routing_common/vehicle_model.cpp index 1386861b71..143ad1f82c 100644 --- a/routing_common/vehicle_model.cpp +++ b/routing_common/vehicle_model.cpp @@ -50,8 +50,8 @@ namespace routing VehicleModel::VehicleModel(Classificator const & classif, LimitsInitList const & featureTypeLimits, SurfaceInitList const & featureTypeSurface, HighwayBasedInfo const & info) : m_highwayBasedInfo(info) -, m_onewayType(classif.GetTypeByPath({"hwtag", "oneway"})) -, m_railwayVehicleType(classif.GetTypeByPath({"railway", "rail", "motor_vehicle"})) +, m_onewayType(ftypes::IsOneWayChecker::Instance().GetType()) +, m_railwayVehicleType(ftypes::IsWayWithDurationChecker::Instance().GetMotorVehicleRailway()) { m_roadTypes.Reserve(featureTypeLimits.size()); for (auto const & v : featureTypeLimits) @@ -302,8 +302,7 @@ VehicleModelFactory::VehicleModelFactory( shared_ptr VehicleModelFactory::GetVehicleModel() const { auto const itr = m_models.find(""); - ASSERT(itr != m_models.end(), ("No default vehicle model. VehicleModelFactory was not " - "properly constructed")); + ASSERT(itr != m_models.end(), ()); return itr->second; } diff --git a/search/geocoder.cpp b/search/geocoder.cpp index cef677c8f2..d8d47803e5 100644 --- a/search/geocoder.cpp +++ b/search/geocoder.cpp @@ -1220,26 +1220,28 @@ void Geocoder::GreedilyMatchStreetsWithSuburbs(BaseContext & ctx, vector suburbs; StreetsMatcher::Go(ctx, ctx.m_suburbs, *m_filter, m_params, suburbs); + auto const & suburbChecker = ftypes::IsSuburbChecker::Instance(); for (auto const & suburb : suburbs) { ScopedMarkTokens mark(ctx.m_tokens, BaseContext::TOKEN_TYPE_SUBURB, suburb.m_tokenRange); - suburb.m_features.ForEach([&](uint64_t suburbId) { - auto ft = m_context->GetFeature(static_cast(suburbId)); + suburb.m_features.ForEach([&](uint64_t suburbId) + { + auto ft = m_context->GetFeature(base::asserted_cast(suburbId)); if (!ft) return; auto & layers = ctx.m_layers; ASSERT(layers.empty(), ()); layers.emplace_back(); - SCOPE_GUARD(cleanupGuard, [&]{ layers.pop_back(); }); + SCOPE_GUARD(cleanupGuard, [&layers]{ layers.pop_back(); }); auto & layer = layers.back(); InitLayer(Model::TYPE_SUBURB, suburb.m_tokenRange, layer); vector suburbFeatures = {ft->GetID().m_index}; layer.m_sortedFeatures = &suburbFeatures; - auto const suburbType = ftypes::IsSuburbChecker::Instance().GetType(*ft); + auto const suburbType = suburbChecker.GetType(*ft); double radius = 0.0; switch (suburbType) {