Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r69057 - in sandbox-branches/geometry/index_080_nhch: boost/geometry/extensions/index/rtree tests
From: adam.wulkiewicz_at_[hidden]
Date: 2011-02-19 09:23:39


Author: awulkiew
Date: 2011-02-19 09:23:37 EST (Sat, 19 Feb 2011)
New Revision: 69057
URL: http://svn.boost.org/trac/boost/changeset/69057

Log:
experimental nodes structure
Added:
   sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree_internal_node.hpp (contents, props changed)
Text files modified:
   sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree.hpp | 26 +-
   sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree_leaf.hpp | 176 ++++++++-------
   sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree_node.hpp | 421 +++++++++++----------------------------
   sandbox-branches/geometry/index_080_nhch/tests/rtree_native.cpp | 2
   4 files changed, 228 insertions(+), 397 deletions(-)

Modified: sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree.hpp
==============================================================================
--- sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree.hpp (original)
+++ sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree.hpp 2011-02-19 09:23:37 EST (Sat, 19 Feb 2011)
@@ -21,7 +21,7 @@
 
 #include <boost/geometry/algorithms/area.hpp>
 
-#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
+#include <boost/geometry/extensions/index/rtree/rtree_internal_node.hpp>
 #include <boost/geometry/extensions/index/rtree/rtree_leaf.hpp>
 
 // awulkiew - added
@@ -43,8 +43,10 @@
     // awulkiew - typedefs added
     typedef rtree_node<Value, Translator, Box> rtree_node;
     typedef rtree_leaf<Value, Translator, Box> rtree_leaf;
+ typedef rtree_internal_node<Value, Translator, Box> rtree_internal_node;
 
     typedef boost::shared_ptr<rtree_node> node_pointer;
+ typedef boost::shared_ptr<rtree_internal_node> internal_node_pointer;
     typedef boost::shared_ptr<rtree_leaf> leaf_pointer;
 
     /**
@@ -54,7 +56,7 @@
         : m_count(0)
         , m_min_elems_per_node(minimum)
         , m_max_elems_per_node(maximum)
- , m_root(new rtree_node(node_pointer(), 1))
+ , m_root(new rtree_internal_node(node_pointer(), 1))
         // awulkiew - added
         , m_translator(tr)
     {
@@ -106,11 +108,11 @@
                 leaf->get_parent()->remove_in(leaf->get_parent()->get_box(leaf), m_translator);
             }
 
- typename rtree_node::node_map q_nodes;
+ typename rtree_internal_node::node_map q_nodes;
             condense_tree(leaf, q_nodes);
 
             std::vector<Value> s;
- for (typename rtree_node::node_map::const_iterator it = q_nodes.begin();
+ for (typename rtree_internal_node::node_map::const_iterator it = q_nodes.begin();
                  it != q_nodes.end(); ++it)
             {
                 typename rtree_leaf::leaf_map leaves = it->second->get_leaves();
@@ -208,11 +210,11 @@
                 leaf->get_parent()->remove_in(leaf->get_parent()->get_box(leaf), m_translator);
             }
 
- typename rtree_node::node_map q_nodes;
+ typename rtree_internal_node::node_map q_nodes;
             condense_tree(leaf, q_nodes);
 
             std::vector<Value> s;
- for (typename rtree_node::node_map::const_iterator it = q_nodes.begin();
+ for (typename rtree_internal_node::node_map::const_iterator it = q_nodes.begin();
                  it != q_nodes.end(); ++it)
             {
                 typename rtree_leaf::leaf_map leaves = it->second->get_leaves();
@@ -352,7 +354,7 @@
      * \brief Reorganize the tree after a removal. It tries to
      * join nodes with less elements than m.
      */
- void condense_tree(node_pointer const& leaf, typename rtree_node::node_map& q_nodes)
+ void condense_tree(node_pointer const& leaf, typename rtree_internal_node::node_map& q_nodes)
     {
         if (leaf.get() == m_root.get())
         {
@@ -372,8 +374,8 @@
             }
 
             // get the nodes that we should reinsert
- typename rtree_node::node_map this_nodes = parent->get_nodes();
- for(typename rtree_node::node_map::const_iterator it = this_nodes.begin();
+ typename rtree_internal_node::node_map this_nodes = parent->get_nodes();
+ for(typename rtree_internal_node::node_map::const_iterator it = this_nodes.begin();
                 it != this_nodes.end(); ++it)
             {
                 q_nodes.push_back(*it);
@@ -413,7 +415,7 @@
         // check if we are in the root and do the split
         if (leaf.get() == m_root.get())
         {
- node_pointer new_root(new rtree_node(node_pointer(), leaf->get_level() + 1));
+ node_pointer new_root(new rtree_internal_node(node_pointer(), leaf->get_level() + 1));
             new_root->add_node(n1->compute_box(m_translator), n1);
             new_root->add_node(n2->compute_box(m_translator), n2);
 
@@ -435,8 +437,8 @@
         // if parent is full, split and readjust
         if (parent->elements() > m_max_elems_per_node)
         {
- node_pointer p1(new rtree_node(parent->get_parent(), parent->get_level()));
- node_pointer p2(new rtree_node(parent->get_parent(), parent->get_level()));
+ node_pointer p1(new rtree_internal_node(parent->get_parent(), parent->get_level()));
+ node_pointer p2(new rtree_internal_node(parent->get_parent(), parent->get_level()));
 
             split_node(parent, p1, p2);
             adjust_tree(parent, p1, p2);

Added: sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree_internal_node.hpp
==============================================================================
--- (empty file)
+++ sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree_internal_node.hpp 2011-02-19 09:23:37 EST (Sat, 19 Feb 2011)
@@ -0,0 +1,432 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Boost.SpatialIndex - rtree node implementation
+//
+// Copyright 2008 Federico J. Fernandez.
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_INTERNAL_NODE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_INTERNAL_NODE_HPP
+
+#include <deque>
+#include <iostream> // TODO: Remove if print() is removed
+#include <stdexcept>
+#include <utility>
+#include <vector>
+
+#include <boost/shared_ptr.hpp>
+
+#include <boost/geometry/algorithms/area.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/combine.hpp>
+#include <boost/geometry/algorithms/equals.hpp>
+
+#include <boost/geometry/extensions/index/rtree/helpers.hpp>
+#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
+
+namespace boost { namespace geometry { namespace index {
+
+template <typename Value, typename Translator, typename Box>
+class rtree_internal_node : public rtree_node<Value, Translator, Box>
+{
+public:
+
+ typedef rtree_node<Value, Translator, Box> rtree_node;
+ typedef rtree_leaf<Value, Translator, Box> rtree_leaf;
+
+ typedef boost::shared_ptr<rtree_node> node_pointer;
+ typedef boost::shared_ptr<rtree_leaf> leaf_pointer;
+
+ /// type for the node map
+ typedef std::vector<std::pair<Box, node_pointer > > node_map;
+
+ /**
+ * \brief Creates a default node (needed for the containers)
+ */
+ rtree_internal_node()
+ {
+ }
+
+ /**
+ * \brief Creates a node with 'parent' as parent and 'level' as its level
+ */
+ rtree_internal_node(node_pointer const& parent, size_t const& level)
+ : rtree_node(parent, level)
+ {
+ }
+
+ // awulkiew - internal node methods
+
+ /**
+ * \brief Clear the node
+ */
+ // awulkiew - name changed from empty_nodes to clear_nodes
+ void clear_nodes()
+ {
+ m_nodes.clear();
+ }
+
+ // awulkiew - internal node and leaf virtual methods
+
+ /**
+ * \brief True if it is a leaf node
+ */
+ virtual bool is_leaf() const
+ {
+ return false;
+ }
+
+ /**
+ * \brief Number of elements in the subtree
+ */
+ virtual size_t elements() const
+ {
+ return m_nodes.size();
+ }
+
+ /**
+ * \brief Search for elements in 'box' in the Rtree. Add them to 'result'.
+ * If exact_match is true only return the elements having as
+ * key the box 'box'. Otherwise return everything inside 'box'.
+ */
+ // awulkiew - exact match case removed
+ virtual void find(Box const& box, std::deque<Value>& result, Translator const& tr)
+ {
+ for (typename node_map::const_iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ // awulkiew - is_overlapping changed to geometry::intersects
+ if (geometry::intersects(it->first, box))
+ {
+ it->second->find(box, result, tr);
+ }
+ }
+ }
+
+ /**
+ * \brief Compute bounding box for this node
+ */
+ virtual Box compute_box(Translator const&) const
+ {
+ if (m_nodes.empty())
+ {
+ return Box();
+ }
+
+ Box result;
+ geometry::assign_inverse(result);
+ for(typename node_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
+ {
+ geometry::combine(result, it->first);
+ }
+
+ return result;
+ }
+
+ /**
+ * \brief Get leaves for a node
+ */
+ virtual std::vector<Value> get_leaves() const
+ {
+ typedef std::vector<Value> leaf_type;
+ leaf_type leaf;
+
+ for (typename node_map::const_iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ leaf_type this_leaves = it->second->get_leaves();
+
+ for (typename leaf_type::iterator it_leaf = this_leaves.begin();
+ it_leaf != this_leaves.end(); ++it_leaf)
+ {
+ leaf.push_back(*it_leaf);
+ }
+ }
+
+ return leaf;
+ }
+
+ /**
+ * \brief Remove elements inside the 'box'
+ */
+ // awulkiew - name changed to avoid ambiguity (Value may be of type Box)
+ virtual void remove_in(Box const& box, Translator const&)
+ {
+ for (typename node_map::iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ if (geometry::equals(it->first, box))
+ {
+ m_nodes.erase(it);
+ return;
+ }
+ }
+ }
+
+ /**
+ * \brief Get the envelopes of a node
+ */
+ virtual std::vector<Box> get_boxes(Translator const&) const
+ {
+ std::vector<Box> result;
+ for(typename node_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
+ {
+ result.push_back(it->first);
+ }
+ return result;
+ }
+
+ /**
+ * \brief Print Rtree subtree (mainly for debug)
+ */
+ virtual void print(Translator const& tr) const
+ {
+ std::cerr << " --> Node --------" << std::endl;
+ std::cerr << " Address: " << this << std::endl;
+ std::cerr << " Level: " << this->get_level() << std::endl;
+ std::cerr << " Size: " << m_nodes.size() << std::endl;
+ std::cerr << " | ";
+ for(typename node_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
+ {
+ if (this != it->second->get_parent().get())
+ {
+ std::cerr << "ERROR - " << this << " is not " << it->second->get_parent().get() << " ";
+ }
+
+ std::cerr << "( " << geometry::get<min_corner, 0>(it->first) << " , "
+ << geometry::get<min_corner, 1>(it->first) << " ) x ";
+ std::cerr << "( " << geometry::get<max_corner, 0>(it->first) << " , "
+ << geometry::get<max_corner, 1>(it->first) << " )";
+ std::cerr << " | ";
+ }
+ std::cerr << std::endl;
+ std::cerr << " --< Node --------" << std::endl;
+
+ // print child nodes
+ std::cerr << " Children: " << std::endl;
+ for (typename node_map::const_iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ it->second->print(tr);
+ }
+ }
+
+ // awulkiew - internal node only virtual methods
+
+ /**
+ * \brief Add a child to this node
+ */
+ virtual void add_node(Box const& box, node_pointer const& node)
+ {
+ m_nodes.push_back(std::make_pair(box, node));
+ node->update_parent(node);
+ }
+
+ /**
+ * \brief Project first element, to replace root in case of condensing
+ */
+ virtual node_pointer first_element() const
+ {
+ if (0 == m_nodes.size())
+ {
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("first_element in empty node");
+ }
+ return m_nodes.begin()->second;
+ }
+
+ /**
+ * \brief Proyector for the 'i' node
+ */
+ virtual node_pointer get_node(size_t index)
+ {
+ return m_nodes[index].second;
+ }
+
+ /**
+ * \brief Return in 'result' all the leaves inside 'box'
+ */
+ virtual void find_leaves(Box const& box, typename std::vector<node_pointer>& result) const
+ {
+ for (typename node_map::const_iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ // awulkiew - is_overlapping changed to geometry::intersects
+ if (geometry::intersects(it->first, box))
+ {
+ if (it->second->is_leaf())
+ {
+ result.push_back(it->second);
+ }
+ else
+ {
+ it->second->find_leaves(box, result);
+ }
+ }
+ }
+ }
+
+ /**
+ * \brief Recompute the bounding box
+ */
+ virtual void adjust_box(node_pointer const& node, Translator const& tr)
+ {
+ unsigned int index = 0;
+ for (typename node_map::iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it, index++)
+ {
+ if (it->second.get() == node.get())
+ {
+ m_nodes[index] = std::make_pair(node->compute_box(tr), node);
+ return;
+ }
+ }
+ }
+
+ /**
+ * \brief Replace the node in the m_nodes vector and recompute the box
+ */
+ virtual void replace_node(node_pointer const& leaf, node_pointer& new_leaf, Translator const& tr)
+ {
+ unsigned int index = 0;
+ for(typename node_map::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it, index++)
+ {
+ if (it->second.get() == leaf.get())
+ {
+ m_nodes[index] = std::make_pair(new_leaf->compute_box(tr), new_leaf);
+ new_leaf->update_parent(new_leaf);
+ return;
+ }
+ }
+
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("Node not found.");
+ }
+
+ /**
+ * \brief Add a child leaf to this node
+ */
+ virtual void add_leaf_node(Box const& box, leaf_pointer const& leaf)
+ {
+ m_nodes.push_back(std::make_pair(box, leaf));
+ }
+
+ /**
+ * \brief Choose a node suitable for adding 'box'
+ */
+ virtual node_pointer choose_node(Box const& box)
+ {
+ if (m_nodes.size() == 0)
+ {
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("Empty node trying to choose the least enlargement node.");
+ }
+
+ // awulkiew - areas types changed
+ typedef typename area_result<Box>::type area_type;
+
+ bool first = true;
+ area_type min_area = 0;
+ area_type min_diff_area = 0;
+ node_pointer chosen_node;
+
+ // check for the least enlargement
+ for (typename node_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
+ {
+ // awulkiew - areas types changed
+ area_type const diff_area = compute_union_area(box, it->first) - geometry::area(it->first);
+
+ if (first)
+ {
+ // it's the first time, we keep the first
+ min_diff_area = diff_area;
+ min_area = geometry::area(it->first);
+ chosen_node = it->second;
+
+ first = false;
+ }
+ else
+ {
+ if (diff_area < min_diff_area)
+ {
+ min_diff_area = diff_area;
+ min_area = geometry::area(it->first);
+ chosen_node = it->second;
+ }
+ else
+ {
+ if (diff_area == min_diff_area)
+ {
+ if (geometry::area(it->first) < min_area)
+ {
+ min_diff_area = diff_area;
+ min_area = geometry::area(it->first);
+ chosen_node = it->second;
+ }
+ }
+ }
+ }
+ }
+
+ return chosen_node;
+ }
+
+ /**
+ * \brief Update the parent of all the childs
+ */
+ virtual void update_parent(node_pointer const& node)
+ {
+ for (typename node_map::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
+ {
+ it->second->set_parent(node);
+ }
+ }
+
+ /**
+ * \brief Box projector for node pointed by 'leaf'
+ */
+ virtual Box get_box(node_pointer const& leaf) const
+ {
+ for (typename node_map::const_iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ if (it->second.get() == leaf.get())
+ {
+ return it->first;
+ }
+ }
+
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("Node not found");
+ }
+
+ /**
+ * \brief Children projector
+ */
+ virtual node_map get_nodes() const
+ {
+ return m_nodes;
+ }
+
+ // awulkiew - unclassified methods
+
+ /**
+ * \brief Box projector for node 'index'
+ */
+ // awulkiew - commented, not used
+ /*virtual Box get_box(unsigned int index, Translator const& tr) const
+ {
+ return m_nodes[index].first;
+ }*/
+
+private:
+
+ /// child nodes
+ node_map m_nodes;
+};
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_INTERNAL_NODE_HPP

Modified: sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree_leaf.hpp
==============================================================================
--- sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree_leaf.hpp (original)
+++ sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree_leaf.hpp 2011-02-19 09:23:37 EST (Sat, 19 Feb 2011)
@@ -23,6 +23,7 @@
 #include <boost/geometry/algorithms/combine.hpp>
 #include <boost/geometry/algorithms/intersects.hpp>
 
+#include <boost/geometry/extensions/index/rtree/helpers.hpp>
 #include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
 
 namespace boost { namespace geometry { namespace index
@@ -36,8 +37,9 @@
     // awulkiew - typedef added
     typedef rtree_node<Value, Translator, Box> rtree_node;
 
- /// container type for the leaves
     typedef boost::shared_ptr<rtree_node> node_pointer;
+
+ /// container type for the leaves
     typedef std::vector<Value> leaf_map;
 
     /**
@@ -55,6 +57,35 @@
     {
     }
 
+ // awulkiew - leaf methods
+
+ /**
+ * \brief Clear the node
+ */
+ // awulkiew - name changed from empty_nodes to clear_values
+ void clear_values()
+ {
+ m_nodes.clear();
+ }
+
+ // awulkiew - internal node and leaf virtual methods
+
+ /**
+ * \brief True if we are a leaf
+ */
+ virtual bool is_leaf() const
+ {
+ return true;
+ }
+
+ /**
+ * \brief Number of elements in the tree
+ */
+ virtual size_t elements() const
+ {
+ return m_nodes.size();
+ }
+
     /**
      * \brief Search for elements in 'box' in the Rtree. Add them to 'result'.
      * If exact_match is true only return the elements having as
@@ -107,30 +138,6 @@
     }
 
     /**
- * \brief True if we are a leaf
- */
- virtual bool is_leaf() const
- {
- return true;
- }
-
- /**
- * \brief Number of elements in the tree
- */
- virtual unsigned int elements() const
- {
- return m_nodes.size();
- }
-
- /**
- * \brief Insert a new element, with key 'box' and value 'v'
- */
- virtual void insert(Value const& v)
- {
- m_nodes.push_back(v);
- }
-
- /**
      * \brief Proyect leaves of this node.
      */
     virtual std::vector<Value> get_leaves() const
@@ -139,44 +146,6 @@
     }
 
     /**
- * \brief Add a new child (node) to this node
- */
- virtual void add_node(Box const&, node_pointer const&)
- {
- // TODO: mloskot - define & use GGL exception
- throw std::logic_error("Can't add node to leaf node.");
- }
-
- /**
- * \brief Add a new leaf to this node
- */
- virtual void add_value(Value const& v)
- {
- m_nodes.push_back(v);
- }
-
- /**
- * \brief Proyect value in position 'index' in the nodes container
- */
- virtual Value get_value(unsigned int index) const
- {
- return m_nodes[index];
- }
-
- /**
- * \brief Box projector for leaf
- */
- // awulkiew - commented, not used
- //virtual Box get_box(unsigned int index, Translator const& tr) const
- //{
- // // TODO: awulkiew - get_bounding_object - add object specific behaviour
- // // or just base on get_value
- // Box box;
- // detail::convert_to_box(tr(m_nodes[index]), box);
- // return box;
- //}
-
- /**
      * \brief Remove value with key 'box' in this leaf
      */
     // awulkiew - name changed to avoid ambiguity (Value may be of type Box)
@@ -201,26 +170,6 @@
     }
 
     /**
- * \brief Remove value in this leaf
- */
- virtual void remove(Value const& v, Translator const& tr)
- {
- for (typename leaf_map::iterator it = m_nodes.begin();
- it != m_nodes.end(); ++it)
- {
- // awulkiew - use of translator
- if ( tr.equals(*it, v) )
- {
- m_nodes.erase(it);
- return;
- }
- }
-
- // TODO: mloskot - use GGL exception
- throw std::logic_error("Node not found.");
- }
-
- /**
     * \brief Proyect boxes from this node
     */
     virtual std::vector<Box> get_boxes(Translator const& tr) const
@@ -268,6 +217,67 @@
         std::cerr << "\t" << " --< Leaf --------" << std::endl;
     }
 
+ // awulkiew - leaf only virtual methods
+
+ /**
+ * \brief Insert a new element, with key 'box' and value 'v'
+ */
+ virtual void insert(Value const& v)
+ {
+ m_nodes.push_back(v);
+ }
+
+ /**
+ * \brief Add a new leaf to this node
+ */
+ virtual void add_value(Value const& v)
+ {
+ m_nodes.push_back(v);
+ }
+
+ /**
+ * \brief Proyect value in position 'index' in the nodes container
+ */
+ virtual Value get_value(unsigned int index) const
+ {
+ return m_nodes[index];
+ }
+
+ /**
+ * \brief Remove value in this leaf
+ */
+ virtual void remove(Value const& v, Translator const& tr)
+ {
+ for (typename leaf_map::iterator it = m_nodes.begin();
+ it != m_nodes.end(); ++it)
+ {
+ // awulkiew - use of translator
+ if ( tr.equals(*it, v) )
+ {
+ m_nodes.erase(it);
+ return;
+ }
+ }
+
+ // TODO: mloskot - use GGL exception
+ throw std::logic_error("Node not found.");
+ }
+
+ // awulkiew - unclassified methods
+
+ /**
+ * \brief Box projector for leaf
+ */
+ // awulkiew - commented, not used
+ //virtual Box get_box(unsigned int index, Translator const& tr) const
+ //{
+ // // TODO: awulkiew - get_bounding_object - add object specific behaviour
+ // // or just base on get_value
+ // Box box;
+ // detail::convert_to_box(tr(m_nodes[index]), box);
+ // return box;
+ //}
+
 private:
 
     /// leaves of this node

Modified: sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree_node.hpp
==============================================================================
--- sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree_node.hpp (original)
+++ sandbox-branches/geometry/index_080_nhch/boost/geometry/extensions/index/rtree/rtree_node.hpp 2011-02-19 09:23:37 EST (Sat, 19 Feb 2011)
@@ -1,8 +1,8 @@
 // Boost.Geometry (aka GGL, Generic Geometry Library)
 //
-// Boost.SpatialIndex - rtree node implementation
+// Boost.SpatialIndex - rtree node, base class to leafs and internal nodes
 //
-// Copyright 2008 Federico J. Fernandez.
+// Copyright 2011 Adam Wulkiewicz.
 // Use, modification and distribution is subject to the Boost Software License,
 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
@@ -10,28 +10,15 @@
 #ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_NODE_HPP
 #define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RTREE_NODE_HPP
 
-#include <deque>
-#include <iostream> // TODO: Remove if print() is removed
-#include <stdexcept>
-#include <utility>
-#include <vector>
-
-#include <boost/shared_ptr.hpp>
-
-#include <boost/geometry/algorithms/area.hpp>
-#include <boost/geometry/algorithms/assign.hpp>
-#include <boost/geometry/algorithms/combine.hpp>
-#include <boost/geometry/algorithms/equals.hpp>
-
-#include <boost/geometry/extensions/index/rtree/helpers.hpp>
-
 namespace boost { namespace geometry { namespace index {
 
-/// forward declaration
 template <typename Value, typename Translator, typename Box>
 class rtree_leaf;
 
 template <typename Value, typename Translator, typename Box>
+class rtree_internal_node;
+
+template <typename Value, typename Translator, typename Box>
 class rtree_node
 {
 public:
@@ -39,144 +26,102 @@
     typedef boost::shared_ptr<rtree_node<Value, Translator, Box> > node_pointer;
     typedef boost::shared_ptr<rtree_leaf<Value, Translator, Box> > leaf_pointer;
 
- /// type for the node map
     typedef std::vector<std::pair<Box, node_pointer > > node_map;
 
     /**
- * \brief Creates a default node (needed for the containers)
+ * \brief destructor (virtual because we have virtual functions)
      */
- rtree_node()
+ virtual ~rtree_node()
     {
     }
 
+ // awulkiew - node methods
+
     /**
- * \brief Creates a node with 'parent' as parent and 'level' as its level
+ * \brief Projector for parent
      */
- rtree_node(node_pointer const& parent, unsigned int const& level)
- : m_parent(parent), m_level(level)
+ inline node_pointer get_parent() const
     {
+ return m_parent;
     }
 
     /**
- * \brief destructor (virtual because we have virtual functions)
+ * \brief Set parent
      */
- virtual ~rtree_node()
+ void set_parent(node_pointer const& node)
     {
+ m_parent = node;
     }
 
     /**
      * \brief Level projector
      */
- virtual unsigned int get_level() const
+ size_t get_level() const
     {
         return m_level;
     }
 
- /**
- * \brief Number of elements in the subtree
- */
- virtual unsigned int elements() const
- {
- return m_nodes.size();
- }
-
- /**
- * \brief Project first element, to replace root in case of condensing
- */
- inline node_pointer first_element() const
- {
- if (0 == m_nodes.size())
- {
- // TODO: mloskot - define & use GGL exception
- throw std::logic_error("first_element in empty node");
- }
- return m_nodes.begin()->second;
- }
+ // awulkiew - internal node and leaf virtual methods
 
     /**
      * \brief True if it is a leaf node
      */
     virtual bool is_leaf() const
     {
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here");
         return false;
     }
 
     /**
- * \brief Proyector for the 'i' node
+ * \brief Number of elements in the subtree
      */
- node_pointer get_node(unsigned int index)
+ virtual size_t elements() const
     {
- return m_nodes[index].second;
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here");
+ return 0;
     }
 
     /**
      * \brief Search for elements in 'box' in the Rtree. Add them to 'result'.
- * If exact_match is true only return the elements having as
- * key the box 'box'. Otherwise return everything inside 'box'.
      */
- virtual void find(Box const& box, std::deque<Value>& result, bool const exact_match, Translator const& tr)
+ virtual void find(Box const& box, std::deque<Value>& result, Translator const& tr)
     {
- for (typename node_map::const_iterator it = m_nodes.begin();
- it != m_nodes.end(); ++it)
- {
- // awulkiew - is_overlapping changed to geometry::intersects
- if (geometry::intersects(it->first, box))
- {
- it->second->find(box, result, exact_match, tr);
- }
- }
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here");
     }
 
     /**
- * \brief Return in 'result' all the leaves inside 'box'
- */
- void find_leaves(Box const& box, typename std::vector<node_pointer>& result) const
+ * \brief Compute bounding box for this node
+ */
+ virtual Box compute_box(Translator const&) const
     {
- for (typename node_map::const_iterator it = m_nodes.begin();
- it != m_nodes.end(); ++it)
- {
- // awulkiew - is_overlapping changed to geometry::intersects
- if (geometry::intersects(it->first, box))
- {
- if (it->second->is_leaf())
- {
- result.push_back(it->second);
- }
- else
- {
- it->second->find_leaves(box, result);
- }
- }
- }
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here");
+
+ return Box();
     }
 
     /**
- * \brief Compute bounding box for this node
+ * \brief Get leaves for a node
     */
- virtual Box compute_box(Translator const&) const
+ virtual std::vector<Value> get_leaves() const
     {
- if (m_nodes.empty())
- {
- return Box();
- }
-
- Box result;
- geometry::assign_inverse(result);
- for(typename node_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
- {
- geometry::combine(result, it->first);
- }
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here");
 
- return result;
+ return std::vector<Value>();
     }
 
     /**
- * \brief Insert a value (not allowed for a node, only on leaves)
+ * \brief Remove elements inside the 'box'
      */
- virtual void insert(Value const&)
+ // awulkiew - name changed to avoid ambiguity (Value may be of type Box)
+ virtual void remove_in(Box const& box, Translator const&)
     {
         // TODO: mloskot - define & use GGL exception
- throw std::logic_error("Insert in node!");
+ throw std::logic_error("shouldn't be here");
     }
 
     /**
@@ -184,299 +129,175 @@
      */
     virtual std::vector<Box> get_boxes(Translator const&) const
     {
- std::vector<Box> result;
- for(typename node_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
- {
- result.push_back(it->first);
- }
- return result;
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here");
+
+ return std::vector<Box>();
     }
 
     /**
- * \brief Recompute the bounding box
+ * \brief Print Rtree subtree (mainly for debug)
      */
- void adjust_box(node_pointer const& node, Translator const& tr)
+ virtual void print(Translator const& tr) const
     {
- unsigned int index = 0;
- for (typename node_map::iterator it = m_nodes.begin();
- it != m_nodes.end(); ++it, index++)
- {
- if (it->second.get() == node.get())
- {
- m_nodes[index] = std::make_pair(node->compute_box(tr), node);
- return;
- }
- }
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here");
     }
 
+ // awulkiew - leaf only virtual methods
+
     /**
- * \brief Remove elements inside the 'box'
+ * \brief Insert a value (not allowed for a node, only on leaves)
      */
- // awulkiew - name changed to avoid ambiguity (Value may be of type Box)
- virtual void remove_in(Box const& box, Translator const&)
+ virtual void insert(Value const&)
     {
- for (typename node_map::iterator it = m_nodes.begin();
- it != m_nodes.end(); ++it)
- {
- if (geometry::equals(it->first, box))
- {
- m_nodes.erase(it);
- return;
- }
- }
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("Insert in node!");
     }
 
     /**
- * \brief Remove value in this leaf
+ * \brief add a value (not allowed in nodes, only on leaves)
      */
- virtual void remove(Value const&, Translator const&)
+ virtual void add_value(Value const&)
     {
         // TODO: mloskot - define & use GGL exception
- throw std::logic_error("Can't remove a non-leaf node by value.");
+ throw std::logic_error("Can't add value to non-leaf node.");
     }
 
     /**
- * \brief Replace the node in the m_nodes vector and recompute the box
+ * \brief Value projector for leaf_node (not allowed for non-leaf nodes)
      */
- void replace_node(node_pointer const& leaf, node_pointer& new_leaf, Translator const& tr)
+ virtual Value get_value(unsigned int) const
     {
- unsigned int index = 0;
- for(typename node_map::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it, index++)
- {
- if (it->second.get() == leaf.get())
- {
- m_nodes[index] = std::make_pair(new_leaf->compute_box(tr), new_leaf);
- new_leaf->update_parent(new_leaf);
- return;
- }
- }
-
         // TODO: mloskot - define & use GGL exception
- throw std::logic_error("Node not found.");
+ throw std::logic_error("No values in a non-leaf node.");
     }
 
     /**
- * \brief Add a child to this node
+ * \brief Remove value in this leaf
      */
- virtual void add_node(Box const& box, node_pointer const& node)
+ virtual void remove(Value const&, Translator const&)
     {
- m_nodes.push_back(std::make_pair(box, node));
- node->update_parent(node);
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("Can't remove a non-leaf node by value.");
     }
 
+ // awulkiew - internal node only virtual methods
+
     /**
- * \brief add a value (not allowed in nodes, only on leaves)
+ * \brief Add a new child (node) to this node
      */
- virtual void add_value(Value const&)
+ virtual void add_node(Box const&, node_pointer const&)
     {
         // TODO: mloskot - define & use GGL exception
- throw std::logic_error("Can't add value to non-leaf node.");
+ throw std::logic_error("Can't add node to leaf node.");
     }
 
- /**
- * \brief Add a child leaf to this node
- */
- inline void add_leaf_node(Box const& box, leaf_pointer const& leaf)
+ virtual node_pointer first_element() const
     {
- m_nodes.push_back(std::make_pair(box, leaf));
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here.");
+ return node_pointer();
     }
 
     /**
- * \brief Choose a node suitable for adding 'box'
+ * \brief Proyector for the 'i' node
      */
- node_pointer choose_node(Box const& box)
+ virtual node_pointer get_node(size_t index)
     {
- if (m_nodes.size() == 0)
- {
- // TODO: mloskot - define & use GGL exception
- throw std::logic_error("Empty node trying to choose the least enlargement node.");
- }
-
- // awulkiew - areas types changed
- typedef typename area_result<Box>::type area_type;
-
- bool first = true;
- area_type min_area = 0;
- area_type min_diff_area = 0;
- node_pointer chosen_node;
-
- // check for the least enlargement
- for (typename node_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
- {
- // awulkiew - areas types changed
- area_type const diff_area = compute_union_area(box, it->first) - geometry::area(it->first);
-
- if (first)
- {
- // it's the first time, we keep the first
- min_diff_area = diff_area;
- min_area = geometry::area(it->first);
- chosen_node = it->second;
-
- first = false;
- }
- else
- {
- if (diff_area < min_diff_area)
- {
- min_diff_area = diff_area;
- min_area = geometry::area(it->first);
- chosen_node = it->second;
- }
- else
- {
- if (diff_area == min_diff_area)
- {
- if (geometry::area(it->first) < min_area)
- {
- min_diff_area = diff_area;
- min_area = geometry::area(it->first);
- chosen_node = it->second;
- }
- }
- }
- }
- }
-
- return chosen_node;
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here.");
+ return node_pointer();
     }
 
     /**
- * \brief Empty the node
+ * \brief Return in 'result' all the leaves inside 'box'
      */
- virtual void empty_nodes()
+ virtual void find_leaves(Box const& box, typename std::vector<node_pointer>& result) const
     {
- m_nodes.clear();
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here.");
     }
 
     /**
- * \brief Projector for parent
+ * \brief Recompute the bounding box
      */
- inline node_pointer get_parent() const
+ virtual void adjust_box(node_pointer const& node, Translator const& tr)
     {
- return m_parent;
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here.");
     }
 
     /**
- * \brief Update the parent of all the childs
+ * \brief Replace the node in the m_nodes vector and recompute the box
      */
- void update_parent(node_pointer const& node)
+ virtual void replace_node(node_pointer const& leaf, node_pointer& new_leaf, Translator const& tr)
     {
- for (typename node_map::iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
- {
- it->second->set_parent(node);
- }
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here.");
     }
 
     /**
- * \brief Set parent
+ * \brief Add a child leaf to this node
      */
- void set_parent(node_pointer const& node)
+ virtual void add_leaf_node(Box const& box, leaf_pointer const& leaf)
     {
- m_parent = node;
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here.");
     }
 
     /**
- * \brief Value projector for leaf_node (not allowed for non-leaf nodes)
+ * \brief Choose a node suitable for adding 'box'
      */
- virtual Value get_value(unsigned int) const
+ virtual node_pointer choose_node(Box const& box)
     {
         // TODO: mloskot - define & use GGL exception
- throw std::logic_error("No values in a non-leaf node.");
+ throw std::logic_error("shouldn't be here.");
     }
 
     /**
- * \brief Box projector for node 'index'
+ * \brief Update the parent of all the childs
      */
- // awulkiew - commented, not used
- /*virtual Box get_box(unsigned int index, Translator const& tr) const
+ virtual void update_parent(node_pointer const& node)
     {
- return m_nodes[index].first;
- }*/
+ // In case of leaf do nothing
+ }
 
     /**
      * \brief Box projector for node pointed by 'leaf'
      */
- // awulkiew - virtual keyword not needed
     virtual Box get_box(node_pointer const& leaf) const
     {
- for (typename node_map::const_iterator it = m_nodes.begin();
- it != m_nodes.end(); ++it)
- {
- if (it->second.get() == leaf.get())
- {
- return it->first;
- }
- }
-
         // TODO: mloskot - define & use GGL exception
- throw std::logic_error("Node not found");
+ throw std::logic_error("shouldn't be here.");
+ return Box();
     }
 
     /**
      * \brief Children projector
      */
- node_map get_nodes() const
+ virtual node_map get_nodes() const
     {
- return m_nodes;
+ // TODO: mloskot - define & use GGL exception
+ throw std::logic_error("shouldn't be here.");
+ return node_map();
     }
 
+protected:
+
     /**
- * \brief Get leaves for a node
- */
- virtual std::vector<Value> get_leaves() const
+ * \brief Creates a default node
+ */
+ rtree_node()
     {
- typedef std::vector<Value> leaf_type;
- leaf_type leaf;
-
- for (typename node_map::const_iterator it = m_nodes.begin();
- it != m_nodes.end(); ++it)
- {
- leaf_type this_leaves = it->second->get_leaves();
-
- for (typename leaf_type::iterator it_leaf = this_leaves.begin();
- it_leaf != this_leaves.end(); ++it_leaf)
- {
- leaf.push_back(*it_leaf);
- }
- }
-
- return leaf;
     }
 
     /**
- * \brief Print Rtree subtree (mainly for debug)
+ * \brief Creates a node with 'parent' as parent and 'level' as its level
      */
- virtual void print(Translator const& tr) const
+ rtree_node(node_pointer const& parent, size_t const& level)
+ : m_parent(parent), m_level(level)
     {
- std::cerr << " --> Node --------" << std::endl;
- std::cerr << " Address: " << this << std::endl;
- std::cerr << " Level: " << m_level << std::endl;
- std::cerr << " Size: " << m_nodes.size() << std::endl;
- std::cerr << " | ";
- for(typename node_map::const_iterator it = m_nodes.begin(); it != m_nodes.end(); ++it)
- {
- if (this != it->second->get_parent().get())
- {
- std::cerr << "ERROR - " << this << " is not " << it->second->get_parent().get() << " ";
- }
-
- std::cerr << "( " << geometry::get<min_corner, 0>(it->first) << " , "
- << geometry::get<min_corner, 1>(it->first) << " ) x ";
- std::cerr << "( " << geometry::get<max_corner, 0>(it->first) << " , "
- << geometry::get<max_corner, 1>(it->first) << " )";
- std::cerr << " | ";
- }
- std::cerr << std::endl;
- std::cerr << " --< Node --------" << std::endl;
-
- // print child nodes
- std::cerr << " Children: " << std::endl;
- for (typename node_map::const_iterator it = m_nodes.begin();
- it != m_nodes.end(); ++it)
- {
- it->second->print(tr);
- }
     }
 
 private:
@@ -486,10 +307,8 @@
 
     /// level of this node
     // TODO: mloskot - Why not std::size_t or node_map::size_type, same with member functions?
- unsigned int m_level;
-
- /// child nodes
- node_map m_nodes;
+ // awulkiew - size_t used instead of unsigned int
+ size_t m_level;
 };
 
 }}} // namespace boost::geometry::index

Modified: sandbox-branches/geometry/index_080_nhch/tests/rtree_native.cpp
==============================================================================
--- sandbox-branches/geometry/index_080_nhch/tests/rtree_native.cpp (original)
+++ sandbox-branches/geometry/index_080_nhch/tests/rtree_native.cpp 2011-02-19 09:23:37 EST (Sat, 19 Feb 2011)
@@ -191,7 +191,7 @@
         typedef boost::geometry::model::box<P> B;
 
         boost::geometry::index::rtree<B>::rtree_leaf l;
- boost::geometry::index::rtree<B>::rtree_node n;
+ boost::geometry::index::rtree<B>::rtree_internal_node n;
 
         std::cout << sizeof(boost::shared_ptr<int>) << '\n';
         std::cout << sizeof(std::vector<int>) << '\n';


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk