Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvng <viktor.govako@gmail.com>2010-12-26 15:53:05 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 01:08:50 +0300
commit1c699a5a4009906f8a712261c5108431655f9f53 (patch)
treed632f9eb3838a4ab8e47fd1e003cf9769040ce2f /geometry/tree4d.hpp
parent4223de90999ac069efbef4739e5865318710c706 (diff)
Add kdtree++ and tree4d as 4-dimensional tree by object's limit rect.
Diffstat (limited to 'geometry/tree4d.hpp')
-rw-r--r--geometry/tree4d.hpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/geometry/tree4d.hpp b/geometry/tree4d.hpp
new file mode 100644
index 0000000000..7e22ed290f
--- /dev/null
+++ b/geometry/tree4d.hpp
@@ -0,0 +1,106 @@
+#pragma once
+
+#include "rect2d.hpp"
+#include "point2d.hpp"
+
+#include "../base/stl_add.hpp"
+
+#include "../std/kdtree.hpp"
+
+
+namespace m4
+{
+ template <class T, class TTraits>
+ class Tree
+ {
+ struct value_t
+ {
+ T m_val;
+ double m_pts[4];
+
+ typedef double value_type;
+
+ value_t(T const & t, m2::RectD const & r) : m_val(t)
+ {
+ m_pts[0] = r.minX();
+ m_pts[1] = r.minY();
+ m_pts[2] = r.maxX();
+ m_pts[3] = r.maxY();
+ }
+
+ bool IsIntersect(m2::RectD const & r) const
+ {
+ return !((m_pts[2] <= r.minX()) || (m_pts[0] >= r.maxX()) ||
+ (m_pts[3] <= r.minY()) || (m_pts[1] >= r.maxY()));
+ }
+
+ double operator[](size_t i) const { return m_pts[i]; }
+ };
+
+ typedef KDTree::KDTree<4, value_t> tree_t;
+ typedef typename tree_t::_Region_ region_t;
+ tree_t m_tree;
+
+ public:
+
+ template <class TCompare>
+ void ReplaceIf(T const & obj, TCompare comp)
+ {
+ m2::RectD const rect = TTraits::GetLimitRect(obj);
+
+ region_t rgn;
+ for (size_t i = 0; i < 4; ++i)
+ {
+ if (i % 2 == 0)
+ {
+ rgn._M_low_bounds[i] = rect.minX();
+ rgn._M_high_bounds[i] = rect.maxX();
+ }
+ else
+ {
+ rgn._M_low_bounds[i] = rect.minY();
+ rgn._M_high_bounds[i] = rect.maxY();
+ }
+ }
+
+ typedef vector<value_t const *> store_vec_t;
+ store_vec_t isect;
+
+ class insert_if_intersect
+ {
+ store_vec_t & m_isect;
+ m2::RectD const & m_rect;
+
+ public:
+ insert_if_intersect(store_vec_t & isect, m2::RectD const & r)
+ : m_isect(isect), m_rect(r)
+ {
+ }
+
+ void operator() (value_t const & v)
+ {
+ if (v.IsIntersect(m_rect))
+ m_isect.push_back(&v);
+ }
+ };
+
+ m_tree.visit_within_range(rgn, insert_if_intersect(isect, rect));
+
+ for (size_t i = 0; i < isect.size(); ++i)
+ if (!comp(obj, isect[i]->m_val))
+ return;
+
+ for (store_vec_t::const_iterator i = isect.begin(); i != isect.end(); ++i)
+ m_tree.erase(**i);
+
+ m_tree.insert(value_t(obj, rect));
+ }
+
+ template <class ToDo>
+ void ForEach(ToDo toDo) const
+ {
+ for (tree_t::const_iterator i = m_tree.begin(); i != m_tree.end(); ++i)
+ toDo((*i).m_val);
+ }
+ };
+}