diff --git a/generator/regions/admin_suburbs_marker.cpp b/generator/regions/admin_suburbs_marker.cpp index 9c75e2f988..c27354630c 100644 --- a/generator/regions/admin_suburbs_marker.cpp +++ b/generator/regions/admin_suburbs_marker.cpp @@ -23,24 +23,36 @@ void AdminSuburbsMarker::MarkLocality(Node::Ptr & tree) { ASSERT(tree->GetData().GetLevel() == PlaceLevel::Locality, ()); for (auto & subtree : tree->GetChildren()) - MarkSuburbsInLocality(subtree); + MarkSuburbsInLocality(subtree, tree->GetData()); } -void AdminSuburbsMarker::MarkSuburbsInLocality(Node::Ptr & tree) +void AdminSuburbsMarker::MarkSuburbsInLocality(Node::Ptr & tree, LevelRegion const & locality) { auto & region = tree->GetData(); - auto const level = region.GetLevel(); - if (level == PlaceLevel::Locality) + if (region.GetLevel() == PlaceLevel::Locality) { MarkLocality(tree); return; } - if (level == PlaceLevel::Unknown && region.GetAdminLevel() != AdminLevel::Unknown) - region.SetLevel(PlaceLevel::Suburb); + if (region.GetLevel() == PlaceLevel::Unknown && region.GetAdminLevel() != AdminLevel::Unknown) + { + if (region.GetName() != locality.GetName() || + region.GetArea() < kLocalityAreaRatioMax * locality.GetArea()) + { + region.SetLevel(PlaceLevel::Suburb); + } + } + + if (region.GetLevel() >= PlaceLevel::Suburb) + { + for (auto & subtree : tree->GetChildren()) + MarkUnderLocalityAsSublocalities(subtree); + return; + } for (auto & subtree : tree->GetChildren()) - MarkUnderLocalityAsSublocalities(subtree); + MarkSuburbsInLocality(subtree, locality); } void AdminSuburbsMarker::MarkUnderLocalityAsSublocalities(Node::Ptr & tree) diff --git a/generator/regions/admin_suburbs_marker.hpp b/generator/regions/admin_suburbs_marker.hpp index fc958ae60a..b101bcf202 100644 --- a/generator/regions/admin_suburbs_marker.hpp +++ b/generator/regions/admin_suburbs_marker.hpp @@ -9,11 +9,13 @@ namespace regions class AdminSuburbsMarker { public: + static constexpr double kLocalityAreaRatioMax = 0.8; + void MarkSuburbs(Node::Ptr & tree); private: void MarkLocality(Node::Ptr & tree); - void MarkSuburbsInLocality(Node::Ptr & tree); + void MarkSuburbsInLocality(Node::Ptr & tree, LevelRegion const & locality); void MarkUnderLocalityAsSublocalities(Node::Ptr & tree); }; } // namespace regions