diff options
author | vng <viktor.govako@gmail.com> | 2011-01-27 02:59:23 +0300 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:11:00 +0300 |
commit | a13b24206a7119e1b1547ca5d092c42dfee4e1a5 (patch) | |
tree | eaba55d58a0773188a3ff285715c8e284c32f040 | |
parent | 87560d46bade928d019331a58f27a1106712cacd (diff) |
Add m4::Tree::ForEachInRect and some othe functions.
-rw-r--r-- | geometry/geometry_tests/tree_test.cpp | 12 | ||||
-rw-r--r-- | geometry/tree4d.hpp | 66 |
2 files changed, 66 insertions, 12 deletions
diff --git a/geometry/geometry_tests/tree_test.cpp b/geometry/geometry_tests/tree_test.cpp index 4de8c8cc4a..1e4feb0f94 100644 --- a/geometry/geometry_tests/tree_test.cpp +++ b/geometry/geometry_tests/tree_test.cpp @@ -29,6 +29,12 @@ UNIT_TEST(Tree4D_Smoke) theTree.ForEach(MakeBackInsertFunctor(test)); TEST_EQUAL(3, test.size(), ()); + test.clear(); + m2::RectD const searchR(1.5, 1.5, 1.5, 1.5); + theTree.ForEachInRect(searchR, MakeBackInsertFunctor(test)); + TEST_EQUAL(1, test.size(), ()); + TEST_EQUAL(test[0], arr[1], ()); + m2::RectD const replaceR(0.5, 0.5, 2.5, 2.5); theTree.ReplaceIf(replaceR, replaceR, &compare_true); @@ -36,9 +42,13 @@ UNIT_TEST(Tree4D_Smoke) theTree.ForEach(MakeBackInsertFunctor(test)); TEST_EQUAL(1, test.size(), ()); TEST_EQUAL(test[0], replaceR, ()); + + test.clear(); + theTree.ForEachInRect(searchR, MakeBackInsertFunctor(test)); + TEST_EQUAL(1, test.size(), ()); } -UNIT_TEST(Tree4D_DrawTexts) +UNIT_TEST(Tree4D_ReplaceIf) { tree_t theTree; diff --git a/geometry/tree4d.hpp b/geometry/tree4d.hpp index 9ab5e791c8..2976da82ff 100644 --- a/geometry/tree4d.hpp +++ b/geometry/tree4d.hpp @@ -42,23 +42,17 @@ namespace m4 typedef vector<value_t const *> store_vec_t; - class insert_if_intersect + // Base do-class for rect-iteration in tree. + class for_each_base { - store_vec_t & m_isect; + protected: m2::RectD const & m_rect; public: - insert_if_intersect(store_vec_t & isect, m2::RectD const & r) - : m_isect(isect), m_rect(r) + for_each_base(m2::RectD const & r) : m_rect(r) { } - void operator() (value_t const & v) - { - if (v.IsIntersect(m_rect)) - m_isect.push_back(&v); - } - bool ScanLeft(size_t plane, value_t const & v) const { switch (plane & 3) // % 4 @@ -80,8 +74,50 @@ namespace m4 } }; + // Do-class for getting elements in rect. + class insert_if_intersect : public for_each_base + { + typedef for_each_base base_t; + + store_vec_t & m_isect; + + public: + insert_if_intersect(store_vec_t & isect, m2::RectD const & r) + : for_each_base(r), m_isect(isect) + { + } + void operator() (value_t const & v) + { + if (v.IsIntersect(base_t::m_rect)) + m_isect.push_back(&v); + } + }; + + // Do-class for processing elements in rect. + template <class ToDo> class for_each_in_rect : public for_each_base + { + typedef for_each_base base_t; + + ToDo & m_toDo; + public: + for_each_in_rect(ToDo & toDo, m2::RectD const & rect) + : for_each_base(rect), m_toDo(toDo) + { + } + void operator() (value_t const & v) + { + if (v.IsIntersect(base_t::m_rect)) + m_toDo(v.m_val); + } + }; + public: + void Add(T const & obj, m2::RectD const & rect) + { + m_tree.insert(value_t(obj, rect)); + } + template <class TCompare> void ReplaceIf(T const & obj, m2::RectD const & rect, TCompare comp) { @@ -95,7 +131,7 @@ namespace m4 for (typename store_vec_t::const_iterator i = isect.begin(); i != isect.end(); ++i) m_tree.erase(**i); - m_tree.insert(value_t(obj, rect)); + Add(obj, rect); } template <class TCompare> @@ -111,6 +147,14 @@ namespace m4 toDo((*i).m_val); } + template <class ToDo> + void ForEachInRect(m2::RectD const & rect, ToDo toDo) const + { + m_tree.for_each(for_each_in_rect<ToDo>(toDo, rect)); + } + + bool IsEmpty() const { return m_tree.empty(); } + size_t GetSize() const { return m_tree.size(); } void Clear() { m_tree.clear(); } |