7#include "mdds/quad_node.hpp"
17#define DEBUG_POINT_QUAD_TREE 0
21template<
typename _PairType>
22void ensure_order(_PairType& v)
24 if (v.first > v.second)
25 ::std::swap(v.first, v.second);
28template<
typename _Key,
typename _NodeType,
typename _Inserter>
29void search_region_node(
const _NodeType* p, _Key x1, _Key y1, _Key x2, _Key y2, _Inserter& result)
36 search_region_space_t region = ::mdds::get_search_region_space(p, x1, y1, x2, y2);
42 search_region_node(p->northeast.get(), x1, y1, x2, y2, result);
43 search_region_node(p->northwest.get(), x1, y1, x2, y2, result);
44 search_region_node(p->southeast.get(), x1, y1, x2, y2, result);
45 search_region_node(p->southwest.get(), x1, y1, x2, y2, result);
48 search_region_node(p->northwest.get(), x1, y1, x2, y2, result);
49 search_region_node(p->southwest.get(), x1, y1, x2, y2, result);
52 search_region_node(p->southeast.get(), x1, y1, x2, y2, result);
53 search_region_node(p->southwest.get(), x1, y1, x2, y2, result);
55 case region_northeast:
56 search_region_node(p->southwest.get(), x1, y1, x2, y2, result);
58 case region_northwest:
59 search_region_node(p->southeast.get(), x1, y1, x2, y2, result);
62 search_region_node(p->northeast.get(), x1, y1, x2, y2, result);
63 search_region_node(p->northwest.get(), x1, y1, x2, y2, result);
65 case region_southeast:
66 search_region_node(p->northwest.get(), x1, y1, x2, y2, result);
68 case region_southwest:
69 search_region_node(p->northeast.get(), x1, y1, x2, y2, result);
72 search_region_node(p->northeast.get(), x1, y1, x2, y2, result);
73 search_region_node(p->southeast.get(), x1, y1, x2, y2, result);
80template<
typename _Key,
typename _Value>
84 class search_result_inserter;
87 typedef _Key key_type;
88 typedef _Value value_type;
89 typedef size_t size_type;
90 typedef ::std::vector<value_type> data_array_type;
98 typedef ::boost::intrusive_ptr<node> node_ptr;
103 node(key_type _x, key_type _y, value_type _data) :
quad_node_base<node_ptr, node, key_type>(_x, _y), data(_data)
106 node(
const node& r) :
quad_node_base<node_ptr, node, key_type>(r), data(r.data)
112 bool operator==(
const node& r)
const
114 return quad_node_base<node_ptr, node, key_type>::operator==(r) && data == r.data;
117 node& operator=(
const node& r)
125 typedef ::std::vector<node_ptr> reinsert_tree_array_type;
126 typedef ::std::pair<key_type, key_type> key_range_type;
135 friend class point_quad_tree<_Key, _Value>;
138 node_access northeast()
const
140 return node_access(mp->northeast.get());
142 node_access northwest()
const
144 return node_access(mp->northwest.get());
146 node_access southeast()
const
148 return node_access(mp->southeast.get());
150 node_access southwest()
const
152 return node_access(mp->southwest.get());
155 value_type data()
const
168 operator bool()
const
170 return mp !=
nullptr;
172 bool operator==(
const node_access& r)
const
177 node_access() : mp(
nullptr)
183 node_access(
const node* p) : mp(p)
194 point(key_type _x, key_type _y) : x(_x), y(_y)
202 friend class search_result_inserter;
204 using res_nodes_type = std::vector<const node*>;
205 using res_nodes_ptr = std::shared_ptr<res_nodes_type>;
210 friend class point_quad_tree<_Key, _Value>::search_results;
211 typedef typename point_quad_tree<_Key, _Value>::point point;
212 typedef typename point_quad_tree<_Key, _Value>::value_type parent_value_type;
216 typedef std::pair<point, parent_value_type> value_type;
217 typedef value_type* pointer;
218 typedef value_type& reference;
219 typedef ptrdiff_t difference_type;
220 typedef ::std::bidirectional_iterator_tag iterator_category;
222 const_iterator(res_nodes_ptr& ptr) : mp_res_nodes(ptr), m_end_pos(false)
225 const_iterator(
const const_iterator& r)
226 : mp_res_nodes(r.mp_res_nodes), m_cur_pos(r.m_cur_pos), m_cur_value(r.m_cur_value),
227 m_end_pos(r.m_end_pos)
230 const_iterator& operator=(
const const_iterator& r)
232 mp_res_nodes = r.mp_res_nodes;
233 m_cur_pos = r.m_cur_pos;
234 m_cur_value = r.m_cur_value;
235 m_end_pos = r.m_end_pos;
239 bool operator==(
const const_iterator& r)
const
244 return mp_res_nodes.get() == r.mp_res_nodes.get() && m_cur_pos == r.m_cur_pos &&
245 m_end_pos == r.m_end_pos;
252 return m_end_pos == r.m_end_pos;
255 bool operator!=(
const const_iterator& r)
const
257 return !operator==(r);
260 const value_type& operator*()
const
265 const value_type* operator->()
const
267 return get_current_value();
270 const value_type* operator++()
277 typename res_nodes_type::const_iterator cur_pos = m_cur_pos;
278 if (++cur_pos == mp_res_nodes->end())
284 update_current_value();
288 const value_type* operator--()
293 return get_current_value();
296 update_current_value();
297 return get_current_value();
310 m_cur_pos = mp_res_nodes->begin();
312 update_current_value();
322 m_cur_pos = mp_res_nodes->end();
326 void update_current_value()
328 const node* p = *m_cur_pos;
329 m_cur_value.first = point(p->x, p->y);
330 m_cur_value.second = p->data;
333 const value_type* get_current_value()
const
339 res_nodes_ptr mp_res_nodes;
340 typename res_nodes_type::const_iterator m_cur_pos;
341 value_type m_cur_value;
345 search_results() =
default;
346 search_results(
const search_results& other) =
default;
347 search_results(search_results&& other) =
default;
348 search_results& operator=(
const search_results& other) =
default;
349 search_results& operator=(search_results&& other) =
default;
366 void push_back(
const node* p)
369 mp_res_nodes.reset(
new res_nodes_type);
370 mp_res_nodes->push_back(p);
374 res_nodes_ptr mp_res_nodes;
378 point_quad_tree(
const point_quad_tree& r);
389 void insert(key_type x, key_type y, value_type data);
403 void search_region(key_type x1, key_type y1, key_type x2, key_type y2, data_array_type& result)
const;
418 search_results
search_region(key_type x1, key_type y1, key_type x2, key_type y2)
const;
430 value_type
find(key_type x, key_type y)
const;
474 point_quad_tree& operator=(
const point_quad_tree& r);
476 bool operator==(
const point_quad_tree& r)
const;
478 bool operator!=(
const point_quad_tree& r)
const
480 return !operator==(r);
497 node_data(key_type _x, key_type _y,
value_type _data) : x(_x), y(_y), data(_data)
499 node_data(
const node_data& r) : x(r.x), y(r.y), data(r.data)
502 bool operator==(
const node_data& r)
const
504 return (x == r.x) && (y == r.y) && (data == r.data);
507 bool operator!=(
const node_data& r)
const
509 return !operator==(r);
514 bool operator()(
const node_data& left,
const node_data& right)
const
516 if (left.x != right.x)
517 return left.x < right.x;
518 if (left.y != right.y)
519 return left.y < right.y;
520 return left.data < right.data;
525 static bool equals(::std::vector<node_data>& v1, ::std::vector<node_data>& v2);
527 bool verify_data(::std::vector<node_data>& expected)
const;
529 bool verify_node_iterator(
const node_access& nac)
const;
530 static bool verify_node_iterator(
const node_access& nac,
const node* p);
532 void get_all_stored_data(::std::vector<node_data>& stored_data)
const;
534 void dump_tree_svg(const ::std::string& fpath)
const;
540 array_inserter(data_array_type& result) : m_result(result)
543 void operator()(
const node* p)
545 m_result.push_back(p->data);
549 data_array_type& m_result;
552 class search_result_inserter
555 search_result_inserter(search_results& result) : m_result(result)
558 void operator()(
const node* p)
560 m_result.push_back(p);
564 search_results& m_result;
570 data_inserter(point_quad_tree& db) : m_db(db)
573 void operator()(
const node_data& v)
575 m_db.insert(v.x, v.y, v.data);
579 point_quad_tree& m_db;
584 node_quadrant_t quad;
588 node_distance() : quad(quad_unspecified), dist(0), node(nullptr)
590 node_distance(node_quadrant_t _quad, key_type _dist,
const node_ptr& _node)
591 : quad(_quad), dist(_dist), node(_node)
595 node_ptr find_node(key_type x, key_type y)
const;
596 const node* find_node_ptr(key_type x, key_type y)
const;
597 node_ptr find_replacement_node(key_type x, key_type y,
const node_ptr& delete_node)
const;
599 void find_candidate_in_quad(
600 key_type x, key_type y, node_distance& dx_node, node_distance& dy_node, node_distance& min_city_block_node,
601 const node_ptr& delete_node, node_quadrant_t quad)
const;
604 const key_range_type& hatched_xrange,
const key_range_type& hatched_yrange, node_ptr quad_root, direction_t dir,
605 reinsert_tree_array_type& insert_list);
608 const key_range_type& hatched_xrange,
const key_range_type& hatched_yrange, node_ptr& quad_root,
609 node_quadrant_t dir, reinsert_tree_array_type& insert_list);
611 void insert_node(node_ptr& dest, node_ptr& node);
612 void reinsert_tree(node_ptr& dest, node_ptr& root);
613 void reinsert_tree(node_ptr& dest, node_quadrant_t quad, node_ptr& root);
614 void clear_all_nodes();
615 void dump_node_svg(
const node* p, ::std::ofstream& file)
const;
616 void count_all_nodes(
const node* p,
size_t& node_count)
const;
617 void insert_data_from(
const point_quad_tree& r);
618 void get_all_stored_data(
const node* p, ::std::vector<node_data>& stored_data)
const;
623 key_range_type m_xrange;
624 key_range_type m_yrange;
627template<
typename _Key,
typename _Value>
628point_quad_tree<_Key, _Value>::point_quad_tree() : m_root(nullptr), m_xrange(0, 0), m_yrange(0, 0)
631template<
typename _Key,
typename _Value>
632point_quad_tree<_Key, _Value>::point_quad_tree(
const point_quad_tree& r)
633 : m_root(nullptr), m_xrange(0, 0), m_yrange(0, 0)
638template<
typename _Key,
typename _Value>
639point_quad_tree<_Key, _Value>::~point_quad_tree()
644template<
typename _Key,
typename _Value>
647 m_xrange.first = ::std::min(m_xrange.first, x);
648 m_xrange.second = ::std::max(m_xrange.second, x);
649 m_yrange.first = ::std::min(m_yrange.first, y);
650 m_yrange.second = ::std::max(m_yrange.second, y);
655 m_root.reset(
new node(x, y, data));
659 node_ptr cur_node = m_root;
662 if (cur_node->x == x && cur_node->y == y)
665 cur_node->data = data;
669 node_quadrant_t quad = cur_node->get_quadrant(x, y);
673 if (cur_node->northeast)
674 cur_node = cur_node->northeast;
677 cur_node->northeast.reset(
new node(x, y, data));
678 cur_node->northeast->parent = cur_node;
683 if (cur_node->northwest)
684 cur_node = cur_node->northwest;
687 cur_node->northwest.reset(
new node(x, y, data));
688 cur_node->northwest->parent = cur_node;
693 if (cur_node->southeast)
694 cur_node = cur_node->southeast;
697 cur_node->southeast.reset(
new node(x, y, data));
698 cur_node->southeast->parent = cur_node;
703 if (cur_node->southwest)
704 cur_node = cur_node->southwest;
707 cur_node->southwest.reset(
new node(x, y, data));
708 cur_node->southwest->parent = cur_node;
716 assert(!
"This should never be reached.");
719template<
typename _Key,
typename _Value>
721 key_type x1, key_type y1, key_type x2, key_type y2, data_array_type& result)
const
724 const node* p = m_root.get();
725 array_inserter _inserter(result);
726 ::mdds::search_region_node(p, x1, y1, x2, y2, _inserter);
729template<
typename _Key,
typename _Value>
731 key_type x1, key_type y1, key_type x2, key_type y2)
const
735 const node* p = m_root.get();
736 search_result_inserter _inserter(result);
737 ::mdds::search_region_node(p, x1, y1, x2, y2, _inserter);
741template<
typename _Key,
typename _Value>
744 const node* p = find_node_ptr(x, y);
750template<
typename _Key,
typename _Value>
754 node_ptr delete_node = find_node(x, y);
759#if DEBUG_POINT_QUAD_TREE
760 cout <<
"found the node to be removed at " << delete_node->x <<
"," << delete_node->y <<
" (" << *delete_node->data
766 if (delete_node->leaf())
768#if DEBUG_POINT_QUAD_TREE
769 cout <<
"deleting a leaf node." << endl;
771 if (delete_node.get() == m_root.get())
774 disconnect_node_from_parent(delete_node);
779 node_ptr repl_node = find_replacement_node(x, y, delete_node);
782 throw general_error(
"failed to find a replacement candidate node.");
784 node_quadrant_t repl_quad = delete_node->get_quadrant(repl_node->x, repl_node->y);
786 key_range_type xrange(delete_node->x, repl_node->x);
787 key_range_type yrange(delete_node->y, repl_node->y);
788 ensure_order(xrange);
789 ensure_order(yrange);
790 reinsert_tree_array_type insert_list;
798 adjust_quad(xrange, yrange, delete_node->northwest, dir_south, insert_list);
799 adjust_quad(xrange, yrange, delete_node->southeast, dir_west, insert_list);
800 set_new_root(xrange, yrange, delete_node->northeast, quad_southwest, insert_list);
803 adjust_quad(xrange, yrange, delete_node->northeast, dir_south, insert_list);
804 adjust_quad(xrange, yrange, delete_node->southwest, dir_east, insert_list);
805 set_new_root(xrange, yrange, delete_node->northwest, quad_southeast, insert_list);
808 adjust_quad(xrange, yrange, delete_node->northeast, dir_west, insert_list);
809 adjust_quad(xrange, yrange, delete_node->southwest, dir_north, insert_list);
810 set_new_root(xrange, yrange, delete_node->southeast, quad_northwest, insert_list);
813 adjust_quad(xrange, yrange, delete_node->northwest, dir_east, insert_list);
814 adjust_quad(xrange, yrange, delete_node->southeast, dir_north, insert_list);
815 set_new_root(xrange, yrange, delete_node->southwest, quad_northeast, insert_list);
818 throw general_error(
"quadrant for the replacement node is unspecified.");
828 node_ptr root = repl_node->northwest;
829 repl_node->northwest.reset();
830 reinsert_tree(delete_node, quad_northwest, root);
832 root = repl_node->southeast;
833 repl_node->southeast.reset();
834 reinsert_tree(delete_node, quad_southeast, root);
840 node_ptr root = repl_node->northeast;
841 repl_node->northeast.reset();
842 reinsert_tree(delete_node, quad_northeast, root);
844 root = repl_node->southwest;
845 repl_node->southwest.reset();
846 reinsert_tree(delete_node, quad_southwest, root);
850 throw general_error(
"quadrant for the replacement node is unspecified.");
854 delete_node->x = repl_node->x;
855 delete_node->y = repl_node->y;
856 delete_node->data = repl_node->data;
859 delete_node->parent = repl_node->parent;
860 repl_node->parent.reset();
865 delete_node->northeast = repl_node->northeast;
866 repl_node->northeast.reset();
869 delete_node->northwest = repl_node->northwest;
870 repl_node->northwest.reset();
873 delete_node->southeast = repl_node->southeast;
874 repl_node->southeast.reset();
877 delete_node->southwest = repl_node->southwest;
878 repl_node->southwest.reset();
881 throw general_error(
"quadrant for the replacement node is unspecified.");
886 typename reinsert_tree_array_type::iterator itr = insert_list.begin(), itr_end = insert_list.end();
887 for (; itr != itr_end; ++itr)
888 reinsert_tree(delete_node, *itr);
891template<
typename _Key,
typename _Value>
894 m_root.swap(r.m_root);
895 ::std::swap(m_xrange, r.m_xrange);
896 ::std::swap(m_yrange, r.m_yrange);
899template<
typename _Key,
typename _Value>
905template<
typename _Key,
typename _Value>
908 return (m_root.get() ==
nullptr);
911template<
typename _Key,
typename _Value>
914 size_t node_count = 0;
915 count_all_nodes(m_root.get(), node_count);
919template<
typename _Key,
typename _Value>
925template<
typename _Key,
typename _Value>
928 m_xrange = key_range_type(0, 0);
929 m_yrange = key_range_type(0, 0);
935template<
typename _Key,
typename _Value>
936bool point_quad_tree<_Key, _Value>::operator==(
const point_quad_tree& r)
const
938 ::std::vector<node_data> v1, v2;
939 get_all_stored_data(v1);
940 r.get_all_stored_data(v2);
941 return equals(v1, v2);
944template<
typename _Key,
typename _Value>
945void point_quad_tree<_Key, _Value>::dump_tree_svg(const ::std::string& fpath)
const
948 ofstream file(fpath.c_str());
949 file <<
"<svg width=\"60cm\" height=\"60cm\" viewBox=\"-2 -2 202 202\" xmlns=\"http://www.w3.org/2000/svg\" "
953 <<
" <marker id=\"Triangle\""
954 <<
" viewBox=\"0 0 10 10\" refX=\"10\" refY=\"5\" "
955 <<
" markerUnits=\"strokeWidth\""
956 <<
" markerWidth=\"9\" markerHeight=\"6\""
957 <<
" orient=\"auto\">"
958 <<
" <path d=\"M 0 0 L 10 5 L 0 10 z\" />"
960 <<
"</defs>" << endl;
962 file <<
"<path d=\"M 0 0 L 0 " << m_yrange.second + 1
963 <<
"\" stroke=\"blue\" stroke-width=\"0.2\" marker-end=\"url(#Triangle)\"/>" << endl;
964 file <<
"<path d=\"M 0 0 L " << m_xrange.second + 1
965 <<
" 0\" stroke=\"blue\" stroke-width=\"0.2\" marker-end=\"url(#Triangle)\"/>" << endl;
966 dump_node_svg(m_root.get(), file);
967 file <<
"</svg>" << endl;
970template<
typename _NodePtr>
971void draw_svg_arrow(::std::ofstream& file,
const _NodePtr start,
const _NodePtr end)
974 file <<
"<g stroke=\"red\" marker-end=\"url(#Triangle)\">" << endl;
975 file <<
"<line x1=\"" << start->x <<
"\" y1=\"" << start->y <<
"\" x2=\"" << end->x <<
"\" y2=\"" << end->y
976 <<
"\" stroke-width=\"0.2\"/>" << endl;
977 file <<
"</g>" << endl;
980template<
typename _Key,
typename _Value>
981void point_quad_tree<_Key, _Value>::dump_node_svg(
const node* p, ::std::ofstream& file)
const
988 file <<
"<circle cx=\"" << p->x <<
"\" cy=\"" << p->y <<
"\" r=\"0.1\""
989 <<
" fill=\"black\" stroke=\"black\"/>" << endl;
990 file <<
"<text x=\"" << p->x + 1 <<
"\" y=\"" << p->y + 2 <<
"\" font-size=\"1.2\" fill=\"black\">" << *p->data
991 <<
" (" << p->x <<
"," << p->y <<
")</text>" << endl;
994 draw_svg_arrow<const node*>(file, p, p->northwest.get());
997 draw_svg_arrow<const node*>(file, p, p->northeast.get());
1000 draw_svg_arrow<const node*>(file, p, p->southwest.get());
1003 draw_svg_arrow<const node*>(file, p, p->southeast.get());
1005 dump_node_svg(p->northeast.get(), file);
1006 dump_node_svg(p->northwest.get(), file);
1007 dump_node_svg(p->southeast.get(), file);
1008 dump_node_svg(p->southwest.get(), file);
1011template<
typename _Key,
typename _Value>
1012bool point_quad_tree<_Key, _Value>::equals(::std::vector<node_data>& v1, ::std::vector<node_data>& v2)
1014 using namespace std;
1016 if (v1.size() != v2.size())
1019 sort(v1.begin(), v1.end(),
typename node_data::sorter());
1020 sort(v2.begin(), v2.end(),
typename node_data::sorter());
1022 typename vector<node_data>::const_iterator itr1 = v1.begin(), itr1_end = v1.end(), itr2 = v2.begin(),
1023 itr2_end = v2.end();
1025 for (; itr1 != itr1_end; ++itr1, ++itr2)
1027 if (itr2 == itr2_end)
1033 if (itr2 != itr2_end)
1039template<
typename _Key,
typename _Value>
1040void point_quad_tree<_Key, _Value>::get_all_stored_data(::std::vector<node_data>& stored_data)
const
1042 stored_data.clear();
1046 get_all_stored_data(m_root.get(), stored_data);
1049template<
typename _Key,
typename _Value>
1050void point_quad_tree<_Key, _Value>::count_all_nodes(
const node* p,
size_t& node_count)
const
1057 count_all_nodes(p->northeast.get(), node_count);
1058 count_all_nodes(p->northwest.get(), node_count);
1059 count_all_nodes(p->southeast.get(), node_count);
1060 count_all_nodes(p->southwest.get(), node_count);
1063template<
typename _Key,
typename _Value>
1064void point_quad_tree<_Key, _Value>::insert_data_from(
const point_quad_tree& r)
1066 using namespace std;
1067 vector<node_data> all_data;
1068 r.get_all_stored_data(all_data);
1069 for_each(all_data.begin(), all_data.end(), data_inserter(*
this));
1072template<
typename _Key,
typename _Value>
1073bool point_quad_tree<_Key, _Value>::verify_data(::std::vector<node_data>& expected)
const
1075 ::std::vector<node_data> stored;
1076 get_all_stored_data(stored);
1077 return equals(stored, expected);
1080template<
typename _Key,
typename _Value>
1081bool point_quad_tree<_Key, _Value>::verify_node_iterator(
const node_access& nac)
const
1083 return verify_node_iterator(nac, m_root.get());
1086template<
typename _Key,
typename _Value>
1087bool point_quad_tree<_Key, _Value>::verify_node_iterator(
const node_access& nac,
const node* p)
1090 return (p ==
nullptr);
1095 if (!verify_node_iterator(nac.northeast(), p->northeast.get()))
1097 if (!verify_node_iterator(nac.northwest(), p->northwest.get()))
1099 if (!verify_node_iterator(nac.southeast(), p->southeast.get()))
1101 if (!verify_node_iterator(nac.southwest(), p->southwest.get()))
1107template<
typename _Key,
typename _Value>
1108void point_quad_tree<_Key, _Value>::get_all_stored_data(
const node* p, ::std::vector<node_data>& stored_data)
const
1113 stored_data.push_back(node_data(p->x, p->y, p->data));
1115 get_all_stored_data(p->northeast.get(), stored_data);
1116 get_all_stored_data(p->northwest.get(), stored_data);
1117 get_all_stored_data(p->southeast.get(), stored_data);
1118 get_all_stored_data(p->southwest.get(), stored_data);
1121template<
typename _Key,
typename _Value>
1122typename point_quad_tree<_Key, _Value>::node_ptr point_quad_tree<_Key, _Value>::find_node(key_type x, key_type y)
const
1124 node_ptr cur_node = m_root;
1127 if (cur_node->x == x && cur_node->y == y)
1133 node_quadrant_t quad = cur_node->get_quadrant(x, y);
1136 case quad_northeast:
1137 if (!cur_node->northeast)
1139 cur_node = cur_node->northeast;
1141 case quad_northwest:
1142 if (!cur_node->northwest)
1144 cur_node = cur_node->northwest;
1146 case quad_southeast:
1147 if (!cur_node->southeast)
1149 cur_node = cur_node->southeast;
1151 case quad_southwest:
1152 if (!cur_node->southwest)
1154 cur_node = cur_node->southwest;
1157 throw general_error(
"unknown quadrant");
1163template<
typename _Key,
typename _Value>
1164const typename point_quad_tree<_Key, _Value>::node* point_quad_tree<_Key, _Value>::find_node_ptr(
1165 key_type x, key_type y)
const
1167 const node* cur_node = m_root.get();
1170 if (cur_node->x == x && cur_node->y == y)
1176 node_quadrant_t quad = cur_node->get_quadrant(x, y);
1179 case quad_northeast:
1180 if (!cur_node->northeast)
1182 cur_node = cur_node->northeast.get();
1184 case quad_northwest:
1185 if (!cur_node->northwest)
1187 cur_node = cur_node->northwest.get();
1189 case quad_southeast:
1190 if (!cur_node->southeast)
1192 cur_node = cur_node->southeast.get();
1194 case quad_southwest:
1195 if (!cur_node->southwest)
1197 cur_node = cur_node->southwest.get();
1200 throw general_error(
"unknown quadrant");
1206template<
typename _Key,
typename _Value>
1207typename point_quad_tree<_Key, _Value>::node_ptr point_quad_tree<_Key, _Value>::find_replacement_node(
1208 key_type x, key_type y,
const node_ptr& delete_node)
const
1210 using namespace std;
1213 node_distance dx_node, dy_node, min_city_block_node;
1215#if DEBUG_POINT_QUAD_TREE
1216 cout <<
"northeast" << endl;
1218 find_candidate_in_quad(x, y, dx_node, dy_node, min_city_block_node, delete_node, quad_northeast);
1220#if DEBUG_POINT_QUAD_TREE
1221 cout <<
"northwest" << endl;
1223 find_candidate_in_quad(x, y, dx_node, dy_node, min_city_block_node, delete_node, quad_northwest);
1225#if DEBUG_POINT_QUAD_TREE
1226 cout <<
"southwest" << endl;
1228 find_candidate_in_quad(x, y, dx_node, dy_node, min_city_block_node, delete_node, quad_southwest);
1230#if DEBUG_POINT_QUAD_TREE
1231 cout <<
"southeast" << endl;
1233 find_candidate_in_quad(x, y, dx_node, dy_node, min_city_block_node, delete_node, quad_southeast);
1237#if DEBUG_POINT_QUAD_TREE
1239 cout <<
"node closest to x axis: " << *dx_node.node->data <<
" (dx=" << dx_node.dist <<
")" << endl;
1242 cout <<
"node closest to y axis: " << *dy_node.node->data <<
" (dy=" << dy_node.dist <<
")" << endl;
1245 if (dx_node.node == dy_node.node && ((dx_node.quad == quad_northwest) || (dx_node.quad == quad_southeast)))
1247#if DEBUG_POINT_QUAD_TREE
1248 cout <<
"node that satisfies Criterion 1: " << *dx_node.node->data << endl;
1250 return dx_node.node;
1254#if DEBUG_POINT_QUAD_TREE
1255 cout <<
"unable to find node that satisfies Criterion 1." << endl;
1261 if (min_city_block_node.node)
1263#if DEBUG_POINT_QUAD_TREE
1264 cout <<
"node that satisfies Criterion 2: " << *min_city_block_node.node->data
1265 <<
" (dist=" << min_city_block_node.dist <<
")" << endl;
1267 return min_city_block_node.node;
1273template<
typename _Key,
typename _Value>
1274void point_quad_tree<_Key, _Value>::find_candidate_in_quad(
1275 key_type x, key_type y, node_distance& dx_node, node_distance& dy_node, node_distance& min_city_block_node,
1276 const node_ptr& delete_node, node_quadrant_t quad)
const
1278 using namespace std;
1280 node_ptr repl_node = delete_node->get_quadrant_node(quad);
1284#if DEBUG_POINT_QUAD_TREE
1285 cout <<
" no candidate in this quadrant" << endl;
1290 node_quadrant_t oppo_quad = opposite(quad);
1291 while (repl_node->has_quadrant_node(oppo_quad))
1292 repl_node = repl_node->get_quadrant_node(oppo_quad);
1294#if DEBUG_POINT_QUAD_TREE
1295 cout <<
" candidate: " << repl_node->x <<
"," << repl_node->y <<
" (" << *repl_node->data <<
")" << endl;
1299 key_type dx = repl_node->x > x ? repl_node->x - x : x - repl_node->x;
1300 key_type dy = repl_node->y > y ? repl_node->y - y : y - repl_node->y;
1301#if DEBUG_POINT_QUAD_TREE
1302 cout <<
" dx = " << dx <<
", dy = " << dy << endl;
1305 if (!dx_node.node || dx_node.dist > dx)
1306 dx_node = node_distance(quad, dx, repl_node);
1307 if (!dy_node.node || dy_node.dist > dy)
1308 dy_node = node_distance(quad, dy, repl_node);
1310 if (!min_city_block_node.node || min_city_block_node.dist > (dx + dy))
1311 min_city_block_node = node_distance(quad_unspecified, dx + dy, repl_node);
1314template<
typename _Key,
typename _Value>
1315void point_quad_tree<_Key, _Value>::adjust_quad(
1316 const key_range_type& hatched_xrange,
const key_range_type& hatched_yrange, node_ptr quad_root, direction_t dir,
1317 reinsert_tree_array_type& insert_list)
1319 using namespace std;
1324#if DEBUG_POINT_QUAD_TREE
1325 cout <<
"adjust_quad: checking " << *quad_root->data <<
" (" << quad_root->x <<
"," << quad_root->y <<
")" << endl;
1328 if ((hatched_xrange.first <= quad_root->x && quad_root->x <= hatched_xrange.second) ||
1329 (hatched_yrange.first <= quad_root->y && quad_root->y <= hatched_yrange.second))
1331#if DEBUG_POINT_QUAD_TREE
1332 cout <<
" " << *quad_root->data <<
" is in the hatched region" << endl;
1335 disconnect_node_from_parent(quad_root);
1336 quad_root->parent.reset();
1337 insert_list.push_back(quad_root);
1344 adjust_quad(hatched_xrange, hatched_yrange, quad_root->northeast, dir_east, insert_list);
1345 adjust_quad(hatched_xrange, hatched_yrange, quad_root->southeast, dir_east, insert_list);
1348 adjust_quad(hatched_xrange, hatched_yrange, quad_root->northeast, dir_north, insert_list);
1349 adjust_quad(hatched_xrange, hatched_yrange, quad_root->northwest, dir_north, insert_list);
1352 adjust_quad(hatched_xrange, hatched_yrange, quad_root->southeast, dir_south, insert_list);
1353 adjust_quad(hatched_xrange, hatched_yrange, quad_root->southwest, dir_south, insert_list);
1356 adjust_quad(hatched_xrange, hatched_yrange, quad_root->northwest, dir_west, insert_list);
1357 adjust_quad(hatched_xrange, hatched_yrange, quad_root->southwest, dir_west, insert_list);
1363template<
typename _Key,
typename _Value>
1364void point_quad_tree<_Key, _Value>::set_new_root(
1365 const key_range_type& hatched_xrange,
const key_range_type& hatched_yrange, node_ptr& quad_root,
1366 node_quadrant_t dir, reinsert_tree_array_type& insert_list)
1368 node_ptr cur_node = quad_root;
1373 case quad_northeast:
1374 adjust_quad(hatched_xrange, hatched_yrange, cur_node->southeast, dir_east, insert_list);
1375 adjust_quad(hatched_xrange, hatched_yrange, cur_node->northwest, dir_north, insert_list);
1377 case quad_northwest:
1378 adjust_quad(hatched_xrange, hatched_yrange, cur_node->northeast, dir_north, insert_list);
1379 adjust_quad(hatched_xrange, hatched_yrange, cur_node->southwest, dir_west, insert_list);
1381 case quad_southeast:
1382 adjust_quad(hatched_xrange, hatched_yrange, cur_node->northeast, dir_east, insert_list);
1383 adjust_quad(hatched_xrange, hatched_yrange, cur_node->southwest, dir_south, insert_list);
1385 case quad_southwest:
1386 adjust_quad(hatched_xrange, hatched_yrange, cur_node->northwest, dir_west, insert_list);
1387 adjust_quad(hatched_xrange, hatched_yrange, cur_node->southeast, dir_south, insert_list);
1390 throw general_error(
"unspecified quadrant");
1392 cur_node = cur_node->get_quadrant_node(dir);
1396template<
typename _Key,
typename _Value>
1397void point_quad_tree<_Key, _Value>::insert_node(node_ptr& dest, node_ptr& this_node)
1399 node_ptr cur_node = dest;
1402 if (cur_node->x == this_node->x && cur_node->y == this_node->y)
1407 throw general_error(
"node with identical position encountered.");
1410 node_quadrant_t quad = cur_node->get_quadrant(this_node->x, this_node->y);
1413 case quad_northeast:
1414 if (cur_node->northeast)
1415 cur_node = cur_node->northeast;
1418 cur_node->northeast = this_node;
1419 this_node->parent = cur_node;
1423 case quad_northwest:
1424 if (cur_node->northwest)
1425 cur_node = cur_node->northwest;
1428 cur_node->northwest = this_node;
1429 this_node->parent = cur_node;
1433 case quad_southeast:
1434 if (cur_node->southeast)
1435 cur_node = cur_node->southeast;
1438 cur_node->southeast = this_node;
1439 this_node->parent = cur_node;
1443 case quad_southwest:
1444 if (cur_node->southwest)
1445 cur_node = cur_node->southwest;
1448 cur_node->southwest = this_node;
1449 this_node->parent = cur_node;
1454 throw general_error(
"unknown quadrant");
1457 assert(!
"This should never be reached.");
1460template<
typename _Key,
typename _Value>
1461void point_quad_tree<_Key, _Value>::reinsert_tree(node_ptr& dest, node_ptr& root)
1469 if (root->northeast)
1471 reinsert_tree(dest, root->northeast);
1472 root->northeast.reset();
1474 if (root->northwest)
1476 reinsert_tree(dest, root->northwest);
1477 root->northwest.reset();
1479 if (root->southeast)
1481 reinsert_tree(dest, root->southeast);
1482 root->southeast.reset();
1484 if (root->southwest)
1486 reinsert_tree(dest, root->southwest);
1487 root->southwest.reset();
1490 root->parent.reset();
1491 insert_node(dest, root);
1494template<
typename _Key,
typename _Value>
1495void point_quad_tree<_Key, _Value>::reinsert_tree(node_ptr& dest, node_quadrant_t quad, node_ptr& root)
1503 case quad_northeast:
1504 if (dest->northeast)
1505 reinsert_tree(dest->northeast, root);
1508 dest->northeast = root;
1509 root->parent = dest;
1512 case quad_northwest:
1513 if (dest->northwest)
1514 reinsert_tree(dest->northwest, root);
1517 dest->northwest = root;
1518 root->parent = dest;
1521 case quad_southeast:
1522 if (dest->southeast)
1523 reinsert_tree(dest->southeast, root);
1526 dest->southeast = root;
1527 root->parent = dest;
1530 case quad_southwest:
1531 if (dest->southwest)
1532 reinsert_tree(dest->southwest, root);
1535 dest->southwest = root;
1536 root->parent = dest;
1540 throw general_error(
"reinsert_tree: quadrant unspecified");
1544template<
typename _Key,
typename _Value>
1545void point_quad_tree<_Key, _Value>::clear_all_nodes()
1547 ::mdds::disconnect_all_nodes(m_root);
Definition point_quad_tree.hpp:93
Definition point_quad_tree.hpp:134
Definition point_quad_tree.hpp:209
Definition point_quad_tree.hpp:201
search_results search_region(key_type x1, key_type y1, key_type x2, key_type y2) const
Definition point_quad_tree.hpp:730
void insert(key_type x, key_type y, value_type data)
Definition point_quad_tree.hpp:645
void swap(point_quad_tree &r)
Definition point_quad_tree.hpp:892
bool empty() const
Definition point_quad_tree.hpp:906
size_t size() const
Definition point_quad_tree.hpp:912
void search_region(key_type x1, key_type y1, key_type x2, key_type y2, data_array_type &result) const
Definition point_quad_tree.hpp:720
void clear()
Definition point_quad_tree.hpp:900
void remove(key_type x, key_type y)
Definition point_quad_tree.hpp:751
node_access get_node_access() const
Definition point_quad_tree.hpp:920
value_type find(key_type x, key_type y) const
Definition point_quad_tree.hpp:742
Definition point_quad_tree.hpp:513
Definition quad_node.hpp:94
quad_node_base & operator=(const quad_node_base &r)
Definition quad_node.hpp:145