diff --git a/generator/final_processor_intermediate_mwm.cpp b/generator/final_processor_intermediate_mwm.cpp index bd96de12a4..b549e83851 100644 --- a/generator/final_processor_intermediate_mwm.cpp +++ b/generator/final_processor_intermediate_mwm.cpp @@ -640,10 +640,7 @@ void ComplexFinalProcessor::Process() relationBuildingParts = RemoveRelationBuildingParts(fbs); // This case is second. We build a hierarchy using the geometry of objects and their nesting. - hierarchy::HierarchyBuilder builder(std::move(fbs)); - builder.SetGetMainTypeFunction(m_getMainType); - builder.SetFilter(m_filter); - auto trees = builder.Build(); + auto trees = hierarchy::BuildHierarchy(std::move(fbs), m_getMainType, m_filter); // We remove tree roots with tag 'building:part'. base::EraseIf(trees, [](auto const & node) { @@ -704,23 +701,20 @@ ComplexFinalProcessor::RemoveRelationBuildingParts(std::vector & { CHECK(m_buildingToParts, ()); - std::unordered_map relationBuildingParts; - auto last = std::end(fbs); - for (auto it = std::begin(fbs); it != last;) - { - if (m_buildingToParts->HasBuildingPart(it->GetMostGenericOsmId())) - { - relationBuildingParts.emplace(it->GetMostGenericOsmId(), *it); - std::iter_swap(it, --last); - } - else - { - ++it; - } - } + auto it = std::partition(std::begin(fbs), std::end(fbs), [&](auto const & fb) { + return !m_buildingToParts->HasBuildingPart(fb.GetMostGenericOsmId()); + }); - fbs.erase(last, std::end(fbs)); - return relationBuildingParts; + std::unordered_map buildingParts; + buildingParts.reserve(static_cast(std::distance(it, std::end(fbs)))); + + std::transform(it, std::end(fbs), std::inserter(buildingParts, std::begin(buildingParts)), [](auto && fb) { + auto const id = fb.GetMostGenericOsmId(); + return std::make_pair(id, std::move(fb)); + }); + + fbs.resize(static_cast(std::distance(std::begin(fbs), it))); + return buildingParts; } void ComplexFinalProcessor::WriteLines(std::vector const & lines) diff --git a/generator/generator_tests/hierarchy_tests.cpp b/generator/generator_tests/hierarchy_tests.cpp index bb49076f2c..8d896a6e99 100644 --- a/generator/generator_tests/hierarchy_tests.cpp +++ b/generator/generator_tests/hierarchy_tests.cpp @@ -60,7 +60,7 @@ std::vector MakeTestSet1() return fbs; } -void TestDepthNodeById(generator::hierarchy::HierarchyBuilder::Node::Ptr const & tree, uint64_t id, +void TestDepthNodeById(generator::hierarchy::HierarchyLinker::Node::Ptr const & tree, uint64_t id, size_t depth) { auto osmId = base::MakeOsmWay(id); @@ -71,11 +71,10 @@ void TestDepthNodeById(generator::hierarchy::HierarchyBuilder::Node::Ptr const & UNIT_CLASS_TEST(TestWithClassificator, ComplexHierarchy_FlattenBuildingParts) { - generator::hierarchy::HierarchyBuilder builder(MakeTestSet1()); - builder.SetGetMainTypeFunction(generator::hierarchy::GetMainType); - builder.SetFilter(std::make_shared()); - auto trees = builder.Build(); + auto trees = generator::hierarchy::BuildHierarchy(MakeTestSet1(), + generator::hierarchy::GetMainType, + std::make_shared()); TEST_EQUAL(trees.size(), 1, ()); TEST_EQUAL(tree_node::Size(trees[0]), 4, ()); @@ -95,11 +94,9 @@ UNIT_CLASS_TEST(TestWithClassificator, ComplexHierarchy_FlattenBuildingParts) UNIT_CLASS_TEST(TestWithClassificator, ComplexHierarchy_AddChildrenTo) { - generator::hierarchy::HierarchyBuilder builder(MakeTestSet1()); - builder.SetGetMainTypeFunction(generator::hierarchy::GetMainType); - builder.SetFilter(std::make_shared()); - auto trees = builder.Build(); - + auto trees = generator::hierarchy::BuildHierarchy(MakeTestSet1(), + generator::hierarchy::GetMainType, + std::make_shared()); TEST_EQUAL(trees.size(), 1, ()); TEST_EQUAL(tree_node::Size(trees[0]), 4, ()); diff --git a/generator/hierarchy.cpp b/generator/hierarchy.cpp index 43e59c7023..6625a6055f 100644 --- a/generator/hierarchy.cpp +++ b/generator/hierarchy.cpp @@ -160,43 +160,6 @@ HierarchyLinker::Node::Ptrs HierarchyLinker::Link() return m_nodes; } -HierarchyBuilder::HierarchyBuilder(std::vector && fbs) - : m_fbs(std::move(fbs)) -{ -} - -HierarchyBuilder::HierarchyBuilder(std::vector const & fbs) - : m_fbs(fbs) -{ -} - -void HierarchyBuilder::SetGetMainTypeFunction(GetMainTypeFn const & getMainType) -{ - m_getMainType = getMainType; -} - -void HierarchyBuilder::SetFilter(std::shared_ptr const & filter) -{ - m_filter = filter; -} - -HierarchyBuilder::Node::Ptrs HierarchyBuilder::Build() -{ - CHECK(m_getMainType, ()); - - base::EraseIf(m_fbs, [&](auto const & fb) { return !m_filter->IsAccepted(fb); }); - Node::Ptrs places; - places.reserve(m_fbs.size()); - std::transform(std::cbegin(m_fbs), std::cend(m_fbs), std::back_inserter(places), - [](auto const & fb) { return std::make_shared(HierarchyPlace(fb)); }); - auto nodes = HierarchyLinker(std::move(places)).Link(); - // We leave only the trees. - base::EraseIf(nodes, [](auto const & node) { - return node->HasParent(); - }); - return nodes; -} - HierarchyEntryEnricher::HierarchyEntryEnricher(std::string const & osm2FtIdsPath, std::string const & countryFullPath) : m_featureGetter(countryFullPath) @@ -238,7 +201,7 @@ boost::optional HierarchyEntryEnricher::GetFeatureCenter(CompositeId return {}; } -HierarchyLinesBuilder::HierarchyLinesBuilder(HierarchyBuilder::Node::Ptrs && trees) +HierarchyLinesBuilder::HierarchyLinesBuilder(HierarchyLinker::Node::Ptrs && trees) : m_trees(std::move(trees)) { } @@ -277,7 +240,7 @@ std::vector HierarchyLinesBuilder::GetHierarchyLines() return lines; } -m2::PointD HierarchyLinesBuilder::GetCenter(HierarchyBuilder::Node::Ptr const & node) +m2::PointD HierarchyLinesBuilder::GetCenter(HierarchyLinker::Node::Ptr const & node) { auto const & data = node->GetData(); if (!m_enricher) @@ -287,7 +250,7 @@ m2::PointD HierarchyLinesBuilder::GetCenter(HierarchyBuilder::Node::Ptr const & return optCenter ? *optCenter : data.GetCenter(); } -HierarchyEntry HierarchyLinesBuilder::Transform(HierarchyBuilder::Node::Ptr const & node) +HierarchyEntry HierarchyLinesBuilder::Transform(HierarchyLinker::Node::Ptr const & node) { HierarchyEntry line; auto const & data = node->GetData(); @@ -304,7 +267,25 @@ HierarchyEntry HierarchyLinesBuilder::Transform(HierarchyBuilder::Node::Ptr cons return line; } -void AddChildrenTo(HierarchyBuilder::Node::Ptrs & trees, +HierarchyLinker::Node::Ptrs BuildHierarchy(std::vector && fbs, + GetMainTypeFn const & getMainType, + std::shared_ptr const & filter) +{ + base::EraseIf(fbs, [&](auto const & fb) { return !filter->IsAccepted(fb); }); + HierarchyLinker::Node::Ptrs places; + places.reserve(fbs.size()); + std::transform(std::cbegin(fbs), std::cend(fbs), std::back_inserter(places), + [](auto const & fb) { return tree_node::MakeTreeNode(HierarchyPlace(fb)); }); + auto nodes = HierarchyLinker(std::move(places)).Link(); + // We leave only the trees. + base::EraseIf(nodes, [](auto const & node) { + return node->HasParent(); + }); + return nodes; +} + + +void AddChildrenTo(HierarchyLinker::Node::Ptrs & trees, std::function(CompositeId const &)> const & fn) { for (auto & tree : trees) @@ -323,7 +304,7 @@ void AddChildrenTo(HierarchyBuilder::Node::Ptrs & trees, } } -void FlattenBuildingParts(HierarchyBuilder::Node::Ptrs & trees) +void FlattenBuildingParts(HierarchyLinker::Node::Ptrs & trees) { for (auto & tree : trees) { @@ -331,11 +312,11 @@ void FlattenBuildingParts(HierarchyBuilder::Node::Ptrs & trees) CHECK(!tree->HasParent(), ()); std::vector< - std::pair> + std::pair> buildingPartsTrees; static auto const & buildingPartChecker = ftypes::IsBuildingPartChecker::Instance(); - std::function visit; + std::function visit; visit = [&](auto const & n) { if (buildingPartChecker(n->GetData().GetTypes())) { diff --git a/generator/hierarchy.hpp b/generator/hierarchy.hpp index f7005f27ea..d6c21112ec 100644 --- a/generator/hierarchy.hpp +++ b/generator/hierarchy.hpp @@ -96,26 +96,6 @@ private: Tree4d m_tree; }; -// HierarchyBuilder class filters input elements and builds hierarchy from file *.mwm.tmp. -class HierarchyBuilder -{ -public: - using Node = HierarchyLinker::Node; - - explicit HierarchyBuilder(std::vector && fbs); - explicit HierarchyBuilder(std::vector const & fbs); - - void SetGetMainTypeFunction(GetMainTypeFn const & getMainType); - void SetFilter(std::shared_ptr const & filter); - - Node::Ptrs Build(); - -protected: - GetMainTypeFn m_getMainType; - std::shared_ptr m_filter; - std::vector m_fbs; -}; - class HierarchyEntryEnricher { public: @@ -131,7 +111,7 @@ private: class HierarchyLinesBuilder { public: - HierarchyLinesBuilder(HierarchyBuilder::Node::Ptrs && trees); + HierarchyLinesBuilder(HierarchyLinker::Node::Ptrs && trees); void SetGetMainTypeFunction(GetMainTypeFn const & getMainType); void SetGetNameFunction(GetNameFn const & getName); @@ -141,19 +121,23 @@ public: std::vector GetHierarchyLines(); private: - m2::PointD GetCenter(HierarchyBuilder::Node::Ptr const & node); - HierarchyEntry Transform(HierarchyBuilder::Node::Ptr const & node); + m2::PointD GetCenter(HierarchyLinker::Node::Ptr const & node); + HierarchyEntry Transform(HierarchyLinker::Node::Ptr const & node); - HierarchyBuilder::Node::Ptrs m_trees; + HierarchyLinker::Node::Ptrs m_trees; GetMainTypeFn m_getMainType; GetNameFn m_getName; storage::CountryId m_countryName; std::unique_ptr m_enricher; }; +HierarchyLinker::Node::Ptrs BuildHierarchy(std::vector && fbs, + GetMainTypeFn const & getMainType, + std::shared_ptr const & filter); + // AddChildrenTo adds children to node of tree if fn returns not empty vector of HierarchyPlaces // for node id. -void AddChildrenTo(HierarchyBuilder::Node::Ptrs & trees, +void AddChildrenTo(HierarchyLinker::Node::Ptrs & trees, std::function(CompositeId const &)> const & fn); // FlattenBuildingParts transforms trees from @@ -164,6 +148,6 @@ void AddChildrenTo(HierarchyBuilder::Node::Ptrs & trees, // building // |_building-part // |_building-part -void FlattenBuildingParts(HierarchyBuilder::Node::Ptrs & trees); +void FlattenBuildingParts(HierarchyLinker::Node::Ptrs & trees); } // namespace hierarchy } // namespace generator