diff --git a/generator/descriptions_section_builder.hpp b/generator/descriptions_section_builder.hpp index 8c117c1a8c..1ccaebb314 100644 --- a/generator/descriptions_section_builder.hpp +++ b/generator/descriptions_section_builder.hpp @@ -109,8 +109,8 @@ public: { descriptions::DescriptionsCollection descriptionList; auto fn = [&](Ft & f, uint32_t featureId) { - auto const & wikiChecker = ftypes::WikiChecker::Instance(); - if (!wikiChecker.NeedFeature(f)) + auto const & attractionsChecker = ftypes::AttractionsChecker::Instance(); + if (!attractionsChecker.NeedFeature(f)) return; std::function incSource = []() {}; diff --git a/generator/generator_tests/descriptions_section_builder_tests.cpp b/generator/generator_tests/descriptions_section_builder_tests.cpp index e5054246a0..5b37b9a237 100644 --- a/generator/generator_tests/descriptions_section_builder_tests.cpp +++ b/generator/generator_tests/descriptions_section_builder_tests.cpp @@ -300,11 +300,11 @@ private: Feature ft; ft.SetMetadata(md); - auto const & wikiChecker = ftypes::WikiChecker::Instance(); - CHECK(!wikiChecker.kTypesForWiki.empty(), ()); - auto const itFirst = std::begin(wikiChecker.kTypesForWiki); - auto const type = classif().GetTypeByPath({itFirst->first, itFirst->second}); - ft.SetTypes({type}); + auto const & attractionsChecker = ftypes::AttractionsChecker::Instance(); + CHECK(!attractionsChecker.m_primaryTypes.empty(), ()); + CHECK(!attractionsChecker.m_additionalTypes.empty(), ()); + auto const itFirst = std::begin(attractionsChecker.m_primaryTypes); + ft.SetTypes({*itFirst}); return ft; } diff --git a/generator/wiki_url_dumper.cpp b/generator/wiki_url_dumper.cpp index 48fdb4833c..0073ab3998 100644 --- a/generator/wiki_url_dumper.cpp +++ b/generator/wiki_url_dumper.cpp @@ -55,7 +55,7 @@ void WikiUrlDumper::Dump(size_t cpuCount) const // static void WikiUrlDumper::DumpOne(std::string const & path, std::ostream & stream) { - auto const & needWikiUrl = ftypes::WikiChecker::Instance(); + auto const & needWikiUrl = ftypes::AttractionsChecker::Instance(); feature::ForEachFromDatRawFormat(path, [&](FeatureBuilder const & feature, uint64_t /* pos */) { if (!needWikiUrl(feature.GetTypesHolder())) return; @@ -88,7 +88,7 @@ WikiDataFilter::WikiDataFilter(std::string const & path, std::vector const & idToWikiData, std::ostream & stream) { - auto const & needWikiUrl = ftypes::WikiChecker::Instance(); + auto const & needWikiUrl = ftypes::AttractionsChecker::Instance(); feature::ForEachFromDatRawFormat(path, [&](FeatureBuilder const & feature, uint64_t /* pos */) { if (!needWikiUrl(feature.GetTypesHolder())) return; diff --git a/indexer/ftypes_matcher.cpp b/indexer/ftypes_matcher.cpp index da4bfd7f0a..8b1b29f7c1 100644 --- a/indexer/ftypes_matcher.cpp +++ b/indexer/ftypes_matcher.cpp @@ -327,36 +327,88 @@ IsPoiChecker::IsPoiChecker() : BaseChecker(1 /* level */) m_types.push_back(classif().GetTypeByPath({type})); } -// static -set> const WikiChecker::kTypesForWiki = { - {"amenity", "place_of_worship"}, - {"historic", "archaeological_site"}, - {"historic", "castle"}, - {"historic", "memorial"}, - {"historic", "monument"}, - {"historic", "museum"}, - {"historic", "ruins"}, - {"historic", "ship"}, - {"historic", "tomb"}, - {"tourism", "artwork"}, - {"tourism", "attraction"}, - {"tourism", "museum"}, - {"tourism", "gallery"}, - {"tourism", "viewpoint"}, - {"tourism", "zoo"}, - {"tourism", "theme_park"}, - {"leisure", "park"}, - {"leisure", "water_park"}, - {"highway", "pedestrian"}, - {"man_made", "lighthouse"}, - {"waterway", "waterfall"}, - {"leisure", "garden"}, -}; - -WikiChecker::WikiChecker() : BaseChecker(2 /* level */) +AttractionsChecker::AttractionsChecker() : BaseChecker(2 /* level */) { - for (auto const & t : kTypesForWiki) - m_types.push_back(classif().GetTypeByPath({t.first, t.second})); + set> const primaryAttractionTypes = { + {"amenity", "grave_yard"}, + {"amenity", "fountain"}, + {"amenity", "place_of_worship"}, + {"amenity", "theatre"}, + {"amenity", "townhall"}, + {"amenity", "university"}, + {"boundary", "national_park"}, + {"building", "train_station"}, + {"highway", "pedestrian"}, + {"historic", "archaeological_site"}, + {"historic", "boundary_stone"}, + {"historic", "castle"}, + {"historic", "fort"}, + {"historic", "memorial"}, + {"historic", "monument"}, + {"historic", "museum"}, + {"historic", "ruins"}, + {"historic", "ship"}, + {"historic", "tomb"}, + {"historic", "wayside_cross"}, + {"historic", "wayside_shrine"}, + {"landuse", "cemetery"}, + {"leisure", "garden"}, + {"leisure", "nature_reserve"}, + {"leisure", "park"}, + {"leisure", "water_park"}, + {"man_made", "lighthouse"}, + {"man_made", "tower"}, + {"natural", "beach"}, + {"natural", "cave_entrance"}, + {"natural", "geyser"}, + {"natural", "glacier"}, + {"natural", "hot_spring"}, + {"natural", "peak"}, + {"natural", "volcano"}, + {"place", "square"}, + {"tourism", "artwork"}, + {"tourism", "museum"}, + {"tourism", "gallery"}, + {"tourism", "zoo"}, + {"tourism", "theme_park"}, + {"waterway", "waterfall"}, + }; + + set> const additionalAttractionTypes = { + {"tourism", "viewpoint"}, + {"tourism", "attraction"}, + }; + + for (auto const & t : primaryAttractionTypes) + { + auto const type = classif().GetTypeByPath({t.first, t.second}); + m_types.push_back(type); + m_primaryTypes.push_back(type); + } + sort(m_primaryTypes.begin(), m_primaryTypes.end()); + + for (auto const & t : additionalAttractionTypes) + { + auto const type = classif().GetTypeByPath({t.first, t.second}); + m_types.push_back(type); + m_additionalTypes.push_back(type); + } + sort(m_additionalTypes.begin(), m_additionalTypes.end()); +} + +uint32_t AttractionsChecker::GetBestType(FeatureParams::Types const & types) const +{ + auto additionalType = ftype::GetEmptyValue(); + for (auto type : types) + { + type = PrepareToMatch(type, m_level); + if (binary_search(m_primaryTypes.begin(), m_primaryTypes.end(), type)) + return type; + + if (binary_search(m_additionalTypes.begin(), m_additionalTypes.end(), type)) + additionalType = type; + } + return additionalType; } IsPlaceChecker::IsPlaceChecker() : BaseChecker(1 /* level */) @@ -471,7 +523,7 @@ IsPopularityPlaceChecker::IsPopularityPlaceChecker() {"waterway", "waterfall"} }; - Classificator const & c = classif(); + Classificator const & c = classif(); for (auto const & t : popularityPlaceTypes) m_types.push_back(c.GetTypeByPath({t.first, t.second})); } diff --git a/indexer/ftypes_matcher.hpp b/indexer/ftypes_matcher.hpp index 40c62b0cea..7ef0ce3d16 100644 --- a/indexer/ftypes_matcher.hpp +++ b/indexer/ftypes_matcher.hpp @@ -28,9 +28,8 @@ namespace ftypes { class BaseChecker { - size_t const m_level; - protected: + size_t const m_level; std::vector m_types; BaseChecker(size_t level = 2) : m_level(level) {} @@ -191,13 +190,15 @@ public: DECLARE_CHECKER_INSTANCE(IsPoiChecker); }; -class WikiChecker : public BaseChecker +class AttractionsChecker : public BaseChecker { - WikiChecker(); -public: - static std::set> const kTypesForWiki; + AttractionsChecker(); - DECLARE_CHECKER_INSTANCE(WikiChecker); +public: + std::vector m_primaryTypes; + std::vector m_additionalTypes; + + DECLARE_CHECKER_INSTANCE(AttractionsChecker); template bool NeedFeature(Ft & feature) const @@ -209,6 +210,8 @@ public: }); return need; } + + uint32_t GetBestType(FeatureParams::Types const & types) const; }; class IsPlaceChecker : public BaseChecker diff --git a/indexer/indexer_tests/checker_test.cpp b/indexer/indexer_tests/checker_test.cpp index 19f14e6a34..fc51095d4d 100644 --- a/indexer/indexer_tests/checker_test.cpp +++ b/indexer/indexer_tests/checker_test.cpp @@ -29,16 +29,6 @@ vector GetTypes(char const * arr[][roadArrColumnCount], size_t const r return types; } -vector GetTypes(std::vector> const & t) -{ - Classificator const & c = classif(); - vector types; - - for (auto const & k : t) - types.push_back(c.GetTypeByPath({k.first, k.second})); - return types; -} - vector GetTypes(std::vector const & t) { Classificator const & c = classif(); @@ -130,33 +120,17 @@ vector GetPoiTypes() return GetTypes(types); } -vector GetWikiTypes() +vector GetAttractionsTypes() { - vector> const types = { - {"amenity", "place_of_worship"}, - {"historic", "archaeological_site"}, - {"historic", "castle"}, - {"historic", "memorial"}, - {"historic", "monument"}, - {"historic", "museum"}, - {"historic", "ruins"}, - {"historic", "ship"}, - {"historic", "tomb"}, - {"tourism", "artwork"}, - {"tourism", "attraction"}, - {"tourism", "museum"}, - {"tourism", "gallery"}, - {"tourism", "viewpoint"}, - {"tourism", "zoo"}, - {"tourism", "theme_park"}, - {"leisure", "park"}, - {"leisure", "water_park"}, - {"highway", "pedestrian"}, - {"man_made", "lighthouse"}, - {"waterway", "waterfall"}, - {"leisure", "garden"} - }; - return GetTypes(types); + auto const & checker = ftypes::AttractionsChecker::Instance(); + vector types; + types.reserve(checker.m_primaryTypes.size() + checker.m_additionalTypes.size()); + for (auto t : checker.m_primaryTypes) + types.push_back(t); + for (auto t : checker.m_additionalTypes) + types.push_back(t); + + return types; } } // namespace @@ -253,13 +227,13 @@ UNIT_TEST(IsPoiChecker) TEST(!checker(c.GetTypeByPath({"building"})), ()); } -UNIT_TEST(IsWikiChecker) +UNIT_TEST(IsAttractionsChecker) { classificator::Load(); Classificator const & c = classif(); - auto const & checker = ftypes::WikiChecker::Instance(); + auto const & checker = ftypes::AttractionsChecker::Instance(); - for (auto const & t : GetWikiTypes()) + for (auto const & t : GetAttractionsTypes()) TEST(checker(t), ()); TEST(!checker(c.GetTypeByPath({"route", "shuttle_train"})), ());