15#ifndef dealii_numerics_rtree_h
16#define dealii_numerics_rtree_h
28#include <boost/geometry/algorithms/distance.hpp>
29#include <boost/geometry/index/rtree.hpp>
30#include <boost/geometry/strategies/strategies.hpp>
140template <
typename LeafType,
141 typename IndexType = boost::geometry::index::linear<16>,
142 typename IndexableGetter =
145 boost::geometry::index::rtree<LeafType, IndexType, IndexableGetter>;
154template <
typename IndexType = boost::geometry::index::linear<16>,
155 typename LeafTypeIterator,
156 typename IndexableGetter = boost::geometry::index::indexable<
157 typename LeafTypeIterator::value_type>>
159pack_rtree(
const LeafTypeIterator &begin,
const LeafTypeIterator &end);
171template <
typename IndexType = boost::geometry::index::linear<16>,
172 typename ContainerType,
173 typename IndexableGetter = boost::geometry::index::indexable<
174 typename ContainerType::value_type>>
196template <
typename Container>
215 using size_t =
typename Container::size_type;
300template <
typename IndexType = boost::geometry::index::linear<16>,
301 typename ContainerType>
302RTree<
typename ContainerType::size_type,
319template <
typename Value,
325 :
public boost::geometry::index::detail::rtree::visitor<
327 typename Options::parameters_type,
330 typename Options::node_tag,
346 typename boost::geometry::index::detail::rtree::internal_node<
348 typename Options::parameters_type,
351 typename Options::node_tag>::type;
356 using Leaf =
typename boost::geometry::index::detail::rtree::leaf<
358 typename Options::parameters_type,
361 typename Options::node_tag>::type;
394 std::vector<BoundingBox<boost::geometry::dimension<Box>::value>> &
boxes;
448template <
typename Rtree>
450 boost::geometry::dimension<typename Rtree::indexable_type>::value>>
464template <
typename Rtree>
466 boost::geometry::dimension<typename Rtree::indexable_type>::value>>>
474template <
typename IndexType,
475 typename LeafTypeIterator,
476 typename IndexableGetter>
478pack_rtree(
const LeafTypeIterator &begin,
const LeafTypeIterator &end)
480 return RTree<
typename LeafTypeIterator::value_type,
482 IndexableGetter>(begin, end);
487template <
typename IndexType,
typename ContainerType,
typename IndexableGetter>
491 return pack_rtree<IndexType,
decltype(container.begin()), IndexableGetter>(
492 container.begin(), container.end());
497template <
typename IndexType,
typename ContainerType>
498RTree<
typename ContainerType::size_type,
510 std::vector<typename ContainerType::size_type> indices(container.size());
511 for (
typename ContainerType::size_type i = 0; i < container.size(); ++i)
514 return RTree<
typename ContainerType::size_type,
525template <
typename Value,
532 const Translator &translator,
533 const unsigned int target_level,
534 std::vector<
BoundingBox<boost::geometry::dimension<Box>::value>> &boxes)
535 : translator(translator)
537 , target_level(target_level)
543template <
typename Value,
553 typename boost::geometry::index::detail::rtree::elements_type<
556 const auto &elements = boost::geometry::index::detail::rtree::elements(node);
558 if (
level == target_level)
560 const auto offset = boxes.size();
561 boxes.resize(offset + elements.size());
563 unsigned int i = offset;
564 for (
typename ElementsType::const_iterator it = elements.begin();
565 it != elements.end();
568 boost::geometry::convert(it->first, boxes[i]);
574 const size_t level_backup =
level;
577 for (
typename ElementsType::const_iterator it = elements.begin();
578 it != elements.end();
581 boost::geometry::index::detail::rtree::apply_visitor(*
this, *it->second);
584 level = level_backup;
587template <
typename Value,
599template <
typename Rtree>
601 boost::geometry::dimension<typename Rtree::indexable_type>::value>>
604 constexpr unsigned int dim =
605 boost::geometry::dimension<typename Rtree::indexable_type>::value;
608 boost::geometry::index::detail::rtree::utilities::view<Rtree>;
611 std::vector<BoundingBox<dim>> boxes;
613 if (rtv.depth() == 0)
619 boost::geometry::convert(tree.bounds(), boxes[0]);
623 const unsigned int target_level =
624 std::min<unsigned int>(
level, rtv.depth() - 1);
627 typename RtreeView::options_type,
628 typename RtreeView::translator_type,
629 typename RtreeView::box_type,
630 typename RtreeView::allocators_type>
631 extract_level_visitor(rtv.translator(), target_level, boxes);
632 rtv.apply_visitor(extract_level_visitor);
640template <
class Rtree>
642n_levels(
const Rtree &tree)
644 boost::geometry::index::detail::rtree::utilities::view<Rtree> rtv(tree);
649template <
typename Value,
654struct NodeVisitor :
public boost::geometry::index::detail::rtree::visitor<
656 typename Options::parameters_type,
659 typename Options::node_tag,
663 const Translator &translator,
664 unsigned int target_level,
666 std::vector<
BoundingBox<boost::geometry::dimension<Box>::value>>> &boxes);
673 typename boost::geometry::index::detail::rtree::internal_node<
675 typename Options::parameters_type,
678 typename Options::node_tag>::type;
683 using Leaf =
typename boost::geometry::index::detail::rtree::leaf<
685 typename Options::parameters_type,
688 typename Options::node_tag>::type;
695 operator()(
const InternalNode &node);
701 operator()(
const Leaf &);
706 const Translator &translator;
723 const size_t target_level;
730 std::vector<std::vector<BoundingBox<boost::geometry::dimension<Box>::value>>>
736template <
typename Value,
741NodeVisitor<Value, Options, Translator, Box, Allocators>::NodeVisitor(
742 const Translator &translator,
743 const unsigned int target_level,
744 std::vector<std::vector<
BoundingBox<boost::geometry::dimension<Box>::value>>>
746 : translator(translator)
749 , target_level(target_level)
750 , boxes_in_boxes(bb_in_boxes)
755template <
typename Value,
761NodeVisitor<Value, Options, Translator, Box, Allocators>::operator()(
762 const NodeVisitor::InternalNode &node)
764 using elements_type =
765 typename boost::geometry::index::detail::rtree::elements_type<
767 const elements_type &elements =
768 boost::geometry::index::detail::rtree::elements(node);
770 if (
level == target_level)
772 const unsigned int n_children = elements.size();
773 const auto offset = boxes_in_boxes.size();
774 boxes_in_boxes.resize(offset + n_children);
777 if (
level == target_level + 1)
780 boxes_in_boxes[node_counter].resize(elements.size());
782 for (
typename elements_type::const_iterator it = elements.begin();
783 it != elements.end();
786 boost::geometry::convert(it->first, boxes_in_boxes[node_counter][i]);
794 size_t level_backup =
level;
797 for (
typename elements_type::const_iterator it = elements.begin();
798 it != elements.end();
801 boost::geometry::index::detail::rtree::apply_visitor(*
this, *it->second);
804 level = level_backup;
809template <
typename Value,
815NodeVisitor<Value, Options, Translator, Box, Allocators>::operator()(
816 const NodeVisitor::Leaf &)
819 boxes_in_boxes.clear();
822template <
typename Rtree>
824 boost::geometry::dimension<typename Rtree::indexable_type>::value>>>
827 constexpr unsigned int dim =
828 boost::geometry::dimension<typename Rtree::indexable_type>::value;
831 boost::geometry::index::detail::rtree::utilities::view<Rtree>;
834 std::vector<std::vector<BoundingBox<dim>>> boxes_in_boxes;
836 if (rtv.depth() == 0)
841 boxes_in_boxes.resize(1);
842 boxes_in_boxes[0].resize(1);
843 boost::geometry::convert(tree.bounds(), boxes_in_boxes[0][0]);
847 const unsigned int target_level =
848 std::min<unsigned int>(
level, rtv.depth() - 1);
850 NodeVisitor<
typename RtreeView::value_type,
851 typename RtreeView::options_type,
852 typename RtreeView::translator_type,
853 typename RtreeView::box_type,
854 typename RtreeView::allocators_type>
855 node_visitor(rtv.translator(), target_level, boxes_in_boxes);
856 rtv.apply_visitor(node_visitor);
859 return boxes_in_boxes;
result_type operator()(size_t i) const
const Container & container
typename Container::size_type size_t
typename boost::geometry::index::indexable< typename Container::value_type > IndexableGetter
typename IndexableGetter::result_type result_type
IndexableGetterFromIndices(const Container &c)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
std::vector< BoundingBox< boost::geometry::dimension< typename Rtree::indexable_type >::value > > extract_rtree_level(const Rtree &tree, const unsigned int level)
boost::geometry::index::rtree< LeafType, IndexType, IndexableGetter > RTree
std::vector< std::vector< BoundingBox< boost::geometry::dimension< typename Rtree::indexable_type >::value > > > extract_children_of_level(const Rtree &tree, const unsigned int level)
RTree< typename LeafTypeIterator::value_type, IndexType, IndexableGetter > pack_rtree(const LeafTypeIterator &begin, const LeafTypeIterator &end)
RTree< typename ContainerType::size_type, IndexType, IndexableGetterFromIndices< ContainerType > > pack_rtree_of_indices(const ContainerType &container)