diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt index 714b65e094..03688500c4 100644 --- a/generator/CMakeLists.txt +++ b/generator/CMakeLists.txt @@ -145,6 +145,8 @@ set( ratings_section_builder.hpp region_meta.cpp region_meta.hpp + regions/admin_suburbs_marker.cpp + regions/admin_suburbs_marker.hpp regions/collector_region_info.cpp regions/collector_region_info.hpp regions/country_specifier.cpp diff --git a/generator/generator_tests/regions_tests.cpp b/generator/generator_tests/regions_tests.cpp index 2c71a02a1a..37599a3023 100644 --- a/generator/generator_tests/regions_tests.cpp +++ b/generator/generator_tests/regions_tests.cpp @@ -528,11 +528,9 @@ UNIT_TEST(RegionsBuilderTest_GenerateRusCitySuburb) TEST(HasName(regions, u8"Россия, region: Омская область, subregion: городской округ Омск, " u8"locality: Омск"), ()); - /* FIXME: TEST(HasName(regions, u8"Россия, region: Омская область, subregion: городской округ Омск, " u8"locality: Омск, suburb: Кировский административный округ"), ()); - */ } UNIT_TEST(RegionsBuilderTest_GenerateRusMoscowSuburb) @@ -560,14 +558,12 @@ UNIT_TEST(RegionsBuilderTest_GenerateRusMoscowSuburb) u8"Россия, region: Москва, subregion: Западный административный округ, " u8"locality: Москва"), ()); - /* FIXME: TEST(HasName(regions, u8"Россия, region: Москва, subregion: Западный административный округ, " u8"locality: Москва, suburb: Раменки"), ()); TEST(HasName(regions, u8"Россия, region: Москва, subregion: Западный административный округ, " u8"locality: Москва, suburb: Раменки, sublocality: Воробъёвы горы"), ()); - */ TEST(HasName(regions, u8"Россия, region: Москва, subregion: Западный административный округ, " u8"locality: Москва, sublocality: Центр"), @@ -592,12 +588,10 @@ UNIT_TEST(RegionsBuilderTest_GenerateRusSPetersburgSuburb) }); TEST(HasName(regions, u8"Россия, region: Санкт-Петербург, locality: Санкт-Петербург"), ()); - /* FIXME: TEST(HasName(regions, u8"Россия, region: Санкт-Петербург, locality: Санкт-Петербург, " u8"suburb: Центральный район"), ()); TEST(HasName(regions, u8"Россия, region: Санкт-Петербург, locality: Санкт-Петербург, " u8"suburb: Центральный район, sublocality: Дворцовый округ"), ()); - */ } diff --git a/generator/regions/admin_suburbs_marker.cpp b/generator/regions/admin_suburbs_marker.cpp new file mode 100644 index 0000000000..738c5d4e54 --- /dev/null +++ b/generator/regions/admin_suburbs_marker.cpp @@ -0,0 +1,64 @@ +#include "generator/regions/admin_suburbs_marker.hpp" + +#include "generator/regions/region.hpp" + +namespace generator +{ +namespace regions +{ +void AdminSuburbsMarker::MarkSuburbs(Node::Ptr & tree) +{ + auto const & region = tree->GetData(); + if (region.GetLevel() == PlaceLevel::Locality) + { + MarkLocality(tree); + return; + } + + for (auto & subtree : tree->GetChildren()) + MarkSuburbs(subtree); +} + +void AdminSuburbsMarker::MarkLocality(Node::Ptr & tree) +{ + ASSERT_EQUAL(tree->GetData().GetLevel(), PlaceLevel::Locality, ()); + for (auto & subtree : tree->GetChildren()) + MarkSuburbsInLocality(subtree); +} + +void AdminSuburbsMarker::MarkSuburbsInLocality(Node::Ptr & tree) +{ + auto & region = tree->GetData(); + if (region.GetLevel() == PlaceLevel::Locality) + { + MarkLocality(tree); + return; + } + + if (region.GetAdminLevel() != AdminLevel::Unknown) + region.SetLevel(PlaceLevel::Suburb); + + for (auto & subtree : tree->GetChildren()) + MarkUnderLocalityAsSublocalities(subtree); +} + +void AdminSuburbsMarker::MarkUnderLocalityAsSublocalities(Node::Ptr & tree) +{ + auto & region = tree->GetData(); + auto const level = region.GetLevel(); + if (level == PlaceLevel::Locality) + { + MarkLocality(tree); + return; + } + + if (level == PlaceLevel::Suburb) + region.SetLevel(PlaceLevel::Sublocality); + else if (level == PlaceLevel::Unknown && region.GetAdminLevel() != AdminLevel::Unknown) + region.SetLevel(PlaceLevel::Sublocality); + + for (auto & subtree : tree->GetChildren()) + MarkUnderLocalityAsSublocalities(subtree); +} +} // namespace regions +} // namespace generator diff --git a/generator/regions/admin_suburbs_marker.hpp b/generator/regions/admin_suburbs_marker.hpp new file mode 100644 index 0000000000..fc958ae60a --- /dev/null +++ b/generator/regions/admin_suburbs_marker.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "generator/regions/node.hpp" + +namespace generator +{ +namespace regions +{ +class AdminSuburbsMarker +{ +public: + void MarkSuburbs(Node::Ptr & tree); + +private: + void MarkLocality(Node::Ptr & tree); + void MarkSuburbsInLocality(Node::Ptr & tree); + void MarkUnderLocalityAsSublocalities(Node::Ptr & tree); +}; +} // namespace regions +} // namespace generator diff --git a/generator/regions/regions_builder.cpp b/generator/regions/regions_builder.cpp index cf12f74816..fda16cf6c3 100644 --- a/generator/regions/regions_builder.cpp +++ b/generator/regions/regions_builder.cpp @@ -1,5 +1,6 @@ #include "generator/regions/regions_builder.hpp" +#include "generator/regions/admin_suburbs_marker.hpp" #include "generator/regions/place_points_integrator.hpp" #include "generator/regions/specs/rus.hpp" @@ -302,7 +303,13 @@ Node::PtrList RegionsBuilder::BuildCountry(std::string const & countryName) cons LOG(LINFO, ("Start integrate place points for", countryName)); pointsIntegrator.ApplyTo(countryTrees); LOG(LINFO, ("Finish integrate place points for", countryName)); - + + AdminSuburbsMarker suburbsMarker; + LOG(LINFO, ("Start mark admin suburbs for", countryName)); + for (auto & tree : countryTrees) + suburbsMarker.MarkSuburbs(tree); + LOG(LINFO, ("Finish mark admin suburbs for", countryName)); + countrySpecifier->AdjustRegionsLevel(countryTrees); return countryTrees;