From 68fc281a60aec78947d64abb4c2de326a3e1c825 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 28 Sep 2011 11:04:17 +0000 Subject: [PATCH] Value predicates added. Error in boost::tuple predicates check fixed. [SVN r74596] --- .../extensions/index/distance_predicates.hpp | 2 + .../geometry/extensions/index/predicates.hpp | 96 ++++++++++++------- .../extensions/index/rtree/predicates.hpp | 43 ++++----- .../index/rtree/visitors/nearest.hpp | 5 +- .../extensions/index/rtree/visitors/query.hpp | 9 +- tests/additional_sizes_and_times.cpp | 33 ++++++- 6 files changed, 121 insertions(+), 67 deletions(-) diff --git a/include/boost/geometry/extensions/index/distance_predicates.hpp b/include/boost/geometry/extensions/index/distance_predicates.hpp index e7cc5d903..4134d0941 100644 --- a/include/boost/geometry/extensions/index/distance_predicates.hpp +++ b/include/boost/geometry/extensions/index/distance_predicates.hpp @@ -122,6 +122,8 @@ detail::far far(T const& v) namespace detail { +// TODO: awulkiew - consider storing points instead of PointRelations in predicates below + template struct unbounded : nonassignable diff --git a/include/boost/geometry/extensions/index/predicates.hpp b/include/boost/geometry/extensions/index/predicates.hpp index a48d222f4..26b4967ec 100644 --- a/include/boost/geometry/extensions/index/predicates.hpp +++ b/include/boost/geometry/extensions/index/predicates.hpp @@ -27,7 +27,6 @@ struct empty {}; template struct covered_by - : nonassignable { covered_by(Geometry const& g) : geometry(g) {} Geometry geometry; @@ -35,7 +34,6 @@ struct covered_by template struct intersects - : nonassignable { intersects(Geometry const& g) : geometry(g) {} Geometry geometry; @@ -43,7 +41,6 @@ struct intersects template struct overlaps - : nonassignable { overlaps(Geometry const& g) : geometry(g) {} Geometry geometry; @@ -51,12 +48,18 @@ struct overlaps template struct within - : nonassignable { within(Geometry const& g) : geometry(g) {} Geometry geometry; }; +template +struct value +{ + value(ValuePredicate const& vpred) : value_predicate(vpred) {} + ValuePredicate value_predicate; +}; + } // namespace detail inline detail::empty empty() @@ -88,6 +91,12 @@ inline detail::within within(Geometry const& g) return detail::within(g); } +template +inline detail::value value(ValuePredicate const& vpred) +{ + return detail::value(vpred); +} + namespace detail { @@ -99,11 +108,14 @@ namespace detail // distinguish between geometries and other types by use of geometry::tag // in predicate_check_default<..., GeomTag> -> predicate_check_default<..., void> +// TODO: awulkiew - consider passing Value/Node and Translator instead of +// Value and Indexable + template struct predicate_check { - template - static inline bool apply(Geometry const& g, Indexable const& i) + template + static inline bool apply(Geometry const& g, Value const&, Indexable const& i) { return geometry::intersects(i, g); } @@ -112,8 +124,8 @@ struct predicate_check template struct predicate_check { - template - static inline bool apply(Geometry const&, Indexable const&) + template + static inline bool apply(Geometry const&, Value const&, Indexable const&) { return true; } @@ -122,8 +134,8 @@ struct predicate_check template struct predicate_check, Tag> { - template - static inline bool apply(covered_by const& p, Indexable const& i) + template + static inline bool apply(covered_by const& p, Value const&, Indexable const& i) { return geometry::covered_by(i, p.geometry); } @@ -132,8 +144,8 @@ struct predicate_check, Tag> template struct predicate_check, Tag> { - template - static inline bool apply(intersects const& p, Indexable const& i) + template + static inline bool apply(intersects const& p, Value const&, Indexable const& i) { return geometry::intersects(i, p.geometry); } @@ -142,8 +154,8 @@ struct predicate_check, Tag> template struct predicate_check, Tag> { - template - static inline bool apply(overlaps const& p, Indexable const& i) + template + static inline bool apply(overlaps const& p, Value const&, Indexable const& i) { return geometry::overlaps(i, p.geometry); } @@ -152,60 +164,70 @@ struct predicate_check, Tag> template struct predicate_check, Tag> { - template - static inline bool apply(within const& p, Indexable const& i) + template + static inline bool apply(within const& p, Value const&, Indexable const& i) { return geometry::within(i, p.geometry); } }; +template +struct predicate_check, Tag> +{ + template + static inline bool apply(value const& p, Value const& v, Indexable const&) + { + return p.value_predicate(v); + } +}; + // predicates check template struct predicates_check_tuple { - template - static inline bool apply(TuplePredicates const& p, Indexable const& i) + template + static inline bool apply(TuplePredicates const& p, Value const& v, Indexable const& i) { - return predicates_check_tuple::apply(p, i) + return predicates_check_tuple::apply(p, v, i) && predicate_check< typename boost::tuples::element::type, Tag - >::apply(boost::get(p), i); + >::apply(boost::get(p), v, i); } }; template -struct predicates_check_tuple +struct predicates_check_tuple { - template - static inline bool apply(TuplePredicates const& p, Indexable const& i) + template + static inline bool apply(TuplePredicates const& p, Value const& v, Indexable const& i) { return predicate_check< typename boost::tuples::element<0, TuplePredicates>::type, Tag - >::apply(boost::get<0>(p), i); + >::apply(boost::get<0>(p), v, i); } }; template struct predicates_check { - template - static inline bool apply(Predicate const& p, Indexable const& i) + template + static inline bool apply(Predicate const& p, Value const& v, Indexable const& i) { - return predicate_check::apply(p, i); + return predicate_check::apply(p, v, i); } }; template struct predicates_check, Tag> { - template - static inline bool apply(std::pair const& p, Indexable const& i) + template + static inline bool apply(std::pair const& p, Value const& v, Indexable const& i) { - return predicate_check::apply(p.first, i) - && predicate_check::apply(p.second, i); + return predicate_check::apply(p.first, v, i) + && predicate_check::apply(p.second, v, i); } }; @@ -221,24 +243,24 @@ struct predicates_check< { typedef boost::tuple predicates_type; - template - static inline bool apply(predicates_type const& p, Indexable const& i) + template + static inline bool apply(predicates_type const& p, Value const& v, Indexable const& i) { return predicates_check_tuple< predicates_type, Tag, boost::tuples::length::value - >::apply(p, i); + >::apply(p, v, i); } }; } // namespace detail -template -inline bool predicates_check(Predicates const& p, Indexable const& i) +template +inline bool predicates_check(Predicates const& p, Value const& v, Indexable const& i) { return detail::predicates_check - ::apply(p, i); + ::apply(p, v, i); } }}} // namespace boost::geometry::index diff --git a/include/boost/geometry/extensions/index/rtree/predicates.hpp b/include/boost/geometry/extensions/index/rtree/predicates.hpp index 35efc773f..75306e22f 100644 --- a/include/boost/geometry/extensions/index/rtree/predicates.hpp +++ b/include/boost/geometry/extensions/index/rtree/predicates.hpp @@ -17,41 +17,24 @@ namespace boost { namespace geometry { namespace index { namespace detail { -//template -//struct predicate_check -//{ -// template -// static inline bool apply(Geometry const& g, Box const& i) -// { -// return geometry::intersects(i, g); -// } -//}; +// TODO: awulkiew - consider removing Value from parameters +// then predicates_check must be implemented for nodes as well template struct predicate_check, rtree::node_tag> { - template - static bool apply(covered_by const& p, Box const& i) + template + static bool apply(covered_by const& p, Value const&, Box const& i) { return geometry::intersects(i, p.geometry); } }; -//template -//struct predicate_check, rtree::node_predicates_tag> -//{ -// template -// static inline bool apply(intersects const& p, Box const& i) -// { -// return geometry::intersects(i, p.geometry); -// } -//}; - template struct predicate_check, rtree::node_tag> { - template - static inline bool apply(overlaps const& p, Box const& i) + template + static inline bool apply(overlaps const& p, Value const&, Box const& i) { // TODO: awulkiew - possibly change to the version without border case // e.g. intersects_without_border(0,0x1,1, 1,1x2,2) should give false @@ -62,8 +45,8 @@ struct predicate_check, rtree::node_tag> template struct predicate_check, rtree::node_tag> { - template - static bool apply(within const& p, Box const& i) + template + static bool apply(within const& p, Value const&, Box const& i) { // TODO: awulkiew - possibly change to the version without border case // e.g. intersects_without_border(0,0x1,1, 1,1x2,2) should give false @@ -71,6 +54,16 @@ struct predicate_check, rtree::node_tag> } }; +template +struct predicate_check, rtree::node_tag> +{ + template + static bool apply(value const&, Value const&, Box const&) + { + return true; + } +}; + } // namespace detail }}} // namespace boost::geometry::index diff --git a/include/boost/geometry/extensions/index/rtree/visitors/nearest.hpp b/include/boost/geometry/extensions/index/rtree/visitors/nearest.hpp index e896a90f1..0999903f9 100644 --- a/include/boost/geometry/extensions/index/rtree/visitors/nearest.hpp +++ b/include/boost/geometry/extensions/index/rtree/visitors/nearest.hpp @@ -174,7 +174,8 @@ public: it != elements.end(); ++it) { // if current node meets predicates - if ( index::predicates_check(m_pred, it->first) ) + // 0 - dummy value + if ( index::predicates_check(m_pred, 0, it->first) ) { // calculate node's distance(s) for distance predicate node_distances_type node_dist_data = node_distances_calc::apply(m_dist_pred, it->first); @@ -218,7 +219,7 @@ public: it != elements.end(); ++it) { // if value meets predicates - if ( index::predicates_check(m_pred, m_tr(*it)) ) + if ( index::predicates_check(m_pred, *it, m_tr(*it)) ) { // calculate values distance for distance predicate value_distances_type distances = value_distances_calc::apply(m_dist_pred, m_tr(*it)); diff --git a/include/boost/geometry/extensions/index/rtree/visitors/query.hpp b/include/boost/geometry/extensions/index/rtree/visitors/query.hpp index 13581945d..39a12a345 100644 --- a/include/boost/geometry/extensions/index/rtree/visitors/query.hpp +++ b/include/boost/geometry/extensions/index/rtree/visitors/query.hpp @@ -34,10 +34,13 @@ struct query typedef typename rtree::elements_type::type elements_type; elements_type const& elements = rtree::elements(n); + // traverse nodes meeting predicates for (typename elements_type::const_iterator it = elements.begin(); it != elements.end(); ++it) { - if ( index::predicates_check(pred, it->first) ) + // if node meets predicates + // 0 - dummy value + if ( index::predicates_check(pred, 0, it->first) ) rtree::apply_visitor(*this, *it->second); } } @@ -47,10 +50,12 @@ struct query typedef typename rtree::elements_type::type elements_type; elements_type const& elements = rtree::elements(n); + // get all values meeting predicates for (typename elements_type::const_iterator it = elements.begin(); it != elements.end(); ++it) { - if ( index::predicates_check(pred, tr(*it)) ) + // if value meets predicates + if ( index::predicates_check(pred, *it, tr(*it)) ) { out_iter = *it; ++out_iter; diff --git a/tests/additional_sizes_and_times.cpp b/tests/additional_sizes_and_times.cpp index 384dc1ab8..09aa04f4a 100644 --- a/tests/additional_sizes_and_times.cpp +++ b/tests/additional_sizes_and_times.cpp @@ -19,6 +19,15 @@ #include #include +template +struct test_pred +{ + bool operator()(V const& v) const + { + return v.second % 2 != 0; + } +}; + int main() { boost::timer tim; @@ -192,6 +201,28 @@ int main() std::cout << "found: " << temp << "\n"; } + // searching test + { + std::cout << "query(B) and value(odd index) searching time test... (" + << queries_count << ")\n"; + tim.restart(); + size_t temp = 0; + for (size_t i = 0 ; i < queries_count ; ++i ) + { + float x = coords[i].first; + float y = coords[i].second; + std::deque< std::pair > result; + t.query( + std::make_pair( + B(P(x - 10, y - 10), P(x + 10, y + 10)), + bgi::value(test_pred< std::pair >()) + ), std::back_inserter(result)); + temp += result.size(); + } + std::cout << "time: " << tim.elapsed() << "s\n"; + std::cout << "found: " << temp << "\n"; + } + // searching test { std::cout << "vector searching time test... (" @@ -231,7 +262,7 @@ int main() float x = coords[i].first + 100; float y = coords[i].second + 100; std::pair result; - temp += t.nearest(P(x, y), result); + temp += t.nearest(bgi::unbounded(P(x, y)), result); } std::cout << "time: " << tim.elapsed() << "s\n"; std::cout << "found: " << temp << "\n";