diff --git a/include/boost/geometry/index/detail/rtree/pack_create.hpp b/include/boost/geometry/index/detail/rtree/pack_create.hpp index 6db468129..9e92866b0 100644 --- a/include/boost/geometry/index/detail/rtree/pack_create.hpp +++ b/include/boost/geometry/index/detail/rtree/pack_create.hpp @@ -13,6 +13,80 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { +namespace pack_utils { + +template +struct biggest_edge +{ + BOOST_STATIC_ASSERT(0 < Dimension); + template + static inline void apply(Box const& box, typename coordinate_type::type & length, std::size_t & dim_index) + { + biggest_edge::apply(box, length, dim_index); + typename coordinate_type::type curr + = geometry::get(box) - geometry::get(box); + if ( length < curr ) + { + dim_index = Dimension - 1; + length = curr; + } + } +}; + +template <> +struct biggest_edge<1> +{ + template + static inline void apply(Box const& box, typename coordinate_type::type & length, std::size_t & dim_index) + { + dim_index = 0; + length = geometry::get(box) - geometry::get(box); + } +}; + +template +struct point_entries_comparer +{ + template + bool operator()(PointEntry const& e1, PointEntry const& e2) const + { + return geometry::get(e1.first) < geometry::get(e2.first); + } +}; + +template +struct partial_sort_and_half_boxes +{ + template + static inline void apply(EIt first, EIt median, EIt last, Box const& box, Box & left, Box & right, std::size_t dim_index) + { + if ( I == dim_index ) + { + std::partial_sort(first, median, last, point_entries_comparer()); + + geometry::convert(box, left); + geometry::convert(box, right); + typename coordinate_type::type edge_len + = geometry::get(box) - geometry::get(box); + typename coordinate_type::type median + = geometry::get(box) + edge_len / 2; + geometry::set(left, median); + geometry::set(right, median); + } + else + partial_sort_and_half_boxes::apply(first, median, last, box, left, right, dim_index); + } +}; + +template +struct partial_sort_and_half_boxes +{ + template + static inline void apply(EIt , EIt , EIt , Box const& , Box & , Box & , std::size_t ) {} +}; + +} // namespace pack_utils + // STR leafs number are calculated as rcount/max // and the number of splitting planes for each dimension as (count/max)^(1/dimension) // <-> for dimension==2 -> sqrt(count/max) @@ -170,10 +244,10 @@ private: coordinate_type greatest_length; std::size_t greatest_dim_index = 0; - biggest_edge::apply(hint_box, greatest_length, greatest_dim_index); - partial_sort_for_dimension<0, dimension>::apply(first, median, last, greatest_dim_index); + pack_utils::biggest_edge::apply(hint_box, greatest_length, greatest_dim_index); Box left, right; - half_boxes_for_dimension<0, dimension>::apply(hint_box, left, right, greatest_dim_index); + pack_utils::partial_sort_and_half_boxes<0, dimension> + ::apply(first, median, last, hint_box, left, right, greatest_dim_index); per_level_packets(first, median, counts_first, counts_median, left, next_subtree_counts, elements, elements_box); per_level_packets(median, last, counts_median, counts_last, right, next_subtree_counts, elements, elements_box); @@ -238,86 +312,6 @@ private: return true; } - template - struct biggest_edge - { - BOOST_STATIC_ASSERT(0 < Dimension); - static inline void apply(Box const& box, coordinate_type & length, std::size_t & dim_index) - { - biggest_edge::apply(box, length, dim_index); - coordinate_type curr = geometry::get(box) - geometry::get(box); - if ( length < curr ) - { - dim_index = Dimension - 1; - length = curr; - } - } - }; - - template <> - struct biggest_edge<1> - { - static inline void apply(Box const& box, coordinate_type & length, std::size_t & dim_index) - { - dim_index = 0; - length = geometry::get(box) - geometry::get(box); - } - }; - - template - struct partial_sort_for_dimension - { - template - static inline void apply(EIt first, EIt median, EIt last, std::size_t dim_index) - { - if ( I == dim_index ) - std::partial_sort(first, median, last, point_entries_comparer()); - else - partial_sort_for_dimension::apply(first, median, last, dim_index); - } - }; - - template - struct partial_sort_for_dimension - { - template - static inline void apply(EIt , EIt , EIt , std::size_t ) {} - }; - - template - struct point_entries_comparer - { - template - bool operator()(PointEntry const& e1, PointEntry const& e2) const - { - return geometry::get(e1.first) < geometry::get(e2.first); - } - }; - - template - struct half_boxes_for_dimension - { - static inline void apply(Box const& box, Box & left, Box & right, std::size_t dim_index) - { - if ( I == dim_index ) - { - geometry::convert(box, left); - geometry::convert(box, right); - coordinate_type median = geometry::get(box) + (geometry::get(box) - geometry::get(box)) / 2; - geometry::set(left, median); - geometry::set(right, median); - } - else - half_boxes_for_dimension::apply(box, left, right, dim_index); - } - }; - - template - struct half_boxes_for_dimension - { - static inline void apply(Box const& , Box & , Box & , std::size_t ) {} - }; - parameters_type const& m_parameters; Translator const& m_translator; Allocators & m_allocators;