|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r70607 - in sandbox-branches/geometry/index_080_new: boost/geometry/extensions/index/rtree boost/geometry/extensions/index/rtree/rstar boost/geometry/extensions/index/rtree/visitors tests
From: adam.wulkiewicz_at_[hidden]
Date: 2011-03-26 22:21:46
Author: awulkiew
Date: 2011-03-26 22:21:45 EDT (Sat, 26 Mar 2011)
New Revision: 70607
URL: http://svn.boost.org/trac/boost/changeset/70607
Log:
other version of split algorithm + a lot of minor changes
Added:
sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/choose_next_node.hpp (contents, props changed)
sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/split.hpp (contents, props changed)
sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/visitors/rtree_are_boxes_ok.hpp (contents, props changed)
Text files modified:
sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/rtree_insert.hpp | 645 ---------------------------------------
sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rtree.hpp | 15
sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rtree_node.hpp | 18 +
sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/visitors/gl_draw.hpp | 30
sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/visitors/print.hpp | 29
sandbox-branches/geometry/index_080_new/tests/additional_glut_vis.cpp | 29 +
sandbox-branches/geometry/index_080_new/tests/additional_sizes_and_times.cpp | 8
sandbox-branches/geometry/index_080_new/tests/main.cpp | 13
sandbox-branches/geometry/index_080_new/tests/rtree_native.hpp | 19 +
9 files changed, 118 insertions(+), 688 deletions(-)
Added: sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/choose_next_node.hpp
==============================================================================
--- (empty file)
+++ sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/choose_next_node.hpp 2011-03-26 22:21:45 EDT (Sat, 26 Mar 2011)
@@ -0,0 +1,186 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Boost.Index - R*-tree ChooseNextNode algorithm
+//
+// 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)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_CHOOSE_NEXT_NODE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_CHOOSE_NEXT_NODE_HPP
+
+#include <algorithm>
+
+#include <boost/geometry/extensions/index/algorithms/area.hpp>
+#include <boost/geometry/extensions/index/algorithms/overlap.hpp>
+#include <boost/geometry/extensions/index/algorithms/union_area.hpp>
+
+#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
+#include <boost/geometry/extensions/index/rtree/visitors/rtree_is_leaf.hpp>
+
+namespace boost { namespace geometry { namespace index {
+
+namespace visitors {
+
+struct rtree_rstar_chnn_min_overlap_cost {};
+struct rtree_rstar_chnn_nearly_min_overlap_cost {};
+
+// TODO: awulkiew - it's possible that goodness values may be used to choose next node
+// on this step some of the goodness values would be calculated (not all)
+// and only for some nodes (goodness values should be calculated only if there is an overflow)
+
+template <typename Value, typename Box, typename Tag>
+class rtree_rstar_choose_next_node
+{};
+
+// TODO: awulkiew finish this version
+// use min_element instead of searching by myself
+
+//template <typename Value, typename Box>
+//class rtree_rstar_choose_next_node<Value, Box, rtree_rstar_chnn_nearly_min_overlap_cost>
+//{
+// typedef typename index::detail::rtree_node<Value, Box, rtree_rstar_tag>::type node;
+// typedef typename index::detail::rtree_internal_node<Value, Box, rtree_rstar_tag>::type internal_node;
+// typedef typename index::detail::rtree_leaf<Value, Box, rtree_rstar_tag>::type leaf;
+//
+// typedef typename internal_node::children_type children_type;
+//
+//public:
+// template <typename Indexable>
+// static inline size_t apply(internal_node & n, Indexable const& indexable)
+// {
+// assert(!n.children.empty());
+//
+// bool has_leaves = boost::apply_visitor(
+// visitors::rtree_is_leaf<Value, Box, rtree_rstar_tag>(),
+// *n.children.front().second);
+//
+// if ( !has_leaves )
+// return impl<internal_node_areas>(n, indexable);
+// else
+// return impl<branch_areas>(n, indexable);
+// }
+//
+//private:
+// template <typename Areas, typename Indexable>
+// static inline size_t impl(internal_node & n, Indexable const& indexable)
+// {
+// }
+//
+//};
+
+// TODO: awulkiew - wrong algorithm? Should branch check be applied to Leafs?
+// TODO: awulkiew - further optimization: don't calculate area with the overlap, calculate it only if
+// overlap < smallest_overlap (and current area must be stored) OR
+// overlap == smallest_overlap (and area must be compared)
+
+template <typename Value, typename Box>
+class rtree_rstar_choose_next_node<Value, Box, rtree_rstar_chnn_min_overlap_cost>
+{
+ typedef typename index::detail::rtree_node<Value, Box, rtree_rstar_tag>::type node;
+ typedef typename index::detail::rtree_internal_node<Value, Box, rtree_rstar_tag>::type internal_node;
+ typedef typename index::detail::rtree_leaf<Value, Box, rtree_rstar_tag>::type leaf;
+
+ typedef typename internal_node::children_type children_type;
+
+public:
+ template <typename Indexable>
+ static inline size_t apply(internal_node & n, Indexable const& indexable)
+ {
+ assert(!n.children.empty());
+
+ bool has_leaves = boost::apply_visitor(
+ visitors::rtree_is_leaf<Value, Box, rtree_rstar_tag>(),
+ *n.children.front().second);
+
+ if ( !has_leaves )
+ return impl<internal_node_areas>(n, indexable);
+ else
+ return impl<branch_areas>(n, indexable);
+ }
+
+private:
+ template <typename Areas, typename Indexable>
+ static inline size_t impl(internal_node & n, Indexable const& indexable)
+ {
+ typedef typename children_type::iterator children_iterator;
+
+ //assert(!n.children.empty());
+
+ children_iterator temp_it = n.children.begin();
+ children_iterator child_it = temp_it;
+ Areas min_areas(n.children, child_it, indexable);
+
+ for (children_iterator it = ++temp_it;
+ it != n.children.end(); ++it)
+ {
+ Areas areas(n.children, it, indexable);
+
+ if ( areas < min_areas )
+ {
+ child_it = it;
+ min_areas = areas;
+ }
+ }
+
+ // TODO: awulkiew - switch to indexes in the whole class?
+ return child_it - n.children.begin();
+ }
+
+ struct branch_areas
+ {
+ typedef typename area_result<Box>::type area_type;
+
+ template <typename Indexable>
+ inline branch_areas(children_type const& ch, typename children_type::iterator const& k_it, Indexable const& indexable)
+ {
+ overlap_area = 0;
+ for (typename children_type::const_iterator it = ch.begin(); it != ch.end(); ++it)
+ if ( it != k_it )
+ overlap_area += index::overlap(k_it->first, it->first);
+
+ area = index::area(k_it->first);
+
+ diff_area = index::union_area(k_it->first, indexable) - area;
+ }
+
+ inline bool operator<(branch_areas &a) const
+ {
+ return overlap_area < a.overlap_area ||
+ ( overlap_area == a.overlap_area && diff_area < a.diff_area ) ||
+ ( diff_area == a.diff_area && area < a.area );
+ }
+
+ area_type overlap_area;
+ area_type diff_area;
+ area_type area;
+ };
+
+ struct internal_node_areas
+ {
+ typedef typename area_result<Box>::type area_type;
+
+ template <typename Indexable>
+ inline internal_node_areas(children_type const&, typename children_type::iterator const& k_it, Indexable const& indexable)
+ {
+ area = index::area(k_it->first);
+ diff_area = index::union_area(k_it->first, indexable) - area;
+ }
+
+ inline bool operator<(internal_node_areas &a) const
+ {
+ return diff_area < a.diff_area ||
+ ( diff_area == a.diff_area && area < a.area );
+ }
+
+ area_type diff_area;
+ area_type area;
+ };
+};
+
+} // namespace visitors
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_CHOOSE_NEXT_NODE_HPP
Modified: sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/rtree_insert.hpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/rtree_insert.hpp (original)
+++ sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/rtree_insert.hpp 2011-03-26 22:21:45 EDT (Sat, 26 Mar 2011)
@@ -23,578 +23,13 @@
#include <boost/geometry/extensions/index/rtree/visitors/rtree_insert.hpp>
#include <boost/geometry/extensions/index/rtree/visitors/rtree_is_leaf.hpp>
+#include <boost/geometry/extensions/index/rtree/rstar/choose_next_node.hpp>
+#include <boost/geometry/extensions/index/rtree/rstar/split.hpp>
+
namespace boost { namespace geometry { namespace index {
namespace visitors {
-// ----------------------------------------------------------------------------- //
-// rstar/choose_next_node
-// ----------------------------------------------------------------------------- //
-
-// TODO: awulkiew - it's possible that goodness values may be used to choose next node
-
-// rtree choose_next_node algorithm for rstar variant
-
-template <typename Value, typename Box>
-class rtree_rstar_choose_next_node
-{
- typedef typename index::detail::rtree_node<Value, Box, rtree_rstar_tag>::type node;
- typedef typename index::detail::rtree_internal_node<Value, Box, rtree_rstar_tag>::type internal_node;
- typedef typename index::detail::rtree_leaf<Value, Box, rtree_rstar_tag>::type leaf;
-
- typedef typename internal_node::children_type children_type;
-
-public:
- // TODO: awulkiew - alternative lower-cost version of overlap calculation may be used (branch_areas)
- // TODO: awulkiew - further optimization: don't calculate area with the overlap, calculate it only if
- // overlap < smallest_overlap (and current area must be stored) OR
- // overlap == smallest_overlap (and area must be compared)
- template <typename Indexable>
- static inline size_t apply(internal_node & n, Indexable const& indexable)
- {
- assert(!n.children.empty());
-
- bool has_leaves = boost::apply_visitor(
- visitors::rtree_is_leaf<Value, Box, rtree_rstar_tag>(),
- *n.children.front().second);
-
- if ( !has_leaves )
- return impl<internal_node_areas>(n, indexable);
- else
- return impl<branch_areas>(n, indexable);
- }
-
-private:
- template <typename Areas, typename Indexable>
- static inline size_t impl(internal_node & n, Indexable const& indexable)
- {
- typedef typename children_type::iterator children_iterator;
-
- //assert(!n.children.empty());
-
- children_iterator temp_it = n.children.begin();
- children_iterator child_it = temp_it;
- Areas min_areas(n.children, child_it, indexable);
-
- for (children_iterator it = ++temp_it;
- it != n.children.end(); ++it)
- {
- Areas areas(n.children, it, indexable);
-
- if ( areas < min_areas )
- {
- child_it = it;
- min_areas = areas;
- }
- }
-
- // TODO: awulkiew - switch to indexes in the whole class?
- return child_it - n.children.begin();
- }
-
- struct branch_areas
- {
- typedef typename area_result<Box>::type area_type;
-
- template <typename Indexable>
- inline branch_areas(children_type const& ch, typename children_type::iterator const& k_it, Indexable const& indexable)
- {
- overlap_area = 0;
- for (typename children_type::const_iterator it = ch.begin(); it != ch.end(); ++it)
- if ( it != k_it )
- overlap_area += index::overlap(k_it->first, it->first);
-
- area = index::area(k_it->first);
-
- diff_area = index::union_area(k_it->first, indexable) - area;
- }
-
- inline bool operator<(branch_areas &a) const
- {
- return overlap_area < a.overlap_area ||
- ( overlap_area == a.overlap_area && diff_area < a.diff_area ) ||
- ( diff_area == a.diff_area && area < a.area );
- }
-
- area_type overlap_area;
- area_type diff_area;
- area_type area;
- };
-
- struct internal_node_areas
- {
- typedef typename area_result<Box>::type area_type;
-
- template <typename Indexable>
- inline internal_node_areas(children_type const&, typename children_type::iterator const& k_it, Indexable const& indexable)
- {
- area = index::area(k_it->first);
- diff_area = index::union_area(k_it->first, indexable) - area;
- }
-
- inline bool operator<(internal_node_areas &a) const
- {
- return diff_area < a.diff_area ||
- ( diff_area == a.diff_area && area < a.area );
- }
-
- area_type diff_area;
- area_type area;
- };
-};
-
-// ----------------------------------------------------------------------------- //
-// rstar/sorts
-// ----------------------------------------------------------------------------- //
-
-// elements ids less comparator
-
-template <typename Elements, typename Translator, size_t Corner, size_t AxisIndex>
-class rtree_rstar_elements_indexes_less
-{
-public:
- rtree_rstar_elements_indexes_less(Elements const& elements, Translator const& tr)
- : m_elements(elements), m_tr(tr)
- {}
-
- bool operator()(size_t e1_index, size_t e2_index)
- {
- return
- index::detail::get<Corner, AxisIndex>(
- index::detail::rtree_element_indexable(m_elements[e1_index], m_tr)
- )
- <
- index::detail::get<Corner, AxisIndex>(
- index::detail::rtree_element_indexable(m_elements[e2_index], m_tr)
- );
- }
-
-private:
- Elements const& m_elements;
- Translator const& m_tr;
-};
-
-template <typename T, size_t Dimension>
-class rtree_rstar_vectors
-{
-public:
- inline rtree_rstar_vectors(size_t count)
- : m_count(count), m_ids(Dimension * 2 * count)
- {}
-
- template <size_t AxisIndex, size_t Corner>
- inline typename std::vector<T>::iterator begin()
- {
- BOOST_STATIC_ASSERT(AxisIndex < Dimension);
- BOOST_STATIC_ASSERT(Corner < 2);
- return m_ids.begin() + ( AxisIndex * 2 + Corner ) * m_count;
- }
-
- template <size_t AxisIndex, size_t Corner>
- inline typename std::vector<T>::iterator end()
- {
- BOOST_STATIC_ASSERT(AxisIndex < Dimension);
- BOOST_STATIC_ASSERT(Corner < 2);
- return m_ids.begin() + ( AxisIndex * 2 + Corner + 1) * m_count;
- }
-
- template <size_t AxisIndex, size_t Corner>
- inline T const& get(size_t index) const
- {
- BOOST_STATIC_ASSERT(AxisIndex < Dimension);
- BOOST_STATIC_ASSERT(Corner < 2);
- assert(index < m_count);
- return m_ids[( AxisIndex * 2 + Corner ) * m_count + index];
- }
-
- template <size_t AxisIndex, size_t Corner>
- inline void set(size_t index, T const& v)
- {
- BOOST_STATIC_ASSERT(AxisIndex < Dimension);
- BOOST_STATIC_ASSERT(Corner < 2);
- assert(index < m_count);
- m_ids[( AxisIndex * 2 + Corner ) * m_count + index] = v;
- }
-
- inline T const& get(size_t axis, size_t corner, size_t index) const
- {
- assert(axis < Dimension);
- assert(corner < 2);
- assert(index < m_count);
- return m_ids[( axis * 2 + corner ) * m_count + index];
- }
-
- inline size_t vector_size() const
- {
- return m_count;
- }
-
-private:
- size_t m_count;
- std::vector<T> m_ids;
-};
-
-// init indexes of elements and sort them
-
-template <typename Elements, typename Translator, size_t Dimension>
-class rtree_rstar_sorts_fill_ids
-{
- BOOST_STATIC_ASSERT(0 < Dimension);
-
-public:
- template <size_t D>
- static inline void apply(rtree_rstar_vectors<size_t, D> & ids, Elements const& elements, Translator const& tr)
- {
- rtree_rstar_sorts_fill_ids<Elements, Translator, Dimension - 1>::apply(ids, elements, tr);
-
- fill<min_corner>(ids, elements, tr);
- fill<max_corner>(ids, elements, tr);
- }
-
-private:
- template <size_t Corner, size_t D>
- static inline void fill(rtree_rstar_vectors<size_t, D> & ids, Elements const& elements, Translator const& tr)
- {
- for ( size_t i = 0 ; i < elements.size() ; ++i )
- ids.set<Dimension - 1, Corner>(i, i);
-
- rtree_rstar_elements_indexes_less<Elements, Translator, Corner, Dimension - 1> less(elements, tr);
- std::sort(ids.begin<Dimension - 1, Corner>(), ids.end<Dimension - 1, Corner>(), less);
- }
-};
-
-template <typename Elements, typename Translator>
-class rtree_rstar_sorts_fill_ids<Elements, Translator, 1>
-{
-public:
- template <size_t D>
- static inline void apply(rtree_rstar_vectors<size_t, D> & ids, Elements const& elements, Translator const& tr)
- {
- fill<min_corner>(ids, elements, tr);
- fill<max_corner>(ids, elements, tr);
- }
-
-private:
- template <size_t Corner, size_t D>
- static inline void fill(rtree_rstar_vectors<size_t, D> & ids, Elements const& elements, Translator const& tr)
- {
- for ( size_t i = 0 ; i < elements.size() ; ++i )
- ids.set<0, Corner>(i, i);
-
- rtree_rstar_elements_indexes_less<Elements, Translator, Corner, 0> less(elements, tr);
- std::sort(ids.begin<0, Corner>(), ids.end<0, Corner>(), less);
- }
-};
-
-// sorts for each axis for min and max
-
-template <typename Elements, typename Translator, size_t Dimension>
-class rtree_rstar_sorts
-{
-public:
- inline rtree_rstar_sorts(Elements const& elements, Translator const& tr)
- : m_elems(elements), m_tr(tr), m_ids(m_elems.size())
- {
- rtree_rstar_sorts_fill_ids<Elements, Translator, Dimension>::apply(m_ids, elements, tr);
- }
-
- // TODO: awulkiew - should those methods be here? Just leave get_element?
-
- template <size_t AxisIndex, size_t Corner>
- inline typename index::detail::rtree_element_indexable_type<typename Elements::value_type, Translator>::type const&
- get_indexable(size_t index) const
- {
- size_t id = m_ids.get<AxisIndex, Corner>(index);
- return index::detail::rtree_element_indexable(m_elems[id], m_tr);
- }
-
- inline typename index::detail::rtree_element_indexable_type<typename Elements::value_type, Translator>::type const&
- get_indexable(size_t axis, size_t corner, size_t index) const
- {
- size_t id = m_ids.get(axis, corner, index);
- return index::detail::rtree_element_indexable(m_elems[id], m_tr);
- }
-
- template <size_t AxisIndex, size_t Corner>
- inline typename Elements::value_type const& get_element(size_t index) const
- {
- size_t id = m_ids.get<AxisIndex, Corner>(index);
- return m_elems[id];
- }
-
- inline typename Elements::value_type const& get_element(size_t axis, size_t corner, size_t index) const
- {
- size_t id = m_ids.get(axis, corner, index);
- return m_elems[id];
- }
-
- inline size_t sort_size() const
- {
- return m_ids.vector_size();
- }
-
-private:
- Elements const& m_elems;
- Translator const& m_tr;
-
- rtree_rstar_vectors<size_t, Dimension> m_ids;
-};
-
-// ----------------------------------------------------------------------------- //
-// rstar/goodness_values
-// ----------------------------------------------------------------------------- //
-
-// calculate margins, areas and overlaps
-
-template <typename Box, size_t AxisIndex, size_t Corner>
-class rtree_rstar_calculate_goodness_values_for_axis
-{
- typedef typename geometry::traits::coordinate_type<
- typename geometry::traits::point_type<Box>::type
- >::type coordinate_type;
-
- static const size_t dimension = geometry::traits::dimension<
- typename geometry::traits::point_type<Box>::type
- >::value;
-
- typedef typename area_result<Box>::type area_type;
- typedef typename margin_result<Box>::type margin_type;
- typedef typename overlap_result<Box>::type overlap_type;
- typedef boost::tuple<Box, Box, margin_type, overlap_type, area_type> goodness_type;
-
-public:
- template <typename Elements, typename Translator>
- static inline void apply(
- rtree_rstar_vectors<goodness_type, dimension> & goodness_vectors,
- rtree_rstar_sorts<Elements, Translator, dimension> const& sorts,
- size_t min_elems,
- size_t max_elems)
- {
- assert(sorts.sort_size() == max_elems + 1);
- assert(goodness_vectors.vector_size() == max_elems - 2 * min_elems + 2);
-
- size_t median_index_last = max_elems - min_elems + 2;
- size_t i = 0;
- for ( size_t median_index = min_elems ; median_index < median_index_last ; ++median_index, ++i )
- {
- Box left_box = calculate_box(sorts, 0, median_index);
- Box right_box = calculate_box(sorts, median_index, sorts.sort_size());
-
- margin_type margin = index::margin(left_box) + index::margin(right_box);
- area_type area = index::area(left_box) + index::area(right_box);
- overlap_type overlap = index::overlap(left_box, right_box);
-
- goodness_vectors.set<AxisIndex, Corner>(
- i,
- boost::make_tuple(left_box, right_box, margin, overlap, area));
- }
- }
-private:
- template <typename Elements, typename Translator>
- static inline Box calculate_box(
- rtree_rstar_sorts<Elements, Translator, dimension> const& sorts,
- size_t index_first,
- size_t index_last)
- {
- assert(index_first < index_last);
-
- Box result;
- geometry::convert(sorts.template get_indexable<AxisIndex, Corner>(index_first), result);
- ++index_first;
- for ( ; index_first < index_last ; ++index_first )
- geometry::expand(result, sorts.template get_indexable<AxisIndex, Corner>(index_first));
- return result;
- }
-};
-
-// calculate goodness values for all axis
-
-template <typename Box, size_t Dimension>
-struct rtree_rstar_calculate_goodness_values
-{
- BOOST_STATIC_ASSERT(0 < Dimension);
-
- typedef typename area_result<Box>::type area_type;
- typedef typename margin_result<Box>::type margin_type;
- typedef typename overlap_result<Box>::type overlap_type;
- typedef boost::tuple<Box, Box, margin_type, overlap_type, area_type> goodness_type;
-
- template <typename Elements, typename Translator, size_t D>
- static inline void apply(
- rtree_rstar_vectors<goodness_type, D> & goodness_vectors,
- rtree_rstar_sorts<Elements, Translator, D> const& sorts,
- size_t min_elems,
- size_t max_elems)
- {
- rtree_rstar_calculate_goodness_values<Box, Dimension - 1>
- ::apply(goodness_vectors, sorts, min_elems, max_elems);
-
- rtree_rstar_calculate_goodness_values_for_axis<Box, Dimension - 1, min_corner>
- ::apply(goodness_vectors, sorts, min_elems, max_elems);
- rtree_rstar_calculate_goodness_values_for_axis<Box, Dimension - 1, max_corner>
- ::apply(goodness_vectors, sorts, min_elems, max_elems);
- }
-};
-
-template <typename Box>
-struct rtree_rstar_calculate_goodness_values<Box, 1>
-{
- typedef typename area_result<Box>::type area_type;
- typedef typename margin_result<Box>::type margin_type;
- typedef typename overlap_result<Box>::type overlap_type;
- typedef boost::tuple<Box, Box, margin_type, overlap_type, area_type> goodness_type;
-
- template <typename Elements, typename Translator, size_t D>
- static inline void apply(
- rtree_rstar_vectors<goodness_type, D> & goodness_vectors,
- rtree_rstar_sorts<Elements, Translator, D> const& sorts,
- size_t min_elems,
- size_t max_elems)
- {
- rtree_rstar_calculate_goodness_values_for_axis<Box, 0, min_corner>
- ::apply(goodness_vectors, sorts, min_elems, max_elems);
- rtree_rstar_calculate_goodness_values_for_axis<Box, 0, max_corner>
- ::apply(goodness_vectors, sorts, min_elems, max_elems);
- }
-};
-
-// goodness values
-
-template <typename Elements, typename Translator, typename Box>
-class rtree_rstar_goodness_values
-{
- typedef typename geometry::traits::coordinate_type<
- typename geometry::traits::point_type<Box>::type
- >::type coordinate_type;
-
- static const size_t dimension = geometry::traits::dimension<
- typename geometry::traits::point_type<Box>::type
- >::value;
-
- typedef typename area_result<Box>::type area_type;
- typedef typename margin_result<Box>::type margin_type;
- typedef typename overlap_result<Box>::type overlap_type;
- typedef boost::tuple<Box, Box, margin_type, overlap_type, area_type> goodness_type;
-
-public:
- inline rtree_rstar_goodness_values(
- Elements const& elements,
- Translator const& tr,
- size_t min_elems,
- size_t max_elems)
- : m_sorts(elements, tr)
- , m_goodness_vectors(max_elems - 2 * min_elems + 2)
- {
- rtree_rstar_calculate_goodness_values<Box, dimension>::apply(
- m_goodness_vectors, m_sorts, min_elems, max_elems);
- }
-
- inline size_t elements_size() const
- {
- return m_sorts.sort_size();
- }
-
- inline size_t goodnesses_size() const
- {
- return m_goodness_vectors.vector_size();
- }
-
- inline goodness_type const& get_goodness(size_t axis, size_t corner, size_t index) const
- {
- return m_goodness_vectors.get(axis, corner, index);
- }
-
- inline typename Elements::value_type const& get_element(size_t axis, size_t corner, size_t index) const
- {
- return m_sorts.get_element(axis, corner, index);
- }
-
-private:
- rtree_rstar_sorts<Elements, Translator, dimension> m_sorts;
- rtree_rstar_vectors<goodness_type, dimension> m_goodness_vectors;
-};
-
-template <typename Elements, typename Translator, typename Box>
-class rtree_rstar_choose_split_axis
-{
- typedef typename margin_result<Box>::type margin_type;
-public:
- static inline std::pair<size_t, size_t> apply(rtree_rstar_goodness_values<Elements, Translator, Box> const& gv)
- {
- std::pair<size_t, size_t> smallest_distr = std::make_pair(0, 0);
- margin_type smallest_margins_sum = calculate_margins_sum(0, 0, gv);
-
- margin_type margins_sum = calculate_margins_sum(0, 1, gv);
- if ( margins_sum < smallest_margins_sum )
- {
- smallest_distr.second = 1;
- smallest_margins_sum = margins_sum;
- }
-
- for ( size_t a = 1 ; a < traits::dimension<Box>::value ; ++a )
- {
- for ( size_t c = 0 ; c < 2 ; ++c )
- {
- margins_sum = calculate_margins_sum(a, c, gv);
- if ( margins_sum < smallest_margins_sum )
- {
- smallest_distr.first = a;
- smallest_distr.second = c;
- smallest_margins_sum = margins_sum;
- }
- }
- }
- return smallest_distr;
- }
-private:
- static inline typename margin_result<Box>::type
- calculate_margins_sum(size_t axis, size_t corner, rtree_rstar_goodness_values<Elements, Translator, Box> const& gv)
- {
- typename margin_result<Box>::type margins_sum = 0;
- for ( size_t i = 0 ; i < gv.goodnesses_size() ; ++i )
- margins_sum += boost::get<2>(gv.get_goodness(axis, corner, i));
- return margins_sum;
- }
-};
-
-template <typename Elements, typename Translator, typename Box>
-class rtree_rstar_choose_split_index
-{
- typedef typename area_result<Box>::type area_type;
- typedef typename overlap_result<Box>::type overlap_type;
-public:
- static inline size_t apply(rtree_rstar_goodness_values<Elements, Translator, Box> const& gv, size_t axis, size_t corner)
- {
- size_t smallest_index = 0;
- overlap_type smallest_overlap = boost::get<3>(gv.get_goodness(axis, corner, 0));
- overlap_type smallest_area = boost::get<4>(gv.get_goodness(axis, corner, 0));
-
- for ( size_t i = 1 ; i < gv.goodnesses_size() ; ++i )
- {
- overlap_type overlap = boost::get<3>(gv.get_goodness(axis, corner, i));
- if ( overlap < smallest_overlap )
- {
- smallest_overlap = overlap;
- smallest_area = boost::get<4>(gv.get_goodness(axis, corner, i));
- smallest_index = i;
- }
- else if ( overlap == smallest_overlap )
- {
- area_type area = boost::get<4>(gv.get_goodness(axis, corner, i));
- if ( area < smallest_area )
- {
- smallest_area = area;
- smallest_index = i;
- }
- }
- }
-
- return smallest_index;
- }
-};
-
-// rtree insert routine for rstar variant
-
template <typename Value, typename Translator, typename Box>
class rtree_insert<Value, Translator, Box, rtree_rstar_tag> : public boost::static_visitor<>
{
@@ -617,7 +52,9 @@
size_t current_child_index_bckup = m_current_child_index;
// choose next node, where value insert traversing should go
- m_current_child_index = rtree_rstar_choose_next_node<Value, Box>::apply(n, m_tr(m_value));
+ m_current_child_index =
+ rtree_rstar_choose_next_node<Value, Box, rtree_rstar_chnn_min_overlap_cost>::
+ apply(n, m_tr(m_value));
// TODO: awulkiew - if reinsert is implemented this must be changed
geometry::expand(n.children[m_current_child_index].first, m_tr(m_value));
@@ -631,7 +68,8 @@
if ( m_max_elems_per_node < n.children.size() )
{
- split(n);
+ rtree_rstar_split<Value, Translator, Box>::
+ apply(n, m_parent, m_current_child_index, m_root_node, m_min_elems_per_node, m_max_elems_per_node, m_tr);
}
}
@@ -641,75 +79,12 @@
if ( m_max_elems_per_node < n.values.size() )
{
- split(n);
+ rtree_rstar_split<Value, Translator, Box>::
+ apply(n, m_parent, m_current_child_index, m_root_node, m_min_elems_per_node, m_max_elems_per_node, m_tr);
}
}
private:
- template <typename Node>
- inline void split(Node & n)
- {
- typedef typename index::detail::rtree_elements_type<Node>::type elements_type;
- typedef typename elements_type::value_type element_type;
-
- elements_type & elems = index::detail::get_elements(n);
-
- rtree_rstar_goodness_values<elements_type, Translator, Box> gv(elems, m_tr, m_min_elems_per_node, m_max_elems_per_node);
-
- std::pair<size_t, size_t> axis_and_corner =
- rtree_rstar_choose_split_axis<elements_type, Translator, Box>::apply(gv);
- size_t axis = axis_and_corner.first;
- size_t corner = axis_and_corner.second;
-
- size_t choosen_index =
- rtree_rstar_choose_split_index<elements_type, Translator, Box>::apply(gv, axis, corner);
-
- size_t median_index = m_min_elems_per_node + choosen_index;
- assert(median_index <= m_max_elems_per_node + 1 - m_min_elems_per_node);
-
- // create new node
- node * right_node = rtree_create_node(Node());
- elements_type & new_elems = index::detail::get_elements(boost::get<Node>(*right_node));
-
- // update new node's elements
- new_elems.reserve(m_max_elems_per_node + 1 - median_index);
- for ( size_t i = median_index ; i < m_max_elems_per_node + 1 ; ++i)
- new_elems.push_back(gv.get_element(axis, corner, i));
-
- // fill temporary container with left node's elements
- elements_type left_elems;
- left_elems.reserve(median_index);
- for ( size_t i = 0 ; i < median_index ; ++i )
- left_elems.push_back(gv.get_element(axis, corner, i));
- // update old node's elements
- elems = left_elems;
-
- if ( m_parent != 0 )
- {
- // update old node's box
- m_parent->children[m_current_child_index].first = boost::get<0>(gv.get_goodness(axis, corner, choosen_index));
- // add new node to the parent's children
- m_parent->children.push_back( std::make_pair(
- boost::get<1>(gv.get_goodness(axis, corner, choosen_index)), right_node ) );
- }
- else
- {
- assert(&n == boost::get<Node>(m_root_node));
-
- // create new root and add nodes
- node * new_root = rtree_create_node(internal_node());
-
- boost::get<internal_node>(*new_root).children.push_back(
- std::make_pair(boost::get<0>(gv.get_goodness(axis, corner, choosen_index)), m_root_node)
- );
- boost::get<internal_node>(*new_root).children.push_back(
- std::make_pair(boost::get<1>(gv.get_goodness(axis, corner, choosen_index)), right_node)
- );
-
- m_root_node = new_root;
- }
- }
-
Value const& m_value;
Translator const& m_tr;
size_t m_min_elems_per_node;
Added: sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/split.hpp
==============================================================================
--- (empty file)
+++ sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rstar/split.hpp 2011-03-26 22:21:45 EDT (Sat, 26 Mar 2011)
@@ -0,0 +1,338 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Boost.Index - R*-tree split algorithm implementation
+//
+// 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)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_SPLIT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_SPLIT_HPP
+
+#include <algorithm>
+
+#include <boost/tuple/tuple.hpp>
+
+#include <boost/geometry/extensions/index/algorithms/area.hpp>
+#include <boost/geometry/extensions/index/algorithms/margin.hpp>
+#include <boost/geometry/extensions/index/algorithms/overlap.hpp>
+#include <boost/geometry/extensions/index/algorithms/union_area.hpp>
+
+#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
+#include <boost/geometry/extensions/index/rtree/visitors/rtree_insert.hpp>
+#include <boost/geometry/extensions/index/rtree/visitors/rtree_is_leaf.hpp>
+
+namespace boost { namespace geometry { namespace index {
+
+namespace visitors {
+
+// elements less
+
+template <typename Elements, typename Translator, size_t AxisIndex, size_t Corner>
+class rtree_rstar_elements_less
+{
+ typedef typename Elements::value_type element_type;
+public:
+ inline rtree_rstar_elements_less(Translator const& tr)
+ : m_tr(tr)
+ {}
+
+ inline bool operator()(element_type const& e1, element_type const e2) const
+ {
+ return
+ index::detail::get<Corner, AxisIndex>(
+ index::detail::rtree_element_indexable(e1, m_tr)
+ )
+ <
+ index::detail::get<Corner, AxisIndex>(
+ index::detail::rtree_element_indexable(e2, m_tr)
+ );
+ }
+
+private:
+ Translator const& m_tr;
+};
+
+// rstar split axis data
+
+template <typename Box>
+struct rtree_rstar_split_axis_data
+{
+ typedef typename margin_result<Box>::type margin_type;
+ typedef typename overlap_result<Box>::type overlap_type;
+ typedef typename area_result<Box>::type area_type;
+
+ inline rtree_rstar_split_axis_data()
+ : margins_sum(0)
+ , smallest_overlap(std::numeric_limits<overlap_type>::max())
+ , smallest_area(std::numeric_limits<area_type>::max())
+ {}
+
+ inline void update(
+ size_t corner,
+ size_t median_index,
+ Box const& left_box,
+ Box const& right_box,
+ margin_type const& margin,
+ overlap_type const& overlap,
+ area_type const& area)
+ {
+ margins_sum += margin;
+
+ if ( overlap < smallest_overlap ||
+ ( overlap == smallest_overlap && area < smallest_area ) )
+ {
+ choosen_corner = corner;
+ choosen_median_index = median_index;
+ choosen_left_box = left_box;
+ choosen_right_box = right_box;
+ smallest_overlap = overlap;
+ smallest_area = area;
+ }
+ }
+
+ size_t choosen_corner;
+ size_t choosen_median_index;
+ Box choosen_left_box;
+ Box choosen_right_box;
+ margin_type margins_sum;
+ overlap_type smallest_overlap;
+ area_type smallest_area;
+};
+
+// update axis data for given axis and corner
+
+template <typename Value, typename Translator, typename Box, size_t Corner>
+class rtree_rstar_split_update_axis_data_for_corner
+{
+ typedef typename rtree_rstar_split_axis_data<Box>::margin_type margin_type;
+ typedef typename rtree_rstar_split_axis_data<Box>::overlap_type overlap_type;
+ typedef typename rtree_rstar_split_axis_data<Box>::area_type area_type;
+
+ BOOST_STATIC_ASSERT(Corner < 2);
+
+public:
+ template <typename Elements>
+ static inline void apply(
+ rtree_rstar_split_axis_data<Box> & split_axis_data,
+ Elements const& sorted_elements,
+ size_t min_elems,
+ size_t max_elems,
+ Translator const& tr)
+ {
+ size_t median_index_last = max_elems - min_elems + 2;
+ for ( size_t median_index = min_elems ; median_index < median_index_last ; ++median_index )
+ {
+ Box left_box = index::detail::elements_box<Box>(sorted_elements.begin(), sorted_elements.begin() + median_index, tr);
+ Box right_box = index::detail::elements_box<Box>(sorted_elements.begin() + median_index, sorted_elements.end(), tr);
+
+ margin_type margin = index::margin(left_box) + index::margin(right_box);
+ overlap_type overlap = index::overlap(left_box, right_box);
+ area_type area = index::area(left_box) + index::area(right_box);
+
+ split_axis_data.update(Corner, median_index, left_box, right_box, margin, overlap, area);
+ }
+ }
+};
+
+// split data
+
+template <typename Elements, typename Box>
+struct rtree_rstar_split_data
+{
+ typedef typename margin_result<Box>::type margin_type;
+ typedef typename overlap_result<Box>::type overlap_type;
+ typedef typename area_result<Box>::type area_type;
+
+ inline rtree_rstar_split_data()
+ : smallest_margins_sum(std::numeric_limits<margin_type>::max())
+ {}
+
+ inline void update(
+ size_t axis,
+ size_t corner,
+ size_t median_index,
+ Box const& left_box,
+ Box const& right_box,
+ margin_type const& margins_sum,
+ Elements const& distribution)
+ {
+ if ( margins_sum < smallest_margins_sum )
+ {
+ choosen_axis = axis;
+ choosen_corner = corner;
+ choosen_median_index = median_index;
+ choosen_left_box = left_box;
+ choosen_right_box = right_box;
+ smallest_margins_sum = margins_sum;
+ choosen_distribution = distribution;
+ }
+ }
+
+ size_t choosen_axis;
+ size_t choosen_corner;
+ size_t choosen_median_index;
+ Box choosen_left_box;
+ Box choosen_right_box;
+ margin_type smallest_margins_sum;
+ Elements choosen_distribution;
+};
+
+// update split data for given axis and corner
+
+template <typename Value, typename Translator, typename Box, size_t AxisIndex, size_t Corner>
+class rtree_rstar_split_update_data_for_axis_and_corner
+{
+ typedef typename rtree_rstar_split_axis_data<Box>::margin_type margin_type;
+ typedef typename rtree_rstar_split_axis_data<Box>::overlap_type overlap_type;
+ typedef typename rtree_rstar_split_axis_data<Box>::area_type area_type;
+
+public:
+ template <typename Elements>
+ static inline void apply(
+ rtree_rstar_split_data<Elements, Box> & split_data,
+ Elements & elements,
+ size_t min_elems,
+ size_t max_elems,
+ Translator const& tr)
+ {
+ rtree_rstar_split_axis_data<Box> split_axis_data;
+
+ rtree_rstar_elements_less<Elements, Translator, AxisIndex, Corner> less_min(tr);
+ std::sort(elements.begin(), elements.end(), less_min);
+
+ rtree_rstar_split_update_axis_data_for_corner<Value, Translator, Box, Corner>::
+ apply(split_axis_data, elements, min_elems, max_elems, tr);
+
+ split_data.update(
+ AxisIndex,
+ split_axis_data.choosen_corner,
+ split_axis_data.choosen_median_index,
+ split_axis_data.choosen_left_box,
+ split_axis_data.choosen_right_box,
+ split_axis_data.margins_sum,
+ elements);
+ }
+};
+
+// for each dimension and corner update split data
+
+template <typename Value, typename Translator, typename Box, size_t Dimension>
+struct rtree_rstar_split_update_data
+{
+ BOOST_STATIC_ASSERT(0 < Dimension);
+
+ template <typename Elements>
+ static inline void apply(
+ rtree_rstar_split_data<Elements, Box> & split_data,
+ Elements & elements,
+ size_t min_elems,
+ size_t max_elems,
+ Translator const& tr)
+ {
+ rtree_rstar_split_update_data<Value, Translator, Box, Dimension - 1>::
+ apply(split_data, elements, min_elems, max_elems, tr);
+
+ rtree_rstar_split_update_data_for_axis_and_corner<Value, Translator, Box, Dimension - 1, min_corner>::
+ apply(split_data, elements, min_elems, max_elems, tr);
+ rtree_rstar_split_update_data_for_axis_and_corner<Value, Translator, Box, Dimension - 1, max_corner>::
+ apply(split_data, elements, min_elems, max_elems, tr);
+ }
+};
+
+template <typename Value, typename Translator, typename Box>
+struct rtree_rstar_split_update_data<Value, Translator, Box, 1>
+{
+ template <typename Elements>
+ static inline void apply(
+ rtree_rstar_split_data<Elements, Box> & split_data,
+ Elements & elements,
+ size_t min_elems,
+ size_t max_elems,
+ Translator const& tr)
+ {
+ rtree_rstar_split_update_data_for_axis_and_corner<Value, Translator, Box, 0, min_corner>::
+ apply(split_data, elements, min_elems, max_elems, tr);
+ rtree_rstar_split_update_data_for_axis_and_corner<Value, Translator, Box, 0, max_corner>::
+ apply(split_data, elements, min_elems, max_elems, tr);
+ }
+};
+
+// split
+
+template <typename Value, typename Translator, typename Box>
+class rtree_rstar_split
+{
+ typedef typename index::detail::rtree_node<Value, Box, rtree_rstar_tag>::type node;
+ typedef typename index::detail::rtree_internal_node<Value, Box, rtree_rstar_tag>::type internal_node;
+ typedef typename index::detail::rtree_leaf<Value, Box, rtree_rstar_tag>::type leaf;
+
+ static const size_t dimension = index::traits::dimension<Box>::value;
+
+public:
+ template <typename Node>
+ static inline void apply(
+ Node & n,
+ internal_node *parent,
+ size_t current_child_index,
+ node *& root,
+ size_t min_elems,
+ size_t max_elems,
+ Translator const& tr)
+ {
+ typedef typename index::detail::rtree_elements_type<Node>::type elements_type;
+ typedef typename elements_type::value_type element_type;
+
+ elements_type & elements = index::detail::get_elements(n);
+
+ // get split data
+ rtree_rstar_split_data<elements_type, Box> split_data;
+ rtree_rstar_split_update_data<Value, Translator, Box, dimension>::
+ apply(split_data, elements, min_elems, max_elems, tr);
+
+ // create new node
+ node * right_node = rtree_create_node(Node());
+ elements_type & new_elems = index::detail::get_elements(boost::get<Node>(*right_node));
+
+ // update new node's elements
+ new_elems.resize(max_elems + 1 - split_data.choosen_median_index);
+ std::copy(
+ split_data.choosen_distribution.begin() + split_data.choosen_median_index,
+ split_data.choosen_distribution.end(),
+ new_elems.begin());
+
+ // update elements of the current node
+ elements.resize(split_data.choosen_median_index);
+ std::copy(
+ split_data.choosen_distribution.begin(),
+ split_data.choosen_distribution.begin() + split_data.choosen_median_index,
+ elements.begin());
+
+ if ( parent != 0 )
+ {
+ // update old node's box
+ parent->children[current_child_index].first = split_data.choosen_left_box;
+ // add new node to the parent's children
+ parent->children.push_back(std::make_pair(split_data.choosen_right_box, right_node));
+ }
+ else
+ {
+ assert(&n == boost::get<Node>(root));
+
+ // create new root and add nodes
+ node * new_root = rtree_create_node(internal_node());
+
+ boost::get<internal_node>(*new_root).children.push_back(std::make_pair(split_data.choosen_left_box, root));
+ boost::get<internal_node>(*new_root).children.push_back(std::make_pair(split_data.choosen_right_box, right_node));
+
+ root = new_root;
+ }
+ }
+};
+
+} // namespace visitors
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_RSTAR_SPLIT_HPP
Modified: sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rtree.hpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rtree.hpp (original)
+++ sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rtree.hpp 2011-03-26 22:21:45 EDT (Sat, 26 Mar 2011)
@@ -41,18 +41,17 @@
typedef typename detail::rtree_internal_node<Value, box_type, rtree_rstar_tag>::type internal_node;
typedef typename detail::rtree_leaf<Value, box_type, rtree_rstar_tag>::type leaf;
- inline explicit rtree(size_t max_elems_per_node = 4, size_t min_elems_per_node = 2, translator_type const& translator = translator_type())
+ inline explicit rtree(size_t max_elems_per_node = 2, size_t min_elems_per_node = 1, translator_type const& translator = translator_type())
: m_values_count(0)
, m_max_elems_per_node(max_elems_per_node)
, m_min_elems_per_node(min_elems_per_node)
, m_root(0)
, m_translator(translator)
{
- if ( min_elems_per_node < 2 )
- min_elems_per_node = 2;
-
- // TODO: awulkiew - reconsider following assert
- assert(2 * m_min_elems_per_node <= m_max_elems_per_node);
+ if ( m_min_elems_per_node < 1 )
+ m_min_elems_per_node = 1;
+ if ( m_max_elems_per_node < 2 )
+ m_max_elems_per_node = 2;
m_root = detail::rtree_create_node(leaf());
}
@@ -82,9 +81,9 @@
}
template <typename Visitor>
- void apply_visitor(Visitor & visitor) const
+ typename Visitor::result_type apply_visitor(Visitor & visitor) const
{
- boost::apply_visitor(visitor, *m_root);
+ return boost::apply_visitor(visitor, *m_root);
}
translator_type const& get_translator() const
Modified: sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rtree_node.hpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rtree_node.hpp (original)
+++ sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/rtree_node.hpp 2011-03-26 22:21:45 EDT (Sat, 26 Mar 2011)
@@ -153,6 +153,24 @@
return tr(el);
};
+// elements box
+
+template <typename Box, typename FwdIter, typename Translator>
+inline Box elements_box(FwdIter first, FwdIter last, Translator const& tr)
+{
+ assert(first != last);
+
+ Box result;
+
+ geometry::convert(index::detail::rtree_element_indexable(*first, tr), result);
+ ++first;
+
+ for ( ; first != last ; ++first )
+ geometry::expand(result, index::detail::rtree_element_indexable(*first, tr));
+
+ return result;
+}
+
// create leaf node
template <typename Value, typename Box, typename Tag>
Modified: sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/visitors/gl_draw.hpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/visitors/gl_draw.hpp (original)
+++ sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/visitors/gl_draw.hpp 2011-03-26 22:21:45 EDT (Sat, 26 Mar 2011)
@@ -27,10 +27,10 @@
template <typename Point>
struct rtree_gl_draw_point<Point, 2>
{
- static inline void apply(Point const& p)
+ static inline void apply(Point const& p, size_t level)
{
glBegin(GL_POINT);
- glVertex2f(geometry::get<0>(p), geometry::get<1>(p));
+ glVertex2f(geometry::get<0>(p), geometry::get<1>(p), level);
glEnd();
}
};
@@ -42,13 +42,13 @@
template <typename Box>
struct rtree_gl_draw_box<Box, 2>
{
- static inline void apply(Box const& b)
+ static inline void apply(Box const& b, size_t level)
{
glBegin(GL_LINE_LOOP);
- glVertex2f(geometry::get<min_corner, 0>(b), geometry::get<min_corner, 1>(b));
- glVertex2f(geometry::get<max_corner, 0>(b), geometry::get<min_corner, 1>(b));
- glVertex2f(geometry::get<max_corner, 0>(b), geometry::get<max_corner, 1>(b));
- glVertex2f(geometry::get<min_corner, 0>(b), geometry::get<max_corner, 1>(b));
+ glVertex3f(geometry::get<min_corner, 0>(b), geometry::get<min_corner, 1>(b), level);
+ glVertex3f(geometry::get<max_corner, 0>(b), geometry::get<min_corner, 1>(b), level);
+ glVertex3f(geometry::get<max_corner, 0>(b), geometry::get<max_corner, 1>(b), level);
+ glVertex3f(geometry::get<min_corner, 0>(b), geometry::get<max_corner, 1>(b), level);
glEnd();
}
};
@@ -64,9 +64,9 @@
typedef typename geometry::traits::point_type<Indexable>::type point_type;
static const size_t dimension = geometry::traits::dimension<point_type>::value;
- static inline void apply(Indexable const& i)
+ static inline void apply(Indexable const& i, size_t level)
{
- rtree_gl_draw_box<Indexable, dimension>::apply(i);
+ rtree_gl_draw_box<Indexable, dimension>::apply(i, level);
}
};
@@ -75,9 +75,9 @@
{
static const size_t dimension = geometry::traits::dimension<Indexable>::value;
- static inline void apply(std::ostream &os, Indexable const& i)
+ static inline void apply(Indexable const& i, size_t level)
{
- rtree_gl_draw_point<Indexable, dimension>::apply(i);
+ rtree_gl_draw_point<Indexable, dimension>::apply(i, level);
}
};
@@ -86,12 +86,12 @@
namespace detail {
template <typename Indexable>
-inline void rtree_gl_draw_indexable(Indexable const& i)
+inline void rtree_gl_draw_indexable(Indexable const& i, size_t level)
{
dispatch::rtree_gl_draw_indexable<
Indexable,
typename geometry::traits::tag<Indexable>::type
- >::apply(i);
+ >::apply(i, level);
}
} // namespace detail
@@ -128,7 +128,7 @@
for (typename children_type::const_iterator it = n.children.begin();
it != n.children.end(); ++it)
{
- detail::rtree_gl_draw_indexable(it->first);
+ detail::rtree_gl_draw_indexable(it->first, level);
}
size_t level_backup = level;
@@ -152,7 +152,7 @@
for (typename values_type::const_iterator it = n.values.begin();
it != n.values.end(); ++it)
{
- detail::rtree_gl_draw_indexable(tr(*it));
+ detail::rtree_gl_draw_indexable(tr(*it), level);
}
}
Modified: sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/visitors/print.hpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/visitors/print.hpp (original)
+++ sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/visitors/print.hpp 2011-03-26 22:21:45 EDT (Sat, 26 Mar 2011)
@@ -128,22 +128,15 @@
{
typedef typename internal_node::children_type children_type;
- os << " --> Node --------" << std::endl;
- os << " Address: " << this << std::endl;
- os << " Level: " << level << std::endl;
- os << " Children: " << n.children.size() << std::endl;
- os << " | ";
-
+ spaces(level) << "INTERNAL NODE - L:" << level << " Ch:" << n.children.size() << " @:" << &n << '\n';
+
for (typename children_type::const_iterator it = n.children.begin();
it != n.children.end(); ++it)
{
+ spaces(level);
detail::rtree_print_indexable(os, it->first);
- os << " | ";
+ os << " ->" << it->second << '\n';
}
- os << std::endl;
- os << " --< Node --------" << std::endl;
-
- os << " Children: " << std::endl;
size_t level_backup = level;
++level;
@@ -161,17 +154,21 @@
{
typedef typename leaf::values_type values_type;
- os << "\t" << " --> Leaf --------" << std::endl;
- os << "\t" << " Values: " << n.values.size() << std::endl;
+ spaces(level) << "LEAF - L:" << level << " V:" << n.values.size() << " @:" << &n << '\n';
for (typename values_type::const_iterator it = n.values.begin();
it != n.values.end(); ++it)
{
- os << "\t" << " | ";
+ spaces(level);
detail::rtree_print_indexable(os, tr(*it));
- os << " | " << std::endl;;
+ os << '\n';
}
- os << "\t" << " --< Leaf --------" << std::endl;
+ }
+ inline std::ostream & spaces(size_t level)
+ {
+ for ( size_t i = 0 ; i < 2 * level ; ++i )
+ os << ' ';
+ return os;
}
std::ostream & os;
Added: sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/visitors/rtree_are_boxes_ok.hpp
==============================================================================
--- (empty file)
+++ sandbox-branches/geometry/index_080_new/boost/geometry/extensions/index/rtree/visitors/rtree_are_boxes_ok.hpp 2011-03-26 22:21:45 EDT (Sat, 26 Mar 2011)
@@ -0,0 +1,103 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Boost.Index - R-tree boxes checking visitor
+//
+// 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)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_ARE_BOXES_OK_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_ARE_BOXES_OK_HPP
+
+#include <boost/geometry/algorithms//equals.hpp>
+#include <boost/geometry/extensions/index/rtree/rtree_node.hpp>
+
+namespace boost { namespace geometry { namespace index {
+
+namespace visitors {
+
+template <typename Value, typename Translator, typename Box, typename Tag>
+class rtree_are_boxes_ok : public boost::static_visitor<bool>
+{
+ typedef typename index::detail::rtree_internal_node<Value, Box, Tag>::type internal_node;
+ typedef typename index::detail::rtree_leaf<Value, Box, Tag>::type leaf;
+
+public:
+ inline rtree_are_boxes_ok(Translator const& tr)
+ : m_tr(tr), m_is_root(true)
+ {}
+
+ inline bool operator()(internal_node const& n)
+ {
+ if (n.children.empty())
+ return false;
+
+ Box box_bckup = m_box;
+ bool is_root_bckup = m_is_root;
+
+ m_is_root = false;
+
+ for ( internal_node::children_type::const_iterator it = n.children.begin();
+ it != n.children.end() ; ++it)
+ {
+ m_box = it->first;
+
+ if ( false == boost::apply_visitor(*this, *it->second) )
+ return false;
+ }
+
+ m_box = box_bckup;
+ m_is_root = is_root_bckup;
+
+ Box result;
+ geometry::convert(n.children.front().first, result);
+ for(internal_node::children_type::const_iterator it = n.children.begin() + 1;
+ it != n.children.end() ; ++it)
+ {
+ geometry::expand(result, it->first);
+ }
+
+ return m_is_root || geometry::equals(result, m_box);
+ }
+
+ inline bool operator()(leaf const& n)
+ {
+ if (n.values.empty())
+ return false;
+
+ Box result;
+ geometry::convert(m_tr(n.values.front()), result);
+ for(leaf::values_type::const_iterator it = n.values.begin() + 1;
+ it != n.values.end() ; ++it)
+ {
+ geometry::expand(result, m_tr(*it));
+ }
+
+ return m_is_root || geometry::equals(result, m_box);
+ }
+
+private:
+ Translator const& m_tr;
+ Box m_box;
+ bool m_is_root;
+};
+
+} // namespace visitors
+
+template <typename Value, typename Translator, typename Box, typename Tag>
+bool rtree_are_boxes_ok(rtree<Value, Translator, Box, Tag> const& tree)
+{
+ typedef rtree<Value, Translator, Box, Tag> rt;
+ visitors::rtree_are_boxes_ok<
+ typename rt::value_type,
+ typename rt::translator_type,
+ typename rt::box_type,
+ Tag> v(tree.get_translator());
+
+ return tree.apply_visitor(v);
+}
+
+}}} // namespace boost::geometry::index
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_RTREE_VISITORS_RTREE_ARE_BOXES_OK_HPP
Modified: sandbox-branches/geometry/index_080_new/tests/additional_glut_vis.cpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/tests/additional_glut_vis.cpp (original)
+++ sandbox-branches/geometry/index_080_new/tests/additional_glut_vis.cpp 2011-03-26 22:21:45 EDT (Sat, 26 Mar 2011)
@@ -4,10 +4,12 @@
#include <boost/geometry/extensions/index/rtree/rtree.hpp>
#include <boost/geometry/extensions/index/rtree/visitors/gl_draw.hpp>
+#include <boost/geometry/extensions/index/rtree/visitors/print.hpp>
+#include <boost/geometry/extensions/index/rtree/visitors/rtree_are_boxes_ok.hpp>
typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> P;
typedef boost::geometry::model::box<P> B;
-boost::geometry::index::rtree<B> t;
+boost::geometry::index::rtree<B> t(2, 1);
void render_scene(void)
{
@@ -30,8 +32,8 @@
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(
- 5.0f, 5.0f, 15.0f,
- 5.0f, 5.0f, -1.0f,
+ 150.0f, 150.0f, 150.0f,
+ 50.0f, 50.0f, -1.0f,
0.0f, 1.0f, 0.0f);
}
@@ -39,12 +41,21 @@
{
if ( state == GLUT_DOWN )
{
- float x = ( rand() % 10000 ) / 1000.0f;
- float y = ( rand() % 10000 ) / 1000.0f;
- float w = ( rand() % 10000 ) / 100000.0f;
- float h = ( rand() % 10000 ) / 100000.0f;
-
- boost::geometry::index::insert(t, B(P(x - w, y - h),P(x + w, y + h)));
+ float x = ( rand() % 100 );
+ float y = ( rand() % 100 );
+ float w = ( rand() % 2 ) + 1;
+ float h = ( rand() % 2 ) + 1;
+
+ B b(P(x - w, y - h),P(x + w, y + h));
+
+ boost::geometry::index::insert(t, b);
+
+ std::cout << "\n\n\n" << t << "\n\n";
+
+ std::cout << "inserted: ";
+ boost::geometry::index::visitors::detail::rtree_print_indexable(std::cout, b);
+ std::cout << '\n';
+ std::cout << ( boost::geometry::index::rtree_are_boxes_ok(t) ? "boxes OK" : "WRONG BOXES!" );
glutPostRedisplay();
}
Modified: sandbox-branches/geometry/index_080_new/tests/additional_sizes_and_times.cpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/tests/additional_sizes_and_times.cpp (original)
+++ sandbox-branches/geometry/index_080_new/tests/additional_sizes_and_times.cpp 2011-03-26 22:21:45 EDT (Sat, 26 Mar 2011)
@@ -29,10 +29,10 @@
std::vector<B> v(n);
for ( size_t i = 0 ; i < n ; ++i )
{
- float x = ( rand() % 10000 ) / 1000.0f;
- float y = ( rand() % 10000 ) / 1000.0f;
- float w = ( rand() % 10000 ) / 100000.0f;
- float h = ( rand() % 10000 ) / 100000.0f;
+ float x = float( rand() % 1000 );
+ float y = float( rand() % 1000 );
+ float w = float( rand() % 10 ) / 10.0f;
+ float h = float( rand() % 10 ) / 10.0f;
v[i] = B(P(x - w, y - h),P(x + w, y + h));
}
Modified: sandbox-branches/geometry/index_080_new/tests/main.cpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/tests/main.cpp (original)
+++ sandbox-branches/geometry/index_080_new/tests/main.cpp 2011-03-26 22:21:45 EDT (Sat, 26 Mar 2011)
@@ -8,6 +8,19 @@
tests_rtree_native_hpp();
tests_rtree_filters_hpp();
+ /*namespace g = boost::geometry;
+ typedef g::model::point<float, 2, g::cs::cartesian> P;
+ typedef g::model::box<P> B;
+
+ g::index::rtree<B> tree(4, 2);
+ g::index::insert(tree, B(P(1, 6),P(6, 19)));
+ g::index::insert(tree, B(P(10, 1),P(18, 18)));
+ g::index::insert(tree, B(P(22, 6),P(27, 20)));
+ g::index::insert(tree, B(P(29, 2),P(34, 18)));
+ g::index::insert(tree, B(P(35, 3),P(39, 19)));
+
+ std::cout << tree;*/
+
#ifdef _MSC_VER
std::cin.get();
#endif
Modified: sandbox-branches/geometry/index_080_new/tests/rtree_native.hpp
==============================================================================
--- sandbox-branches/geometry/index_080_new/tests/rtree_native.hpp (original)
+++ sandbox-branches/geometry/index_080_new/tests/rtree_native.hpp 2011-03-26 22:21:45 EDT (Sat, 26 Mar 2011)
@@ -17,7 +17,24 @@
{
std::cout << "tests/rtree_native.hpp\n";
- std::cout << "Boxes\n";
+ std::cout << "Boxes3d\n";
+ {
+ typedef boost::geometry::model::point<float, 3, boost::geometry::cs::cartesian> P;
+ typedef boost::geometry::model::box<P> B;
+
+ boost::geometry::index::rtree<B> t(4, 2);
+ boost::geometry::index::insert(t, B(P(0, 0, 0), P(1, 1, 1)));
+ boost::geometry::index::insert(t, B(P(2, 2, 2), P(3, 3, 3)));
+ boost::geometry::index::insert(t, B(P(4, 4, 4), P(5, 5, 5)));
+ boost::geometry::index::insert(t, B(P(6, 6, 6), P(7, 7, 7)));
+ boost::geometry::index::insert(t, B(P(8, 8, 8), P(9, 9, 9)));
+ std::cerr << t;
+ }
+
+ std::cout << "-------------------------------------------------\n";
+ std::cout << "-------------------------------------------------\n";
+
+ std::cout << "Boxes2d\n";
{
typedef boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian> P;
typedef boost::geometry::model::box<P> B;
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