From 45970c56964aae860f7f43cefa38ce37b855b161 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 19 Jun 2013 23:00:12 +0000 Subject: [PATCH] [geometry][index]: implemented version of linear find_greatest_normalized_separation optimized for Points. Removed index::detail::traits, the official ones used instead. [SVN r84840] --- .../comparable_distance_centroid.hpp | 8 +- .../algorithms/comparable_distance_far.hpp | 8 +- .../algorithms/comparable_distance_near.hpp | 8 +- .../index/detail/algorithms/content.hpp | 6 +- .../index/detail/algorithms/diff_abs.hpp | 17 ++- .../index/detail/algorithms/is_valid.hpp | 12 +- .../index/detail/algorithms/margin.hpp | 2 - .../index/detail/algorithms/minmaxdist.hpp | 8 +- .../detail/algorithms/path_intersection.hpp | 12 +- .../algorithms/segment_intersection.hpp | 20 ++- .../detail/algorithms/sum_for_indexable.hpp | 2 - .../boost/geometry/index/detail/indexable.hpp | 139 ----------------- .../rtree/linear/redistribute_elements.hpp | 140 +++++++++++++----- .../rtree/quadratic/redistribute_elements.hpp | 4 +- .../rtree/rstar/redistribute_elements.hpp | 56 +++++-- .../index/detail/rtree/utilities/gl_draw.hpp | 24 ++- .../index/detail/rtree/utilities/print.hpp | 6 +- .../detail/rtree/utilities/statistics.hpp | 1 - include/boost/geometry/index/rtree.hpp | 10 +- 19 files changed, 228 insertions(+), 255 deletions(-) delete mode 100644 include/boost/geometry/index/detail/indexable.hpp diff --git a/include/boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp b/include/boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp index 269a2c9c3..841876eb3 100644 --- a/include/boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp +++ b/include/boost/geometry/index/detail/algorithms/comparable_distance_centroid.hpp @@ -42,8 +42,8 @@ struct sum_for_indexable_dimension::type point_coord_t; - typedef typename index::detail::traits::coordinate_type::type indexable_coord_t; + typedef typename coordinate_type::type point_coord_t; + typedef typename coordinate_type::type indexable_coord_t; point_coord_t pt_c = geometry::get(pt); indexable_coord_t ind_c_min = geometry::get(i); @@ -65,9 +65,9 @@ comparable_distance_centroid(Point const& pt, Indexable const& i) return detail::sum_for_indexable< Point, Indexable, - typename index::detail::traits::tag::type, + typename tag::type, detail::comparable_distance_centroid_tag, - index::detail::traits::dimension::value + dimension::value >::apply(pt, i); } diff --git a/include/boost/geometry/index/detail/algorithms/comparable_distance_far.hpp b/include/boost/geometry/index/detail/algorithms/comparable_distance_far.hpp index 1646a82d6..07dfcfc0f 100644 --- a/include/boost/geometry/index/detail/algorithms/comparable_distance_far.hpp +++ b/include/boost/geometry/index/detail/algorithms/comparable_distance_far.hpp @@ -30,8 +30,8 @@ struct sum_for_indexable_dimension::type point_coord_t; - typedef typename index::detail::traits::coordinate_type::type indexable_coord_t; + typedef typename coordinate_type::type point_coord_t; + typedef typename coordinate_type::type indexable_coord_t; point_coord_t pt_c = geometry::get(pt); indexable_coord_t ind_c_min = geometry::get(i); @@ -55,9 +55,9 @@ comparable_distance_far(Point const& pt, Indexable const& i) return detail::sum_for_indexable< Point, Indexable, - typename index::detail::traits::tag::type, + typename tag::type, detail::comparable_distance_far_tag, - index::detail::traits::dimension::value + dimension::value >::apply(pt, i); } diff --git a/include/boost/geometry/index/detail/algorithms/comparable_distance_near.hpp b/include/boost/geometry/index/detail/algorithms/comparable_distance_near.hpp index 221d3ee3f..5584bf85e 100644 --- a/include/boost/geometry/index/detail/algorithms/comparable_distance_near.hpp +++ b/include/boost/geometry/index/detail/algorithms/comparable_distance_near.hpp @@ -41,8 +41,8 @@ struct sum_for_indexable_dimension::type point_coord_t; - typedef typename index::detail::traits::coordinate_type::type indexable_coord_t; + typedef typename coordinate_type::type point_coord_t; + typedef typename coordinate_type::type indexable_coord_t; point_coord_t pt_c = geometry::get(pt); indexable_coord_t ind_c_min = geometry::get(i); @@ -66,9 +66,9 @@ comparable_distance_near(Point const& pt, Indexable const& i) return detail::sum_for_indexable< Point, Indexable, - typename index::detail::traits::tag::type, + typename tag::type, detail::comparable_distance_near_tag, - index::detail::traits::dimension::value + dimension::value >::apply(pt, i); } diff --git a/include/boost/geometry/index/detail/algorithms/content.hpp b/include/boost/geometry/index/detail/algorithms/content.hpp index 1b6e370a1..1c4739d8e 100644 --- a/include/boost/geometry/index/detail/algorithms/content.hpp +++ b/include/boost/geometry/index/detail/algorithms/content.hpp @@ -11,8 +11,6 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP -#include - namespace boost { namespace geometry { namespace index { namespace detail { template @@ -35,7 +33,7 @@ struct content_box static inline typename detail::default_content_result::type apply(Box const& b) { return content_box::apply(b) * - ( detail::get(b) - detail::get(b) ); + ( get(b) - get(b) ); } }; @@ -44,7 +42,7 @@ struct content_box { static inline typename detail::default_content_result::type apply(Box const& b) { - return detail::get(b) - detail::get(b); + return get(b) - get(b); } }; diff --git a/include/boost/geometry/index/detail/algorithms/diff_abs.hpp b/include/boost/geometry/index/detail/algorithms/diff_abs.hpp index a89784d7f..ec63bd9a5 100644 --- a/include/boost/geometry/index/detail/algorithms/diff_abs.hpp +++ b/include/boost/geometry/index/detail/algorithms/diff_abs.hpp @@ -14,11 +14,26 @@ namespace boost { namespace geometry { namespace index { namespace detail { template -inline T diff_abs(T const& v1, T const& v2) +inline T diff_abs_dispatch(T const& v1, T const& v2, boost::mpl::bool_ const& /*is_integral*/) { return v1 < v2 ? v2 - v1 : v1 - v2; } +template +inline T diff_abs_dispatch(T const& v1, T const& v2, boost::mpl::bool_ const& /*is_integral*/) +{ + return ::fabs(v1 - v2); +} + +template +inline T diff_abs(T const& v1, T const& v2) +{ + typedef boost::mpl::bool_< + boost::is_integral::value + > is_integral; + return diff_abs_dispatch(v1, v2, is_integral()); +} + }}}} // namespace boost::geometry::index::detail #endif // BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_DIFF_ABS_HPP diff --git a/include/boost/geometry/index/detail/algorithms/is_valid.hpp b/include/boost/geometry/index/detail/algorithms/is_valid.hpp index 65716a57d..56c164dae 100644 --- a/include/boost/geometry/index/detail/algorithms/is_valid.hpp +++ b/include/boost/geometry/index/detail/algorithms/is_valid.hpp @@ -11,8 +11,6 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP -#include - namespace boost { namespace geometry { namespace index { namespace detail { namespace dispatch { @@ -21,14 +19,14 @@ template struct is_valid_box { BOOST_MPL_ASSERT_MSG( - (0 < Dimension && Dimension <= detail::traits::dimension::value), + (0 < Dimension && Dimension <= dimension::value), INVALID_DIMENSION_PARAMETER, (is_valid_box)); static inline bool apply(Box const& b) { return is_valid_box::apply(b) && - ( detail::get(b) <= detail::get(b) ); + ( get(b) <= get(b) ); } }; @@ -37,7 +35,7 @@ struct is_valid_box { static inline bool apply(Box const& b) { - return detail::get(b) <= detail::get(b); + return get(b) <= get(b); } }; @@ -64,7 +62,7 @@ struct is_valid { static inline bool apply(Indexable const& b) { - return dispatch::is_valid_box::value>::apply(b); + return dispatch::is_valid_box::value>::apply(b); } }; @@ -73,7 +71,7 @@ struct is_valid template inline bool is_valid(Indexable const& b) { - return dispatch::is_valid::type>::apply(b); + return dispatch::is_valid::type>::apply(b); } }}}} // namespace boost::geometry::index::detail diff --git a/include/boost/geometry/index/detail/algorithms/margin.hpp b/include/boost/geometry/index/detail/algorithms/margin.hpp index 7389ec72d..501181271 100644 --- a/include/boost/geometry/index/detail/algorithms/margin.hpp +++ b/include/boost/geometry/index/detail/algorithms/margin.hpp @@ -11,8 +11,6 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP -#include - // WARNING! comparable_margin() will work only if the same Geometries are compared // so it shouldn't be used in the case of Variants! diff --git a/include/boost/geometry/index/detail/algorithms/minmaxdist.hpp b/include/boost/geometry/index/detail/algorithms/minmaxdist.hpp index d2429cbb2..680fb202b 100644 --- a/include/boost/geometry/index/detail/algorithms/minmaxdist.hpp +++ b/include/boost/geometry/index/detail/algorithms/minmaxdist.hpp @@ -32,8 +32,8 @@ struct smallest_for_indexable_dimension::type point_coord_t; - typedef typename index::traits::coordinate_type::type indexable_coord_t; + typedef typename coordinate_type::type point_coord_t; + typedef typename coordinate_type::type indexable_coord_t; point_coord_t pt_c = geometry::get(pt); indexable_coord_t ind_c_min = geometry::get(i); @@ -95,7 +95,7 @@ struct minmaxdist_impl Indexable, box_tag, minmaxdist_tag, - index::traits::dimension::value + dimension::value >::apply(pt, i, maxd); } }; @@ -110,7 +110,7 @@ minmaxdist(Point const& pt, Indexable const& i) return detail::minmaxdist_impl< Point, Indexable, - typename index::traits::tag::type + typename tag::type >::apply(pt, i); } diff --git a/include/boost/geometry/index/detail/algorithms/path_intersection.hpp b/include/boost/geometry/index/detail/algorithms/path_intersection.hpp index 0bdb6552f..a9e0f3dcb 100644 --- a/include/boost/geometry/index/detail/algorithms/path_intersection.hpp +++ b/include/boost/geometry/index/detail/algorithms/path_intersection.hpp @@ -26,11 +26,11 @@ struct path_intersection template struct path_intersection { - typedef typename default_distance_result::type>::type comparable_distance_type; + typedef typename default_distance_result::type>::type comparable_distance_type; static inline bool apply(Indexable const& b, Segment const& segment, comparable_distance_type & comparable_distance) { - typedef typename ::boost::geometry::traits::point_type::type point_type; + typedef typename point_type::type point_type; point_type p1, p2; geometry::detail::assign_point_from_index<0>(segment, p1); geometry::detail::assign_point_from_index<1>(segment, p2); @@ -90,8 +90,8 @@ struct default_path_intersection_distance_type { typedef typename dispatch::path_intersection< Indexable, SegmentOrLinestring, - typename detail::traits::tag::type, - typename detail::traits::tag::type + typename tag::type, + typename tag::type >::comparable_distance_type type; }; @@ -104,8 +104,8 @@ bool path_intersection(Indexable const& b, return dispatch::path_intersection< Indexable, SegmentOrLinestring, - typename detail::traits::tag::type, - typename detail::traits::tag::type + typename tag::type, + typename tag::type >::apply(b, path, comparable_distance); } diff --git a/include/boost/geometry/index/detail/algorithms/segment_intersection.hpp b/include/boost/geometry/index/detail/algorithms/segment_intersection.hpp index f1e41d6dc..4ae82c6ba 100644 --- a/include/boost/geometry/index/detail/algorithms/segment_intersection.hpp +++ b/include/boost/geometry/index/detail/algorithms/segment_intersection.hpp @@ -11,8 +11,6 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SEGMENT_INTERSECTION_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SEGMENT_INTERSECTION_HPP -#include - namespace boost { namespace geometry { namespace index { namespace detail { //template @@ -20,8 +18,8 @@ namespace boost { namespace geometry { namespace index { namespace detail { //{ // typedef typename select_most_precise< // typename select_most_precise< -// typename traits::coordinate_type::type, -// typename traits::coordinate_type::type +// typename coordinate_type::type, +// typename coordinate_type::type // >::type, // float // TODO - use bigger type, calculated from the size of coordinate types // >::type type; @@ -36,9 +34,9 @@ namespace dispatch { template struct box_segment_intersection_dim { - BOOST_STATIC_ASSERT(I < traits::dimension::value); - BOOST_STATIC_ASSERT(I < traits::dimension::value); - BOOST_STATIC_ASSERT(traits::dimension::value == traits::dimension::value); + BOOST_STATIC_ASSERT(I < dimension::value); + BOOST_STATIC_ASSERT(I < dimension::value); + BOOST_STATIC_ASSERT(dimension::value == dimension::value); // WARNING! - RelativeDistance must be IEEE float for this to work @@ -47,8 +45,8 @@ struct box_segment_intersection_dim RelativeDistance & t_near, RelativeDistance & t_far) { RelativeDistance ray_d = geometry::get(p1) - geometry::get(p0); - RelativeDistance tn = ( detail::get(b) - geometry::get(p0) ) / ray_d; - RelativeDistance tf = ( detail::get(b) - geometry::get(p0) ) / ray_d; + RelativeDistance tn = ( geometry::get(b) - geometry::get(p0) ) / ray_d; + RelativeDistance tf = ( geometry::get(b) - geometry::get(p0) ) / ray_d; if ( tf < tn ) ::std::swap(tn, tf); @@ -105,7 +103,7 @@ struct segment_intersection template struct segment_intersection { - typedef dispatch::box_segment_intersection::value> impl; + typedef dispatch::box_segment_intersection::value> impl; template static inline bool apply(Indexable const& b, Point const& p0, Point const& p1, RelativeDistance & relative_distance) @@ -134,7 +132,7 @@ bool segment_intersection(Indexable const& b, return dispatch::segment_intersection< Indexable, Point, - typename detail::traits::tag::type + typename tag::type >::apply(b, p0, p1, relative_distance); } diff --git a/include/boost/geometry/index/detail/algorithms/sum_for_indexable.hpp b/include/boost/geometry/index/detail/algorithms/sum_for_indexable.hpp index ebe9fee93..4aef36352 100644 --- a/include/boost/geometry/index/detail/algorithms/sum_for_indexable.hpp +++ b/include/boost/geometry/index/detail/algorithms/sum_for_indexable.hpp @@ -11,8 +11,6 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SUM_FOR_INDEXABLE_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_SUM_FOR_INDEXABLE_HPP -#include - namespace boost { namespace geometry { namespace index { namespace detail { template < diff --git a/include/boost/geometry/index/detail/indexable.hpp b/include/boost/geometry/index/detail/indexable.hpp deleted file mode 100644 index f0791b170..000000000 --- a/include/boost/geometry/index/detail/indexable.hpp +++ /dev/null @@ -1,139 +0,0 @@ -// Boost.Geometry Index -// -// Indexable's traits and related functions -// -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. -// -// 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_INDEX_DETAIL_INDEXABLE_HPP -#define BOOST_GEOMETRY_INDEX_DETAIL_INDEXABLE_HPP - -namespace boost { namespace geometry { namespace index { namespace detail { - -namespace dispatch { - -template -struct point_type -{ - typedef void type; -}; - -template -struct point_type -{ - typedef typename geometry::traits::point_type::type type; -}; - -template -struct point_type -{ - typedef Indexable type; -}; - -} // namespace dispatch - -namespace traits { - -template -struct point_type -{ - typedef typename dispatch::point_type< - Indexable, - typename geometry::traits::tag::type - >::type type; -}; - -template -struct coordinate_system -{ - typedef typename geometry::traits::coordinate_system< - typename point_type::type - >::type type; -}; - -template -struct coordinate_type -{ - typedef typename geometry::traits::coordinate_type< - typename point_type::type - >::type type; -}; - -template -struct dimension -{ - static const size_t value = - geometry::traits::dimension< - typename point_type::type - >::value; -}; - -template -struct tag -{ - typedef typename geometry::traits::tag< - Indexable - >::type type; -}; - -} // namespace traits - -namespace dispatch { - -template -struct indexable_indexed_access {}; - -template -struct indexable_indexed_access -{ - typedef typename traits::point_type::type point_type; - typedef typename traits::coordinate_type::type coordinate_type; - - static inline coordinate_type get(Indexable const& i) - { - return geometry::get(i); - } -}; - -template -struct indexable_indexed_access -{ - typedef typename traits::coordinate_type::type coordinate_type; - - static inline coordinate_type get(Indexable const& i) - { - return geometry::get(i); - } -}; - -} // namespace dispatch - -template -typename traits::coordinate_type::type get(Indexable const& i) -{ - return dispatch::indexable_indexed_access< - Corner, - DimensionIndex, - Indexable, - typename geometry::traits::tag::type - >::get(i); -} - -template -struct default_box_type -{ - typedef geometry::model::box< - geometry::model::point< - typename traits::coordinate_type::type, - traits::dimension::value, - typename traits::coordinate_system::type - > - > type; -}; - -}}}} // namespace boost::geometry::index::detail - -#endif // BOOST_GEOMETRY_INDEX_DETAIL_INDEXABLE_HPP diff --git a/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp index 48aa032d3..ef36faecb 100644 --- a/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp @@ -26,21 +26,49 @@ namespace detail { namespace rtree { namespace linear { +template +inline R difference_dispatch(T const& from, T const& to, ::boost::mpl::bool_ const& /*is_unsigned*/) +{ + return to - from; +} + +template +inline R difference_dispatch(T const& from, T const& to, ::boost::mpl::bool_ const& /*is_unsigned*/) +{ + return from <= to ? R(to - from) : -R(from - to); +} + +template +inline R difference(T const& from, T const& to) +{ + BOOST_MPL_ASSERT_MSG(!boost::is_unsigned::value, RESULT_CANT_BE_UNSIGNED, (R)); + + typedef ::boost::mpl::bool_< + boost::is_unsigned::value + > is_unsigned; + + return difference_dispatch(from, to, is_unsigned()); +} + // TODO: awulkiew - there are loops inside find_greatest_normalized_separation::apply() // iteration is done for each DimensionIndex. // Separations and seeds for all DimensionIndex(es) could be calculated at once, stored, then the greatest would be choosen. -// TODO: Implement separate version for Points - // The following struct/method was adapted for the preliminary version of the R-tree. Then it was called: // void find_normalized_separations(std::vector const& boxes, T& separation, unsigned int& first, unsigned int& second) const -template +template struct find_greatest_normalized_separation +{ + BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag)); +}; + +template +struct find_greatest_normalized_separation { typedef typename Elements::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename index::detail::traits::coordinate_type::type coordinate_type; + typedef typename coordinate_type::type coordinate_type; typedef typename boost::mpl::if_c< boost::is_integral::value, @@ -48,10 +76,6 @@ struct find_greatest_normalized_separation coordinate_type >::type separation_type; - typedef ::boost::mpl::bool_< - boost::is_unsigned::value - > is_coordinate_type_unsigned; - static inline void apply(Elements const& elements, Parameters const& parameters, Translator const& translator, @@ -64,15 +88,15 @@ struct find_greatest_normalized_separation BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements"); // find the lowest low, highest high - coordinate_type lowest_low = index::detail::get(rtree::element_indexable(elements[0], translator)); - coordinate_type highest_high = index::detail::get(rtree::element_indexable(elements[0], translator)); + coordinate_type lowest_low = geometry::get(rtree::element_indexable(elements[0], translator)); + coordinate_type highest_high = geometry::get(rtree::element_indexable(elements[0], translator)); // and the lowest high coordinate_type lowest_high = highest_high; size_t lowest_high_index = 0; for ( size_t i = 1 ; i < elements_count ; ++i ) { - coordinate_type min_coord = index::detail::get(rtree::element_indexable(elements[i], translator)); - coordinate_type max_coord = index::detail::get(rtree::element_indexable(elements[i], translator)); + coordinate_type min_coord = geometry::get(rtree::element_indexable(elements[i], translator)); + coordinate_type max_coord = geometry::get(rtree::element_indexable(elements[i], translator)); if ( max_coord < lowest_high ) { @@ -89,10 +113,10 @@ struct find_greatest_normalized_separation // find the highest low size_t highest_low_index = lowest_high_index == 0 ? 1 : 0; - coordinate_type highest_low = index::detail::get(rtree::element_indexable(elements[highest_low_index], translator)); + coordinate_type highest_low = geometry::get(rtree::element_indexable(elements[highest_low_index], translator)); for ( size_t i = highest_low_index ; i < elements_count ; ++i ) { - coordinate_type min_coord = index::detail::get(rtree::element_indexable(elements[i], translator)); + coordinate_type min_coord = geometry::get(rtree::element_indexable(elements[i], translator)); if ( highest_low < min_coord && i != lowest_high_index ) { @@ -103,7 +127,8 @@ struct find_greatest_normalized_separation coordinate_type const width = highest_high - lowest_low; - separation = difference(highest_low, lowest_high, is_coordinate_type_unsigned()); + // highest_low - lowest_high + separation = difference(lowest_high, highest_low); // BOOST_ASSERT(0 <= width); if ( std::numeric_limits::epsilon() < width ) separation /= width; @@ -113,21 +138,60 @@ struct find_greatest_normalized_separation BOOST_GEOMETRY_INDEX_DETAIL_USE_PARAM(parameters) } +}; - static inline separation_type difference(coordinate_type const& highest_low, - coordinate_type const& lowest_high, - ::boost::mpl::bool_ const& /*is_unsigned*/) - { - return (highest_low - lowest_high); - } +// Version for points doesn't calculate normalized separation since it would always be equal to 1 +// It returns two seeds most distant to each other, separation is equal to distance +template +struct find_greatest_normalized_separation +{ + typedef typename Elements::value_type element_type; + typedef typename rtree::element_indexable_type::type indexable_type; + typedef typename coordinate_type::type coordinate_type; - static inline separation_type difference(coordinate_type const& highest_low, - coordinate_type const& lowest_high, - ::boost::mpl::bool_ const& /*is_unsigned*/) + typedef coordinate_type separation_type; + + static inline void apply(Elements const& elements, + Parameters const& parameters, + Translator const& translator, + separation_type & separation, + size_t & seed1, + size_t & seed2) { - return lowest_high <= highest_low ? - separation_type(highest_low - lowest_high) : - -separation_type(lowest_high - highest_low); + const size_t elements_count = parameters.get_max_elements() + 1; + BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "unexpected number of elements"); + BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements"); + + // find the lowest low, highest high + coordinate_type lowest = geometry::get(rtree::element_indexable(elements[0], translator)); + coordinate_type highest = geometry::get(rtree::element_indexable(elements[0], translator)); + size_t lowest_index = 0; + size_t highest_index = 0; + for ( size_t i = 1 ; i < elements_count ; ++i ) + { + coordinate_type coord = geometry::get(rtree::element_indexable(elements[i], translator)); + + if ( coord < lowest ) + { + lowest = coord; + lowest_index = i; + } + + if ( highest < coord ) + { + highest = coord; + highest_index = i; + } + } + + separation = highest - lowest; + seed1 = lowest_index; + seed2 = highest_index; + + if ( lowest_index == highest_index ) + seed2 = (lowest_index + 1) % elements_count; // % is just in case since if this is true lowest_index is 0 + + BOOST_GEOMETRY_INDEX_DETAIL_USE_PARAM(parameters) } }; @@ -138,9 +202,13 @@ struct pick_seeds_impl typedef typename Elements::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename index::detail::traits::coordinate_type::type coordinate_type; + typedef typename coordinate_type::type coordinate_type; + + typedef find_greatest_normalized_separation< + Elements, Parameters, Translator, + typename tag::type, Dimension - 1 + > find_norm_sep; - typedef find_greatest_normalized_separation find_norm_sep; typedef typename find_norm_sep::separation_type separation_type; static inline void apply(Elements const& elements, @@ -171,9 +239,13 @@ struct pick_seeds_impl { typedef typename Elements::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename index::detail::traits::coordinate_type::type coordinate_type; + typedef typename coordinate_type::type coordinate_type; + + typedef find_greatest_normalized_separation< + Elements, Parameters, Translator, + typename tag::type, 0 + > find_norm_sep; - typedef find_greatest_normalized_separation find_norm_sep; typedef typename find_norm_sep::separation_type separation_type; static inline void apply(Elements const& elements, @@ -194,9 +266,9 @@ struct pick_seeds { typedef typename Elements::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename index::detail::traits::coordinate_type::type coordinate_type; + typedef typename coordinate_type::type coordinate_type; - static const size_t dimension = index::detail::traits::dimension::value; + static const size_t dimension = dimension::value; typedef pick_seeds_impl impl; typedef typename impl::separation_type separation_type; @@ -237,7 +309,7 @@ struct redistribute_elements::type elements_type; typedef typename elements_type::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename index::detail::traits::coordinate_type::type coordinate_type; + typedef typename coordinate_type::type coordinate_type; typedef typename index::detail::default_content_result::type content_type; elements_type & elements1 = rtree::elements(n); diff --git a/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp index 100279583..3218022a2 100644 --- a/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp @@ -31,7 +31,7 @@ struct pick_seeds { typedef typename Elements::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename index::detail::traits::coordinate_type::type coordinate_type; + typedef typename coordinate_type::type coordinate_type; typedef Box box_type; typedef typename index::detail::default_content_result::type content_type; @@ -100,7 +100,7 @@ struct redistribute_elements::type elements_type; typedef typename elements_type::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename index::detail::traits::coordinate_type::type coordinate_type; + typedef typename coordinate_type::type coordinate_type; elements_type & elements1 = rtree::elements(n); elements_type & elements2 = rtree::elements(second_node); diff --git a/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp index 53337b397..50f93b830 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp @@ -25,8 +25,14 @@ namespace detail { namespace rtree { namespace rstar { -template +template class element_axis_corner_less +{ + BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag)); +}; + +template +class element_axis_corner_less { public: element_axis_corner_less(Translator const& tr) @@ -35,8 +41,26 @@ public: bool operator()(Element const& e1, Element const& e2) const { - return index::detail::get(rtree::element_indexable(e1, m_tr)) - < index::detail::get(rtree::element_indexable(e2, m_tr)); + return geometry::get(rtree::element_indexable(e1, m_tr)) + < geometry::get(rtree::element_indexable(e2, m_tr)); + } + +private: + Translator const& m_tr; +}; + +template +class element_axis_corner_less +{ +public: + element_axis_corner_less(Translator const& tr) + : m_tr(tr) + {} + + bool operator()(Element const& e1, Element const& e2) const + { + return geometry::get(rtree::element_indexable(e1, m_tr)) + < geometry::get(rtree::element_indexable(e2, m_tr)); } private: @@ -59,6 +83,8 @@ struct choose_split_axis_and_index_for_corner Translator const& translator) { typedef typename Elements::value_type element_type; + typedef typename rtree::element_indexable_type::type indexable_type; + typedef typename tag::type indexable_tag; BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == parameters.get_max_elements() + 1, "wrong number of elements"); @@ -66,7 +92,7 @@ struct choose_split_axis_and_index_for_corner Elements elements_copy(elements); // MAY THROW, STRONG (alloc, copy) // sort elements - element_axis_corner_less elements_less(translator); + element_axis_corner_less elements_less(translator); std::sort(elements_copy.begin(), elements_copy.end(), elements_less); // MAY THROW, BASIC (copy) // init outputs @@ -106,7 +132,7 @@ struct choose_split_axis_and_index_for_corner template struct choose_split_axis_and_index_for_axis { - //BOOST_STATIC_ASSERT(0); + BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (ElementIndexableTag)); }; template @@ -227,7 +253,7 @@ struct choose_split_axis_and_index Parameters, Box, Dimension - 1, - typename index::detail::traits::tag::type + typename tag::type >::apply(elements, corner, index, sum_of_margins, overlap_val, content_val, parameters, translator); // MAY THROW, STRONG if ( sum_of_margins < smallest_sum_of_margins ) @@ -267,7 +293,7 @@ struct choose_split_axis_and_index Parameters, Box, 0, - typename index::detail::traits::tag::type + typename tag::type >::apply(elements, choosen_corner, choosen_index, smallest_sum_of_margins, smallest_overlap, smallest_content, parameters, translator); // MAY THROW } }; @@ -289,7 +315,10 @@ struct partial_sort BOOST_GEOMETRY_INDEX_ASSERT(axis == Dimension - 1, "unexpected axis value"); typedef typename Elements::value_type element_type; - element_axis_corner_less less(tr); + typedef typename rtree::element_indexable_type::type indexable_type; + typedef typename tag::type indexable_tag; + + element_axis_corner_less less(tr); std::partial_sort(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy) } } @@ -307,7 +336,10 @@ struct partial_sort BOOST_GEOMETRY_INDEX_ASSERT(axis == 0, "unexpected axis value"); typedef typename Elements::value_type element_type; - element_axis_corner_less less(tr); + typedef typename rtree::element_indexable_type::type indexable_type; + typedef typename tag::type indexable_tag; + + element_axis_corner_less less(tr); std::partial_sort(elements.begin(), elements.begin() + index, elements.end(), less); // MAY THROW, BASIC (copy) } }; @@ -323,7 +355,7 @@ struct redistribute_elements::value; + static const size_t dimension = dimension::value; typedef typename index::detail::default_margin_result::type margin_type; typedef typename index::detail::default_content_result::type content_type; @@ -353,7 +385,7 @@ struct redistribute_elements::value + dimension >::apply(elements1, split_axis, split_corner, split_index, smallest_sum_of_margins, smallest_overlap, smallest_content, @@ -361,7 +393,7 @@ struct redistribute_elements::value, "unexpected value"); + BOOST_GEOMETRY_INDEX_ASSERT(split_axis < dimension, "unexpected value"); BOOST_GEOMETRY_INDEX_ASSERT(split_corner == static_cast(min_corner) || split_corner == static_cast(max_corner), "unexpected value"); BOOST_GEOMETRY_INDEX_ASSERT(parameters.get_min_elements() <= split_index && split_index <= parameters.get_max_elements() - parameters.get_min_elements() + 1, "unexpected value"); diff --git a/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp b/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp index d8a2f5377..7072a1879 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp @@ -11,8 +11,6 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP -#include - namespace boost { namespace geometry { namespace index { namespace detail { namespace utilities { @@ -26,7 +24,7 @@ struct gl_draw_point template struct gl_draw_point { - static inline void apply(Point const& p, typename index::detail::traits::coordinate_type::type z) + static inline void apply(Point const& p, typename coordinate_type::type z) { glBegin(GL_POINT); glVertex3f(geometry::get<0>(p), geometry::get<1>(p), z); @@ -41,7 +39,7 @@ struct gl_draw_box template struct gl_draw_box { - static inline void apply(Box const& b, typename index::detail::traits::coordinate_type::type z) + static inline void apply(Box const& b, typename coordinate_type::type z) { glBegin(GL_LINE_LOOP); glVertex3f(geometry::get(b), geometry::get(b), z); @@ -60,9 +58,9 @@ struct gl_draw_indexable template struct gl_draw_indexable { - static const size_t dimension = index::detail::traits::dimension::value; + static const size_t dimension = dimension::value; - static inline void apply(Indexable const& i, typename index::detail::traits::coordinate_type::type z) + static inline void apply(Indexable const& i, typename coordinate_type::type z) { gl_draw_box::apply(i, z); } @@ -71,9 +69,9 @@ struct gl_draw_indexable template struct gl_draw_indexable { - static const size_t dimension = index::detail::traits::dimension::value; + static const size_t dimension = dimension::value; - static inline void apply(Indexable const& i, typename index::detail::traits::coordinate_type::type z) + static inline void apply(Indexable const& i, typename coordinate_type::type z) { gl_draw_point::apply(i, z); } @@ -82,11 +80,11 @@ struct gl_draw_indexable } // namespace dispatch template inline -void gl_draw_indexable(Indexable const& i, typename index::detail::traits::coordinate_type::type z) +void gl_draw_indexable(Indexable const& i, typename coordinate_type::type z) { dispatch::gl_draw_indexable< Indexable, - typename index::detail::traits::tag::type + typename tag::type >::apply(i, z); } @@ -105,7 +103,7 @@ struct gl_draw : public rtree::visitor::max)(), - typename index::detail::traits::coordinate_type::type z_coord_level_multiplier = 1 + typename coordinate_type::type z_coord_level_multiplier = 1 ) : tr(t) , level_f(level_first) @@ -182,7 +180,7 @@ struct gl_draw : public rtree::visitor::type z_mul; + typename coordinate_type::type z_mul; size_t level; }; @@ -193,7 +191,7 @@ template inline void gl_draw(Rtree const& tree, size_t level_first = 0, size_t level_last = (std::numeric_limits::max)(), - typename index::detail::traits::coordinate_type< + typename coordinate_type< typename Rtree::bounds_type >::type z_coord_level_multiplier = 1 ) diff --git a/include/boost/geometry/index/detail/rtree/utilities/print.hpp b/include/boost/geometry/index/detail/rtree/utilities/print.hpp index 5361bd126..f7d503a7d 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/print.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/print.hpp @@ -71,7 +71,7 @@ struct print_indexable template struct print_indexable { - static const size_t dimension = index::detail::traits::dimension::value; + static const size_t dimension = dimension::value; static inline void apply(std::ostream &os, Indexable const& i) { @@ -86,7 +86,7 @@ struct print_indexable template struct print_indexable { - static const size_t dimension = index::detail::traits::dimension::value; + static const size_t dimension = dimension::value; static inline void apply(std::ostream &os, Indexable const& i) { @@ -103,7 +103,7 @@ void print_indexable(std::ostream & os, Indexable const& i) { dispatch::print_indexable< Indexable, - typename geometry::traits::tag::type + typename tag::type >::apply(os, i); } diff --git a/include/boost/geometry/index/detail/rtree/utilities/statistics.hpp b/include/boost/geometry/index/detail/rtree/utilities/statistics.hpp index c3b4c9c34..c8e420d91 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/statistics.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/statistics.hpp @@ -12,7 +12,6 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_STATISTICS_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_STATISTICS_HPP -#include #include #include diff --git a/include/boost/geometry/index/rtree.hpp b/include/boost/geometry/index/rtree.hpp index 13eee6e02..018d508f6 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -29,7 +29,6 @@ #include #include -#include #include #include @@ -143,7 +142,14 @@ public: >::type indexable_type; /*! \brief The Box type used by the R-tree. */ - typedef typename index::detail::default_box_type::type bounds_type; + typedef geometry::model::box< + geometry::model::point< + typename coordinate_type::type, + dimension::value, + typename coordinate_system::type + > + > + bounds_type; private: