Below is the visitor code I wrote. The struct 'tempnode' is used to be stored as a temp result in the priority queue. How should I change it to meet the requirement?
Actually, my problem is quite similar to visiting the MBRs level by level (breadth first), so if there is an example of breadth-first visiting using visitor, I think I could figure out my problem according to it.
Here you go, breadth-first and depth-first printing of internal nodes MBRs and leafs elements numbers. Note that I only store node pointers of the nodes that are going to be traversed next in m_nodes container and that you have to keep traversing also when you reach leafs because there may be nodes left in the container.
#include <boost/geometry.hpp>
#include
<boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <deque>
#include <iostream>
namespace bg = boost::geometry;
namespace bgi = boost::geometry::index;
namespace bgid = bgi::detail;
typedef bg::model::point<float, 2,
bg::cs::cartesian> point;
typedef bgi::rtree<point, bgi::linear<3> >
rtree;
typedef bg::model::box<point> box;
template
<
typename Value,
typename Options,
typename Translator,
typename Box,
typename Allocators>
class breadth_first_visitor
: public bgid::rtree::visitor
<
Value,
typename Options::parameters_type,
Box,
Allocators,
typename Options::node_tag,
true
>::type
{
typedef typename bgid::rtree::internal_node
<
Value, typename Options::parameters_type,
Box, Allocators, typename Options::node_tag
>::type internal_node;
typedef typename bgid::rtree::leaf
<
Value, typename Options::parameters_type,
Box, Allocators, typename Options::node_tag
>::type leaf;
typedef typename Allocators::node_pointer
node_pointer;
public:
void operator()(internal_node const& n)
{
typedef typename
bgid::rtree::elements_type<internal_node>::type
elements_type;
elements_type const& elements =
bgid::rtree::elements(n);
for ( typename elements_type::const_iterator it
= elements.begin();
it != elements.end() ; ++it)
{
// do something with MBR
std::cout << bg::dsv(it->first)
<< std::endl;
// add child node pointer to the container
m_nodes.push_back(it->second);
}
traverse();
}
void operator()(leaf const& n)
{
std::cout <<
boost::size(bgid::rtree::elements(n)) << " elements in
leaf" << std::endl;
traverse();
}
private:
void traverse()
{
if (! m_nodes.empty())
{
node_pointer next = m_nodes.front();
m_nodes.pop_front();
bgid::rtree::apply_visitor(*this, *next);
}
}
std::deque<node_pointer> m_nodes;
};
template
<
typename Value,
typename Options,
typename Translator,
typename Box,
typename Allocators>
class depth_first_visitor
: public bgid::rtree::visitor
<
Value,
typename Options::parameters_type,
Box,
Allocators,
typename Options::node_tag,
true
>::type
{
typedef typename bgid::rtree::internal_node
<
Value, typename Options::parameters_type,
Box, Allocators, typename Options::node_tag
>::type internal_node;
typedef typename bgid::rtree::leaf
<
Value, typename Options::parameters_type,
Box, Allocators, typename Options::node_tag
>::type leaf;
typedef typename Allocators::node_pointer
node_pointer;
public:
void operator()(internal_node const& n)
{
typedef typename
bgid::rtree::elements_type<internal_node>::type
elements_type;
elements_type const& elements =
bgid::rtree::elements(n);
for ( typename elements_type::const_iterator it
= elements.begin();
it != elements.end() ; ++it)
{
// do something with MBR
std::cout << bg::dsv(it->first)
<< std::endl;
// traverse
node_pointer next = it->second;
bgid::rtree::apply_visitor(*this, *next);
}
}
void operator()(leaf const& n)
{
std::cout <<
boost::size(bgid::rtree::elements(n)) << " elements in
leaf" << std::endl;
}
};
template <typename Rtree>
inline void print_breadth_first(Rtree const& tree)
{
typedef bgid::rtree::utilities::view<Rtree>
RTV;
RTV rtv(tree);
breadth_first_visitor
<
typename RTV::value_type,
typename RTV::options_type,
typename RTV::translator_type,
typename RTV::box_type,
typename RTV::allocators_type
> v;
rtv.apply_visitor(v);
}
template <typename Rtree>
inline void print_depth_first(Rtree const& tree)
{
typedef bgid::rtree::utilities::view<Rtree>
RTV;
RTV rtv(tree);
depth_first_visitor
<
typename RTV::value_type,
typename RTV::options_type,
typename RTV::translator_type,
typename RTV::box_type,
typename RTV::allocators_type
> v;
rtv.apply_visitor(v);
}
int main()
{
rtree tree;
for (int i = 0 ; i < 10 ; i += 1)
tree.insert(point(i, i));
std::cout << "breadth first" <<
std::endl;
print_breadth_first(tree);
std::cout << "depth first" <<
std::endl;
print_depth_first(tree);
}
I get the following results:
breadth first
((4, 4), (9, 9))
((0, 0), (3, 3))
((6, 6), (7, 7))
((4, 4), (5, 5))
((8, 8), (9, 9))
((0, 0), (1, 1))
((2, 2), (3, 3))
2 elements in leaf
2 elements in leaf
2 elements in leaf
2 elements in leaf
2 elements in leaf
depth first
((4, 4), (9, 9))
((6, 6), (7, 7))
2 elements in leaf
((4, 4), (5, 5))
2 elements in leaf
((8, 8), (9, 9))
2 elements in leaf
((0, 0), (3, 3))
((0, 0), (1, 1))
2 elements in leaf
((2, 2), (3, 3))
2 elements in leaf
Adam