From cce708e4ba5a1964272b58c32f9f36d5889300dd Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 16 Jan 2025 21:43:20 +0100 Subject: [PATCH 1/3] fix: pass umbrella strategies in rtree spatial predicates --- .../geometry/index/detail/predicates.hpp | 60 +++++-------------- 1 file changed, 14 insertions(+), 46 deletions(-) diff --git a/include/boost/geometry/index/detail/predicates.hpp b/include/boost/geometry/index/detail/predicates.hpp index 0f82abc27..9b67993f5 100644 --- a/include/boost/geometry/index/detail/predicates.hpp +++ b/include/boost/geometry/index/detail/predicates.hpp @@ -174,9 +174,9 @@ template <> struct spatial_predicate_call { template - static inline bool apply(G1 const& g1, G2 const& g2, S const&) + static inline bool apply(G1 const& g1, G2 const& g2, S const& s) { - return geometry::within(g2, g1); + return geometry::within(g2, g1, s); } }; @@ -184,9 +184,9 @@ template <> struct spatial_predicate_call { template - static inline bool apply(G1 const& g1, G2 const& g2, S const&) + static inline bool apply(G1 const& g1, G2 const& g2, S const& s) { - return geometry::covered_by(g1, g2); + return geometry::covered_by(g1, g2, s); } }; @@ -194,9 +194,9 @@ template <> struct spatial_predicate_call { template - static inline bool apply(G1 const& g1, G2 const& g2, S const&) + static inline bool apply(G1 const& g1, G2 const& g2, S const& s) { - return geometry::covered_by(g2, g1); + return geometry::covered_by(g2, g1, s); } }; @@ -204,41 +204,9 @@ template <> struct spatial_predicate_call { template - static inline bool apply(G1 const& g1, G2 const& g2, S const&) - { - return geometry::disjoint(g1, g2); - } -}; - -// TEMP: used to implement CS-specific intersects predicate for certain -// combinations of geometries until umbrella strategies are implemented -template -< - typename G1, typename G2, - typename Tag1 = tag_t, - typename Tag2 = tag_t -> -struct spatial_predicate_intersects -{ - template - static inline bool apply(G1 const& g1, G2 const& g2, S const&) - { - return geometry::intersects(g1, g2); - } -}; -// TEMP: used in within and relate -template -struct spatial_predicate_intersects -{ - static inline bool apply(G1 const& g1, G2 const& g2, default_strategy const&) - { - return geometry::intersects(g1, g2); - } - - template static inline bool apply(G1 const& g1, G2 const& g2, S const& s) { - return geometry::intersects(g1, g2, s); + return geometry::disjoint(g1, g2, s); } }; @@ -248,7 +216,7 @@ struct spatial_predicate_call template static inline bool apply(G1 const& g1, G2 const& g2, S const& s) { - return spatial_predicate_intersects::apply(g1, g2, s); + return geometry::intersects(g1, g2, s); } }; @@ -256,9 +224,9 @@ template <> struct spatial_predicate_call { template - static inline bool apply(G1 const& g1, G2 const& g2, S const&) + static inline bool apply(G1 const& g1, G2 const& g2, S const& s) { - return geometry::overlaps(g1, g2); + return geometry::overlaps(g1, g2, s); } }; @@ -266,9 +234,9 @@ template <> struct spatial_predicate_call { template - static inline bool apply(G1 const& g1, G2 const& g2, S const&) + static inline bool apply(G1 const& g1, G2 const& g2, S const& s) { - return geometry::touches(g1, g2); + return geometry::touches(g1, g2, s); } }; @@ -276,9 +244,9 @@ template <> struct spatial_predicate_call { template - static inline bool apply(G1 const& g1, G2 const& g2, S const&) + static inline bool apply(G1 const& g1, G2 const& g2, S const& s) { - return geometry::within(g1, g2); + return geometry::within(g1, g2, s); } }; From cb59e0e82c9faa87b10ef6488c68512b94bb31b6 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 16 Jan 2025 21:44:00 +0100 Subject: [PATCH 2/3] test: add test for rtree with strategies in undefined cs --- index/test/rtree/CMakeLists.txt | 2 + index/test/rtree/Jamfile | 3 +- index/test/rtree/rtree_with_strategies.cpp | 156 +++++++++++++++++++++ 3 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 index/test/rtree/rtree_with_strategies.cpp diff --git a/index/test/rtree/CMakeLists.txt b/index/test/rtree/CMakeLists.txt index 5c09204f9..7c2ee72b8 100644 --- a/index/test/rtree/CMakeLists.txt +++ b/index/test/rtree/CMakeLists.txt @@ -1,4 +1,5 @@ # Boost.Geometry +# Copyright (c) 2025 Adam Wulkiewicz, Lodz, Poland. # Copyright (c) 2024, Oracle and/or its affiliates. # Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle # Use, modification and distribution is subject to the Boost Software License, @@ -13,6 +14,7 @@ foreach(item IN ITEMS rtree_move_pack rtree_non_cartesian rtree_values + rtree_with_strategies #compile-fail rtree_values_invalid ) boost_geometry_add_unit_test("index" ${item}) diff --git a/index/test/rtree/Jamfile b/index/test/rtree/Jamfile index c930e8a3f..0ea4a30d1 100644 --- a/index/test/rtree/Jamfile +++ b/index/test/rtree/Jamfile @@ -1,6 +1,6 @@ # Boost.Geometry Index # -# Copyright (c) 2011-2016 Adam Wulkiewicz, Lodz, Poland. +# Copyright (c) 2011-2025 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 @@ -19,5 +19,6 @@ test-suite boost-geometry-index-rtree [ run rtree_move_pack.cpp ] [ run rtree_non_cartesian.cpp ] [ run rtree_values.cpp ] + [ compile rtree_with_strategies.cpp ] [ compile-fail rtree_values_invalid.cpp ] ; diff --git a/index/test/rtree/rtree_with_strategies.cpp b/index/test/rtree/rtree_with_strategies.cpp new file mode 100644 index 000000000..66b192a32 --- /dev/null +++ b/index/test/rtree/rtree_with_strategies.cpp @@ -0,0 +1,156 @@ +// Boost.Geometry Index +// Unit Test + +// Copyright (c) 2025 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 +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +#define BOOST_GEOMETRY_INDEX_DETAIL_EXPERIMENTAL_PREDICATES + +#include + +#include +#include +#include + +struct point { double x, y; }; +struct box { point mi, ma; }; +struct segment { point first, second; }; + +BOOST_GEOMETRY_REGISTER_POINT_2D(point, double, cs::undefined, x, y) +BOOST_GEOMETRY_REGISTER_BOX(box, point, mi, ma) +BOOST_GEOMETRY_REGISTER_SEGMENT(segment, point, first, second) + +template +constexpr bool is_bp_or_bb_v = bg::util::is_box::value + && bg::util::is_box::value + || bg::util::is_box::value + && bg::util::is_point::value; + +template +constexpr bool is_pb_or_bb_v = bg::util::is_box::value + && bg::util::is_box::value + || bg::util::is_point::value + && bg::util::is_box::value; + +template +constexpr bool is_pp_or_bb_v = bg::util::is_box::value + && bg::util::is_box::value + || bg::util::is_point::value + && bg::util::is_point::value; + +template +< + typename QueryValue, typename Rtree, + std::enable_if_t, int> = 0 +> +void test_queries_bp_bb(Rtree const& rtree) +{ + std::vector values; + rtree.query(bgi::covered_by(QueryValue{}), std::back_inserter(values)); + rtree.query(bgi::disjoint(QueryValue{}), std::back_inserter(values)); + rtree.query(bgi::within(QueryValue{}), std::back_inserter(values)); +} + +template +< + typename QueryValue, typename Rtree, + std::enable_if_t<(!is_bp_or_bb_v), int> = 0 +> +void test_queries_bp_bb(Rtree const& ) {} + +template +< + typename QueryValue, typename Rtree, + std::enable_if_t, int> = 0 +> +void test_queries_pb_bb(Rtree const& rtree) +{ + // These predicates use algorithms that are not implemented for + // some geometry combinations + std::vector values; + rtree.query(bgi::contains(QueryValue{}), std::back_inserter(values)); + rtree.query(bgi::covers(QueryValue{}), std::back_inserter(values)); +} + +template +< + typename QueryValue, typename Rtree, + std::enable_if_t<(!is_pb_or_bb_v), int> = 0 +> +void test_queries_pb_bb(Rtree const& ) {} + +template +< + typename QueryValue, typename Rtree, + std::enable_if_t, int> = 0 +> +void test_overlaps_pp_bb(Rtree const& rtree) +{ + std::vector values; + rtree.query(bgi::overlaps(QueryValue{}), std::back_inserter(values)); + rtree.query(bgi::touches(QueryValue{}), std::back_inserter(values)); +} + +template +< + typename QueryValue, typename Rtree, + std::enable_if_t<(!is_pp_or_bb_v), int> = 0 +> +void test_overlaps_pp_bb(Rtree const& ) {} + +template +void test_queries(Rtree const& rtree) +{ + std::vector values; + rtree.query(bgi::intersects(QueryValue{}), std::back_inserter(values)); + rtree.query(bgi::nearest(QueryValue{}, 1), std::back_inserter(values)); + test_queries_bp_bb(rtree); + test_queries_pb_bb(rtree); + test_overlaps_pp_bb(rtree); +} + +template +void test_strategies() +{ + std::vector values; + bgi::rtree> rtree{values}; + rtree.insert(Value{}); + rtree.remove(Value{}); + + test_queries(rtree); + test_queries(rtree); + test_queries(rtree); +} + +template +void test_params() +{ + test_strategies>(); + test_strategies>(); + test_strategies>(); + test_strategies>(); + test_strategies>(); + test_strategies>(); +} + +template +void test_value() +{ + test_params>(); + test_params>(); + test_params>(); +} + +int test_main(int, char* []) +{ + test_value(); + test_value(); + test_value(); + + return 0; +} From 4178becbab5ff98f0de618fc0a5c61095b824d5e Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 17 Jan 2025 23:46:10 +0100 Subject: [PATCH 3/3] test: add parentheses, change names in rtree strategies test --- index/test/rtree/rtree_with_strategies.cpp | 34 ++++++++++++---------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/index/test/rtree/rtree_with_strategies.cpp b/index/test/rtree/rtree_with_strategies.cpp index 66b192a32..40abeb03e 100644 --- a/index/test/rtree/rtree_with_strategies.cpp +++ b/index/test/rtree/rtree_with_strategies.cpp @@ -26,22 +26,22 @@ BOOST_GEOMETRY_REGISTER_BOX(box, point, mi, ma) BOOST_GEOMETRY_REGISTER_SEGMENT(segment, point, first, second) template -constexpr bool is_bp_or_bb_v = bg::util::is_box::value - && bg::util::is_box::value - || bg::util::is_box::value - && bg::util::is_point::value; +constexpr bool is_bp_or_bb_v = (bg::util::is_box::value + && bg::util::is_point::value) + || (bg::util::is_box::value + && bg::util::is_box::value); template -constexpr bool is_pb_or_bb_v = bg::util::is_box::value - && bg::util::is_box::value - || bg::util::is_point::value - && bg::util::is_box::value; +constexpr bool is_pb_or_bb_v = (bg::util::is_point::value + && bg::util::is_box::value) + || (bg::util::is_box::value + && bg::util::is_box::value); template -constexpr bool is_pp_or_bb_v = bg::util::is_box::value - && bg::util::is_box::value - || bg::util::is_point::value - && bg::util::is_point::value; +constexpr bool is_pp_or_bb_v = (bg::util::is_point::value + && bg::util::is_point::value) + || (bg::util::is_box::value + && bg::util::is_box::value); template < @@ -50,6 +50,8 @@ template > void test_queries_bp_bb(Rtree const& rtree) { + // These predicates use algorithms that are not implemented for + // some geometry combinations std::vector values; rtree.query(bgi::covered_by(QueryValue{}), std::back_inserter(values)); rtree.query(bgi::disjoint(QueryValue{}), std::back_inserter(values)); @@ -89,8 +91,10 @@ template typename QueryValue, typename Rtree, std::enable_if_t, int> = 0 > -void test_overlaps_pp_bb(Rtree const& rtree) +void test_queries_pp_bb(Rtree const& rtree) { + // These predicates use algorithms that are not implemented for + // some geometry combinations std::vector values; rtree.query(bgi::overlaps(QueryValue{}), std::back_inserter(values)); rtree.query(bgi::touches(QueryValue{}), std::back_inserter(values)); @@ -101,7 +105,7 @@ template typename QueryValue, typename Rtree, std::enable_if_t<(!is_pp_or_bb_v), int> = 0 > -void test_overlaps_pp_bb(Rtree const& ) {} +void test_queries_pp_bb(Rtree const& ) {} template void test_queries(Rtree const& rtree) @@ -111,7 +115,7 @@ void test_queries(Rtree const& rtree) rtree.query(bgi::nearest(QueryValue{}, 1), std::back_inserter(values)); test_queries_bp_bb(rtree); test_queries_pb_bb(rtree); - test_overlaps_pp_bb(rtree); + test_queries_pp_bb(rtree); } template