diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index da9988be14..e6813eacf4 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -38,8 +38,8 @@ jobs: fi echo "BOOST_SELF=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_ENV echo "BOOST_ROOT=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_ENV - echo "::set-output name=boost_self::$(basename $GITHUB_WORKSPACE)" - echo "::set-output name=boost_root::$GITHUB_WORKSPACE/boost-root" + echo "boost_self=$(basename $GITHUB_WORKSPACE)" >> "$GITHUB_OUTPUT" + echo "boost_root=$GITHUB_WORKSPACE/boost-root" >> "$GITHUB_OUTPUT" - name: Clone boostorg/boost run: | diff --git a/.github/workflows/headers.yml b/.github/workflows/headers.yml index 295f01eb56..3b0bbed3ec 100644 --- a/.github/workflows/headers.yml +++ b/.github/workflows/headers.yml @@ -28,8 +28,8 @@ jobs: fi echo "BOOST_SELF=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_ENV echo "BOOST_ROOT=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_ENV - echo "::set-output name=boost_self::$(basename $GITHUB_WORKSPACE)" - echo "::set-output name=boost_root::$GITHUB_WORKSPACE/boost-root" + echo "boost_self=$(basename $GITHUB_WORKSPACE)" >> "$GITHUB_OUTPUT" + echo "boost_root=$GITHUB_WORKSPACE/boost-root" >> "$GITHUB_OUTPUT" - name: Clone boostorg/boost run: | diff --git a/.github/workflows/minimal.yml b/.github/workflows/minimal.yml index bdc49b429c..8e5aba837e 100644 --- a/.github/workflows/minimal.yml +++ b/.github/workflows/minimal.yml @@ -102,8 +102,8 @@ jobs: fi echo "BOOST_SELF=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_ENV echo "BOOST_ROOT=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_ENV - echo "boost_self=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_OUTPUT - echo "boost_root=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_OUTPUT + echo "boost_self=$(basename $GITHUB_WORKSPACE)" >> "$GITHUB_OUTPUT" + echo "boost_root=$GITHUB_WORKSPACE/boost-root" >> "$GITHUB_OUTPUT" - name: Clone boostorg/boost run: | @@ -221,8 +221,8 @@ jobs: fi echo "BOOST_SELF=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_ENV echo "BOOST_ROOT=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_ENV - echo "boost_self=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_OUTPUT - echo "boost_root=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_OUTPUT + echo "boost_self=$(basename $GITHUB_WORKSPACE)" >> "$GITHUB_OUTPUT" + echo "boost_root=$GITHUB_WORKSPACE/boost-root" >> "$GITHUB_OUTPUT" - name: Clone boostorg/boost run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index 168c023f74..5b859fe837 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,7 @@ -# Generated by `boostdep --cmake geometry` +# Originally generated by `boostdep --cmake geometry` +# Adapted manually # Copyright 2020, 2021 Peter Dimov +# Copyright (c) 2024 Barend Gehrels, Amsterdam, the Netherlands. # Distributed under the Boost Software License, Version 1.0. # https://www.boost.org/LICENSE_1_0.txt @@ -11,6 +13,7 @@ add_library(boost_geometry INTERFACE) add_library(Boost::geometry ALIAS boost_geometry) target_include_directories(boost_geometry INTERFACE include) +target_compile_features(boost_geometry INTERFACE cxx_std_14) target_link_libraries(boost_geometry INTERFACE @@ -20,12 +23,8 @@ target_link_libraries(boost_geometry Boost::assert Boost::concept_check Boost::config - Boost::container Boost::core - Boost::endian Boost::function_types - Boost::fusion - Boost::integer Boost::iterator Boost::lexical_cast Boost::math @@ -33,28 +32,97 @@ target_link_libraries(boost_geometry Boost::mpl Boost::multiprecision Boost::numeric_conversion - Boost::polygon - Boost::predef Boost::qvm Boost::range Boost::rational - Boost::serialization - Boost::smart_ptr Boost::static_assert - Boost::thread Boost::throw_exception Boost::tokenizer Boost::tuple Boost::type_traits Boost::utility Boost::variant - Boost::variant2 ) -target_compile_features(boost_geometry INTERFACE cxx_std_14) +# Required for Boost.Geometry Index +target_link_libraries(boost_geometry + INTERFACE + Boost::container + Boost::serialization +) + +# Optional requirements (for example, for adaptations) +if(BOOST_GEOMETRY_BUILD_OPTIONAL) + target_link_libraries(boost_geometry + INTERFACE + Boost::fusion + Boost::integer + Boost::polygon + Boost::variant2 + ) + + # Mentioned in SRS Shared_grids_boost (which is optional) + target_link_libraries(boost_geometry + INTERFACE + Boost::thread + ) + + # Requirements for extensions + target_link_libraries(boost_geometry + INTERFACE + Boost::endian + Boost::predef + ) + +endif() if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") + if (${PROJECT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) + # Project is root. Find Boost source. + set(BOOST_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../.." CACHE STRING "Boost source dir to use when running CMake from this directory") + if (NOT IS_ABSOLUTE ${BOOST_SRC_DIR}) + set(BOOST_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${BOOST_SRC_DIR}") + endif() + + set(BOOST_SRC_DIR_IS_VALID ON) + foreach (PATH "CMakeLists.txt" "Jamroot" "boost-build.jam" "libs") + if (NOT EXISTS "${BOOST_SRC_DIR}/${PATH}") + message(STATUS "${BOOST_SRC_DIR}/${PATH} does not exist. Fallback to find_package.") + set(BOOST_SRC_DIR_IS_VALID OFF) + break() + endif() + endforeach() + + # Create Boost targets from source dir or boost package. + # These are the direct dependencies currently used in unit tests. + set(BOOST_INCLUDE_LIBRARIES + config + algorithm + any + lexical_cast + math + multiprecision + qvm + rational + serialization + tokenizer + variant + test) + + if (BOOST_SRC_DIR_IS_VALID) + set(BOOST_EXCLUDE_LIBRARIES ${PROJECT_NAME}) + add_subdirectory(${BOOST_SRC_DIR} deps_/boost EXCLUDE_FROM_ALL) + else() + find_package(Boost 1.81.0 REQUIRED) + foreach (BOOST_INCLUDE_LIBRARY ${BOOST_INCLUDE_LIBRARIES}) + add_library(Boost::${BOOST_INCLUDE_LIBRARY} ALIAS Boost::headers) + endforeach () + endif() + + endif() + + enable_testing() add_subdirectory(test) endif() diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk index 55a7529423..1ff00214ba 100644 --- a/doc/release_notes.qbk +++ b/doc/release_notes.qbk @@ -6,8 +6,8 @@ Copyright (c) 2009-2017 Mateusz Loskot , London, UK. Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland. - This file was modified by Oracle on 2015-2023. - Modifications copyright (c) 2015-2023, Oracle and/or its affiliates. + This file was modified by Oracle on 2015-2024. + Modifications copyright (c) 2015-2024, 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 @@ -19,6 +19,27 @@ [section:release_notes Release Notes] +[/=================] +[heading Boost 1.85] +[/=================] + +[*Improvements] + +* [@https://github.com/boostorg/geometry/pull/1247 1247] Use if constexpr macro instead of condition macro +* [@https://github.com/boostorg/geometry/pull/1242 1242] Pass strategy to sort by side +* [@https://github.com/boostorg/geometry/pull/1234 1234] Add cmake files for clang/mac/darwin/arm64 + +[*Solved issues] + +* [@https://github.com/boostorg/geometry/issues/1231 1231], [@https://github.com/boostorg/geometry/issues/1244 1244] Fix invalid set operations for CCW polygons +* [@https://github.com/boostorg/geometry/issues/1259 1259] Fix compilation error with CUDA NVCC compiler +* [@https://github.com/boostorg/geometry/issues/1250 1250] Fix buffer of linestring returning incorrect inner polygon +* [@https://github.com/boostorg/geometry/issues/1230 1230] Fix union operation perturbing a point and returning wrong result +* [@https://github.com/boostorg/geometry/issues/1229 1229] Fix union producing self intersections +* [@https://github.com/boostorg/geometry/pull/1248 1248] Fix buffer issue by setting turns in closed clusters as non traversable +* [@https://github.com/boostorg/geometry/pull/1246 1246] Fix compilation of converter and is_base_of +* Various fixes of errors and warnings + [/=================] [heading Boost 1.84] [/=================] @@ -37,16 +58,16 @@ [*Improvements] -* [https://github.com/boostorg/geometry/pull/1140 1140] Drop dependencies and replace boost with std in several places -* [https://github.com/boostorg/geometry/pull/1154 1154] Add missing headers so that all headers compile independently complying with Boost policy -* [https://github.com/boostorg/geometry/pull/1157 1157] Check const Ring concept in calculate_point_order +* [@https://github.com/boostorg/geometry/pull/1140 1140] Drop dependencies and replace boost with std in several places +* [@https://github.com/boostorg/geometry/pull/1154 1154] Add missing headers so that all headers compile independently complying with Boost policy +* [@https://github.com/boostorg/geometry/pull/1157 1157] Check const Ring concept in calculate_point_order [*Solved issues] * [@https://github.com/boostorg/geometry/issues/1100 1100] Fix for union * [@https://github.com/boostorg/geometry/issues/1139 1139] Fix for different geometry types * [@https://github.com/boostorg/geometry/issues/1158 1158] Fix for convex hull -* [*https://github.com/boostorg/geometry/issues/1161 1161] Fix within algorithm for geometries having a pole as a vertex +* [@https://github.com/boostorg/geometry/issues/1161 1161] Fix within algorithm for geometries having a pole as a vertex * Various fixes of errors and warnings [/=================] diff --git a/include/boost/geometry/algorithms/convert.hpp b/include/boost/geometry/algorithms/convert.hpp index 2d07ce2b7f..e61b50c30c 100644 --- a/include/boost/geometry/algorithms/convert.hpp +++ b/include/boost/geometry/algorithms/convert.hpp @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -45,6 +44,7 @@ #include +#include #include #include @@ -80,7 +80,7 @@ struct point_to_box typedef typename coordinate_type::type coordinate_type; set(box, - boost::numeric_cast(get(point))); + util::numeric_cast(get(point))); point_to_box < Point, Box, diff --git a/include/boost/geometry/algorithms/detail/assign_indexed_point.hpp b/include/boost/geometry/algorithms/detail/assign_indexed_point.hpp index 560dc67f35..9ae46768ea 100644 --- a/include/boost/geometry/algorithms/detail/assign_indexed_point.hpp +++ b/include/boost/geometry/algorithms/detail/assign_indexed_point.hpp @@ -21,12 +21,11 @@ #include -#include - #include #include #include #include +#include namespace boost { namespace geometry @@ -60,7 +59,7 @@ inline void assign_point_to_index(Point const& point, Geometry& geometry) detail::for_each_dimension([&](auto dimension) { geometry::set(geometry, - boost::numeric_cast + util::numeric_cast < typename coordinate_type::type >(geometry::get(point))); @@ -92,7 +91,7 @@ inline void assign_point_from_index(Geometry const& geometry, Point& point) detail::for_each_dimension([&](auto dimension) { geometry::set(point, - boost::numeric_cast + util::numeric_cast < typename coordinate_type::type >(geometry::get(geometry))); diff --git a/include/boost/geometry/algorithms/detail/assign_values.hpp b/include/boost/geometry/algorithms/detail/assign_values.hpp index f20a2041e7..fe72bc5683 100644 --- a/include/boost/geometry/algorithms/detail/assign_values.hpp +++ b/include/boost/geometry/algorithms/detail/assign_values.hpp @@ -26,8 +26,6 @@ #include #include -#include -#include #include #include @@ -39,7 +37,8 @@ #include #include -#include +#include +#include namespace boost { namespace geometry @@ -74,8 +73,8 @@ struct assign_inverse_box_or_segment { typedef typename coordinate_type::type coordinate_type; - coordinate_type const highest = geometry::bounds::highest(); - coordinate_type const lowest = geometry::bounds::lowest(); + coordinate_type const highest = util::bounds::highest(); + coordinate_type const lowest = util::bounds::lowest(); detail::for_each_dimension([&](auto dimension) { set<0, dimension>(geometry, highest); @@ -117,8 +116,8 @@ inline void assign_box_2d_corner(Box const& box, Point& point) // Copy coordinates typedef typename coordinate_type::type coordinate_type; - geometry::set<0>(point, boost::numeric_cast(get(box))); - geometry::set<1>(point, boost::numeric_cast(get(box))); + geometry::set<0>(point, util::numeric_cast(get(box))); + geometry::set<1>(point, util::numeric_cast(get(box))); } @@ -136,10 +135,10 @@ struct assign_2d_box_or_segment static inline void apply(Geometry& geometry, Type const& x1, Type const& y1, Type const& x2, Type const& y2) { - geometry::set<0, 0>(geometry, boost::numeric_cast(x1)); - geometry::set<0, 1>(geometry, boost::numeric_cast(y1)); - geometry::set<1, 0>(geometry, boost::numeric_cast(x2)); - geometry::set<1, 1>(geometry, boost::numeric_cast(y2)); + geometry::set<0, 0>(geometry, util::numeric_cast(x1)); + geometry::set<0, 1>(geometry, util::numeric_cast(y1)); + geometry::set<1, 0>(geometry, util::numeric_cast(x2)); + geometry::set<1, 1>(geometry, util::numeric_cast(y2)); } }; @@ -167,8 +166,8 @@ struct assign template static inline void apply(Point& point, T const& c1, T const& c2) { - set<0>(point, boost::numeric_cast(c1)); - set<1>(point, boost::numeric_cast(c2)); + set<0>(point, util::numeric_cast(c1)); + set<1>(point, util::numeric_cast(c2)); } }; @@ -180,9 +179,9 @@ struct assign template static inline void apply(Point& point, T const& c1, T const& c2, T const& c3) { - set<0>(point, boost::numeric_cast(c1)); - set<1>(point, boost::numeric_cast(c2)); - set<2>(point, boost::numeric_cast(c3)); + set<0>(point, util::numeric_cast(c1)); + set<1>(point, util::numeric_cast(c2)); + set<2>(point, util::numeric_cast(c3)); } }; diff --git a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp index 5e8635c3d7..2f0c5e3c05 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffer_inserter.hpp @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -973,8 +972,9 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator { collection.check_turn_in_original(); } - - collection.verify_turns(); + collection.handle_colocations(); + collection.check_turn_in_pieces(); + collection.make_traversable_consistent_per_cluster(); // Visit the piece collection. This does nothing (by default), but // optionally a debugging tool can be attached (e.g. console or svg), diff --git a/include/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp b/include/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp index e75532c3f3..918c2a9ee1 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffer_policies.hpp @@ -281,16 +281,6 @@ struct turn_overlaps_box Strategy const& m_strategy; }; -struct enriched_map_buffer_include_policy -{ - template - static inline bool include(Operation const& op) - { - return op != detail::overlay::operation_intersection - && op != detail::overlay::operation_blocked; - } -}; - }} // namespace detail::buffer #endif // DOXYGEN_NO_DETAIL diff --git a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp index 66943b303c..bd39116fc4 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp @@ -249,7 +249,8 @@ struct buffered_piece_collection // Offsetted rings, and representations of original ring(s) // both indexed by multi_index - buffered_ring_collection > offsetted_rings; + using ring_collection_t = buffered_ring_collection>; + ring_collection_t offsetted_rings; std::vector original_rings; std::vector m_linear_end_points; @@ -305,29 +306,6 @@ struct buffered_piece_collection } } - inline void verify_turns() - { - typedef detail::overlay::indexed_turn_operation - < - buffer_turn_operation_type - > indexed_turn_operation; - typedef std::map - < - ring_identifier, - std::vector - > mapped_vector_type; - mapped_vector_type mapped_vector; - - detail::overlay::create_map(m_turns, mapped_vector, - enriched_map_buffer_include_policy()); - - // Sort turns over offsetted ring(s) - for (auto& pair : mapped_vector) - { - std::sort(pair.second.begin(), pair.second.end(), buffer_less()); - } - } - inline void deflate_check_turns() { if (! m_has_deflated) @@ -470,24 +448,25 @@ struct buffered_piece_collection } update_turn_administration(); + } - { - // Check if turns are inside pieces - turn_in_piece_visitor - < - typename geometry::cs_tag::type, - turn_vector_type, piece_vector_type, DistanceStrategy, Strategy - > visitor(m_turns, m_pieces, m_distance_strategy, m_strategy); + inline void check_turn_in_pieces() + { + // Check if turns are inside pieces + turn_in_piece_visitor + < + typename geometry::cs_tag::type, + turn_vector_type, piece_vector_type, DistanceStrategy, Strategy + > visitor(m_turns, m_pieces, m_distance_strategy, m_strategy); - geometry::partition - < - box_type - >::apply(m_turns, m_pieces, visitor, - turn_get_box(m_strategy), - turn_overlaps_box(m_strategy), - piece_get_box(m_strategy), - piece_overlaps_box(m_strategy)); - } + geometry::partition + < + box_type + >::apply(m_turns, m_pieces, visitor, + turn_get_box(m_strategy), + turn_overlaps_box(m_strategy), + piece_get_box(m_strategy), + piece_overlaps_box(m_strategy)); } inline void start_new_ring(bool deflate) @@ -898,6 +877,61 @@ struct buffered_piece_collection //------------------------------------------------------------------------- + inline void handle_colocations() + { + if (! detail::overlay::handle_colocations + < + false, false, overlay_buffer, + ring_collection_t, ring_collection_t + >(m_turns, m_clusters, m_robust_policy)) + { + return; + } + + detail::overlay::gather_cluster_properties + < + false, false, overlay_buffer + >(m_clusters, m_turns, detail::overlay::operation_union, + offsetted_rings, offsetted_rings, m_strategy); + + for (auto const& cluster : m_clusters) + { + if (cluster.second.open_count == 0 && cluster.second.spike_count == 0) + { + // If the cluster is completely closed, mark it as not traversable. + for (auto const& index : cluster.second.turn_indices) + { + m_turns[index].is_turn_traversable = false; + } + } + } + } + + inline void make_traversable_consistent_per_cluster() + { + for (auto const& cluster : m_clusters) + { + bool is_traversable = false; + for (auto const& index : cluster.second.turn_indices) + { + if (m_turns[index].is_turn_traversable) + { + // If there is one turn traversable in the cluster, + // then all turns should be traversable. + is_traversable = true; + break; + } + } + if (is_traversable) + { + for (auto const& index : cluster.second.turn_indices) + { + m_turns[index].is_turn_traversable = true; + } + } + } + } + inline void enrich() { enrich_intersection_points(m_turns, diff --git a/include/boost/geometry/algorithms/detail/convert_indexed_to_indexed.hpp b/include/boost/geometry/algorithms/detail/convert_indexed_to_indexed.hpp index fccdf4bb1d..607fdae009 100644 --- a/include/boost/geometry/algorithms/detail/convert_indexed_to_indexed.hpp +++ b/include/boost/geometry/algorithms/detail/convert_indexed_to_indexed.hpp @@ -17,10 +17,10 @@ #include -#include #include #include #include +#include namespace boost { namespace geometry @@ -45,10 +45,10 @@ struct indexed_to_indexed typedef typename coordinate_type::type coordinate_type; geometry::set(destination, - boost::numeric_cast( + util::numeric_cast( geometry::get(source))); geometry::set(destination, - boost::numeric_cast( + util::numeric_cast( geometry::get(source))); indexed_to_indexed diff --git a/include/boost/geometry/algorithms/detail/convert_point_to_point.hpp b/include/boost/geometry/algorithms/detail/convert_point_to_point.hpp index 8762cd6687..a29ca3fcf4 100644 --- a/include/boost/geometry/algorithms/detail/convert_point_to_point.hpp +++ b/include/boost/geometry/algorithms/detail/convert_point_to_point.hpp @@ -18,10 +18,10 @@ #include -#include #include #include #include +#include namespace boost { namespace geometry @@ -45,7 +45,7 @@ struct point_to_point { typedef typename coordinate_type::type coordinate_type; - set(destination, boost::numeric_cast(get(source))); + set(destination, util::numeric_cast(get(source))); point_to_point::apply(source, destination); } }; diff --git a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp index 884a9278b3..e141036141 100644 --- a/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp +++ b/include/boost/geometry/algorithms/detail/convex_hull/interface.hpp @@ -53,7 +53,7 @@ #include #include -#include +#include #include #include #include @@ -240,7 +240,7 @@ struct convex_hull geometry::detail::assign_box_corners_oriented(box, arr); std::move(arr.begin(), arr.end(), range::back_inserter(out)); - if (BOOST_GEOMETRY_CONDITION(Close)) + if BOOST_GEOMETRY_CONSTEXPR (Close) { range::push_back(out, range::front(out)); } diff --git a/include/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp b/include/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp index 5af854f901..8d5d8b57cc 100644 --- a/include/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp +++ b/include/boost/geometry/algorithms/detail/distance/geometry_to_segment_or_box.hpp @@ -1,7 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2021, Oracle and/or its affiliates. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2014-2021, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -35,7 +36,7 @@ #include #include -#include +#include namespace boost { namespace geometry @@ -247,26 +248,28 @@ class geometry_to_segment_or_box } } - if (BOOST_GEOMETRY_CONDITION(is_comparable::value)) + if BOOST_GEOMETRY_CONSTEXPR (is_comparable::value) { return (std::min)(cd_min1, cd_min2); } - - if (cd_min1 < cd_min2) - { - return strategy.apply(*pit_min, *it_min1, *it_min2); - } - else + else // else prevents unreachable code warning { - return dispatch::distance - < - segment_or_box_point, - typename std::iterator_traits - < - segment_iterator_type - >::value_type, - Strategies - >::apply(*it_min, *sit_min, strategies); + if (cd_min1 < cd_min2) + { + return strategy.apply(*pit_min, *it_min1, *it_min2); + } + else + { + return dispatch::distance + < + segment_or_box_point, + typename std::iterator_traits + < + segment_iterator_type + >::value_type, + Strategies + >::apply(*it_min, *sit_min, strategies); + } } } diff --git a/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp b/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp index 09f3cc4f61..547d0fdd6a 100644 --- a/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp +++ b/include/boost/geometry/algorithms/detail/distance/segment_to_box.hpp @@ -1,5 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) +// Copyright (c) 2023-2024 Adam Wulkiewicz, Lodz, Poland. + // Copyright (c) 2014-2023 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle @@ -18,7 +20,6 @@ #include #include -#include #include #include @@ -41,9 +42,10 @@ #include #include -#include +#include #include #include +#include #include #include @@ -154,21 +156,23 @@ class segment_to_box_2D_generic } } - if (BOOST_GEOMETRY_CONDITION(is_comparable::value)) + if BOOST_GEOMETRY_CONSTEXPR (is_comparable::value) { return cd[imin]; } - - if (imin < 4) - { - return strategy.apply(box_points[imin], p[0], p[1]); - } - else + else // else prevents unreachable code warning { - unsigned int bimin = imin - 4; - return strategy.apply(p[bimin], - *bit_min[bimin].first, - *bit_min[bimin].second); + if (imin < 4) + { + return strategy.apply(box_points[imin], p[0], p[1]); + } + else + { + unsigned int bimin = imin - 4; + return strategy.apply(p[bimin], + *bit_min[bimin].first, + *bit_min[bimin].second); + } } } }; @@ -285,7 +289,7 @@ class segment_to_box_2D template static inline Result apply(T const& t) { - return boost::numeric_cast(t); + return util::numeric_cast(t); } }; diff --git a/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp b/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp index 9cbececdb7..f308e58210 100644 --- a/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp +++ b/include/boost/geometry/algorithms/detail/distance/segment_to_segment.hpp @@ -1,7 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2021, Oracle and/or its affiliates. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2014-2021, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -28,7 +29,7 @@ #include #include -#include +#include namespace boost { namespace geometry @@ -82,21 +83,23 @@ class segment_to_segment std::size_t imin = std::distance(boost::addressof(d[0]), std::min_element(d, d + 4)); - if (BOOST_GEOMETRY_CONDITION(is_comparable::value)) + if BOOST_GEOMETRY_CONSTEXPR (is_comparable::value) { return d[imin]; } - - switch (imin) + else // else prevents unreachable code warning { - case 0: - return strategy.apply(q[0], p[0], p[1]); - case 1: - return strategy.apply(q[1], p[0], p[1]); - case 2: - return strategy.apply(p[0], q[0], q[1]); - default: - return strategy.apply(p[1], q[0], q[1]); + switch (imin) + { + case 0: + return strategy.apply(q[0], p[0], p[1]); + case 1: + return strategy.apply(q[1], p[0], p[1]); + case 2: + return strategy.apply(p[0], q[0], q[1]); + default: + return strategy.apply(p[1], q[0], q[1]); + } } } }; diff --git a/include/boost/geometry/algorithms/detail/envelope/initialize.hpp b/include/boost/geometry/algorithms/detail/envelope/initialize.hpp index d8e252b53a..8d83426619 100644 --- a/include/boost/geometry/algorithms/detail/envelope/initialize.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/initialize.hpp @@ -13,11 +13,10 @@ #include -#include - #include #include #include +#include namespace boost { namespace geometry @@ -67,9 +66,9 @@ struct initialize static inline void apply(Box& box, coordinate_type min_value - = boost::numeric::bounds::highest(), + = util::bounds::highest(), coordinate_type max_value - = boost::numeric::bounds::lowest()) + = util::bounds::lowest()) { initialize_loop < diff --git a/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp b/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp index 04032c6237..d22d9f5467 100644 --- a/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp @@ -32,8 +32,8 @@ #include #include +#include #include -#include #include #include diff --git a/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp b/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp index 40ea1e4245..f74cbd8b3b 100644 --- a/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp +++ b/include/boost/geometry/algorithms/detail/equals/collect_vectors.hpp @@ -20,7 +20,6 @@ #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP -#include #include #include @@ -35,6 +34,7 @@ #include #include +#include #include #include @@ -77,7 +77,7 @@ struct collected_vector_cartesian bool normalize() { - T magnitude = math::sqrt(boost::numeric_cast(dx * dx + dy * dy)); + T magnitude = math::sqrt(util::numeric_cast(dx * dx + dy * dy)); // NOTE: shouldn't here math::equals() be called? if (magnitude > 0) diff --git a/include/boost/geometry/algorithms/detail/is_valid/pointlike.hpp b/include/boost/geometry/algorithms/detail/is_valid/pointlike.hpp index c0cf239c25..f4523454ac 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/pointlike.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/pointlike.hpp @@ -1,7 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2020, Oracle and/or its affiliates. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2014-2020, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -20,7 +21,7 @@ #include #include -#include +#include namespace boost { namespace geometry @@ -63,21 +64,21 @@ struct is_valid { boost::ignore_unused(multipoint, visitor); - if (BOOST_GEOMETRY_CONDITION( - AllowEmptyMultiGeometries || !boost::empty(multipoint))) - { - // we allow empty multi-geometries, so an empty multipoint - // is considered valid - return ! detail::is_valid::has_invalid_coordinate - < - MultiPoint - >::apply(multipoint, visitor); - } - else + if BOOST_GEOMETRY_CONSTEXPR (! AllowEmptyMultiGeometries) { - // we do not allow an empty multipoint - return visitor.template apply(); + if (boost::empty(multipoint)) + { + // we do not allow an empty multipoint + return visitor.template apply(); + } } + + // if we allow empty multi-geometries, an empty multipoint + // is considered valid + return ! detail::is_valid::has_invalid_coordinate + < + MultiPoint + >::apply(multipoint, visitor); } }; diff --git a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp index 39512ad154..006581aa3b 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp @@ -450,42 +450,44 @@ class is_valid_polygon { return true; } + else // else prevents unreachable code warning + { + // compute turns and check if all are acceptable + typedef debug_validity_phase debug_phase; + debug_phase::apply(3); - // compute turns and check if all are acceptable - typedef debug_validity_phase debug_phase; - debug_phase::apply(3); - - typedef has_valid_self_turns has_valid_turns; + typedef has_valid_self_turns has_valid_turns; - std::deque turns; - bool has_invalid_turns - = ! has_valid_turns::apply(polygon, turns, visitor, strategy); - debug_print_turns(turns.begin(), turns.end()); + std::deque turns; + bool has_invalid_turns + = ! has_valid_turns::apply(polygon, turns, visitor, strategy); + debug_print_turns(turns.begin(), turns.end()); - if (has_invalid_turns) - { - return false; - } + if (has_invalid_turns) + { + return false; + } - // check if all interior rings are inside the exterior ring - debug_phase::apply(4); + // check if all interior rings are inside the exterior ring + debug_phase::apply(4); - if (! has_holes_inside::apply(polygon, - turns.begin(), turns.end(), - visitor, - strategy)) - { - return false; - } + if (! has_holes_inside::apply(polygon, + turns.begin(), turns.end(), + visitor, + strategy)) + { + return false; + } - // check whether the interior of the polygon is a connected set - debug_phase::apply(5); + // check whether the interior of the polygon is a connected set + debug_phase::apply(5); - return has_connected_interior::apply(polygon, - turns.begin(), - turns.end(), - visitor, - strategy); + return has_connected_interior::apply(polygon, + turns.begin(), + turns.end(), + visitor, + strategy); + } } }; diff --git a/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp b/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp index c52266c190..6596104af4 100644 --- a/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp @@ -1,10 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2014-2020. // Modifications copyright (c) 2014-2020 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, @@ -29,7 +29,7 @@ #include -#include +#include #include @@ -53,30 +53,32 @@ inline bool points_equal_or_close(Point1 const& point1, return true; } - if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled)) + if BOOST_GEOMETRY_CONSTEXPR (! RobustPolicy::enabled) { return false; } - - // Try using specified robust policy - typedef typename geometry::robust_point_type - < - Point1, - RobustPolicy - >::type robust_point_type; - - robust_point_type point1_rob, point2_rob; - geometry::recalculate(point1_rob, point1, robust_policy); - geometry::recalculate(point2_rob, point2, robust_policy); - - // Only if this is the case the same strategy can be used. - BOOST_STATIC_ASSERT((std::is_same - < - typename geometry::cs_tag::type, - typename geometry::cs_tag::type - >::value)); - - return detail::equals::equals_point_point(point1_rob, point2_rob, strategy); + else // else prevents unreachable code warning + { + // Try using specified robust policy + using robust_point_type = typename geometry::robust_point_type + < + Point1, + RobustPolicy + >::type; + + robust_point_type point1_rob, point2_rob; + geometry::recalculate(point1_rob, point1, robust_policy); + geometry::recalculate(point2_rob, point2, robust_policy); + + // Only if this is the case the same strategy can be used. + BOOST_STATIC_ASSERT((std::is_same + < + typename geometry::cs_tag::type, + typename geometry::cs_tag::type + >::value)); + + return detail::equals::equals_point_point(point1_rob, point2_rob, strategy); + } } @@ -214,7 +216,7 @@ inline void remove_spikes_at_closure(Ring& ring, Strategy const& strategy, template inline void fix_closure(Ring& ring, Strategy const& strategy) { - if (BOOST_GEOMETRY_CONDITION(geometry::closure::value == geometry::open)) + if BOOST_GEOMETRY_CONSTEXPR (geometry::closure::value == geometry::open) { if (! boost::empty(ring) && detail::equals::equals_point_point(range::front(ring), range::back(ring), strategy)) diff --git a/include/boost/geometry/algorithms/detail/overlay/cluster_exits.hpp b/include/boost/geometry/algorithms/detail/overlay/cluster_exits.hpp index b1c7de217d..94fe235d4e 100644 --- a/include/boost/geometry/algorithms/detail/overlay/cluster_exits.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/cluster_exits.hpp @@ -1,6 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2020 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2020-2023. // Modifications copyright (c) 2020-2023 Oracle and/or its affiliates. @@ -24,7 +25,7 @@ #include #include #include -#include +#include #if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) \ || defined(BOOST_GEOMETRY_OVERLAY_REPORT_WKT) \ @@ -199,13 +200,14 @@ public : // Points to different target return false; } - if (first_run - && BOOST_GEOMETRY_CONDITION(OverlayType == overlay_buffer) - && target.turn_index >= 0) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_buffer) { - // Target already assigned, so there are more targets - // or more ways to the same target - return false; + if (first_run && target.turn_index >= 0) + { + // Target already assigned, so there are more targets + // or more ways to the same target + return false; + } } target = lti; diff --git a/include/boost/geometry/algorithms/detail/overlay/cluster_info.hpp b/include/boost/geometry/algorithms/detail/overlay/cluster_info.hpp index 19343488f3..dae519c18a 100644 --- a/include/boost/geometry/algorithms/detail/overlay/cluster_info.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/cluster_info.hpp @@ -27,11 +27,11 @@ struct cluster_info std::set turn_indices; //! Number of open spaces (e.g. 2 for touch) - std::size_t open_count; + std::size_t open_count{0}; - inline cluster_info() - : open_count(0) - {} + //! Number of spikes, where a segment goes to the cluster point + //! and leaves immediately in the opposite direction. + std::size_t spike_count{0}; }; diff --git a/include/boost/geometry/algorithms/detail/overlay/discard_duplicate_turns.hpp b/include/boost/geometry/algorithms/detail/overlay/discard_duplicate_turns.hpp index ca537e0815..604dd9fd36 100644 --- a/include/boost/geometry/algorithms/detail/overlay/discard_duplicate_turns.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/discard_duplicate_turns.hpp @@ -137,6 +137,13 @@ inline void discard_duplicate_start_turns(Turns& turns, { for (std::size_t const& i : it->second) { + if (turns[i].cluster_id != turn.cluster_id) + { + // The turns are not part of the same cluster, + // or one is clustered and the other is not. + // This is not corresponding. + continue; + } if (corresponding_turn(turn, turns[i], geometry0, geometry1)) { diff --git a/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp b/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp index 962c68be69..2a6d62ef6c 100644 --- a/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #ifdef BOOST_GEOMETRY_DEBUG_ENRICH @@ -106,69 +107,86 @@ inline void enrich_sort(Operations& operations, } +// Assign travel-to-vertex/ip index for each turn. template inline void enrich_assign(Operations& operations, Turns& turns, - bool check_turns) + bool check_consecutive_turns) { - if (operations.empty()) - { - return; - } - - // Assign travel-to-vertex/ip index for each turning point. - // Iterator "next" is circular - - geometry::ever_circling_range_iterator next(operations); - ++next; - - for (auto const& indexed : operations) + for_each_with_index(operations, [&](std::size_t index, auto const& indexed) { auto& turn = turns[indexed.turn_index]; auto& op = turn.operations[indexed.operation_index]; - if (check_turns && indexed.turn_index == next->turn_index) + std::size_t next_index = index + 1 < operations.size() ? index + 1 : 0; + auto advance = [&operations](auto index) + { + std::size_t const result = index + 1; + return result >= operations.size() ? 0 : result; + }; + + auto next_turn = [&operations, &turns, &next_index]() + { + return turns[operations[next_index].turn_index]; + }; + auto next_operation = [&operations, &turns, &next_index]() + { + auto const& next_turn = turns[operations[next_index].turn_index]; + return next_turn.operations[operations[next_index].operation_index]; + }; + + if (check_consecutive_turns + && indexed.turn_index == operations[next_index].turn_index + && op.seg_id == next_operation().seg_id) { - // Normal behaviour: next points at next turn, increase next. - // For dissolve this should not be done, turn_index is often - // the same for two consecutive operations - ++next; + // If the two operations on the same turn are ordered consecutively, + // and they are on the same segment, then the turn where to travel to should + // be considered one further. Therefore next is increased. + // + // It often happens in buffer, in these configurations: + // +---->--+ + // | | + // | +->-*----> + // | | | + // ^ +-<-+ + // If the next index is not corrected, the small rectangle + // will be kept in the output. + + // This is a normal situation and occurs, for example, in every concave bend. + // In general it should always travel from turn to next turn. + // Only in some circumstances traveling to the same turn is necessary, for example + // if there is only one turn in the outer ring. + // + // (For dissolve this is not done, turn_index is often + // the same for two consecutive operations - but the conditions are changed + // and this should be verified again) + next_index = advance(next_index); } // Cluster behaviour: next should point after cluster, unless // their seg_ids are not the same // (For dissolve, this is still to be examined - TODO) while (turn.is_clustered() - && indexed.turn_index != next->turn_index - && turn.cluster_id == turns[next->turn_index].cluster_id - && op.seg_id == turns[next->turn_index].operations[next->operation_index].seg_id) + && turn.cluster_id == next_turn().cluster_id + && op.seg_id == next_operation().seg_id + && indexed.turn_index != operations[next_index].turn_index) { - ++next; + next_index = advance(next_index); } - auto const& next_turn = turns[next->turn_index]; - auto const& next_op = next_turn.operations[next->operation_index]; - op.enriched.travels_to_ip_index - = static_cast(next->turn_index); + = static_cast(operations[next_index].turn_index); op.enriched.travels_to_vertex_index - = next->subject->seg_id.segment_index; + = operations[next_index].subject->seg_id.segment_index; + auto const& next_op = next_operation(); if (op.seg_id.segment_index == next_op.seg_id.segment_index - && op.fraction < next_op.fraction) - { - // Next turn is located further on same segment - // assign next_ip_index - // (this is one not circular therefore fraction is considered) - op.enriched.next_ip_index = static_cast(next->turn_index); - } - - if (! check_turns) + && op.fraction < next_op.fraction) { - ++next; + // Next turn is located further on same segment: assign next_ip_index + op.enriched.next_ip_index = static_cast(operations[next_index].turn_index); } - } + }); - // DEBUG #ifdef BOOST_GEOMETRY_DEBUG_ENRICH for (auto const& indexed_op : operations) { @@ -190,8 +208,6 @@ inline void enrich_assign(Operations& operations, Turns& turns, << std::endl; } #endif - // END DEBUG - } template @@ -383,6 +399,7 @@ inline void enrich_intersection_points(Turns& turns, ? detail::overlay::operation_intersection : detail::overlay::operation_union; constexpr bool is_dissolve = OverlayType == overlay_dissolve; + constexpr bool is_buffer = OverlayType == overlay_buffer; using turn_type = typename boost::range_value::type; using indexed_turn_operation = detail::overlay::indexed_turn_operation @@ -396,16 +413,36 @@ inline void enrich_intersection_points(Turns& turns, std::vector >; - // From here on, turn indexes are used (in clusters, next_index, etc) - // and turns may not be DELETED - they may only be flagged as discarded - discard_duplicate_start_turns(turns, geometry1, geometry2); + // Turns are often used by index (in clusters, next_index, etc) + // and turns may therefore NOT be DELETED - they may only be flagged as discarded bool has_cc = false; - bool const has_colocations - = detail::overlay::handle_colocations + bool has_colocations = false; + + if BOOST_GEOMETRY_CONSTEXPR (! is_buffer) + { + // Handle colocations, gathering clusters and (below) their properties. + has_colocations = detail::overlay::handle_colocations + < + Reverse1, Reverse2, OverlayType, Geometry1, Geometry2 + >(turns, clusters, robust_policy); + // Gather cluster properties (using even clusters with + // discarded turns - for open turns) + detail::overlay::gather_cluster_properties < - Reverse1, Reverse2, OverlayType, Geometry1, Geometry2 - >(turns, clusters, robust_policy); + Reverse1, + Reverse2, + OverlayType + >(clusters, turns, target_operation, + geometry1, geometry2, strategy); + } + else + { + // For buffer, this was already done before calling enrich_intersection_points. + has_colocations = ! clusters.empty(); + } + + discard_duplicate_start_turns(turns, geometry1, geometry2); // Discard turns not part of target overlay for (auto& turn : turns) @@ -468,28 +505,12 @@ inline void enrich_intersection_points(Turns& turns, pair.second, turns, geometry1, geometry2, robust_policy, strategy); -#ifdef BOOST_GEOMETRY_DEBUG_ENRICH - std::cout << "ENRICH-sort Ring " << pair.first << std::endl; - for (auto const& op : pair.second) - { - std::cout << op.turn_index << " " << op.operation_index << std::endl; - } -#endif } if (has_colocations) { - // First gather cluster properties (using even clusters with - // discarded turns - for open turns), then clean up clusters - detail::overlay::gather_cluster_properties - < - Reverse1, - Reverse2, - OverlayType - >(clusters, turns, target_operation, - geometry1, geometry2, strategy.side()); // TODO: pass strategy - detail::overlay::cleanup_clusters(turns, clusters); + detail::overlay::colocate_clusters(clusters, turns); } // After cleaning up clusters assign the next turns diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp index 0fa6bdbd1b..dfc87d2fa4 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info.hpp @@ -1,7 +1,7 @@ // Boost.Geometry // Copyright (c) 2007-2023 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2017-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2015-2022. // Modifications copyright (c) 2015-2022 Oracle and/or its affiliates. @@ -27,7 +27,7 @@ #include #include -#include +#include namespace boost { namespace geometry @@ -286,7 +286,7 @@ struct turn_info_verification_functions std::size_t index_p, std::size_t index_q, TurnInfo& ti) { - if (BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_side_verification)) + if BOOST_GEOMETRY_CONSTEXPR (VerifyPolicy::use_side_verification) { set_both_verified(range_p, range_q, umbrella_strategy, index_p, index_q, ti); @@ -309,29 +309,29 @@ struct turn_info_verification_functions UmbrellaStrategy const& umbrella_strategy, int index_p, int index_q) { - if (side == 0 - && BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_side_verification)) + if BOOST_GEOMETRY_CONSTEXPR (VerifyPolicy::use_side_verification) { - if (index_p >= 1 && range_p.is_last_segment()) + if (side == 0) { - return 0; - } - if (index_q >= 2 && range_q.is_last_segment()) - { - return 0; - } + if (index_p >= 1 && range_p.is_last_segment()) + { + return 0; + } + if (index_q >= 2 && range_q.is_last_segment()) + { + return 0; + } - auto const dm = get_distance_measure(range_p.at(index_p), - range_p.at(index_p + 1), - range_q.at(index_q), - umbrella_strategy); - static decltype(dm.measure) const zero = 0; - return dm.measure == zero ? 0 : dm.measure > zero ? 1 : -1; - } - else - { - return side; + auto const dm = get_distance_measure(range_p.at(index_p), + range_p.at(index_p + 1), + range_q.at(index_q), + umbrella_strategy); + static decltype(dm.measure) const zero = 0; + return dm.measure == zero ? 0 : dm.measure > zero ? 1 : -1; + } } + + return side; } }; @@ -354,45 +354,47 @@ struct touch_interior : public base_turn_handler static bool handle_as_touch(IntersectionInfo const& info, UniqueSubRange const& non_touching_range) { - if (! BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_handle_as_touch)) + if BOOST_GEOMETRY_CONSTEXPR (! VerifyPolicy::use_handle_as_touch) { return false; } + else // else prevents unreachable code warning + { + // + // + // ^ Q(i) ^ P(i) + // \ / + // \ / + // \ / + // \ / + // \ / + // \ / + // \ / + // \ / + // \ / + // \ / it is about buffer_rt_r + // P(k) v/ they touch here "in the middle", but at the intersection... + // <---------------->v there is no follow up IP + // / + // / + // / + // / + // / + // / + // v Q(k) + // - // - // - // ^ Q(i) ^ P(i) - // \ / - // \ / - // \ / - // \ / - // \ / - // \ / - // \ / - // \ / - // \ / - // \ / it is about buffer_rt_r - // P(k) v/ they touch here "in the middle", but at the intersection... - // <---------------->v there is no follow up IP - // / - // / - // / - // / - // / - // / - // v Q(k) - // - - // Measure where the IP is located. If it is really close to the end, - // then there is no space for the next IP (on P(1)/Q(2). A "from" - // intersection will be generated, but those are never handled. - // Therefore handle it as a normal touch (two segments arrive at the - // intersection point). It currently checks for zero, but even a - // distance a little bit larger would do. - auto const dm = fun::distance_measure(info.intersections[0], non_touching_range.at(1)); - decltype(dm) const zero = 0; - bool const result = math::equals(dm, zero); - return result; + // Measure where the IP is located. If it is really close to the end, + // then there is no space for the next IP (on P(1)/Q(2). A "from" + // intersection will be generated, but those are never handled. + // Therefore handle it as a normal touch (two segments arrive at the + // intersection point). It currently checks for zero, but even a + // distance a little bit larger would do. + auto const dm = fun::distance_measure(info.intersections[0], non_touching_range.at(1)); + decltype(dm) const zero = 0; + bool const result = math::equals(dm, zero); + return result; + } } // Index: 0, P is the interior, Q is touching and vice versa @@ -561,65 +563,67 @@ struct touch : public base_turn_handler UmbrellaStrategy const& umbrella_strategy, TurnInfo& ti) { - if (! BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_handle_imperfect_touch)) + if BOOST_GEOMETRY_CONSTEXPR (! VerifyPolicy::use_handle_imperfect_touch) { return false; } - - // Q - // ^ - // || - // || - // |^---- - // >----->P - // * * they touch here (P/Q are (nearly) on top) - // - // Q continues from where P comes. - // P continues from where Q comes - // This is often a blocking situation, - // unless there are FP issues: there might be a distance - // between Pj and Qj, in that case handle it as a union. - // - // Exaggerated: - // Q - // ^ Q is nearly vertical - // \ but not completely - and still ends above P - // | \qj In this case it should block P and - // | ^------ set Q to Union - // >----->P qj is LEFT of P1 and pi is LEFT of Q2 - // (the other way round is also possible) - - auto has_distance = [&](auto const& r1, auto const& r2) -> bool + else // else prevents unreachable code warning { - auto const d1 = get_distance_measure(r1.at(0), r1.at(1), r2.at(1), umbrella_strategy); - auto const d2 = get_distance_measure(r2.at(1), r2.at(2), r1.at(0), umbrella_strategy); - return d1.measure > 0 && d2.measure > 0; - }; + // Q + // ^ + // || + // || + // |^---- + // >----->P + // * * they touch here (P/Q are (nearly) on top) + // + // Q continues from where P comes. + // P continues from where Q comes + // This is often a blocking situation, + // unless there are FP issues: there might be a distance + // between Pj and Qj, in that case handle it as a union. + // + // Exaggerated: + // Q + // ^ Q is nearly vertical + // \ but not completely - and still ends above P + // | \qj In this case it should block P and + // | ^------ set Q to Union + // >----->P qj is LEFT of P1 and pi is LEFT of Q2 + // (the other way round is also possible) + + auto has_distance = [&](auto const& r1, auto const& r2) -> bool + { + auto const d1 = get_distance_measure(r1.at(0), r1.at(1), r2.at(1), umbrella_strategy); + auto const d2 = get_distance_measure(r2.at(1), r2.at(2), r1.at(0), umbrella_strategy); + return d1.measure > 0 && d2.measure > 0; + }; - if (side_pk_q2 == -1 && has_distance(range_p, range_q)) - { - // Even though there is a touch, Q(j) is left of P1 - // and P(i) is still left from Q2. - // Q continues to the right. - // It can continue. - ti.operations[0].operation = operation_blocked; - // Q turns right -> union (both independent), - // Q turns left -> intersection - ti.operations[1].operation = operation_union; - ti.touch_only = true; - return true; - } + if (side_pk_q2 == -1 && has_distance(range_p, range_q)) + { + // Even though there is a touch, Q(j) is left of P1 + // and P(i) is still left from Q2. + // Q continues to the right. + // It can continue. + ti.operations[0].operation = operation_blocked; + // Q turns right -> union (both independent), + // Q turns left -> intersection + ti.operations[1].operation = operation_union; + ti.touch_only = true; + return true; + } - if (side_pk_q2 == 1 && has_distance(range_q, range_p)) - { - // Similarly, but the other way round. - // Q continues to the left. - ti.operations[0].operation = operation_union; - ti.operations[1].operation = operation_blocked; - ti.touch_only = true; - return true; + if (side_pk_q2 == 1 && has_distance(range_q, range_p)) + { + // Similarly, but the other way round. + // Q continues to the left. + ti.operations[0].operation = operation_union; + ti.operations[1].operation = operation_blocked; + ti.touch_only = true; + return true; + } + return false; } - return false; } template @@ -915,39 +919,40 @@ struct start : public base_turn_handler SideCalculator const& side, UmbrellaStrategy const& ) { - if (! BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_start_turn)) + if BOOST_GEOMETRY_CONSTEXPR (! VerifyPolicy::use_start_turn) { return false; } + else // else prevents unreachable code warning + { + // Start turns have either how_a = -1, or how_b = -1 (either p leaves or q leaves) + BOOST_GEOMETRY_ASSERT(dir_info.how_a != dir_info.how_b); + BOOST_GEOMETRY_ASSERT(dir_info.how_a == -1 || dir_info.how_b == -1); + BOOST_GEOMETRY_ASSERT(dir_info.how_a == 0 || dir_info.how_b == 0); - // Start turns have either how_a = -1, or how_b = -1 (either p leaves or q leaves) - BOOST_GEOMETRY_ASSERT(dir_info.how_a != dir_info.how_b); - BOOST_GEOMETRY_ASSERT(dir_info.how_a == -1 || dir_info.how_b == -1); - BOOST_GEOMETRY_ASSERT(dir_info.how_a == 0 || dir_info.how_b == 0); + if (dir_info.how_b == -1) + { + // p ---------------> + // | + // | q q leaves + // v + // - if (dir_info.how_b == -1) - { - // p ---------------> - // | - // | q q leaves - // v - // + int const side_qj_p1 = side.qj_wrt_p1(); + ui_else_iu(side_qj_p1 == -1, ti); + } + else if (dir_info.how_a == -1) + { + // p leaves + int const side_pj_q1 = side.pj_wrt_q1(); + ui_else_iu(side_pj_q1 == 1, ti); + } - int const side_qj_p1 = side.qj_wrt_p1(); - ui_else_iu(side_qj_p1 == -1, ti); - } - else if (dir_info.how_a == -1) - { - // p leaves - int const side_pj_q1 = side.pj_wrt_q1(); - ui_else_iu(side_pj_q1 == 1, ti); + // Copy intersection point + assign_point_and_correct(ti, method_start, info, dir_info); + return true; } - - // Copy intersection point - assign_point_and_correct(ti, method_start, info, dir_info); - return true; } - }; @@ -973,7 +978,7 @@ struct equal_opposite : public base_turn_handler IntersectionInfo const& intersection_info) { // For equal-opposite segments, normally don't do anything. - if (BOOST_GEOMETRY_CONDITION(AssignPolicy::include_opposite)) + if BOOST_GEOMETRY_CONSTEXPR (AssignPolicy::include_opposite) { tp.method = method_equal; for (unsigned int i = 0; i < 2; i++) @@ -1010,24 +1015,26 @@ struct collinear : public base_turn_handler UniqueSubRange2 const& range_q, DirInfo const& dir_info) { - if (! BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_handle_as_equal)) + if BOOST_GEOMETRY_CONSTEXPR (! VerifyPolicy::use_handle_as_equal) { return false; } - - int const arrival_p = dir_info.arrival[0]; - int const arrival_q = dir_info.arrival[1]; - if (arrival_p * arrival_q != -1 || info.count != 2) + else // else prevents unreachable code warning { - // Code below assumes that either p or q arrives in the other segment - return false; - } + int const arrival_p = dir_info.arrival[0]; + int const arrival_q = dir_info.arrival[1]; + if (arrival_p * arrival_q != -1 || info.count != 2) + { + // Code below assumes that either p or q arrives in the other segment + return false; + } - auto const dm = arrival_p == 1 - ? fun::distance_measure(info.intersections[1], range_q.at(1)) - : fun::distance_measure(info.intersections[1], range_p.at(1)); - decltype(dm) const zero = 0; - return math::equals(dm, zero); + auto const dm = arrival_p == 1 + ? fun::distance_measure(info.intersections[1], range_q.at(1)) + : fun::distance_measure(info.intersections[1], range_p.at(1)); + decltype(dm) const zero = 0; + return math::equals(dm, zero); + } } /* @@ -1191,7 +1198,7 @@ private : // two operations blocked, so the whole point does not need // to be generated. // So return false to indicate nothing is to be done. - if (BOOST_GEOMETRY_CONDITION(AssignPolicy::include_opposite)) + if BOOST_GEOMETRY_CONSTEXPR (AssignPolicy::include_opposite) { tp.operations[Index].operation = operation_opposite; blocked = operation_opposite; @@ -1285,7 +1292,7 @@ private : *out++ = tp; } - if (BOOST_GEOMETRY_CONDITION(AssignPolicy::include_opposite)) + if BOOST_GEOMETRY_CONSTEXPR (AssignPolicy::include_opposite) { // Handle cases not yet handled above if ((arrival_q == -1 && arrival_p == 0) diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp index 90e4d0d063..c849774d6f 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp @@ -1,7 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2017-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2013-2020. // Modifications copyright (c) 2013-2020 Oracle and/or its affiliates. @@ -19,7 +19,7 @@ #include -#include +#include #include #include @@ -216,15 +216,17 @@ struct get_turn_info_linear_areal tp.operations[0].operation, tp.operations[1].operation); - bool ignore_spike - = calculate_spike_operation(tp.operations[0].operation, - inters, - umbrella_strategy); + bool const ignore_spike = calculate_spike_operation(tp.operations[0].operation, + inters, + umbrella_strategy); - if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) - || ignore_spike - || ! append_opposite_spikes( // for 'i' or 'c' i??? - tp, inters, out) ) + if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes) + { + *out++ = tp; + } + else if (ignore_spike + // for 'i' or 'c' i??? + || ! append_opposite_spikes(tp, inters, out)) { *out++ = tp; } @@ -256,9 +258,12 @@ struct get_turn_info_linear_areal transformer(tp); // conditionally handle spikes - if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) - || ! append_collinear_spikes(tp, inters, - method_touch, append_equal, out) ) + if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes) + { + *out++ = tp; + } + else if (! append_collinear_spikes(tp, inters, method_touch, + append_equal, out)) { *out++ = tp; // no spikes } @@ -319,9 +324,12 @@ struct get_turn_info_linear_areal transformer(tp); // conditionally handle spikes - if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) - || ! append_collinear_spikes(tp, inters, - method_replace, version, out) ) + if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes) + { + *out++ = tp; + } + else if (! append_collinear_spikes(tp, inters, method_replace, + version, out)) { // no spikes *out++ = tp; @@ -333,10 +341,9 @@ struct get_turn_info_linear_areal turn_transformer_ec transformer(method_touch_interior); // conditionally handle spikes - if ( BOOST_GEOMETRY_CONDITION(handle_spikes) ) + if BOOST_GEOMETRY_CONSTEXPR (handle_spikes) { - append_opposite_spikes( - tp, inters, out); + append_opposite_spikes(tp, inters, out); } // TODO: ignore for spikes? @@ -357,7 +364,7 @@ struct get_turn_info_linear_areal case '0' : { // degenerate points - if ( BOOST_GEOMETRY_CONDITION(AssignPolicy::include_degenerate) ) + if BOOST_GEOMETRY_CONSTEXPR (AssignPolicy::include_degenerate) { only_convert::apply(tp, inters.i_info()); @@ -542,26 +549,30 @@ struct get_turn_info_linear_areal return false; } else*/ - if ( is_p_spike ) + if (is_p_spike) { - if ( BOOST_GEOMETRY_CONDITION(is_version_touches) - || inters.d_info().arrival[0] == 1 ) + bool output_spike = false; + if BOOST_GEOMETRY_CONSTEXPR (is_version_touches) { - if ( BOOST_GEOMETRY_CONDITION(is_version_touches) ) - { - tp.operations[0].is_collinear = true; - //tp.operations[1].is_collinear = false; - tp.method = method_touch; - } - else - { - tp.operations[0].is_collinear = true; - //tp.operations[1].is_collinear = false; + tp.operations[0].is_collinear = true; + //tp.operations[1].is_collinear = false; + tp.method = method_touch; - BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1); - base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1); - } + output_spike = true; + } + else if (inters.d_info().arrival[0] == 1) + { + tp.operations[0].is_collinear = true; + //tp.operations[1].is_collinear = false; + + BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1); + base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1); + + output_spike = true; + } + if (output_spike) + { tp.operations[0].operation = operation_blocked; tp.operations[1].operation = operation_continue; // boundary *out++ = tp; @@ -636,9 +647,12 @@ struct get_turn_info_linear_areal operation_type & op1 = turn.operations[1].operation; // NOTE: probably only if methods are WRT IPs, not segments! - if ( BOOST_GEOMETRY_CONDITION(IsFront) - || op0 == operation_intersection || op0 == operation_union - || op1 == operation_intersection || op1 == operation_union ) + if BOOST_GEOMETRY_CONSTEXPR (IsFront) + { + turn.method = m_method; + } + else if (op0 == operation_intersection || op0 == operation_union + || op1 == operation_intersection || op1 == operation_union) { turn.method = m_method; } @@ -724,145 +738,151 @@ struct get_turn_info_linear_areal // IP on the first point of Linear Geometry bool was_first_point_handled = false; - if ( BOOST_GEOMETRY_CONDITION(EnableFirst) - && range_p.is_first_segment() && ip0.is_pi && !ip0.is_qi ) // !q0i prevents duplication + if BOOST_GEOMETRY_CONSTEXPR (EnableFirst) { - TurnInfo tp = tp_model; - tp.operations[0].position = position_front; - tp.operations[1].position = position_middle; - - if ( opposite ) // opposite -> collinear - { - tp.operations[0].operation = operation_continue; - tp.operations[1].operation = operation_union; - tp.method = ip0.is_qj ? method_touch : method_touch_interior; - } - else + if (range_p.is_first_segment() && ip0.is_pi && ! ip0.is_qi ) // !q0i prevents duplication { - auto const sides = strategy.side(); - - // pi is the intersection point at qj or in the middle of q1 - // so consider segments - // 1. pi at qj: qi-qj-pj and qi-qj-qk - // x: qi-qj, y: qj-qk, qz: qk - // 2. pi in the middle of q1: qi-pi-pj and qi-pi-qj - // x: qi-pi, y: pi-qj, qz: qj - // qi-pi, side the same as WRT q1 - // pi-qj, side the same as WRT q1 - // qj WRT q1 is 0 - method_type replaced_method = method_none; - int side_pj_y = 0, side_pj_x = 0, side_qz_x = 0; - // 1. ip0 or pi at qj - if ( ip0.is_qj ) + TurnInfo tp = tp_model; + tp.operations[0].position = position_front; + tp.operations[1].position = position_middle; + + if ( opposite ) // opposite -> collinear { - replaced_method = method_touch; - side_pj_y = sides.apply(range_q.at(1), range_q.at(2), range_p.at(1)); // pj wrt q2 - side_pj_x = sides.apply(range_q.at(0), range_q.at(1), range_p.at(1)); // pj wrt q1 - side_qz_x = sides.apply(range_q.at(0), range_q.at(1), range_q.at(2)); // qk wrt q1 + tp.operations[0].operation = operation_continue; + tp.operations[1].operation = operation_union; + tp.method = ip0.is_qj ? method_touch : method_touch_interior; } - // 2. ip0 or pi in the middle of q1 else { - replaced_method = method_touch_interior; - side_pj_y = sides.apply(range_q.at(0), range_q.at(1), range_p.at(1)); // pj wrt q1 - side_pj_x = side_pj_y; // pj wrt q1 - side_qz_x = 0; // qj wrt q1 - } + auto const sides = strategy.side(); + + // pi is the intersection point at qj or in the middle of q1 + // so consider segments + // 1. pi at qj: qi-qj-pj and qi-qj-qk + // x: qi-qj, y: qj-qk, qz: qk + // 2. pi in the middle of q1: qi-pi-pj and qi-pi-qj + // x: qi-pi, y: pi-qj, qz: qj + // qi-pi, side the same as WRT q1 + // pi-qj, side the same as WRT q1 + // qj WRT q1 is 0 + method_type replaced_method = method_none; + int side_pj_y = 0, side_pj_x = 0, side_qz_x = 0; + // 1. ip0 or pi at qj + if ( ip0.is_qj ) + { + replaced_method = method_touch; + side_pj_y = sides.apply(range_q.at(1), range_q.at(2), range_p.at(1)); // pj wrt q2 + side_pj_x = sides.apply(range_q.at(0), range_q.at(1), range_p.at(1)); // pj wrt q1 + side_qz_x = sides.apply(range_q.at(0), range_q.at(1), range_q.at(2)); // qk wrt q1 + } + // 2. ip0 or pi in the middle of q1 + else + { + replaced_method = method_touch_interior; + side_pj_y = sides.apply(range_q.at(0), range_q.at(1), range_p.at(1)); // pj wrt q1 + side_pj_x = side_pj_y; // pj wrt q1 + side_qz_x = 0; // qj wrt q1 + } - std::pair operations - = get_info_e::operations_of_equal(side_pj_y, side_pj_x, side_qz_x); + std::pair operations + = get_info_e::operations_of_equal(side_pj_y, side_pj_x, side_qz_x); - tp.operations[0].operation = operations.first; - tp.operations[1].operation = operations.second; + tp.operations[0].operation = operations.first; + tp.operations[1].operation = operations.second; - turn_transformer_ec transformer(replaced_method); - transformer(tp); - } + turn_transformer_ec transformer(replaced_method); + transformer(tp); + } - // equals<> or collinear<> will assign the second point, - // we'd like to assign the first one - base_turn_handler::assign_point(tp, tp.method, inters.i_info(), 0); + // equals<> or collinear<> will assign the second point, + // we'd like to assign the first one + base_turn_handler::assign_point(tp, tp.method, inters.i_info(), 0); - // NOTE: is_collinear is not set for the first endpoint of L - // for which there is no preceding segment - // here is_p_first_ip == true - tp.operations[0].is_collinear = false; + // NOTE: is_collinear is not set for the first endpoint of L + // for which there is no preceding segment + // here is_p_first_ip == true + tp.operations[0].is_collinear = false; - *out++ = tp; + *out++ = tp; - was_first_point_handled = true; + was_first_point_handled = true; + } } // ANALYSE AND ASSIGN LAST // IP on the last point of Linear Geometry - if ( BOOST_GEOMETRY_CONDITION(EnableLast) - && range_p.is_last_segment() - && ( ip_count > 1 ? (ip1.is_pj && !ip1.is_qi) : (ip0.is_pj && !ip0.is_qi) ) ) // prevents duplication + if BOOST_GEOMETRY_CONSTEXPR (EnableLast) { - TurnInfo tp = tp_model; - - if ( inters.i_info().count > 1 ) + if (range_p.is_last_segment() + && (ip_count > 1 + ? (ip1.is_pj && ! ip1.is_qi) + : (ip0.is_pj && ! ip0.is_qi))) // prevents duplication { - //BOOST_GEOMETRY_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 ); - tp.operations[0].is_collinear = true; - tp.operations[1].operation = opposite ? operation_continue : operation_union; - } - else //if ( result.template get<0>().count == 1 ) - { - auto const sides = strategy.side(); - - // pj is the intersection point at qj or in the middle of q1 - // so consider segments - // 1. pj at qj: qi-qj-pi and qi-qj-qk - // x: qi-qj, y: qj-qk, qz: qk - // 2. pj in the middle of q1: qi-pj-pi and qi-pj-qj - // x: qi-pj, y: pj-qj, qz: qj - // qi-pj, the side is the same as WRT q1 - // pj-qj, the side is the same as WRT q1 - // side of qj WRT q1 is 0 - int side_pi_y = 0, side_pi_x = 0, side_qz_x = 0; - // 1. ip0 or pj at qj - if ( ip0.is_qj ) + TurnInfo tp = tp_model; + + if ( inters.i_info().count > 1 ) { - side_pi_y = sides.apply(range_q.at(1), range_q.at(2), range_p.at(0)); // pi wrt q2 - side_pi_x = sides.apply(range_q.at(0), range_q.at(1), range_p.at(0)); // pi wrt q1 - side_qz_x = sides.apply(range_q.at(0), range_q.at(1), range_q.at(2)); // qk wrt q1 + //BOOST_GEOMETRY_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 ); + tp.operations[0].is_collinear = true; + tp.operations[1].operation = opposite ? operation_continue : operation_union; } - // 2. ip0 or pj in the middle of q1 - else + else //if ( result.template get<0>().count == 1 ) { - side_pi_y = sides.apply(range_q.at(0), range_q.at(1), range_p.at(0)); // pi wrt q1 - side_pi_x = side_pi_y; // pi wrt q1 - side_qz_x = 0; // qj wrt q1 - } + auto const sides = strategy.side(); + + // pj is the intersection point at qj or in the middle of q1 + // so consider segments + // 1. pj at qj: qi-qj-pi and qi-qj-qk + // x: qi-qj, y: qj-qk, qz: qk + // 2. pj in the middle of q1: qi-pj-pi and qi-pj-qj + // x: qi-pj, y: pj-qj, qz: qj + // qi-pj, the side is the same as WRT q1 + // pj-qj, the side is the same as WRT q1 + // side of qj WRT q1 is 0 + int side_pi_y = 0, side_pi_x = 0, side_qz_x = 0; + // 1. ip0 or pj at qj + if ( ip0.is_qj ) + { + side_pi_y = sides.apply(range_q.at(1), range_q.at(2), range_p.at(0)); // pi wrt q2 + side_pi_x = sides.apply(range_q.at(0), range_q.at(1), range_p.at(0)); // pi wrt q1 + side_qz_x = sides.apply(range_q.at(0), range_q.at(1), range_q.at(2)); // qk wrt q1 + } + // 2. ip0 or pj in the middle of q1 + else + { + side_pi_y = sides.apply(range_q.at(0), range_q.at(1), range_p.at(0)); // pi wrt q1 + side_pi_x = side_pi_y; // pi wrt q1 + side_qz_x = 0; // qj wrt q1 + } - std::pair operations - = get_info_e::operations_of_equal(side_pi_y, side_pi_x, side_qz_x); + std::pair operations + = get_info_e::operations_of_equal(side_pi_y, side_pi_x, side_qz_x); - tp.operations[0].operation = operations.first; - tp.operations[1].operation = operations.second; + tp.operations[0].operation = operations.first; + tp.operations[1].operation = operations.second; - turn_transformer_ec transformer(method_none); - transformer(tp); + turn_transformer_ec transformer(method_none); + transformer(tp); - tp.operations[0].is_collinear = tp.both(operation_continue); - } + tp.operations[0].is_collinear = tp.both(operation_continue); + } - tp.method = ( ip_count > 1 ? ip1.is_qj : ip0.is_qj ) ? method_touch : method_touch_interior; - tp.operations[0].operation = operation_blocked; - tp.operations[0].position = position_back; - tp.operations[1].position = position_middle; + tp.method = ( ip_count > 1 ? ip1.is_qj : ip0.is_qj ) ? method_touch : method_touch_interior; + tp.operations[0].operation = operation_blocked; + tp.operations[0].position = position_back; + tp.operations[1].position = position_middle; - // equals<> or collinear<> will assign the second point, - // we'd like to assign the first one - unsigned int ip_index = ip_count > 1 ? 1 : 0; - base_turn_handler::assign_point(tp, tp.method, inters.i_info(), ip_index); + // equals<> or collinear<> will assign the second point, + // we'd like to assign the first one + unsigned int ip_index = ip_count > 1 ? 1 : 0; + base_turn_handler::assign_point(tp, tp.method, inters.i_info(), ip_index); - *out++ = tp; + *out++ = tp; - // don't ignore the first IP if the segment is opposite - return !( opposite && ip_count > 1 ) || was_first_point_handled; + // don't ignore the first IP if the segment is opposite + return !( opposite && ip_count > 1 ) || was_first_point_handled; + } } // don't ignore anything for now diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp index 6dbd6d682c..d0d1dfe5c6 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp @@ -1,11 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2017-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018. // Modifications copyright (c) 2013-2018 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, @@ -22,7 +21,7 @@ #include #include -#include +#include namespace boost { namespace geometry { @@ -264,8 +263,11 @@ struct get_turn_info_linear_linear tp.operations[0].operation, tp.operations[1].operation); - if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) - || ! append_opposite_spikes(tp, inters, out) ) + if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes) + { + *out++ = tp; + } + else if (! append_opposite_spikes(tp, inters, out)) { *out++ = tp; } @@ -307,10 +309,12 @@ struct get_turn_info_linear_linear transformer(tp); // conditionally handle spikes - if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) - || ! append_collinear_spikes(tp, inters, - method_touch, spike_op, - out) ) + if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes) + { + *out++ = tp; + } + else if (! append_collinear_spikes(tp, inters, method_touch, + spike_op, out)) { *out++ = tp; // no spikes } @@ -381,10 +385,12 @@ struct get_turn_info_linear_linear transformer(tp); // conditionally handle spikes - if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) - || ! append_collinear_spikes(tp, inters, - method_replace, spike_op, - out) ) + if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes) + { + *out++ = tp; + } + else if (! append_collinear_spikes(tp, inters, method_replace, + spike_op, out)) { // no spikes *out++ = tp; @@ -396,7 +402,7 @@ struct get_turn_info_linear_linear turn_transformer_ec transformer(method_touch_interior); // conditionally handle spikes - if ( BOOST_GEOMETRY_CONDITION(handle_spikes) ) + if BOOST_GEOMETRY_CONSTEXPR (handle_spikes) { append_opposite_spikes(tp, inters, out); } @@ -419,7 +425,7 @@ struct get_turn_info_linear_linear case '0' : { // degenerate points - if ( BOOST_GEOMETRY_CONDITION(AssignPolicy::include_degenerate) ) + if BOOST_GEOMETRY_CONSTEXPR (AssignPolicy::include_degenerate) { only_convert::apply(tp, inters.i_info()); @@ -553,65 +559,75 @@ struct get_turn_info_linear_linear bool res = false; - if ( is_p_spike - && ( BOOST_GEOMETRY_CONDITION(is_version_touches) - || inters.d_info().arrival[0] == 1 ) ) + if (is_p_spike) { - if ( BOOST_GEOMETRY_CONDITION(is_version_touches) ) + bool output_spike = false; + if BOOST_GEOMETRY_CONSTEXPR (is_version_touches) { tp.operations[0].is_collinear = true; tp.operations[1].is_collinear = false; tp.method = method_touch; + + output_spike = true; } - else // Version == append_collinear_opposite + else if (inters.d_info().arrival[0] == 1) // Version == append_collinear_opposite { tp.operations[0].is_collinear = true; tp.operations[1].is_collinear = false; BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1); - base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1); + + output_spike = true; } - tp.operations[0].operation = operation_blocked; - tp.operations[1].operation = operation_intersection; - *out++ = tp; - tp.operations[0].operation = operation_intersection; - //tp.operations[1].operation = operation_intersection; - *out++ = tp; + if (output_spike) + { + tp.operations[0].operation = operation_blocked; + tp.operations[1].operation = operation_intersection; + *out++ = tp; + tp.operations[0].operation = operation_intersection; + //tp.operations[1].operation = operation_intersection; + *out++ = tp; - res = true; + res = true; + } } - if ( is_q_spike - && ( BOOST_GEOMETRY_CONDITION(is_version_touches) - || inters.d_info().arrival[1] == 1 ) ) + if (is_q_spike) { - if ( BOOST_GEOMETRY_CONDITION(is_version_touches) ) + bool output_spike = false; + if BOOST_GEOMETRY_CONSTEXPR (is_version_touches) { tp.operations[0].is_collinear = false; tp.operations[1].is_collinear = true; tp.method = method_touch; + + output_spike = true; } - else // Version == append_collinear_opposite + else if (inters.d_info().arrival[1] == 1) // Version == append_collinear_opposite { tp.operations[0].is_collinear = false; tp.operations[1].is_collinear = true; BOOST_GEOMETRY_ASSERT(inters.i_info().count > 0); - base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 0); + + output_spike = true; } - tp.operations[0].operation = operation_intersection; - tp.operations[1].operation = operation_blocked; - *out++ = tp; - //tp.operations[0].operation = operation_intersection; - tp.operations[1].operation = operation_intersection; - *out++ = tp; + if (output_spike) + { + tp.operations[0].operation = operation_intersection; + tp.operations[1].operation = operation_blocked; + *out++ = tp; + //tp.operations[0].operation = operation_intersection; + tp.operations[1].operation = operation_intersection; + *out++ = tp; - res = true; + res = true; + } } return res; diff --git a/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp b/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp index b41697477d..5bb0d83e82 100644 --- a/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/handle_colocations.hpp @@ -1,11 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2017-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2017-2020. // Modifications copyright (c) 2017-2020 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, @@ -37,7 +36,7 @@ #include #include #include -#include +#include #if defined(BOOST_GEOMETRY_DEBUG_HANDLE_COLOCATIONS) # include @@ -97,7 +96,6 @@ inline void cleanup_clusters(Turns& turns, Clusters& clusters) } remove_clusters(turns, clusters); - colocate_clusters(clusters, turns); } template @@ -339,7 +337,7 @@ inline bool handle_colocations(Turns& turns, Clusters& clusters, // on turns which are discarded afterwards set_colocation(turns, clusters); - if (BOOST_GEOMETRY_CONDITION(target_operation == operation_intersection)) + if BOOST_GEOMETRY_CONSTEXPR (target_operation == operation_intersection) { discard_interior_exterior_turns < @@ -427,12 +425,12 @@ template typename Clusters, typename Geometry1, typename Geometry2, - typename SideStrategy + typename Strategy > inline void gather_cluster_properties(Clusters& clusters, Turns& turns, operation_type for_operation, Geometry1 const& geometry1, Geometry2 const& geometry2, - SideStrategy const& strategy) + Strategy const& strategy) { typedef typename boost::range_value::type turn_type; typedef typename turn_type::point_type point_type; @@ -442,7 +440,7 @@ inline void gather_cluster_properties(Clusters& clusters, Turns& turns, // right side typedef sort_by_side::side_sorter < - Reverse1, Reverse2, OverlayType, point_type, SideStrategy, std::less + Reverse1, Reverse2, OverlayType, point_type, Strategy, std::less > sbs_type; for (auto& pair : clusters) @@ -463,6 +461,21 @@ inline void gather_cluster_properties(Clusters& clusters, Turns& turns, cinfo.open_count = sbs.open_count(for_operation); + // Determine spikes + cinfo.spike_count = 0; + for (std::size_t i = 0; i + 1 < sbs.m_ranked_points.size(); i++) + { + auto const& current = sbs.m_ranked_points[i]; + auto const& next = sbs.m_ranked_points[i + 1]; + if (current.rank == next.rank + && current.direction == detail::overlay::sort_by_side::dir_from + && next.direction == detail::overlay::sort_by_side::dir_to) + { + // It leaves, from cluster point, and immediately returns. + cinfo.spike_count += 1; + } + } + bool const set_startable = OverlayType != overlay_dissolve; // Unset the startable flag for all 'closed' zones. This does not @@ -475,7 +488,8 @@ inline void gather_cluster_properties(Clusters& clusters, Turns& turns, turn_operation_type& op = turn.operations[ranked.operation_index]; if (set_startable - && for_operation == operation_union && cinfo.open_count == 0) + && for_operation == operation_union + && cinfo.open_count == 0) { op.enriched.startable = false; } @@ -495,11 +509,13 @@ inline void gather_cluster_properties(Clusters& clusters, Turns& turns, continue; } - if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_difference) - && is_self_turn(turn)) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_difference) { - // TODO: investigate - continue; + if (is_self_turn(turn)) + { + // TODO: investigate + continue; + } } if ((for_operation == operation_union diff --git a/include/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp b/include/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp index 4ad311277a..388c965446 100644 --- a/include/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp @@ -36,7 +36,7 @@ #include -#include +#include namespace boost { namespace geometry @@ -261,13 +261,15 @@ struct multipoint_multipoint_point { typedef geometry::less less_type; - if (BOOST_GEOMETRY_CONDITION(OverlayType != overlay_difference) - && boost::size(multipoint1) > boost::size(multipoint2)) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType != overlay_difference) { - return multipoint_multipoint_point - < - MultiPoint2, MultiPoint1, PointOut, OverlayType - >::apply(multipoint2, multipoint1, robust_policy, oit, strategy); + if (boost::size(multipoint1) > boost::size(multipoint2)) + { + return multipoint_multipoint_point + < + MultiPoint2, MultiPoint1, PointOut, OverlayType + >::apply(multipoint2, multipoint1, robust_policy, oit, strategy); + } } typedef typename boost::range_value::type point2_type; diff --git a/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp b/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp index 7e31a9fa9d..14f32beeda 100644 --- a/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/sort_by_side.hpp @@ -1,7 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2017-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2017-2023. // Modifications copyright (c) 2017-2023 Oracle and/or its affiliates. @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include @@ -39,35 +39,22 @@ namespace boost { namespace geometry namespace detail { namespace overlay { namespace sort_by_side { +// From means: from intersecting-segment-begin-point to cluster +// To means: from cluster to intersecting-segment-end-point enum direction_type { dir_unknown = -1, dir_from = 0, dir_to = 1 }; -typedef signed_size_type rank_type; - +using rank_type = signed_size_type; // Point-wrapper, adding some properties template struct ranked_point { - ranked_point() - : rank(0) - , turn_index(-1) - , operation_index(-1) - , direction(dir_unknown) - , count_left(0) - , count_right(0) - , operation(operation_none) - {} - ranked_point(Point const& p, signed_size_type ti, int oi, direction_type d, operation_type op, segment_identifier const& si) : point(p) - , rank(0) - , zone(-1) , turn_index(ti) , operation_index(oi) , direction(d) - , count_left(0) - , count_right(0) , operation(op) , seg_id(si) {} @@ -75,14 +62,19 @@ struct ranked_point using point_type = Point; Point point; - rank_type rank; - signed_size_type zone; // index of closed zone, in uu turn there would be 2 zones - signed_size_type turn_index; - int operation_index; // 0,1 - direction_type direction; - std::size_t count_left; - std::size_t count_right; - operation_type operation; + rank_type rank{0}; + signed_size_type zone{-1}; // index of closed zone, in uu turn there would be 2 zones + signed_size_type turn_index{-1}; + int operation_index{-1}; // 0,1 + direction_type direction{dir_unknown}; + + // The number of polygons on the left side + std::size_t count_left{0}; + + // The number of polygons on the right side + std::size_t count_right{0}; + + operation_type operation{operation_none}; segment_identifier seg_id; }; @@ -91,10 +83,8 @@ struct less_by_turn_index template inline bool operator()(T const& first, T const& second) const { - return first.turn_index == second.turn_index - ? first.index < second.index - : first.turn_index < second.turn_index - ; + return std::tie(first.turn_index, first.index) + < std::tie(second.turn_index, second.index); } }; @@ -103,20 +93,13 @@ struct less_by_index template inline bool operator()(T const& first, T const& second) const { - // Length might be considered too - // First order by from/to - if (first.direction != second.direction) - { - return first.direction < second.direction; - } + // First order by direction (from/to) // Then by turn index - if (first.turn_index != second.turn_index) - { - return first.turn_index < second.turn_index; - } // This can also be the same (for example in buffer), but seg_id is // never the same - return first.seg_id < second.seg_id; + // (Length might be considered too) + return std::tie(first.direction, first.turn_index, first.seg_id) + < std::tie(second.direction, second.turn_index, second.seg_id); } }; @@ -129,10 +112,10 @@ struct less_false } }; -template +template struct less_by_side { - less_by_side(PointOrigin const& p1, PointTurn const& p2, SideStrategy const& strategy) + less_by_side(PointOrigin const& p1, PointTurn const& p2, Strategy const& strategy) : m_origin(p1) , m_turn_point(p2) , m_strategy(strategy) @@ -141,13 +124,14 @@ struct less_by_side template inline bool operator()(T const& first, T const& second) const { - typedef typename SideStrategy::cs_tag cs_tag; + using cs_tag = typename Strategy::cs_tag; LessOnSame on_same; Compare compare; - int const side_first = m_strategy.apply(m_origin, m_turn_point, first.point); - int const side_second = m_strategy.apply(m_origin, m_turn_point, second.point); + auto const side_strategy = m_strategy.side(); + int const side_first = side_strategy.apply(m_origin, m_turn_point, first.point); + int const side_second = side_strategy.apply(m_origin, m_turn_point, second.point); if (side_first == 0 && side_second == 0) { @@ -187,14 +171,14 @@ struct less_by_side // They are both left, both right, and/or both collinear (with each other and/or with p1,p2) // Check mutual side - int const side_second_wrt_first = m_strategy.apply(m_turn_point, first.point, second.point); + int const side_second_wrt_first = side_strategy.apply(m_turn_point, first.point, second.point); if (side_second_wrt_first == 0) { return on_same(first, second); } - int const side_first_wrt_second = m_strategy.apply(m_turn_point, second.point, first.point); + int const side_first_wrt_second = side_strategy.apply(m_turn_point, second.point, first.point); if (side_second_wrt_first != -side_first_wrt_second) { // (FP) accuracy error in side calculation, the sides are not opposite. @@ -213,22 +197,28 @@ struct less_by_side private : PointOrigin const& m_origin; PointTurn const& m_turn_point; - SideStrategy const& m_strategy; + + // Umbrella strategy containing side strategy + Strategy const& m_strategy; }; // Sorts vectors in counter clockwise order (by default) +// Purposes: +// - from one entry vector, find the next exit vector +// - find the open counts +// - find zones template < bool Reverse1, bool Reverse2, overlay_type OverlayType, typename Point, - typename SideStrategy, + typename Strategy, typename Compare > struct side_sorter { - typedef ranked_point rp; + using rp = ranked_point; private : struct include_union @@ -254,7 +244,7 @@ private : }; public : - side_sorter(SideStrategy const& strategy) + side_sorter(Strategy const& strategy) : m_origin_count(0) , m_origin_segment_distance(0) , m_strategy(strategy) @@ -289,6 +279,17 @@ public : Point const& point_from, Point const& point_to, Operation const& op, bool is_origin) { + // The segment is added in two parts (sub-segment). + // In picture: + // + // from -----> * -----> to + // + // where * means: cluster point (intersection point) + // from means: start point of original segment + // to means: end point of original segment + // So from/to is from the perspective of the segment. + // From the perspective of the cluster, it is the other way round + // (from means: from-segment-to-cluster, to means: from-cluster-to-segment) add_segment_from(turn_index, op_index, point_from, op, is_origin); add_segment_to(turn_index, op_index, point_to, op); } @@ -356,7 +357,7 @@ public : Geometry2 const& geometry2, bool is_departure) { - Point potential_origin = add(turn, op, turn_index, op_index, geometry1, geometry2, false); + auto const potential_origin = add(turn, op, turn_index, op_index, geometry1, geometry2, false); if (is_departure) { @@ -392,8 +393,8 @@ public : // to give colinear points // Sort by side and assign rank - less_by_side less_unique(m_origin, turn_point, m_strategy); - less_by_side less_non_unique(m_origin, turn_point, m_strategy); + less_by_side less_unique(m_origin, turn_point, m_strategy); + less_by_side less_non_unique(m_origin, turn_point, m_strategy); std::sort(m_ranked_points.begin(), m_ranked_points.end(), less_unique); @@ -458,7 +459,7 @@ public : void find_open() { - if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_buffer)) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_buffer) { find_open_by_piece_index(); } @@ -512,12 +513,14 @@ public : //private : - typedef std::vector container_type; + using container_type = std::vector; container_type m_ranked_points; Point m_origin; std::size_t m_origin_count; signed_size_type m_origin_segment_distance; - SideStrategy m_strategy; + + // Umbrella strategy containing side strategy + Strategy m_strategy; private : @@ -724,13 +727,13 @@ struct side_compare {}; template <> struct side_compare { - typedef std::greater type; + using type = std::greater; }; template <> struct side_compare { - typedef std::less type; + using type = std::less; }; diff --git a/include/boost/geometry/algorithms/detail/overlay/traversal.hpp b/include/boost/geometry/algorithms/detail/overlay/traversal.hpp index 82cfb86a83..f79e97365e 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traversal.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traversal.hpp @@ -1,10 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2023-2024 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2017-2020. // Modifications copyright (c) 2017-2020 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, @@ -27,7 +27,7 @@ #include #include #include -#include +#include #if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) \ || defined(BOOST_GEOMETRY_OVERLAY_REPORT_WKT) \ @@ -84,7 +84,7 @@ template typename Turns, typename Clusters, typename RobustPolicy, - typename SideStrategy, + typename Strategy, typename Visitor > struct traversal @@ -101,13 +101,13 @@ private : typedef sort_by_side::side_sorter < Reverse1, Reverse2, OverlayType, - point_type, SideStrategy, side_compare_type + point_type, Strategy, side_compare_type > sbs_type; public : inline traversal(Geometry1 const& geometry1, Geometry2 const& geometry2, Turns& turns, Clusters const& clusters, - RobustPolicy const& robust_policy, SideStrategy const& strategy, + RobustPolicy const& robust_policy, Strategy const& strategy, Visitor& visitor) : m_geometry1(geometry1) , m_geometry2(geometry2) @@ -233,23 +233,25 @@ public : { // For uu/ii, only switch sources if indicated - if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_buffer)) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_buffer) { // Buffer does not use source_index (always 0). return select_source_generic<&segment_identifier::multi_index>( turn, candidate_seg_id, previous_seg_id); } - - if (is_self_turn(turn)) + else // else prevents unreachable code warning { - // Also, if it is a self-turn, stay on same ring (multi/ring) - return select_source_generic<&segment_identifier::multi_index>( + if (is_self_turn(turn)) + { + // Also, if it is a self-turn, stay on same ring (multi/ring) + return select_source_generic<&segment_identifier::multi_index>( + turn, candidate_seg_id, previous_seg_id); + } + + // Use source_index + return select_source_generic<&segment_identifier::source_index>( turn, candidate_seg_id, previous_seg_id); } - - // Use source_index - return select_source_generic<&segment_identifier::source_index>( - turn, candidate_seg_id, previous_seg_id); } inline bool traverse_possible(signed_size_type turn_index) const @@ -342,25 +344,27 @@ public : return true; } - if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_buffer) - && possible[0] && possible[1]) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_buffer) { - // Buffers sometimes have multiple overlapping pieces, where remaining - // distance could lead to the wrong choice. Take the matching operation. - - bool is_target[2] = {0}; - for (int i = 0; i < 2; i++) + if (possible[0] && possible[1]) { - turn_operation_type const& next_op = m_turns[next[i]].operations[i]; - is_target[i] = next_op.operation == target_operation; - } + // Buffers sometimes have multiple overlapping pieces, where remaining + // distance could lead to the wrong choice. Take the matching operation. - if (is_target[0] != is_target[1]) - { - // Take the matching operation - selected_op_index = is_target[0] ? 0 : 1; - debug_traverse(turn, turn.operations[selected_op_index], "Candidate cc target"); - return true; + bool is_target[2] = {0}; + for (int i = 0; i < 2; i++) + { + turn_operation_type const& next_op = m_turns[next[i]].operations[i]; + is_target[i] = next_op.operation == target_operation; + } + + if (is_target[0] != is_target[1]) + { + // Take the matching operation + selected_op_index = is_target[0] ? 0 : 1; + debug_traverse(turn, turn.operations[selected_op_index], "Candidate cc target"); + return true; + } } } @@ -517,7 +521,7 @@ public : result = select_cc_operation(turn, start_turn_index, selected_op_index); } - else if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_dissolve)) + else if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_dissolve) { result = select_preferred_operation(turn, turn_index, start_turn_index, selected_op_index); @@ -559,16 +563,18 @@ public : return true; } + // Returns a priority, the one with the highst priority will be selected + // 0: not OK + // 1: OK following spike out + // 2: OK but next turn is in same cluster + // 3: OK + // 4: OK and start turn matches + // 5: OK and start turn and start operation both match, this is the best inline int priority_of_turn_in_cluster_union(sort_by_side::rank_type selected_rank, typename sbs_type::rp const& ranked_point, - std::set const& cluster_indices, + cluster_info const& cinfo, signed_size_type start_turn_index, int start_op_index) const { - // Returns 0: not OK - // Returns 1: OK but next turn is in same cluster - // Returns 2: OK - // Returns 3: OK and start turn matches - // Returns 4: OK and start turn and start op both match if (ranked_point.rank != selected_rank || ranked_point.direction != sort_by_side::dir_to) { @@ -584,24 +590,30 @@ public : return 0; } - if (BOOST_GEOMETRY_CONDITION(OverlayType != overlay_dissolve) - && (op.enriched.count_left != 0 || op.enriched.count_right == 0)) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType != overlay_dissolve) { - // Check counts: in some cases interior rings might be generated with - // polygons on both sides. For dissolve it can be anything. - return 0; + if (op.enriched.count_left != 0 || op.enriched.count_right == 0) + { + // Check counts: in some cases interior rings might be generated with + // polygons on both sides. For dissolve it can be anything. + + // If this forms a spike, going to/from the cluster point in the same + // (opposite) direction, it can still be used. + return cinfo.spike_count > 0 ? 1 : 0; + } } bool const to_start = ranked_point.turn_index == start_turn_index; bool const to_start_index = ranked_point.operation_index == start_op_index; bool const next_in_same_cluster - = cluster_indices.count(op.enriched.get_next_turn_index()) > 0; + = cinfo.turn_indices.count(op.enriched.get_next_turn_index()) > 0; - return to_start && to_start_index ? 4 - : to_start ? 3 - : next_in_same_cluster ? 1 - : 2 + // Return the priority as described above + return to_start && to_start_index ? 5 + : to_start ? 4 + : next_in_same_cluster ? 2 + : 3 ; } @@ -647,7 +659,7 @@ public : } inline bool select_from_cluster_union(signed_size_type& turn_index, - std::set const& cluster_indices, + cluster_info const& cinfo, int& op_index, sbs_type const& sbs, signed_size_type start_turn_index, int start_op_index) const { @@ -656,7 +668,7 @@ public : int current_priority = 0; for (std::size_t i = 1; i < sbs.m_ranked_points.size(); i++) { - typename sbs_type::rp const& ranked_point = sbs.m_ranked_points[i]; + auto const& ranked_point = sbs.m_ranked_points[i]; if (ranked_point.rank > selected_rank) { @@ -664,7 +676,7 @@ public : } int const priority = priority_of_turn_in_cluster_union(selected_rank, - ranked_point, cluster_indices, start_turn_index, start_op_index); + ranked_point, cinfo, start_turn_index, start_op_index); if (priority > current_priority) { @@ -791,6 +803,27 @@ public : return false; } + if BOOST_GEOMETRY_CONSTEXPR (is_union) + { + if (cinfo.open_count == 0 && cinfo.spike_count > 0) + { + // Leave the cluster from the spike. + for (std::size_t i = 0; i + 1 < sbs.m_ranked_points.size(); i++) + { + auto const& current = sbs.m_ranked_points[i]; + auto const& next = sbs.m_ranked_points[i + 1]; + if (current.rank == next.rank + && current.direction == detail::overlay::sort_by_side::dir_from + && next.direction == detail::overlay::sort_by_side::dir_to) + { + turn_index = next.turn_index; + op_index = next.operation_index; + return true; + } + } + } + } + cluster_exits exits(m_turns, cinfo.turn_indices, sbs); if (exits.apply(turn_index, op_index)) @@ -800,9 +833,9 @@ public : bool result = false; - if (is_union) + if BOOST_GEOMETRY_CONSTEXPR (is_union) { - result = select_from_cluster_union(turn_index, cinfo.turn_indices, + result = select_from_cluster_union(turn_index, cinfo, op_index, sbs, start_turn_index, start_op_index); if (! result) @@ -852,56 +885,58 @@ public : turn_operation_type const& start_op, int start_op_index) const { - if (BOOST_GEOMETRY_CONDITION(OverlayType != overlay_buffer - && OverlayType != overlay_dissolve)) + if BOOST_GEOMETRY_CONSTEXPR (OverlayType != overlay_buffer + && OverlayType != overlay_dissolve) { return; } - - const bool allow_uu = OverlayType != overlay_buffer; - - // It travels to itself, can happen. If this is a buffer, it can - // sometimes travel to itself in the following configuration: - // - // +---->--+ - // | | - // | +---*----+ *: one turn, with segment index 2/7 - // | | | | - // | +---C | C: closing point (start/end) - // | | - // +------------+ - // - // If it starts on segment 2 and travels to itself on segment 2, that - // should be corrected to 7 because that is the shortest path - // - // Also a uu turn (touching with another buffered ring) might have this - // apparent configuration, but there it should - // always travel the whole ring - - turn_operation_type const& other_op - = start_turn.operations[1 - start_op_index]; - - bool const correct - = (allow_uu || ! start_turn.both(operation_union)) - && start_op.seg_id.source_index == other_op.seg_id.source_index - && start_op.seg_id.multi_index == other_op.seg_id.multi_index - && start_op.seg_id.ring_index == other_op.seg_id.ring_index - && start_op.seg_id.segment_index == to_vertex_index; + else // else prevents unreachable code warning + { + const bool allow_uu = OverlayType != overlay_buffer; + + // It travels to itself, can happen. If this is a buffer, it can + // sometimes travel to itself in the following configuration: + // + // +---->--+ + // | | + // | +---*----+ *: one turn, with segment index 2/7 + // | | | | + // | +---C | C: closing point (start/end) + // | | + // +------------+ + // + // If it starts on segment 2 and travels to itself on segment 2, that + // should be corrected to 7 because that is the shortest path + // + // Also a uu turn (touching with another buffered ring) might have this + // apparent configuration, but there it should + // always travel the whole ring + + turn_operation_type const& other_op + = start_turn.operations[1 - start_op_index]; + + bool const correct + = (allow_uu || ! start_turn.both(operation_union)) + && start_op.seg_id.source_index == other_op.seg_id.source_index + && start_op.seg_id.multi_index == other_op.seg_id.multi_index + && start_op.seg_id.ring_index == other_op.seg_id.ring_index + && start_op.seg_id.segment_index == to_vertex_index; #if defined(BOOST_GEOMETRY_DEBUG_TRAVERSE) - std::cout << " WARNING: self-buffer " - << " correct=" << correct - << " turn=" << operation_char(start_turn.operations[0].operation) - << operation_char(start_turn.operations[1].operation) - << " start=" << start_op.seg_id.segment_index - << " from=" << to_vertex_index - << " to=" << other_op.enriched.travels_to_vertex_index - << std::endl; + std::cout << " WARNING: self-buffer " + << " correct=" << correct + << " turn=" << operation_char(start_turn.operations[0].operation) + << operation_char(start_turn.operations[1].operation) + << " start=" << start_op.seg_id.segment_index + << " from=" << to_vertex_index + << " to=" << other_op.enriched.travels_to_vertex_index + << std::endl; #endif - if (correct) - { - to_vertex_index = other_op.enriched.travels_to_vertex_index; + if (correct) + { + to_vertex_index = other_op.enriched.travels_to_vertex_index; + } } } @@ -960,7 +995,7 @@ public : = has_points && current_turn.is_clustered() && m_turns[start_turn_index].cluster_id == current_turn.cluster_id; - if (BOOST_GEOMETRY_CONDITION(target_operation == operation_intersection)) + if BOOST_GEOMETRY_CONSTEXPR (target_operation == operation_intersection) { // Intersection or difference @@ -1037,7 +1072,7 @@ private : Turns& m_turns; Clusters const& m_clusters; RobustPolicy const& m_robust_policy; - SideStrategy m_strategy; + Strategy m_strategy; Visitor& m_visitor; }; diff --git a/include/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp b/include/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp index 692de7345a..e3ee6bb23b 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp @@ -56,7 +56,7 @@ struct traversal_ring_creator Reverse1, Reverse2, OverlayType, Geometry1, Geometry2, Turns, Clusters, RobustPolicy, - decltype(std::declval().side()), + Strategy, Visitor > traversal_type; @@ -72,7 +72,7 @@ struct traversal_ring_creator Strategy const& strategy, RobustPolicy const& robust_policy, Visitor& visitor) : m_trav(geometry1, geometry2, turns, clusters, - robust_policy, strategy.side(), visitor) + robust_policy, strategy, visitor) , m_geometry1(geometry1) , m_geometry2(geometry2) , m_turns(turns) diff --git a/include/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp b/include/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp index 1858c9ec2a..82e32acdda 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traversal_switch_detector.hpp @@ -1,10 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2015-2016 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2018-2020. // Modifications copyright (c) 2018-2020 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, @@ -26,7 +26,7 @@ #include #endif -#include +#include #include #include @@ -391,11 +391,19 @@ struct traversal_switch_detector { for (turn_type& turn : m_turns) { + constexpr auto order1 = geometry::point_order::value; + constexpr bool reverse1 = (order1 == boost::geometry::counterclockwise) + ? ! Reverse1 : Reverse1; + + constexpr auto order2 = geometry::point_order::value; + constexpr bool reverse2 = (order2 == boost::geometry::counterclockwise) + ? ! Reverse2 : Reverse2; + // For difference, for the input walked through in reverse, // the meaning is reversed: what is isolated is actually not, // and vice versa. bool const reverseMeaningInTurn - = (Reverse1 || Reverse2) + = (reverse1 || reverse2) && ! turn.is_self() && ! turn.is_clustered() && uu_or_ii(turn) @@ -409,8 +417,8 @@ struct traversal_switch_detector { bool const reverseMeaningInOp = reverseMeaningInTurn - && ((op.seg_id.source_index == 0 && Reverse1) - || (op.seg_id.source_index == 1 && Reverse2)); + && ((op.seg_id.source_index == 0 && reverse1) + || (op.seg_id.source_index == 1 && reverse2)); // It is assigned to isolated if it's property is "Yes", // (one connected interior, or chained). @@ -525,19 +533,21 @@ struct traversal_switch_detector return ! uu_or_ii(turn); } - if (BOOST_GEOMETRY_CONDITION(target_operation == operation_union)) + if BOOST_GEOMETRY_CONSTEXPR (target_operation == operation_union) { // It is a cluster, check zones // (assigned by sort_by_side/handle colocations) of both operations return turn.operations[0].enriched.zone == turn.operations[1].enriched.zone; } - - // For an intersection, two regions connect if they are not ii - // (ii-regions are isolated) or, in some cases, not iu (for example - // when a multi-polygon is inside an interior ring and connecting it) - return ! (turn.both(operation_intersection) - || turn.combination(operation_intersection, operation_union)); + else // else prevents unreachable code warning + { + // For an intersection, two regions connect if they are not ii + // (ii-regions are isolated) or, in some cases, not iu (for example + // when a multi-polygon is inside an interior ring and connecting it) + return ! (turn.both(operation_intersection) + || turn.combination(operation_intersection, operation_union)); + } } void create_region(signed_size_type& new_region_id, ring_identifier const& ring_id, @@ -682,11 +692,13 @@ struct traversal_switch_detector { turn_type const& turn = m_turns[turn_index]; - if (turn.discarded - && BOOST_GEOMETRY_CONDITION(target_operation == operation_intersection)) + if BOOST_GEOMETRY_CONSTEXPR (target_operation == operation_intersection) { - // Discarded turn (union currently still needs it to determine regions) - continue; + if (turn.discarded) + { + // Discarded turn (union currently still needs it to determine regions) + continue; + } } for (auto const& op : turn.operations) diff --git a/include/boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp b/include/boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp index e5ba6e30d8..9d2a6b7f52 100644 --- a/include/boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp +++ b/include/boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp @@ -3,11 +3,10 @@ // 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) 2013-2015 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2013-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2015, 2017, 2019. // Modifications copyright (c) 2015-2019 Oracle and/or its affiliates. - // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -23,7 +22,7 @@ #include #include #include -#include +#include #include @@ -85,30 +84,27 @@ inline bool point_is_spike_or_equal(Point1 const& last_point, return true; } - if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled)) + if BOOST_GEOMETRY_CONSTEXPR (! RobustPolicy::enabled) { return false; } - - // Try using specified robust policy - typedef typename geometry::robust_point_type - < - Point1, - RobustPolicy - >::type robust_point_type; - - robust_point_type last_point_rob, segment_a_rob, segment_b_rob; - geometry::recalculate(last_point_rob, last_point, robust_policy); - geometry::recalculate(segment_a_rob, segment_a, robust_policy); - geometry::recalculate(segment_b_rob, segment_b, robust_policy); - - return point_is_spike_or_equal - ( - last_point_rob, - segment_a_rob, - segment_b_rob, - strategy - ); + else // else prevents unreachable code warning + { + // Try using specified robust policy + using robust_point_type = typename geometry::robust_point_type + < + Point1, + RobustPolicy + >::type; + + robust_point_type last_point_rob, segment_a_rob, segment_b_rob; + geometry::recalculate(last_point_rob, last_point, robust_policy); + geometry::recalculate(segment_a_rob, segment_a, robust_policy); + geometry::recalculate(segment_b_rob, segment_b, robust_policy); + + return point_is_spike_or_equal(last_point_rob, segment_a_rob, segment_b_rob, + strategy); + } } template @@ -133,25 +129,27 @@ inline bool point_is_collinear(Point1 const& last_point, // This part (or whole method, because it is then trivial) // will be removed after rescaling - if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled)) + if BOOST_GEOMETRY_CONSTEXPR (! RobustPolicy::enabled) { return false; } - - // Redo, using specified robust policy - typedef typename geometry::robust_point_type - < - Point1, - RobustPolicy - >::type robust_point_type; - - robust_point_type last_point_rob, segment_a_rob, segment_b_rob; - geometry::recalculate(last_point_rob, last_point, robust_policy); - geometry::recalculate(segment_a_rob, segment_a, robust_policy); - geometry::recalculate(segment_b_rob, segment_b, robust_policy); - - int const side_rob = strategy.apply(segment_a_rob, segment_b_rob, last_point_rob); - return side_rob == 0; + else // else prevents unreachable code warning + { + // Redo, using specified robust policy + using robust_point_type = typename geometry::robust_point_type + < + Point1, + RobustPolicy + >::type; + + robust_point_type last_point_rob, segment_a_rob, segment_b_rob; + geometry::recalculate(last_point_rob, last_point, robust_policy); + geometry::recalculate(segment_a_rob, segment_a, robust_policy); + geometry::recalculate(segment_b_rob, segment_b, robust_policy); + + int const side_rob = strategy.apply(segment_a_rob, segment_b_rob, last_point_rob); + return side_rob == 0; + } } diff --git a/include/boost/geometry/algorithms/detail/recalculate.hpp b/include/boost/geometry/algorithms/detail/recalculate.hpp index eb633c9c2f..79f6a4eb1e 100644 --- a/include/boost/geometry/algorithms/detail/recalculate.hpp +++ b/include/boost/geometry/algorithms/detail/recalculate.hpp @@ -21,8 +21,6 @@ #include #include -#include -#include #include #include #include diff --git a/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp b/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp index 41366e3167..3a2b307858 100644 --- a/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp +++ b/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp @@ -31,6 +31,8 @@ #include +#include + namespace boost { namespace geometry { @@ -836,7 +838,7 @@ struct areal_areal segment_identifier const& seg_id = turn.operations[OpId].seg_id; signed_size_type - count = boost::numeric_cast( + count = util::numeric_cast( geometry::num_interior_rings( detail::single_geometry(analyser.geometry, seg_id))); diff --git a/include/boost/geometry/algorithms/detail/relate/follow_helpers.hpp b/include/boost/geometry/algorithms/detail/relate/follow_helpers.hpp index 39d27da01e..7bea322748 100644 --- a/include/boost/geometry/algorithms/detail/relate/follow_helpers.hpp +++ b/include/boost/geometry/algorithms/detail/relate/follow_helpers.hpp @@ -30,6 +30,7 @@ #include #include +#include #include @@ -42,10 +43,12 @@ namespace detail { namespace relate { // NOTE: This iterates through single geometries for which turns were not generated. // It doesn't mean that the geometry is disjoint, only that no turns were detected. -template ::type, - bool IsMulti = std::is_base_of::value +template +< + std::size_t OpId, + typename Geometry, + typename Tag = typename geometry::tag::type, + bool IsMulti = util::is_multi::value > struct for_each_disjoint_geometry_if : public not_implemented diff --git a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp index 1e35e64fc5..1dfea74903 100644 --- a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp +++ b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp @@ -17,25 +17,20 @@ #include #include -#include -#include - -#include -#include -#include - -#include #include -#include -#include - -#include -#include #include #include - +#include +#include +#include +#include +#include +#include +#include #include - +#include +#include +#include #include namespace boost { namespace geometry @@ -854,30 +849,30 @@ struct linear_areal m_exit_watcher.reset_detected_exit(); } - if ( BOOST_GEOMETRY_CONDITION( util::is_multi::value ) - && m_first_from_unknown ) + if BOOST_GEOMETRY_CONSTEXPR (util::is_multi::value) { - // For MultiPolygon many x/u operations may be generated as a first IP - // if for all turns x/u was generated and any of the Polygons doesn't contain the LineString - // then we know that the LineString is outside - // Similar with the u/u turns, if it was the first one it doesn't mean that the - // Linestring came from the exterior - if ( ( m_previous_operation == overlay::operation_blocked - && ( op != overlay::operation_blocked // operation different than block - || seg_id.multi_index != m_previous_turn_ptr->operations[op_id].seg_id.multi_index ) ) // or the next single-geometry - || ( m_previous_operation == overlay::operation_union - && ! turn_on_the_same_ip(*m_previous_turn_ptr, *it, - strategy) ) - ) + if (m_first_from_unknown) { - update(res); - if ( m_first_from_unknown_boundary_detected ) + // For MultiPolygon many x/u operations may be generated as a first IP + // if for all turns x/u was generated and any of the Polygons doesn't contain the LineString + // then we know that the LineString is outside + // Similar with the u/u turns, if it was the first one it doesn't mean that the + // Linestring came from the exterior + if ((m_previous_operation == overlay::operation_blocked + && (op != overlay::operation_blocked // operation different than block + || seg_id.multi_index != m_previous_turn_ptr->operations[op_id].seg_id.multi_index)) // or the next single-geometry + || (m_previous_operation == overlay::operation_union + && ! turn_on_the_same_ip(*m_previous_turn_ptr, *it, strategy))) { - update(res); - } + update(res); + if ( m_first_from_unknown_boundary_detected ) + { + update(res); + } - m_first_from_unknown = false; - m_first_from_unknown_boundary_detected = false; + m_first_from_unknown = false; + m_first_from_unknown_boundary_detected = false; + } } } @@ -1037,7 +1032,7 @@ struct linear_areal } } - if ( BOOST_GEOMETRY_CONDITION( util::is_multi::value ) ) + if BOOST_GEOMETRY_CONSTEXPR (util::is_multi::value) { m_first_from_unknown = false; m_first_from_unknown_boundary_detected = false; @@ -1123,9 +1118,9 @@ struct linear_areal } else { - if ( BOOST_GEOMETRY_CONDITION( util::is_multi::value ) + if BOOST_GEOMETRY_CONSTEXPR (util::is_multi::value) /*&& ( op == overlay::operation_blocked - || op == overlay::operation_union )*/ ) // if we're here it's u or x + || op == overlay::operation_union )*/ // if we're here it's u or x { m_first_from_unknown = true; } @@ -1150,9 +1145,9 @@ struct linear_areal } else { - if ( BOOST_GEOMETRY_CONDITION( util::is_multi::value ) + if BOOST_GEOMETRY_CONSTEXPR (util::is_multi::value) /*&& ( op == overlay::operation_blocked - || op == overlay::operation_union )*/ ) // if we're here it's u or x + || op == overlay::operation_union )*/ // if we're here it's u or x { BOOST_GEOMETRY_ASSERT(m_first_from_unknown); m_first_from_unknown_boundary_detected = true; @@ -1200,18 +1195,20 @@ struct linear_areal // For MultiPolygon many x/u operations may be generated as a first IP // if for all turns x/u was generated and any of the Polygons doesn't contain the LineString // then we know that the LineString is outside - if ( BOOST_GEOMETRY_CONDITION( util::is_multi::value ) - && m_first_from_unknown ) + if BOOST_GEOMETRY_CONSTEXPR (util::is_multi::value) { - update(res); - if ( m_first_from_unknown_boundary_detected ) + if (m_first_from_unknown) { - update(res); - } + update(res); + if ( m_first_from_unknown_boundary_detected ) + { + update(res); + } - // done below - //m_first_from_unknown = false; - //m_first_from_unknown_boundary_detected = false; + // done below + //m_first_from_unknown = false; + //m_first_from_unknown_boundary_detected = false; + } } // here, the possible exit is the real one diff --git a/include/boost/geometry/algorithms/detail/relate/point_point.hpp b/include/boost/geometry/algorithms/detail/relate/point_point.hpp index 9e8ccaca23..1348c0dc63 100644 --- a/include/boost/geometry/algorithms/detail/relate/point_point.hpp +++ b/include/boost/geometry/algorithms/detail/relate/point_point.hpp @@ -1,10 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2023-2024 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2013-2022. // Modifications copyright (c) 2013-2023, 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 @@ -197,10 +197,12 @@ struct multipoint_multipoint || relate::may_update(result) ) { // NlogN + MlogN - bool is_disjoint = search(first_sorted_mpt, first_iterated_mpt, result); + bool const is_disjoint = search(first_sorted_mpt, first_iterated_mpt, result); - if ( BOOST_GEOMETRY_CONDITION(is_disjoint || result.interrupt) ) + if (is_disjoint || BOOST_GEOMETRY_CONDITION(result.interrupt) ) + { return; + } } if ( relate::may_update(result) diff --git a/include/boost/geometry/algorithms/detail/relate/result.hpp b/include/boost/geometry/algorithms/detail/relate/result.hpp index 84c342e636..de982c37a8 100644 --- a/include/boost/geometry/algorithms/detail/relate/result.hpp +++ b/include/boost/geometry/algorithms/detail/relate/result.hpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include namespace boost { namespace geometry { @@ -292,15 +292,18 @@ struct interrupt_dispatch template static inline bool check_element(char m) { - if ( BOOST_GEOMETRY_CONDITION(V >= '0' && V <= '9') ) + if BOOST_GEOMETRY_CONSTEXPR (V >= '0' && V <= '9') { return m == 'F' || ( m < V && m >= '0' && m <= '9' ); } - else if ( BOOST_GEOMETRY_CONDITION(V == 'T') ) + else if BOOST_GEOMETRY_CONSTEXPR (V == 'T') { return m == 'F'; } - return false; + else + { + return false; + } } }; diff --git a/include/boost/geometry/algorithms/detail/sections/sectionalize.hpp b/include/boost/geometry/algorithms/detail/sections/sectionalize.hpp index 3317ff70a9..d9cd958857 100644 --- a/include/boost/geometry/algorithms/detail/sections/sectionalize.hpp +++ b/include/boost/geometry/algorithms/detail/sections/sectionalize.hpp @@ -721,24 +721,31 @@ struct sectionalize_multi template inline void enlarge_sections(Sections& sections, Strategy const&) { - // Expand the box to avoid missing any intersection. The amount is - // should be larger than epsilon. About the value itself: the smaller - // it is, the higher the risk to miss intersections. The larger it is, - // the more comparisons are made, which is not harmful for the result - // (but it might be for the performance). - // So it should be on the high side. - - // Use a compilable and workable epsilon for all types, for example: + // Expand the box to avoid missing any intersection. + // About the value itself: the smaller it is, + // the higher the risk to miss intersections. + // The larger it is, the more comparisons are made, + // which is not harmful for the result, + // but it might be for the performance. + // So it should be on the higher side. + // + // The current value: // - for double :~ 2.22e-13 // - for float :~ 1e-4 // - for Boost.Multiprecision (50) :~ 5.35e-48 // - for Boost.Rational : 0/1 + // WARNING: don't use decltype here. + // Earlier code used decltype(section.bonding_box) below, + // but that somehow is not accepted by the NVCC (CUDA 12.4) compiler. + using section_t = typename boost::range_value::type; + using box_t = typename section_t::box_type; + using coor_t = typename geometry::coordinate_type::type; + + static auto const eps = math::scaled_epsilon(1000); + for (auto& section : sections) { - using gt = decltype(section.bounding_box); - using ct = typename geometry::coordinate_type::type; - static ct const eps = math::scaled_epsilon(1000); expand_by_epsilon(section.bounding_box, eps); } } diff --git a/include/boost/geometry/algorithms/detail/single_geometry.hpp b/include/boost/geometry/algorithms/detail/single_geometry.hpp index c7d2192fb0..054771feb5 100644 --- a/include/boost/geometry/algorithms/detail/single_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/single_geometry.hpp @@ -18,6 +18,7 @@ #include #include #include +#include namespace boost { namespace geometry { @@ -29,11 +30,7 @@ namespace detail_dispatch { template < typename Geometry, - bool IsMulti = std::is_base_of - < - multi_tag, - typename geometry::tag::type - >::value + bool IsMulti = util::is_multi::value > struct single_geometry { diff --git a/include/boost/geometry/algorithms/detail/sub_range.hpp b/include/boost/geometry/algorithms/detail/sub_range.hpp index d0ac6fba66..c1ae9fefb1 100644 --- a/include/boost/geometry/algorithms/detail/sub_range.hpp +++ b/include/boost/geometry/algorithms/detail/sub_range.hpp @@ -25,6 +25,7 @@ #include #include +#include namespace boost { namespace geometry { @@ -33,9 +34,12 @@ namespace boost { namespace geometry { #ifndef DOXYGEN_NO_DISPATCH namespace detail_dispatch { -template ::type, - bool IsMulti = std::is_base_of::value> +template +< + typename Geometry, + typename Tag = typename geometry::tag::type, + bool IsMulti = util::is_multi::value +> struct sub_range : not_implemented {}; diff --git a/include/boost/geometry/algorithms/detail/within/multi_point.hpp b/include/boost/geometry/algorithms/detail/within/multi_point.hpp index be984e9364..559d89d028 100644 --- a/include/boost/geometry/algorithms/detail/within/multi_point.hpp +++ b/include/boost/geometry/algorithms/detail/within/multi_point.hpp @@ -42,7 +42,7 @@ #include #include -#include +#include #include @@ -238,9 +238,16 @@ struct multi_point_multi_geometry if (boundaries > 0) { - if (BOOST_GEOMETRY_CONDITION(is_linear) && boundaries % 2 == 0) + if BOOST_GEOMETRY_CONSTEXPR (is_linear) { - found_interior = true; + if (boundaries % 2 == 0) + { + found_interior = true; + } + else + { + found_boundary = true; + } } else { diff --git a/include/boost/geometry/algorithms/detail/within/within_no_turns.hpp b/include/boost/geometry/algorithms/detail/within/within_no_turns.hpp deleted file mode 100644 index d6d0417c3b..0000000000 --- a/include/boost/geometry/algorithms/detail/within/within_no_turns.hpp +++ /dev/null @@ -1,228 +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. - -// This file was modified by Oracle on 2013-2023. -// Modifications copyright (c) 2013-2023, Oracle and/or its affiliates. -// Contributed and/or modified by Vissarion Fysikopoulos, 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_ALGORITHMS_DETAIL_WITHIN_WITHIN_NO_TURNS_HPP -#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_WITHIN_NO_TURNS_HPP - -#include -#include - -namespace boost { namespace geometry { - -#ifndef DOXYGEN_NO_DETAIL -namespace detail_dispatch { namespace within { - -// returns true if G1 is within G2 -// this function should be called only if there are no intersection points -// otherwise it may return invalid result -// e.g. when non-first point of G1 is outside G2 or when some rings of G1 are the same as rings of G2 - -template ::type, - typename Tag2 = typename geometry::tag::type> -struct within_no_turns -{ - template static inline - bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) - { - typedef typename geometry::point_type::type point1_type; - point1_type p; - if (! geometry::point_on_border(p, geometry1)) - { - return false; - } - - return detail::within::point_in_geometry(p, geometry2, strategy) >= 0; - } -}; - -template -struct within_no_turns -{ - template static inline - bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) - { - typedef typename geometry::point_type::type point1_type; - typedef typename geometry::point_type::type point2_type; - point1_type p; - if (! geometry::point_on_border(p, geometry1)) - { - return false; - } - // check if one of ring points is outside the polygon - if (detail::within::point_in_geometry(p, geometry2, strategy) < 0) - { - return false; - } - // Now check if holes of G2 aren't inside G1 - auto const& rings2 = geometry::interior_rings(geometry2); - for (auto it = boost::begin(rings2); it != boost::end(rings2); ++it) - { - point2_type p; - if (! geometry::point_on_border(p, *it)) - { - return false; - } - if (detail::within::point_in_geometry(p, geometry1, strategy) > 0) - { - return false; - } - } - return true; - } -}; - -template -struct within_no_turns -{ - template static inline - bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) - { - typedef typename geometry::point_type::type point1_type; - typedef typename geometry::point_type::type point2_type; - point1_type p; - if (! geometry::point_on_border(p, geometry1)) - { - return false; - } - // check if one of ring points is outside the polygon - if (detail::within::point_in_geometry(p, geometry2, strategy) < 0) - { - return false; - } - // Now check if holes of G2 aren't inside G1 - auto const& rings2 = geometry::interior_rings(geometry2); - for (auto it2 = boost::begin(rings2); it2 != boost::end(rings2); ++it2) - { - point2_type p2; - if (! geometry::point_on_border(p2, *it2)) - { - return false; - } - // if the hole of G2 is inside G1 - if (detail::within::point_in_geometry(p2, geometry1, strategy) > 0) - { - // if it's also inside one of the G1 holes, it's ok - bool ok = false; - auto const& rings1 = geometry::interior_rings(geometry1); - for (auto it1 = boost::begin(rings1); it1 != boost::end(rings1); ++it1) - { - if (detail::within::point_in_geometry(p2, *it1, strategy) < 0) - { - ok = true; - break; - } - } - if (! ok) - { - return false; - } - } - } - return true; - } -}; - -template ::type, - typename Tag2 = typename geometry::tag::type, - bool IsMulti1 = boost::is_base_of::value, - bool IsMulti2 = boost::is_base_of::value> -struct within_no_turns_multi -{ - template static inline - bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) - { - return within_no_turns::apply(geometry1, geometry2, strategy); - } -}; - -template -struct within_no_turns_multi -{ - template static inline - bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) - { - // All values of G1 must be inside G2 - typedef typename boost::range_value::type subgeometry1; - for (auto it = boost::begin(geometry1) ; it != boost::end(geometry1) ; ++it ) - { - if (! within_no_turns::apply(*it, geometry2, strategy)) - { - return false; - } - } - return true; - } -}; - -template -struct within_no_turns_multi -{ - template static inline - bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) - { - // G1 must be within at least one value of G2 - typedef typename boost::range_value::type subgeometry2; - for (auto it = boost::begin(geometry2); it != boost::end(geometry2); ++it) - { - if (within_no_turns::apply(geometry1, *it, strategy)) - { - return true; - } - } - return false; - } -}; - -template -struct within_no_turns_multi -{ - template static inline - bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) - { - // each value of G1 must be inside at least one value of G2 - typedef typename boost::range_value::type subgeometry1; - for (auto it = boost::begin(geometry1) ; it != boost::end(geometry1) ; ++it) - { - if (! within_no_turns_multi::apply(*it, geometry2, strategy)) - { - return false; - } - } - return true; - } -}; - -}} // namespace detail_dispatch::within - -namespace detail { namespace within { - -template -inline bool within_no_turns(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) -{ - return detail_dispatch::within::within_no_turns_multi::apply(geometry1, geometry2, strategy); -} - -}} // namespace detail::within -#endif // DOXYGEN_NO_DETAIL - -}} // namespace boost::geometry - -#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_WITHIN_NO_TURNS_HPP diff --git a/include/boost/geometry/algorithms/line_interpolate.hpp b/include/boost/geometry/algorithms/line_interpolate.hpp index 5739c444ee..9afbe5092c 100644 --- a/include/boost/geometry/algorithms/line_interpolate.hpp +++ b/include/boost/geometry/algorithms/line_interpolate.hpp @@ -1,5 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) +// Copyright (c) 2023-2024 Adam Wulkiewicz, Lodz, Poland. + // Copyright (c) 2018-2023 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 @@ -35,7 +37,7 @@ #include #include -#include +#include #include #include @@ -133,13 +135,16 @@ struct interpolate_range p, diff_distance); Policy::apply(p, pointlike); - if ( BOOST_GEOMETRY_CONDITION(util::is_point::value) ) + if BOOST_GEOMETRY_CONSTEXPR (util::is_point::value) { return; } - start_p = p; - prev_distance = repeated_distance; - repeated_distance += max_distance; + else // else prevents unreachable code warning + { + start_p = p; + prev_distance = repeated_distance; + repeated_distance += max_distance; + } } prev_distance = current_distance; prev = it; diff --git a/include/boost/geometry/algorithms/remove_spikes.hpp b/include/boost/geometry/algorithms/remove_spikes.hpp index 7a144db154..9d50c60fcd 100644 --- a/include/boost/geometry/algorithms/remove_spikes.hpp +++ b/include/boost/geometry/algorithms/remove_spikes.hpp @@ -3,7 +3,7 @@ // Copyright (c) 2007-2013 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2013 Bruno Lalande, Paris, France. // Copyright (c) 2009-2013 Mateusz Loskot, London, UK. -// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2013-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2017-2023. // Modifications copyright (c) 2017-2023 Oracle and/or its affiliates. @@ -37,7 +37,7 @@ #include -#include +#include #include @@ -104,7 +104,7 @@ struct range_remove_spikes std::size_t cleaned_count = cleaned.size(); // For a closed-polygon, remove closing point, this makes checking first point(s) easier and consistent - if ( BOOST_GEOMETRY_CONDITION(geometry::closure::value == geometry::closed) ) + if BOOST_GEOMETRY_CONSTEXPR (geometry::closure::value == geometry::closed) { --cleaned_e; --cleaned_count; @@ -148,7 +148,7 @@ struct range_remove_spikes } // Close if necessary - if ( BOOST_GEOMETRY_CONDITION(geometry::closure::value == geometry::closed) ) + if BOOST_GEOMETRY_CONSTEXPR (geometry::closure::value == geometry::closed) { BOOST_GEOMETRY_ASSERT(cleaned_e != cleaned.end()); *cleaned_e = *cleaned_b; diff --git a/include/boost/geometry/algorithms/simplify.hpp b/include/boost/geometry/algorithms/simplify.hpp index 40c66e91a8..624d01334f 100644 --- a/include/boost/geometry/algorithms/simplify.hpp +++ b/include/boost/geometry/algorithms/simplify.hpp @@ -3,7 +3,7 @@ // 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) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2023-2024 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2018-2023. // Modifications copyright (c) 2018-2023 Oracle and/or its affiliates. @@ -61,6 +61,7 @@ #include #include +#include #include #ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER @@ -429,10 +430,10 @@ public : return; } - bool const is_closed_in = geometry::closure::value == closed; - bool const is_closed_out = geometry::closure::value == closed; - bool const is_clockwise_in = geometry::point_order::value == clockwise; - bool const is_clockwise_out = geometry::point_order::value == clockwise; + constexpr bool is_closed_in = geometry::closure::value == closed; + constexpr bool is_closed_out = geometry::closure::value == closed; + constexpr bool is_clockwise_in = geometry::point_order::value == clockwise; + constexpr bool is_clockwise_out = geometry::point_order::value == clockwise; // TODO: instead of area() use calculate_point_order() ? @@ -482,10 +483,13 @@ public : // Do not duplicate the closing point auto rot_end = boost::end(ring); std::size_t rot_index = index; - if (BOOST_GEOMETRY_CONDITION(is_closed_in) && size > 1) + if BOOST_GEOMETRY_CONSTEXPR (is_closed_in) { - --rot_end; - if (rot_index == size - 1) { rot_index = 0; } + if (size > 1) + { + --rot_end; + if (rot_index == size - 1) { rot_index = 0; } + } } std::rotate_copy(boost::begin(ring), range::pos(ring, rot_index), @@ -497,9 +501,12 @@ public : simplify_range<0>::apply(rotated, out, max_distance, impl, strategies); // Open output if needed - if (BOOST_GEOMETRY_CONDITION(! is_closed_out) && boost::size(out) > 1) + if BOOST_GEOMETRY_CONSTEXPR (! is_closed_out) { - range::pop_back(out); + if (boost::size(out) > 1) + { + range::pop_back(out); + } } // TODO: instead of area() use calculate_point_order() ? @@ -532,7 +539,7 @@ public : rotated.clear(); } - if (BOOST_GEOMETRY_CONDITION(is_clockwise_in != is_clockwise_out)) + if BOOST_GEOMETRY_CONSTEXPR (is_clockwise_in != is_clockwise_out) { std::reverse(boost::begin(out), boost::end(out)); } diff --git a/include/boost/geometry/arithmetic/determinant.hpp b/include/boost/geometry/arithmetic/determinant.hpp index 59c596b124..63974a9eac 100644 --- a/include/boost/geometry/arithmetic/determinant.hpp +++ b/include/boost/geometry/arithmetic/determinant.hpp @@ -16,9 +16,9 @@ #include #include +#include #include -#include namespace boost { namespace geometry { @@ -33,7 +33,7 @@ class calculate_determinant template static inline ReturnType rt(T const& v) { - return boost::numeric_cast(v); + return util::numeric_cast(v); } public : diff --git a/include/boost/geometry/core/radian_access.hpp b/include/boost/geometry/core/radian_access.hpp index c2f00552dd..ef87701ba5 100644 --- a/include/boost/geometry/core/radian_access.hpp +++ b/include/boost/geometry/core/radian_access.hpp @@ -23,13 +23,12 @@ #include -#include - #include #include #include #include +#include @@ -48,7 +47,7 @@ struct degree_radian_converter static inline coordinate_type get(Geometry const& geometry) { - return boost::numeric_cast + return util::numeric_cast < coordinate_type >(geometry::get(geometry) @@ -57,7 +56,7 @@ struct degree_radian_converter static inline void set(Geometry& geometry, coordinate_type const& radians) { - geometry::set(geometry, boost::numeric_cast + geometry::set(geometry, util::numeric_cast < coordinate_type >(radians * math::r2d())); @@ -113,7 +112,7 @@ struct degree_radian_converter_box_segment static inline coordinate_type get(Geometry const& geometry) { - return boost::numeric_cast + return util::numeric_cast < coordinate_type >(geometry::get(geometry) @@ -122,7 +121,7 @@ struct degree_radian_converter_box_segment static inline void set(Geometry& geometry, coordinate_type const& radians) { - geometry::set(geometry, boost::numeric_cast + geometry::set(geometry, util::numeric_cast < coordinate_type >(radians * math::r2d())); diff --git a/include/boost/geometry/formulas/andoyer_inverse.hpp b/include/boost/geometry/formulas/andoyer_inverse.hpp index 98f5dcd79e..708a574399 100644 --- a/include/boost/geometry/formulas/andoyer_inverse.hpp +++ b/include/boost/geometry/formulas/andoyer_inverse.hpp @@ -1,9 +1,8 @@ // Boost.Geometry -// Copyright (c) 2018 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2018-2023 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2015-2020 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, @@ -18,7 +17,7 @@ #include -#include +#include #include #include @@ -98,7 +97,7 @@ class andoyer_inverse CT const d = acos(cos_d); // [0, pi] CT const sin_d = sin(d); // [-1, 1] - if ( BOOST_GEOMETRY_CONDITION(EnableDistance) ) + if BOOST_GEOMETRY_CONSTEXPR (EnableDistance) { CT const K = math::sqr(sin_lat1-sin_lat2); CT const L = math::sqr(sin_lat1+sin_lat2); @@ -123,7 +122,7 @@ class andoyer_inverse result.distance = a * (d + dd); } - if ( BOOST_GEOMETRY_CONDITION(CalcAzimuths) ) + if BOOST_GEOMETRY_CONSTEXPR (CalcAzimuths) { // sin_d = 0 <=> antipodal points (incl. poles) or very close if (math::equals(sin_d, c0)) @@ -210,14 +209,14 @@ class andoyer_inverse // therefore dA and dB may be great and the resulting azimuths // may be some more or less arbitrary angles - if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcFwdAzimuth) { CT const dA = V*T - U; result.azimuth = A - dA; normalize_azimuth(result.azimuth, A, dA); } - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { CT const dB = -U*T + V; if (B >= 0) @@ -229,7 +228,7 @@ class andoyer_inverse } } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { CT const b = CT(get_radius<2>(spheroid)); diff --git a/include/boost/geometry/formulas/area_formulas.hpp b/include/boost/geometry/formulas/area_formulas.hpp index b8da8a6727..c45cd94f1f 100644 --- a/include/boost/geometry/formulas/area_formulas.hpp +++ b/include/boost/geometry/formulas/area_formulas.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2023-2024 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2015-2022 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -381,26 +382,33 @@ class area_formulas return pi; } - if (BOOST_GEOMETRY_CONDITION(LongSegment) && lat1r != lat2r) // not for segments parallel to equator + if BOOST_GEOMETRY_CONSTEXPR (LongSegment) { - CT const cbet1 = cos(lat1r); - CT const sbet1 = sin(lat1r); - CT const cbet2 = cos(lat2r); - CT const sbet2 = sin(lat2r); - - CT const omg12 = lon2r - lon1r; - CT const comg12 = cos(omg12); - CT const somg12 = sin(omg12); - - CT const cbet1_sbet2 = cbet1 * sbet2; - CT const sbet1_cbet2 = sbet1 * cbet2; - CT const alp1 = atan2(cbet1_sbet2 - sbet1_cbet2 * comg12, cbet2 * somg12); - CT const alp2 = atan2(cbet1_sbet2 * comg12 - sbet1_cbet2, cbet1 * somg12); + if (lat1r != lat2r) // not for segments parallel to equator + { + CT const cbet1 = cos(lat1r); + CT const sbet1 = sin(lat1r); + CT const cbet2 = cos(lat2r); + CT const sbet2 = sin(lat2r); - excess = alp2 - alp1; + CT const omg12 = lon2r - lon1r; + CT const comg12 = cos(omg12); + CT const somg12 = sin(omg12); - } else { + CT const cbet1_sbet2 = cbet1 * sbet2; + CT const sbet1_cbet2 = sbet1 * cbet2; + CT const alp1 = atan2(cbet1_sbet2 - sbet1_cbet2 * comg12, cbet2 * somg12); + CT const alp2 = atan2(cbet1_sbet2 * comg12 - sbet1_cbet2, cbet1 * somg12); + excess = alp2 - alp1; + } + else + { + excess = trapezoidal_formula(lat1r, lat2r, lon12r); + } + } + else + { excess = trapezoidal_formula(lat1r, lat2r, lon12r); } diff --git a/include/boost/geometry/formulas/differential_quantities.hpp b/include/boost/geometry/formulas/differential_quantities.hpp index 1df9adb8e6..140a73867d 100644 --- a/include/boost/geometry/formulas/differential_quantities.hpp +++ b/include/boost/geometry/formulas/differential_quantities.hpp @@ -14,7 +14,7 @@ #include -#include +#include #include @@ -73,7 +73,7 @@ class differential_quantities if (math::equals(sin_bet1, c0) && math::equals(sin_bet2, c0)) { CT const sig_12 = dlon / one_minus_f; - if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) + if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength) { BOOST_GEOMETRY_ASSERT((-math::pi() <= azimuth && azimuth <= math::pi())); @@ -82,7 +82,7 @@ class differential_quantities reduced_length = m12; } - if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableGeodesicScale) { CT M12 = cos(sig_12); geodesic_scale = M12; @@ -123,7 +123,7 @@ class differential_quantities CT const dn1 = math::sqrt(c1 + ep2 * math::sqr(sin_bet1)); CT const dn2 = math::sqrt(c1 + ep2 * math::sqr(sin_bet2)); - if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) + if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength) { CT const m12_b = dn2 * (cos_sig1 * sin_sig2) - dn1 * (sin_sig1 * cos_sig2) @@ -133,7 +133,7 @@ class differential_quantities reduced_length = m12; } - if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableGeodesicScale) { CT const cos_sig12 = cos_sig1 * cos_sig2 + sin_sig1 * sin_sig2; CT const t = ep2 * (cos_bet1 - cos_bet2) * (cos_bet1 + cos_bet2) / (dn1 + dn2); diff --git a/include/boost/geometry/formulas/karney_direct.hpp b/include/boost/geometry/formulas/karney_direct.hpp index bfe35ddc49..ed365c8f1b 100644 --- a/include/boost/geometry/formulas/karney_direct.hpp +++ b/include/boost/geometry/formulas/karney_direct.hpp @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include #include @@ -162,7 +162,7 @@ class karney_direct CT const sin_sigma2 = sin_sigma1 * cos_sigma12 + cos_sigma1 * sin_sigma12; CT const cos_sigma2 = cos_sigma1 * cos_sigma12 - sin_sigma1 * sin_sigma12; - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { CT const sin_alpha2 = sin_alpha0; CT const cos_alpha2 = cos_alpha0 * cos_sigma2; @@ -170,7 +170,7 @@ class karney_direct result.reverse_azimuth = atan2(sin_alpha2, cos_alpha2); } - if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) + if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates) { // Find the latitude at the second point. CT const sin_beta2 = cos_alpha0 * sin_sigma2; @@ -217,7 +217,7 @@ class karney_direct result.lon2 *= math::d2r(); } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { // Evaluate the coefficients for C2. // Index zero element of coeffs_C2 is unused. diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 12dd2b2598..cf338a5685 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include #include @@ -309,7 +309,7 @@ class karney_inverse sigma12 = omega12 = lam12 / one_minus_f; m12x = b * sin(sigma12); - if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableGeodesicScale) { result.geodesic_scale = cos(sigma12); } @@ -335,7 +335,7 @@ class karney_inverse // Short lines case (newton_start sets sin_alpha2, cos_alpha2, dnm). s12x = sigma12 * b * dnm; m12x = math::sqr(dnm) * b * sin(sigma12 / dnm); - if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableGeodesicScale) { result.geodesic_scale = cos(sigma12 / dnm); } @@ -460,25 +460,25 @@ class karney_inverse sin_alpha2 *= swap_point * lon12_sign; cos_alpha2 *= swap_point * lat_sign; - if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) + if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength) { result.reduced_length = m12x; } - if (BOOST_GEOMETRY_CONDITION(CalcAzimuths)) + if BOOST_GEOMETRY_CONSTEXPR (CalcAzimuths) { - if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcFwdAzimuth) { result.azimuth = atan2(sin_alpha1, cos_alpha1); } - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { result.reverse_azimuth = atan2(sin_alpha2, cos_alpha2); } } - if (BOOST_GEOMETRY_CONDITION(EnableDistance)) + if BOOST_GEOMETRY_CONSTEXPR (EnableDistance) { result.distance = s12x; } @@ -503,16 +503,13 @@ class karney_inverse // Evaluate the coefficients for C2. se::coeffs_C2 coeffs_C2(epsilon); - if (BOOST_GEOMETRY_CONDITION(EnableDistance) || - BOOST_GEOMETRY_CONDITION(EnableReducedLength) || - BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableDistance || EnableReducedLength || EnableGeodesicScale) { // Find the coefficients for A1 by computing the // series expansion using Horner scehme. expansion_A1 = se::evaluate_A1(epsilon); - if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || - BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength || EnableGeodesicScale) { // Find the coefficients for A2 by computing the // series expansion using Horner scehme. @@ -524,15 +521,14 @@ class karney_inverse expansion_A1 += c1; } - if (BOOST_GEOMETRY_CONDITION(EnableDistance)) + if BOOST_GEOMETRY_CONSTEXPR (EnableDistance) { CT B1 = se::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C1) - se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C1); s12x = expansion_A1 * (sigma12 + B1); - if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || - BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength || EnableGeodesicScale) { CT B2 = se::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C2) - se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2); @@ -540,8 +536,7 @@ class karney_inverse J12 = A12x * sigma12 + (expansion_A1 * B1 - expansion_A2 * B2); } } - else if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || - BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + else if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength || EnableGeodesicScale) { for (size_t i = 1; i <= SeriesOrder; ++i) { @@ -554,7 +549,7 @@ class karney_inverse - se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2)); } - if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) + if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength) { m0 = A12x; @@ -563,7 +558,7 @@ class karney_inverse cos_sigma1 * cos_sigma2 * J12; } - if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + if BOOST_GEOMETRY_CONSTEXPR (EnableGeodesicScale) { CT cos_sigma12 = cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2; CT t = ep2 * (cos_beta1 - cos_beta2) * diff --git a/include/boost/geometry/formulas/meridian_direct.hpp b/include/boost/geometry/formulas/meridian_direct.hpp index 3699e4c7cb..bbcb314fab 100644 --- a/include/boost/geometry/formulas/meridian_direct.hpp +++ b/include/boost/geometry/formulas/meridian_direct.hpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include namespace boost { namespace geometry { namespace formula @@ -66,7 +66,7 @@ class meridian_direct CT azimuth = north ? c0 : pi; - if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) + if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates) { CT s0 = meridian_inverse::apply(la1, spheroid); int signed_distance = north ? distance : -distance; @@ -74,7 +74,7 @@ class meridian_direct result.lat2 = apply(s0 + signed_distance, spheroid); } - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { result.reverse_azimuth = azimuth; @@ -92,7 +92,7 @@ class meridian_direct } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { CT const b = CT(get_radius<2>(spheroid)); CT const f = formula::flattening(spheroid); diff --git a/include/boost/geometry/formulas/thomas_direct.hpp b/include/boost/geometry/formulas/thomas_direct.hpp index 5889056671..c39c3751e4 100644 --- a/include/boost/geometry/formulas/thomas_direct.hpp +++ b/include/boost/geometry/formulas/thomas_direct.hpp @@ -1,7 +1,8 @@ // Boost.Geometry -// Copyright (c) 2016-2020 Oracle and/or its affiliates. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2016-2020 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 @@ -18,7 +19,7 @@ #include #include -#include +#include #include #include @@ -108,7 +109,7 @@ class thomas_direct CT const C2 = f * (c1 - math::sqr(M)) / c4; // lower-case c2 in the technical report CT D = 0; CT P = 0; - if ( BOOST_GEOMETRY_CONDITION(SecondOrder) ) + if BOOST_GEOMETRY_CONSTEXPR (SecondOrder) { D = (c1 - C2) * (c1 - C2 - C1 * M); P = C2 * (c1 + C1 * M / c2) / D; @@ -142,7 +143,7 @@ class thomas_direct CT const Y = c2 * P * V * W * sin_d; CT X = 0; CT d_sigma = d - Y; - if ( BOOST_GEOMETRY_CONDITION(SecondOrder) ) + if BOOST_GEOMETRY_CONSTEXPR (SecondOrder) { X = math::sqr(C2) * sin_d * cos_d * (2 * math::sqr(V) - c1); d_sigma += X; @@ -150,7 +151,7 @@ class thomas_direct CT const sin_d_sigma = sin(d_sigma); CT const cos_d_sigma = cos(d_sigma); - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { result.reverse_azimuth = atan2(M, N * cos_d_sigma - sin_theta1 * sin_d_sigma); @@ -160,12 +161,12 @@ class thomas_direct } } - if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) + if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates) { CT const S_sigma = c2 * sigma1 - d_sigma; CT cos_S_sigma = 0; CT H = C1 * d_sigma; - if ( BOOST_GEOMETRY_CONDITION(SecondOrder) ) + if BOOST_GEOMETRY_CONSTEXPR (SecondOrder) { cos_S_sigma = cos(S_sigma); H = H * (c1 - C2) - C1 * C2 * sin_d_sigma * cos_S_sigma; @@ -196,7 +197,7 @@ class thomas_direct } } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { typedef differential_quantities quantities; quantities::apply(lon1, lat1, result.lon2, result.lat2, @@ -205,7 +206,7 @@ class thomas_direct result.reduced_length, result.geodesic_scale); } - if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) + if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates) { // For longitudes close to the antimeridian the result can be out // of range. Therefore normalize. diff --git a/include/boost/geometry/formulas/thomas_inverse.hpp b/include/boost/geometry/formulas/thomas_inverse.hpp index c93aaf838c..5a6236d5d4 100644 --- a/include/boost/geometry/formulas/thomas_inverse.hpp +++ b/include/boost/geometry/formulas/thomas_inverse.hpp @@ -1,7 +1,8 @@ // Boost.Geometry -// Copyright (c) 2015-2018 Oracle and/or its affiliates. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2015-2018 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 @@ -17,7 +18,7 @@ #include -#include +#include #include #include @@ -137,7 +138,7 @@ class thomas_inverse CT const f_sqr = math::sqr(f); CT const f_sqr_per_64 = f_sqr / CT(64); - if ( BOOST_GEOMETRY_CONDITION(EnableDistance) ) + if BOOST_GEOMETRY_CONSTEXPR (EnableDistance) { CT const n1 = X * (A + C*X); CT const n2 = Y * (B + E*Y); @@ -152,7 +153,7 @@ class thomas_inverse result.distance = a * sin_d * (T - delta1d + delta2d); } - if ( BOOST_GEOMETRY_CONDITION(CalcAzimuths) ) + if BOOST_GEOMETRY_CONSTEXPR (CalcAzimuths) { // NOTE: if both cos_latX == 0 then below we'd have 0 * INF // it's a situation when the endpoints are on the poles +-90 deg @@ -178,7 +179,7 @@ class thomas_inverse CT const pi = math::pi(); - if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcFwdAzimuth) { CT alpha1 = v + u; if (alpha1 > pi) @@ -189,7 +190,7 @@ class thomas_inverse result.azimuth = alpha1; } - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { CT alpha2 = pi - (v - u); if (alpha2 > pi) @@ -201,7 +202,7 @@ class thomas_inverse } } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { typedef differential_quantities quantities; quantities::apply(lon1, lat1, lon2, lat2, diff --git a/include/boost/geometry/formulas/vincenty_direct.hpp b/include/boost/geometry/formulas/vincenty_direct.hpp index 274af3f2f2..2692266a67 100644 --- a/include/boost/geometry/formulas/vincenty_direct.hpp +++ b/include/boost/geometry/formulas/vincenty_direct.hpp @@ -1,10 +1,10 @@ // Boost.Geometry // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2014-2020. // Modifications copyright (c) 2014-2020 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, @@ -19,7 +19,7 @@ #include -#include +#include #include #include @@ -136,7 +136,7 @@ class vincenty_direct //&& geometry::math::abs(sigma) < pi && counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness - if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) + if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates) { result.lat2 = atan2( sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_azimuth12, @@ -151,13 +151,13 @@ class vincenty_direct result.lon2 = lon1 + L; } - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { result.reverse_azimuth = atan2(sin_alpha, -sin_U1 * sin_sigma + cos_U1 * cos_sigma * cos_azimuth12); // (12) } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { typedef differential_quantities quantities; quantities::apply(lon1, lat1, result.lon2, result.lat2, @@ -166,7 +166,7 @@ class vincenty_direct result.reduced_length, result.geodesic_scale); } - if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) + if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates) { // For longitudes close to the antimeridian the result can be out // of range. Therefore normalize. diff --git a/include/boost/geometry/formulas/vincenty_inverse.hpp b/include/boost/geometry/formulas/vincenty_inverse.hpp index 24f285d9bc..7789e17e97 100644 --- a/include/boost/geometry/formulas/vincenty_inverse.hpp +++ b/include/boost/geometry/formulas/vincenty_inverse.hpp @@ -1,11 +1,10 @@ // Boost.Geometry // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2018 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2018-2023 Adam Wulkiewicz, Lodz, Poland. // This file was modified by Oracle on 2014, 2016, 2017. // Modifications copyright (c) 2014-2017 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, @@ -20,7 +19,7 @@ #include -#include +#include #include #include @@ -160,7 +159,7 @@ struct vincenty_inverse && geometry::math::abs(lambda) < pi && counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness - if ( BOOST_GEOMETRY_CONDITION(EnableDistance) ) + if BOOST_GEOMETRY_CONSTEXPR (EnableDistance) { // Some types cannot divide by doubles CT const c6 = 6; @@ -188,20 +187,20 @@ struct vincenty_inverse result.distance = radius_b * A * (sigma - delta_sigma); // (19) } - if ( BOOST_GEOMETRY_CONDITION(CalcAzimuths) ) + if BOOST_GEOMETRY_CONSTEXPR (CalcAzimuths) { - if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcFwdAzimuth) { result.azimuth = atan2(cos_U2 * sin_lambda, cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda); // (20) } - if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth) { result.reverse_azimuth = atan2(cos_U1 * sin_lambda, -sin_U1 * cos_U2 + cos_U1 * sin_U2 * cos_lambda); // (21) } } - if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) + if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities) { typedef differential_quantities quantities; quantities::apply(lon1, lat1, lon2, lat2, diff --git a/include/boost/geometry/index/detail/rtree/node/node.hpp b/include/boost/geometry/index/detail/rtree/node/node.hpp index fba76efb1c..621b602c19 100644 --- a/include/boost/geometry/index/detail/rtree/node/node.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node.hpp @@ -21,6 +21,8 @@ #include +#include + #include #include @@ -36,14 +38,14 @@ #include #include -#include - #include #include #include #include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { @@ -92,11 +94,10 @@ inline Box values_box(FwdIter first, FwdIter last, Translator const& tr, Box result = elements_box(first, last, tr, strategy); #ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON - if (BOOST_GEOMETRY_CONDITION(( - ! is_bounding_geometry - < - typename indexable_type::type - >::value))) + if BOOST_GEOMETRY_CONSTEXPR (! index::detail::is_bounding_geometry + < + typename indexable_type::type + >::value) { geometry::detail::expand_by_epsilon(result); } diff --git a/include/boost/geometry/index/detail/rtree/pack_create.hpp b/include/boost/geometry/index/detail/rtree/pack_create.hpp index 33600a4c93..dab7cfdbdd 100644 --- a/include/boost/geometry/index/detail/rtree/pack_create.hpp +++ b/include/boost/geometry/index/detail/rtree/pack_create.hpp @@ -31,6 +31,8 @@ #include #include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace pack_utils { @@ -343,11 +345,10 @@ class pack // NOTE: this is done only if the Indexable is a different kind of Geometry // than the bounds (only Box for now). Spatial predicates are checked // the same way for Geometry of the same kind. - if ( BOOST_GEOMETRY_CONDITION(( - ! index::detail::is_bounding_geometry - < - typename indexable_type::type - >::value )) ) + if BOOST_GEOMETRY_CONSTEXPR (! index::detail::is_bounding_geometry + < + typename indexable_type::type + >::value) { elements_box.expand_by_epsilon(); } diff --git a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp index 2d87e21a17..27e62584d4 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp @@ -30,7 +30,7 @@ #include #include -#include +#include namespace boost { namespace geometry { namespace index { @@ -328,12 +328,11 @@ class insert // Enlarge it in case if it's not bounding geometry type. // It's because Points and Segments are compared WRT machine epsilon // This ensures that leafs bounds correspond to the stored elements - if (BOOST_GEOMETRY_CONDITION(( - std::is_same::value - && ! index::detail::is_bounding_geometry - < - typename indexable_type::type - >::value )) ) + if BOOST_GEOMETRY_CONSTEXPR ((std::is_same::value) + && ! index::detail::is_bounding_geometry + < + typename indexable_type::type + >::value) { geometry::detail::expand_by_epsilon(m_element_bounds); } @@ -425,16 +424,16 @@ class insert // Enlarge bounds of a leaf node. // It's because Points and Segments are compared WRT machine epsilon // This ensures that leafs' bounds correspond to the stored elements. - if (BOOST_GEOMETRY_CONDITION(( - std::is_same::value - && ! index::detail::is_bounding_geometry - < - typename indexable_type::type - >::value ))) + if BOOST_GEOMETRY_CONSTEXPR ((std::is_same::value) + && ! index::detail::is_bounding_geometry + < + typename indexable_type::type + >::value) { geometry::detail::expand_by_epsilon(n_box); geometry::detail::expand_by_epsilon(additional_nodes[0].first); } + #endif // node is not the root - just add the new node diff --git a/include/boost/geometry/io/wkt/detail/wkt_multi.hpp b/include/boost/geometry/io/wkt/detail/wkt_multi.hpp deleted file mode 100644 index f332752160..0000000000 --- a/include/boost/geometry/io/wkt/detail/wkt_multi.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) - -// Copyright (c) 2007-2022 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. - -// 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_IO_WKT_MULTI_HPP -#define BOOST_GEOMETRY_IO_WKT_MULTI_HPP - -#include -#include - -#include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") - -#endif // BOOST_GEOMETRY_IO_WKT_MULTI_HPP diff --git a/include/boost/geometry/multi/algorithms/append.hpp b/include/boost/geometry/multi/algorithms/append.hpp index d1589aca84..e3c94efcb2 100644 --- a/include/boost/geometry/multi/algorithms/append.hpp +++ b/include/boost/geometry/multi/algorithms/append.hpp @@ -20,6 +20,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/area.hpp b/include/boost/geometry/multi/algorithms/area.hpp index 0e25ffc64e..a9397d82e1 100644 --- a/include/boost/geometry/multi/algorithms/area.hpp +++ b/include/boost/geometry/multi/algorithms/area.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_AREA_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_AREA_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/centroid.hpp b/include/boost/geometry/multi/algorithms/centroid.hpp index 1c9902f2bf..d9606ffd6c 100644 --- a/include/boost/geometry/multi/algorithms/centroid.hpp +++ b/include/boost/geometry/multi/algorithms/centroid.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CENTROID_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_CENTROID_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/clear.hpp b/include/boost/geometry/multi/algorithms/clear.hpp index 6d9e284d0a..f1e9bc4011 100644 --- a/include/boost/geometry/multi/algorithms/clear.hpp +++ b/include/boost/geometry/multi/algorithms/clear.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CLEAR_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_CLEAR_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/convert.hpp b/include/boost/geometry/multi/algorithms/convert.hpp index 0e7b2946d4..54a1a3294e 100644 --- a/include/boost/geometry/multi/algorithms/convert.hpp +++ b/include/boost/geometry/multi/algorithms/convert.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CONVERT_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_CONVERT_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/correct.hpp b/include/boost/geometry/multi/algorithms/correct.hpp index 83d26ca60c..32a229604b 100644 --- a/include/boost/geometry/multi/algorithms/correct.hpp +++ b/include/boost/geometry/multi/algorithms/correct.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CORRECT_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_CORRECT_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/covered_by.hpp b/include/boost/geometry/multi/algorithms/covered_by.hpp index 706bc78475..04e40e721e 100644 --- a/include/boost/geometry/multi/algorithms/covered_by.hpp +++ b/include/boost/geometry/multi/algorithms/covered_by.hpp @@ -20,6 +20,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/detail/extreme_points.hpp b/include/boost/geometry/multi/algorithms/detail/extreme_points.hpp index da2ac5e9fa..9b84730ffc 100644 --- a/include/boost/geometry/multi/algorithms/detail/extreme_points.hpp +++ b/include/boost/geometry/multi/algorithms/detail/extreme_points.hpp @@ -12,6 +12,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_EXTREME_POINTS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_EXTREME_POINTS_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/detail/for_each_range.hpp b/include/boost/geometry/multi/algorithms/detail/for_each_range.hpp index 2fe475ed58..fb6633c0df 100644 --- a/include/boost/geometry/multi/algorithms/detail/for_each_range.hpp +++ b/include/boost/geometry/multi/algorithms/detail/for_each_range.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/detail/modify.hpp b/include/boost/geometry/multi/algorithms/detail/modify.hpp index ae52e002f0..8a52b42980 100644 --- a/include/boost/geometry/multi/algorithms/detail/modify.hpp +++ b/include/boost/geometry/multi/algorithms/detail/modify.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/detail/modify_with_predicate.hpp b/include/boost/geometry/multi/algorithms/detail/modify_with_predicate.hpp index 1a82a67142..0be6828351 100644 --- a/include/boost/geometry/multi/algorithms/detail/modify_with_predicate.hpp +++ b/include/boost/geometry/multi/algorithms/detail/modify_with_predicate.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/detail/multi_sum.hpp b/include/boost/geometry/multi/algorithms/detail/multi_sum.hpp index b91970a164..ca10adc8ff 100644 --- a/include/boost/geometry/multi/algorithms/detail/multi_sum.hpp +++ b/include/boost/geometry/multi/algorithms/detail/multi_sum.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MULTI_SUM_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MULTI_SUM_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp b/include/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp index 5e23cf4bad..69cff5fdc1 100644 --- a/include/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp +++ b/include/boost/geometry/multi/algorithms/detail/overlay/copy_segment_point.hpp @@ -12,6 +12,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp b/include/boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp index 54114bfae4..76f239df09 100644 --- a/include/boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp +++ b/include/boost/geometry/multi/algorithms/detail/overlay/copy_segments.hpp @@ -9,6 +9,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/detail/overlay/get_turns.hpp b/include/boost/geometry/multi/algorithms/detail/overlay/get_turns.hpp index a83fb77393..fbc2e85a02 100644 --- a/include/boost/geometry/multi/algorithms/detail/overlay/get_turns.hpp +++ b/include/boost/geometry/multi/algorithms/detail/overlay/get_turns.hpp @@ -9,6 +9,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/detail/overlay/self_turn_points.hpp b/include/boost/geometry/multi/algorithms/detail/overlay/self_turn_points.hpp index 39bfea2fb3..f2dae9efed 100644 --- a/include/boost/geometry/multi/algorithms/detail/overlay/self_turn_points.hpp +++ b/include/boost/geometry/multi/algorithms/detail/overlay/self_turn_points.hpp @@ -9,6 +9,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/detail/point_on_border.hpp b/include/boost/geometry/multi/algorithms/detail/point_on_border.hpp index 2ee789c5da..56fa25063b 100644 --- a/include/boost/geometry/multi/algorithms/detail/point_on_border.hpp +++ b/include/boost/geometry/multi/algorithms/detail/point_on_border.hpp @@ -17,6 +17,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp b/include/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp index 5604d9d74f..b507d51ccf 100644 --- a/include/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp +++ b/include/boost/geometry/multi/algorithms/detail/sections/range_by_section.hpp @@ -19,6 +19,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp b/include/boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp index ef98021237..4e7aa9c31c 100644 --- a/include/boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp +++ b/include/boost/geometry/multi/algorithms/detail/sections/sectionalize.hpp @@ -17,6 +17,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/disjoint.hpp b/include/boost/geometry/multi/algorithms/disjoint.hpp index 55f0f01cd6..8e732558da 100644 --- a/include/boost/geometry/multi/algorithms/disjoint.hpp +++ b/include/boost/geometry/multi/algorithms/disjoint.hpp @@ -16,6 +16,9 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DISJOINT_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DISJOINT_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") + #include #endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DISJOINT_HPP diff --git a/include/boost/geometry/multi/algorithms/distance.hpp b/include/boost/geometry/multi/algorithms/distance.hpp index 4946b6f3e1..35ebcb5fb9 100644 --- a/include/boost/geometry/multi/algorithms/distance.hpp +++ b/include/boost/geometry/multi/algorithms/distance.hpp @@ -19,8 +19,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DISTANCE_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DISTANCE_HPP -// this file is intentionally empty (with the exception of the #include below) -// it is used for backward compatinility and may be removed in the future +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/envelope.hpp b/include/boost/geometry/multi/algorithms/envelope.hpp index 457dfaf3bc..1b99bebcf0 100644 --- a/include/boost/geometry/multi/algorithms/envelope.hpp +++ b/include/boost/geometry/multi/algorithms/envelope.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_ENVELOPE_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_ENVELOPE_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/equals.hpp b/include/boost/geometry/multi/algorithms/equals.hpp index 0f045fff90..3aea16e947 100644 --- a/include/boost/geometry/multi/algorithms/equals.hpp +++ b/include/boost/geometry/multi/algorithms/equals.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_EQUALS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_EQUALS_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/for_each.hpp b/include/boost/geometry/multi/algorithms/for_each.hpp index d8b3af1ff2..dc0b29c8bc 100644 --- a/include/boost/geometry/multi/algorithms/for_each.hpp +++ b/include/boost/geometry/multi/algorithms/for_each.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_FOR_EACH_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_FOR_EACH_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/intersection.hpp b/include/boost/geometry/multi/algorithms/intersection.hpp index f434463253..117b084e6e 100644 --- a/include/boost/geometry/multi/algorithms/intersection.hpp +++ b/include/boost/geometry/multi/algorithms/intersection.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/length.hpp b/include/boost/geometry/multi/algorithms/length.hpp index 168e6a732f..12d0efc087 100644 --- a/include/boost/geometry/multi/algorithms/length.hpp +++ b/include/boost/geometry/multi/algorithms/length.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_LENGTH_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_LENGTH_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/num_geometries.hpp b/include/boost/geometry/multi/algorithms/num_geometries.hpp index 3a85f4e4bf..6dcd44aacc 100644 --- a/include/boost/geometry/multi/algorithms/num_geometries.hpp +++ b/include/boost/geometry/multi/algorithms/num_geometries.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_GEOMETRIES_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_GEOMETRIES_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/num_interior_rings.hpp b/include/boost/geometry/multi/algorithms/num_interior_rings.hpp index fbaa113aff..62f74fc1f3 100644 --- a/include/boost/geometry/multi/algorithms/num_interior_rings.hpp +++ b/include/boost/geometry/multi/algorithms/num_interior_rings.hpp @@ -19,6 +19,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/num_points.hpp b/include/boost/geometry/multi/algorithms/num_points.hpp index a736f4254b..9b56ce241c 100644 --- a/include/boost/geometry/multi/algorithms/num_points.hpp +++ b/include/boost/geometry/multi/algorithms/num_points.hpp @@ -20,6 +20,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/perimeter.hpp b/include/boost/geometry/multi/algorithms/perimeter.hpp index 4820111f1f..844bb526bc 100644 --- a/include/boost/geometry/multi/algorithms/perimeter.hpp +++ b/include/boost/geometry/multi/algorithms/perimeter.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_PERIMETER_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_PERIMETER_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/remove_spikes.hpp b/include/boost/geometry/multi/algorithms/remove_spikes.hpp index af224ec478..5660cf6a97 100644 --- a/include/boost/geometry/multi/algorithms/remove_spikes.hpp +++ b/include/boost/geometry/multi/algorithms/remove_spikes.hpp @@ -12,6 +12,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_REMOVE_SPIKES_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_REMOVE_SPIKES_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/reverse.hpp b/include/boost/geometry/multi/algorithms/reverse.hpp index a7872bdd2a..cea453e7c1 100644 --- a/include/boost/geometry/multi/algorithms/reverse.hpp +++ b/include/boost/geometry/multi/algorithms/reverse.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_REVERSE_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_REVERSE_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/simplify.hpp b/include/boost/geometry/multi/algorithms/simplify.hpp index 8648d366d1..f4d7222a70 100644 --- a/include/boost/geometry/multi/algorithms/simplify.hpp +++ b/include/boost/geometry/multi/algorithms/simplify.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_SIMPLIFY_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_SIMPLIFY_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/transform.hpp b/include/boost/geometry/multi/algorithms/transform.hpp index 7aa691ec4a..e384dbed60 100644 --- a/include/boost/geometry/multi/algorithms/transform.hpp +++ b/include/boost/geometry/multi/algorithms/transform.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_TRANSFORM_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_TRANSFORM_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/unique.hpp b/include/boost/geometry/multi/algorithms/unique.hpp index fa063a312d..bb0a04e994 100644 --- a/include/boost/geometry/multi/algorithms/unique.hpp +++ b/include/boost/geometry/multi/algorithms/unique.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_UNIQUE_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_UNIQUE_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/algorithms/within.hpp b/include/boost/geometry/multi/algorithms/within.hpp index 9fdc5dd39a..7127775fd3 100644 --- a/include/boost/geometry/multi/algorithms/within.hpp +++ b/include/boost/geometry/multi/algorithms/within.hpp @@ -20,6 +20,9 @@ #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_WITHIN_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_WITHIN_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") + #include #endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_WITHIN_HPP diff --git a/include/boost/geometry/multi/core/closure.hpp b/include/boost/geometry/multi/core/closure.hpp index 9e7cf3c248..65eb5b80fc 100644 --- a/include/boost/geometry/multi/core/closure.hpp +++ b/include/boost/geometry/multi/core/closure.hpp @@ -14,6 +14,9 @@ #ifndef BOOST_GEOMETRY_MULTI_CORE_CLOSURE_HPP #define BOOST_GEOMETRY_MULTI_CORE_CLOSURE_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") + #include #endif // BOOST_GEOMETRY_MULTI_CORE_CLOSURE_HPP diff --git a/include/boost/geometry/multi/core/geometry_id.hpp b/include/boost/geometry/multi/core/geometry_id.hpp index 7d5e888bab..f929ab5aec 100644 --- a/include/boost/geometry/multi/core/geometry_id.hpp +++ b/include/boost/geometry/multi/core/geometry_id.hpp @@ -15,6 +15,9 @@ #ifndef BOOST_GEOMETRY_MULTI_CORE_GEOMETRY_ID_HPP #define BOOST_GEOMETRY_MULTI_CORE_GEOMETRY_ID_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") + #include #endif // BOOST_GEOMETRY_MULTI_CORE_GEOMETRY_ID_HPP diff --git a/include/boost/geometry/multi/core/interior_rings.hpp b/include/boost/geometry/multi/core/interior_rings.hpp index deeeff81d0..472bcacfbe 100644 --- a/include/boost/geometry/multi/core/interior_rings.hpp +++ b/include/boost/geometry/multi/core/interior_rings.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_MULTI_CORE_INTERIOR_RINGS_HPP #define BOOST_GEOMETRY_MULTI_CORE_INTERIOR_RINGS_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/core/is_areal.hpp b/include/boost/geometry/multi/core/is_areal.hpp index 30f98527ab..1c8e0d3450 100644 --- a/include/boost/geometry/multi/core/is_areal.hpp +++ b/include/boost/geometry/multi/core/is_areal.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_MULTI_CORE_IS_AREAL_HPP #define BOOST_GEOMETRY_MULTI_CORE_IS_AREAL_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/core/point_order.hpp b/include/boost/geometry/multi/core/point_order.hpp index 119e55c3ba..79aa84b3ac 100644 --- a/include/boost/geometry/multi/core/point_order.hpp +++ b/include/boost/geometry/multi/core/point_order.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_CORE_POINT_ORDER_HPP #define BOOST_GEOMETRY_MULTI_CORE_POINT_ORDER_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/core/point_type.hpp b/include/boost/geometry/multi/core/point_type.hpp index a7277d09a9..5871b9ba76 100644 --- a/include/boost/geometry/multi/core/point_type.hpp +++ b/include/boost/geometry/multi/core/point_type.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_MULTI_CORE_POINT_TYPE_HPP #define BOOST_GEOMETRY_MULTI_CORE_POINT_TYPE_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/core/ring_type.hpp b/include/boost/geometry/multi/core/ring_type.hpp index b27b5527c2..85ece1f611 100644 --- a/include/boost/geometry/multi/core/ring_type.hpp +++ b/include/boost/geometry/multi/core/ring_type.hpp @@ -18,6 +18,8 @@ #ifndef BOOST_GEOMETRY_MULTI_CORE_RING_TYPE_HPP #define BOOST_GEOMETRY_MULTI_CORE_RING_TYPE_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/core/tags.hpp b/include/boost/geometry/multi/core/tags.hpp index fb0758d95f..cd69701f2a 100644 --- a/include/boost/geometry/multi/core/tags.hpp +++ b/include/boost/geometry/multi/core/tags.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_MULTI_CORE_TAGS_HPP #define BOOST_GEOMETRY_MULTI_CORE_TAGS_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/core/topological_dimension.hpp b/include/boost/geometry/multi/core/topological_dimension.hpp index b4f1e89ae8..1347285fe3 100644 --- a/include/boost/geometry/multi/core/topological_dimension.hpp +++ b/include/boost/geometry/multi/core/topological_dimension.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_MULTI_TOPOLOGICAL_DIMENSION_HPP #define BOOST_GEOMETRY_MULTI_TOPOLOGICAL_DIMENSION_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/geometries/concepts/check.hpp b/include/boost/geometry/multi/geometries/concepts/check.hpp index c741afd794..4626084ea8 100644 --- a/include/boost/geometry/multi/geometries/concepts/check.hpp +++ b/include/boost/geometry/multi/geometries/concepts/check.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_CHECK_HPP #define BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_CHECK_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/geometries/concepts/multi_linestring_concept.hpp b/include/boost/geometry/multi/geometries/concepts/multi_linestring_concept.hpp index 9a9438efcc..2080aff2f4 100644 --- a/include/boost/geometry/multi/geometries/concepts/multi_linestring_concept.hpp +++ b/include/boost/geometry/multi/geometries/concepts/multi_linestring_concept.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_LINESTRING_CONCEPT_HPP #define BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_LINESTRING_CONCEPT_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/geometries/concepts/multi_point_concept.hpp b/include/boost/geometry/multi/geometries/concepts/multi_point_concept.hpp index 14c1d25e57..0fd0bb78d9 100644 --- a/include/boost/geometry/multi/geometries/concepts/multi_point_concept.hpp +++ b/include/boost/geometry/multi/geometries/concepts/multi_point_concept.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_POINT_CONCEPT_HPP #define BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_POINT_CONCEPT_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/geometries/concepts/multi_polygon_concept.hpp b/include/boost/geometry/multi/geometries/concepts/multi_polygon_concept.hpp index 5e46fb7539..3f0c1f72df 100644 --- a/include/boost/geometry/multi/geometries/concepts/multi_polygon_concept.hpp +++ b/include/boost/geometry/multi/geometries/concepts/multi_polygon_concept.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_POLYGON_CONCEPT_HPP #define BOOST_GEOMETRY_MULTI_GEOMETRIES_CONCEPTS_MULTI_POLYGON_CONCEPT_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/geometries/multi_geometries.hpp b/include/boost/geometry/multi/geometries/multi_geometries.hpp index 53042091bd..f94b6526e2 100644 --- a/include/boost/geometry/multi/geometries/multi_geometries.hpp +++ b/include/boost/geometry/multi/geometries/multi_geometries.hpp @@ -14,6 +14,9 @@ #ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_GEOMETRIES_HPP #define BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_GEOMETRIES_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") + #include #include #include diff --git a/include/boost/geometry/multi/geometries/multi_linestring.hpp b/include/boost/geometry/multi/geometries/multi_linestring.hpp index 696d907dcc..758e45e4c7 100644 --- a/include/boost/geometry/multi/geometries/multi_linestring.hpp +++ b/include/boost/geometry/multi/geometries/multi_linestring.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_LINESTRING_HPP #define BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_LINESTRING_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/geometries/multi_point.hpp b/include/boost/geometry/multi/geometries/multi_point.hpp index 750ad7802a..e547c8e9cd 100644 --- a/include/boost/geometry/multi/geometries/multi_point.hpp +++ b/include/boost/geometry/multi/geometries/multi_point.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_POINT_HPP #define BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_POINT_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/geometries/multi_polygon.hpp b/include/boost/geometry/multi/geometries/multi_polygon.hpp index 06fefc7856..71cb38cb86 100644 --- a/include/boost/geometry/multi/geometries/multi_polygon.hpp +++ b/include/boost/geometry/multi/geometries/multi_polygon.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_POLYGON_HPP #define BOOST_GEOMETRY_MULTI_GEOMETRIES_MULTI_POLYGON_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/geometries/register/multi_linestring.hpp b/include/boost/geometry/multi/geometries/register/multi_linestring.hpp index 2783a8455b..005b910e7c 100644 --- a/include/boost/geometry/multi/geometries/register/multi_linestring.hpp +++ b/include/boost/geometry/multi/geometries/register/multi_linestring.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_LINESTRING_HPP #define BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_LINESTRING_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/geometries/register/multi_point.hpp b/include/boost/geometry/multi/geometries/register/multi_point.hpp index 6063492c2b..2560fa02ee 100644 --- a/include/boost/geometry/multi/geometries/register/multi_point.hpp +++ b/include/boost/geometry/multi/geometries/register/multi_point.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_POINT_HPP #define BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_POINT_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/geometries/register/multi_polygon.hpp b/include/boost/geometry/multi/geometries/register/multi_polygon.hpp index 6a3e47e3da..2549333b3e 100644 --- a/include/boost/geometry/multi/geometries/register/multi_polygon.hpp +++ b/include/boost/geometry/multi/geometries/register/multi_polygon.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_POLYGON_HPP #define BOOST_GEOMETRY_MULTI_GEOMETRIES_REGISTER_MULTI_POLYGON_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/io/dsv/write.hpp b/include/boost/geometry/multi/io/dsv/write.hpp index 092869f56c..cd4a96d0f3 100644 --- a/include/boost/geometry/multi/io/dsv/write.hpp +++ b/include/boost/geometry/multi/io/dsv/write.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_IO_DSV_WRITE_HPP #define BOOST_GEOMETRY_MULTI_IO_DSV_WRITE_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/io/wkt/detail/prefix.hpp b/include/boost/geometry/multi/io/wkt/detail/prefix.hpp deleted file mode 100644 index ee6b37e592..0000000000 --- a/include/boost/geometry/multi/io/wkt/detail/prefix.hpp +++ /dev/null @@ -1,20 +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. - -// 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_MULTI_IO_WKT_DETAIL_PREFIX_HPP -#define BOOST_GEOMETRY_MULTI_IO_WKT_DETAIL_PREFIX_HPP - -#include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") - -#endif // BOOST_GEOMETRY_MULTI_IO_WKT_DETAIL_PREFIX_HPP diff --git a/include/boost/geometry/multi/io/wkt/read.hpp b/include/boost/geometry/multi/io/wkt/read.hpp index 37e5f9e72e..9fe026cca4 100644 --- a/include/boost/geometry/multi/io/wkt/read.hpp +++ b/include/boost/geometry/multi/io/wkt/read.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_IO_WKT_READ_MULTI_HPP #define BOOST_GEOMETRY_MULTI_IO_WKT_READ_MULTI_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/io/wkt/wkt.hpp b/include/boost/geometry/multi/io/wkt/wkt.hpp index a6159e1409..5d4fcc8e0c 100644 --- a/include/boost/geometry/multi/io/wkt/wkt.hpp +++ b/include/boost/geometry/multi/io/wkt/wkt.hpp @@ -14,6 +14,9 @@ #ifndef BOOST_GEOMETRY_MULTI_IO_WKT_WKT_HPP #define BOOST_GEOMETRY_MULTI_IO_WKT_WKT_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") + #include #include diff --git a/include/boost/geometry/multi/io/wkt/write.hpp b/include/boost/geometry/multi/io/wkt/write.hpp index 2c26d3d2e4..c83e337b39 100644 --- a/include/boost/geometry/multi/io/wkt/write.hpp +++ b/include/boost/geometry/multi/io/wkt/write.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_IO_WKT_WRITE_HPP #define BOOST_GEOMETRY_MULTI_IO_WKT_WRITE_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/multi/multi.hpp b/include/boost/geometry/multi/multi.hpp index 85d763ee6e..d9f15bd28a 100644 --- a/include/boost/geometry/multi/multi.hpp +++ b/include/boost/geometry/multi/multi.hpp @@ -17,6 +17,9 @@ #ifndef BOOST_GEOMETRY_MULTI_HPP #define BOOST_GEOMETRY_MULTI_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") + // keep this file for now, for backward compatibility // functionality-wise, make it equivalent to boost/geometry/geometry.hpp #include diff --git a/include/boost/geometry/multi/strategies/cartesian/centroid_average.hpp b/include/boost/geometry/multi/strategies/cartesian/centroid_average.hpp index ce614e2e76..1d7476b687 100644 --- a/include/boost/geometry/multi/strategies/cartesian/centroid_average.hpp +++ b/include/boost/geometry/multi/strategies/cartesian/centroid_average.hpp @@ -14,6 +14,8 @@ #ifndef BOOST_GEOMETRY_MULTI_STRATEGIES_CARTESIAN_CENTROID_AVERAGE_HPP #define BOOST_GEOMETRY_MULTI_STRATEGIES_CARTESIAN_CENTROID_AVERAGE_HPP +#include +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/policies/is_valid/failing_reason_policy.hpp b/include/boost/geometry/policies/is_valid/failing_reason_policy.hpp index 701e72c2d3..89292a47f7 100644 --- a/include/boost/geometry/policies/is_valid/failing_reason_policy.hpp +++ b/include/boost/geometry/policies/is_valid/failing_reason_policy.hpp @@ -181,12 +181,11 @@ class failing_reason_policy static inline void apply(std::ostringstream& oss, Point const& point) { - if BOOST_GEOMETRY_CONSTEXPR (AllowDuplicates) + if BOOST_GEOMETRY_CONSTEXPR (! AllowDuplicates) { - return; + oss << ". Duplicate points were found near point " + << geometry::dsv(point); } - oss << ". Duplicate points were found near point " - << geometry::dsv(point); } }; diff --git a/include/boost/geometry/policies/relate/direction.hpp b/include/boost/geometry/policies/relate/direction.hpp index 2c903bd79f..11c18d6e48 100644 --- a/include/boost/geometry/policies/relate/direction.hpp +++ b/include/boost/geometry/policies/relate/direction.hpp @@ -163,6 +163,14 @@ struct segments_direction ; } + template + static inline return_type segments_share_common_point(side_info const& sides, + SegmentIntersectionInfo const& , + Point const&) + { + return segments_crosses(sides, sides, sides, sides); + } + template static inline int arrival_value(Ratio const& r_from, Ratio const& r_to) { diff --git a/include/boost/geometry/policies/relate/intersection_points.hpp b/include/boost/geometry/policies/relate/intersection_points.hpp index 1d7671ddfd..1b11c59f4e 100644 --- a/include/boost/geometry/policies/relate/intersection_points.hpp +++ b/include/boost/geometry/policies/relate/intersection_points.hpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -61,6 +62,21 @@ struct segments_intersection_points return result; } + template + static inline return_type + segments_share_common_point(side_info const&, SegmentIntersectionInfo const& sinfo, + Point const& p) + { + return_type result; + result.count = 1; + boost::geometry::assign(result.intersections[0], p); + + // Temporary - this should go later + result.fractions[0].assign(sinfo); + + return result; + } + template static inline return_type segments_collinear( Segment1 const& a, Segment2 const& b, bool /*opposite*/, diff --git a/include/boost/geometry/policies/relate/intersection_policy.hpp b/include/boost/geometry/policies/relate/intersection_policy.hpp index 6afffc20c1..6a573f9f20 100644 --- a/include/boost/geometry/policies/relate/intersection_policy.hpp +++ b/include/boost/geometry/policies/relate/intersection_policy.hpp @@ -67,6 +67,19 @@ struct segments_intersection_policy ); } + template + static inline return_type + segments_share_common_point(side_info const& sides, + SegmentIntersectionInfo const& sinfo, + Point const& p) + { + return return_type + ( + pts_policy::segments_share_common_point(sides, sinfo, p), + dir_policy::segments_share_common_point(sides, sinfo, p) + ); + } + template static inline return_type segments_collinear( Segment1 const& segment1, diff --git a/include/boost/geometry/policies/relate/intersection_ratios.hpp b/include/boost/geometry/policies/relate/intersection_ratios.hpp index 81ecba0b54..0d4f4f1413 100644 --- a/include/boost/geometry/policies/relate/intersection_ratios.hpp +++ b/include/boost/geometry/policies/relate/intersection_ratios.hpp @@ -14,7 +14,6 @@ #include #include -#include #include #include @@ -55,6 +54,16 @@ struct segments_intersection_ratios return result; } + template + static inline return_type + segments_share_common_point(side_info const&, SegmentIntersectionInfo const& sinfo, + Point const& p) + { + return_type result; + result.assign(sinfo); + return result; + } + template static inline return_type segments_collinear( Segment1 const& , Segment2 const& , diff --git a/include/boost/geometry/policies/robustness/get_rescale_policy.hpp b/include/boost/geometry/policies/robustness/get_rescale_policy.hpp index 5e1dd5e4d0..aabf3d3568 100644 --- a/include/boost/geometry/policies/robustness/get_rescale_policy.hpp +++ b/include/boost/geometry/policies/robustness/get_rescale_policy.hpp @@ -38,6 +38,7 @@ #include #include #include +#include #include // TEMP @@ -70,7 +71,7 @@ inline void scale_box_to_integer_range(Box const& box, < typename geometry::coordinate_type::type >::type num_type; - num_type const diff = boost::numeric_cast(detail::get_max_size(box)); + num_type const diff = util::numeric_cast(detail::get_max_size(box)); num_type const range = 10000000.0; // Define a large range to get precise integer coordinates num_type const half = 0.5; if (math::equals(diff, num_type()) @@ -81,8 +82,8 @@ inline void scale_box_to_integer_range(Box const& box, } else { - factor = boost::numeric_cast( - boost::numeric_cast(half + range / diff)); + factor = util::numeric_cast( + util::numeric_cast(half + range / diff)); BOOST_GEOMETRY_ASSERT(factor >= 1); } @@ -90,7 +91,7 @@ inline void scale_box_to_integer_range(Box const& box, detail::assign_point_from_index<0>(box, min_point); num_type const two = 2; boost::long_long_type const min_coordinate - = boost::numeric_cast(-range / two); + = util::numeric_cast(-range / two); assign_values(min_robust_point, min_coordinate, min_coordinate); } diff --git a/include/boost/geometry/policies/robustness/segment_ratio.hpp b/include/boost/geometry/policies/robustness/segment_ratio.hpp index 5a75fad014..5b09f6c4e5 100644 --- a/include/boost/geometry/policies/robustness/segment_ratio.hpp +++ b/include/boost/geometry/policies/robustness/segment_ratio.hpp @@ -21,6 +21,8 @@ #include #include #include +#include + namespace boost { namespace geometry { @@ -227,8 +229,8 @@ class segment_ratio m_approximation = m_denominator == zero_instance() ? floating_point_type{0} : ( - boost::numeric_cast(m_numerator) * scale() - / boost::numeric_cast(m_denominator) + util::numeric_cast(m_numerator) * scale() + / util::numeric_cast(m_denominator) ); } diff --git a/include/boost/geometry/srs/projections/impl/pj_transform.hpp b/include/boost/geometry/srs/projections/impl/pj_transform.hpp index b4f14c80b5..9f16c0e6f6 100644 --- a/include/boost/geometry/srs/projections/impl/pj_transform.hpp +++ b/include/boost/geometry/srs/projections/impl/pj_transform.hpp @@ -252,7 +252,7 @@ inline bool pj_transform(SrcPrj const& srcprj, Par const& srcdefn, /* -------------------------------------------------------------------- */ /* Transform Z to meters if it isn't already. */ /* -------------------------------------------------------------------- */ - if( BOOST_GEOMETRY_CONDITION(srcdefn.vto_meter != 1.0 && dimension > 2) ) + if( srcdefn.vto_meter != 1.0 && BOOST_GEOMETRY_CONDITION(dimension > 2) ) { for( std::size_t i = 0; i < point_count; i++ ) { @@ -589,7 +589,7 @@ inline bool pj_transform(SrcPrj const& srcprj, Par const& srcdefn, /* -------------------------------------------------------------------- */ /* Transform Z from meters if needed. */ /* -------------------------------------------------------------------- */ - if( dstdefn.vto_meter != 1.0 && dimension > 2 ) + if( dstdefn.vto_meter != 1.0 && BOOST_GEOMETRY_CONDITION(dimension > 2) ) { for( std::size_t i = 0; i < point_count; i++ ) { diff --git a/include/boost/geometry/strategies/area.hpp b/include/boost/geometry/strategies/area.hpp index 9e0cd01b4a..b2c7a440ab 100644 --- a/include/boost/geometry/strategies/area.hpp +++ b/include/boost/geometry/strategies/area.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/area_result.hpp b/include/boost/geometry/strategies/area_result.hpp index e15a116ae3..7b6f915d29 100644 --- a/include/boost/geometry/strategies/area_result.hpp +++ b/include/boost/geometry/strategies/area_result.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/cartesian/area.hpp b/include/boost/geometry/strategies/cartesian/area.hpp index a19738c0a7..6dee57d6cd 100644 --- a/include/boost/geometry/strategies/cartesian/area.hpp +++ b/include/boost/geometry/strategies/cartesian/area.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/cartesian/area_surveyor.hpp b/include/boost/geometry/strategies/cartesian/area_surveyor.hpp index 181d66f73d..d10e945dc1 100644 --- a/include/boost/geometry/strategies/cartesian/area_surveyor.hpp +++ b/include/boost/geometry/strategies/cartesian/area_surveyor.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/cartesian/buffer_end_round.hpp b/include/boost/geometry/strategies/cartesian/buffer_end_round.hpp index 47ecb22e72..fd52eb2596 100644 --- a/include/boost/geometry/strategies/cartesian/buffer_end_round.hpp +++ b/include/boost/geometry/strategies/cartesian/buffer_end_round.hpp @@ -165,7 +165,7 @@ public : return distance; } - //! Returns the piece_type (flat end) + //! Returns the piece_type (round end) static inline piece_type get_piece_type() { return buffered_round_end; diff --git a/include/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp b/include/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp index d4713da92d..45138b9da7 100644 --- a/include/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp +++ b/include/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp @@ -22,13 +22,13 @@ #include #include -#include #include #include #include #include #include +#include #include @@ -190,10 +190,10 @@ public : typedef typename calculation_type::type calc_type; // Get coordinates and promote them to calculation_type - calc_type const x1 = boost::numeric_cast(get<0>(p1)); - calc_type const y1 = boost::numeric_cast(get<1>(p1)); - calc_type const x2 = boost::numeric_cast(get<0>(p2)); - calc_type const y2 = boost::numeric_cast(get<1>(p2)); + calc_type const x1 = util::numeric_cast(get<0>(p1)); + calc_type const y1 = util::numeric_cast(get<1>(p1)); + calc_type const x2 = util::numeric_cast(get<0>(p2)); + calc_type const y2 = util::numeric_cast(get<1>(p2)); calc_type const ai = geometry::detail::determinant(p1, p2); state.count++; state.sum_a2 += ai; @@ -225,9 +225,9 @@ public : // which means that the centroid can still be filled with INF // if e.g. calculation_type is double and centroid contains floats set<0>(centroid, - boost::numeric_cast(state.sum_x / a3)); + util::numeric_cast(state.sum_x / a3)); set<1>(centroid, - boost::numeric_cast(state.sum_y / a3)); + util::numeric_cast(state.sum_y / a3)); return true; } } diff --git a/include/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp b/include/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp index 477d68b892..3bf16a4c00 100644 --- a/include/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp +++ b/include/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp @@ -19,7 +19,6 @@ #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP #include -#include #include @@ -32,6 +31,7 @@ #include #include +#include #include @@ -132,7 +132,7 @@ public : typedef typename geometry::coordinate_type::type coordinate_type; geometry::set( centroid, - boost::numeric_cast( + util::numeric_cast( geometry::get(state.average_sum) / state.length ) ); diff --git a/include/boost/geometry/strategies/cartesian/densify.hpp b/include/boost/geometry/strategies/cartesian/densify.hpp index a6bc0a793f..4d18e1f0cf 100644 --- a/include/boost/geometry/strategies/cartesian/densify.hpp +++ b/include/boost/geometry/strategies/cartesian/densify.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -68,8 +69,8 @@ class cartesian // dir01 = p1 - p0 geometry::detail::for_each_dimension([&](auto index) { - calc_t const coord0 = boost::numeric_cast(get(p0)); - calc_t const coord1 = boost::numeric_cast(get(p1)); + calc_t const coord0 = util::numeric_cast(get(p0)); + calc_t const coord1 = util::numeric_cast(get(p1)); set(cp0, coord0); set(dir01, coord1 - coord0); }); @@ -96,7 +97,7 @@ class cartesian // out = p0 + d * dir01 calc_t const coord = get(cp0) + get(dir01) * num / den; - set(out, boost::numeric_cast(coord)); + set(out, util::numeric_cast(coord)); }); policy.apply(out); diff --git a/include/boost/geometry/strategies/cartesian/disjoint_segment_box.hpp b/include/boost/geometry/strategies/cartesian/disjoint_segment_box.hpp index d903f21008..ee041d2542 100644 --- a/include/boost/geometry/strategies/cartesian/disjoint_segment_box.hpp +++ b/include/boost/geometry/strategies/cartesian/disjoint_segment_box.hpp @@ -23,11 +23,6 @@ #include #include -#include - -#include -#include - #include #include #include @@ -38,6 +33,9 @@ #include #include +#include +#include +#include namespace boost { namespace geometry { namespace strategy { namespace disjoint { @@ -62,22 +60,22 @@ struct compute_tmin_tmax_per_dim SegmentPoint >::type point_coordinate_type; - RelativeDistance c_p0 = boost::numeric_cast + RelativeDistance c_p0 = util::numeric_cast < point_coordinate_type >( geometry::get(p0) ); - RelativeDistance c_p1 = boost::numeric_cast + RelativeDistance c_p1 = util::numeric_cast < point_coordinate_type >( geometry::get(p1) ); - RelativeDistance c_b_min = boost::numeric_cast + RelativeDistance c_b_min = util::numeric_cast < box_coordinate_type >( geometry::get(box) ); - RelativeDistance c_b_max = boost::numeric_cast + RelativeDistance c_b_max = util::numeric_cast < box_coordinate_type >( geometry::get(box) ); diff --git a/include/boost/geometry/strategies/cartesian/distance_pythagoras.hpp b/include/boost/geometry/strategies/cartesian/distance_pythagoras.hpp index 8d8b954362..c7e77bb1db 100644 --- a/include/boost/geometry/strategies/cartesian/distance_pythagoras.hpp +++ b/include/boost/geometry/strategies/cartesian/distance_pythagoras.hpp @@ -26,8 +26,9 @@ #include -#include #include +#include +#include namespace boost { namespace geometry @@ -46,8 +47,8 @@ struct compute_pythagoras template static inline T apply(Point1 const& p1, Point2 const& p2) { - T const c1 = boost::numeric_cast(get(p1)); - T const c2 = boost::numeric_cast(get(p2)); + T const c1 = util::numeric_cast(get(p1)); + T const c2 = util::numeric_cast(get(p2)); T const d = c1 - c2; return d * d + compute_pythagoras::apply(p1, p2); } @@ -59,7 +60,7 @@ struct compute_pythagoras<0, T> template static inline T apply(Point1 const&, Point2 const&) { - return boost::numeric_cast(0); + return util::numeric_cast(0); } }; @@ -163,7 +164,7 @@ public : // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call return math::sqrt ( - boost::numeric_cast::type> + util::numeric_cast::type> ( comparable::pythagoras::apply(p1, p2) ) diff --git a/include/boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp b/include/boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp index 96a4ef027d..61545fa2a9 100644 --- a/include/boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp +++ b/include/boost/geometry/strategies/cartesian/distance_pythagoras_box_box.hpp @@ -28,9 +28,9 @@ #include -#include #include - +#include +#include namespace boost { namespace geometry @@ -50,14 +50,14 @@ struct compute_pythagoras_box_box static inline void apply(Box1 const& box1, Box2 const& box2, T& result) { T const b1_min_coord = - boost::numeric_cast(geometry::get(box1)); + util::numeric_cast(geometry::get(box1)); T const b1_max_coord = - boost::numeric_cast(geometry::get(box1)); + util::numeric_cast(geometry::get(box1)); T const b2_min_coord = - boost::numeric_cast(geometry::get(box2)); + util::numeric_cast(geometry::get(box2)); T const b2_max_coord = - boost::numeric_cast(geometry::get(box2)); + util::numeric_cast(geometry::get(box2)); if ( b1_max_coord < b2_min_coord ) { @@ -187,7 +187,7 @@ public : // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call return math::sqrt ( - boost::numeric_cast::type> diff --git a/include/boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp b/include/boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp index 719569d558..c9115a6cbb 100644 --- a/include/boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp +++ b/include/boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp @@ -28,9 +28,9 @@ #include -#include #include - +#include +#include namespace boost { namespace geometry @@ -49,11 +49,11 @@ struct compute_pythagoras_point_box template static inline void apply(Point const& point, Box const& box, T& result) { - T const p_coord = boost::numeric_cast(geometry::get(point)); + T const p_coord = util::numeric_cast(geometry::get(point)); T const b_min_coord = - boost::numeric_cast(geometry::get(box)); + util::numeric_cast(geometry::get(box)); T const b_max_coord = - boost::numeric_cast(geometry::get(box)); + util::numeric_cast(geometry::get(box)); if ( p_coord < b_min_coord ) { @@ -182,7 +182,7 @@ public : // The cast is necessary for MSVC which considers sqrt __int64 as an ambiguous call return math::sqrt ( - boost::numeric_cast::type> diff --git a/include/boost/geometry/strategies/cartesian/envelope.hpp b/include/boost/geometry/strategies/cartesian/envelope.hpp index 0e07e84256..0b3cad7a60 100644 --- a/include/boost/geometry/strategies/cartesian/envelope.hpp +++ b/include/boost/geometry/strategies/cartesian/envelope.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/cartesian/envelope_box.hpp b/include/boost/geometry/strategies/cartesian/envelope_box.hpp index de7d186f6d..daf96f59f7 100644 --- a/include/boost/geometry/strategies/cartesian/envelope_box.hpp +++ b/include/boost/geometry/strategies/cartesian/envelope_box.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/cartesian/envelope_multipoint.hpp b/include/boost/geometry/strategies/cartesian/envelope_multipoint.hpp index 835bb56c51..2722a41326 100644 --- a/include/boost/geometry/strategies/cartesian/envelope_multipoint.hpp +++ b/include/boost/geometry/strategies/cartesian/envelope_multipoint.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/cartesian/envelope_point.hpp b/include/boost/geometry/strategies/cartesian/envelope_point.hpp index 1abd002820..26b157786d 100644 --- a/include/boost/geometry/strategies/cartesian/envelope_point.hpp +++ b/include/boost/geometry/strategies/cartesian/envelope_point.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/cartesian/envelope_segment.hpp b/include/boost/geometry/strategies/cartesian/envelope_segment.hpp index b2951a5faa..0d709f7f96 100644 --- a/include/boost/geometry/strategies/cartesian/envelope_segment.hpp +++ b/include/boost/geometry/strategies/cartesian/envelope_segment.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/cartesian/expand_box.hpp b/include/boost/geometry/strategies/cartesian/expand_box.hpp index 2e9cf2df90..14218f7778 100644 --- a/include/boost/geometry/strategies/cartesian/expand_box.hpp +++ b/include/boost/geometry/strategies/cartesian/expand_box.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/cartesian/expand_point.hpp b/include/boost/geometry/strategies/cartesian/expand_point.hpp index 1f067d27b7..dc46cf0581 100644 --- a/include/boost/geometry/strategies/cartesian/expand_point.hpp +++ b/include/boost/geometry/strategies/cartesian/expand_point.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/cartesian/expand_segment.hpp b/include/boost/geometry/strategies/cartesian/expand_segment.hpp index b658779767..427d3a21e1 100644 --- a/include/boost/geometry/strategies/cartesian/expand_segment.hpp +++ b/include/boost/geometry/strategies/cartesian/expand_segment.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/cartesian/intersection.hpp b/include/boost/geometry/strategies/cartesian/intersection.hpp index 94d33401c5..f712d3121b 100644 --- a/include/boost/geometry/strategies/cartesian/intersection.hpp +++ b/include/boost/geometry/strategies/cartesian/intersection.hpp @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -177,17 +178,17 @@ struct cartesian_segments typedef typename promote_integral::type calc_type; calc_type const numerator - = boost::numeric_cast(ratio.numerator()); + = util::numeric_cast(ratio.numerator()); calc_type const denominator - = boost::numeric_cast(ratio.denominator()); - calc_type const dx_calc = boost::numeric_cast(dx); - calc_type const dy_calc = boost::numeric_cast(dy); + = util::numeric_cast(ratio.denominator()); + calc_type const dx_calc = util::numeric_cast(dx); + calc_type const dy_calc = util::numeric_cast(dy); set<0>(point, get<0, 0>(segment) - + boost::numeric_cast( + + util::numeric_cast( math::divide(numerator * dx_calc, denominator))); set<1>(point, get<0, 1>(segment) - + boost::numeric_cast( + + util::numeric_cast( math::divide(numerator * dy_calc, denominator))); } @@ -459,6 +460,7 @@ struct cartesian_segments bool collinear = sides.collinear(); + //TODO: remove this when rescaling is removed // Calculate the differences again // (for rescaled version, this is different from dx_p etc) coordinate_type const dx_p = get<0>(p2) - get<0>(p1); @@ -533,6 +535,16 @@ struct cartesian_segments } } + if (equals_point_point(p1, q1) || equals_point_point(p1, q2)) + { + return Policy::segments_share_common_point(sides, sinfo, p1); + } + + if (equals_point_point(p2, q1) || equals_point_point(p2, q2)) + { + return Policy::segments_share_common_point(sides, sinfo, p2); + } + return Policy::segments_crosses(sides, sinfo, p, q); } diff --git a/include/boost/geometry/strategies/cartesian/line_interpolate.hpp b/include/boost/geometry/strategies/cartesian/line_interpolate.hpp index bc55da8fa1..a63cb85488 100644 --- a/include/boost/geometry/strategies/cartesian/line_interpolate.hpp +++ b/include/boost/geometry/strategies/cartesian/line_interpolate.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -67,10 +68,10 @@ class cartesian // NOTE: numeric_cast is a leftover from convert, it could probably be ommited. // NOTE: the order of points is different than in the formula above // this is also a leftover from the previous implementation - calc_t coord0 = boost::numeric_cast(get(p0)); - calc_t coord1 = boost::numeric_cast(get(p1)); + calc_t coord0 = util::numeric_cast(get(p0)); + calc_t coord1 = util::numeric_cast(get(p1)); calc_t result = calc_t(coord1 * fraction) + calc_t(coord0 * one_minus_fraction); - set(p, boost::numeric_cast(result)); + set(p, util::numeric_cast(result)); }); } }; diff --git a/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp b/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp index 848570fd9b..423a194a0e 100644 --- a/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp +++ b/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/convex_hull/cartesian.hpp b/include/boost/geometry/strategies/convex_hull/cartesian.hpp index 5bf46f2110..62d7a93cf9 100644 --- a/include/boost/geometry/strategies/convex_hull/cartesian.hpp +++ b/include/boost/geometry/strategies/convex_hull/cartesian.hpp @@ -46,7 +46,7 @@ class cartesian : public strategies::detail::cartesian_base static auto side() { using side_strategy_type - = strategy::side::side_robust; + = strategy::side::side_robust; return side_strategy_type(); } diff --git a/include/boost/geometry/strategies/default_area_result.hpp b/include/boost/geometry/strategies/default_area_result.hpp index 21561f326a..fbf6bbdd60 100644 --- a/include/boost/geometry/strategies/default_area_result.hpp +++ b/include/boost/geometry/strategies/default_area_result.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/envelope.hpp b/include/boost/geometry/strategies/envelope.hpp index 5cbc80361a..884db64433 100644 --- a/include/boost/geometry/strategies/envelope.hpp +++ b/include/boost/geometry/strategies/envelope.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/expand.hpp b/include/boost/geometry/strategies/expand.hpp index 0a5b21125c..5c94d91802 100644 --- a/include/boost/geometry/strategies/expand.hpp +++ b/include/boost/geometry/strategies/expand.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/geographic/area.hpp b/include/boost/geometry/strategies/geographic/area.hpp index 600c739454..7edf868204 100644 --- a/include/boost/geometry/strategies/geographic/area.hpp +++ b/include/boost/geometry/strategies/geographic/area.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/geographic/buffer_end_round.hpp b/include/boost/geometry/strategies/geographic/buffer_end_round.hpp index 1d6c8d197a..2191e96e15 100644 --- a/include/boost/geometry/strategies/geographic/buffer_end_round.hpp +++ b/include/boost/geometry/strategies/geographic/buffer_end_round.hpp @@ -134,7 +134,7 @@ public : return distance; } - //! Returns the piece_type (flat end) + //! Returns the piece_type (round end) static inline piece_type get_piece_type() { return buffered_round_end; diff --git a/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp b/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp index d7ea122a34..e62e5a3d7e 100644 --- a/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp +++ b/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp @@ -16,8 +16,6 @@ #include #include -#include - #include #include diff --git a/include/boost/geometry/strategies/geographic/envelope.hpp b/include/boost/geometry/strategies/geographic/envelope.hpp index b6dc642de4..67ea6be9fa 100644 --- a/include/boost/geometry/strategies/geographic/envelope.hpp +++ b/include/boost/geometry/strategies/geographic/envelope.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/geographic/envelope_segment.hpp b/include/boost/geometry/strategies/geographic/envelope_segment.hpp index 8afe6959e8..d9139ffa05 100644 --- a/include/boost/geometry/strategies/geographic/envelope_segment.hpp +++ b/include/boost/geometry/strategies/geographic/envelope_segment.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/geographic/expand_segment.hpp b/include/boost/geometry/strategies/geographic/expand_segment.hpp index 20c327602d..3e573c47b5 100644 --- a/include/boost/geometry/strategies/geographic/expand_segment.hpp +++ b/include/boost/geometry/strategies/geographic/expand_segment.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/normalize.hpp b/include/boost/geometry/strategies/normalize.hpp index a722b1fe0a..0b45069983 100644 --- a/include/boost/geometry/strategies/normalize.hpp +++ b/include/boost/geometry/strategies/normalize.hpp @@ -14,8 +14,6 @@ #include #include -#include - #include #include #include @@ -25,6 +23,7 @@ #include #include +#include #include @@ -57,7 +56,7 @@ struct assign_loop PointIn const& point_in, PointOut& point_out) { - geometry::set(point_out, boost::numeric_cast + geometry::set(point_out, util::numeric_cast < typename coordinate_type::type >(geometry::get(point_in))); @@ -90,7 +89,7 @@ struct assign_loop<0, DimensionCount> PointIn const& point_in, PointOut& point_out) { - geometry::set<0>(point_out, boost::numeric_cast + geometry::set<0>(point_out, util::numeric_cast < typename coordinate_type::type >(longitude)); @@ -111,7 +110,7 @@ struct assign_loop<1, DimensionCount> PointIn const& point_in, PointOut& point_out) { - geometry::set<1>(point_out, boost::numeric_cast + geometry::set<1>(point_out, util::numeric_cast < typename coordinate_type::type >(latitude)); diff --git a/include/boost/geometry/strategies/relate.hpp b/include/boost/geometry/strategies/relate.hpp index 7d388eb513..de1a58b8d6 100644 --- a/include/boost/geometry/strategies/relate.hpp +++ b/include/boost/geometry/strategies/relate.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/spherical/area.hpp b/include/boost/geometry/strategies/spherical/area.hpp index e726d2392e..981c8fec36 100644 --- a/include/boost/geometry/strategies/spherical/area.hpp +++ b/include/boost/geometry/strategies/spherical/area.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp b/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp index 29b6bdaf59..dbb7fe8f6e 100644 --- a/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp +++ b/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp @@ -16,11 +16,6 @@ #include #include -#include - -#include -#include - #include #include #include @@ -36,6 +31,9 @@ #include #include +#include +#include + namespace boost { namespace geometry { namespace strategy { namespace disjoint { diff --git a/include/boost/geometry/strategies/spherical/distance_segment_box.hpp b/include/boost/geometry/strategies/spherical/distance_segment_box.hpp index c48377d77a..32ce3bcaaa 100644 --- a/include/boost/geometry/strategies/spherical/distance_segment_box.hpp +++ b/include/boost/geometry/strategies/spherical/distance_segment_box.hpp @@ -25,6 +25,9 @@ #include // spherical #include +#include + + namespace boost { namespace geometry { @@ -148,7 +151,7 @@ struct generic_segment_box if (less_equal(geometry::get_as_radian<0>(bottom_left), geometry::get_as_radian<0>(p_max))) { - result = boost::numeric_cast( + result = util::numeric_cast( strategies.distance(bottom_left, seg).apply(bottom_left, p0, p1)); } else diff --git a/include/boost/geometry/strategies/spherical/envelope.hpp b/include/boost/geometry/strategies/spherical/envelope.hpp index 7cc069b90a..510ec8a4af 100644 --- a/include/boost/geometry/strategies/spherical/envelope.hpp +++ b/include/boost/geometry/strategies/spherical/envelope.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/spherical/envelope_box.hpp b/include/boost/geometry/strategies/spherical/envelope_box.hpp index ba3f848507..4ea840ed99 100644 --- a/include/boost/geometry/strategies/spherical/envelope_box.hpp +++ b/include/boost/geometry/strategies/spherical/envelope_box.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/spherical/envelope_multipoint.hpp b/include/boost/geometry/strategies/spherical/envelope_multipoint.hpp index f057566aee..6fd64a5676 100644 --- a/include/boost/geometry/strategies/spherical/envelope_multipoint.hpp +++ b/include/boost/geometry/strategies/spherical/envelope_multipoint.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/spherical/envelope_point.hpp b/include/boost/geometry/strategies/spherical/envelope_point.hpp index cb6e2453be..05101073f4 100644 --- a/include/boost/geometry/strategies/spherical/envelope_point.hpp +++ b/include/boost/geometry/strategies/spherical/envelope_point.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/spherical/envelope_segment.hpp b/include/boost/geometry/strategies/spherical/envelope_segment.hpp index 8e9a099bbd..2eae6976a6 100644 --- a/include/boost/geometry/strategies/spherical/envelope_segment.hpp +++ b/include/boost/geometry/strategies/spherical/envelope_segment.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/spherical/expand_box.hpp b/include/boost/geometry/strategies/spherical/expand_box.hpp index 123542244d..10f8caa1ed 100644 --- a/include/boost/geometry/strategies/spherical/expand_box.hpp +++ b/include/boost/geometry/strategies/spherical/expand_box.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/spherical/expand_point.hpp b/include/boost/geometry/strategies/spherical/expand_point.hpp index b56d9fd186..e784f15ff2 100644 --- a/include/boost/geometry/strategies/spherical/expand_point.hpp +++ b/include/boost/geometry/strategies/spherical/expand_point.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/spherical/expand_segment.hpp b/include/boost/geometry/strategies/spherical/expand_segment.hpp index 19211e5dfb..e87bec450e 100644 --- a/include/boost/geometry/strategies/spherical/expand_segment.hpp +++ b/include/boost/geometry/strategies/spherical/expand_segment.hpp @@ -12,7 +12,7 @@ #include -BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.") +BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86") #include diff --git a/include/boost/geometry/strategies/spherical/point_order.hpp b/include/boost/geometry/strategies/spherical/point_order.hpp index 52450dc635..3f9eb8ce47 100644 --- a/include/boost/geometry/strategies/spherical/point_order.hpp +++ b/include/boost/geometry/strategies/spherical/point_order.hpp @@ -1,7 +1,8 @@ // Boost.Geometry -// Copyright (c) 2019-2020, Oracle and/or its affiliates. +// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2019-2020, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Licensed under the Boost Software License version 1.0. @@ -100,7 +101,7 @@ namespace strategy { namespace point_order // spherical_polar_tag // >::value; // -// if (BOOST_GEOMETRY_CONDITION(is_polar)) +// if BOOST_GEOMETRY_CONSTEXPR (is_polar) // { // CalcT pi_half = math::half_pi(); // lat1 = pi_half - lat1; diff --git a/include/boost/geometry/strategies/strategy_transform.hpp b/include/boost/geometry/strategies/strategy_transform.hpp index ee2216ac71..d095a374de 100644 --- a/include/boost/geometry/strategies/strategy_transform.hpp +++ b/include/boost/geometry/strategies/strategy_transform.hpp @@ -23,8 +23,6 @@ #include #include -#include - #include #include #include @@ -34,6 +32,7 @@ #include #include +#include #include namespace boost { namespace geometry @@ -60,7 +59,7 @@ struct transform_coordinates typedef typename select_coordinate_type::type coordinate_type; F function; - set(dest, boost::numeric_cast(function(get(source), value))); + set(dest, util::numeric_cast(function(get(source), value))); transform_coordinates::transform(source, dest, value); } }; diff --git a/include/boost/geometry/strategies/transform/map_transformer.hpp b/include/boost/geometry/strategies/transform/map_transformer.hpp index 01ea6168c5..101be83f28 100644 --- a/include/boost/geometry/strategies/transform/map_transformer.hpp +++ b/include/boost/geometry/strategies/transform/map_transformer.hpp @@ -18,6 +18,8 @@ #include #include +#include + namespace boost { namespace geometry { @@ -117,8 +119,8 @@ private : // Scale is in PIXELS/MAPUNITS (meters) W wdx = wx2 - wx1; W wdy = wy2 - wy1; - type sx = (px2 - px1) / boost::numeric_cast(wdx); - type sy = (py2 - py1) / boost::numeric_cast(wdy); + type sx = (px2 - px1) / util::numeric_cast(wdx); + type sy = (py2 - py1) / util::numeric_cast(wdy); if (SameScale) { diff --git a/include/boost/geometry/strategies/transform/matrix_transformers.hpp b/include/boost/geometry/strategies/transform/matrix_transformers.hpp index 70f11b889b..937cc14899 100644 --- a/include/boost/geometry/strategies/transform/matrix_transformers.hpp +++ b/include/boost/geometry/strategies/transform/matrix_transformers.hpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -61,7 +62,7 @@ struct set_point_from_vec static inline void apply(Point & p, Vector const& v) { typedef typename geometry::coordinate_type::type coord_t; - set(p, boost::numeric_cast(qvm::A(v))); + set(p, util::numeric_cast(qvm::A(v))); set_point_from_vec::apply(p, v); } }; @@ -197,8 +198,8 @@ public : ct const& c2 = get<1>(p1); typedef typename geometry::coordinate_type::type ct2; - set<0>(p2, boost::numeric_cast(c1 * qvm::A<0,0>(this->m_matrix) + c2 * qvm::A<0,1>(this->m_matrix) + qvm::A<0,2>(this->m_matrix))); - set<1>(p2, boost::numeric_cast(c1 * qvm::A<1,0>(this->m_matrix) + c2 * qvm::A<1,1>(this->m_matrix) + qvm::A<1,2>(this->m_matrix))); + set<0>(p2, util::numeric_cast(c1 * qvm::A<0,0>(this->m_matrix) + c2 * qvm::A<0,1>(this->m_matrix) + qvm::A<0,2>(this->m_matrix))); + set<1>(p2, util::numeric_cast(c1 * qvm::A<1,0>(this->m_matrix) + c2 * qvm::A<1,1>(this->m_matrix) + qvm::A<1,2>(this->m_matrix))); return true; } @@ -241,9 +242,9 @@ public : typedef typename geometry::coordinate_type::type ct2; - set<0>(p2, boost::numeric_cast( + set<0>(p2, util::numeric_cast( c1 * qvm::A<0,0>(this->m_matrix) + c2 * qvm::A<0,1>(this->m_matrix) + c3 * qvm::A<0,2>(this->m_matrix) + qvm::A<0,3>(this->m_matrix))); - set<1>(p2, boost::numeric_cast( + set<1>(p2, util::numeric_cast( c1 * qvm::A<1,0>(this->m_matrix) + c2 * qvm::A<1,1>(this->m_matrix) + c3 * qvm::A<1,2>(this->m_matrix) + qvm::A<1,3>(this->m_matrix))); return true; @@ -290,11 +291,11 @@ public : typedef typename geometry::coordinate_type::type ct2; - set<0>(p2, boost::numeric_cast( + set<0>(p2, util::numeric_cast( c1 * qvm::A<0,0>(this->m_matrix) + c2 * qvm::A<0,1>(this->m_matrix) + c3 * qvm::A<0,2>(this->m_matrix) + qvm::A<0,3>(this->m_matrix))); - set<1>(p2, boost::numeric_cast( + set<1>(p2, util::numeric_cast( c1 * qvm::A<1,0>(this->m_matrix) + c2 * qvm::A<1,1>(this->m_matrix) + c3 * qvm::A<1,2>(this->m_matrix) + qvm::A<1,3>(this->m_matrix))); - set<2>(p2, boost::numeric_cast( + set<2>(p2, util::numeric_cast( c1 * qvm::A<2,0>(this->m_matrix) + c2 * qvm::A<2,1>(this->m_matrix) + c3 * qvm::A<2,2>(this->m_matrix) + qvm::A<2,3>(this->m_matrix))); return true; diff --git a/include/boost/geometry/strategy/spherical/envelope_segment.hpp b/include/boost/geometry/strategy/spherical/envelope_segment.hpp index 428f0f71a7..49b36192fd 100644 --- a/include/boost/geometry/strategy/spherical/envelope_segment.hpp +++ b/include/boost/geometry/strategy/spherical/envelope_segment.hpp @@ -16,7 +16,6 @@ #include #include -#include #include @@ -40,6 +39,7 @@ #include #include +#include namespace boost { namespace geometry { namespace strategy { namespace envelope { @@ -288,22 +288,22 @@ class envelope_segment_impl geometry::set < min_corner, 0 - >(helper_mbr, boost::numeric_cast(lon1)); + >(helper_mbr, util::numeric_cast(lon1)); geometry::set < min_corner, 1 - >(helper_mbr, boost::numeric_cast(lat1)); + >(helper_mbr, util::numeric_cast(lat1)); geometry::set < max_corner, 0 - >(helper_mbr, boost::numeric_cast(lon2)); + >(helper_mbr, util::numeric_cast(lon2)); geometry::set < max_corner, 1 - >(helper_mbr, boost::numeric_cast(lat2)); + >(helper_mbr, util::numeric_cast(lat2)); geometry::detail::envelope::transform_units(helper_mbr, mbr); } diff --git a/include/boost/geometry/strategy/spherical/expand_box.hpp b/include/boost/geometry/strategy/spherical/expand_box.hpp index 9400f0cc4d..3e775d3099 100644 --- a/include/boost/geometry/strategy/spherical/expand_box.hpp +++ b/include/boost/geometry/strategy/spherical/expand_box.hpp @@ -38,6 +38,8 @@ #include +#include + #include namespace boost { namespace geometry diff --git a/include/boost/geometry/util/bounds.hpp b/include/boost/geometry/util/bounds.hpp new file mode 100644 index 0000000000..dbd3920ffb --- /dev/null +++ b/include/boost/geometry/util/bounds.hpp @@ -0,0 +1,28 @@ +// Boost.Geometry + +// Copyright (c) 2024 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_UTIL_BOUNDS_HPP +#define BOOST_GEOMETRY_UTIL_BOUNDS_HPP + +#include + +namespace boost { namespace geometry { namespace util +{ + +// Define a boost::geometry::util::bounds +// It might be specialized for other numeric types, for example Boost.Rational +template +struct bounds +{ + static CT lowest () { return boost::numeric::bounds::lowest(); } + static CT highest () { return boost::numeric::bounds::highest(); } +}; + +}}} // namespace boost::geometry::util + +#endif // BOOST_GEOMETRY_UTIL_BOUNDS_HPP diff --git a/include/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp b/include/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp index 59746653a6..8bae1ecf76 100644 --- a/include/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp +++ b/include/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp @@ -16,26 +16,20 @@ #include #include +#include #include namespace boost { namespace geometry { -template -struct bounds -{ - static CT lowest () { return boost::numeric::bounds::lowest(); } - static CT highest () { return boost::numeric::bounds::highest(); } -}; - template bool is_inverse_spheroidal_coordinates(Box const& box) { typedef typename point_type::type point_type; typedef typename coordinate_type::type bound_type; - bound_type high = bounds::highest(); - bound_type low = bounds::lowest(); + bound_type const high = util::bounds::highest(); + bound_type const low = util::bounds::lowest(); return (geometry::get<0, 0>(box) == high) && (geometry::get<0, 1>(box) == high) && diff --git a/include/boost/geometry/util/math.hpp b/include/boost/geometry/util/math.hpp index edd0f412c2..ed011da726 100644 --- a/include/boost/geometry/util/math.hpp +++ b/include/boost/geometry/util/math.hpp @@ -31,10 +31,10 @@ #include #include //#include -#include #include +#include #include namespace boost { namespace geometry @@ -351,7 +351,7 @@ struct square_root return square_root_for_fundamental_fp < double - >::apply(boost::numeric_cast(value)); + >::apply(util::numeric_cast(value)); } }; @@ -499,7 +499,7 @@ struct rounding_cast { static inline Result apply(Source const& v) { - return boost::numeric_cast(v); + return util::numeric_cast(v); } }; @@ -519,7 +519,7 @@ struct rounding_cast { static inline Result apply(Source const& v) { - return boost::numeric_cast(v < Source(0) ? + return util::numeric_cast(v < Source(0) ? v - Source(0.5) : v + Source(0.5)); } diff --git a/include/boost/geometry/util/numeric_cast.hpp b/include/boost/geometry/util/numeric_cast.hpp new file mode 100644 index 0000000000..3809ebae77 --- /dev/null +++ b/include/boost/geometry/util/numeric_cast.hpp @@ -0,0 +1,45 @@ +// Boost.Geometry + +// Copyright (c) 2024 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_UTIL_NUMERIC_CAST_HPP +#define BOOST_GEOMETRY_UTIL_NUMERIC_CAST_HPP + +#include + +namespace boost { namespace geometry { namespace util + +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +/// brief calls numeric cast +template +struct numeric_caster +{ + static inline Target apply(Source const& source) + { + return boost::numeric_cast(source); + } +}; + +} // namespace detail +#endif + +// Calls either boost::numeric_cast, or functionality specific for Boost.Geometry +// (such as rational_cast for Boost.Rational) +template +inline Target numeric_cast(Source const& source) +{ + return detail::numeric_caster::apply(source); +} + +}}} // namespace boost::geometry::util + +#endif // BOOST_GEOMETRY_UTIL_NUMERIC_CAST_HPP diff --git a/include/boost/geometry/util/precise_math.hpp b/include/boost/geometry/util/precise_math.hpp index fb1b078451..2d367e5527 100644 --- a/include/boost/geometry/util/precise_math.hpp +++ b/include/boost/geometry/util/precise_math.hpp @@ -328,7 +328,7 @@ inline RealNumber orient2dtail(vec2d const& p1, * std::numeric_limits::epsilon(); absolute_bound = C_relative_bound * magnitude + sub_bound * std::abs(det); det += (t1[0] * t2[1] + t2[0] * t1[1]) - (t3[0] * t4[1] + t4[0] * t3[1]); - if (Robustness == 2 || std::abs(det) >= absolute_bound) + if (BOOST_GEOMETRY_CONDITION(Robustness == 2) || std::abs(det) >= absolute_bound) { return det; //C estimate } @@ -457,7 +457,10 @@ RealNumber incircle(std::array const& p1, RealNumber det = A_13 * (A_21_x_A_32[0] - A_31_x_A_22[0]) + A_23 * (A_31_x_A_12[0] - A_11_x_A_32[0]) + A_33 * (A_11_x_A_22[0] - A_21_x_A_12[0]); - if(Robustness == 0) return det; + if (BOOST_GEOMETRY_CONDITION(Robustness == 0)) + { + return det; + } RealNumber magnitude = (std::abs(A_21_x_A_32[0]) + std::abs(A_31_x_A_22[0])) * A_13 @@ -585,7 +588,10 @@ RealNumber incircle(std::array const& p1, det = std::accumulate(det_expansion.begin(), det_expansion.begin() + det_expansion_nz, static_cast(0)); - if(Robustness == 1) return det; + if (BOOST_GEOMETRY_CONDITION(Robustness == 1)) + { + return det; + } RealNumber B_relative_bound = (2 + 12 * std::numeric_limits::epsilon()) * std::numeric_limits::epsilon(); diff --git a/include/boost/geometry/util/rational.hpp b/include/boost/geometry/util/rational.hpp index 2e8b751ad9..bfe6161e76 100644 --- a/include/boost/geometry/util/rational.hpp +++ b/include/boost/geometry/util/rational.hpp @@ -14,10 +14,13 @@ #ifndef BOOST_GEOMETRY_UTIL_RATIONAL_HPP #define BOOST_GEOMETRY_UTIL_RATIONAL_HPP +// Contains specializations for Boost.Rational + #include -#include +#include #include +#include #include @@ -110,70 +113,46 @@ struct select_most_precise, double> typedef typename boost::rational type; }; +namespace util +{ -}} // namespace boost::geometry - - -// Specializes boost::rational to boost::numeric::bounds -namespace boost { namespace numeric +#ifndef DOXYGEN_NO_DETAIL +namespace detail { -template -struct bounds > +// Specialize numeric_caster, needed for geomery::util::numeric_cast, for Boost.Rational +// Without it, code using Boost.Rational does not compile +template +struct numeric_caster> { - static inline rational lowest() + static inline Target apply(rational const& source) { - return rational(bounds::lowest(), 1); - } - static inline rational highest() - { - return rational(bounds::highest(), 1); + return boost::rational_cast(source); } }; -}} // namespace boost::numeric - +} // namespace detail +#endif -// Support for boost::numeric_cast to int and to double (necessary for SVG-mapper) -namespace boost { namespace numeric -{ -template -< - typename T, - typename Traits, - typename OverflowHandler, - typename Float2IntRounder, - typename RawConverter, - typename UserRangeChecker -> -struct converter, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker> +// Specializes geometry::util::bounds for Boost.Rational +// Without it, bounds contains (0,1) by default for Boost.Rational +template +struct bounds > { - static inline int convert(rational const& arg) + static inline rational lowest() { - return int(rational_cast(arg)); + return rational(bounds::lowest(), 1); } -}; - -template -< - typename T, - typename Traits, - typename OverflowHandler, - typename Float2IntRounder, - typename RawConverter, - typename UserRangeChecker -> -struct converter, Traits, OverflowHandler, Float2IntRounder, RawConverter, UserRangeChecker> -{ - static inline double convert(rational const& arg) + static inline rational highest() { - return rational_cast(arg); + return rational(bounds::highest(), 1); } }; +} // namespace util -}} +}} // namespace boost::geometry #endif // BOOST_GEOMETRY_UTIL_RATIONAL_HPP diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000000..11287a29ce --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,51 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +# This takes care of many (but not all) floating point differences on arm64/clang14 on Mac. +# It also lets running the tests much faster. +if (APPLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffp-contract=fast") +endif() + +function(boost_geometry_add_unit_test prefix item) + set(unit_test_name "boost_geometry_${prefix}_${item}") + add_executable(${unit_test_name} ${item}.cpp) + + # Add a dependendcy to Boost.Geometry + target_link_libraries(${unit_test_name} + PRIVATE + Boost::geometry) + + # For unit tests, add a dependency to the unit test framework (in header only mode) + target_link_libraries(${unit_test_name} + PRIVATE + Boost::included_unit_test_framework) + + # Include the main Geometry test folder and the current folder + target_include_directories(${unit_test_name} + PRIVATE + "${PROJECT_SOURCE_DIR}/test" + .) + + # To compile with C++14 + target_compile_features(${unit_test_name} PRIVATE cxx_std_14) + + # To be able to run ctest + add_test(NAME ${unit_test_name} COMMAND ${unit_test_name}) + + # Add a dependency to the global tests target + add_dependencies(tests ${unit_test_name}) + + # Inform the caller about the test name. It can then set defines, if necessary. + set(BOOST_GEOMETRY_UNIT_TEST_NAME ${unit_test_name} PARENT_SCOPE) +endfunction() + +if (NOT TARGET tests) + add_custom_target(tests) +endif() + +add_subdirectory(algorithms) +add_subdirectory(util) diff --git a/test/algorithms/CMakeLists.txt b/test/algorithms/CMakeLists.txt new file mode 100644 index 0000000000..de99aefde8 --- /dev/null +++ b/test/algorithms/CMakeLists.txt @@ -0,0 +1,15 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +add_subdirectory(area) +add_subdirectory(buffer) +add_subdirectory(convex_hull) +add_subdirectory(detail) +add_subdirectory(envelope_expand) +add_subdirectory(overlay) +add_subdirectory(relate) +add_subdirectory(set_operations) +add_subdirectory(within) diff --git a/test/algorithms/Jamfile b/test/algorithms/Jamfile index 65931a6f93..a73358971c 100644 --- a/test/algorithms/Jamfile +++ b/test/algorithms/Jamfile @@ -39,9 +39,6 @@ test-suite boost-geometry-algorithms [ run is_valid.cpp : : : : algorithms_is_valid ] [ run is_valid_failure.cpp : : : : algorithms_is_valid_failure ] [ run is_valid_geo.cpp : : : : algorithms_is_valid_geo ] - [ run is_valid.cpp : : : BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_is_valid_alternative ] - [ run is_valid_failure.cpp : : : BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_is_valid_failure_alternative ] - [ run is_valid_geo.cpp : : : BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_is_valid_geo_alternative ] [ run line_interpolate.cpp : : : : algorithms_line_interpolate ] [ run make.cpp : : : : algorithms_make ] [ run maximum_gap.cpp : : : : algorithms_maximum_gap ] diff --git a/test/algorithms/area/CMakeLists.txt b/test/algorithms/area/CMakeLists.txt new file mode 100644 index 0000000000..6c56365975 --- /dev/null +++ b/test/algorithms/area/CMakeLists.txt @@ -0,0 +1,23 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +foreach(item IN ITEMS + area + area_box_sg + area_multi + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() + +if (NOT APPLE) + # The results of these tests vary considerably on Apple/Darwin/arm64 using clang + foreach(item IN ITEMS + area_geo + area_sph_geo + ) + boost_geometry_add_unit_test("algorithms" ${item}) + endforeach() +endif() \ No newline at end of file diff --git a/test/algorithms/buffer/CMakeLists.txt b/test/algorithms/buffer/CMakeLists.txt new file mode 100644 index 0000000000..1fb93e5ae1 --- /dev/null +++ b/test/algorithms/buffer/CMakeLists.txt @@ -0,0 +1,49 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +foreach(item IN ITEMS + buffer + buffer_gc + buffer_variable_width + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() + +# Tests for all geometry types, cartesian, for one floating point type +foreach(item IN ITEMS + buffer_point + buffer_linestring + buffer_ring + buffer_polygon + buffer_multi_point + buffer_multi_polygon + buffer_multi_linestring + ) + boost_geometry_add_unit_test("algorithms" ${item}) + target_compile_definitions(${BOOST_GEOMETRY_UNIT_TEST_NAME} PRIVATE BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) +endforeach() + +# Tests for geographic and spherical +foreach(item IN ITEMS + buffer_point_geo + buffer_polygon_geo + buffer_multi_linestring_geo + buffer_multi_polygon_geo + buffer_geo_spheroid + ) + boost_geometry_add_unit_test("algorithms" ${item}) + target_compile_definitions(${BOOST_GEOMETRY_UNIT_TEST_NAME} PRIVATE BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) +endforeach() + +# Other tests +foreach(item IN ITEMS + buffer_with_strategies + buffer_piece_border + buffer_linestring_aimes + ) + boost_geometry_add_unit_test("algorithms" ${item}) + target_compile_definitions(${BOOST_GEOMETRY_UNIT_TEST_NAME} PRIVATE BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) +endforeach() diff --git a/test/algorithms/buffer/Jamfile b/test/algorithms/buffer/Jamfile index f0f3b35c6b..7a84e61975 100644 --- a/test/algorithms/buffer/Jamfile +++ b/test/algorithms/buffer/Jamfile @@ -32,13 +32,6 @@ test-suite boost-geometry-algorithms-buffer [ run buffer_multi_polygon_geo.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_buffer_multi_polygon_geo ] [ run buffer_geo_spheroid.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_buffer_geo_spheroid ] [ run buffer_linestring_aimes.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_buffer_linestring_aimes ] - [ run buffer_linestring.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_linestring_alternative ] - [ run buffer_multi_linestring.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_multi_linestring_alternative ] - [ run buffer_ring.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_ring_alternative ] - [ run buffer_polygon.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_polygon_alternative ] - [ run buffer_multi_point.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_multi_point_alternative ] - [ run buffer_multi_polygon.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_multi_polygon_alternative ] - [ run buffer_linestring_aimes.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_linestring_aimes_alternative ] # Uncomment next lines if you want to test this manually; requires access to data/ folder # [ run buffer_countries.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_buffer_countries ] # [ run buffer_countries.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_buffer_countries_alternative ] diff --git a/test/algorithms/buffer/buffer_geo_spheroid.cpp b/test/algorithms/buffer/buffer_geo_spheroid.cpp index d7a6a98f7e..ff56c60a13 100644 --- a/test/algorithms/buffer/buffer_geo_spheroid.cpp +++ b/test/algorithms/buffer/buffer_geo_spheroid.cpp @@ -57,7 +57,11 @@ void test_linestring(std::string const& label, Spheroid const& spheroid, using linestring = bg::model::linestring; using polygon = bg::model::polygon; +#ifdef __APPLE__ + ut_settings settings(1.0); +#else ut_settings settings(0.1); +#endif using CT = typename bg::coordinate_type::type; geo_buffer_accurate_area strategy(spheroid); @@ -79,7 +83,11 @@ void test_point(std::string const& label, Spheroid const& spheroid, double expec { using polygon = bg::model::polygon; +#ifdef __APPLE__ + ut_settings settings(1.15); +#else ut_settings settings(0.01); +#endif using CT = typename bg::coordinate_type::type; geo_buffer_accurate_area strategy(spheroid); diff --git a/test/algorithms/buffer/buffer_linestring.cpp b/test/algorithms/buffer/buffer_linestring.cpp index da0fb9e14a..45bd06cc2f 100644 --- a/test/algorithms/buffer/buffer_linestring.cpp +++ b/test/algorithms/buffer/buffer_linestring.cpp @@ -34,7 +34,9 @@ static std::string const two_bends = "LINESTRING(0 0,4 5,7 4,10 6)"; static std::string const bend_near_start1 = "LINESTRING(0 0,1 0,5 2)"; static std::string const bend_near_start2 = "LINESTRING(0 0,1 0,2 1.5,5 3)"; -static std::string const overlapping = "LINESTRING(0 0,4 5,7 4,10 6, 10 2,2 2)"; +static std::string const overlapping = "LINESTRING(0 0,4 5,7 4,10 6,10 2,2 2)"; +static std::string const overlapping_rev = "LINESTRING(2 2,10 2,10 6,7 4,4 5,0 0)"; + static std::string const curve = "LINESTRING(2 7,3 5,5 4,7 5,8 7)"; static std::string const tripod = "LINESTRING(5 0,5 5,1 8,5 5,9 8)"; // with spike @@ -111,6 +113,8 @@ static std::string const issue_803 = "LINESTRING(2773.6899360413681 -17.49335640 static std::string const issue_988 = "LINESTRING(0.10144 0.034912,0.106079 0.035156,0.109375 0.034302,0.114502 0.035889,0.116333 0.036743,0.117065 0.036499,0.121582 0.035156,0.12439 0.029175,0.123779 0.026978,0.12146 0.025513,0.119507 0.025513,0.118164 0.025513,0.114624 0.025757,0.111694 0.026001,0.108887 0.02832,0.105957 0.028442,0.099854 0.027344,0.095581 0.029419,0.093506 0.031128,0.090576 0.032593,0.085571 0.032959,0.082153 0.035522,0.081421 0.039307,0.082275 0.044067,0.083862 0.047485,0.08606 0.049805,0.087891 0.051025,0.090942 0.05188,0.094727 0.051392,0.100098 0.050049,0.10144 0.05249,0.100952 0.054932,0.098633 0.05835,0.098267 0.062134,0.098755 0.064697,0.098511 0.067383,0.113892 0.068848,0.110718 0.065552,0.109619 0.064331,0.111084 0.063965,0.118042 0.0625,0.115234 0.049805,0.117676 0.049194,0.118774 0.046997,0.119385 0.04541,0.119507 0.043945,0.116089 0.041138,0.116089 0.041016,0.11438 0.040894,0.11145 0.041016,0.109009 0.042114,0.106079 0.04248,0.102417 0.041138,0.102051 0.040039)"; static std::string const issue_1084 = "LINESTRING(269.3 -7.03, 270.23 -3.57, 270.54 0, 270.54 100, 270.23 103.57, 269.3 107.03, 267.79 110.27, 265.73 113.2, 263.2 115.73, 258.89 118.43, 254.28 108.54, 248.52 109, 80 97.21, 72.71 95.87, 67.46 93.82, 62.61 90.92, 58.32 87.27, 54.69 82.95, 51.83 78.08, 49.81 72.81, 48.7 67.28, 48.45 63.38, 48.52 34.87, 49.29 29.26, 50.96 23.87, 54.69 17.05, 58.32 12.73, 62.61 9.08, 65.57 7.18, 70.68 4.81, 76.12 3.31, 80 2.79, 248.52 -9, 254.28 -8.54, 258.89 -18.43, 263.2 -15.73, 265.73 -13.2, 267.79 -10.27, 269.3 -7.03, 270.23 -3.57, 270.54 0, 270.54 100, 270.23 103.57, 269.3 107.03, 267.79 110.27, 265.73 113.2, 264 114.93, 256.24 107.17, 251.86 108.16, 248.58 108.2, 76.24 95.9, 70.93 94.43, 65.94 92.11, 61.4 88.99, 57.44 85.16, 54.18 80.72, 51.69 75.8, 50.06 70.54, 49.25 63.38, 49.32 34.93, 50.06 29.46, 51.69 24.2, 55.36 17.49, 58.9 13.28, 63.1 9.71, 67.83 6.89, 70.93 5.57, 76.24 4.1, 80.06 3.59, 248.58 -8.2, 251.86 -8.16, 256.24 -7.17, 258.89 -18.43)"; +static std::string const issue_1250 = "LINESTRING(3 1, 4 2, 4 4, 2 4, 2 2, 3 2)"; +static std::string const issue_1250_rev = "LINESTRING(3 2, 2 2, 2 4, 4 4, 4 2, 3 1)"; template void test_all() @@ -179,23 +183,38 @@ void test_all() test_one("bend_near_start1", bend_near_start1, join_round, end_flat, 109.2625, 9.0); test_one("bend_near_start2", bend_near_start2, join_round, end_flat, 142.8709, 9.0); - // Next (and all similar cases) which a offsetted-one-sided buffer has to be fixed. TODO + // Next (and all similar cases) which a offsetted-one-sided buffer has to be supported. TODO //test_one("two_bends_neg", two_bends, join_miter, end_flat, 99, +1.5, settings, -1.0); //test_one("two_bends_pos", two_bends, join_miter, end_flat, 99, -1.5, settings, +1.0); - //test_one("two_bends_neg", two_bends, join_round, end_flat,99, +1.5, settings, -1.0); + //test_one("two_bends_neg", two_bends, join_round, end_flat,99, +1.5, settings, -1.0); //test_one("two_bends_pos", two_bends, join_round, end_flat, 99, -1.5, settings, +1.0); - test_one("overlapping150", overlapping, join_round, end_flat, 65.6786, 1.5); - test_one("overlapping150", overlapping, join_miter, end_flat, 68.140, 1.5); + test_one("overlapping_50", overlapping, join_round, end_flat, 24.6326, 0.5); + test_one("overlapping_50", overlapping, join_miter, end_flat, 24.9147, 0.5); + test_one("overlapping_150", overlapping, join_round, end_flat, 65.6786, 1.5); + test_one("overlapping_150", overlapping, join_miter, end_flat, 68.140, 1.5); + + test_one("overlapping_rev_50", overlapping_rev, join_round, end_flat, 24.6326, 0.5); + test_one("overlapping_rev_50", overlapping_rev, join_miter, end_flat, 24.9147, 0.5); + test_one("overlapping_rev_150", overlapping_rev, join_round, end_flat, 65.6786, 1.5); + test_one("overlapping_rev_150", overlapping_rev, join_miter, end_flat, 68.140, 1.5); // Different cases with intersection points on flat and (left/right from line itself) - test_one("overlapping_asym_150_010", overlapping, join_round, end_flat, 48.308, 1.5, settings, 0.25); - test_one("overlapping_asym_150_010", overlapping, join_miter, end_flat, 50.770, 1.5, settings, 0.25); + test_one("overlapping_asym_150_025", overlapping, join_round, end_flat, 48.308, 1.5, settings, 0.25); + test_one("overlapping_asym_150_025", overlapping, join_miter, end_flat, 50.770, 1.5, settings, 0.25); test_one("overlapping_asym_150_075", overlapping, join_round, end_flat, 58.506, 1.5, settings, 0.75); test_one("overlapping_asym_150_075", overlapping, join_miter, end_flat, 60.985, 1.5, settings, 0.75); test_one("overlapping_asym_150_100", overlapping, join_round, end_flat, 62.514, 1.5, settings, 1.0); test_one("overlapping_asym_150_100", overlapping, join_miter, end_flat, 64.984, 1.5, settings, 1.0); + // The reverse cases need to reverse the distance too, for the same result + test_one("overlapping_rev_asym_150_025", overlapping_rev, join_round, end_flat, 48.308, 0.25, settings, 1.5); + test_one("overlapping_rev_asym_150_025", overlapping_rev, join_miter, end_flat, 50.770, 0.25, settings, 1.5); + test_one("overlapping_rev_asym_150_075", overlapping_rev, join_round, end_flat, 58.506, 0.75, settings, 1.5); + test_one("overlapping_rev_asym_150_075", overlapping_rev, join_miter, end_flat, 60.985, 0.75, settings, 1.5); + test_one("overlapping_rev_asym_150_100", overlapping_rev, join_round, end_flat, 62.514, 1.0, settings, 1.5); + test_one("overlapping_rev_asym_150_100", overlapping_rev, join_miter, end_flat, 64.984, 1.0, settings, 1.5); + // Having flat end test_one("for_collinear", for_collinear, join_round, end_flat, 68.561, 2.0); test_one("for_collinear", for_collinear, join_miter, end_flat, 72, 2.0); @@ -326,6 +345,12 @@ void test_all() using bg::strategy::buffer::end_round; test_one("issue_1084", issue_1084, join_round(10), end_round(10), 13200.83, 10.0); } + { + using bg::strategy::buffer::join_miter; + using bg::strategy::buffer::end_flat; + test_one("issue_1250", issue_1250, join_miter(5), end_flat(), 8.39277, 0.5); + test_one("issue_1250_rev", issue_1250_rev, join_miter(5), end_flat(), 8.39277, 0.5); + } test_one("mysql_report_2015_06_11", mysql_report_2015_06_11, join_round32, end_round32, diff --git a/test/algorithms/buffer/buffer_multi_linestring_geo.cpp b/test/algorithms/buffer/buffer_multi_linestring_geo.cpp index e42f368926..72fd9323cf 100644 --- a/test/algorithms/buffer/buffer_multi_linestring_geo.cpp +++ b/test/algorithms/buffer/buffer_multi_linestring_geo.cpp @@ -48,7 +48,9 @@ void test_geometry() test_one_geo("trondheim10_rr", trondheim, strategy, side, circle, join_round, end_round, 8994.0, 10.0, settings); } +#ifndef __APPLE__ test_one_geo("trondheim12_rr", trondheim, strategy, side, circle, join_round, end_round, 10790.0, 12.0, settings); +#endif if (! BOOST_GEOMETRY_CONDITION(thomas_skip) && ! BOOST_GEOMETRY_CONDITION(andoyer_skip)) { diff --git a/test/algorithms/buffer/buffer_polygon.cpp b/test/algorithms/buffer/buffer_polygon.cpp index 9a671016a3..4fa2d62856 100644 --- a/test/algorithms/buffer/buffer_polygon.cpp +++ b/test/algorithms/buffer/buffer_polygon.cpp @@ -154,6 +154,8 @@ static std::string const issue_555 static std::string const issue_1019 = "POLYGON((577255 928582,577255 928582,577228 928786,577245 932654,577619 933122,580589 933287,580929 933297,583237 932957,583504 932546,583652 929953,582964 928631,577255 928582))"; +static std::string const issue_1262 + = "POLYGON((-2.447356204196278639528828 57.21240623671037894837355,34.00960378453005006349485 54.01542955431686721112783,-0.000789642333984375 18.712947845458984375,-41.480987548828125 60.193248748779296875,-3.12519073486328125 57.271846771240234375,-2.447356204196278639528828 57.21240623671037894837355),(-36.24821876005196230607908 57.78889760314127244100746,-0.000785932392148191993896944 21.54137477179954629491476,30.75139677038663066355184 52.2934724874262641947098,-36.24821876005196230607908 57.78889760314127244100746))"; // CCW Polygons not working in 1.56 static std::string const mysql_report_2014_10_24 @@ -614,6 +616,17 @@ void test_all() test_one("issue_1019", issue_1019, join_miter, end_flat, 34835787.44782, 300.0); + { + // The reported issue created a huge polygon, instead of 0.0 (because the negative distance should fill + // the whole input polygon) + bg::strategy::buffer::join_round join_round4(4); + bg::strategy::buffer::end_round end_round4(4); + test_one("issue_1262", issue_1262, join_round4, end_round4, 0.0, -1.8); + test_one("issue_1262_1", issue_1262, join_round4, end_round4, 8.9161, -1.0); + test_one("issue_1262_2", issue_1262, join_round4, end_round4, 62.5276, -0.8); + test_one("issue_1262_3", issue_1262, join_round4, end_round4, 193.47288, -0.4); + } + { bg::strategy::buffer::join_round join_round32(32); bg::strategy::buffer::end_round end_round32(32); diff --git a/test/algorithms/buffer/buffer_variable_width.cpp b/test/algorithms/buffer/buffer_variable_width.cpp new file mode 100644 index 0000000000..ee39255129 --- /dev/null +++ b/test/algorithms/buffer/buffer_variable_width.cpp @@ -0,0 +1,184 @@ +// Boost.Geometry + +// Copyright (c) 2024 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) + +#include + +#include +#include +#include +#include + +namespace bg = boost::geometry; + +#if defined(TEST_WITH_SVG) +#include "test_buffer_svg.hpp" +#endif + +// A point with extra info, such that +// - it can influence the buffer with dynamically (input) +// - it can receive the side at which the buffer was (output) +struct specific_point +{ + double x{0.0}; + double y{0.0}; + double distance_left{0.0}; + double distance_right{0.0}; + boost::optional side{}; +}; + +BOOST_GEOMETRY_REGISTER_POINT_2D(specific_point, double, cs::cartesian, x, y) + +struct specific_buffer_side_strategy +{ + bool equidistant() const + { + return true; + } + + template + bg::strategy::buffer::result_code apply(Point const& input_p1, Point const& input_p2, + bg::strategy::buffer::buffer_side_selector side, + DistanceStrategy const& distance, + OutputRange &output_range) const + { + const auto result = + bg::strategy::buffer::side_straight::apply(input_p1, input_p2, side, distance, output_range); + + for (auto& point : output_range) + { + point.side = side; + } + return result; + } +}; + +struct specific_buffer_distance_strategy +{ + /// Returns the distance-value. + template + double apply(Point const& p, Point const& q, + bg::strategy::buffer::buffer_side_selector side) const + { + return bg::strategy::buffer::buffer_side_left == side + ? std::max(p.distance_left, q.distance_left) + : std::max(p.distance_right, q.distance_right); + } + + bool negative() const + { + return false; + } + + bool empty(bg::strategy::buffer::buffer_side_selector) const + { + return false; + } + + /// Returns the max distance distance up to the buffer will reach. + template + double max_distance(JoinStrategy const &, EndStrategy const &) const + { + constexpr double unit_buffer_width{3.0}; + return 6.0 * unit_buffer_width; + } + + /// Returns the distance at which the input is simplified before the buffer process. + double simplify_distance() const + { + constexpr double unit_buffer_width{3.0}; + return unit_buffer_width / 1000.0; + } +}; + +void test_buffer(std::string const& caseid, std::string const& wkt, std::vector const& widths, double expected_area) +{ + using ls_t = boost::geometry::model::linestring; + using mls_t = boost::geometry::model::multi_linestring; + using polygon_t = boost::geometry::model::polygon; + + mls_t mls; + boost::geometry::read_wkt(wkt, mls); + + if (mls.size() != widths.size()) + { + throw std::runtime_error("There should be correct widths"); + } + + using point_type = specific_point; + using strategy_t = bg::strategies::buffer::services::default_strategy< + mls_t>::type; + strategy_t strategy; + +#if defined(TEST_WITH_SVG) + bg::model::box envelope; + bg::envelope(mls, envelope, strategy); + + buffer_svg_mapper buffer_mapper(caseid); + + std::ostringstream filename; + filename << "/tmp/buffer_variable_width_" << caseid << ".svg"; + std::ofstream svg(filename.str().c_str()); + typedef bg::svg_mapper mapper_type; + mapper_type mapper(svg, 1000, 800); + + svg_visitor> visitor(mapper); + + // Set the SVG boundingbox, with a margin. The margin is necessary because + // drawing is already started before the buffer is finished. It is not + // possible to "add" the buffer (unless we buffer twice). + buffer_mapper.prepare(mapper, visitor, envelope, 2.0); +#else + bg::detail::buffer::visit_pieces_default_policy visitor; +#endif + + for (std::size_t i = 0; i < mls.size(); i++) + { + for (auto& point : mls[i]) + { + point.distance_left = widths[i]; + point.distance_right = widths[i]; + } + } + + specific_buffer_side_strategy buffer_side_strategy; + specific_buffer_distance_strategy distance_strategy; + boost::geometry::strategy::buffer::join_miter join_strategy; + boost::geometry::strategy::buffer::end_flat end_strategy; + boost::geometry::strategy::buffer::point_circle point_strategy; + boost::geometry::model::multi_polygon result; + boost::geometry::detail::buffer::buffer_inserter + < + polygon_t + >(mls, + std::back_inserter(result), + distance_strategy, buffer_side_strategy, join_strategy, + end_strategy, point_strategy, + strategy, + bg::detail::no_rescale_policy(), + visitor); + +#if defined(TEST_WITH_SVG) + buffer_mapper.map_input_output(mapper, mls, result, false); +#endif + + std::cout << caseid << " : " << boost::geometry::area(result) << std::endl; + BOOST_CHECK_CLOSE_FRACTION(boost::geometry::area(result), expected_area, 0.001); +} + +int test_main(int argc, char **argv) +{ + test_buffer("case1", "MULTILINESTRING((-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875,18.00000000002045652536253328435122966766357421875 10.4999999997948947338954894803464412689208984375),(-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875,17.99999999995061017443731543608009815216064453125 -4.5000000001943778471513724070973694324493408203125),(-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875,11.99999999996175148453403380699455738067626953125 -10.49999999983214848953139153309166431427001953125))", + {4.5, 1.5, 1.5}, 304.294); + test_buffer("case2", "MULTILINESTRING((-18.00000000002045652536253328435122966766357421875 10.4999999997948929575386500800959765911102294921875,-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875),(-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875,17.99999999995061017443731543608009815216064453125 -4.5000000001943778471513724070973694324493408203125),(-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875,11.99999999996175148453403380699455738067626953125 -10.49999999983214848953139153309166431427001953125))", + {6.0, 1.5, 1.5}, 319.767); + test_buffer("case3", "MULTILINESTRING((-18.00000000002045652536253328435122966766357421875 10.4999999997948929575386500800959765911102294921875,-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875),(-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875,18.00000000002045652536253328435122966766357421875 10.4999999997948947338954894803464412689208984375),(-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875,11.99999999996175148453403380699455738067626953125 -10.49999999983214848953139153309166431427001953125))", + {6.0, 4.5, 1.5}, 429.831); + test_buffer("case4", "MULTILINESTRING((-18.00000000002045652536253328435122966766357421875 10.4999999997948929575386500800959765911102294921875,-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875),(-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875,18.00000000002045652536253328435122966766357421875 10.4999999997948947338954894803464412689208984375),(-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875,17.99999999995061017443731543608009815216064453125 -4.5000000001943778471513724070973694324493408203125))", + {6.0, 4.5, 1.5}, 423.195); + return 0; +} diff --git a/test/algorithms/buffer/test_buffer.hpp b/test/algorithms/buffer/test_buffer.hpp index fd6261ea14..5f112eb03b 100644 --- a/test/algorithms/buffer/test_buffer.hpp +++ b/test/algorithms/buffer/test_buffer.hpp @@ -15,11 +15,6 @@ #ifndef BOOST_GEOMETRY_TEST_BUFFER_HPP #define BOOST_GEOMETRY_TEST_BUFFER_HPP -#if defined(TEST_WITH_SVG) - // Define before including any buffer headerfile - #define BOOST_GEOMETRY_BUFFER_USE_HELPER_POINTS -#endif - #include #include #include diff --git a/test/algorithms/buffer/test_buffer_svg_per_turn.hpp b/test/algorithms/buffer/test_buffer_svg_per_turn.hpp index 1a32323a68..fa0d0ad0bd 100644 --- a/test/algorithms/buffer/test_buffer_svg_per_turn.hpp +++ b/test/algorithms/buffer/test_buffer_svg_per_turn.hpp @@ -15,6 +15,8 @@ #ifndef BOOST_GEOMETRY_TEST_BUFFER_SVG_PER_TURN_HPP #define BOOST_GEOMETRY_TEST_BUFFER_SVG_PER_TURN_HPP +#if defined(TEST_WITH_SVG_PER_TURN) + #include #include @@ -163,5 +165,6 @@ public : } }; +#endif #endif // BOOST_GEOMETRY_TEST_BUFFER_SVG_PER_TURN_HPP diff --git a/test/algorithms/convex_hull/CMakeLists.txt b/test/algorithms/convex_hull/CMakeLists.txt new file mode 100644 index 0000000000..cd3255ce50 --- /dev/null +++ b/test/algorithms/convex_hull/CMakeLists.txt @@ -0,0 +1,14 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +foreach(item IN ITEMS + convex_hull + convex_hull_multi + convex_hull_robust + convex_hull_sph_geo + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() diff --git a/test/algorithms/convex_hull/Jamfile b/test/algorithms/convex_hull/Jamfile index 41c679c0a1..5bc7958111 100644 --- a/test/algorithms/convex_hull/Jamfile +++ b/test/algorithms/convex_hull/Jamfile @@ -14,8 +14,4 @@ test-suite boost-geometry-algorithms-convex_hull [ run convex_hull_multi.cpp : : : : algorithms_convex_hull_multi ] [ run convex_hull_robust.cpp : : : : algorithms_convex_hull_robust ] [ run convex_hull_sph_geo.cpp : : : : algorithms_convex_hull_sph_geo ] - [ run convex_hull.cpp : : : BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_convex_hull_alternative ] - [ run convex_hull_multi.cpp : : : BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_convex_hull_multi_alternative ] - [ run convex_hull_robust.cpp : : : BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_convex_hull_robust_alternative ] - [ run convex_hull_sph_geo.cpp : : : BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_convex_hull_sph_geo_alternative ] ; diff --git a/test/algorithms/detail/CMakeLists.txt b/test/algorithms/detail/CMakeLists.txt new file mode 100644 index 0000000000..1dea5e5eec --- /dev/null +++ b/test/algorithms/detail/CMakeLists.txt @@ -0,0 +1,15 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +foreach(item IN ITEMS + calculate_point_order + approximately_equals + partition + tupled_output + visit + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() diff --git a/test/algorithms/detail/approximately_equals.cpp b/test/algorithms/detail/approximately_equals.cpp index 39e9ec39a1..0e004737c4 100644 --- a/test/algorithms/detail/approximately_equals.cpp +++ b/test/algorithms/detail/approximately_equals.cpp @@ -14,6 +14,8 @@ #include #include +#include + #include template @@ -81,18 +83,29 @@ void test_all(E const multiplier, std::size_t expected_index) int test_main(int, char* []) { + constexpr bool has_long_double = sizeof(long double) > sizeof(double); + double m = 1000.0; - test_all>(m, 54); + if (BOOST_GEOMETRY_CONDITION(has_long_double)) + { + test_all>(m, 54); + } test_all>(m, 43); test_all>(m, 24); m *= 1000.0; - test_all>(m, 44); + if (BOOST_GEOMETRY_CONDITION(has_long_double)) + { + test_all>(m, 44); + } test_all>(m, 33); test_all>(m, 24); m *= 1000.0; - test_all>(m, 34); + if (BOOST_GEOMETRY_CONDITION(has_long_double)) + { + test_all>(m, 34); + } test_all>(m, 23); test_all>(m, 23); diff --git a/test/algorithms/envelope_expand/CMakeLists.txt b/test/algorithms/envelope_expand/CMakeLists.txt new file mode 100644 index 0000000000..bd229c48af --- /dev/null +++ b/test/algorithms/envelope_expand/CMakeLists.txt @@ -0,0 +1,23 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +foreach(item IN ITEMS + envelope + envelope_multi + expand + expand_on_spheroid + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() + +if (NOT APPLE) + # The results of these tests vary considerably on Apple/Darwin/arm64 using clang + foreach(item IN ITEMS + envelope_on_spheroid + ) + boost_geometry_add_unit_test("algorithms" ${item}) + endforeach() +endif() \ No newline at end of file diff --git a/test/algorithms/envelope_expand/envelope.cpp b/test/algorithms/envelope_expand/envelope.cpp index 19c5af5880..df6db7437a 100644 --- a/test/algorithms/envelope_expand/envelope.cpp +++ b/test/algorithms/envelope_expand/envelope.cpp @@ -18,8 +18,6 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include - #include "test_envelope.hpp" #include @@ -27,6 +25,7 @@ #include #include #include +#include #include BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian) @@ -68,8 +67,8 @@ template void test_empty_geometry(std::string const& wkt) { typedef typename bg::coordinate_type::type ct; - ct high_val = boost::numeric::bounds::highest(); - ct low_val = boost::numeric::bounds::lowest(); + ct const high_val = bg::util::bounds::highest(); + ct const low_val = bg::util::bounds::lowest(); test_envelope(wkt, high_val, low_val, high_val, low_val); } diff --git a/test/algorithms/envelope_expand/envelope_on_spheroid.cpp b/test/algorithms/envelope_expand/envelope_on_spheroid.cpp index c2e20ce1e0..9d2bd688d8 100644 --- a/test/algorithms/envelope_expand/envelope_on_spheroid.cpp +++ b/test/algorithms/envelope_expand/envelope_on_spheroid.cpp @@ -22,8 +22,6 @@ #include #include -#include - #include #include #include "test_envelope_expand_on_spheroid.hpp" @@ -38,6 +36,7 @@ #include #include #include +#include #include #include @@ -492,8 +491,8 @@ void test_empty_geometry(std::string const& case_id, std::string const& wkt) typedef test_envelope_on_sphere_or_spheroid tester; typedef typename bg::coordinate_type::type ct; - ct high_val = boost::numeric::bounds::highest(); - ct low_val = boost::numeric::bounds::lowest(); + ct const high_val = bg::util::bounds::highest(); + ct const low_val = bg::util::bounds::lowest(); if (BOOST_GEOMETRY_CONDITION(dim == 2)) { diff --git a/test/algorithms/envelope_expand/expand_on_spheroid.cpp b/test/algorithms/envelope_expand/expand_on_spheroid.cpp index b3c9af1f20..e7e45a230b 100644 --- a/test/algorithms/envelope_expand/expand_on_spheroid.cpp +++ b/test/algorithms/envelope_expand/expand_on_spheroid.cpp @@ -38,6 +38,7 @@ #include #include +#include #include diff --git a/test/algorithms/is_simple.cpp b/test/algorithms/is_simple.cpp index 41cef5ed56..e829f45931 100644 --- a/test/algorithms/is_simple.cpp +++ b/test/algorithms/is_simple.cpp @@ -256,6 +256,21 @@ BOOST_AUTO_TEST_CASE( test_is_simple_areal ) BOOST_AUTO_TEST_CASE( test_geometry_with_NaN_coordinates ) { +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl; + std::cout << "************************************" << std::endl; + std::cout << " is_valid: geometry with NaN coordinates" << std::endl; + std::cout << "************************************" << std::endl; +#endif + + multi_linestring_type mls; + bg::read_wkt("MULTILINESTRING((nan nan))", mls); + + test_simple(mls, true, false); +} + +BOOST_AUTO_TEST_CASE( test_geometry_with_NaN_coordinates_2 ) +{ #ifdef BOOST_GEOMETRY_TEST_DEBUG std::cout << std::endl << std::endl; std::cout << "************************************" << std::endl; @@ -267,12 +282,10 @@ BOOST_AUTO_TEST_CASE( test_geometry_with_NaN_coordinates ) bg::read_wkt("LINESTRING(1 1,1.115235e+308 1.738137e+308)", ls1); bg::read_wkt("LINESTRING(-1 1,1.115235e+308 1.738137e+308)", ls2); - // the intersection of the two linestrings is a new linestring - // (multilinestring with a single element) that has NaN coordinates multi_linestring_type mls; bg::intersection(ls1, ls2, mls); - test_simple(mls, true, false); + test_simple(mls, false, false); } BOOST_AUTO_TEST_CASE( test_is_simple_variant ) diff --git a/test/algorithms/is_valid.cpp b/test/algorithms/is_valid.cpp index aaf4995069..82ba5ae469 100644 --- a/test/algorithms/is_valid.cpp +++ b/test/algorithms/is_valid.cpp @@ -1426,6 +1426,32 @@ BOOST_AUTO_TEST_CASE( test_geometries_with_invalid_coordinates ) BOOST_AUTO_TEST_CASE( test_with_NaN_coordinates ) { +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl; + std::cout << "************************************" << std::endl; + std::cout << " is_valid: geometry with NaN coordinates" << std::endl; + std::cout << "************************************" << std::endl; +#endif + + multi_linestring_type mls; + bg::read_wkt("MULTILINESTRING((nan nan))", mls); + + typedef validity_tester_linear tester_allow_spikes; + typedef validity_tester_linear tester_disallow_spikes; + + test_valid + < + tester_allow_spikes, multi_linestring_type + >::apply("mls-NaN", mls, false); + + test_valid + < + tester_disallow_spikes, multi_linestring_type + >::apply("mls-NaN", mls, false); +} + +BOOST_AUTO_TEST_CASE( test_with_NaN_coordinates_2 ) +{ #ifdef BOOST_GEOMETRY_TEST_DEBUG std::cout << std::endl << std::endl; std::cout << "************************************" << std::endl; @@ -1437,8 +1463,6 @@ BOOST_AUTO_TEST_CASE( test_with_NaN_coordinates ) bg::read_wkt("LINESTRING(1 1,1.115235e+308 1.738137e+308)", ls1); bg::read_wkt("LINESTRING(-1 1,1.115235e+308 1.738137e+308)", ls2); - // the intersection of the two linestrings is a new linestring - // (multilinestring with a single element) that has NaN coordinates multi_linestring_type mls; bg::intersection(ls1, ls2, mls); diff --git a/test/algorithms/overlay/CMakeLists.txt b/test/algorithms/overlay/CMakeLists.txt new file mode 100644 index 0000000000..362c5caf81 --- /dev/null +++ b/test/algorithms/overlay/CMakeLists.txt @@ -0,0 +1,38 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +# Cartesian +foreach(item IN ITEMS + assemble + copy_segment_point + get_clusters + get_distance_measure + get_ring + get_turn_info + get_turns + get_turns_const + get_turns_areal_areal + get_turns_linear_areal + get_turns_linear_linear + overlay + sort_by_side_basic + sort_by_side + relative_order + select_rings + self_intersection_points + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() + +# Spherical +foreach(item IN ITEMS + get_turns_areal_areal_sph + get_turns_linear_areal_sph + get_turns_linear_linear_sph + get_turns_linear_linear_geo + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() diff --git a/test/algorithms/overlay/Jamfile b/test/algorithms/overlay/Jamfile index 22995f954a..d234385aa0 100644 --- a/test/algorithms/overlay/Jamfile +++ b/test/algorithms/overlay/Jamfile @@ -14,7 +14,7 @@ # http://www.boost.org/LICENSE_1_0.txt) test-suite boost-geometry-algorithms-overlay - : + : [ run assemble.cpp : : : : algorithms_assemble ] [ run copy_segment_point.cpp : : : : algorithms_copy_segment_point ] [ run get_clusters.cpp : : : : algorithms_get_clusters ] @@ -28,7 +28,6 @@ test-suite boost-geometry-algorithms-overlay [ run get_turns_linear_areal.cpp : : : : algorithms_get_turns_linear_areal ] [ run get_turns_linear_areal_sph.cpp : : : : algorithms_get_turns_linear_areal_sph ] [ run get_turns_linear_linear.cpp : : : : algorithms_get_turns_linear_linear ] - [ run get_turns_linear_linear.cpp : : : BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_get_turns_linear_linear_alternative ] [ run get_turns_linear_linear_geo.cpp : : : : algorithms_get_turns_linear_linear_geo ] [ run get_turns_linear_linear_sph.cpp : : : : algorithms_get_turns_linear_linear_sph ] [ run overlay.cpp : : : : algorithms_overlay ] diff --git a/test/algorithms/overlay/copy_segment_point.cpp b/test/algorithms/overlay/copy_segment_point.cpp index 33c3f9536d..5a85c2080b 100644 --- a/test/algorithms/overlay/copy_segment_point.cpp +++ b/test/algorithms/overlay/copy_segment_point.cpp @@ -9,7 +9,7 @@ #include -#include +#include #include #include diff --git a/test/algorithms/overlay/get_clusters.cpp b/test/algorithms/overlay/get_clusters.cpp index 5b9a3602fd..ec33c7515a 100644 --- a/test/algorithms/overlay/get_clusters.cpp +++ b/test/algorithms/overlay/get_clusters.cpp @@ -20,6 +20,8 @@ #include #include +#include + #include #include @@ -93,6 +95,7 @@ void test_get_clusters_border_cases(typename bg::coordinate_type::type ep int test_main(int, char* []) { + constexpr bool has_long_double = sizeof(long double) > sizeof(double); using fp = bg::model::point; using dp = bg::model::point; using ep = bg::model::point; @@ -101,11 +104,15 @@ int test_main(int, char* []) test_get_clusters(); test_get_clusters(); - // These constant relate to the threshold in get_clusters.hpp, + // These constant relate to the (earlier) thresholds in get_clusters.hpp, // and the used floating point type. + // (thresholds are now replaced by common_approximately_equals_epsilon_multiplier) test_get_clusters_border_cases(1.0e-5); test_get_clusters_border_cases(1.0e-14); - test_get_clusters_border_cases(1.0e-17); + if (BOOST_GEOMETRY_CONDITION(has_long_double)) + { + test_get_clusters_border_cases(1.0e-17); + } return 0; } diff --git a/test/algorithms/overlay/get_distance_measure.cpp b/test/algorithms/overlay/get_distance_measure.cpp index df0322b35e..f526fe07a6 100644 --- a/test/algorithms/overlay/get_distance_measure.cpp +++ b/test/algorithms/overlay/get_distance_measure.cpp @@ -76,8 +76,8 @@ void test_get_distance_measure() do_test("simplex_left", {1.0, 0.0}, {1.0, 1.0}, {0.9, 0.5}, 1); do_test("simplex_right", {1.0, 0.0}, {1.0, 1.0}, {1.1, 0.5}, -1); - bool const is_float = std::is_same::value; - bool const is_double = std::is_same::value; + bool const is_float = std::is_floating_point::value && sizeof(coor_t) == 4; + bool const is_double = std::is_floating_point::value && sizeof(coor_t) == 8; // The issue 1183 where get_distance_measure failed for these coordinates. std::string const case_id = "issue_1183_"; diff --git a/test/algorithms/overlay/overlay.cpp b/test/algorithms/overlay/overlay.cpp index 8162a848c3..25d027a5a1 100644 --- a/test/algorithms/overlay/overlay.cpp +++ b/test/algorithms/overlay/overlay.cpp @@ -318,9 +318,9 @@ struct map_visitor // Create a rounded off point std::pair p = std::make_pair( - boost::numeric_cast(half + util::numeric_cast(half + ten * bg::get<0>(turn.point)), - boost::numeric_cast(half + util::numeric_cast(half + ten * bg::get<1>(turn.point)) ); m_mapper.text(turn.point, text, style, margin, m_offsets[p], lineheight); diff --git a/test/algorithms/overlay/overlay_cases.hpp b/test/algorithms/overlay/overlay_cases.hpp index 48ebfcde11..ef477631e2 100644 --- a/test/algorithms/overlay/overlay_cases.hpp +++ b/test/algorithms/overlay/overlay_cases.hpp @@ -1176,6 +1176,25 @@ static std::string issue_1186[2] = "POLYGON((-13848.1446527556 6710443.1496919869,-13848.2559722463 6710440.2884572418,-13847.8106942832 6710440.1096301023,-13847.6993747924 6710443.1496919869,-13847.3654163201 6710442.9708647905,-13846.0295824308 6710442.9708647905,-13846.4748603939 6710435.1024718173,-13847.8106942832 6710435.1024718173,-13848.1446527556 6710435.1024718173,-13849.8144451172 6710443.1496919869,-13848.1446527556 6710443.1496919869),(-13847.4767358109 6710440.1096301023,-13847.8106942832 6710440.1096301023,-13847.9220137740 6710439.9308029665,-13847.5880553017 6710439.7519758362,-13847.4767358109 6710440.1096301023))" }; +// Triangle, nearly a line +static std::string issue_1229[2] = +{ + "POLYGON((38436.758 22765.61,930.538 -10523.68,925.121 -10507.965,38436.758 22765.61))", + "POLYGON((38436.758 22765.61,925.121 -10507.965,925.121 -10507.965,38436.758 22765.61))" +}; + +static std::string issue_1231[2] = +{ + "POLYGON((0 5,-6 -17,12 17,0 5),(4 6,5 5,0 1,4 6))", + "POLYGON((3 9,-15 -5,13 -11,3 9))" +}; + +static std::string issue_1244[2] = +{ + "POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1,1 3,2 2,1 1))", + "POLYGON((2 -1,5 2,2 5,2 -1))" +}; + static std::string ggl_list_20120229_volker[3] = { "POLYGON((1716 1554,2076 2250,2436 2352,2796 1248,3156 2484,3516 2688,3516 2688,3156 2484,2796 1248,2436 2352,2076 2250, 1716 1554))", diff --git a/test/algorithms/overlay/sort_by_side.cpp b/test/algorithms/overlay/sort_by_side.cpp index 5776d70404..389588b528 100644 --- a/test/algorithms/overlay/sort_by_side.cpp +++ b/test/algorithms/overlay/sort_by_side.cpp @@ -51,13 +51,13 @@ template typename Turns, typename Geometry1, typename Geometry2, - typename SideStrategy + typename Strategy > std::vector gather_cluster_properties( Clusters& clusters, Turns& turns, bg::detail::overlay::operation_type for_operation, Geometry1 const& geometry1, Geometry2 const& geometry2, - SideStrategy const& strategy) + Strategy const& strategy) { using namespace boost::geometry; using namespace boost::geometry::detail::overlay; @@ -72,7 +72,7 @@ std::vector gather_cluster_properties( // right side typedef sort_by_side::side_sorter < - Reverse1, Reverse2, OverlayType, point_type, SideStrategy, std::less + Reverse1, Reverse2, OverlayType, point_type, Strategy, std::less > sbs_type; for (typename Clusters::iterator mit = clusters.begin(); @@ -165,7 +165,7 @@ std::vector apply_overlay( // Gather cluster properties, with test option return ::gather_cluster_properties( clusters, turns, bg::detail::overlay::operation_from_overlay::value, - geometry1, geometry2, strategy.side()); + geometry1, geometry2, strategy); } diff --git a/test/algorithms/overlay/sort_by_side_basic.cpp b/test/algorithms/overlay/sort_by_side_basic.cpp index 4ce87c7248..dc863e591b 100644 --- a/test/algorithms/overlay/sort_by_side_basic.cpp +++ b/test/algorithms/overlay/sort_by_side_basic.cpp @@ -85,14 +85,13 @@ std::vector apply_get_turns(std::string const& case_id, // Define sorter, sorting counter-clockwise such that polygons are on the // right side - typedef decltype(strategy.side()) side_strategy; - typedef bg::detail::overlay::sort_by_side::side_sorter + using sbs_type = bg::detail::overlay::sort_by_side::side_sorter < false, false, overlay_union, - point_type, side_strategy, std::less - > sbs_type; + point_type, Strategy, std::less + >; - sbs_type sbs(strategy.side()); + sbs_type sbs(strategy); std::cout << "Case: " << case_id << std::endl; diff --git a/test/algorithms/overlay/traverse.cpp b/test/algorithms/overlay/traverse.cpp index 6d58b08cfd..b1dfba1c90 100644 --- a/test/algorithms/overlay/traverse.cpp +++ b/test/algorithms/overlay/traverse.cpp @@ -246,9 +246,9 @@ struct test_traverse // Create a rounded off point std::pair p = std::make_pair( - boost::numeric_cast(half + util::numeric_cast(half + ten * bg::get<0>(turn.point)), - boost::numeric_cast(half + util::numeric_cast(half + ten * bg::get<1>(turn.point)) ); std::string style = "fill:rgb(0,0,0);font-family:Arial;font-size:8px"; @@ -303,8 +303,8 @@ struct test_traverse /*out << std::setprecision(3) - << "dist: " << boost::numeric_cast(turn.operations[0].enriched.distance) - << " / " << boost::numeric_cast(turn.operations[1].enriched.distance) + << "dist: " << util::numeric_cast(turn.operations[0].enriched.distance) + << " / " << util::numeric_cast(turn.operations[1].enriched.distance) << std::endl << "vis: " << bg::visited_char(turn.operations[0].visited) << " / " << bg::visited_char(turn.operations[1].visited); diff --git a/test/algorithms/overlay/traverse_ccw.cpp b/test/algorithms/overlay/traverse_ccw.cpp index a3f643606e..3e90e8d073 100644 --- a/test/algorithms/overlay/traverse_ccw.cpp +++ b/test/algorithms/overlay/traverse_ccw.cpp @@ -144,8 +144,8 @@ intersect(Geometry1 const& g1, Geometry2 const& g2, std::string const& name, // Create a rounded off point std::pair p = std::make_pair( - boost::numeric_cast(0.5 + 10 * bg::get<0>(turn.point)), - boost::numeric_cast(0.5 + 10 * bg::get<1>(turn.point)) + util::numeric_cast(0.5 + 10 * bg::get<0>(turn.point)), + util::numeric_cast(0.5 + 10 * bg::get<1>(turn.point)) ); std::string style = "fill:rgb(0,0,0);font-family:Arial;font-size:10px"; diff --git a/test/algorithms/relate/CMakeLists.txt b/test/algorithms/relate/CMakeLists.txt new file mode 100644 index 0000000000..3efbdbc4e7 --- /dev/null +++ b/test/algorithms/relate/CMakeLists.txt @@ -0,0 +1,25 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +# Cartesian +foreach(item IN ITEMS + relate_const_custom + relate_areal_areal + relate_linear_areal + relate_linear_linear + relate_pointlike_geometry + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() + +# Spherical +foreach(item IN ITEMS + relate_areal_areal_sph + relate_linear_areal_sph + relate_linear_linear_sph + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() diff --git a/test/algorithms/set_operations/CMakeLists.txt b/test/algorithms/set_operations/CMakeLists.txt new file mode 100644 index 0000000000..a27a257eb0 --- /dev/null +++ b/test/algorithms/set_operations/CMakeLists.txt @@ -0,0 +1,10 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +add_subdirectory(union) +add_subdirectory(intersection) +add_subdirectory(difference) +add_subdirectory(sym_difference) diff --git a/test/algorithms/set_operations/difference/CMakeLists.txt b/test/algorithms/set_operations/difference/CMakeLists.txt new file mode 100644 index 0000000000..1878dc5c34 --- /dev/null +++ b/test/algorithms/set_operations/difference/CMakeLists.txt @@ -0,0 +1,27 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +foreach(item IN ITEMS + difference + difference_multi + difference_multi_spike + ) + boost_geometry_add_unit_test("algorithms" ${item}) + target_compile_definitions(${BOOST_GEOMETRY_UNIT_TEST_NAME} PRIVATE BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) +endforeach() + +foreach(item IN ITEMS + difference_gc + difference_l_a_sph + difference_linear_linear + difference_multi_areal_linear + difference_pl_a + difference_pl_l + difference_pl_pl + difference_tupled + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() diff --git a/test/algorithms/set_operations/difference/Jamfile b/test/algorithms/set_operations/difference/Jamfile index 4228363187..8852c49d81 100644 --- a/test/algorithms/set_operations/difference/Jamfile +++ b/test/algorithms/set_operations/difference/Jamfile @@ -18,8 +18,6 @@ test-suite boost-geometry-algorithms-difference : [ run difference.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_difference ] [ run difference_multi.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_difference_multi ] - [ run difference.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_difference_alternative ] - [ run difference_multi.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_difference_multi_alternative ] [ run difference_multi_spike.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_difference_multi_spike ] [ run difference_areal_linear.cpp : : : : algorithms_difference_areal_linear ] [ run difference_gc.cpp : : : : algorithms_difference_gc ] diff --git a/test/algorithms/set_operations/difference/difference.cpp b/test/algorithms/set_operations/difference/difference.cpp index 1c36b8f650..98a7f69a61 100644 --- a/test/algorithms/set_operations/difference/difference.cpp +++ b/test/algorithms/set_operations/difference/difference.cpp @@ -22,6 +22,8 @@ #include +#include + #include #include "test_difference.hpp" @@ -29,8 +31,33 @@ #include #include +namespace +{ + +// Change compiler defines to constexpr bools +// to make conditions more readable +// and to always compile all code. +#if defined(BOOST_GEOMETRY_TEST_FAILURES) +constexpr bool test_failures = true; +#else +constexpr bool test_failures = false; +#endif + +#if defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) +constexpr bool test_only_one_type = true; +#else +constexpr bool test_only_one_type = false; +#endif -// Convenience macros (points are not checked) +#if defined(BOOST_GEOMETRY_TEST_ONLY_ONE_ORDER) +constexpr bool test_only_one_order = true; +#else +constexpr bool test_only_one_order = false; +#endif + +} // namespace + +// Convenience macros (point counts are not checked) #define TEST_DIFFERENCE(caseid, clips1, area1, clips2, area2, clips3) \ (test_one) \ ( #caseid, caseid[0], caseid[1], clips1, -1, area1, clips2, -1, area2, \ @@ -41,10 +68,12 @@ ( #caseid, caseid[0], caseid[1], clips1, -1, area1, clips2, -1, area2, \ clips3, -1, area1 + area2, settings) -template +template void test_all() { - typedef bg::model::polygon

polygon; + using polygon = bg::model::polygon; + + constexpr bool is_ccw = ! ClockWise; test_one("simplex_normal", simplex_normal[0], simplex_normal[1], @@ -67,7 +96,7 @@ void test_all() 1, 5, 8.0); { - // Sym difference works, but expectations are different for rescaling + // It reports self-intersections for symmetric difference ut_settings settings; settings.sym_difference = false; test_one("star_comb_15", @@ -250,19 +279,17 @@ void test_all() TEST_DIFFERENCE(case_precision_9, optional(), optional_sliver(), 1, 59.0, count_set(1, 2)); TEST_DIFFERENCE_WITH(case_precision_10, optional(), optional_sliver(), 1, 59, count_set(1, 2), ut_settings(0.001)); -#if defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) - // Fails without rescaling - TEST_DIFFERENCE(case_precision_11, optional(), optional_sliver(), 1, 59.0, count_set(1, 2)); -#endif + if BOOST_GEOMETRY_CONSTEXPR(test_failures) + { + // Fails (since rescaling is turned off) + TEST_DIFFERENCE(case_precision_11, optional(), optional_sliver(), 1, 59.0, count_set(1, 2)); + } TEST_DIFFERENCE(case_precision_12, 1, 12.0, 0, 0.0, 1); TEST_DIFFERENCE_WITH(case_precision_13, 1, 12, 0, 0.0, 1, ut_settings(0.001)); TEST_DIFFERENCE(case_precision_14, 1, 14.0, 1, 8.0, 1); TEST_DIFFERENCE(case_precision_15, 0, 0.0, 1, 59.0, 1); -#if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) - // Fails if rescaling is used in combination with get_clusters TEST_DIFFERENCE(case_precision_16, optional(), optional_sliver(), 1, 59.0, 1); -#endif TEST_DIFFERENCE(case_precision_17, 0, 0.0, 1, 59.0, 1); TEST_DIFFERENCE(case_precision_18, 0, 0.0, 1, 59.0, 1); TEST_DIFFERENCE(case_precision_19, 1, expectation_limits(1.2e-6, 1.35e-5), 1, 59.0, 2); @@ -335,11 +362,8 @@ void test_all() settings); } -#if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) { 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 @@ -348,7 +372,6 @@ void test_all() ignore_count(), expectation_limits(0.00060440758, 0.00076856), ignore_count(), settings); } -#endif { ut_settings settings; @@ -471,13 +494,14 @@ void test_all() count_set(1, 6), 20.096189, count_set(1, 6)); -#if defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) - // Without rescaling the "b" case produces no output. - test_one("ticket_10108_a", - ticket_10108_a[0], ticket_10108_a[1], - 1, 4, {0.0145036, 0.0145037}, - 1, 4, 0.029019232); -#endif + if BOOST_GEOMETRY_CONSTEXPR(test_failures) + { + // Without rescaling the second case (labeled "b") produces no output. + test_one("ticket_10108_a", + ticket_10108_a[0], ticket_10108_a[1], + 1, 4, {0.0145036, 0.0145037}, + 1, 4, 0.029019232); + } test_one("ticket_10108_b", ticket_10108_b[0], ticket_10108_b[1], @@ -498,66 +522,66 @@ void test_all() 2, 23, 62.25, 0, 0, 0.0); -#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) - typedef bg::model::box

box; - typedef bg::model::ring

ring; - - // Other combinations + if BOOST_GEOMETRY_CONSTEXPR(! test_only_one_type) { - test_one( - "star_ring_ring", example_star, example_ring, - 5, 22, 1.1901714, - 5, 27, 1.6701714); - - test_one( - "ring_star_ring", example_ring, example_star, - 5, 27, 1.6701714, - 5, 22, 1.1901714); - - static std::string const clip = "POLYGON((2.5 0.5,5.5 2.5))"; - - test_one("star_box", - clip, example_star, - 4, 20, 2.833333, 4, 16, 0.833333); - - test_one("box_star", - example_star, clip, - 4, 16, 0.833333, 4, 20, 2.833333); + using box = bg::model::box

; + using ring = bg::model::ring

; + { + // Other combinations + test_one( + "star_ring_ring", example_star, example_ring, + 5, 22, 1.1901714, + 5, 27, 1.6701714); + + test_one( + "ring_star_ring", example_ring, example_star, + 5, 27, 1.6701714, + 5, 22, 1.1901714); + + static std::string const clip = "POLYGON((2.5 0.5,5.5 2.5))"; + + test_one("star_box", + clip, example_star, + 4, 20, 2.833333, 4, 16, 0.833333); + + test_one("box_star", + example_star, clip, + 4, 16, 0.833333, 4, 20, 2.833333); + } + + // Combinations of clockwise and counter clockwise + { + using polygon_ccw = bg::model::polygon; + test_one( + "star_ring_ccw", example_star, example_ring, + 5, 22, 1.1901714, + 5, 27, 1.6701714); + test_one( + "star_ring_ccw1", example_star, example_ring, + 5, 22, 1.1901714, + 5, 27, 1.6701714); + test_one( + "star_ring_ccw2", example_star, example_ring, + 5, 22, 1.1901714, + 5, 27, 1.6701714); + } + + // Multi/box (should be moved to multi) + { + using mp = bg::model::multi_polygon; + + static std::string const clip = "POLYGON((2 2,4 4))"; + + test_one("simplex_multi_box_mp", + clip, case_multi_simplex[0], + 2, -1, 0.53333333333, 3, -1, 8.53333333333); + test_one("simplex_multi_mp_box", + case_multi_simplex[0], clip, + 3, -1, 8.53333333333, 2, -1, 0.53333333333); + + } } - // Counter clockwise - { - typedef bg::model::polygon polygon_ccw; - test_one( - "star_ring_ccw", example_star, example_ring, - 5, 22, 1.1901714, - 5, 27, 1.6701714); - test_one( - "star_ring_ccw1", example_star, example_ring, - 5, 22, 1.1901714, - 5, 27, 1.6701714); - test_one( - "star_ring_ccw2", example_star, example_ring, - 5, 22, 1.1901714, - 5, 27, 1.6701714); - } - - // Multi/box (should be moved to multi) - { - typedef bg::model::multi_polygon mp; - - static std::string const clip = "POLYGON((2 2,4 4))"; - - test_one("simplex_multi_box_mp", - clip, case_multi_simplex[0], - 2, -1, 0.53333333333, 3, -1, 8.53333333333); - test_one("simplex_multi_mp_box", - case_multi_simplex[0], clip, - 3, -1, 8.53333333333, 2, -1, 0.53333333333); - - } -#endif - // Rescaling generates a very small false polygon TEST_DIFFERENCE(issue_566_a, 1, expectation_limits(143.662), optional(), optional_sliver(1.0e-5), @@ -577,24 +601,33 @@ void test_all() settings); } - TEST_DIFFERENCE(issue_875, 1, 3468.77515, 1, 105.425816, 2); -#if ! defined(BOOST_GEOMETRY_USE_RESCALING) || defined(BOOST_GEOMETRY_TEST_FAILURES) + { + // The symmetric difference is invalid for ccw + ut_settings settings; + settings.validity_of_sym = ! is_ccw; + TEST_DIFFERENCE_WITH(issue_875, 1, 3468.77515, 1, 105.425816, 2, settings); + } + TEST_DIFFERENCE(issue_876a, 1, 4728.89916, 1, 786.29563, 2); -#endif TEST_DIFFERENCE(issue_876b, 1, 6114.18234, 1, 4754.29449, count_set(1, 2)); TEST_DIFFERENCE(issue_1138, 1, 203161.751, 2, 1237551.0171, 1); + TEST_DIFFERENCE(issue_1231, 2, 36.798659456837477, 3, 195.2986, 5); + + TEST_DIFFERENCE(issue_1244, 3, 8, 3, 2, 6); + TEST_DIFFERENCE(mysql_21977775, 2, 160.856568913, 2, 92.3565689126, 4); TEST_DIFFERENCE(mysql_21965285, 1, 92.0, 1, 14.0, 1); TEST_DIFFERENCE(mysql_23023665_1, 1, 92.0, 1, 142.5, 2); TEST_DIFFERENCE(mysql_23023665_2, 1, 96.0, 1, 16.0, 2); 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 rescaling it is invalid + // The symmetric difference is invalid for ccw ut_settings settings; - settings.set_test_validity(true); + settings.validity_of_sym = ! is_ccw; TEST_DIFFERENCE_WITH(mysql_23023665_6, 2, 105.68756, 3, 10.18756, 5, settings); } { @@ -609,7 +642,7 @@ void test_all() template void test_specific() { - typedef bg::model::polygon polygon; + using polygon = bg::model::polygon; test_one("ggl_list_20120717_volker", ggl_list_20120717_volker[0], ggl_list_20120717_volker[1], @@ -635,13 +668,18 @@ void test_specific() int test_main(int, char* []) { BoostGeometryWriteTestConfiguration(); - test_all >(); - test_specific, false, false>(); + test_all, true>(); -#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) - test_all >(); -#endif + if BOOST_GEOMETRY_CONSTEXPR(! test_only_one_order) + { + test_all, false>(); + } + + if BOOST_GEOMETRY_CONSTEXPR(! test_only_one_type) + { + test_all, true>(); + } #if defined(BOOST_GEOMETRY_TEST_FAILURES) // Not yet fully tested for float and long double. diff --git a/test/algorithms/set_operations/intersection/CMakeLists.txt b/test/algorithms/set_operations/intersection/CMakeLists.txt new file mode 100644 index 0000000000..baf7d480bc --- /dev/null +++ b/test/algorithms/set_operations/intersection/CMakeLists.txt @@ -0,0 +1,27 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +foreach(item IN ITEMS + intersection + intersection_multi + ) + boost_geometry_add_unit_test("algorithms" ${item}) + target_compile_definitions(${BOOST_GEOMETRY_UNIT_TEST_NAME} PRIVATE BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) +endforeach() + +foreach(item IN ITEMS + intersection_box + intersection_gc + intersection_linear_linear + intersection_areal_areal_linear + intersection_pl_a + intersection_pl_l + intersection_pl_pl + intersection_tupled + intersection_integer + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() \ No newline at end of file diff --git a/test/algorithms/set_operations/intersection/Jamfile b/test/algorithms/set_operations/intersection/Jamfile index c65ebc6732..3ee9b10b59 100644 --- a/test/algorithms/set_operations/intersection/Jamfile +++ b/test/algorithms/set_operations/intersection/Jamfile @@ -18,10 +18,7 @@ test-suite boost-geometry-algorithms-intersection : [ run intersection.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_intersection ] [ run intersection_multi.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_intersection_multi ] - [ run intersection.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_intersection_alternative ] - [ run intersection_multi.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_intersection_multi_alternative ] [ run intersection_linear_linear.cpp : : : : algorithms_intersection_linear_linear ] - [ run intersection_linear_linear.cpp : : : BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_intersection_linear_linear_alternative ] [ run intersection_areal_areal_linear.cpp : : : : algorithms_intersection_areal_areal_linear ] [ run intersection_box.cpp : : : : algorithms_intersection_box ] [ run intersection_gc.cpp : : : : algorithms_intersection_gc ] diff --git a/test/algorithms/set_operations/intersection/intersection.cpp b/test/algorithms/set_operations/intersection/intersection.cpp index 4ce0127604..27a3635943 100644 --- a/test/algorithms/set_operations/intersection/intersection.cpp +++ b/test/algorithms/set_operations/intersection/intersection.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include "test_intersection.hpp" @@ -310,6 +311,12 @@ void test_areal() TEST_INTERSECTION(issue_861, 1, -1, 1.4715007684573677693e-10); #endif + TEST_INTERSECTION(issue_1229, 0, -1, 0); + + TEST_INTERSECTION(issue_1231, 1, -1, 54.701340543162516); + + TEST_INTERSECTION(issue_1244, 1, -1, 7); + test_one("buffer_mp1", buffer_mp1[0], buffer_mp1[1], 1, 31, 2.271707796); test_one("buffer_mp2", buffer_mp2[0], buffer_mp2[1], @@ -414,15 +421,9 @@ void test_areal() TEST_INTERSECTION(mysql_23023665_6, 2, 0, 11.812440191387557); - // Formation of an interior ring is optional - test_one("mysql_23023665_10", - mysql_23023665_10[0], mysql_23023665_10[1], - 1, optional(), -1, 54.701340543162523); - - // Formation of an interior ring is optional - test_one("mysql_23023665_11", - mysql_23023665_11[0], mysql_23023665_11[1], - 1, optional(), -1, 35.933385462482065); + // Formation of an interior ring is optional for these cases + TEST_INTERSECTION(mysql_23023665_10, optional(), 1, 54.701340543162523); + TEST_INTERSECTION(mysql_23023665_11, optional(), 1, 35.933385462482065); // test_one( // "polygon_pseudo_line", @@ -686,9 +687,11 @@ void test_all() std::string clip = "box(2 2,8 8)"; test_areal_linear(); +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_ORDER) + test_areal_linear(); +#endif #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) test_areal_linear(); - test_areal_linear(); test_areal_linear(); #endif @@ -697,8 +700,10 @@ void test_all() // Test polygons clockwise and counter clockwise test_areal(); -#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_ORDER) test_areal(); +#endif +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) test_areal(); test_areal(); #endif @@ -752,7 +757,7 @@ void test_all() // polygons outputing points //test_one("ppp1", simplex_normal[0], simplex_normal[1], 1, 7, 5.47363293); - + test_point_output

(); /* diff --git a/test/algorithms/set_operations/intersection/intersection_linear_linear.cpp b/test/algorithms/set_operations/intersection/intersection_linear_linear.cpp index abaf02e1aa..2d83a75cb1 100644 --- a/test/algorithms/set_operations/intersection/intersection_linear_linear.cpp +++ b/test/algorithms/set_operations/intersection/intersection_linear_linear.cpp @@ -8,7 +8,6 @@ // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html - #include #ifndef BOOST_TEST_MODULE @@ -1300,7 +1299,7 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_degenerate ) // NOTE: if get_turn_info uses policy_verify_all then the result is different #if BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS - from_wkt("MULTILINESTRING((-0.7654 8.88178e-16,-0.7654 0,5 3))"), + from_wkt("MULTILINESTRING((-0.7654 0,5 3))"), #else from_wkt("MULTILINESTRING((-0.756651 3.30964),(1.60494 6),\ (2.51371 6),(3.26673 6),(4 6),(8.18862 3.07616),\ @@ -1337,7 +1336,7 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_degenerate ) (8.5655 2.85228),(5.26567 4.81254),(4 3.8),\ (1.4995 3.27036),(0.591231 3.43401),\ (-0.706503 3.66784),\ - (-0.7654 8.88178e-16,-0.7654 0,5 3))"), + (-0.7654 0,5 3))"), from_wkt("MULTILINESTRING((1.87562 6.68515),(1.60494 6),\ (1.18124 4.9275),(1.00439 4.47984),(0.91526 4.25422),\ (0.729883 3.78498),(0.614728 3.49349),\ @@ -1368,7 +1367,7 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_degenerate ) (9.98265 0.00543606),(9.09826 -100.515944),\ (7.08745 -329.0674155),(5.06428 -559.024344),\ (3.23365 -767.0972558),(3.16036 -775.427199),\ - (-0.7654 8.88178e-16,-0.7654 0,5 3))"), + (-0.7654 0,5 3))"), #endif // isolated "mlmli21", 1e-4 diff --git a/test/algorithms/set_operations/sym_difference/CMakeLists.txt b/test/algorithms/set_operations/sym_difference/CMakeLists.txt new file mode 100644 index 0000000000..07d2ecdaf6 --- /dev/null +++ b/test/algorithms/set_operations/sym_difference/CMakeLists.txt @@ -0,0 +1,14 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +foreach(item IN ITEMS + sym_difference_gc + sym_difference_areal_areal + sym_difference_linear_linear + sym_difference_tupled + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() diff --git a/test/algorithms/set_operations/union/CMakeLists.txt b/test/algorithms/set_operations/union/CMakeLists.txt new file mode 100644 index 0000000000..6cfd20a50a --- /dev/null +++ b/test/algorithms/set_operations/union/CMakeLists.txt @@ -0,0 +1,26 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +foreach(item IN ITEMS + union + union_multi + union_other_types + ) + boost_geometry_add_unit_test("algorithms" ${item}) + target_compile_definitions(${BOOST_GEOMETRY_UNIT_TEST_NAME} PRIVATE BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) +endforeach() + +foreach(item IN ITEMS + union_aa_geo + union_aa_sph + union_gc + union_linear_linear + union_pl_pl + union_issues + union_tupled + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() diff --git a/test/algorithms/set_operations/union/Jamfile b/test/algorithms/set_operations/union/Jamfile index 6cd0159c03..c82973a32e 100644 --- a/test/algorithms/set_operations/union/Jamfile +++ b/test/algorithms/set_operations/union/Jamfile @@ -18,8 +18,6 @@ test-suite boost-geometry-algorithms-union : [ run union.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_union ] [ run union_multi.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE : algorithms_union_multi ] - [ run union.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_union_alternative ] - [ run union_multi.cpp : : : BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE BOOST_GEOMETRY_ROBUSTNESS_ALTERNATIVE : algorithms_union_multi_alternative ] [ run union_aa_geo.cpp : : : : algorithms_union_aa_geo ] [ run union_aa_sph.cpp : : : : algorithms_union_aa_sph ] [ run union_gc.cpp : : : : algorithms_union_gc ] diff --git a/test/algorithms/set_operations/union/union.cpp b/test/algorithms/set_operations/union/union.cpp index a009911cc1..3e47a12870 100644 --- a/test/algorithms/set_operations/union/union.cpp +++ b/test/algorithms/set_operations/union/union.cpp @@ -24,6 +24,7 @@ #include #include +#include #define TEST_UNION(caseid, clips, holes, points, area) \ @@ -44,6 +45,8 @@ void test_areal() { typedef typename bg::coordinate_type::type ct; + constexpr bool is_ccw = bg::point_order::value == bg::counterclockwise; + ut_settings ignore_validity_for_float; if (BOOST_GEOMETRY_CONDITION((std::is_same::value)) ) { @@ -471,12 +474,16 @@ void test_areal() TEST_UNION(issue_1186, 1, 1, -1, 21.6189); TEST_UNION_REV(issue_1186, 1, 1, -1, 21.6189); - { - // Rescaling produces an invalid result - ut_settings settings; - settings.set_test_validity(BG_IF_RESCALED(false, true)); - TEST_UNION_WITH(geos_1, 1, 0, -1, expectation_limits(3458.0, 3461.3203125)); - } + TEST_UNION(issue_1229, 1, 0, -1, 384869.166); + TEST_UNION_REV(issue_1229, 1, 0, -1, 384869.166); + + TEST_UNION(issue_1231, 1, 0, -1, 286.799); + TEST_UNION_REV(issue_1231, 1, 0, -1, 286.799); + + TEST_UNION(issue_1244, 1, 1, -1, 17); + TEST_UNION_REV(issue_1244, 1, 1, -1, 17); + + TEST_UNION(geos_1, 1, 0, -1, expectation_limits(3458.0, 3461.3203125)); TEST_UNION(geos_2, 1, 0, -1, expectation_limits(349.0625, 350.55102539)); TEST_UNION(geos_3, 1, 0, -1, 29391548.4998779); TEST_UNION(geos_4, 1, 0, -1, 2304.4163115); @@ -541,8 +548,14 @@ void test_areal() test_one("buffer_mp1", buffer_mp1[0], buffer_mp1[1], 1, 0, -1, 22.815); - test_one("buffer_mp2", buffer_mp2[0], buffer_mp2[1], - 1, -1, 217, 36.752837); + { + // Contains a self-intersection invalidity for ccw + ut_settings settings; + settings.set_test_validity(! is_ccw); + test_one("buffer_mp2", + buffer_mp2[0], buffer_mp2[1], + 1, -1, 217, 36.752837, settings); + } test_one("mysql_21964079_1", mysql_21964079_1[0], mysql_21964079_1[1], @@ -565,12 +578,12 @@ void test_areal() 1, 1, -1, 220.5); } -template +template void test_all() { - typedef bg::model::polygon

polygon; - typedef bg::model::ring

ring; - typedef bg::model::box

box; + using polygon = bg::model::polygon; + using ring = bg::model::ring

; + using box = bg::model::box

; test_areal(); @@ -626,12 +639,16 @@ void test_all() int test_main(int, char* []) { BoostGeometryWriteTestConfiguration(); - test_all>(); + test_all, true>(); + +#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_ORDER) + test_all, false>(); +#endif #if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE) - test_all>(); - test_all>(); - test_all>(); + test_all, true>(); + test_all, true>(); + test_all, true>(); #endif #if defined(BOOST_GEOMETRY_TEST_FAILURES) diff --git a/test/algorithms/within/CMakeLists.txt b/test/algorithms/within/CMakeLists.txt new file mode 100644 index 0000000000..d2e7bf33d6 --- /dev/null +++ b/test/algorithms/within/CMakeLists.txt @@ -0,0 +1,26 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +# Cartesian +foreach(item IN ITEMS + within + within_areal_areal + within_gc + within_linear_areal + within_linear_linear + within_multi + within_pointlike_geometry + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() + +# Spherical +foreach(item IN ITEMS + within_sph + within_sph_geo + ) + boost_geometry_add_unit_test("algorithms" ${item}) +endforeach() diff --git a/test/geometries/box.cpp b/test/geometries/box.cpp index cfe5fbfdca..b5910a33da 100644 --- a/test/geometries/box.cpp +++ b/test/geometries/box.cpp @@ -69,12 +69,12 @@ void test_construction() check_box(b2, 1,2,5,3,4,6); bg::model::box

b3 = bg::make_inverse >(); - check_box(b3, boost::numeric::bounds::highest(), - boost::numeric::bounds::highest(), - boost::numeric::bounds::highest(), - boost::numeric::bounds::lowest(), - boost::numeric::bounds::lowest(), - boost::numeric::bounds::lowest()); + check_box(b3, bg::util::bounds::highest(), + bg::util::bounds::highest(), + bg::util::bounds::highest(), + bg::util::bounds::lowest(), + bg::util::bounds::lowest(), + bg::util::bounds::lowest()); } template diff --git a/test/to_svg.hpp b/test/to_svg.hpp index 8b6e9ebe67..99b6c19a65 100644 --- a/test/to_svg.hpp +++ b/test/to_svg.hpp @@ -53,9 +53,9 @@ inline void turns_to_svg(Turns const& turns, Mapper& mapper) // Create a rounded off point std::pair p = std::make_pair( - boost::numeric_cast(half + util::numeric_cast(half + ten * bg::get<0>(turn.point)), - boost::numeric_cast(half + util::numeric_cast(half + ten * bg::get<1>(turn.point)) ); std::string style = "fill:rgb(0,0,0);font-family:Arial;font-size:12px"; diff --git a/test/util/CMakeLists.txt b/test/util/CMakeLists.txt new file mode 100644 index 0000000000..de954beb64 --- /dev/null +++ b/test/util/CMakeLists.txt @@ -0,0 +1,24 @@ +# Boost.Geometry +# Copyright (c) 2024 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) + +foreach(item IN ITEMS + algorithm + calculation_type + for_each_coordinate + math_abs + math_divide + math_equals + math_sqrt + math_normalize_spheroidal + promote_integral + range + rational + select_most_precise + tuples + write_dsv + ) + boost_geometry_add_unit_test("util" ${item}) +endforeach() diff --git a/test/util/rational.cpp b/test/util/rational.cpp index 8ec47eb9c5..1e3056edf3 100644 --- a/test/util/rational.cpp +++ b/test/util/rational.cpp @@ -1,7 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2007-2024 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. @@ -15,17 +15,104 @@ #include +#include +#include +#include +#include +#include #include #include +#include #include void test_coordinate_cast(std::string const& s, int expected_nom, int expected_denom) { - boost::rational a = bg::detail::coordinate_cast >::apply(s); + boost::rational const a = bg::detail::coordinate_cast >::apply(s); BOOST_CHECK_EQUAL(a.numerator(), expected_nom); BOOST_CHECK_EQUAL(a.denominator(), expected_denom); } +void test_numeric_cast() +{ + boost::rational const r1(3, 4); + BOOST_CHECK_CLOSE(bg::util::numeric_cast(r1), 0.75, 0.00001); + + boost::rational const r2(10, 4); + BOOST_CHECK_CLOSE(bg::util::numeric_cast(r2), 2.5, 0.00001); + BOOST_CHECK_EQUAL(bg::util::numeric_cast(r2), 2); +} + +template +void test_bounds() +{ + using coordinate_t = boost::rational; + using point_t = bg::model::point; + + auto const lowest = bg::util::bounds::lowest(); + auto const highest = bg::util::bounds::highest(); + + BOOST_CHECK_MESSAGE(lowest < highest, + "Lowest should be smaller than highest, lowest: " << lowest << " highest: " << highest); +} + +// Tests box-related functionality, which depends on geometry::util::bounds +// specialization for Boost.Rational +template +void test_box() +{ + using coordinate_t = boost::rational; + using point_t = bg::model::point; + using box_t = bg::model::box; + + box_t box; + bg::assign_inverse(box); + + point_t south_west, north_east; + bg::detail::assign_point_from_index<0>(box, south_west); + bg::detail::assign_point_from_index<1>(box, north_east); + + BOOST_CHECK_MESSAGE(bg::get<0>(south_west) > bg::get<0>(north_east), + "Bounding box should be inversed. Now x-min: " << bg::get<0>(south_west) + << " x-max: " << bg::get<0>(north_east) + << " " << bg::wkt(box)); + + BOOST_CHECK_MESSAGE(bg::get<1>(south_west) > bg::get<1>(north_east), + "Bounding box should be inversed. Now y-min: " << bg::get<1>(south_west) + << " y-max: " << bg::get<1>(north_east) + << " " << bg::wkt(box)); + + // Test specifically for points larger than 0, because without specialization Boost.Rational + // will return (0,1) (== 0) by default and code will compile but give wrong results. + bg::expand(box, bg::make(4, 4)); + bg::expand(box, bg::make(8, 8)); + + // Test within (without specialization, both points are within the box) + auto const point1 = bg::make(6, 6); + auto const point2 = bg::make(2, 2); + BOOST_CHECK_MESSAGE(bg::within(point1, box), + "Point " << bg::wkt(point1) << " is not within the box " << bg::wkt(box)); + BOOST_CHECK_MESSAGE(! bg::within(point2, box), + "Point " << bg::wkt(point2) << " is within the box " << bg::wkt(box)); + + // Test area (without specialization, it will be 64) + auto const area = bg::util::numeric_cast(bg::area(box)); + T const expected_area = 16; + BOOST_CHECK_EQUAL(expected_area, area); +} + +void test_select_most_precise() +{ + using rational1_t = boost::rational; + using rational2_t = boost::rational; + + using t1 = bg::select_most_precise::type; + using t2 = bg::select_most_precise::type; + using t12 = bg::select_most_precise::type; + + BOOST_CHECK((std::is_same::value)); + BOOST_CHECK((std::is_same::value)); + BOOST_CHECK((std::is_same::value)); +} void test_wkt(std::string const& wkt, std::string const expected_wkt) { @@ -52,6 +139,16 @@ int test_main(int, char* []) test_coordinate_cast("3/2", 3, 2); test_coordinate_cast("-3/2", -3, 2); + test_numeric_cast(); + + test_bounds(); + test_bounds(); + test_bounds(); + + test_box(); + + test_select_most_precise(); + test_wkt("POINT(1.5 2.75)", "POINT(3/2 11/4)"); test_wkt("POINT(3/2 11/4)", "POINT(3/2 11/4)"); test_wkt("POINT(-1.5 2.75)", "POINT(-3/2 11/4)");