From fb9b1d40ff853e4c88c0bdc6ba4facecd5ccdd2d Mon Sep 17 00:00:00 2001 From: Vissarion Fisikopoulos Date: Tue, 29 Jun 2021 13:20:07 +0300 Subject: [PATCH 01/19] Replace side_by_triangle with side_robust --- .../detail/equals/collect_vectors.hpp | 6 +- .../agnostic/point_in_box_by_side.hpp | 6 +- .../cartesian/distance_segment_box.hpp | 1 - .../strategies/cartesian/intersection.hpp | 4 +- .../cartesian/point_in_poly_winding.hpp | 4 +- .../geometry/strategies/relate/cartesian.hpp | 12 +- .../strategy/cartesian/side_non_robust.hpp | 1 + .../strategy/cartesian/side_robust.hpp | 119 +++++++++++++++--- include/boost/geometry/util/precise_math.hpp | 55 ++++++-- .../geometry/util/select_most_precise.hpp | 40 +++++- .../convex_hull/convex_hull_robust.cpp | 1 + .../convex_hull/test_convex_hull.hpp | 70 +++++++++-- .../overlay/get_turns_linear_linear.cpp | 13 +- .../sym_difference/sym_difference_tupled.cpp | 2 +- 14 files changed, 267 insertions(+), 67 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp b/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp index 35ec77a92..b435fff2f 100644 --- a/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp +++ b/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp @@ -40,7 +40,7 @@ #include -#include +#include #include #include @@ -62,11 +62,11 @@ struct collected_vector : nyi::not_implemented_tag {}; -// compatible with side_by_triangle cartesian strategy +// compatible with side_robust cartesian strategy template struct collected_vector < - T, Geometry, strategy::side::side_by_triangle, CSTag + T, Geometry, strategy::side::side_robust, CSTag > { typedef T type; diff --git a/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp b/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp index 5ea58736e..c794a3b23 100644 --- a/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp +++ b/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -118,7 +118,7 @@ struct cartesian_point_box_by_side < within::detail::decide_within >(point, box, - strategy::side::side_by_triangle()); + strategy::side::side_robust()); } }; @@ -189,7 +189,7 @@ struct cartesian_point_box_by_side < within::detail::decide_covered_by >(point, box, - strategy::side::side_by_triangle()); + strategy::side::side_robust()); } }; diff --git a/include/boost/geometry/strategies/cartesian/distance_segment_box.hpp b/include/boost/geometry/strategies/cartesian/distance_segment_box.hpp index c00e426a4..ab3aab726 100644 --- a/include/boost/geometry/strategies/cartesian/distance_segment_box.hpp +++ b/include/boost/geometry/strategies/cartesian/distance_segment_box.hpp @@ -17,7 +17,6 @@ #include #include #include -#include namespace boost { namespace geometry { diff --git a/include/boost/geometry/strategies/cartesian/intersection.hpp b/include/boost/geometry/strategies/cartesian/intersection.hpp index be7b92e59..cbf4aa486 100644 --- a/include/boost/geometry/strategies/cartesian/intersection.hpp +++ b/include/boost/geometry/strategies/cartesian/intersection.hpp @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include #include @@ -402,7 +402,7 @@ struct cartesian_segments return Policy::disjoint(); } - typedef side::side_by_triangle side_strategy_type; + typedef side::side_robust side_strategy_type; side_info sides; sides.set<0>(side_strategy_type::apply(q1, q2, p1), side_strategy_type::apply(q1, q2, p2)); diff --git a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp index b3556741c..3df4bcc44 100644 --- a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp +++ b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include @@ -116,7 +116,7 @@ public: else // count == 2 || count == -2 { // 1 left, -1 right - typedef side::side_by_triangle side_strategy_type; + typedef side::side_robust side_strategy_type; side = side_strategy_type::apply(s1, s2, point); } diff --git a/include/boost/geometry/strategies/relate/cartesian.hpp b/include/boost/geometry/strategies/relate/cartesian.hpp index 16c6853a3..5b418913d 100644 --- a/include/boost/geometry/strategies/relate/cartesian.hpp +++ b/include/boost/geometry/strategies/relate/cartesian.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -147,7 +148,7 @@ public: static auto side() { - return strategy::side::side_by_triangle(); + return strategy::side::side_robust(); } // within @@ -372,6 +373,15 @@ struct strategy_converter> } }; +template +struct strategy_converter> +{ + static auto get(strategy::side::side_robust const&) + { + return strategies::relate::cartesian(); + } +}; + } // namespace services diff --git a/include/boost/geometry/strategy/cartesian/side_non_robust.hpp b/include/boost/geometry/strategy/cartesian/side_non_robust.hpp index 2ef109cc1..098cb9bd4 100644 --- a/include/boost/geometry/strategy/cartesian/side_non_robust.hpp +++ b/include/boost/geometry/strategy/cartesian/side_non_robust.hpp @@ -62,6 +62,7 @@ public: * (promoted_type(get<1>(p2)) - promoted_type(get<1>(p))); auto detright = (promoted_type(get<1>(p1)) - promoted_type(get<1>(p))) * (promoted_type(get<0>(p2)) - promoted_type(get<0>(p))); + return detleft > detright ? 1 : (detleft < detright ? -1 : 0 ); } diff --git a/include/boost/geometry/strategy/cartesian/side_robust.hpp b/include/boost/geometry/strategy/cartesian/side_robust.hpp index 4ee4a1726..9e69a0c80 100644 --- a/include/boost/geometry/strategy/cartesian/side_robust.hpp +++ b/include/boost/geometry/strategy/cartesian/side_robust.hpp @@ -5,6 +5,11 @@ // Contributed and/or modified by Tinko Bartels, // as part of Google Summer of Code 2019 program. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, 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, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -12,9 +17,16 @@ #ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP #define BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP +#include + +#include + +#include + #include #include #include +#include namespace boost { namespace geometry { @@ -22,6 +34,28 @@ namespace boost { namespace geometry namespace strategy { namespace side { +struct eps_equals_policy +{ +public: + + template + static auto apply(T1 a, T2 b, Policy policy) + { + return boost::geometry::math::detail::equals_by_policy(a, b, policy); + } +}; + +struct fp_equals_policy +{ +public: + template + static auto apply(T1 a, T2 b, Policy) + { + return a == b; + } +}; + + /*! \brief Adaptive precision predicate to check at which side of a segment a point lies: left of segment (>0), right of segment (< 0), on segment (0). @@ -33,57 +67,106 @@ namespace strategy { namespace side template < typename CalculationType = void, + typename EpsPolicy = eps_equals_policy, std::size_t Robustness = 3 > struct side_robust { + template + struct eps_policy + { + eps_policy() {} + template + eps_policy(Type const& a, Type const& b, Type const& c, Type const& d) + : policy(a, b, c, d) + {} + Policy policy; + }; + public: - //! \brief Computes double the signed area of the CCW triangle p1, p2, p + + typedef cartesian_tag cs_tag; + + //! \brief Computes the sign of the CCW triangle p1, p2, p template < typename PromotedType, typename P1, typename P2, - typename P + typename P, + typename EpsPolicyInternal, + std::enable_if_t::value, int> = 0 > - static inline PromotedType side_value(P1 const& p1, P2 const& p2, - P const& p) + static inline PromotedType side_value(P1 const& p1, + P2 const& p2, + P const& p, + EpsPolicyInternal& eps_policy) { - typedef ::boost::geometry::detail::precise_math::vec2d vec2d; - vec2d pa { get<0>(p1), get<1>(p1) }; - vec2d pb { get<0>(p2), get<1>(p2) }; - vec2d pc { get<0>(p), get<1>(p) }; + using vec2d = ::boost::geometry::detail::precise_math::vec2d; + vec2d pa; + pa.x = get<0>(p1); + pa.y = get<1>(p1); + vec2d pb; + pb.x = get<0>(p2); + pb.y = get<1>(p2); + vec2d pc; + pc.x = get<0>(p); + pc.y = get<1>(p); return ::boost::geometry::detail::precise_math::orient2d - (pa, pb, pc); + (pa, pb, pc, eps_policy); + } + + template + < + typename PromotedType, + typename P1, + typename P2, + typename P, + typename EpsPolicyInternal, + std::enable_if_t::value, int> = 0 + > + static inline auto side_value(P1 const& p1, P2 const& p2, P const& p, + EpsPolicyInternal&) + { + return side_non_robust<>::apply(p1, p2, p); } #ifndef DOXYGEN_SHOULD_SKIP_THIS template - < + < typename P1, typename P2, typename P > static inline int apply(P1 const& p1, P2 const& p2, P const& p) { - typedef typename select_calculation_type_alt + using coordinate_type = typename select_calculation_type_alt < CalculationType, P1, P2, P - >::type coordinate_type; - typedef typename select_most_precise + >::type; + + using promoted_type = typename select_most_precise < coordinate_type, double - >::type promoted_type; + >::type; - promoted_type sv = side_value(p1, p2, p); - return sv > 0 ? 1 - : sv < 0 ? -1 - : 0; + eps_policy + < + boost::geometry::math::detail::equals_factor_policy + > epsp; + + promoted_type sv = side_value(p1, p2, p, epsp); + + promoted_type const zero = promoted_type(); + return EpsPolicy::apply(sv, zero, epsp.policy) ? 0 + : sv > zero ? 1 + : -1; } + #endif }; diff --git a/include/boost/geometry/util/precise_math.hpp b/include/boost/geometry/util/precise_math.hpp index c70762097..eccf08800 100644 --- a/include/boost/geometry/util/precise_math.hpp +++ b/include/boost/geometry/util/precise_math.hpp @@ -5,6 +5,10 @@ // Contributed and/or modified by Tinko Bartels, // as part of Google Summer of Code 2019 program. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle + // 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) @@ -157,7 +161,9 @@ inline int fast_expansion_sum_zeroelim( int n = InSize2) { std::array Qh; - int i_e = 0, i_f = 0, i_h = 0; + int i_e = 0; + int i_f = 0; + int i_h = 0; if (std::abs(f[0]) > std::abs(e[0])) { Qh[0] = e[i_e++]; @@ -282,14 +288,16 @@ inline RealNumber orient2dtail(vec2d const& p1, std::array& t4, std::array& t5_01, std::array& t6_01, - RealNumber const& magnitude - ) + RealNumber const& magnitude) { t5_01[1] = two_product_tail(t1[0], t2[0], t5_01[0]); t6_01[1] = two_product_tail(t3[0], t4[0], t6_01[0]); std::array tA_03 = two_two_expansion_diff(t5_01, t6_01); RealNumber det = std::accumulate(tA_03.begin(), tA_03.end(), static_cast(0)); - if(Robustness == 1) return det; + if (Robustness == 1) + { + return det; + } // see p.39, mind the different definition of epsilon for error bound RealNumber B_relative_bound = (1 + 3 * std::numeric_limits::epsilon()) @@ -347,29 +355,51 @@ inline RealNumber orient2dtail(vec2d const& p1, return(D[D_nz - 1]); } -// see page 38, Figure 21 for the calculations, notation follows the notation in the figure. +// see page 38, Figure 21 for the calculations, notation follows the notation +// in the figure. template < typename RealNumber, - std::size_t Robustness = 3 + std::size_t Robustness = 3, + typename EpsPolicy > inline RealNumber orient2d(vec2d const& p1, vec2d const& p2, - vec2d const& p3) + vec2d const& p3, + EpsPolicy& eps_policy) { - if(Robustness == 0) - { - return (p1.x - p3.x) * (p2.y - p3.y) - (p1.y - p3.y) * (p2.x - p3.x); - } + auto const x = p3.x; + auto const y = p3.y; + + auto const sx1 = p1.x; + auto const sy1 = p1.y; + auto const sx2 = p2.x; + auto const sy2 = p2.y; + + + auto const dx = sx2 - sx1; + auto const dy = sy2 - sy1; + auto const dpx = x - sx1; + auto const dpy = y - sy1; + + eps_policy = EpsPolicy(dx, dy, dpx, dpy); + std::array t1, t2, t3, t4; t1[0] = p1.x - p3.x; t2[0] = p2.y - p3.y; t3[0] = p1.y - p3.y; t4[0] = p2.x - p3.x; + std::array t5_01, t6_01; t5_01[0] = t1[0] * t2[0]; t6_01[0] = t3[0] * t4[0]; RealNumber det = t5_01[0] - t6_01[0]; + + if (Robustness == 0) + { + return det; + } + RealNumber const magnitude = std::abs(t5_01[0]) + std::abs(t6_01[0]); // see p.39, mind the different definition of epsilon for error bound @@ -388,7 +418,8 @@ inline RealNumber orient2d(vec2d const& p1, //obvious return det; } - return orient2dtail(p1, p2, p3, t1, t2, t3, t4, t5_01, t6_01, magnitude); + return orient2dtail(p1, p2, p3, t1, t2, t3, t4, + t5_01, t6_01, magnitude); } // This method adaptively computes increasingly precise approximations of the following diff --git a/include/boost/geometry/util/select_most_precise.hpp b/include/boost/geometry/util/select_most_precise.hpp index d6c6337b4..3fb8d8a73 100644 --- a/include/boost/geometry/util/select_most_precise.hpp +++ b/include/boost/geometry/util/select_most_precise.hpp @@ -30,7 +30,6 @@ namespace boost { namespace geometry namespace detail { namespace select_most_precise { - // 0 - void // 1 - integral // 2 - floating point @@ -55,6 +54,43 @@ struct type_priority > {}; +/* +// 0 - void +// 1 - integral (int, long int) +// 2 - floating point (float, double) +// 3 - long long int +// 4 - long double +// 5 - non-fundamental +template +struct type_priority + : std::conditional_t + < + std::is_void::value, + std::integral_constant, + std::conditional_t + < + std::is_fundamental::value, + std::conditional_t + < + std::is_same::value, + std::integral_constant, + std::conditional_t + < + std::is_same::value, + std::integral_constant, + std::conditional_t + < + std::is_floating_point::value, + std::integral_constant, + std::integral_constant + > + > + >, + std::integral_constant + > + > +{}; +*/ template struct type_size @@ -119,7 +155,7 @@ struct select_most_precise T2, std::conditional_t // priority1 == priority2 < - (priority1 == 0 || priority1 == 3), // both void or non-fundamental + (priority1 == 0 || priority1 == 5), // both void or non-fundamental T1, std::conditional_t // both fundamental < diff --git a/test/algorithms/convex_hull/convex_hull_robust.cpp b/test/algorithms/convex_hull/convex_hull_robust.cpp index 9ee6e55f4..1a53321fd 100644 --- a/test/algorithms/convex_hull/convex_hull_robust.cpp +++ b/test/algorithms/convex_hull/convex_hull_robust.cpp @@ -82,6 +82,7 @@ void test_all() polygon_wkt3, 5, 4, 1.4210854715202004e-14); test_geometry, non_robust_cartesian_sbt >( polygon_wkt3, 5, 5, 1.69333333333333265e-13); + return ; // missing one point could lead in arbitrary large errors in area auto polygon_wkt4 = "polygon((0.10000000000000001 0.10000000000000001,\ diff --git a/test/algorithms/convex_hull/test_convex_hull.hpp b/test/algorithms/convex_hull/test_convex_hull.hpp index df1b959b0..c901e3c0b 100644 --- a/test/algorithms/convex_hull/test_convex_hull.hpp +++ b/test/algorithms/convex_hull/test_convex_hull.hpp @@ -3,9 +3,10 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2014, 2015. -// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2015, 2021. +// Modifications copyright (c) 2014-2021 Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -43,7 +44,11 @@ struct robust_cartesian : boost::geometry::strategies::detail::cartesian_base { static auto side() { - return boost::geometry::strategy::side::side_robust<>(); + return boost::geometry::strategy::side::side_robust + < + double, + boost::geometry::strategy::side::fp_equals_policy + >(); } }; @@ -159,15 +164,12 @@ struct test_convex_hull std::size_t size_hull_closed, double expected_area, double expected_perimeter, - bool reverse) + bool /*reverse*/) { - bool const is_original_closed = resolve_variant::get_closure(geometry) != bg::open; static bool const is_hull_closed = bg::closure::value != bg::open; // convex_hull_insert() uses the original Geometry as a source of the info // about the order and closure - std::size_t const size_hull_from_orig = is_original_closed ? - size_hull_closed : size_hull_closed - 1; std::size_t const size_hull = is_hull_closed ? size_hull_closed : size_hull_closed - 1; @@ -179,14 +181,19 @@ struct test_convex_hull check_convex_hull(geometry, hull, size_original, size_hull, expected_area, expected_perimeter, false, AreaStrategy()); - // Test version with output iterator and strategy + // Do not test with output iterator since it does not support + // non-default strategy + /* + bool const is_original_closed = resolve_variant::get_closure(geometry) != bg::open; + std::size_t const size_hull_from_orig = is_original_closed ? + size_hull_closed : size_hull_closed - 1; bg::clear(hull); bg::detail::convex_hull::convex_hull_insert( geometry, std::back_inserter(hull.outer()), Strategy()); check_convex_hull(geometry, hull, size_original, size_hull_from_orig, expected_area, expected_perimeter, reverse, AreaStrategy()); - + */ } }; @@ -254,6 +261,49 @@ struct test_convex_hull }; +template +< + typename Hull +> +struct test_convex_hull +{ + template + static void apply(Geometry const& geometry, + std::size_t size_original, + std::size_t size_hull_closed, + double expected_area, + double expected_perimeter, + bool reverse) + { + bool const is_original_closed = resolve_variant::get_closure(geometry) != bg::open; + static bool const is_hull_closed = bg::closure::value != bg::open; + + // convex_hull_insert() uses the original Geometry as a source of the info + // about the order and closure + std::size_t const size_hull_from_orig = is_original_closed ? + size_hull_closed : size_hull_closed - 1; + std::size_t const size_hull = is_hull_closed ? size_hull_closed : + size_hull_closed - 1; + + Hull hull; + + // Test version with strategy + bg::clear(hull); + bg::convex_hull(geometry, hull.outer(), robust_cartesian()); + check_convex_hull(geometry, hull, size_original, size_hull, expected_area, + expected_perimeter, false, precise_cartesian()); + + // Test version with output iterator and strategy + bg::clear(hull); + bg::detail::convex_hull::convex_hull_insert(geometry, + std::back_inserter(hull.outer()), robust_cartesian()); + check_convex_hull(geometry, hull, size_original, size_hull_from_orig, + expected_area, expected_perimeter, reverse, precise_cartesian()); + + } +}; + + template < typename Geometry, @@ -342,6 +392,4 @@ void test_empty_input() BOOST_CHECK_MESSAGE(bg::is_empty(hull), "Output convex hull should be empty" ); } - - #endif diff --git a/test/algorithms/overlay/get_turns_linear_linear.cpp b/test/algorithms/overlay/get_turns_linear_linear.cpp index b6d0c8266..11b1453ea 100644 --- a/test/algorithms/overlay/get_turns_linear_linear.cpp +++ b/test/algorithms/overlay/get_turns_linear_linear.cpp @@ -285,21 +285,12 @@ void test_all() "LINESTRING(2 8,4 0.4,8 1,0 5)", expected("iuu++")("mui=+")("tiu+=")); -#if ! ( defined(BOOST_CLANG) && defined(BOOST_GEOMETRY_COMPILER_MODE_RELEASE) ) - - // In clang/release mode this testcase gives other results - - // assertion failure in 1.57 - // FAILING - no assertion failure but the result is not very good test_geometry("LINESTRING(-2305843009213693956 4611686018427387906, -33 -92, 78 83)", "LINESTRING(31 -97, -46 57, -20 -4)", - expected("")("")); + expected("iuu++")); test_geometry("LINESTRING(31 -97, -46 57, -20 -4)", "LINESTRING(-2305843009213693956 4611686018427387906, -33 -92, 78 83)", - expected("")("")); - -#endif - + expected("iuu++")); } // In 1.57 the results of those combinations was different for MinGW diff --git a/test/algorithms/set_operations/sym_difference/sym_difference_tupled.cpp b/test/algorithms/set_operations/sym_difference/sym_difference_tupled.cpp index 0985ed410..9730935fc 100644 --- a/test/algorithms/set_operations/sym_difference/sym_difference_tupled.cpp +++ b/test/algorithms/set_operations/sym_difference/sym_difference_tupled.cpp @@ -348,7 +348,7 @@ inline void test_aa() "MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))," "((2 6, 2 8, 8 8, 8 5, 7 5, 7 6, 2 6)))", "MULTIPOLYGON(((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0))," - "((5 0, 5 1, 6 1, 6 4, 5 4, 3 6, 2 5, 2 7, 7 7, 7 0 5 0)))", + "((5 0, 5 1, 6 1, 6 4, 5 4, 3 6, 2 5, 2 7, 7 7, 7 0, 5 0)))", "MULTIPOINT()", "MULTILINESTRING()", "MULTIPOLYGON(((0 0,0 5,4 5,3 6,7 6,7 7,2 7,2 8,8 8,8 5,7 5,7 0,0 0)," From 6b49308808ab123fb22d2a0529b81861a8d9d909 Mon Sep 17 00:00:00 2001 From: Vissarion Fisikopoulos Date: Wed, 30 Jun 2021 12:51:28 +0300 Subject: [PATCH 02/19] Move side_by_triangle to strategy/cartesian --- .../agnostic/point_in_box_by_side.hpp | 6 +- .../strategies/cartesian/intersection.hpp | 2 +- .../cartesian/point_in_poly_winding.hpp | 2 +- .../strategies/cartesian/side_by_triangle.hpp | 270 +----------------- .../strategies/convex_hull/cartesian.hpp | 2 +- .../strategies/intersection_strategies.hpp | 4 +- .../strategies/is_convex/cartesian.hpp | 4 +- .../geometry/strategies/relate/cartesian.hpp | 3 +- .../boost/geometry/strategies/strategies.hpp | 3 +- .../strategy/cartesian/side_by_triangle.hpp | 262 +++++++++++++++++ .../strategy/cartesian/side_non_robust.hpp | 7 +- .../strategy/cartesian/side_robust.hpp | 23 +- .../geometry/util/select_most_precise.hpp | 40 +-- .../convex_hull/convex_hull_robust.cpp | 1 - .../convex_hull/test_convex_hull.hpp | 5 +- test/algorithms/overlay/relative_order.cpp | 4 +- test/strategies/spherical_side.cpp | 2 +- test/strategies/test_within.hpp | 3 +- 18 files changed, 317 insertions(+), 326 deletions(-) create mode 100644 include/boost/geometry/strategy/cartesian/side_by_triangle.hpp diff --git a/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp b/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp index c794a3b23..8c3f0ba0a 100644 --- a/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp +++ b/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp @@ -20,12 +20,16 @@ #include #include + #include #include + #include + +#include + #include #include -#include #include #include diff --git a/include/boost/geometry/strategies/cartesian/intersection.hpp b/include/boost/geometry/strategies/cartesian/intersection.hpp index cbf4aa486..f81a98998 100644 --- a/include/boost/geometry/strategies/cartesian/intersection.hpp +++ b/include/boost/geometry/strategies/cartesian/intersection.hpp @@ -38,13 +38,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include diff --git a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp index 3df4bcc44..3268d5a33 100644 --- a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp +++ b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp @@ -24,10 +24,10 @@ #include #include +#include #include #include -#include #include #include diff --git a/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp b/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp index 989f3fbb1..848570fd9 100644 --- a/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp +++ b/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp @@ -1,275 +1,21 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) +// Boost.Geometry -// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. -// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. +// Copyright (c) 2021, Oracle and/or its affiliates. -// This file was modified by Oracle on 2015-2021. -// Modifications copyright (c) 2015-2021, Oracle and/or its affiliates. +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle -// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - -// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library -// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. - -// 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) +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP -#include - -#include - -#include - -#include -#include -#include -#include - -#include - -#include +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") -namespace boost { namespace geometry -{ - -namespace strategy { namespace side -{ - -/*! -\brief Check at which side of a segment a point lies: - left of segment (> 0), right of segment (< 0), on segment (0) -\ingroup strategies -\tparam CalculationType \tparam_calculation - */ -template -class side_by_triangle -{ - template - struct eps_policy - { - eps_policy() {} - template - eps_policy(Type const& a, Type const& b, Type const& c, Type const& d) - : policy(a, b, c, d) - {} - Policy policy; - }; - - struct eps_empty - { - eps_empty() {} - template - eps_empty(Type const&, Type const&, Type const&, Type const&) {} - }; - -public : - typedef cartesian_tag cs_tag; - - // Template member function, because it is not always trivial - // or convenient to explicitly mention the typenames in the - // strategy-struct itself. - - // Types can be all three different. Therefore it is - // not implemented (anymore) as "segment" - - template - < - typename CoordinateType, - typename PromotedType, - typename P1, - typename P2, - typename P, - typename EpsPolicy - > - static inline - PromotedType side_value(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & eps_policy) - { - CoordinateType const x = get<0>(p); - CoordinateType const y = get<1>(p); - - CoordinateType const sx1 = get<0>(p1); - CoordinateType const sy1 = get<1>(p1); - CoordinateType const sx2 = get<0>(p2); - CoordinateType const sy2 = get<1>(p2); - - PromotedType const dx = sx2 - sx1; - PromotedType const dy = sy2 - sy1; - PromotedType const dpx = x - sx1; - PromotedType const dpy = y - sy1; - - eps_policy = EpsPolicy(dx, dy, dpx, dpy); - - return geometry::detail::determinant - ( - dx, dy, - dpx, dpy - ); - - } - - template - < - typename CoordinateType, - typename PromotedType, - typename P1, - typename P2, - typename P - > - static inline - PromotedType side_value(P1 const& p1, P2 const& p2, P const& p) - { - eps_empty dummy; - return side_value(p1, p2, p, dummy); - } - - - template - < - typename CoordinateType, - typename PromotedType, - bool AreAllIntegralCoordinates - > - struct compute_side_value - { - template - static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp) - { - return side_value(p1, p2, p, epsp); - } - }; - - template - struct compute_side_value - { - template - static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp) - { - // For robustness purposes, first check if any two points are - // the same; in this case simply return that the points are - // collinear - if (equals_point_point(p1, p2) - || equals_point_point(p1, p) - || equals_point_point(p2, p)) - { - return PromotedType(0); - } - - // The side_by_triangle strategy computes the signed area of - // the point triplet (p1, p2, p); as such it is (in theory) - // invariant under cyclic permutations of its three arguments. - // - // In the context of numerical errors that arise in - // floating-point computations, and in order to make the strategy - // consistent with respect to cyclic permutations of its three - // arguments, we cyclically permute them so that the first - // argument is always the lexicographically smallest point. - - typedef compare::cartesian less; - - if (less::apply(p, p1)) - { - if (less::apply(p, p2)) - { - // p is the lexicographically smallest - return side_value(p, p1, p2, epsp); - } - else - { - // p2 is the lexicographically smallest - return side_value(p2, p, p1, epsp); - } - } - - if (less::apply(p1, p2)) - { - // p1 is the lexicographically smallest - return side_value(p1, p2, p, epsp); - } - else - { - // p2 is the lexicographically smallest - return side_value(p2, p, p1, epsp); - } - } - }; - - - template - static inline int apply(P1 const& p1, P2 const& p2, P const& p) - { - typedef typename coordinate_type::type coordinate_type1; - typedef typename coordinate_type::type coordinate_type2; - typedef typename coordinate_type

::type coordinate_type3; - - typedef std::conditional_t - < - std::is_void::value, - typename select_most_precise - < - coordinate_type1, - coordinate_type2, - coordinate_type3 - >::type, - CalculationType - > coordinate_type; - - // Promote float->double, small int->int - typedef typename select_most_precise - < - coordinate_type, - double - >::type promoted_type; - - bool const are_all_integral_coordinates = - std::is_integral::value - && std::is_integral::value - && std::is_integral::value; - - eps_policy< math::detail::equals_factor_policy > epsp; - promoted_type s = compute_side_value - < - coordinate_type, promoted_type, are_all_integral_coordinates - >::apply(p1, p2, p, epsp); - - promoted_type const zero = promoted_type(); - return math::detail::equals_by_policy(s, zero, epsp.policy) ? 0 - : s > zero ? 1 - : -1; - } - -private: - template - static inline bool equals_point_point(P1 const& p1, P2 const& p2) - { - return strategy::within::cartesian_point_point::apply(p1, p2); - } -}; - - -#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS -namespace services -{ - -template -struct default_strategy -{ - typedef side_by_triangle type; -}; - -} -#endif - -}} // namespace strategy::side - -}} // namespace boost::geometry +#include #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP diff --git a/include/boost/geometry/strategies/convex_hull/cartesian.hpp b/include/boost/geometry/strategies/convex_hull/cartesian.hpp index 1bef4e389..c357ba95e 100644 --- a/include/boost/geometry/strategies/convex_hull/cartesian.hpp +++ b/include/boost/geometry/strategies/convex_hull/cartesian.hpp @@ -10,10 +10,10 @@ #ifndef BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP #define BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP +#include #include #include -#include namespace boost { namespace geometry { diff --git a/include/boost/geometry/strategies/intersection_strategies.hpp b/include/boost/geometry/strategies/intersection_strategies.hpp index bba6545c9..afb1afb5d 100644 --- a/include/boost/geometry/strategies/intersection_strategies.hpp +++ b/include/boost/geometry/strategies/intersection_strategies.hpp @@ -19,12 +19,12 @@ #include #include +#include + #include #include #include - #include -#include #include #include diff --git a/include/boost/geometry/strategies/is_convex/cartesian.hpp b/include/boost/geometry/strategies/is_convex/cartesian.hpp index 4297c223b..d274086ab 100644 --- a/include/boost/geometry/strategies/is_convex/cartesian.hpp +++ b/include/boost/geometry/strategies/is_convex/cartesian.hpp @@ -10,12 +10,14 @@ #ifndef BOOST_GEOMETRY_STRATEGIES_IS_CONVEX_CARTESIAN_HPP #define BOOST_GEOMETRY_STRATEGIES_IS_CONVEX_CARTESIAN_HPP +#include +#include #include -#include #include #include #include + #include diff --git a/include/boost/geometry/strategies/relate/cartesian.hpp b/include/boost/geometry/strategies/relate/cartesian.hpp index 5b418913d..913ef714a 100644 --- a/include/boost/geometry/strategies/relate/cartesian.hpp +++ b/include/boost/geometry/strategies/relate/cartesian.hpp @@ -20,13 +20,14 @@ #include #include #include -#include #include #include #include #include +#include +#include #include diff --git a/include/boost/geometry/strategies/strategies.hpp b/include/boost/geometry/strategies/strategies.hpp index 66cbc9383..541ae1d25 100644 --- a/include/boost/geometry/strategies/strategies.hpp +++ b/include/boost/geometry/strategies/strategies.hpp @@ -67,7 +67,6 @@ #include #include #include -#include #include #include @@ -135,6 +134,8 @@ #include #include #include +#include +#include #include #include diff --git a/include/boost/geometry/strategy/cartesian/side_by_triangle.hpp b/include/boost/geometry/strategy/cartesian/side_by_triangle.hpp new file mode 100644 index 000000000..56436a2a2 --- /dev/null +++ b/include/boost/geometry/strategy/cartesian/side_by_triangle.hpp @@ -0,0 +1,262 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. + +// This file was modified by Oracle on 2015-2021. +// Modifications copyright (c) 2015-2021, Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library +// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. + +// 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) + +#ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_BY_TRIANGLE_HPP +#define BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_BY_TRIANGLE_HPP + + +#include + +#include + +#include + +#include +#include +#include +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace side +{ + +/*! +\brief Check at which side of a segment a point lies: + left of segment (> 0), right of segment (< 0), on segment (0) +\ingroup strategies +\tparam CalculationType \tparam_calculation + */ +template +class side_by_triangle +{ + template + struct eps_policy + { + eps_policy() {} + template + eps_policy(Type const& a, Type const& b, Type const& c, Type const& d) + : policy(a, b, c, d) + {} + Policy policy; + }; + + struct eps_empty + { + eps_empty() {} + template + eps_empty(Type const&, Type const&, Type const&, Type const&) {} + }; + +public : + typedef cartesian_tag cs_tag; + + // Template member function, because it is not always trivial + // or convenient to explicitly mention the typenames in the + // strategy-struct itself. + + // Types can be all three different. Therefore it is + // not implemented (anymore) as "segment" + + template + < + typename CoordinateType, + typename PromotedType, + typename P1, + typename P2, + typename P, + typename EpsPolicy + > + static inline + PromotedType side_value(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & eps_policy) + { + CoordinateType const x = get<0>(p); + CoordinateType const y = get<1>(p); + + CoordinateType const sx1 = get<0>(p1); + CoordinateType const sy1 = get<1>(p1); + CoordinateType const sx2 = get<0>(p2); + CoordinateType const sy2 = get<1>(p2); + + PromotedType const dx = sx2 - sx1; + PromotedType const dy = sy2 - sy1; + PromotedType const dpx = x - sx1; + PromotedType const dpy = y - sy1; + + eps_policy = EpsPolicy(dx, dy, dpx, dpy); + + return geometry::detail::determinant + ( + dx, dy, + dpx, dpy + ); + + } + + template + < + typename CoordinateType, + typename PromotedType, + typename P1, + typename P2, + typename P + > + static inline + PromotedType side_value(P1 const& p1, P2 const& p2, P const& p) + { + eps_empty dummy; + return side_value(p1, p2, p, dummy); + } + + + template + < + typename CoordinateType, + typename PromotedType, + bool AreAllIntegralCoordinates + > + struct compute_side_value + { + template + static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp) + { + return side_value(p1, p2, p, epsp); + } + }; + + template + struct compute_side_value + { + template + static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp) + { + // For robustness purposes, first check if any two points are + // the same; in this case simply return that the points are + // collinear + if (equals_point_point(p1, p2) + || equals_point_point(p1, p) + || equals_point_point(p2, p)) + { + return PromotedType(0); + } + + // The side_by_triangle strategy computes the signed area of + // the point triplet (p1, p2, p); as such it is (in theory) + // invariant under cyclic permutations of its three arguments. + // + // In the context of numerical errors that arise in + // floating-point computations, and in order to make the strategy + // consistent with respect to cyclic permutations of its three + // arguments, we cyclically permute them so that the first + // argument is always the lexicographically smallest point. + + typedef compare::cartesian less; + + if (less::apply(p, p1)) + { + if (less::apply(p, p2)) + { + // p is the lexicographically smallest + return side_value(p, p1, p2, epsp); + } + else + { + // p2 is the lexicographically smallest + return side_value(p2, p, p1, epsp); + } + } + + if (less::apply(p1, p2)) + { + // p1 is the lexicographically smallest + return side_value(p1, p2, p, epsp); + } + else + { + // p2 is the lexicographically smallest + return side_value(p2, p, p1, epsp); + } + } + }; + + + template + static inline int apply(P1 const& p1, P2 const& p2, P const& p) + { + typedef typename coordinate_type::type coordinate_type1; + typedef typename coordinate_type::type coordinate_type2; + typedef typename coordinate_type

::type coordinate_type3; + + typedef std::conditional_t + < + std::is_void::value, + typename select_most_precise + < + coordinate_type1, + coordinate_type2, + coordinate_type3 + >::type, + CalculationType + > coordinate_type; + + // Promote float->double, small int->int + typedef typename select_most_precise + < + coordinate_type, + double + >::type promoted_type; + + bool const are_all_integral_coordinates = + std::is_integral::value + && std::is_integral::value + && std::is_integral::value; + + eps_policy< math::detail::equals_factor_policy > epsp; + promoted_type s = compute_side_value + < + coordinate_type, promoted_type, are_all_integral_coordinates + >::apply(p1, p2, p, epsp); + + promoted_type const zero = promoted_type(); + return math::detail::equals_by_policy(s, zero, epsp.policy) ? 0 + : s > zero ? 1 + : -1; + } + +private: + template + static inline bool equals_point_point(P1 const& p1, P2 const& p2) + { + return strategy::within::cartesian_point_point::apply(p1, p2); + } +}; + +}} // namespace strategy::side + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_BY_TRIANGLE_HPP diff --git a/include/boost/geometry/strategy/cartesian/side_non_robust.hpp b/include/boost/geometry/strategy/cartesian/side_non_robust.hpp index 098cb9bd4..add8e7972 100644 --- a/include/boost/geometry/strategy/cartesian/side_non_robust.hpp +++ b/include/boost/geometry/strategy/cartesian/side_non_robust.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2020, Oracle and/or its affiliates. +// Copyright (c) 2020-2021, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle @@ -21,7 +21,7 @@ namespace strategy { namespace side { /*! -\brief Adaptive precision predicate to check at which side of a segment a point lies: +\brief Predicate to check at which side of a segment a point lies: left of segment (>0), right of segment (< 0), on segment (0). \ingroup strategies \tparam CalculationType \tparam_calculation @@ -35,8 +35,6 @@ struct side_non_robust { public: //! \brief Computes double the signed area of the CCW triangle p1, p2, p - -#ifndef DOXYGEN_SHOULD_SKIP_THIS template < typename P1, @@ -66,7 +64,6 @@ public: return detleft > detright ? 1 : (detleft < detright ? -1 : 0 ); } -#endif }; diff --git a/include/boost/geometry/strategy/cartesian/side_robust.hpp b/include/boost/geometry/strategy/cartesian/side_robust.hpp index 9e69a0c80..61fd6827c 100644 --- a/include/boost/geometry/strategy/cartesian/side_robust.hpp +++ b/include/boost/geometry/strategy/cartesian/side_robust.hpp @@ -17,12 +17,10 @@ #ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP #define BOOST_GEOMETRY_STRATEGY_CARTESIAN_SIDE_ROBUST_HPP -#include - -#include - #include +#include + #include #include #include @@ -133,7 +131,7 @@ public: #ifndef DOXYGEN_SHOULD_SKIP_THIS template - < + < typename P1, typename P2, typename P @@ -171,6 +169,21 @@ public: }; +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef side_robust type; +}; + +} + +#endif + }} // namespace strategy::side }} // namespace boost::geometry diff --git a/include/boost/geometry/util/select_most_precise.hpp b/include/boost/geometry/util/select_most_precise.hpp index 3fb8d8a73..d6c6337b4 100644 --- a/include/boost/geometry/util/select_most_precise.hpp +++ b/include/boost/geometry/util/select_most_precise.hpp @@ -30,6 +30,7 @@ namespace boost { namespace geometry namespace detail { namespace select_most_precise { + // 0 - void // 1 - integral // 2 - floating point @@ -54,43 +55,6 @@ struct type_priority > {}; -/* -// 0 - void -// 1 - integral (int, long int) -// 2 - floating point (float, double) -// 3 - long long int -// 4 - long double -// 5 - non-fundamental -template -struct type_priority - : std::conditional_t - < - std::is_void::value, - std::integral_constant, - std::conditional_t - < - std::is_fundamental::value, - std::conditional_t - < - std::is_same::value, - std::integral_constant, - std::conditional_t - < - std::is_same::value, - std::integral_constant, - std::conditional_t - < - std::is_floating_point::value, - std::integral_constant, - std::integral_constant - > - > - >, - std::integral_constant - > - > -{}; -*/ template struct type_size @@ -155,7 +119,7 @@ struct select_most_precise T2, std::conditional_t // priority1 == priority2 < - (priority1 == 0 || priority1 == 5), // both void or non-fundamental + (priority1 == 0 || priority1 == 3), // both void or non-fundamental T1, std::conditional_t // both fundamental < diff --git a/test/algorithms/convex_hull/convex_hull_robust.cpp b/test/algorithms/convex_hull/convex_hull_robust.cpp index 1a53321fd..9ee6e55f4 100644 --- a/test/algorithms/convex_hull/convex_hull_robust.cpp +++ b/test/algorithms/convex_hull/convex_hull_robust.cpp @@ -82,7 +82,6 @@ void test_all() polygon_wkt3, 5, 4, 1.4210854715202004e-14); test_geometry, non_robust_cartesian_sbt >( polygon_wkt3, 5, 5, 1.69333333333333265e-13); - return ; // missing one point could lead in arbitrary large errors in area auto polygon_wkt4 = "polygon((0.10000000000000001 0.10000000000000001,\ diff --git a/test/algorithms/convex_hull/test_convex_hull.hpp b/test/algorithms/convex_hull/test_convex_hull.hpp index c901e3c0b..d1b01bd38 100644 --- a/test/algorithms/convex_hull/test_convex_hull.hpp +++ b/test/algorithms/convex_hull/test_convex_hull.hpp @@ -31,9 +31,10 @@ #include #include -#include -#include #include +#include +#include +#include #include diff --git a/test/algorithms/overlay/relative_order.cpp b/test/algorithms/overlay/relative_order.cpp index 8d2a5b47a..9a7cda29e 100644 --- a/test/algorithms/overlay/relative_order.cpp +++ b/test/algorithms/overlay/relative_order.cpp @@ -31,9 +31,9 @@ # include #endif -#include -#include +#include +#include template void test_with_point(std::string const& /*caseid*/, diff --git a/test/strategies/spherical_side.cpp b/test/strategies/spherical_side.cpp index 2e426fa74..51345dd21 100644 --- a/test/strategies/spherical_side.cpp +++ b/test/strategies/spherical_side.cpp @@ -27,7 +27,7 @@ #include //#include #include -#include +#include #include #include diff --git a/test/strategies/test_within.hpp b/test/strategies/test_within.hpp index f4280beb0..57ffdefa1 100644 --- a/test/strategies/test_within.hpp +++ b/test/strategies/test_within.hpp @@ -21,6 +21,8 @@ #include #include +#include + #include #include #include @@ -28,7 +30,6 @@ #include #include -#include #include // TEMP From e3eb4bae2cbac767ca1ff106dcbce504fcd0771c Mon Sep 17 00:00:00 2001 From: Vissarion Fisikopoulos Date: Fri, 2 Jul 2021 16:35:32 +0300 Subject: [PATCH 03/19] Simplify the use of eps_policy in orient2d --- include/boost/geometry/util/precise_math.hpp | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/include/boost/geometry/util/precise_math.hpp b/include/boost/geometry/util/precise_math.hpp index eccf08800..e14c20fbb 100644 --- a/include/boost/geometry/util/precise_math.hpp +++ b/include/boost/geometry/util/precise_math.hpp @@ -368,28 +368,14 @@ inline RealNumber orient2d(vec2d const& p1, vec2d const& p3, EpsPolicy& eps_policy) { - auto const x = p3.x; - auto const y = p3.y; - - auto const sx1 = p1.x; - auto const sy1 = p1.y; - auto const sx2 = p2.x; - auto const sy2 = p2.y; - - - auto const dx = sx2 - sx1; - auto const dy = sy2 - sy1; - auto const dpx = x - sx1; - auto const dpy = y - sy1; - - eps_policy = EpsPolicy(dx, dy, dpx, dpy); - std::array t1, t2, t3, t4; t1[0] = p1.x - p3.x; t2[0] = p2.y - p3.y; t3[0] = p1.y - p3.y; t4[0] = p2.x - p3.x; + eps_policy = EpsPolicy(t1[0], t2[0], t3[0], t4[0]); + std::array t5_01, t6_01; t5_01[0] = t1[0] * t2[0]; t6_01[0] = t3[0] * t4[0]; From c1f8ab10de002891c34561ff3e756f996171df04 Mon Sep 17 00:00:00 2001 From: Vissarion Fisikopoulos Date: Fri, 2 Jul 2021 18:03:05 +0300 Subject: [PATCH 04/19] Refactoring the policies in side_robust --- .../strategy/cartesian/side_robust.hpp | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/include/boost/geometry/strategy/cartesian/side_robust.hpp b/include/boost/geometry/strategy/cartesian/side_robust.hpp index 61fd6827c..9d4ba785d 100644 --- a/include/boost/geometry/strategy/cartesian/side_robust.hpp +++ b/include/boost/geometry/strategy/cartesian/side_robust.hpp @@ -32,12 +32,11 @@ namespace boost { namespace geometry namespace strategy { namespace side { -struct eps_equals_policy +struct epsilon_equals_policy { public: - template - static auto apply(T1 a, T2 b, Policy policy) + static bool apply(T1 const& a, T2 const& b, Policy const& policy) { return boost::geometry::math::detail::equals_by_policy(a, b, policy); } @@ -47,7 +46,7 @@ struct fp_equals_policy { public: template - static auto apply(T1 a, T2 b, Policy) + static bool apply(T1 const& a, T2 const& b, Policy const&) { return a == b; } @@ -65,20 +64,32 @@ public: template < typename CalculationType = void, - typename EpsPolicy = eps_equals_policy, + typename EqualsPolicy = epsilon_equals_policy, std::size_t Robustness = 3 > struct side_robust { - template - struct eps_policy + + template + struct epsilon_policy { - eps_policy() {} + using Policy = boost::geometry::math::detail::equals_factor_policy; + + epsilon_policy() {} + template - eps_policy(Type const& a, Type const& b, Type const& c, Type const& d) - : policy(a, b, c, d) + epsilon_policy(Type const& a, Type const& b, Type const& c, Type const& d) + : m_policy(a, b, c, d) {} - Policy policy; + Policy m_policy; + + public: + + template + bool apply(T1 a, T2 b) const + { + return EqualsPolicy::apply(a, b, m_policy); + } }; public: @@ -152,15 +163,11 @@ public: double >::type; - eps_policy - < - boost::geometry::math::detail::equals_factor_policy - > epsp; - + epsilon_policy epsp; promoted_type sv = side_value(p1, p2, p, epsp); - promoted_type const zero = promoted_type(); - return EpsPolicy::apply(sv, zero, epsp.policy) ? 0 + + return epsp.apply(sv, zero) ? 0 : sv > zero ? 1 : -1; } From 6ca6dadede270d22a746b120a70b30cbbf02e4e2 Mon Sep 17 00:00:00 2001 From: Vissarion Fisikopoulos Date: Tue, 13 Jul 2021 13:58:01 +0300 Subject: [PATCH 05/19] Rewrite non robust side predicate --- .../strategy/cartesian/side_non_robust.hpp | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/include/boost/geometry/strategy/cartesian/side_non_robust.hpp b/include/boost/geometry/strategy/cartesian/side_non_robust.hpp index add8e7972..9400f9bd6 100644 --- a/include/boost/geometry/strategy/cartesian/side_non_robust.hpp +++ b/include/boost/geometry/strategy/cartesian/side_non_robust.hpp @@ -14,6 +14,8 @@ #include #include +#include + namespace boost { namespace geometry { @@ -49,20 +51,43 @@ public: P1, P2, P - >::type coordinate_type; + >::type CoordinateType; typedef typename select_most_precise < - coordinate_type, + CoordinateType, double - >::type promoted_type; + >::type PromotedType; - auto detleft = (promoted_type(get<0>(p1)) - promoted_type(get<0>(p))) - * (promoted_type(get<1>(p2)) - promoted_type(get<1>(p))); - auto detright = (promoted_type(get<1>(p1)) - promoted_type(get<1>(p))) - * (promoted_type(get<0>(p2)) - promoted_type(get<0>(p))); + CoordinateType const x = get<0>(p); + CoordinateType const y = get<1>(p); - return detleft > detright ? 1 : (detleft < detright ? -1 : 0 ); + CoordinateType const sx1 = get<0>(p1); + CoordinateType const sy1 = get<1>(p1); + CoordinateType const sx2 = get<0>(p2); + CoordinateType const sy2 = get<1>(p2); + //non-robust 1 + //the following is 2x slower in some generic cases when compiled with g++ + //(tested versions 9 and 10) + // + //auto detleft = (sx1 - x) * (sy2 - y); + //auto detright = (sy1 - y) * (sx2 - x); + //return detleft > detright ? 1 : (detleft < detright ? -1 : 0 ); + + //non-robust 2 + PromotedType const dx = sx2 - sx1; + PromotedType const dy = sy2 - sy1; + PromotedType const dpx = x - sx1; + PromotedType const dpy = y - sy1; + + PromotedType sv = geometry::detail::determinant + ( + dx, dy, + dpx, dpy + ); + PromotedType const zero = PromotedType(); + + return sv == 0 ? 0 : sv > zero ? 1 : -1; } }; From ac89528a7c31dd08e138cd23d4173997a678cdc3 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 23 Aug 2021 12:39:08 +0200 Subject: [PATCH 06/19] [ci] Scan index/test dir while getting dependencies. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a61e96d1c..8af7fca8a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -60,7 +60,7 @@ jobs: git submodule update --init tools/build git submodule update --init libs/config git submodule update --init tools/boostdep - python tools/boostdep/depinst/depinst.py geometry + python tools/boostdep/depinst/depinst.py geometry -I index/test ./bootstrap.sh ./b2 headers - run: mkdir $COVERAGE_DIR From 38031de1f21f7544693d9160b896a791fbf603b2 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 23 Aug 2021 13:04:06 +0200 Subject: [PATCH 07/19] [test][index] Drop Bforeach dependency from rtree tests. --- index/test/rtree/rtree_test_generator.cpp | 15 ++- index/test/rtree/test_rtree.hpp | 156 ++++++++++++++-------- 2 files changed, 108 insertions(+), 63 deletions(-) diff --git a/index/test/rtree/rtree_test_generator.cpp b/index/test/rtree/rtree_test_generator.cpp index e1d76ee2f..512ef4306 100644 --- a/index/test/rtree/rtree_test_generator.cpp +++ b/index/test/rtree/rtree_test_generator.cpp @@ -3,6 +3,10 @@ // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // 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) @@ -10,7 +14,6 @@ #include #include #include -#include #include #include @@ -46,13 +49,13 @@ int main() testsets.push_back(std::make_pair("testset::queries", "que")); testsets.push_back(std::make_pair("testset::additional", "add")); - BOOST_FOREACH(P const& p, parameters) + for (P const& p : parameters) { - BOOST_FOREACH(TS const& ts, testsets) + for (TS const& ts : testsets) { - BOOST_FOREACH(std::string const& i, indexables) + for (std::string const& i : indexables) { - BOOST_FOREACH(std::string const& d, dimensions) + for (std::string const& d : dimensions) { // If the I is Segment, generate only for 2d if ( i == "s" && d != "2" ) @@ -60,7 +63,7 @@ int main() continue; } - BOOST_FOREACH(CT const& c, coordinate_types) + for (CT const& c : coordinate_types) { std::string filename = std::string() + "rtree_" + boost::get<1>(p) + '_' + ts.second + '_' + i + d + boost::get<1>(c) + ".cpp"; diff --git a/index/test/rtree/test_rtree.hpp b/index/test/rtree/test_rtree.hpp index 77f1f5312..4b18f65e6 100644 --- a/index/test/rtree/test_rtree.hpp +++ b/index/test/rtree/test_rtree.hpp @@ -14,7 +14,6 @@ #ifndef BOOST_GEOMETRY_INDEX_TEST_RTREE_HPP #define BOOST_GEOMETRY_INDEX_TEST_RTREE_HPP -#include #include #include @@ -681,15 +680,16 @@ void rtree(Rtree & tree, Elements & input, Box & qbox) } // namespace generate -namespace basictest { +namespace basictest +{ // low level test functions template Iter find(Rtree const& rtree, Iter first, Iter last, Value const& value) { - for ( ; first != last ; ++first ) - if ( rtree.value_eq()(value, *first) ) + for (; first != last; ++first) + if (rtree.value_eq()(value, *first)) return first; return first; } @@ -698,12 +698,12 @@ template void compare_outputs(Rtree const& rtree, std::vector const& output, std::vector const& expected_output) { bool are_sizes_ok = (expected_output.size() == output.size()); - BOOST_CHECK( are_sizes_ok ); - if ( are_sizes_ok ) + BOOST_CHECK(are_sizes_ok); + if (are_sizes_ok) { - BOOST_FOREACH(Value const& v, expected_output) + for (Value const& v : expected_output) { - BOOST_CHECK(find(rtree, output.begin(), output.end(), v) != output.end() ); + BOOST_CHECK(find(rtree, output.begin(), output.end(), v) != output.end()); } } } @@ -715,13 +715,13 @@ void exactly_the_same_outputs(Rtree const& rtree, Range1 const& output, Range2 c size_t s2 = std::distance(expected_output.begin(), expected_output.end()); BOOST_CHECK(s1 == s2); - if ( s1 == s2 ) + if (s1 == s2) { typename Range1::const_iterator it1 = output.begin(); typename Range2::const_iterator it2 = expected_output.begin(); - for ( ; it1 != output.end() && it2 != expected_output.end() ; ++it1, ++it2 ) + for (; it1 != output.end() && it2 != expected_output.end(); ++it1, ++it2) { - if ( !rtree.value_eq()(*it1, *it2) ) + if (!rtree.value_eq()(*it1, *it2)) { BOOST_CHECK(false && "rtree.translator().equals(*it1, *it2)"); break; @@ -734,7 +734,7 @@ void exactly_the_same_outputs(Rtree const& rtree, Range1 const& output, Range2 c template void copy_alt(First first, Last last, Out out) { - for ( ; first != last ; ++first, ++out ) + for (; first != last; ++first, ++out) *out = *first; } @@ -759,7 +759,7 @@ void check_fwd_iterators(QItF first, QItL last) #endif QItF it = first; - for ( ; it != last && first != last ; ++it, ++first) + for (; it != last && first != last; ++it, ++first) { BOOST_CHECK(it == first); @@ -775,20 +775,20 @@ void check_fwd_iterators(QItF first, QItL last) template void spatial_query(Rtree & rtree, Predicates const& pred, std::vector const& expected_output) { - BOOST_CHECK( bgi::detail::rtree::utilities::are_levels_ok(rtree) ); - if ( !rtree.empty() ) - BOOST_CHECK( bgi::detail::rtree::utilities::are_boxes_ok(rtree) ); + BOOST_CHECK(bgi::detail::rtree::utilities::are_levels_ok(rtree)); + if (!rtree.empty()) + BOOST_CHECK(bgi::detail::rtree::utilities::are_boxes_ok(rtree)); std::vector output; size_t n = rtree.query(pred, std::back_inserter(output)); - BOOST_CHECK( expected_output.size() == n ); + BOOST_CHECK(expected_output.size() == n); compare_outputs(rtree, output, expected_output); std::vector output2; size_t n2 = query(rtree, pred, std::back_inserter(output2)); - - BOOST_CHECK( n == n2 ); + + BOOST_CHECK(n == n2); exactly_the_same_outputs(rtree, output, output2); exactly_the_same_outputs(rtree, output, rtree | bgi::adaptors::queried(pred)); @@ -827,9 +827,13 @@ void intersects(Rtree const& tree, std::vector const& input, Box const& q { std::vector expected_output; - BOOST_FOREACH(Value const& v, input) - if ( bg::intersects(tree.indexable_get()(v), qbox) ) + for (Value const& v : input) + { + if (bg::intersects(tree.indexable_get()(v), qbox)) + { expected_output.push_back(v); + } + } //spatial_query(tree, qbox, expected_output); spatial_query(tree, bgi::intersects(qbox), expected_output); @@ -851,9 +855,13 @@ void disjoint(Rtree const& tree, std::vector const& input, Box const& qbo { std::vector expected_output; - BOOST_FOREACH(Value const& v, input) - if ( bg::disjoint(tree.indexable_get()(v), qbox) ) + for (Value const& v : input) + { + if (bg::disjoint(tree.indexable_get()(v), qbox)) + { expected_output.push_back(v); + } + } spatial_query(tree, bgi::disjoint(qbox), expected_output); spatial_query(tree, !bgi::intersects(qbox), expected_output); @@ -875,9 +883,13 @@ struct contains_impl { std::vector expected_output; - BOOST_FOREACH(Value const& v, input) - if ( bg::within(qbox, tree.indexable_get()(v)) ) + for (Value const& v : input) + { + if (bg::within(qbox, tree.indexable_get()(v))) + { expected_output.push_back(v); + } + } spatial_query(tree, bgi::contains(qbox), expected_output); @@ -912,7 +924,7 @@ void contains(Rtree const& tree, std::vector const& input, Box const& qbo { contains_impl< typename bg::tag< - typename Rtree::indexable_type + typename Rtree::indexable_type >::type >::apply(tree, input, qbox); } @@ -925,12 +937,12 @@ struct covered_by_impl { std::vector expected_output; - BOOST_FOREACH(Value const& v, input) + for (Value const& v : input) { - if ( bgi::detail::covered_by_bounds( - tree.indexable_get()(v), - qbox, - bgi::detail::get_strategy(tree.parameters())) ) + if (bgi::detail::covered_by_bounds( + tree.indexable_get()(v), + qbox, + bgi::detail::get_strategy(tree.parameters()))) { expected_output.push_back(v); } @@ -961,7 +973,7 @@ void covered_by(Rtree const& tree, std::vector const& input, Box const& q { covered_by_impl< typename bg::tag< - typename Rtree::indexable_type + typename Rtree::indexable_type >::type >::apply(tree, input, qbox); } @@ -974,9 +986,13 @@ struct covers_impl { std::vector expected_output; - BOOST_FOREACH(Value const& v, input) - if ( bg::covered_by(qbox, tree.indexable_get()(v)) ) + for (Value const& v : input) + { + if (bg::covered_by(qbox, tree.indexable_get()(v))) + { expected_output.push_back(v); + } + } spatial_query(tree, bgi::covers(qbox), expected_output); @@ -1011,7 +1027,7 @@ void covers(Rtree const& tree, std::vector const& input, Box const& qbox) { covers_impl< typename bg::tag< - typename Rtree::indexable_type + typename Rtree::indexable_type >::type >::apply(tree, input, qbox); } @@ -1024,9 +1040,13 @@ struct overlaps_impl { std::vector expected_output; - BOOST_FOREACH(Value const& v, input) - if ( bg::overlaps(tree.indexable_get()(v), qbox) ) + for (Value const& v : input) + { + if (bg::overlaps(tree.indexable_get()(v), qbox)) + { expected_output.push_back(v); + } + } spatial_query(tree, bgi::overlaps(qbox), expected_output); @@ -1061,7 +1081,7 @@ void overlaps(Rtree const& tree, std::vector const& input, Box const& qbo { overlaps_impl< typename bg::tag< - typename Rtree::indexable_type + typename Rtree::indexable_type >::type >::apply(tree, input, qbox); } @@ -1082,9 +1102,13 @@ void overlaps(Rtree const& tree, std::vector const& input, Box const& qbo // { // std::vector expected_output; // -// BOOST_FOREACH(Value const& v, input) -// if ( bg::touches(tree.translator()(v), qbox) ) +// for (Value const& v : input) +// { +// if (bg::touches(tree.translator()(v), qbox)) +// { // expected_output.push_back(v); +// } +// } // // spatial_query(tree, bgi::touches(qbox), expected_output); // } @@ -1107,9 +1131,13 @@ struct within_impl { std::vector expected_output; - BOOST_FOREACH(Value const& v, input) - if ( bg::within(tree.indexable_get()(v), qbox) ) + for (Value const& v : input) + { + if (bg::within(tree.indexable_get()(v), qbox)) + { expected_output.push_back(v); + } + } spatial_query(tree, bgi::within(qbox), expected_output); @@ -1172,15 +1200,15 @@ inline void compare_nearest_outputs(Rtree const& rtree, std::vector const { // check output bool are_sizes_ok = (expected_output.size() == output.size()); - BOOST_CHECK( are_sizes_ok ); - if ( are_sizes_ok ) + BOOST_CHECK(are_sizes_ok); + if (are_sizes_ok) { - BOOST_FOREACH(Value const& v, output) + for (Value const& v : output) { // TODO - perform explicit check here? // should all objects which are closest be checked and should exactly the same be found? - if ( find(rtree, expected_output.begin(), expected_output.end(), v) == expected_output.end() ) + if (find(rtree, expected_output.begin(), expected_output.end(), v) == expected_output.end()) { Distance d = bg::comparable_distance(pt, rtree.indexable_get()(v)); BOOST_CHECK(d == greatest_distance); @@ -1195,7 +1223,7 @@ inline void check_sorted_by_distance(Rtree const& rtree, std::vector cons typedef typename bg::default_distance_result::type D; D prev_dist = 0; - BOOST_FOREACH(Value const& v, output) + for (Value const& v : output) { D d = bg::comparable_distance(pt, rtree.indexable_get()(v)); BOOST_CHECK(prev_dist <= d); @@ -1214,25 +1242,31 @@ inline void nearest_query_k(Rtree const& rtree, std::vector const& input, std::vector< std::pair > test_output; // calculate test output - k closest values pairs - BOOST_FOREACH(Value const& v, input) + for (Value const& v : input) { D d = bg::comparable_distance(pt, rtree.indexable_get()(v)); - if ( test_output.size() < k ) + if (test_output.size() < k) + { test_output.push_back(std::make_pair(d, v)); + } else { std::sort(test_output.begin(), test_output.end(), NearestKLess()); - if ( d < test_output.back().first ) + if (d < test_output.back().first) + { test_output.back() = std::make_pair(d, v); + } } } // caluclate biggest distance std::sort(test_output.begin(), test_output.end(), NearestKLess()); D greatest_distance = 0; - if ( !test_output.empty() ) + if (! test_output.empty()) + { greatest_distance = test_output.back().first; + } // transform test output to vector of values std::vector expected_output(test_output.size(), generate::value_default::apply()); @@ -1441,8 +1475,10 @@ void create_insert(Rtree const& tree, std::vector const& input, Box const { Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator()); - BOOST_FOREACH(Value const& v, input) + for (Value const& v : input) + { t.insert(v); + } BOOST_CHECK(tree.size() == t.size()); std::vector output; t.query(bgi::intersects(qbox), std::back_inserter(output)); @@ -1490,8 +1526,10 @@ void create_insert(Rtree const& tree, std::vector const& input, Box const { Rtree t(tree.parameters(), tree.indexable_get(), tree.value_eq(), tree.get_allocator()); - BOOST_FOREACH(Value const& v, input) + for (Value const& v : input) + { bgi::insert(t, v); + } BOOST_CHECK(tree.size() == t.size()); std::vector output; bgi::query(t, bgi::intersects(qbox), std::back_inserter(output)); @@ -1538,8 +1576,10 @@ void remove(Rtree const& tree, Box const& qbox) { Rtree t(tree); size_t r = 0; - BOOST_FOREACH(Value const& v, values_to_remove) + for (Value const& v : values_to_remove) + { r += t.remove(v); + } BOOST_CHECK( r == expected_removed_count ); std::vector output; t.query(bgi::disjoint(qbox), std::back_inserter(output)); @@ -1571,8 +1611,10 @@ void remove(Rtree const& tree, Box const& qbox) { Rtree t(tree); size_t r = 0; - BOOST_FOREACH(Value const& v, values_to_remove) + for (Value const& v : values_to_remove) + { r += bgi::remove(t, v); + } BOOST_CHECK( r == expected_removed_count ); std::vector output; bgi::query(t, bgi::disjoint(qbox), std::back_inserter(output)); @@ -1643,7 +1685,7 @@ void range(Rtree & tree, std::vector const& input) BOOST_CHECK(count == tree.size()); count = 0; - BOOST_FOREACH(Value const& v, tree) + for (Value const& v : tree) { boost::ignore_unused(v); ++count; @@ -1777,7 +1819,7 @@ void test_count_rtree_values(Parameters const& parameters, Allocator const& allo size_t values_count = Value::counter(); - BOOST_FOREACH(Value const& v, values_to_remove) + for (Value const& v : values_to_remove) { size_t r = t.remove(v); --values_count; From c67f451fa7c72b92555510379e3d62fac91eb24d Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 23 Aug 2021 17:32:58 +0200 Subject: [PATCH 08/19] Create license file. --- LICENSE_1_0.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 LICENSE_1_0.txt diff --git a/LICENSE_1_0.txt b/LICENSE_1_0.txt new file mode 100644 index 000000000..36b7cd93c --- /dev/null +++ b/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. From a8545eefb1f3f0f176ba56b2288d0b04fca53fb2 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 24 Aug 2021 19:02:25 +0200 Subject: [PATCH 09/19] [test][index] Fix different sign compare warning. --- index/test/rtree/rtree_non_cartesian.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/index/test/rtree/rtree_non_cartesian.cpp b/index/test/rtree/rtree_non_cartesian.cpp index 6111a2847..cbc4f633a 100644 --- a/index/test/rtree/rtree_non_cartesian.cpp +++ b/index/test/rtree/rtree_non_cartesian.cpp @@ -3,6 +3,10 @@ // Copyright (c) 2016 Adam Wulkiewicz, Lodz, Poland. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // 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) @@ -101,7 +105,7 @@ void test_ticket_12413() size_t num_removed = rtree.remove(std::make_pair(point_t(-0.127592, 51.503407), 796)); - BOOST_CHECK_EQUAL(num_removed, 1); + BOOST_CHECK_EQUAL(num_removed, 1u); } template From 19a742e3bb1439015f7e8b5565f29e9b5ad860a7 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 24 Aug 2021 19:56:22 +0200 Subject: [PATCH 10/19] [test][index] Fix varray test and counting_value. Explicitly declare ctors and assignments. --- index/test/rtree/test_rtree.hpp | 2 ++ index/test/varray.cpp | 12 ++++++++---- index/test/varray_test.hpp | 16 ++++++++++++---- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/index/test/rtree/test_rtree.hpp b/index/test/rtree/test_rtree.hpp index 4b18f65e6..889f61fac 100644 --- a/index/test/rtree/test_rtree.hpp +++ b/index/test/rtree/test_rtree.hpp @@ -414,6 +414,8 @@ struct counting_value counting_value(counting_value const& c) : indexable(c.indexable) { counter()++; } ~counting_value() { counter()--; } + counting_value& operator=(counting_value const& c) = default; + static size_t & counter() { static size_t c = 0; return c; } Indexable indexable; }; diff --git a/index/test/varray.cpp b/index/test/varray.cpp index d561f1c78..544e8c65f 100644 --- a/index/test/varray.cpp +++ b/index/test/varray.cpp @@ -4,6 +4,10 @@ // Copyright (c) 2012-2014 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2012-2013 Andrew Hundt. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // 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) @@ -55,11 +59,11 @@ void test_ctor_nc(size_t n) if ( 1 < n ) { T val10(10); - s[0] = val10; + s[0] = std::move(val10); BOOST_CHECK(T(10) == s[0]); BOOST_CHECK(T(10) == s.at(0)); T val20(20); - s.at(1) = val20; + s.at(1) = std::move(val20); BOOST_CHECK(T(20) == s[1]); BOOST_CHECK(T(20) == s.at(1)); } @@ -103,11 +107,11 @@ void test_resize_nc(size_t n) if ( 1 < n ) { T val10(10); - s[0] = val10; + s[0] = std::move(val10); BOOST_CHECK(T(10) == s[0]); BOOST_CHECK(T(10) == s.at(0)); T val20(20); - s.at(1) = val20; + s.at(1) = std::move(val20); BOOST_CHECK(T(20) == s[1]); BOOST_CHECK(T(20) == s.at(1)); } diff --git a/index/test/varray_test.hpp b/index/test/varray_test.hpp index 4136db7fc..bd9afa8b3 100644 --- a/index/test/varray_test.hpp +++ b/index/test/varray_test.hpp @@ -4,6 +4,10 @@ // Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2012-2013 Andrew Hundt. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // 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) @@ -23,9 +27,11 @@ public: ~value_ndc() {} bool operator==(value_ndc const& v) const { return aa == v.aa; } bool operator<(value_ndc const& v) const { return aa < v.aa; } + value_ndc(value_ndc const&) = delete; + value_ndc & operator=(value_ndc const&) = delete; + value_ndc(value_ndc&&) = default; + value_ndc & operator=(value_ndc&&) = default; private: - value_ndc(value_ndc const&) {} - value_ndc & operator=(value_ndc const&) { return *this; } size_t aa; }; @@ -47,9 +53,11 @@ public: ~value_nc() {} bool operator==(value_nc const& v) const { return aa == v.aa; } bool operator<(value_nc const& v) const { return aa < v.aa; } + value_nc(value_nc const&) = delete; + value_nc & operator=(value_nc const&) = delete; + value_nc(value_nc&&) = default; + value_nc & operator=(value_nc&&) = default; private: - value_nc(value_nc const&) {} - value_nc & operator=(value_ndc const&) { return *this; } size_t aa; }; From 98678b19c0206a1f4f3467a9e2f5f2cb6b8dc733 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 24 Aug 2021 20:00:47 +0200 Subject: [PATCH 11/19] [test][index] Do not define BOOST_NO_AUTO_PTR in Jamfile to avoid warnings. --- index/test/Jamfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/index/test/Jamfile b/index/test/Jamfile index 2b148a771..485dc1323 100644 --- a/index/test/Jamfile +++ b/index/test/Jamfile @@ -2,6 +2,10 @@ # # Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. # +# This file was modified by Oracle on 2021. +# Modifications copyright (c) 2021 Oracle and/or its affiliates. +# Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle +# # 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) @@ -16,7 +20,6 @@ project boost-geometry-index-test msvc:on msvc:/bigobj windows,intel:/bigobj - BOOST_NO_AUTO_PTR # disable the deprecated std::auto_ptr support in SmartPtr and Core /boost/timer//boost_timer ; From 8ab41f9f8e1c680f4497d8a44ba37d1e15b3cd8d Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 1 Sep 2021 15:50:42 +0200 Subject: [PATCH 12/19] [extensions] Fix nsphere concept checks compilation. --- .../nsphere/geometries/concepts/check.hpp | 50 ------------------- .../geometries/concepts/nsphere_concept.hpp | 16 ++++++ .../geometry/extensions/nsphere/nsphere.hpp | 5 +- 3 files changed, 20 insertions(+), 51 deletions(-) delete mode 100644 include/boost/geometry/extensions/nsphere/geometries/concepts/check.hpp diff --git a/include/boost/geometry/extensions/nsphere/geometries/concepts/check.hpp b/include/boost/geometry/extensions/nsphere/geometries/concepts/check.hpp deleted file mode 100644 index ecab04eff..000000000 --- a/include/boost/geometry/extensions/nsphere/geometries/concepts/check.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) - -// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. - -// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library -// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. - -// 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) - - -#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_CONCEPTS_CHECK_HPP -#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_CONCEPTS_CHECK_HPP - - -#include - - -namespace boost { namespace geometry -{ - - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - -template -struct check - : detail::concept_check::check > -{}; - -template -struct check - : detail::concept_check::check > -{}; - -} // namespace dispatch -#endif - - - - -}} // namespace boost::geometry - - -#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_GEOMETRIES_CONCEPTS_CHECK_HPP diff --git a/include/boost/geometry/extensions/nsphere/geometries/concepts/nsphere_concept.hpp b/include/boost/geometry/extensions/nsphere/geometries/concepts/nsphere_concept.hpp index 7fb631b05..a89528ce4 100644 --- a/include/boost/geometry/extensions/nsphere/geometries/concepts/nsphere_concept.hpp +++ b/include/boost/geometry/extensions/nsphere/geometries/concepts/nsphere_concept.hpp @@ -4,6 +4,10 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -117,6 +121,18 @@ public : }; +template +struct concept_type +{ + using type = Nsphere; +}; + +template +struct concept_type +{ + using type = ConstNsphere; +}; + }}} // namespace boost::geometry::concepts diff --git a/include/boost/geometry/extensions/nsphere/nsphere.hpp b/include/boost/geometry/extensions/nsphere/nsphere.hpp index bd0112704..8c2dd2c52 100644 --- a/include/boost/geometry/extensions/nsphere/nsphere.hpp +++ b/include/boost/geometry/extensions/nsphere/nsphere.hpp @@ -5,6 +5,10 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2011-2015 Adam Wulkiewicz, Lodz, Poland. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -22,7 +26,6 @@ #include #include -#include #include #include From 20840011ce2c7feaf0f6e5093478960495b297a4 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 1 Sep 2021 15:52:36 +0200 Subject: [PATCH 13/19] [test][extensions] Replace BOOST_FOREACH with range-based for loop. --- extensions/test/algorithms/connect.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/extensions/test/algorithms/connect.cpp b/extensions/test/algorithms/connect.cpp index f8766806b..7d4a274d4 100644 --- a/extensions/test/algorithms/connect.cpp +++ b/extensions/test/algorithms/connect.cpp @@ -3,6 +3,10 @@ // Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021 Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // 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) @@ -57,7 +61,7 @@ void test_connect(std::string const& caseid, Geometry const& geometry, std::size_t count = boost::size(connected_vector); std::size_t point_count = 0; - BOOST_FOREACH(GeometryOut& connected, connected_vector) + for (GeometryOut& connected : connected_vector) { bg::unique(connected); length += bg::length(connected); @@ -99,7 +103,7 @@ void test_connect(std::string const& caseid, Geometry const& geometry, mapper.map(geometry, "opacity:0.6;fill:rgb(0,0,255);stroke:rgb(0,0,0);stroke-width:1"); - BOOST_FOREACH(GeometryOut& connected, connected_vector) + for (GeometryOut& connected : connected_vector) { mapper.map(connected, "opacity:0.6;fill:none;stroke:rgb(255,0,0);stroke-width:5"); } From 69230d5c59d649c2c1aa3c579ac1e22d3fe1e1ea Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 1 Sep 2021 15:54:08 +0200 Subject: [PATCH 14/19] [extensions][test] Add/update includes. --- extensions/test/triangulation/in_circle_robust.cpp | 6 +++++- .../boost/geometry/extensions/algorithms/distance_info.hpp | 7 +++---- .../boost/geometry/extensions/gis/io/wkb/detail/endian.hpp | 6 +++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/extensions/test/triangulation/in_circle_robust.cpp b/extensions/test/triangulation/in_circle_robust.cpp index 72668e962..2eb65ec63 100644 --- a/extensions/test/triangulation/in_circle_robust.cpp +++ b/extensions/test/triangulation/in_circle_robust.cpp @@ -6,6 +6,10 @@ // Contributed and/or modified by Tinko Bartels, // as part of Google Summer of Code 2019 program. +// This file was modified by Oracle on 2021. +// Modifications copyright (c) 2021, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // 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) @@ -13,7 +17,7 @@ #include #include -#include +#include template void test_all() diff --git a/include/boost/geometry/extensions/algorithms/distance_info.hpp b/include/boost/geometry/extensions/algorithms/distance_info.hpp index eae5387ce..d64bc2d9e 100644 --- a/include/boost/geometry/extensions/algorithms/distance_info.hpp +++ b/include/boost/geometry/extensions/algorithms/distance_info.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2013 Mateusz Loskot, London, UK. // Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020, Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -30,10 +30,9 @@ #include -#include #include +#include -#include #include #include diff --git a/include/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp b/include/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp index 33d775f36..9e34f293d 100644 --- a/include/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp +++ b/include/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2020. -// Modifications copyright (c) 2020, Oracle and/or its affiliates. +// This file was modified by Oracle on 2020-2021. +// Modifications copyright (c) 2020-2021, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, @@ -31,7 +31,7 @@ #include #include #include -#include +#include #if CHAR_BIT != 8 #error Platforms with CHAR_BIT != 8 are not supported From f7aaf265af4fb1447c1489499e53f245f0ebe877 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 2 Sep 2021 15:03:20 +0200 Subject: [PATCH 15/19] [extensions] Update endian detection checks after changing headers from endian to predef. --- .../geometry/extensions/gis/io/wkb/detail/endian.hpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp b/include/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp index 9e34f293d..b02d9b1c1 100644 --- a/include/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp +++ b/include/boost/geometry/extensions/gis/io/wkb/detail/endian.hpp @@ -50,10 +50,16 @@ namespace detail { namespace endian struct big_endian_tag {}; struct little_endian_tag {}; -#ifdef BOOST_BIG_ENDIAN +#if defined(BOOST_ENDIAN_BIG_BYTE_AVAILABLE) typedef big_endian_tag native_endian_tag; -#else +#elif defined(BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE) typedef little_endian_tag native_endian_tag; +#elif defined(BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE) +#error Word-swapped big-endian not supported +#elif defined(BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE) +#error Word-swapped little-endian not supported +#else +#error Unknown endian memory ordering #endif // Unrolled loops for loading and storing streams of bytes. From f222a8f1d837cb2ed56ce0281eb888d08e00eb62 Mon Sep 17 00:00:00 2001 From: Vissarion Fisikopoulos Date: Tue, 7 Sep 2021 14:05:04 +0300 Subject: [PATCH 16/19] Create collected_vector specialization for side_by_triangle --- .../algorithms/detail/equals/collect_vectors.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp b/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp index f95309906..e6606a160 100644 --- a/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp +++ b/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp @@ -39,6 +39,7 @@ #include +#include #include #include #include @@ -156,6 +157,14 @@ private: //T dx_0, dy_0; }; +template +struct collected_vector + < + T, Geometry, strategy::side::side_by_triangle, CSTag + > + : collected_vector, CSTag> +{}; + // Compatible with spherical_side_formula which currently // is the default spherical_equatorial and geographic strategy // so CSTag is spherical_equatorial_tag or geographic_tag From 03d6e82f264162dd18d21b9d2803d2cfa9c65b7b Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Wed, 8 Sep 2021 11:23:25 +0200 Subject: [PATCH 17/19] [coordinate] deprecate util/promote_floating_point.hpp --- .../algorithms/detail/buffer/piece_border.hpp | 1 - .../geometry/core/coordinate_promotion.hpp | 111 ++++++++++++++++++ .../boost/geometry/core/coordinate_type.hpp | 10 -- include/boost/geometry/core/radian_access.hpp | 3 +- .../robustness/get_rescale_policy.hpp | 2 +- .../policies/robustness/segment_ratio.hpp | 2 +- .../geometry/strategies/cartesian/azimuth.hpp | 2 +- .../strategies/geographic/distance.hpp | 2 +- .../geographic/distance_cross_track.hpp | 2 +- .../geographic/distance_segment_box.hpp | 3 +- .../strategies/geographic/mapping_ssf.hpp | 2 +- .../geometry/strategies/geographic/side.hpp | 2 +- .../spherical/distance_cross_track.hpp | 2 +- .../spherical/distance_haversine.hpp | 2 +- .../strategies/spherical/point_in_point.hpp | 1 + .../spherical/side_by_cross_track.hpp | 2 +- .../geometry/strategies/spherical/ssf.hpp | 2 +- .../strategies/strategy_transform.hpp | 2 +- .../transform/matrix_transformers.hpp | 2 +- .../geometry/util/promote_floating_point.hpp | 32 +---- 20 files changed, 131 insertions(+), 56 deletions(-) create mode 100644 include/boost/geometry/core/coordinate_promotion.hpp diff --git a/include/boost/geometry/algorithms/detail/buffer/piece_border.hpp b/include/boost/geometry/algorithms/detail/buffer/piece_border.hpp index ecd03d9c8..13d388e4e 100644 --- a/include/boost/geometry/algorithms/detail/buffer/piece_border.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/piece_border.hpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/include/boost/geometry/core/coordinate_promotion.hpp b/include/boost/geometry/core/coordinate_promotion.hpp new file mode 100644 index 000000000..efbcdff7d --- /dev/null +++ b/include/boost/geometry/core/coordinate_promotion.hpp @@ -0,0 +1,111 @@ +// Boost.Geometry + +// Copyright (c) 2021 Barend Gehrels, Amsterdam, the Netherlands. + +// 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) + +#ifndef BOOST_GEOMETRY_CORE_COORDINATE_PROMOTION_HPP +#define BOOST_GEOMETRY_CORE_COORDINATE_PROMOTION_HPP + +#include + +// TODO: move this to a future headerfile implementing traits for these types +#include +#include +#include + +namespace boost { namespace geometry +{ + +namespace traits +{ + +// todo + +} // namespace traits + +/*! + \brief Meta-function converting, if necessary, to "a floating point" type + \details + - if input type is integer, type is double + - else type is input type + \ingroup utility + */ +// TODO: replace with, or call, promoted_to_floating_point +template +struct promote_floating_point +{ + typedef std::conditional_t + < + std::is_integral::value, + PromoteIntegerTo, + T + > type; +}; + +// TODO: replace with promoted_to_floating_point +template +struct fp_coordinate_type +{ + typedef typename promote_floating_point + < + typename coordinate_type::type + >::type type; +}; + +namespace detail +{ + +// Promote any integral type to double. Floating point +// and other user defined types stay as they are, unless specialized. +// TODO: we shold add a coordinate_promotion traits for promotion to +// floating point or (larger) integer types. +template +struct promoted_to_floating_point +{ + using type = std::conditional_t + < + std::is_integral::value, double, Type + >; +}; + +// Boost.Rational goes to double +template +struct promoted_to_floating_point> +{ + using type = double; +}; + +// Any Boost.Multiprecision goes to double (for example int128_t), +// unless specialized +template +struct promoted_to_floating_point> +{ + using type = double; +}; + +// Boost.Multiprecision binary floating point numbers are used as FP. +template +struct promoted_to_floating_point + < + boost::multiprecision::number + < + boost::multiprecision::cpp_bin_float + > + > +{ + using type = boost::multiprecision::number + < + boost::multiprecision::cpp_bin_float + >; +}; + +} + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_CORE_COORDINATE_PROMOTION_HPP diff --git a/include/boost/geometry/core/coordinate_type.hpp b/include/boost/geometry/core/coordinate_type.hpp index e4c391ec4..760b122ad 100644 --- a/include/boost/geometry/core/coordinate_type.hpp +++ b/include/boost/geometry/core/coordinate_type.hpp @@ -22,7 +22,6 @@ #include #include #include -#include #include @@ -94,15 +93,6 @@ struct coordinate_type >::type type; }; -template -struct fp_coordinate_type -{ - typedef typename promote_floating_point - < - typename coordinate_type::type - >::type type; -}; - /*! \brief assert_coordinate_type_equal, a compile-time check for equality of two coordinate types \ingroup utility diff --git a/include/boost/geometry/core/radian_access.hpp b/include/boost/geometry/core/radian_access.hpp index 993a6cc4c..c2f00552d 100644 --- a/include/boost/geometry/core/radian_access.hpp +++ b/include/boost/geometry/core/radian_access.hpp @@ -27,8 +27,7 @@ #include #include -#include - +#include #include diff --git a/include/boost/geometry/policies/robustness/get_rescale_policy.hpp b/include/boost/geometry/policies/robustness/get_rescale_policy.hpp index 66f949fe4..5e1dd5e4d 100644 --- a/include/boost/geometry/policies/robustness/get_rescale_policy.hpp +++ b/include/boost/geometry/policies/robustness/get_rescale_policy.hpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -37,7 +38,6 @@ #include #include #include -#include #include // TEMP diff --git a/include/boost/geometry/policies/robustness/segment_ratio.hpp b/include/boost/geometry/policies/robustness/segment_ratio.hpp index 07c74cc43..b1af50ffa 100644 --- a/include/boost/geometry/policies/robustness/segment_ratio.hpp +++ b/include/boost/geometry/policies/robustness/segment_ratio.hpp @@ -19,8 +19,8 @@ #include #include +#include #include -#include namespace boost { namespace geometry { diff --git a/include/boost/geometry/strategies/cartesian/azimuth.hpp b/include/boost/geometry/strategies/cartesian/azimuth.hpp index 74a9ea12b..9035fdddc 100644 --- a/include/boost/geometry/strategies/cartesian/azimuth.hpp +++ b/include/boost/geometry/strategies/cartesian/azimuth.hpp @@ -14,10 +14,10 @@ #include #include +#include #include -#include #include namespace boost { namespace geometry diff --git a/include/boost/geometry/strategies/geographic/distance.hpp b/include/boost/geometry/strategies/geographic/distance.hpp index 41e3cd7aa..3602a631a 100644 --- a/include/boost/geometry/strategies/geographic/distance.hpp +++ b/include/boost/geometry/strategies/geographic/distance.hpp @@ -17,6 +17,7 @@ #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP +#include #include #include #include @@ -32,7 +33,6 @@ #include #include -#include #include #include diff --git a/include/boost/geometry/strategies/geographic/distance_cross_track.hpp b/include/boost/geometry/strategies/geographic/distance_cross_track.hpp index e269703ef..a32d0429f 100644 --- a/include/boost/geometry/strategies/geographic/distance_cross_track.hpp +++ b/include/boost/geometry/strategies/geographic/distance_cross_track.hpp @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -37,7 +38,6 @@ #include #include -#include #include #include diff --git a/include/boost/geometry/strategies/geographic/distance_segment_box.hpp b/include/boost/geometry/strategies/geographic/distance_segment_box.hpp index 3b076b72d..552bfcdbe 100644 --- a/include/boost/geometry/strategies/geographic/distance_segment_box.hpp +++ b/include/boost/geometry/strategies/geographic/distance_segment_box.hpp @@ -13,6 +13,8 @@ #include +#include + #include #include @@ -26,7 +28,6 @@ #include #include -#include #include namespace boost { namespace geometry diff --git a/include/boost/geometry/strategies/geographic/mapping_ssf.hpp b/include/boost/geometry/strategies/geographic/mapping_ssf.hpp index 20a052361..57fd985a9 100644 --- a/include/boost/geometry/strategies/geographic/mapping_ssf.hpp +++ b/include/boost/geometry/strategies/geographic/mapping_ssf.hpp @@ -17,10 +17,10 @@ #include +#include #include #include -#include #include #include diff --git a/include/boost/geometry/strategies/geographic/side.hpp b/include/boost/geometry/strategies/geographic/side.hpp index f9a6b23ab..a0b4abc81 100644 --- a/include/boost/geometry/strategies/geographic/side.hpp +++ b/include/boost/geometry/strategies/geographic/side.hpp @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -32,7 +33,6 @@ #include #include -#include #include namespace boost { namespace geometry diff --git a/include/boost/geometry/strategies/spherical/distance_cross_track.hpp b/include/boost/geometry/strategies/spherical/distance_cross_track.hpp index f543a01c5..16bc70823 100644 --- a/include/boost/geometry/strategies/spherical/distance_cross_track.hpp +++ b/include/boost/geometry/strategies/spherical/distance_cross_track.hpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -36,7 +37,6 @@ #include #include -#include #include #ifdef BOOST_GEOMETRY_DEBUG_CROSS_TRACK diff --git a/include/boost/geometry/strategies/spherical/distance_haversine.hpp b/include/boost/geometry/strategies/spherical/distance_haversine.hpp index bd46a93c6..389277259 100644 --- a/include/boost/geometry/strategies/spherical/distance_haversine.hpp +++ b/include/boost/geometry/strategies/spherical/distance_haversine.hpp @@ -17,6 +17,7 @@ #include +#include #include #include @@ -26,7 +27,6 @@ #include #include -#include #include diff --git a/include/boost/geometry/strategies/spherical/point_in_point.hpp b/include/boost/geometry/strategies/spherical/point_in_point.hpp index f0857c9f6..dc25d0d59 100644 --- a/include/boost/geometry/strategies/spherical/point_in_point.hpp +++ b/include/boost/geometry/strategies/spherical/point_in_point.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/include/boost/geometry/strategies/spherical/side_by_cross_track.hpp b/include/boost/geometry/strategies/spherical/side_by_cross_track.hpp index b5cdb032b..d17de3077 100644 --- a/include/boost/geometry/strategies/spherical/side_by_cross_track.hpp +++ b/include/boost/geometry/strategies/spherical/side_by_cross_track.hpp @@ -16,6 +16,7 @@ #define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_SIDE_BY_CROSS_TRACK_HPP #include +#include #include #include @@ -26,7 +27,6 @@ #include #include -#include #include namespace boost { namespace geometry diff --git a/include/boost/geometry/strategies/spherical/ssf.hpp b/include/boost/geometry/strategies/spherical/ssf.hpp index d1e0e1352..2d29c400c 100644 --- a/include/boost/geometry/strategies/spherical/ssf.hpp +++ b/include/boost/geometry/strategies/spherical/ssf.hpp @@ -16,10 +16,10 @@ #include #include +#include #include #include -#include #include #include diff --git a/include/boost/geometry/strategies/strategy_transform.hpp b/include/boost/geometry/strategies/strategy_transform.hpp index fe94c14f8..ee2216ac7 100644 --- a/include/boost/geometry/strategies/strategy_transform.hpp +++ b/include/boost/geometry/strategies/strategy_transform.hpp @@ -30,10 +30,10 @@ #include #include #include +#include #include #include -#include #include namespace boost { namespace geometry diff --git a/include/boost/geometry/strategies/transform/matrix_transformers.hpp b/include/boost/geometry/strategies/transform/matrix_transformers.hpp index 36e60f3b6..70f11b889 100644 --- a/include/boost/geometry/strategies/transform/matrix_transformers.hpp +++ b/include/boost/geometry/strategies/transform/matrix_transformers.hpp @@ -33,9 +33,9 @@ #include #include +#include #include #include -#include #include #include diff --git a/include/boost/geometry/util/promote_floating_point.hpp b/include/boost/geometry/util/promote_floating_point.hpp index a005adee6..d38109116 100644 --- a/include/boost/geometry/util/promote_floating_point.hpp +++ b/include/boost/geometry/util/promote_floating_point.hpp @@ -18,35 +18,9 @@ #ifndef BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP #define BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP +#include +BOOST_HEADER_DEPRECATED("boost/geometry/core/coordinate_promotion.hpp") -#include - - -namespace boost { namespace geometry -{ - - -/*! - \brief Meta-function converting, if necessary, to "a floating point" type - \details - - if input type is integer, type is double - - else type is input type - \ingroup utility - */ - -template -struct promote_floating_point -{ - typedef std::conditional_t - < - std::is_integral::value, - PromoteIntegerTo, - T - > type; -}; - - -}} // namespace boost::geometry - +#include #endif // BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP From e99cfde120ba347800a1b2472cffed93729e3ad1 Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Wed, 8 Sep 2021 11:54:19 +0200 Subject: [PATCH 18/19] [intersection] use balance between distance-to-end and length-of-segments to determine to use a or b --- .../policies/robustness/segment_ratio.hpp | 64 +++++++------- .../strategies/cartesian/intersection.hpp | 85 +++++++++++++------ test/algorithms/buffer/buffer_linestring.cpp | 2 +- .../buffer/buffer_multi_polygon.cpp | 2 +- .../set_operations/difference/difference.cpp | 62 ++++++++------ .../difference/difference_areal_linear.cpp | 4 +- .../difference/difference_multi.cpp | 38 ++++++--- .../difference/difference_multi_spike.cpp | 40 +++------ .../difference/test_difference.hpp | 78 +++++++++++++---- .../sym_difference_areal_areal.cpp | 2 +- 10 files changed, 228 insertions(+), 149 deletions(-) diff --git a/include/boost/geometry/policies/robustness/segment_ratio.hpp b/include/boost/geometry/policies/robustness/segment_ratio.hpp index b1af50ffa..b4797f39c 100644 --- a/include/boost/geometry/policies/robustness/segment_ratio.hpp +++ b/include/boost/geometry/policies/robustness/segment_ratio.hpp @@ -135,11 +135,15 @@ struct possibly_collinear template class segment_ratio { -public : - typedef Type numeric_type; + // Type used for the approximation (a helper value) + // and for the edge value (0..1) (a helper function). + using floating_point_type = + typename detail::promoted_to_floating_point::type; // Type-alias for the type itself - typedef segment_ratio thistype; + using thistype = segment_ratio; + +public : inline segment_ratio() : m_numerator(0) @@ -221,8 +225,8 @@ public : m_approximation = m_denominator == 0 ? 0 : ( - boost::numeric_cast(m_numerator) * scale() - / boost::numeric_cast(m_denominator) + boost::numeric_cast(m_numerator) * scale() + / boost::numeric_cast(m_denominator) ); } @@ -254,21 +258,16 @@ public : return m_numerator > m_denominator; } - inline bool near_end() const + //! Returns a value between 0.0 and 1.0 + //! 0.0 means: exactly in the middle + //! 1.0 means: exactly on one of the edges (or even over it) + inline floating_point_type edge_value() const { - if (left() || right()) - { - return false; - } - - static fp_type const small_part_of_scale = scale() / 100; - return m_approximation < small_part_of_scale - || m_approximation > scale() - small_part_of_scale; - } - - inline bool close_to(thistype const& other) const - { - return geometry::math::abs(m_approximation - other.m_approximation) < 50; + using fp = floating_point_type; + fp const one{1.0}; + floating_point_type const result + = fp(2) * geometry::math::abs(fp(0.5) - m_approximation / scale()); + return result > one ? one : result; } template @@ -313,19 +312,7 @@ public : } #endif - - private : - // NOTE: if this typedef is used then fp_type is non-fundamental type - // if Type is non-fundamental type - //typedef typename promote_floating_point::type fp_type; - - // TODO: What with user-defined numeric types? - // Shouldn't here is_integral be checked? - typedef std::conditional_t - < - std::is_floating_point::value, Type, double - > fp_type; Type m_numerator; Type m_denominator; @@ -335,12 +322,19 @@ private : // Boost.Rational is used if the approximations are close. // Reason: performance, Boost.Rational does a GCD by default and also the // comparisons contain while-loops. - fp_type m_approximation; + floating_point_type m_approximation; - - static inline fp_type scale() + inline bool close_to(thistype const& other) const { - return 1000000.0; + static floating_point_type const threshold{50.0}; + return geometry::math::abs(m_approximation - other.m_approximation) + < threshold; + } + + static inline floating_point_type scale() + { + static floating_point_type const fp_scale{1000000.0}; + return fp_scale; } }; diff --git a/include/boost/geometry/strategies/cartesian/intersection.hpp b/include/boost/geometry/strategies/cartesian/intersection.hpp index be7b92e59..2d96b9bef 100644 --- a/include/boost/geometry/strategies/cartesian/intersection.hpp +++ b/include/boost/geometry/strategies/cartesian/intersection.hpp @@ -68,6 +68,61 @@ namespace boost { namespace geometry namespace strategy { namespace intersection { +namespace detail_usage +{ + +// When calculating the intersection, the information of "a" or "b" can be used. +// Theoretically this gives equal results, but due to floating point precision +// there might be tiny differences. These are edge cases. +// This structure is to determine if "a" or "b" should be used. +// Prefer the segment closer to the endpoint. +// If both are about equally close, then prefer the longer segment +// To avoid hard thresholds, behavior is made fluent. +// Calculate comparable length indications, +// the longer the segment (relatively), the lower the value +// such that the shorter lengths are evaluated higher and will +// be preferred. +template +struct use_a +{ + template + static bool apply(Ct const& cla, Ct const& clb, Ev const& eva, Ev const& evb) + { + auto const clm = (std::max)(cla, clb); + if (clm <= 0) + { + return true; + } + + // Relative comparible length + auto const rcla = Ct(1.0) - cla / clm; + auto const rclb = Ct(1.0) - clb / clm; + + // Multipliers for edgevalue (ev) and relative comparible length (rcl) + // They determine the balance between edge value (should be larger) + // and segment length. In 99.9xx% of the cases there is no difference + // at all (if either a or b is used). Therefore the values of the + // constants are not sensitive for the majority of the situations. + // One known case is #mysql_23023665_6 (difference) which needs mev >= 2 + Ev const mev = 5; + Ev const mrcl = 1; + + return mev * eva + mrcl * rcla > mev * evb + mrcl * rclb; + } +}; + +// Specialization for non arithmetic types. They will always use "a" +template <> +struct use_a +{ + template + static bool apply(Ct const& , Ct const& , Ev const& , Ev const& ) + { + return true; + } +}; + +} /*! \see http://mathworld.wolfram.com/Line-LineIntersection.html @@ -180,30 +235,12 @@ struct cartesian_segments template void calculate(Point& point, Segment1 const& a, Segment2 const& b) const { - bool use_a = true; - - // Prefer one segment if one is on or near an endpoint - bool const a_near_end = robust_ra.near_end(); - bool const b_near_end = robust_rb.near_end(); - if (a_near_end && ! b_near_end) - { - use_a = true; - } - else if (b_near_end && ! a_near_end) - { - use_a = false; - } - else - { - // Prefer shorter segment - promoted_type const len_a = comparable_length_a(); - promoted_type const len_b = comparable_length_b(); - if (len_b < len_a) - { - use_a = false; - } - // else use_a is true but was already assigned like that - } + bool const use_a + = detail_usage::use_a + < + std::is_arithmetic::value + >::apply(comparable_length_a(), comparable_length_b(), + robust_ra.edge_value(), robust_rb.edge_value()); if (use_a) { diff --git a/test/algorithms/buffer/buffer_linestring.cpp b/test/algorithms/buffer/buffer_linestring.cpp index b892ec30d..24c257438 100644 --- a/test/algorithms/buffer/buffer_linestring.cpp +++ b/test/algorithms/buffer/buffer_linestring.cpp @@ -430,7 +430,7 @@ int test_main(int, char* []) #endif #if defined(BOOST_GEOMETRY_TEST_FAILURES) - BoostGeometryWriteExpectedFailures(2, 4, 9, 4); + BoostGeometryWriteExpectedFailures(2, 4, 11, 3); #endif return 0; diff --git a/test/algorithms/buffer/buffer_multi_polygon.cpp b/test/algorithms/buffer/buffer_multi_polygon.cpp index 03ab006ae..d14ff436d 100644 --- a/test/algorithms/buffer/buffer_multi_polygon.cpp +++ b/test/algorithms/buffer/buffer_multi_polygon.cpp @@ -686,7 +686,7 @@ int test_main(int, char* []) #endif #if defined(BOOST_GEOMETRY_TEST_FAILURES) - BoostGeometryWriteExpectedFailures(5, 1, 3, 4); + BoostGeometryWriteExpectedFailures(3, 1, 3, 3); #endif return 0; diff --git a/test/algorithms/set_operations/difference/difference.cpp b/test/algorithms/set_operations/difference/difference.cpp index 403c79e83..910cf6df1 100644 --- a/test/algorithms/set_operations/difference/difference.cpp +++ b/test/algorithms/set_operations/difference/difference.cpp @@ -46,8 +46,6 @@ void test_all() { typedef bg::model::polygon

polygon; - typedef typename bg::coordinate_type

::type ct; - test_one("simplex_normal", simplex_normal[0], simplex_normal[1], 3, 12, 2.52636706856656, @@ -68,10 +66,15 @@ void test_all() 1, 5, 8.0, 1, 5, 8.0); - test_one("star_comb_15", - star_comb_15[0], star_comb_15[1], - 30, -1, 227.658275102812, - 30, -1, 480.485775259312); + { + ut_settings settings; + settings.validity_false_negative_sym = true; + test_one("star_comb_15", + star_comb_15[0], star_comb_15[1], + 30, -1, 227.658275102812, + 30, -1, 480.485775259312, + settings); + } test_one("new_hole", new_hole[0], new_hole[1], @@ -106,7 +109,7 @@ void test_all() { ut_settings settings; - settings.sym_difference_validity = BG_IF_RESCALED(true, false); + settings.validity_false_negative_sym = true; test_one("only_hole_intersections1", only_hole_intersections[0], only_hole_intersections[1], @@ -114,7 +117,7 @@ void test_all() 4, 16, 10.9090909, settings); - test_one("only_hole_intersection2", + test_one("only_hole_intersections2", only_hole_intersections[0], only_hole_intersections[2], 3, 20, 30.9090909, 4, 16, 10.9090909, @@ -144,7 +147,7 @@ void test_all() { ut_settings settings; - settings.sym_difference_validity = BG_IF_RESCALED(false, true); + settings.validity_of_sym = BG_IF_RESCALED(false, true); test_one("intersect_holes_intersect_and_disjoint", intersect_holes_intersect_and_disjoint[0], intersect_holes_intersect_and_disjoint[1], 2, 16, 15.75, @@ -180,7 +183,6 @@ void test_all() { ut_settings settings; - settings.sym_difference_validity = BG_IF_RESCALED(false, true); test_one("intersect_holes_intersect", intersect_holes_intersect[0], intersect_holes_intersect[1], 2, 16, 15.75, @@ -295,10 +297,9 @@ void test_all() 1, 61, 10.2717, 1, 61, 10.2717); - if ( BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { ut_settings settings; - settings.sym_difference_validity = BG_IF_RESCALED(true, false); + settings.validity_false_negative_sym = true; TEST_DIFFERENCE_WITH(buffer_mp2, 1, 12.09857, 1, 24.19714, count_set(1, 2), settings); } @@ -319,7 +320,7 @@ void test_all() ut_settings settings; settings.percentage = BG_IF_RESCALED(0.001, 0.1); settings.set_test_validity(BG_IF_RESCALED(true, false)); - settings.sym_difference = BG_IF_RESCALED(true, false); + settings.sym_difference = false; // Isovist - the # output polygons differ per compiler/pointtype, (very) small // rings might be discarded. We check area only @@ -330,18 +331,24 @@ void test_all() test_one("isovist", isovist1[0], isovist1[1], - ignore_count(), -1, 0.279132, + ignore_count(), -1, expectation_limits(0.279128, 0.279132), ignore_count(), -1, 224.8892, settings); } #if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) - // SQL Server gives: 0.28937764436705 and 0.000786406897532288 with 44/35 rings - // PostGIS gives: 0.30859375 and 0.033203125 with 35/35 rings - TEST_DIFFERENCE_WITH(geos_1, - ignore_count(), expectation_limits(0.20705, 0.29172), - ignore_count(), expectation_limits(0.00060440758, 0.00076856), - ignore_count(), ut_settings(0.1, false)); + { + ut_settings settings(0.1); + settings.set_test_validity(BG_IF_RESCALED(false, true)); + settings.validity_false_negative_sym = BG_IF_RESCALED(true, false); + + // SQL Server gives: 0.28937764436705 and 0.000786406897532288 with 44/35 rings + // PostGIS gives: 0.30859375 and 0.033203125 with 35/35 rings + TEST_DIFFERENCE_WITH(geos_1, + ignore_count(), expectation_limits(0.20705, 0.29172), + ignore_count(), expectation_limits(0.00060440758, 0.00076856), + ignore_count(), settings); + } #endif { @@ -425,7 +432,7 @@ void test_all() // With rescaling, difference of output a-b and a sym b is invalid ut_settings settings; settings.set_test_validity(BG_IF_RESCALED(false, true)); - settings.sym_difference_validity = BG_IF_RESCALED(false, true); + settings.validity_of_sym = BG_IF_RESCALED(false, true); TEST_DIFFERENCE_WITH(ggl_list_20190307_matthieu_1, count_set(1, 2), 0.18461532, count_set(1, 2), 0.617978, @@ -563,6 +570,7 @@ void test_all() { ut_settings settings; settings.set_test_validity(BG_IF_RESCALED(true, false)); + settings.validity_false_negative_a = true; TEST_DIFFERENCE_WITH(issue_838, count_set(1, 2), expectation_limits(0.000026, 0.0002823), count_set(1, 2), expectation_limits(0.67257, 0.67499), @@ -583,12 +591,16 @@ void test_all() TEST_DIFFERENCE(mysql_23023665_3, 1, 225.0, 1, 66.0, 2); TEST_DIFFERENCE(mysql_23023665_5, 2, 165.23735, 2, 105.73735, 4); { - // Without recaling it is invalid + // Without rescaling it is invalid ut_settings settings; - settings.set_test_validity(BG_IF_RESCALED(true, false)); + settings.set_test_validity(true); TEST_DIFFERENCE_WITH(mysql_23023665_6, 2, 105.68756, 3, 10.18756, 5, settings); } - TEST_DIFFERENCE(mysql_23023665_13, 3, 99.74526, 3, 37.74526, 6); + { + ut_settings settings; + settings.validity_false_negative_sym = true; + TEST_DIFFERENCE_WITH(mysql_23023665_13, 3, 99.74526, 3, 37.74526, 6, settings); + } } @@ -633,7 +645,7 @@ int test_main(int, char* []) // Not yet fully tested for float and long double. // The difference algorithm can generate (additional) slivers // Many of the failures are self-intersection points. - BoostGeometryWriteExpectedFailures(19, 10, 17, 12); + BoostGeometryWriteExpectedFailures(15, 5, 17, 10); #endif return 0; diff --git a/test/algorithms/set_operations/difference/difference_areal_linear.cpp b/test/algorithms/set_operations/difference/difference_areal_linear.cpp index 046b8c800..6fa40fd7d 100644 --- a/test/algorithms/set_operations/difference/difference_areal_linear.cpp +++ b/test/algorithms/set_operations/difference/difference_areal_linear.cpp @@ -240,8 +240,8 @@ int test_main(int, char* []) test_all >(); test_ticket_10835 - ("MULTILINESTRING((5239 2113,5233 2114),(4794 2205,1020 2986))", - "MULTILINESTRING((5239 2113,5233 2114),(4794 2205,1460 2895))"); + ("MULTILINESTRING((5239 2113,5232 2115),(4794 2205,1020 2986))", + "MULTILINESTRING((5239 2113,5232 2115),(4794 2205,1460 2895))"); test_ticket_10835 ("MULTILINESTRING((5239 2113,5232.52 2114.34),(4794.39 2205,1020 2986))", diff --git a/test/algorithms/set_operations/difference/difference_multi.cpp b/test/algorithms/set_operations/difference/difference_multi.cpp index 7d7cad485..2d1a9fcc6 100644 --- a/test/algorithms/set_operations/difference/difference_multi.cpp +++ b/test/algorithms/set_operations/difference/difference_multi.cpp @@ -155,10 +155,12 @@ void test_areal() #if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) { // 1: Very small sliver for B (discarded when rescaling) - // 2: sym difference is not considered as valid + // 2: sym difference is not considered as valid (without rescaling + // this is a false negative) // 3: with rescaling A is considered as invalid (robustness problem) ut_settings settings; - settings.sym_difference_validity = false; + settings.validity_of_sym = BG_IF_RESCALED(false, true); + settings.validity_false_negative_sym = true; TEST_DIFFERENCE_WITH(0, 1, bug_21155501, (count_set(1, 4)), expectation_limits(3.75893, 3.75894), (count_set(1, 4)), (expectation_limits(1.776357e-15, 7.661281e-15)), @@ -172,7 +174,7 @@ void test_areal() // Without rescaling, one ring is missing (for a and s) ut_settings settings; settings.set_test_validity(BG_IF_RESCALED(false, true)); - settings.sym_difference_validity = BG_IF_RESCALED(false, true); + settings.validity_of_sym = BG_IF_RESCALED(false, true); TEST_DIFFERENCE_WITH(0, 1, ticket_9081, 2, 0.0907392476356186, 4, 0.126018011439877, @@ -211,9 +213,12 @@ void test_areal() TEST_DIFFERENCE(issue_888_34, 22, 0.2506824, 6, 0.0253798, 28); // a went wrong TEST_DIFFERENCE(issue_888_37, 15, 0.0451408, 65, 0.3014843, 80); // b went wrong -#if defined(BOOST_GEOMETRY_TEST_FAILURES) - TEST_DIFFERENCE(issue_888_53, 117, 0.2973268, 17, 0.0525798, 134); // a goes wrong -#endif + { + ut_settings settings; + settings.validity_false_negative_a = true; + settings.validity_false_negative_sym = true; + TEST_DIFFERENCE_WITH(0, 1, issue_888_53, 117, 0.2973268, 17, 0.0525798, 134); + } // Areas and #clips correspond with POSTGIS (except sym case) test_one("case_101_multi", @@ -472,24 +477,29 @@ void test_specific_areal() { const std::string a_min_b = - TEST_DIFFERENCE(ticket_10661, 2, 1441632.5, 2, 13167454, 4); + test_one("ticket_10661", + ticket_10661[0], ticket_10661[1], + 2, -1, expectation_limits(1441632, 1441855), + 2, -1, expectation_limits(13167454, 13182415), + count_set(3, 4)); test_one("ticket_10661_2", a_min_b, ticket_10661[2], 1, 8, 825192.0, - 1, 10, expectation_limits(27226370, 27842812), - 1, -1, 825192.0 + 27226370.5); + 1, 10, expectation_limits(27226148, 27842812), + count_set(1, 2)); } { ut_settings settings; settings.sym_difference = false; - TEST_DIFFERENCE_WITH(0, 1, ticket_9942, 4, expectation_limits(7427727.5), 4, - expectation_limits(130083, 131507), 4); + TEST_DIFFERENCE_WITH(0, 1, ticket_9942, 4, + expectation_limits(7427727, 7428108), 4, + expectation_limits(130083, 131823), 4); TEST_DIFFERENCE_WITH(0, 1, ticket_9942a, 2, - expectation_limits(412676, 413184), 2, - expectation_limits(76779, 76925), 4); + expectation_limits(412676, 413469), 2, + expectation_limits(76779, 77038), 4); } } @@ -516,7 +526,7 @@ int test_main(int, char* []) #if defined(BOOST_GEOMETRY_TEST_FAILURES) // Not yet fully tested for float. // The difference algorithm can generate (additional) slivers - BoostGeometryWriteExpectedFailures(28, 15, 19, 10); + BoostGeometryWriteExpectedFailures(24, 11, 21, 7); #endif return 0; diff --git a/test/algorithms/set_operations/difference/difference_multi_spike.cpp b/test/algorithms/set_operations/difference/difference_multi_spike.cpp index a8c711e3c..0a9308d3a 100644 --- a/test/algorithms/set_operations/difference/difference_multi_spike.cpp +++ b/test/algorithms/set_operations/difference/difference_multi_spike.cpp @@ -20,6 +20,7 @@ void test_spikes_in_ticket_8364() { ut_settings ignore_validity; ignore_validity.set_test_validity(false); + ignore_validity.validity_of_sym = false; // See: https://svn.boost.org/trac/boost/ticket/8364 //_TPolygon polygon( "MULTIPOLYGON(((1031 1056,3232 1056,3232 2856,1031 2856)))" ); @@ -30,44 +31,27 @@ void test_spikes_in_ticket_8364() //polygon -= _TPolygon( "MULTIPOLYGON(((1032 2556,1032 2130,1778 2556)),((3234 2580,2136 2760,1778 2556,3234 2556)))" ); USED IN STEP 4 // NOTE: polygons below are closed and clockwise - typedef typename bg::coordinate_type

::type ct; typedef bg::model::polygon polygon; typedef bg::model::multi_polygon multi_polygon; // The difference of polygons below result in a spike. The spike should be there, it was also generated in ttmath, // and (e.g.) in SQL Server. However, using int-coordinates, the spike makes the polygon invalid. Therefore it is now (since August 2013) checked and removed. -#ifdef BOOST_GEOMETRY_TEST_FAILURES - // TODO: commented working at ii/validity, this changes the area slightly, to be checked // So using int's, the spike is removed automatically. Therefore there is one polygon less, and less points. Also area differs test_one("ticket_8364_step3", "MULTIPOLYGON(((3232 2532,2136 2790,1032 1764,1032 1458,1032 1212,2136 2328,3232 2220,3232 1056,1031 1056,1031 2856,3232 2856,3232 2532)))", "MULTIPOLYGON(((1032 2130,2052 2712,1032 1764,1032 2130)),((3234 2580,3234 2532,2558 2690,3234 2580)),((2558 2690,2136 2760,2052 2712,2136 2790,2558 2690)))", - 2, - if_typed(19, 22), - if_typed(2775595.5, 2775256.487954), // SQL Server: 2775256.47588724 - 3, - -1, // don't check point-count - if_typed(7893.0, 7810.487954), // SQL Server: 7810.48711165739 - if_typed(1, 5), - -1, - if_typed(2783349.5, 2775256.487954 + 7810.487954), - ignore_validity); -#endif + count_set(2, 3), -1, expectation_limits(2775256, 2775610), // SQL Server: 2775256.47588724 + 3, -1, expectation_limits(7810, 7893), // SQL Server: 7810.48711165739 + count_set(2, 6), ignore_validity); // TODO: behaviour is not good yet. It is changed at introduction of self-turns. test_one("ticket_8364_step4", "MULTIPOLYGON(((2567 2688,2136 2790,2052 2712,1032 2130,1032 1764,1032 1458,1032 1212,2136 2328,3232 2220,3232 1056,1031 1056,1031 2856,3232 2856,3232 2580,2567 2688)))", "MULTIPOLYGON(((1032 2556,1778 2556,1032 2130,1032 2556)),((3234 2580,3234 2556,1778 2556,2136 2760,3234 2580)))", - if_typed(1, 2), - if_typed(17, 20), - if_typed(2615783.5, 2616029.559567), // SQL Server: 2616029.55616044 - 1, - if_typed(9, 11), - if_typed(161133.5, 161054.559567), // SQL Server: 161054.560110092 - if_typed(1, 3), - if_typed(25, 31), - if_typed(2776875.5, 2616029.559567 + 161054.559567)); + count_set(1, 2), -1, expectation_limits(2615783, 2616030), // SQL Server: 2616029.55616044 + 1, -1, expectation_limits(161054, 161134), // SQL Server: 161054.560110092 + count_set(1, 3)); } template @@ -76,7 +60,6 @@ void test_spikes_in_ticket_8365() // See: https://svn.boost.org/trac/boost/ticket/8365 // NOTE: polygons below are closed and clockwise - typedef typename bg::coordinate_type

::type ct; typedef bg::model::polygon polygon; typedef bg::model::multi_polygon multi_polygon; @@ -85,13 +68,11 @@ void test_spikes_in_ticket_8365() "MULTIPOLYGON(((5388 1560,4650 1722,3912 1884,4650 1398)),((2442 3186,1704 3348,966 2700,1704 3024)))", 2, 18, - if_typed(7975092.5, 7975207.6047877), // SQL Server: + expectation_limits(7975092.5, 7975207.6047877), 2, -1, - if_typed(196.5, 197.1047877), // SQL Server: - if_typed(3, 4), - -1, - if_typed(7975092.5 + 196.5, 7975207.6047877 + 197.1047877)); + expectation_limits(196.5, 198.5), + count_set(2, 4)); } @@ -109,6 +90,7 @@ int test_main(int, char* []) test_spikes_in_ticket_8364, false, false>(); test_spikes_in_ticket_8365, true, true >(); test_spikes_in_ticket_8365, false, false >(); + return 0; } diff --git a/test/algorithms/set_operations/difference/test_difference.hpp b/test/algorithms/set_operations/difference/test_difference.hpp index 2dfc542a2..3ec8dfa24 100644 --- a/test/algorithms/set_operations/difference/test_difference.hpp +++ b/test/algorithms/set_operations/difference/test_difference.hpp @@ -59,20 +59,45 @@ # include #endif +enum difference_type +{ + difference_a, difference_b, difference_sym +}; struct ut_settings : ut_base_settings { double percentage; bool sym_difference; - bool sym_difference_validity = true; + bool validity_of_sym = true; bool remove_spikes = false; + // The validity check gives sometimes false negatives. + // boost::geometry::is_valid can return FALSE while it is valid. + // (especially at touch in combination with a u/u turn) + // For now, the cases where this is the case are skipped for validity check. + bool validity_false_negative_a = false; + bool validity_false_negative_b = false; + bool validity_false_negative_sym = false; + explicit ut_settings(double p = 0.0001, bool validity = true, bool sd = true) : ut_base_settings(validity) , percentage(p) , sym_difference(sd) {} + bool test_validity_of_diff(difference_type dtype) const + { + bool const sym = dtype == difference_sym; + bool const a = dtype == difference_a; + bool const b = dtype == difference_b; + + return sym && validity_false_negative_sym ? false + : a && validity_false_negative_a ? false + : b && validity_false_negative_b ? false + : sym ? (validity_of_sym || BG_IF_TEST_FAILURES) + : test_validity(); + } + }; inline ut_settings tolerance(double percentage) @@ -137,7 +162,7 @@ std::string test_difference(std::string const& caseid, G1 const& g1, G2 const& g const count_set& expected_count, int expected_rings_count, int expected_point_count, expectation_limits const& expected_area, - bool sym, + difference_type dtype, ut_settings const& settings) { typedef typename bg::coordinate_type::type coordinate_type; @@ -145,8 +170,7 @@ std::string test_difference(std::string const& caseid, G1 const& g1, G2 const& g bg::model::multi_polygon result; - - if (sym) + if (dtype == difference_sym) { bg::sym_difference(g1, g2, result); } @@ -167,7 +191,7 @@ std::string test_difference(std::string const& caseid, G1 const& g1, G2 const& g < G1, G2 >::type strategy_type; - if (sym) + if (dtype == difference_sym) { bg::sym_difference(g1, g2, result_s, strategy_type()); } @@ -191,12 +215,7 @@ std::string test_difference(std::string const& caseid, G1 const& g1, G2 const& g typename bg::default_area_result::type const area = bg::area(result); #if ! defined(BOOST_GEOMETRY_NO_BOOST_TEST) - bool const test_validity - = sym - ? (settings.sym_difference_validity || BG_IF_TEST_FAILURES) - : settings.test_validity(); - - if (test_validity) + if (settings.test_validity_of_diff(dtype)) { // std::cout << bg::dsv(result) << std::endl; typedef bg::model::multi_polygon result_type; @@ -218,7 +237,7 @@ std::string test_difference(std::string const& caseid, G1 const& g1, G2 const& g typename setop_output_type::type inserted, array_with_one_empty_geometry; array_with_one_empty_geometry.push_back(OutputType()); - if (sym) + if (dtype == difference_sym) { boost::copy(array_with_one_empty_geometry, bg::detail::sym_difference::sym_difference_insert @@ -287,12 +306,12 @@ template std::string test_difference(std::string const& caseid, G1 const& g1, G2 const& g2, const count_set& expected_count, int expected_point_count, expectation_limits const& expected_area, - bool sym, + difference_type dtype, ut_settings const& settings) { return test_difference(caseid, g1, g2, expected_count, -1, expected_point_count, expected_area, - sym, settings); + dtype, settings); } #ifdef BOOST_GEOMETRY_CHECK_WITH_POSTGIS @@ -331,7 +350,7 @@ std::string test_one(std::string const& caseid, #if ! defined(BOOST_GEOMETRY_TEST_DIFFERENCE_ONLY_B) result = test_difference(caseid + "_a", g1, g2, expected_count1, expected_rings_count1, expected_point_count1, - expected_area1, false, settings); + expected_area1, difference_a, settings); #endif #if defined(BOOST_GEOMETRY_TEST_DIFFERENCE_ONLY_A) return result; @@ -339,7 +358,7 @@ std::string test_one(std::string const& caseid, test_difference(caseid + "_b", g2, g1, expected_count2, expected_rings_count2, expected_point_count2, - expected_area2, false, settings); + expected_area2, difference_b, settings); #if defined(BOOST_GEOMETRY_TEST_DIFFERENCE_ONLY_B) return result; @@ -354,7 +373,7 @@ std::string test_one(std::string const& caseid, expected_rings_count_s, expected_point_count_s, expected_area_s, - true, settings); + difference_sym, settings); } return result; } @@ -383,6 +402,7 @@ std::string test_one(std::string const& caseid, settings); } +// Version with expectations of symmetric: all specified template std::string test_one(std::string const& caseid, std::string const& wkt1, std::string const& wkt2, @@ -404,6 +424,30 @@ std::string test_one(std::string const& caseid, settings); } +// Version with expectations of symmetric: specify only count +template +std::string test_one(std::string const& caseid, + std::string const& wkt1, std::string const& wkt2, + const count_set& expected_count1, + int expected_point_count1, + expectation_limits const& expected_area1, + const count_set& expected_count2, + int expected_point_count2, + expectation_limits const& expected_area2, + const count_set& expected_count_s, + ut_settings const& settings = ut_settings()) +{ + return test_one(caseid, wkt1, wkt2, + expected_count1, -1, expected_point_count1, expected_area1, + expected_count2, -1, expected_point_count2, expected_area2, + expected_count_s, -1, + expected_point_count1 >= 0 && expected_point_count2 >= 0 + ? (expected_point_count1 + expected_point_count2) : -1, + expected_area1 + expected_area2, + settings); +} + +// Version with expectations of symmetric: all automatically template std::string test_one(std::string const& caseid, std::string const& wkt1, std::string const& wkt2, diff --git a/test/algorithms/set_operations/sym_difference/sym_difference_areal_areal.cpp b/test/algorithms/set_operations/sym_difference/sym_difference_areal_areal.cpp index b0b386c1f..c6107f360 100644 --- a/test/algorithms/set_operations/sym_difference/sym_difference_areal_areal.cpp +++ b/test/algorithms/set_operations/sym_difference/sym_difference_areal_areal.cpp @@ -75,7 +75,7 @@ struct test_sym_difference_of_areal_geometries PolygonOut >(case_id, areal1, areal2, expected_polygon_count, expected_point_count, expected_area, - true, settings); + difference_sym, settings); } }; From 716c7913657f8d4d6cac7cdc60dfc98e8b6d8b1f Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Wed, 8 Sep 2021 14:39:49 +0200 Subject: [PATCH 19/19] [test] enhance/fix robustness tests --- .../general_intersection_precision.cpp | 86 +++++++++------ .../areal_areal/interior_triangles.cpp | 10 +- .../overlay/areal_areal/intersection_pies.cpp | 8 +- .../areal_areal/intersection_stars.cpp | 16 ++- .../overlay/areal_areal/intersects.cpp | 19 +++- .../areal_areal/random_ellipses_stars.cpp | 14 ++- .../areal_areal/recursive_polygons.cpp | 9 +- .../overlay/areal_areal/star_comb.cpp | 9 +- .../overlay/areal_areal/test_overlay_p_q.hpp | 103 ++++++++++-------- .../buffer/recursive_polygons_buffer.cpp | 4 +- 10 files changed, 177 insertions(+), 101 deletions(-) diff --git a/test/robustness/overlay/areal_areal/general_intersection_precision.cpp b/test/robustness/overlay/areal_areal/general_intersection_precision.cpp index afd1bdbac..dc7527ae9 100644 --- a/test/robustness/overlay/areal_areal/general_intersection_precision.cpp +++ b/test/robustness/overlay/areal_areal/general_intersection_precision.cpp @@ -1,7 +1,7 @@ // Boost.Geometry // Robustness Test -// Copyright (c) 2019 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2019-2021 Barend Gehrels, Amsterdam, the Netherlands. // This file was modified by Oracle on 2021. // Modifications copyright (c) 2021, Oracle and/or its affiliates. @@ -11,6 +11,8 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#define BOOST_GEOMETRY_NO_ROBUSTNESS + #include #include #include @@ -42,11 +44,22 @@ static std::string case_c[2] = "MULTIPOLYGON(((1 1,0 1,0 3,1 3,1 1)))" }; +struct test_settings +{ + bool verbose{false}; + bool do_output{false}; + + // Settings currently not modifiable, and still giving quite some errors + double start_bound{1.0e-2}; + double step_factor{50.0}; // on each side -> 100 steps per factor + int max_factor{10000}; +}; + template bool test_overlay(std::string const& caseid, Geometry const& g1, Geometry const& g2, double expected_area, - bool do_output) + test_settings const& settings) { typedef typename boost::range_value::type geometry_out; @@ -62,9 +75,9 @@ bool test_overlay(std::string const& caseid, OverlayType > overlay; - typedef typename bg::strategy::intersection::services::default_strategy + typedef typename bg::strategies::relate::services::default_strategy < - typename bg::cs_tag::type + Geometry, Geometry >::type strategy_type; strategy_type strategy; @@ -86,7 +99,7 @@ bool test_overlay(std::string const& caseid, const double detected_area = bg::area(result); if (std::fabs(detected_area - expected_area) > 0.01) { - if (do_output) + if (settings.do_output) { std::cout << "ERROR: " << caseid << std::setprecision(18) << " detected=" << detected_area @@ -118,9 +131,9 @@ template std::size_t test_case(std::size_t& error_count, std::size_t case_index, std::size_t i, std::size_t j, std::size_t min_vertex_index, std::size_t max_vertex_index, - double x, double y, double expectation, + double offset_x, double offset_y, double expectation, MultiPolygon const& poly1, MultiPolygon const& poly2, - bool do_output) + test_settings const settings) { std::size_t n = 0; for (std::size_t k = min_vertex_index; k <= max_vertex_index; k++, ++n) @@ -130,21 +143,23 @@ std::size_t test_case(std::size_t& error_count, switch (case_index) { case 2 : - update(bg::interior_rings(poly2_adapted.front()).front(), x, y, k); + update(bg::interior_rings(poly2_adapted.front()).front(), offset_x, offset_y, k); break; default : - update(bg::exterior_ring(poly2_adapted.front()), x, y, k); + update(bg::exterior_ring(poly2_adapted.front()), offset_x, offset_y, k); break; } std::ostringstream out; out << "case_" << i << "_" << j << "_" << k; - if (! test_overlay(out.str(), poly1, poly2_adapted, expectation, do_output)) + if (! test_overlay(out.str(), poly1, poly2_adapted, expectation, settings)) { - if (error_count == 0) + if (error_count == 0 && ! settings.do_output) { // First failure is always reported - test_overlay(out.str(), poly1, poly2_adapted, expectation, true); + test_settings adapted = settings; + adapted.do_output = true; + test_overlay(out.str(), poly1, poly2_adapted, expectation, adapted); } error_count++; } @@ -155,7 +170,7 @@ std::size_t test_case(std::size_t& error_count, template std::size_t test_all(std::size_t case_index, std::size_t min_vertex_index, std::size_t max_vertex_index, - double expectation, bool do_output) + double expectation, test_settings const& settings) { typedef bg::model::point point_type; typedef bg::model::polygon polygon; @@ -177,21 +192,25 @@ std::size_t test_all(std::size_t case_index, std::size_t min_vertex_index, std::size_t error_count = 0; std::size_t n = 0; - for (double factor = 1.0; factor > 1.0e-10; factor /= 10.0) + for (int factor = 1; factor < settings.max_factor; factor *= 2) { std::size_t i = 0; - double const bound = 1.0e-5 * factor; - double const step = 1.0e-6 * factor; - for (double x = -bound; x <= bound; x += step, ++i) + double const bound = settings.start_bound / factor; + double const step = bound / settings.step_factor; + if (settings.verbose) + { + std::cout << "--> use " << bound << " " << step << std::endl; + } + for (double offset_x = -bound; offset_x <= bound; offset_x += step, ++i) { std::size_t j = 0; - for (double y = -bound; y <= bound; y += step, ++j, ++n) + for (double offset_y = -bound; offset_y <= bound; offset_y += step, ++j, ++n) { n += test_case(error_count, case_index, i, j, - min_vertex_index, max_vertex_index, - x, y, expectation, - poly1, poly2, do_output); + min_vertex_index, max_vertex_index, + offset_x, offset_y, expectation, + poly1, poly2, settings); } } } @@ -205,22 +224,17 @@ std::size_t test_all(std::size_t case_index, std::size_t min_vertex_index, int test_main(int argc, char** argv) { - typedef double coordinate_type; + BoostGeometryWriteTestConfiguration(); + using coor_t = default_test_type; - const double factor = argc > 1 ? atof(argv[1]) : 2.0; - const bool do_output = argc > 2 && atol(argv[2]) == 1; + test_settings settings; + settings.do_output = argc > 2 && atol(argv[2]) == 1; - std::cout << std::endl << " -> TESTING " - << string_from_type::name() - << " " << factor - << std::endl; - - test_all(1, 0, 3, 22.0, do_output); - test_all(2, 0, 3, 73.0, do_output); - test_all(3, 1, 2, 2.0, do_output); - test_all(3, 1, 2, 14.0, do_output); + // Test three polygons, for the last test two types of intersections + test_all(1, 0, 3, 22.0, settings); + test_all(2, 0, 3, 73.0, settings); + test_all(3, 1, 2, 2.0, settings); + test_all(3, 1, 2, 14.0, settings); return 0; - } - - +} diff --git a/test/robustness/overlay/areal_areal/interior_triangles.cpp b/test/robustness/overlay/areal_areal/interior_triangles.cpp index f8f52f44a..95275e9fe 100644 --- a/test/robustness/overlay/areal_areal/interior_triangles.cpp +++ b/test/robustness/overlay/areal_areal/interior_triangles.cpp @@ -1,13 +1,17 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Robustness Test -// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2009-2021 Barend Gehrels, Amsterdam, the Netherlands. // 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) #define BOOST_GEOMETRY_NO_BOOST_TEST +#define BOOST_GEOMETRY_NO_ROBUSTNESS +#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE + +// NOTE: there is no randomness here. Count is to measure performance #include @@ -113,8 +117,10 @@ int main(int argc, char** argv) ("count_y", po::value(&count_y)->default_value(10), "Triangle count in y-direction") ("offset", po::value(&offset)->default_value(0), "Offset of second triangle in x-direction") ("diff", po::value(&settings.also_difference)->default_value(false), "Include testing on difference") +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) ("ccw", po::value(&ccw)->default_value(false), "Counter clockwise polygons") ("open", po::value(&open)->default_value(false), "Open polygons") +#endif ("wkt", po::value(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests") ("svg", po::value(&settings.svg)->default_value(false), "Create a SVG for all tests") ; @@ -129,6 +135,7 @@ int main(int argc, char** argv) return 1; } +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) if (ccw && open) { test_all(count, count_x, count_y, offset, settings); @@ -142,6 +149,7 @@ int main(int argc, char** argv) test_all(count, count_x, count_y, offset, settings); } else +#endif { test_all(count, count_x, count_y, offset, settings); } diff --git a/test/robustness/overlay/areal_areal/intersection_pies.cpp b/test/robustness/overlay/areal_areal/intersection_pies.cpp index 2312d4cb2..e38e90d76 100644 --- a/test/robustness/overlay/areal_areal/intersection_pies.cpp +++ b/test/robustness/overlay/areal_areal/intersection_pies.cpp @@ -1,13 +1,15 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Robustness Test -// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2009-2021 Barend Gehrels, Amsterdam, the Netherlands. // 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) #define BOOST_GEOMETRY_NO_BOOST_TEST +#define BOOST_GEOMETRY_NO_ROBUSTNESS +#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE #include @@ -256,8 +258,10 @@ int main(int argc, char** argv) ("help", "Help message") ("multi", po::value(&multi)->default_value(false), "Multiple tangencies at one point") ("diff", po::value(&settings.also_difference)->default_value(false), "Include testing on difference") +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) ("ccw", po::value(&ccw)->default_value(false), "Counter clockwise polygons") ("open", po::value(&open)->default_value(false), "Open polygons") +#endif ("wkt", po::value(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests") ("svg", po::value(&settings.svg)->default_value(false), "Create a SVG for all tests") ; @@ -273,6 +277,7 @@ int main(int argc, char** argv) } // template par's are: CoordinateType, Clockwise, Closed +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) if (ccw && open) { test_all(multi, single_selftangent, settings); @@ -286,6 +291,7 @@ int main(int argc, char** argv) test_all(multi, single_selftangent, settings); } else +#endif { test_all(multi, single_selftangent, settings); } diff --git a/test/robustness/overlay/areal_areal/intersection_stars.cpp b/test/robustness/overlay/areal_areal/intersection_stars.cpp index 368857f44..6a8ed8ed1 100644 --- a/test/robustness/overlay/areal_areal/intersection_stars.cpp +++ b/test/robustness/overlay/areal_areal/intersection_stars.cpp @@ -1,13 +1,17 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Robustness Test -// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2009-2021 Barend Gehrels, Amsterdam, the Netherlands. // 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) #define BOOST_GEOMETRY_NO_BOOST_TEST +#define BOOST_GEOMETRY_NO_ROBUSTNESS +#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE + +// NOTE: there is no randomness here. Count is to measure performance #include @@ -109,12 +113,14 @@ void test_type(int count, int min_points, int max_points, T rotation, p_q_settin template void test_all(std::string const& type, int count, int min_points, int max_points, T rotation, p_q_settings settings) { +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) if (type == "float") { settings.tolerance = 1.0e-3; test_type(count, min_points, max_points, rotation, settings); } else if (type == "double") +#endif { test_type(count, min_points, max_points, rotation, settings); } @@ -130,7 +136,7 @@ int main(int argc, char** argv) int count = 1; //int seed = static_cast(std::time(0)); - std::string type = "float"; + std::string type = "double"; int min_points = 9; int max_points = 9; bool ccw = false; @@ -140,15 +146,17 @@ int main(int argc, char** argv) description.add_options() ("help", "Help message") - //("seed", po::value(&seed), "Initialization seed for random generator") + // ("seed", po::value(&seed), "Initialization seed for random generator") ("count", po::value(&count)->default_value(1), "Number of tests") ("diff", po::value(&settings.also_difference)->default_value(false), "Include testing on difference") ("min_points", po::value(&min_points)->default_value(9), "Minimum number of points") ("max_points", po::value(&max_points)->default_value(9), "Maximum number of points") ("rotation", po::value(&rotation)->default_value(1.0e-13), "Rotation angle") +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) ("ccw", po::value(&ccw)->default_value(false), "Counter clockwise polygons") ("open", po::value(&open)->default_value(false), "Open polygons") - ("type", po::value(&type)->default_value("float"), "Type (float,double)") + ("type", po::value(&type)->default_value("double"), "Type (float,double)") +#endif ("wkt", po::value(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests") ("svg", po::value(&settings.svg)->default_value(false), "Create a SVG for all tests") ; diff --git a/test/robustness/overlay/areal_areal/intersects.cpp b/test/robustness/overlay/areal_areal/intersects.cpp index 8f9031317..21ab6a265 100644 --- a/test/robustness/overlay/areal_areal/intersects.cpp +++ b/test/robustness/overlay/areal_areal/intersects.cpp @@ -1,13 +1,17 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Robustness Test -// Copyright (c) 2011-2020 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2011-2021 Barend Gehrels, Amsterdam, the Netherlands. // 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) #define BOOST_GEOMETRY_NO_BOOST_TEST +#define BOOST_GEOMETRY_NO_ROBUSTNESS +#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE + +// NOTE: there is no randomness here. Count is to measure performance #include @@ -43,9 +47,8 @@ inline void make_polygon(MultiPolygon& mp, int count_x, int count_y, int index, } - template -void test_intersects(int count_x, int count_y, int width_x, p_q_settings const& settings) +void test_intersects(int index, int count_x, int count_y, int width_x, p_q_settings const& settings) { MultiPolygon mp; @@ -64,6 +67,10 @@ void test_intersects(int count_x, int count_y, int width_x, p_q_settings const& std::ostringstream filename; filename << "intersects_" << string_from_type::name() + << "_" << index + << "_" << count_x + << "_" << count_y + << "_" << width_x << ".svg"; std::ofstream svg(filename.str().c_str()); @@ -92,7 +99,7 @@ void test_all(int count, int count_x, int count_y, int width_x, p_q_settings con for(int i = 0; i < count; i++) { - test_intersects(count_x, count_y, width_x, settings); + test_intersects(i, count_x, count_y, width_x, settings); } auto const t = std::chrono::high_resolution_clock::now(); auto const elapsed_ms = std::chrono::duration_cast(t - t0).count(); @@ -123,8 +130,10 @@ int main(int argc, char** argv) ("count_x", po::value(&count_x)->default_value(10), "Triangle count in x-direction") ("count_y", po::value(&count_y)->default_value(10), "Triangle count in y-direction") ("width_x", po::value(&width_x)->default_value(7), "Width of triangle in x-direction") +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) ("ccw", po::value(&ccw)->default_value(false), "Counter clockwise polygons") ("open", po::value(&open)->default_value(false), "Open polygons") +#endif ("wkt", po::value(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests") ("svg", po::value(&settings.svg)->default_value(false), "Create a SVG for all tests") ; @@ -139,6 +148,7 @@ int main(int argc, char** argv) return 1; } +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) if (ccw && open) { test_all(count, count_x, count_y, width_x, settings); @@ -152,6 +162,7 @@ int main(int argc, char** argv) test_all(count, count_x, count_y, width_x, settings); } else +#endif { test_all(count, count_x, count_y, width_x, settings); } diff --git a/test/robustness/overlay/areal_areal/random_ellipses_stars.cpp b/test/robustness/overlay/areal_areal/random_ellipses_stars.cpp index f7e9fdfb9..59054b092 100644 --- a/test/robustness/overlay/areal_areal/random_ellipses_stars.cpp +++ b/test/robustness/overlay/areal_areal/random_ellipses_stars.cpp @@ -1,13 +1,15 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Robustness Test -// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2009-2021 Barend Gehrels, Amsterdam, the Netherlands. // 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) #define BOOST_GEOMETRY_NO_BOOST_TEST +#define BOOST_GEOMETRY_NO_ROBUSTNESS +#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE #include @@ -166,11 +168,13 @@ void test_type(int seed, int count, p_q_settings const& settings) template void test_all(std::string const& type, int seed, int count, p_q_settings settings) { +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) if (type == "float") { test_type(seed, count, settings); } else if (type == "double") +#endif { test_type(seed, count, settings); } @@ -187,7 +191,7 @@ int main(int argc, char** argv) int count = 1; int seed = static_cast(std::time(0)); - std::string type = "float"; + std::string type = "double"; bool ccw = false; bool open = false; p_q_settings settings; @@ -197,9 +201,11 @@ int main(int argc, char** argv) ("seed", po::value(&seed), "Initialization seed for random generator") ("count", po::value(&count)->default_value(1), "Number of tests") ("diff", po::value(&settings.also_difference)->default_value(false), "Include testing on difference") +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) ("ccw", po::value(&ccw)->default_value(false), "Counter clockwise polygons") ("open", po::value(&open)->default_value(false), "Open polygons") - ("type", po::value(&type)->default_value("float"), "Type (float,double)") + ("type", po::value(&type)->default_value("double"), "Type (float,double)") +#endif ("wkt", po::value(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests") ("svg", po::value(&settings.svg)->default_value(false), "Create a SVG for all tests") ; @@ -214,6 +220,7 @@ int main(int argc, char** argv) return 1; } +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) if (ccw && open) { test_all(type, seed, count, settings); @@ -227,6 +234,7 @@ int main(int argc, char** argv) test_all(type, seed, count, settings); } else +#endif { test_all(type, seed, count, settings); } diff --git a/test/robustness/overlay/areal_areal/recursive_polygons.cpp b/test/robustness/overlay/areal_areal/recursive_polygons.cpp index a2cc17db8..f97becafe 100644 --- a/test/robustness/overlay/areal_areal/recursive_polygons.cpp +++ b/test/robustness/overlay/areal_areal/recursive_polygons.cpp @@ -1,13 +1,15 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Robustness Test -// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2009-2021 Barend Gehrels, Amsterdam, the Netherlands. // 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) #define BOOST_GEOMETRY_NO_BOOST_TEST +#define BOOST_GEOMETRY_NO_ROBUSTNESS +#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE #include @@ -174,8 +176,10 @@ int main(int argc, char** argv) ("level", po::value(&level)->default_value(3), "Level to reach (higher->slower)") ("size", po::value(&field_size)->default_value(10), "Size of the field") ("form", po::value(&form)->default_value("box"), "Form of the polygons (box, triangle)") +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) ("ccw", po::value(&ccw)->default_value(false), "Counter clockwise polygons") ("open", po::value(&open)->default_value(false), "Open polygons") +#endif ("wkt", po::value(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests") ("svg", po::value(&settings.svg)->default_value(false), "Create a SVG for all tests") ; @@ -193,7 +197,7 @@ int main(int argc, char** argv) bool triangular = form != "box"; - +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) if (ccw && open) { test_all(seed, count, field_size, level, triangular, settings); @@ -207,6 +211,7 @@ int main(int argc, char** argv) test_all(seed, count, field_size, level, triangular, settings); } else +#endif { test_all(seed, count, field_size, level, triangular, settings); } diff --git a/test/robustness/overlay/areal_areal/star_comb.cpp b/test/robustness/overlay/areal_areal/star_comb.cpp index 19e5350a2..90a7d0d05 100644 --- a/test/robustness/overlay/areal_areal/star_comb.cpp +++ b/test/robustness/overlay/areal_areal/star_comb.cpp @@ -1,13 +1,15 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Robustness Test -// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2009-2021 Barend Gehrels, Amsterdam, the Netherlands. // 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) #define BOOST_GEOMETRY_NO_BOOST_TEST +#define BOOST_GEOMETRY_NO_ROBUSTNESS +#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE #include @@ -98,8 +100,10 @@ int main(int argc, char** argv) ("count", po::value(&count)->default_value(1), "Number of tests") ("point_count", po::value(&point_count)->default_value(1), "Number of points in the star") ("diff", po::value(&settings.also_difference)->default_value(false), "Include testing on difference") +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) ("ccw", po::value(&ccw)->default_value(false), "Counter clockwise polygons") ("open", po::value(&open)->default_value(false), "Open polygons") +#endif ("wkt", po::value(&settings.wkt)->default_value(false), "Create a WKT of the inputs, for all tests") ("svg", po::value(&settings.svg)->default_value(false), "Create a SVG for all tests") ; @@ -117,7 +121,7 @@ int main(int argc, char** argv) int star_point_count = point_count * 2 + 1; int comb_comb_count = point_count; - +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) if (ccw && open) { test_all(count, star_point_count, comb_comb_count, factor1, factor2, do_union, settings); @@ -131,6 +135,7 @@ int main(int argc, char** argv) test_all(count, star_point_count, comb_comb_count, factor1, factor2, do_union, settings); } else +#endif { test_all(count, star_point_count, comb_comb_count, factor1, factor2, do_union, settings); } diff --git a/test/robustness/overlay/areal_areal/test_overlay_p_q.hpp b/test/robustness/overlay/areal_areal/test_overlay_p_q.hpp index 2e1f421ce..af0ec8264 100644 --- a/test/robustness/overlay/areal_areal/test_overlay_p_q.hpp +++ b/test/robustness/overlay/areal_areal/test_overlay_p_q.hpp @@ -1,7 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Robustness Test -// Copyright (c) 2009-2020 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2009-2021 Barend Gehrels, Amsterdam, the Netherlands. // This file was modified by Oracle on 2021. // Modifications copyright (c) 2021, Oracle and/or its affiliates. @@ -40,21 +40,16 @@ struct p_q_settings { - bool svg; - bool also_difference; - bool validity; - bool wkt; - bool verify_area; - double tolerance; + bool svg{false}; + bool also_difference{false}; + bool validity{false}; + bool wkt{false}; + bool verify_area{false}; + double tolerance{1.0e-3}; + bool verbose{false}; - p_q_settings() - : svg(false) - , also_difference(false) - , validity(false) - , wkt(false) - , verify_area(false) - , tolerance(1.0e-3) // since rescaling to integer the tolerance should be less. Was originally 1.0e-6 - {} + // NOTE: since rescaling to integer the tolerance is less. + // Was originally 1.0e-6 TODO: restore }; template @@ -209,6 +204,7 @@ static bool test_overlay_p_q(std::string const& caseid, } bool svg = settings.svg; + bool wkt = settings.wkt; if (wrong || settings.wkt) { @@ -216,53 +212,66 @@ static bool test_overlay_p_q(std::string const& caseid, { result = false; svg = true; + wkt = true; } - bg::unique(out_i); - bg::unique(out_u); - std::cout - << "type: " << string_from_type::name() - << " id: " << caseid - << " area i: " << area_i - << " area u: " << area_u - << " area p: " << area_p - << " area q: " << area_q - << " sum: " << sum; - - if (settings.also_difference) + if (settings.verbose) { std::cout - << " area d1: " << area_d1 - << " area d2: " << area_d2; - } - std::cout - << std::endl - << std::setprecision(9) - << " p: " << bg::wkt(p) << std::endl - << " q: " << bg::wkt(q) << std::endl - << " i: " << bg::wkt(out_i) << std::endl - << " u: " << bg::wkt(out_u) << std::endl - ; + << "type: " << string_from_type::name() + << " id: " << caseid + << " area i: " << area_i + << " area u: " << area_u + << " area p: " << area_p + << " area q: " << area_q + << " sum: " << sum; + if (settings.also_difference) + { + std::cout + << " area d1: " << area_d1 + << " area d2: " << area_d2; + } + std::cout + << std::endl + << std::setprecision(9) + << " p: " << bg::wkt(p) << std::endl + << " q: " << bg::wkt(q) << std::endl + << " i: " << bg::wkt(out_i) << std::endl + << " u: " << bg::wkt(out_u) << std::endl; + } } - if(svg) + std::string filename; { - std::ostringstream filename; - filename << "overlay_" << caseid << "_" + std::ostringstream out; + out << "overlay_" << caseid << "_" << string_from_type::name(); if (!std::is_same::value) { - filename << string_from_type::name(); + out << string_from_type::name(); } - - filename + out #if defined(BOOST_GEOMETRY_USE_RESCALING) - << "_rescaled" + << "_rescaled" #endif - << ".svg"; + << "."; + filename = out.str(); + } - std::ofstream svg(filename.str().c_str()); + if (wkt) + { + std::ofstream stream(filename + "wkt"); + // Stream input WKT's + stream << bg::wkt(p) << std::endl; + stream << bg::wkt(q) << std::endl; + // If you need the output WKT, then stream out_i and out_u + } + + + if (svg) + { + std::ofstream svg(filename + "svg"); bg::svg_mapper mapper(svg, 500, 500); diff --git a/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp b/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp index 13dba836b..330d78bbf 100644 --- a/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp +++ b/test/robustness/overlay/buffer/recursive_polygons_buffer.cpp @@ -1,7 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Robustness Test -// Copyright (c) 2012-2020 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2012-2021 Barend Gehrels, Amsterdam, the Netherlands. // This file was modified by Oracle on 2015-2021. // Modifications copyright (c) 2015-2021 Oracle and/or its affiliates. @@ -13,6 +13,8 @@ // http://www.boost.org/LICENSE_1_0.txt) #define BOOST_GEOMETRY_NO_BOOST_TEST +#define BOOST_GEOMETRY_NO_ROBUSTNESS +#define BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE #if defined(_MSC_VER) # pragma warning( disable : 4244 )