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 9b5e4d035..84201b6af 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/gl_draw.hpp @@ -11,6 +11,8 @@ #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,8 +28,16 @@ struct gl_draw_point { 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); + typename coordinate_type::type const& x = geometry::get<0>(p); + typename coordinate_type::type const& y = geometry::get<1>(p); + /*glBegin(GL_POINT); + glVertex3f(x, y, z); + glEnd();*/ + glBegin(GL_QUADS); + glVertex3f(x+1, y, z); + glVertex3f(x, y+1, z); + glVertex3f(x-1, y, z); + glVertex3f(x, y-1, z); glEnd(); } }; @@ -50,32 +60,42 @@ struct gl_draw_box } }; +template +struct gl_draw_segment +{}; + +template +struct gl_draw_segment +{ + static inline void apply(Segment const& s, typename coordinate_type::type z) + { + glBegin(GL_LINES); + glVertex3f(geometry::get<0, 0>(s), geometry::get<0, 1>(s), z); + glVertex3f(geometry::get<1, 0>(s), geometry::get<1, 1>(s), z); + glEnd(); + } +}; + template struct gl_draw_indexable { + BOOST_MPL_ASSERT_MSG((false), NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag)); }; -template -struct gl_draw_indexable -{ - static const size_t dimension = geometry::dimension::value; +template +struct gl_draw_indexable + : gl_draw_box::value> +{}; - static inline void apply(Indexable const& i, typename coordinate_type::type z) - { - gl_draw_box::apply(i, z); - } -}; +template +struct gl_draw_indexable + : gl_draw_point::value> +{}; -template -struct gl_draw_indexable -{ - static const size_t dimension = geometry::dimension::value; - - static inline void apply(Indexable const& i, typename coordinate_type::type z) - { - gl_draw_point::apply(i, z); - } -}; +template +struct gl_draw_indexable + : gl_draw_segment::value> +{}; } // namespace dispatch diff --git a/include/boost/geometry/index/detail/rtree/utilities/print.hpp b/include/boost/geometry/index/detail/rtree/utilities/print.hpp index 452471061..4c42659c6 100644 --- a/include/boost/geometry/index/detail/rtree/utilities/print.hpp +++ b/include/boost/geometry/index/detail/rtree/utilities/print.hpp @@ -66,6 +66,7 @@ struct print_corner template struct print_indexable { + BOOST_MPL_ASSERT_MSG((false), NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag)); }; template @@ -96,6 +97,21 @@ struct print_indexable } }; +template +struct print_indexable +{ + static const size_t dimension = geometry::dimension::value; + + static inline void apply(std::ostream &os, Indexable const& i) + { + os << '('; + print_corner::apply(os, i); + os << ")-("; + print_corner::apply(os, i); + os << ')'; + } +}; + } // namespace dispatch template inline diff --git a/index/example/glut_vis.cpp b/index/example/glut_vis.cpp index 755f4d300..865ac08b9 100644 --- a/index/example/glut_vis.cpp +++ b/index/example/glut_vis.cpp @@ -1,7 +1,7 @@ // Boost.Geometry Index -// Additional tests +// OpenGL visualization -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 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 @@ -26,29 +26,164 @@ #include #include +#include + +#define ENABLE_POINTS_AND_SEGMENTS + namespace bg = boost::geometry; namespace bgi = bg::index; +// used types + typedef bg::model::point P; typedef bg::model::box

B; -//bgi::rtree t(2, 1); typedef bg::model::linestring

LS; typedef bg::model::segment

S; typedef bg::model::ring

R; typedef bg::model::polygon

Poly; typedef bg::model::multi_polygon MPoly; -typedef bgi::rtree< - B, - bgi::rstar<4, 2> -> RTree; -RTree t; -std::vector vect; +// containers variant + +template +struct containers +{ + bgi::rtree< V, bgi::rstar<4, 2> > tree; + std::vector values; + std::vector result; +}; + +boost::variant< + containers +#ifdef ENABLE_POINTS_AND_SEGMENTS + , containers

+ , containers +#endif +> cont; + +// visitors + +template +struct query_v : boost::static_visitor +{ + Pred m_pred; + query_v(Pred const& pred) : m_pred(pred) {} + + template + size_t operator()(C & c) const + { + c.result.clear(); + return c.tree.query(m_pred, std::back_inserter(c.result)); + } +}; +template +inline size_t query(Cont & cont, Pred const& pred) +{ + return boost::apply_visitor(query_v(pred), cont); +} + +struct print_result_v : boost::static_visitor<> +{ + template + void operator()(C & c) const + { + for ( size_t i = 0 ; i < c.result.size() ; ++i ) + { + bgi::detail::utilities::print_indexable(std::cout, c.result[i]); + std::cout << '\n'; + } + } +}; +template +inline void print_result(Cont const& cont) +{ + boost::apply_visitor(print_result_v(), cont); +} + +struct bounds_v : boost::static_visitor +{ + template + B operator()(C & c) const + { + return c.tree.bounds(); + } +}; +template +inline B bounds(Cont const& cont) +{ + return boost::apply_visitor(bounds_v(), cont); +} + +struct depth_v : boost::static_visitor +{ + template + size_t operator()(C & c) const + { + return get(c.tree); + } + template + static size_t get(RTree const& t) + { + return bgi::detail::rtree::utilities::view(t).depth(); + } +}; +template +inline size_t depth(Cont const& cont) +{ + return boost::apply_visitor(depth_v(), cont); +} + +struct draw_tree_v : boost::static_visitor<> +{ + template + void operator()(C & c) const + { + bgi::detail::rtree::utilities::gl_draw(c.tree); + } +}; +template +inline void draw_tree(Cont const& cont) +{ + return boost::apply_visitor(draw_tree_v(), cont); +} + +struct draw_result_v : boost::static_visitor<> +{ + template + void operator()(C & c) const + { + for ( size_t i = 0 ; i < c.result.size() ; ++i ) + { + bgi::detail::utilities::gl_draw_indexable(c.result[i], depth_v::get(c.tree)); + } + } +}; +template +inline void draw_result(Cont const& cont) +{ + return boost::apply_visitor(draw_result_v(), cont); +} + +struct print_tree_v : boost::static_visitor<> +{ + template + void operator()(C & c) const + { + bgi::detail::rtree::utilities::print(std::cout, c.tree); + } +}; +template +inline void print_tree(Cont const& cont) +{ + return boost::apply_visitor(print_tree_v(), cont); +} + +// globals used in querying size_t found_count = 0; -P search_point; size_t count = 5; -std::vector nearest_boxes; + +P search_point; B search_box; R search_ring; Poly search_poly; @@ -63,30 +198,24 @@ enum query_mode_type { bool search_valid = false; +// various queries + void query_knn() { float x = ( rand() % 1000 ) / 10.0f; float y = ( rand() % 1000 ) / 10.0f; - nearest_boxes.clear(); - if ( query_mode == qm_knn ) { search_point = P(x, y); - found_count = t.query( - bgi::nearest(search_point, count), - std::back_inserter(nearest_boxes) - ); + found_count = query(cont, bgi::nearest(search_point, count)); } else if ( query_mode == qm_knnb ) { float w = 2 + ( rand() % 1000 ) / 500.0f; float h = 2 + ( rand() % 1000 ) / 500.0f; search_box = B(P(x - w, y - h), P(x + w, y + h)); - found_count = t.query( - bgi::nearest(search_box, count), - std::back_inserter(nearest_boxes) - ); + found_count = query(cont, bgi::nearest(search_box, count)); } else if ( query_mode == qm_knns ) { @@ -95,10 +224,7 @@ void query_knn() float w = (10 + ( rand() % 1000 ) / 100.0f) * signx; float h = (10 + ( rand() % 1000 ) / 100.0f) * signy; search_segment = S(P(x - w, y - h), P(x + w, y + h)); - found_count = t.query( - bgi::nearest(search_segment, count), - std::back_inserter(nearest_boxes) - ); + found_count = query(cont, bgi::nearest(search_segment, count)); } else { @@ -107,20 +233,33 @@ void query_knn() if ( found_count > 0 ) { -// TODO: print the correct indexable! - std::cout << "search point: "; - bgi::detail::utilities::print_indexable(std::cout, search_point); - std::cout << "\nfound: "; - for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i ) + if ( query_mode == qm_knn ) { - bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]); - std::cout << '\n'; + std::cout << "search point: "; + bgi::detail::utilities::print_indexable(std::cout, search_point); } + else if ( query_mode == qm_knnb ) + { + std::cout << "search box: "; + bgi::detail::utilities::print_indexable(std::cout, search_box); + } + else if ( query_mode == qm_knns ) + { + std::cout << "search segment: "; + bgi::detail::utilities::print_indexable(std::cout, search_segment); + } + else + { + BOOST_ASSERT(false); + } + std::cout << "\nfound: "; + print_result(cont); } else std::cout << "nearest not found\n"; } +#ifndef ENABLE_POINTS_AND_SEGMENTS void query_path() { float x = ( rand() % 1000 ) / 10.0f; @@ -136,11 +275,7 @@ void query_path() search_path[2 * i + 1] = P(x+w, yy); } - nearest_boxes.clear(); - found_count = t.query( - bgi::detail::path(search_path, count), - std::back_inserter(nearest_boxes) - ); + found_count = query(cont, bgi::detail::path(search_path, count)); if ( found_count > 0 ) { @@ -148,15 +283,12 @@ void query_path() BOOST_FOREACH(P const& p, search_path) bgi::detail::utilities::print_indexable(std::cout, p); std::cout << "\nfound: "; - for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i ) - { - bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]); - std::cout << '\n'; - } + print_result(cont); } else std::cout << "values on path not found\n"; } +#endif template void query() @@ -169,26 +301,20 @@ void query() float h = 10 + ( rand() % 1000 ) / 100.0f; search_box = B(P(x - w, y - h), P(x + w, y + h)); - nearest_boxes.clear(); - found_count = t.query(Predicate(search_box), std::back_inserter(nearest_boxes) ); } else { - search_box = t.bounds(); - nearest_boxes.clear(); - found_count = t.query(Predicate(search_box), std::back_inserter(nearest_boxes) ); + search_box = bounds(cont); } + found_count = query(cont, Predicate(search_box)); + if ( found_count > 0 ) { std::cout << "search box: "; bgi::detail::utilities::print_indexable(std::cout, search_box); std::cout << "\nfound: "; - for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i ) - { - bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]); - std::cout << '\n'; - } + print_result(cont); } else std::cout << "boxes not found\n"; @@ -221,8 +347,7 @@ void query_ring() search_ring.push_back(P(x - w, y - h/2)); search_ring.push_back(P(x - w, y - h)); - nearest_boxes.clear(); - found_count = t.query(Predicate(search_ring), std::back_inserter(nearest_boxes) ); + found_count = query(cont, Predicate(search_ring)); if ( found_count > 0 ) { @@ -233,11 +358,7 @@ void query_ring() std::cout << ' '; } std::cout << "\nfound: "; - for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i ) - { - bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]); - std::cout << '\n'; - } + print_result(cont); } else std::cout << "boxes not found\n"; @@ -277,8 +398,7 @@ void query_poly() search_poly.inners()[0].push_back(P(x - w/2, y + h/2)); search_poly.inners()[0].push_back(P(x - w/2, y - h/2)); - nearest_boxes.clear(); - found_count = t.query(Predicate(search_poly), std::back_inserter(nearest_boxes) ); + found_count = query(cont, Predicate(search_poly)); if ( found_count > 0 ) { @@ -289,11 +409,7 @@ void query_poly() std::cout << ' '; } std::cout << "\nfound: "; - for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i ) - { - bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]); - std::cout << '\n'; - } + print_result(cont); } else std::cout << "boxes not found\n"; @@ -349,9 +465,8 @@ void query_multi_poly() search_multi_poly[2].outer().push_back(P(x + 6*w/5, y + 2*h)); search_multi_poly[2].outer().push_back(P(x + 6*w/5, y + 6*h/5)); - nearest_boxes.clear(); - found_count = t.query(Predicate(search_multi_poly), std::back_inserter(nearest_boxes) ); - + found_count = query(cont, Predicate(search_multi_poly)); + if ( found_count > 0 ) { std::cout << "search multi_poly[0] outer: "; @@ -361,11 +476,7 @@ void query_multi_poly() std::cout << ' '; } std::cout << "\nfound: "; - for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i ) - { - bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]); - std::cout << '\n'; - } + print_result(cont); } else std::cout << "boxes not found\n"; @@ -386,9 +497,8 @@ void query_segment() boost::geometry::set<1, 0>(search_segment, x + w); boost::geometry::set<1, 1>(search_segment, y + h); - nearest_boxes.clear(); - found_count = t.query(Predicate(search_segment), std::back_inserter(nearest_boxes) ); - + found_count = query(cont, Predicate(search_segment)); + if ( found_count > 0 ) { std::cout << "search segment: "; @@ -396,11 +506,7 @@ void query_segment() bgi::detail::utilities::print_indexable(std::cout, P(x+w, y+h)); std::cout << "\nfound: "; - for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i ) - { - bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]); - std::cout << '\n'; - } + print_result(cont); } else std::cout << "boxes not found\n"; @@ -424,9 +530,8 @@ void query_linestring() search_linestring.push_back(P(xx, yy)); } - nearest_boxes.clear(); - found_count = t.query(Predicate(search_linestring), std::back_inserter(nearest_boxes) ); - + found_count = query(cont, Predicate(search_linestring)); + if ( found_count > 0 ) { std::cout << "search linestring: "; @@ -436,44 +541,46 @@ void query_linestring() std::cout << ' '; } std::cout << "\nfound: "; - for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i ) - { - bgi::detail::utilities::print_indexable(std::cout, nearest_boxes[i]); - std::cout << '\n'; - } + print_result(cont); } else std::cout << "boxes not found\n"; } +// the function running the correct query based on the query_mode + void search() { namespace d = bgi::detail; if ( query_mode == qm_knn || query_mode == qm_knnb || query_mode == qm_knns ) query_knn(); - else if ( query_mode == qm_c ) - query< d::spatial_predicate >(); else if ( query_mode == qm_d ) query< d::spatial_predicate >(); else if ( query_mode == qm_i ) query< d::spatial_predicate >(); + else if ( query_mode == qm_nd ) + query< d::spatial_predicate >(); + else if ( query_mode == qm_ni ) + query< d::spatial_predicate >(); + else if ( query_mode == qm_all ) + query< d::spatial_predicate >(); +#ifdef ENABLE_POINTS_AND_SEGMENTS + else + std::cout << "query disabled\n"; +#else + else if ( query_mode == qm_c ) + query< d::spatial_predicate >(); else if ( query_mode == qm_o ) query< d::spatial_predicate >(); else if ( query_mode == qm_w ) query< d::spatial_predicate >(); else if ( query_mode == qm_nc ) query< d::spatial_predicate >(); - else if ( query_mode == qm_nd ) - query< d::spatial_predicate >(); - else if ( query_mode == qm_ni ) - query< d::spatial_predicate >(); else if ( query_mode == qm_no ) query< d::spatial_predicate >(); else if ( query_mode == qm_nw ) query< d::spatial_predicate >(); - else if ( query_mode == qm_all ) - query< d::spatial_predicate >(); else if ( query_mode == qm_ri ) query_ring< d::spatial_predicate >(); else if ( query_mode == qm_pi ) @@ -486,15 +593,18 @@ void search() query_linestring< d::spatial_predicate >(); else if ( query_mode == qm_path ) query_path(); +#endif search_valid = true; } +// various drawing functions + void draw_point(P const& p) { float x = boost::geometry::get<0>(p); float y = boost::geometry::get<1>(p); - float z = bgi::detail::rtree::utilities::view(t).depth(); + float z = depth(cont); glBegin(GL_QUADS); glVertex3f(x+1, y, z); @@ -508,7 +618,7 @@ void draw_knn_area(float min_distance, float max_distance) { float x = boost::geometry::get<0>(search_point); float y = boost::geometry::get<1>(search_point); - float z = bgi::detail::rtree::utilities::view(t).depth(); + float z = depth(cont); draw_point(search_point); @@ -535,7 +645,7 @@ void draw_linestring(LS const& ls) { float x = boost::geometry::get<0>(p); float y = boost::geometry::get<1>(p); - float z = bgi::detail::rtree::utilities::view(t).depth(); + float z = depth(cont); glVertex3f(x, y, z); } @@ -548,7 +658,7 @@ void draw_segment(S const& s) float y1 = boost::geometry::get<0, 1>(s); float x2 = boost::geometry::get<1, 0>(s); float y2 = boost::geometry::get<1, 1>(s); - float z = bgi::detail::rtree::utilities::view(t).depth(); + float z = depth(cont); glBegin(GL_LINES); glVertex3f(x1, y1, z); @@ -563,7 +673,7 @@ void draw_box(Box const& box) float y1 = boost::geometry::get(box); float x2 = boost::geometry::get(box); float y2 = boost::geometry::get(box); - float z = bgi::detail::rtree::utilities::view(t).depth(); + float z = depth(cont); // search box glBegin(GL_LINE_LOOP); @@ -577,7 +687,7 @@ void draw_box(Box const& box) template void draw_ring(Range const& range) { - float z = bgi::detail::rtree::utilities::view(t).depth(); + float z = depth(cont); // search box glBegin(GL_LINE_LOOP); @@ -607,11 +717,13 @@ void draw_multi_polygon(MultiPolygon const& multi_polygon) draw_polygon(p); } +// render the scene -> tree, if searching data available also the query geometry and result + void render_scene(void) { glClear(GL_COLOR_BUFFER_BIT); - bgi::detail::rtree::utilities::gl_draw(t); + draw_tree(cont); if ( search_valid ) { @@ -640,10 +752,7 @@ void render_scene(void) glColor3f(1.0f, 0.5f, 0.0f); - for ( size_t i = 0 ; i < nearest_boxes.size() ; ++i ) - bgi::detail::utilities::gl_draw_indexable( - nearest_boxes[i], - bgi::detail::rtree::utilities::view(t).depth()); + draw_result(cont); } glFlush(); @@ -680,49 +789,100 @@ void resize(int w, int h) srand(1); } +// randomize various indexables + +inline void rand_val(B & b) +{ + 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)); +} +inline void rand_val(P & p) +{ + float x = ( rand() % 100 ); + float y = ( rand() % 100 ); + p = P(x, y); +} +inline void rand_val(S & s) +{ + float x = ( rand() % 100 ); + float y = ( rand() % 100 ); + float w = ( rand() % 2 + 1) * (rand() % 2 ? 1.0f : -1.0f); + float h = ( rand() % 2 + 1) * (rand() % 2 ? 1.0f : -1.0f); + s = S(P(x - w, y - h),P(x + w, y + h)); +} + +// more higher-level visitors + +struct insert_random_value_v : boost::static_visitor<> +{ + template + void operator()(containers & c) const + { + V v; + rand_val(v); + + boost::geometry::index::insert(c.tree, v); + c.values.push_back(v); + + std::cout << "inserted: "; + bgi::detail::utilities::print_indexable(std::cout, v); + std::cout << '\n'; + + std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(c.tree) ? "boxes OK\n" : "WRONG BOXES!\n" ); + std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(c.tree) ? "levels OK\n" : "WRONG LEVELS!\n" ); + std::cout << "\n"; + } +}; +template +inline void insert_random_value(Cont & cont) +{ + return boost::apply_visitor(insert_random_value_v(), cont); +} + +struct remove_random_value_v : boost::static_visitor<> +{ + template + void operator()(containers & c) const + { + if ( c.values.empty() ) + return; + + size_t i = rand() % c.values.size(); + V v = c.values[i]; + + c.tree.remove(v); + c.values.erase(c.values.begin() + i); + + std::cout << "removed: "; + bgi::detail::utilities::print_indexable(std::cout, v); + std::cout << '\n'; + + std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(c.tree) ? "boxes OK\n" : "WRONG BOXES!\n" ); + std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(c.tree) ? "levels OK\n" : "WRONG LEVELS!\n" ); + std::cout << "\n"; + } +}; +template +inline void remove_random_value(Cont & cont) +{ + return boost::apply_visitor(remove_random_value_v(), cont); +} + +// handle mouse input + void mouse(int button, int state, int /*x*/, int /*y*/) { if ( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN ) { - 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); - vect.push_back(b); - - std::cout << "inserted: "; - bgi::detail::utilities::print_indexable(std::cout, b); - std::cout << '\n'; - - std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" ); - std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" ); - std::cout << "\n"; - + insert_random_value(cont); search_valid = false; } else if ( button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN ) { - if ( vect.empty() ) - return; - - size_t i = rand() % vect.size(); - B b = vect[i]; - - bgi::remove(t, b); - vect.erase(vect.begin() + i); - - std::cout << "removed: "; - bgi::detail::utilities::print_indexable(std::cout, b); - std::cout << '\n'; - - std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" ); - std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" ); - std::cout << "\n"; - + remove_random_value(cont); search_valid = false; } else if ( button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN ) @@ -733,71 +893,117 @@ void mouse(int button, int state, int /*x*/, int /*y*/) glutPostRedisplay(); } +// more higher-level visitors + +struct insert_random_values_v : boost::static_visitor<> +{ + template + void operator()(containers & c) const + { + for ( size_t i = 0 ; i < 35 ; ++i ) + { + V v; + rand_val(v); + + c.tree.insert(v); + c.values.push_back(v); + + std::cout << "inserted: "; + bgi::detail::utilities::print_indexable(std::cout, v); + std::cout << '\n'; + } + + std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(c.tree) ? "boxes OK\n" : "WRONG BOXES!\n" ); + std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(c.tree) ? "levels OK\n" : "WRONG LEVELS!\n" ); + std::cout << "\n"; + } +}; +template +inline void insert_random_values(Cont & cont) +{ + return boost::apply_visitor(insert_random_values_v(), cont); +} + +struct bulk_insert_random_values_v : boost::static_visitor<> +{ + template + void operator()(containers & c) const + { + c.values.clear(); + + for ( size_t i = 0 ; i < 35 ; ++i ) + { + V v; + rand_val(v); + + c.values.push_back(v); + + std::cout << "inserted: "; + bgi::detail::utilities::print_indexable(std::cout, v); + std::cout << '\n'; + } + + create(c.tree, c.values); + + std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(c.tree) ? "boxes OK\n" : "WRONG BOXES!\n" ); + std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(c.tree) ? "levels OK\n" : "WRONG LEVELS!\n" ); + std::cout << "\n"; + } + + template + void create(Tree & tree, Values const& values) const + { + Tree t(values); + tree = boost::move(t); + } +}; +template +inline void bulk_insert_random_values(Cont & cont) +{ + return boost::apply_visitor(bulk_insert_random_values_v(), cont); +} + +// handle keyboard input + std::string current_line; void keyboard(unsigned char key, int /*x*/, int /*y*/) { if ( key == '\r' || key == '\n' ) { - if ( current_line == "t" ) + if ( current_line == "storeb" ) + { + cont = containers(); + glutPostRedisplay(); + } +#ifdef ENABLE_POINTS_AND_SEGMENTS + else if ( current_line == "storep" ) + { + cont = containers

(); + glutPostRedisplay(); + } + else if ( current_line == "stores" ) + { + cont = containers(); + glutPostRedisplay(); + } +#endif + else if ( current_line == "t" ) { std::cout << "\n"; - bgi::detail::rtree::utilities::print(std::cout, t); + print_tree(cont); std::cout << "\n"; } else if ( current_line == "rand" ) { - for ( size_t i = 0 ; i < 35 ; ++i ) - { - 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); - vect.push_back(b); - - std::cout << "inserted: "; - bgi::detail::utilities::print_indexable(std::cout, b); - std::cout << '\n'; - } - - std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" ); - std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" ); - std::cout << "\n"; - + insert_random_values(cont); search_valid = false; glutPostRedisplay(); } else if ( current_line == "bulk" ) { - vect.clear(); - - for ( size_t i = 0 ; i < 35 ; ++i ) - { - 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)); - vect.push_back(b); - - std::cout << "inserted: "; - bgi::detail::utilities::print_indexable(std::cout, b); - std::cout << '\n'; - } - - RTree t2(vect); - t = boost::move(t2); - - std::cout << ( bgi::detail::rtree::utilities::are_boxes_ok(t) ? "boxes OK\n" : "WRONG BOXES!\n" ); - std::cout << ( bgi::detail::rtree::utilities::are_levels_ok(t) ? "levels OK\n" : "WRONG LEVELS!\n" ); - std::cout << "\n"; - + bulk_insert_random_values(cont); search_valid = false; glutPostRedisplay(); @@ -859,6 +1065,8 @@ void keyboard(unsigned char key, int /*x*/, int /*y*/) } } +// main function + int main(int argc, char **argv) { glutInit(&argc, argv);