Merge branch 'develop'

This commit is contained in:
Vissarion Fisikopoulos 2024-04-02 10:44:27 +03:00
commit f82eb32da7
248 changed files with 2887 additions and 1769 deletions

View File

@ -38,8 +38,8 @@ jobs:
fi fi
echo "BOOST_SELF=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_ENV echo "BOOST_SELF=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_ENV
echo "BOOST_ROOT=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_ENV echo "BOOST_ROOT=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_ENV
echo "::set-output name=boost_self::$(basename $GITHUB_WORKSPACE)" echo "boost_self=$(basename $GITHUB_WORKSPACE)" >> "$GITHUB_OUTPUT"
echo "::set-output name=boost_root::$GITHUB_WORKSPACE/boost-root" echo "boost_root=$GITHUB_WORKSPACE/boost-root" >> "$GITHUB_OUTPUT"
- name: Clone boostorg/boost - name: Clone boostorg/boost
run: | run: |

View File

@ -28,8 +28,8 @@ jobs:
fi fi
echo "BOOST_SELF=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_ENV echo "BOOST_SELF=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_ENV
echo "BOOST_ROOT=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_ENV echo "BOOST_ROOT=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_ENV
echo "::set-output name=boost_self::$(basename $GITHUB_WORKSPACE)" echo "boost_self=$(basename $GITHUB_WORKSPACE)" >> "$GITHUB_OUTPUT"
echo "::set-output name=boost_root::$GITHUB_WORKSPACE/boost-root" echo "boost_root=$GITHUB_WORKSPACE/boost-root" >> "$GITHUB_OUTPUT"
- name: Clone boostorg/boost - name: Clone boostorg/boost
run: | run: |

View File

@ -102,8 +102,8 @@ jobs:
fi fi
echo "BOOST_SELF=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_ENV echo "BOOST_SELF=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_ENV
echo "BOOST_ROOT=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_ENV echo "BOOST_ROOT=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_ENV
echo "boost_self=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_OUTPUT echo "boost_self=$(basename $GITHUB_WORKSPACE)" >> "$GITHUB_OUTPUT"
echo "boost_root=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_OUTPUT echo "boost_root=$GITHUB_WORKSPACE/boost-root" >> "$GITHUB_OUTPUT"
- name: Clone boostorg/boost - name: Clone boostorg/boost
run: | run: |
@ -221,8 +221,8 @@ jobs:
fi fi
echo "BOOST_SELF=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_ENV echo "BOOST_SELF=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_ENV
echo "BOOST_ROOT=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_ENV echo "BOOST_ROOT=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_ENV
echo "boost_self=$(basename $GITHUB_WORKSPACE)" >> $GITHUB_OUTPUT echo "boost_self=$(basename $GITHUB_WORKSPACE)" >> "$GITHUB_OUTPUT"
echo "boost_root=$GITHUB_WORKSPACE/boost-root" >> $GITHUB_OUTPUT echo "boost_root=$GITHUB_WORKSPACE/boost-root" >> "$GITHUB_OUTPUT"
- name: Clone boostorg/boost - name: Clone boostorg/boost
run: | run: |

View File

@ -1,5 +1,7 @@
# Generated by `boostdep --cmake geometry` # Originally generated by `boostdep --cmake geometry`
# Adapted manually
# Copyright 2020, 2021 Peter Dimov # Copyright 2020, 2021 Peter Dimov
# Copyright (c) 2024 Barend Gehrels, Amsterdam, the Netherlands.
# Distributed under the Boost Software License, Version 1.0. # Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt # https://www.boost.org/LICENSE_1_0.txt
@ -11,6 +13,7 @@ add_library(boost_geometry INTERFACE)
add_library(Boost::geometry ALIAS boost_geometry) add_library(Boost::geometry ALIAS boost_geometry)
target_include_directories(boost_geometry INTERFACE include) target_include_directories(boost_geometry INTERFACE include)
target_compile_features(boost_geometry INTERFACE cxx_std_14)
target_link_libraries(boost_geometry target_link_libraries(boost_geometry
INTERFACE INTERFACE
@ -20,12 +23,8 @@ target_link_libraries(boost_geometry
Boost::assert Boost::assert
Boost::concept_check Boost::concept_check
Boost::config Boost::config
Boost::container
Boost::core Boost::core
Boost::endian
Boost::function_types Boost::function_types
Boost::fusion
Boost::integer
Boost::iterator Boost::iterator
Boost::lexical_cast Boost::lexical_cast
Boost::math Boost::math
@ -33,28 +32,97 @@ target_link_libraries(boost_geometry
Boost::mpl Boost::mpl
Boost::multiprecision Boost::multiprecision
Boost::numeric_conversion Boost::numeric_conversion
Boost::polygon
Boost::predef
Boost::qvm Boost::qvm
Boost::range Boost::range
Boost::rational Boost::rational
Boost::serialization
Boost::smart_ptr
Boost::static_assert Boost::static_assert
Boost::thread
Boost::throw_exception Boost::throw_exception
Boost::tokenizer Boost::tokenizer
Boost::tuple Boost::tuple
Boost::type_traits Boost::type_traits
Boost::utility Boost::utility
Boost::variant 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(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) add_subdirectory(test)
endif() endif()

View File

@ -6,8 +6,8 @@
Copyright (c) 2009-2017 Mateusz Loskot <mateusz@loskot.net>, London, UK. Copyright (c) 2009-2017 Mateusz Loskot <mateusz@loskot.net>, London, UK.
Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland. Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
This file was modified by Oracle on 2015-2023. This file was modified by Oracle on 2015-2024.
Modifications copyright (c) 2015-2023, Oracle and/or its affiliates. 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 Vissarion Fysikopoulos, on behalf of Oracle
Contributed and/or modified by Menelaos Karavelas, 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 Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -19,6 +19,27 @@
[section:release_notes Release Notes] [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] [heading Boost 1.84]
[/=================] [/=================]
@ -37,16 +58,16 @@
[*Improvements] [*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/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/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/1157 1157] Check const Ring concept in calculate_point_order
[*Solved issues] [*Solved issues]
* [@https://github.com/boostorg/geometry/issues/1100 1100] Fix for union * [@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/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/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 * Various fixes of errors and warnings
[/=================] [/=================]

View File

@ -24,7 +24,6 @@
#include <cstddef> #include <cstddef>
#include <type_traits> #include <type_traits>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/size.hpp> #include <boost/range/size.hpp>
@ -45,6 +44,7 @@
#include <boost/geometry/geometries/concepts/check.hpp> #include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/util/numeric_cast.hpp>
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
#include <boost/geometry/views/detail/closed_clockwise_view.hpp> #include <boost/geometry/views/detail/closed_clockwise_view.hpp>
@ -80,7 +80,7 @@ struct point_to_box
typedef typename coordinate_type<Box>::type coordinate_type; typedef typename coordinate_type<Box>::type coordinate_type;
set<Index, Dimension>(box, set<Index, Dimension>(box,
boost::numeric_cast<coordinate_type>(get<Dimension>(point))); util::numeric_cast<coordinate_type>(get<Dimension>(point)));
point_to_box point_to_box
< <
Point, Box, Point, Box,

View File

@ -21,12 +21,11 @@
#include <cstddef> #include <cstddef>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/geometry/core/access.hpp> #include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_type.hpp> #include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/geometries/concepts/check.hpp> #include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/util/algorithm.hpp> #include <boost/geometry/util/algorithm.hpp>
#include <boost/geometry/util/numeric_cast.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -60,7 +59,7 @@ inline void assign_point_to_index(Point const& point, Geometry& geometry)
detail::for_each_dimension<Geometry>([&](auto dimension) detail::for_each_dimension<Geometry>([&](auto dimension)
{ {
geometry::set<Index, dimension>(geometry, geometry::set<Index, dimension>(geometry,
boost::numeric_cast util::numeric_cast
< <
typename coordinate_type<Geometry>::type typename coordinate_type<Geometry>::type
>(geometry::get<dimension>(point))); >(geometry::get<dimension>(point)));
@ -92,7 +91,7 @@ inline void assign_point_from_index(Geometry const& geometry, Point& point)
detail::for_each_dimension<Geometry>([&](auto dimension) detail::for_each_dimension<Geometry>([&](auto dimension)
{ {
geometry::set<dimension>(point, geometry::set<dimension>(point,
boost::numeric_cast util::numeric_cast
< <
typename coordinate_type<Point>::type typename coordinate_type<Point>::type
>(geometry::get<Index, dimension>(geometry))); >(geometry::get<Index, dimension>(geometry)));

View File

@ -26,8 +26,6 @@
#include <boost/concept/requires.hpp> #include <boost/concept/requires.hpp>
#include <boost/concept_check.hpp> #include <boost/concept_check.hpp>
#include <boost/numeric/conversion/bounds.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/geometry/algorithms/append.hpp> #include <boost/geometry/algorithms/append.hpp>
#include <boost/geometry/algorithms/clear.hpp> #include <boost/geometry/algorithms/clear.hpp>
@ -39,7 +37,8 @@
#include <boost/geometry/geometries/concepts/check.hpp> #include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/util/algorithm.hpp> #include <boost/geometry/util/algorithm.hpp>
#include <boost/geometry/util/is_inverse_spheroidal_coordinates.hpp> #include <boost/geometry/util/bounds.hpp>
#include <boost/geometry/util/numeric_cast.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -74,8 +73,8 @@ struct assign_inverse_box_or_segment
{ {
typedef typename coordinate_type<BoxOrSegment>::type coordinate_type; typedef typename coordinate_type<BoxOrSegment>::type coordinate_type;
coordinate_type const highest = geometry::bounds<coordinate_type>::highest(); coordinate_type const highest = util::bounds<coordinate_type>::highest();
coordinate_type const lowest = geometry::bounds<coordinate_type>::lowest(); coordinate_type const lowest = util::bounds<coordinate_type>::lowest();
detail::for_each_dimension<BoxOrSegment>([&](auto dimension) detail::for_each_dimension<BoxOrSegment>([&](auto dimension)
{ {
set<0, dimension>(geometry, highest); set<0, dimension>(geometry, highest);
@ -117,8 +116,8 @@ inline void assign_box_2d_corner(Box const& box, Point& point)
// Copy coordinates // Copy coordinates
typedef typename coordinate_type<Point>::type coordinate_type; typedef typename coordinate_type<Point>::type coordinate_type;
geometry::set<0>(point, boost::numeric_cast<coordinate_type>(get<Corner1, 0>(box))); geometry::set<0>(point, util::numeric_cast<coordinate_type>(get<Corner1, 0>(box)));
geometry::set<1>(point, boost::numeric_cast<coordinate_type>(get<Corner2, 1>(box))); geometry::set<1>(point, util::numeric_cast<coordinate_type>(get<Corner2, 1>(box)));
} }
@ -136,10 +135,10 @@ struct assign_2d_box_or_segment
static inline void apply(Geometry& geometry, static inline void apply(Geometry& geometry,
Type const& x1, Type const& y1, Type const& x2, Type const& y2) Type const& x1, Type const& y1, Type const& x2, Type const& y2)
{ {
geometry::set<0, 0>(geometry, boost::numeric_cast<coordinate_type>(x1)); geometry::set<0, 0>(geometry, util::numeric_cast<coordinate_type>(x1));
geometry::set<0, 1>(geometry, boost::numeric_cast<coordinate_type>(y1)); geometry::set<0, 1>(geometry, util::numeric_cast<coordinate_type>(y1));
geometry::set<1, 0>(geometry, boost::numeric_cast<coordinate_type>(x2)); geometry::set<1, 0>(geometry, util::numeric_cast<coordinate_type>(x2));
geometry::set<1, 1>(geometry, boost::numeric_cast<coordinate_type>(y2)); geometry::set<1, 1>(geometry, util::numeric_cast<coordinate_type>(y2));
} }
}; };
@ -167,8 +166,8 @@ struct assign<point_tag, Point, 2>
template <typename T> template <typename T>
static inline void apply(Point& point, T const& c1, T const& c2) static inline void apply(Point& point, T const& c1, T const& c2)
{ {
set<0>(point, boost::numeric_cast<coordinate_type>(c1)); set<0>(point, util::numeric_cast<coordinate_type>(c1));
set<1>(point, boost::numeric_cast<coordinate_type>(c2)); set<1>(point, util::numeric_cast<coordinate_type>(c2));
} }
}; };
@ -180,9 +179,9 @@ struct assign<point_tag, Point, 3>
template <typename T> template <typename T>
static inline void apply(Point& point, T const& c1, T const& c2, T const& c3) static inline void apply(Point& point, T const& c1, T const& c2, T const& c3)
{ {
set<0>(point, boost::numeric_cast<coordinate_type>(c1)); set<0>(point, util::numeric_cast<coordinate_type>(c1));
set<1>(point, boost::numeric_cast<coordinate_type>(c2)); set<1>(point, util::numeric_cast<coordinate_type>(c2));
set<2>(point, boost::numeric_cast<coordinate_type>(c3)); set<2>(point, util::numeric_cast<coordinate_type>(c3));
} }
}; };

View File

@ -18,7 +18,6 @@
#include <iterator> #include <iterator>
#include <boost/core/ignore_unused.hpp> #include <boost/core/ignore_unused.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/rbegin.hpp> #include <boost/range/rbegin.hpp>
@ -973,8 +972,9 @@ inline void buffer_inserter(GeometryInput const& geometry_input, OutputIterator
{ {
collection.check_turn_in_original(); collection.check_turn_in_original();
} }
collection.handle_colocations();
collection.verify_turns(); collection.check_turn_in_pieces();
collection.make_traversable_consistent_per_cluster();
// Visit the piece collection. This does nothing (by default), but // Visit the piece collection. This does nothing (by default), but
// optionally a debugging tool can be attached (e.g. console or svg), // optionally a debugging tool can be attached (e.g. console or svg),

View File

@ -281,16 +281,6 @@ struct turn_overlaps_box
Strategy const& m_strategy; Strategy const& m_strategy;
}; };
struct enriched_map_buffer_include_policy
{
template <typename Operation>
static inline bool include(Operation const& op)
{
return op != detail::overlay::operation_intersection
&& op != detail::overlay::operation_blocked;
}
};
}} // namespace detail::buffer }} // namespace detail::buffer
#endif // DOXYGEN_NO_DETAIL #endif // DOXYGEN_NO_DETAIL

View File

@ -249,7 +249,8 @@ struct buffered_piece_collection
// Offsetted rings, and representations of original ring(s) // Offsetted rings, and representations of original ring(s)
// both indexed by multi_index // both indexed by multi_index
buffered_ring_collection<buffered_ring<Ring> > offsetted_rings; using ring_collection_t = buffered_ring_collection<buffered_ring<Ring>>;
ring_collection_t offsetted_rings;
std::vector<original_ring> original_rings; std::vector<original_ring> original_rings;
std::vector<point_type> m_linear_end_points; std::vector<point_type> 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<indexed_turn_operation>
> 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() inline void deflate_check_turns()
{ {
if (! m_has_deflated) if (! m_has_deflated)
@ -470,24 +448,25 @@ struct buffered_piece_collection
} }
update_turn_administration(); update_turn_administration();
}
{ inline void check_turn_in_pieces()
// Check if turns are inside pieces {
turn_in_piece_visitor // Check if turns are inside pieces
< turn_in_piece_visitor
typename geometry::cs_tag<point_type>::type, <
turn_vector_type, piece_vector_type, DistanceStrategy, Strategy typename geometry::cs_tag<point_type>::type,
> visitor(m_turns, m_pieces, m_distance_strategy, m_strategy); turn_vector_type, piece_vector_type, DistanceStrategy, Strategy
> visitor(m_turns, m_pieces, m_distance_strategy, m_strategy);
geometry::partition geometry::partition
< <
box_type box_type
>::apply(m_turns, m_pieces, visitor, >::apply(m_turns, m_pieces, visitor,
turn_get_box<Strategy>(m_strategy), turn_get_box<Strategy>(m_strategy),
turn_overlaps_box<Strategy>(m_strategy), turn_overlaps_box<Strategy>(m_strategy),
piece_get_box<Strategy>(m_strategy), piece_get_box<Strategy>(m_strategy),
piece_overlaps_box<Strategy>(m_strategy)); piece_overlaps_box<Strategy>(m_strategy));
}
} }
inline void start_new_ring(bool deflate) 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() inline void enrich()
{ {
enrich_intersection_points<false, false, overlay_buffer>(m_turns, enrich_intersection_points<false, false, overlay_buffer>(m_turns,

View File

@ -17,10 +17,10 @@
#include <cstddef> #include <cstddef>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/geometry/core/access.hpp> #include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp> #include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_type.hpp> #include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/util/numeric_cast.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -45,10 +45,10 @@ struct indexed_to_indexed
typedef typename coordinate_type<Destination>::type coordinate_type; typedef typename coordinate_type<Destination>::type coordinate_type;
geometry::set<min_corner, Dimension>(destination, geometry::set<min_corner, Dimension>(destination,
boost::numeric_cast<coordinate_type>( util::numeric_cast<coordinate_type>(
geometry::get<min_corner, Dimension>(source))); geometry::get<min_corner, Dimension>(source)));
geometry::set<max_corner, Dimension>(destination, geometry::set<max_corner, Dimension>(destination,
boost::numeric_cast<coordinate_type>( util::numeric_cast<coordinate_type>(
geometry::get<max_corner, Dimension>(source))); geometry::get<max_corner, Dimension>(source)));
indexed_to_indexed indexed_to_indexed

View File

@ -18,10 +18,10 @@
#include <cstddef> #include <cstddef>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/geometry/core/access.hpp> #include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp> #include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_type.hpp> #include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/util/numeric_cast.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -45,7 +45,7 @@ struct point_to_point
{ {
typedef typename coordinate_type<Destination>::type coordinate_type; typedef typename coordinate_type<Destination>::type coordinate_type;
set<Dimension>(destination, boost::numeric_cast<coordinate_type>(get<Dimension>(source))); set<Dimension>(destination, util::numeric_cast<coordinate_type>(get<Dimension>(source)));
point_to_point<Source, Destination, Dimension + 1, DimensionCount>::apply(source, destination); point_to_point<Source, Destination, Dimension + 1, DimensionCount>::apply(source, destination);
} }
}; };

View File

@ -53,7 +53,7 @@
#include <boost/geometry/strategies/convex_hull/spherical.hpp> #include <boost/geometry/strategies/convex_hull/spherical.hpp>
#include <boost/geometry/strategies/default_strategy.hpp> #include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
#include <boost/geometry/util/sequence.hpp> #include <boost/geometry/util/sequence.hpp>
#include <boost/geometry/util/type_traits.hpp> #include <boost/geometry/util/type_traits.hpp>
@ -240,7 +240,7 @@ struct convex_hull<Box, box_tag>
geometry::detail::assign_box_corners_oriented<Reverse>(box, arr); geometry::detail::assign_box_corners_oriented<Reverse>(box, arr);
std::move(arr.begin(), arr.end(), range::back_inserter(out)); 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)); range::push_back(out, range::front(out));
} }

View File

@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // 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 Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -35,7 +36,7 @@
#include <boost/geometry/strategies/distance.hpp> #include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp> #include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -247,26 +248,28 @@ public:
} }
} }
if (BOOST_GEOMETRY_CONDITION(is_comparable<strategy_type>::value)) if BOOST_GEOMETRY_CONSTEXPR (is_comparable<strategy_type>::value)
{ {
return (std::min)(cd_min1, cd_min2); return (std::min)(cd_min1, cd_min2);
} }
else // else prevents unreachable code warning
if (cd_min1 < cd_min2)
{ {
return strategy.apply(*pit_min, *it_min1, *it_min2); if (cd_min1 < cd_min2)
} {
else return strategy.apply(*pit_min, *it_min1, *it_min2);
{ }
return dispatch::distance else
< {
segment_or_box_point, return dispatch::distance
typename std::iterator_traits <
< segment_or_box_point,
segment_iterator_type typename std::iterator_traits
>::value_type, <
Strategies segment_iterator_type
>::apply(*it_min, *sit_min, strategies); >::value_type,
Strategies
>::apply(*it_min, *sit_min, strategies);
}
} }
} }

View File

@ -1,5 +1,7 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2023-2024 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2014-2023 Oracle and/or its affiliates. // Copyright (c) 2014-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
@ -18,7 +20,6 @@
#include <vector> #include <vector>
#include <boost/core/ignore_unused.hpp> #include <boost/core/ignore_unused.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/geometry/algorithms/detail/assign_box_corners.hpp> #include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp> #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
@ -41,9 +42,10 @@
#include <boost/geometry/policies/compare.hpp> #include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/util/calculation_type.hpp> #include <boost/geometry/util/calculation_type.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/has_nan_coordinate.hpp> #include <boost/geometry/util/has_nan_coordinate.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/numeric_cast.hpp>
#include <boost/geometry/strategies/disjoint.hpp> #include <boost/geometry/strategies/disjoint.hpp>
#include <boost/geometry/strategies/distance.hpp> #include <boost/geometry/strategies/distance.hpp>
@ -154,21 +156,23 @@ public:
} }
} }
if (BOOST_GEOMETRY_CONDITION(is_comparable<ps_strategy_type>::value)) if BOOST_GEOMETRY_CONSTEXPR (is_comparable<ps_strategy_type>::value)
{ {
return cd[imin]; return cd[imin];
} }
else // else prevents unreachable code warning
if (imin < 4)
{ {
return strategy.apply(box_points[imin], p[0], p[1]); if (imin < 4)
} {
else return strategy.apply(box_points[imin], p[0], p[1]);
{ }
unsigned int bimin = imin - 4; else
return strategy.apply(p[bimin], {
*bit_min[bimin].first, unsigned int bimin = imin - 4;
*bit_min[bimin].second); return strategy.apply(p[bimin],
*bit_min[bimin].first,
*bit_min[bimin].second);
}
} }
} }
}; };
@ -285,7 +289,7 @@ private:
template <typename T> template <typename T>
static inline Result apply(T const& t) static inline Result apply(T const& t)
{ {
return boost::numeric_cast<Result>(t); return util::numeric_cast<Result>(t);
} }
}; };

View File

@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // 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 Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -28,7 +29,7 @@
#include <boost/geometry/strategies/distance.hpp> #include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp> #include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -82,21 +83,23 @@ public:
std::size_t imin = std::distance(boost::addressof(d[0]), std::size_t imin = std::distance(boost::addressof(d[0]),
std::min_element(d, d + 4)); std::min_element(d, d + 4));
if (BOOST_GEOMETRY_CONDITION(is_comparable<strategy_type>::value)) if BOOST_GEOMETRY_CONSTEXPR (is_comparable<strategy_type>::value)
{ {
return d[imin]; return d[imin];
} }
else // else prevents unreachable code warning
switch (imin)
{ {
case 0: switch (imin)
return strategy.apply(q[0], p[0], p[1]); {
case 1: case 0:
return strategy.apply(q[1], p[0], p[1]); return strategy.apply(q[0], p[0], p[1]);
case 2: case 1:
return strategy.apply(p[0], q[0], q[1]); return strategy.apply(q[1], p[0], p[1]);
default: case 2:
return strategy.apply(p[1], q[0], q[1]); return strategy.apply(p[0], q[0], q[1]);
default:
return strategy.apply(p[1], q[0], q[1]);
}
} }
} }
}; };

View File

@ -13,11 +13,10 @@
#include <cstddef> #include <cstddef>
#include <boost/numeric/conversion/bounds.hpp>
#include <boost/geometry/core/access.hpp> #include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp> #include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_type.hpp> #include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/util/bounds.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -67,9 +66,9 @@ struct initialize
static inline void apply(Box& box, static inline void apply(Box& box,
coordinate_type min_value coordinate_type min_value
= boost::numeric::bounds<coordinate_type>::highest(), = util::bounds<coordinate_type>::highest(),
coordinate_type max_value coordinate_type max_value
= boost::numeric::bounds<coordinate_type>::lowest()) = util::bounds<coordinate_type>::lowest())
{ {
initialize_loop initialize_loop
< <

View File

@ -32,8 +32,8 @@
#include <boost/geometry/core/coordinate_system.hpp> #include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_type.hpp> #include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/util/is_inverse_spheroidal_coordinates.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp> #include <boost/geometry/views/detail/indexed_point_view.hpp>

View File

@ -20,7 +20,6 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP
#include <boost/numeric/conversion/cast.hpp>
#include <boost/range/size.hpp> #include <boost/range/size.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp> #include <boost/geometry/algorithms/detail/normalize.hpp>
@ -35,6 +34,7 @@
#include <boost/geometry/geometries/concepts/check.hpp> #include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/numeric_cast.hpp>
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
#include <boost/geometry/views/detail/closed_clockwise_view.hpp> #include <boost/geometry/views/detail/closed_clockwise_view.hpp>
@ -77,7 +77,7 @@ struct collected_vector_cartesian
bool normalize() bool normalize()
{ {
T magnitude = math::sqrt(boost::numeric_cast<T>(dx * dx + dy * dy)); T magnitude = math::sqrt(util::numeric_cast<T>(dx * dx + dy * dy));
// NOTE: shouldn't here math::equals() be called? // NOTE: shouldn't here math::equals() be called?
if (magnitude > 0) if (magnitude > 0)

View File

@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // 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 Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -20,7 +21,7 @@
#include <boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp> #include <boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp>
#include <boost/geometry/algorithms/dispatch/is_valid.hpp> #include <boost/geometry/algorithms/dispatch/is_valid.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -63,21 +64,21 @@ struct is_valid<MultiPoint, multi_point_tag, AllowEmptyMultiGeometries>
{ {
boost::ignore_unused(multipoint, visitor); boost::ignore_unused(multipoint, visitor);
if (BOOST_GEOMETRY_CONDITION( if BOOST_GEOMETRY_CONSTEXPR (! AllowEmptyMultiGeometries)
AllowEmptyMultiGeometries || !boost::empty(multipoint)))
{ {
// we allow empty multi-geometries, so an empty multipoint if (boost::empty(multipoint))
// is considered valid {
return ! detail::is_valid::has_invalid_coordinate // we do not allow an empty multipoint
< return visitor.template apply<failure_few_points>();
MultiPoint }
>::apply(multipoint, visitor);
}
else
{
// we do not allow an empty multipoint
return visitor.template apply<failure_few_points>();
} }
// if we allow empty multi-geometries, an empty multipoint
// is considered valid
return ! detail::is_valid::has_invalid_coordinate
<
MultiPoint
>::apply(multipoint, visitor);
} }
}; };

View File

@ -450,42 +450,44 @@ public:
{ {
return true; return true;
} }
else // else prevents unreachable code warning
// compute turns and check if all are acceptable
typedef debug_validity_phase<Polygon> debug_phase;
debug_phase::apply(3);
typedef has_valid_self_turns<Polygon, typename Strategy::cs_tag> has_valid_turns;
std::deque<typename has_valid_turns::turn_type> 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; // compute turns and check if all are acceptable
typedef debug_validity_phase<Polygon> debug_phase;
debug_phase::apply(3);
typedef has_valid_self_turns<Polygon, typename Strategy::cs_tag> has_valid_turns;
std::deque<typename has_valid_turns::turn_type> 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;
}
// 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;
}
// 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);
} }
// 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;
}
// 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);
} }
}; };

View File

@ -1,10 +1,10 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // 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. // This file was modified by Oracle on 2014-2020.
// Modifications copyright (c) 2014-2020 Oracle and/or its affiliates. // Modifications copyright (c) 2014-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License, // Use, modification and distribution is subject to the Boost Software License,
@ -29,7 +29,7 @@
#include <boost/geometry/core/closure.hpp> #include <boost/geometry/core/closure.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
@ -53,30 +53,32 @@ inline bool points_equal_or_close(Point1 const& point1,
return true; return true;
} }
if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled)) if BOOST_GEOMETRY_CONSTEXPR (! RobustPolicy::enabled)
{ {
return false; return false;
} }
else // else prevents unreachable code warning
{
// Try using specified robust policy
using robust_point_type = typename geometry::robust_point_type
<
Point1,
RobustPolicy
>::type;
// Try using specified robust policy robust_point_type point1_rob, point2_rob;
typedef typename geometry::robust_point_type geometry::recalculate(point1_rob, point1, robust_policy);
< geometry::recalculate(point2_rob, point2, robust_policy);
Point1,
RobustPolicy
>::type robust_point_type;
robust_point_type point1_rob, point2_rob; // Only if this is the case the same strategy can be used.
geometry::recalculate(point1_rob, point1, robust_policy); BOOST_STATIC_ASSERT((std::is_same
geometry::recalculate(point2_rob, point2, robust_policy); <
typename geometry::cs_tag<Point1>::type,
typename geometry::cs_tag<robust_point_type>::type
>::value));
// Only if this is the case the same strategy can be used. return detail::equals::equals_point_point(point1_rob, point2_rob, strategy);
BOOST_STATIC_ASSERT((std::is_same }
<
typename geometry::cs_tag<Point1>::type,
typename geometry::cs_tag<robust_point_type>::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 <typename Ring, typename Strategy> template <typename Ring, typename Strategy>
inline void fix_closure(Ring& ring, Strategy const& strategy) inline void fix_closure(Ring& ring, Strategy const& strategy)
{ {
if (BOOST_GEOMETRY_CONDITION(geometry::closure<Ring>::value == geometry::open)) if BOOST_GEOMETRY_CONSTEXPR (geometry::closure<Ring>::value == geometry::open)
{ {
if (! boost::empty(ring) if (! boost::empty(ring)
&& detail::equals::equals_point_point(range::front(ring), range::back(ring), strategy)) && detail::equals::equals_point_point(range::front(ring), range::back(ring), strategy))

View File

@ -1,6 +1,7 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2020 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2020 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2020-2023. // This file was modified by Oracle on 2020-2023.
// Modifications copyright (c) 2020-2023 Oracle and/or its affiliates. // Modifications copyright (c) 2020-2023 Oracle and/or its affiliates.
@ -24,7 +25,7 @@
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp> #include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
#include <boost/geometry/algorithms/detail/overlay/sort_by_side.hpp> #include <boost/geometry/algorithms/detail/overlay/sort_by_side.hpp>
#include <boost/geometry/algorithms/detail/signed_size_type.hpp> #include <boost/geometry/algorithms/detail/signed_size_type.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) \ #if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) \
|| defined(BOOST_GEOMETRY_OVERLAY_REPORT_WKT) \ || defined(BOOST_GEOMETRY_OVERLAY_REPORT_WKT) \
@ -199,13 +200,14 @@ public :
// Points to different target // Points to different target
return false; return false;
} }
if (first_run if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_buffer)
&& BOOST_GEOMETRY_CONDITION(OverlayType == overlay_buffer)
&& target.turn_index >= 0)
{ {
// Target already assigned, so there are more targets if (first_run && target.turn_index >= 0)
// or more ways to the same target {
return false; // Target already assigned, so there are more targets
// or more ways to the same target
return false;
}
} }
target = lti; target = lti;

View File

@ -27,11 +27,11 @@ struct cluster_info
std::set<signed_size_type> turn_indices; std::set<signed_size_type> turn_indices;
//! Number of open spaces (e.g. 2 for touch) //! Number of open spaces (e.g. 2 for touch)
std::size_t open_count; std::size_t open_count{0};
inline cluster_info() //! Number of spikes, where a segment goes to the cluster point
: open_count(0) //! and leaves immediately in the opposite direction.
{} std::size_t spike_count{0};
}; };

View File

@ -137,6 +137,13 @@ inline void discard_duplicate_start_turns(Turns& turns,
{ {
for (std::size_t const& i : it->second) 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], if (corresponding_turn(turn, turns[i],
geometry0, geometry1)) geometry0, geometry1))
{ {

View File

@ -41,6 +41,7 @@
#include <boost/geometry/algorithms/detail/overlay/less_by_segment_ratio.hpp> #include <boost/geometry/algorithms/detail/overlay/less_by_segment_ratio.hpp>
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp> #include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
#include <boost/geometry/policies/robustness/robust_type.hpp> #include <boost/geometry/policies/robustness/robust_type.hpp>
#include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/for_each_with_index.hpp> #include <boost/geometry/util/for_each_with_index.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH #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 <typename Operations, typename Turns> template <typename Operations, typename Turns>
inline void enrich_assign(Operations& operations, Turns& turns, inline void enrich_assign(Operations& operations, Turns& turns,
bool check_turns) bool check_consecutive_turns)
{ {
if (operations.empty()) for_each_with_index(operations, [&](std::size_t index, auto const& indexed)
{
return;
}
// Assign travel-to-vertex/ip index for each turning point.
// Iterator "next" is circular
geometry::ever_circling_range_iterator<Operations const> next(operations);
++next;
for (auto const& indexed : operations)
{ {
auto& turn = turns[indexed.turn_index]; auto& turn = turns[indexed.turn_index];
auto& op = turn.operations[indexed.operation_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)
{ {
// Normal behaviour: next points at next turn, increase next. std::size_t const result = index + 1;
// For dissolve this should not be done, turn_index is often return result >= operations.size() ? 0 : result;
// the same for two consecutive operations };
++next;
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)
{
// 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 // Cluster behaviour: next should point after cluster, unless
// their seg_ids are not the same // their seg_ids are not the same
// (For dissolve, this is still to be examined - TODO) // (For dissolve, this is still to be examined - TODO)
while (turn.is_clustered() while (turn.is_clustered()
&& indexed.turn_index != next->turn_index && turn.cluster_id == next_turn().cluster_id
&& turn.cluster_id == turns[next->turn_index].cluster_id && op.seg_id == next_operation().seg_id
&& op.seg_id == turns[next->turn_index].operations[next->operation_index].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 op.enriched.travels_to_ip_index
= static_cast<signed_size_type>(next->turn_index); = static_cast<signed_size_type>(operations[next_index].turn_index);
op.enriched.travels_to_vertex_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 if (op.seg_id.segment_index == next_op.seg_id.segment_index
&& op.fraction < next_op.fraction) && op.fraction < next_op.fraction)
{ {
// Next turn is located further on same segment // Next turn is located further on same segment: assign next_ip_index
// assign next_ip_index op.enriched.next_ip_index = static_cast<signed_size_type>(operations[next_index].turn_index);
// (this is one not circular therefore fraction is considered)
op.enriched.next_ip_index = static_cast<signed_size_type>(next->turn_index);
} }
});
if (! check_turns)
{
++next;
}
}
// DEBUG
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH #ifdef BOOST_GEOMETRY_DEBUG_ENRICH
for (auto const& indexed_op : operations) for (auto const& indexed_op : operations)
{ {
@ -190,8 +208,6 @@ inline void enrich_assign(Operations& operations, Turns& turns,
<< std::endl; << std::endl;
} }
#endif #endif
// END DEBUG
} }
template <typename Operations, typename Turns> template <typename Operations, typename Turns>
@ -383,6 +399,7 @@ inline void enrich_intersection_points(Turns& turns,
? detail::overlay::operation_intersection ? detail::overlay::operation_intersection
: detail::overlay::operation_union; : detail::overlay::operation_union;
constexpr bool is_dissolve = OverlayType == overlay_dissolve; constexpr bool is_dissolve = OverlayType == overlay_dissolve;
constexpr bool is_buffer = OverlayType == overlay_buffer;
using turn_type = typename boost::range_value<Turns>::type; using turn_type = typename boost::range_value<Turns>::type;
using indexed_turn_operation = detail::overlay::indexed_turn_operation using indexed_turn_operation = detail::overlay::indexed_turn_operation
@ -396,16 +413,36 @@ inline void enrich_intersection_points(Turns& turns,
std::vector<indexed_turn_operation> std::vector<indexed_turn_operation>
>; >;
// From here on, turn indexes are used (in clusters, next_index, etc) // Turns are often used by index (in clusters, next_index, etc)
// and turns may not be DELETED - they may only be flagged as discarded // and turns may therefore NOT be DELETED - they may only be flagged as discarded
discard_duplicate_start_turns(turns, geometry1, geometry2);
bool has_cc = false; bool has_cc = false;
bool const has_colocations bool has_colocations = false;
= detail::overlay::handle_colocations
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 Reverse1,
>(turns, clusters, robust_policy); 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 // Discard turns not part of target overlay
for (auto& turn : turns) for (auto& turn : turns)
@ -468,28 +505,12 @@ inline void enrich_intersection_points(Turns& turns,
pair.second, turns, pair.second, turns,
geometry1, geometry2, geometry1, geometry2,
robust_policy, strategy); 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) 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::cleanup_clusters(turns, clusters);
detail::overlay::colocate_clusters(clusters, turns);
} }
// After cleaning up clusters assign the next turns // After cleaning up clusters assign the next turns

View File

@ -1,7 +1,7 @@
// Boost.Geometry // Boost.Geometry
// Copyright (c) 2007-2023 Barend Gehrels, Amsterdam, the Netherlands. // 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. // This file was modified by Oracle on 2015-2022.
// Modifications copyright (c) 2015-2022 Oracle and/or its affiliates. // Modifications copyright (c) 2015-2022 Oracle and/or its affiliates.
@ -27,7 +27,7 @@
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp> #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp> #include <boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -286,7 +286,7 @@ struct turn_info_verification_functions
std::size_t index_p, std::size_t index_q, std::size_t index_p, std::size_t index_q,
TurnInfo& ti) TurnInfo& ti)
{ {
if (BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_side_verification)) if BOOST_GEOMETRY_CONSTEXPR (VerifyPolicy::use_side_verification)
{ {
set_both_verified<IndexP, IndexQ>(range_p, range_q, umbrella_strategy, set_both_verified<IndexP, IndexQ>(range_p, range_q, umbrella_strategy,
index_p, index_q, ti); index_p, index_q, ti);
@ -309,29 +309,29 @@ struct turn_info_verification_functions
UmbrellaStrategy const& umbrella_strategy, UmbrellaStrategy const& umbrella_strategy,
int index_p, int index_q) int index_p, int index_q)
{ {
if (side == 0 if BOOST_GEOMETRY_CONSTEXPR (VerifyPolicy::use_side_verification)
&& BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_side_verification))
{ {
if (index_p >= 1 && range_p.is_last_segment()) if (side == 0)
{ {
return 0; if (index_p >= 1 && range_p.is_last_segment())
} {
if (index_q >= 2 && range_q.is_last_segment()) return 0;
{ }
return 0; if (index_q >= 2 && range_q.is_last_segment())
} {
return 0;
}
auto const dm = get_distance_measure(range_p.at(index_p), auto const dm = get_distance_measure(range_p.at(index_p),
range_p.at(index_p + 1), range_p.at(index_p + 1),
range_q.at(index_q), range_q.at(index_q),
umbrella_strategy); umbrella_strategy);
static decltype(dm.measure) const zero = 0; static decltype(dm.measure) const zero = 0;
return dm.measure == zero ? 0 : dm.measure > zero ? 1 : -1; return dm.measure == zero ? 0 : dm.measure > zero ? 1 : -1;
} }
else
{
return side;
} }
return side;
} }
}; };
@ -354,45 +354,47 @@ struct touch_interior : public base_turn_handler
static bool handle_as_touch(IntersectionInfo const& info, static bool handle_as_touch(IntersectionInfo const& info,
UniqueSubRange const& non_touching_range) 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; 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)
//
// // 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"
// ^ Q(i) ^ P(i) // 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;
// \ / }
// \ /
// \ / 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;
} }
// Index: 0, P is the interior, Q is touching and vice versa // 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, UmbrellaStrategy const& umbrella_strategy,
TurnInfo& ti) TurnInfo& ti)
{ {
if (! BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_handle_imperfect_touch)) if BOOST_GEOMETRY_CONSTEXPR (! VerifyPolicy::use_handle_imperfect_touch)
{ {
return false; return false;
} }
else // else prevents unreachable code warning
// 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); // Q
auto const d2 = get_distance_measure(r2.at(1), r2.at(2), r1.at(0), umbrella_strategy); // ^
return d1.measure > 0 && d2.measure > 0; // ||
}; // ||
// |^----
// >----->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)
if (side_pk_q2 == -1 && has_distance(range_p, range_q)) auto has_distance = [&](auto const& r1, auto const& r2) -> bool
{ {
// Even though there is a touch, Q(j) is left of P1 auto const d1 = get_distance_measure(r1.at(0), r1.at(1), r2.at(1), umbrella_strategy);
// and P(i) is still left from Q2. auto const d2 = get_distance_measure(r2.at(1), r2.at(2), r1.at(0), umbrella_strategy);
// Q continues to the right. return d1.measure > 0 && d2.measure > 0;
// It can continue. };
ti.operations[0].operation = operation_blocked;
// Q turns right -> union (both independent), if (side_pk_q2 == -1 && has_distance(range_p, range_q))
// Q turns left -> intersection {
ti.operations[1].operation = operation_union; // Even though there is a touch, Q(j) is left of P1
ti.touch_only = true; // and P(i) is still left from Q2.
return true; // 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;
}
return false;
} }
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;
} }
template template
@ -915,39 +919,40 @@ struct start : public base_turn_handler
SideCalculator const& side, SideCalculator const& side,
UmbrellaStrategy const& ) UmbrellaStrategy const& )
{ {
if (! BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_start_turn)) if BOOST_GEOMETRY_CONSTEXPR (! VerifyPolicy::use_start_turn)
{ {
return false; 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);
if (dir_info.how_b == -1)
{ {
// p ---------------> // 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);
// | q q leaves BOOST_GEOMETRY_ASSERT(dir_info.how_a == -1 || dir_info.how_b == -1);
// v BOOST_GEOMETRY_ASSERT(dir_info.how_a == 0 || dir_info.how_b == 0);
//
int const side_qj_p1 = side.qj_wrt_p1(); if (dir_info.how_b == -1)
ui_else_iu(side_qj_p1 == -1, ti); {
} // p --------------->
else if (dir_info.how_a == -1) // |
{ // | q q leaves
// p leaves // v
int const side_pj_q1 = side.pj_wrt_q1(); //
ui_else_iu(side_pj_q1 == 1, ti);
}
// Copy intersection point int const side_qj_p1 = side.qj_wrt_p1();
assign_point_and_correct(ti, method_start, info, dir_info); ui_else_iu(side_qj_p1 == -1, ti);
return true; }
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;
}
} }
}; };
@ -973,7 +978,7 @@ struct equal_opposite : public base_turn_handler
IntersectionInfo const& intersection_info) IntersectionInfo const& intersection_info)
{ {
// For equal-opposite segments, normally don't do anything. // 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; tp.method = method_equal;
for (unsigned int i = 0; i < 2; i++) for (unsigned int i = 0; i < 2; i++)
@ -1010,24 +1015,26 @@ struct collinear : public base_turn_handler
UniqueSubRange2 const& range_q, UniqueSubRange2 const& range_q,
DirInfo const& dir_info) DirInfo const& dir_info)
{ {
if (! BOOST_GEOMETRY_CONDITION(VerifyPolicy::use_handle_as_equal)) if BOOST_GEOMETRY_CONSTEXPR (! VerifyPolicy::use_handle_as_equal)
{ {
return false; return false;
} }
else // else prevents unreachable code warning
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 int const arrival_p = dir_info.arrival[0];
return false; 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 auto const dm = arrival_p == 1
? fun::distance_measure(info.intersections[1], range_q.at(1)) ? fun::distance_measure(info.intersections[1], range_q.at(1))
: fun::distance_measure(info.intersections[1], range_p.at(1)); : fun::distance_measure(info.intersections[1], range_p.at(1));
decltype(dm) const zero = 0; decltype(dm) const zero = 0;
return math::equals(dm, zero); return math::equals(dm, zero);
}
} }
/* /*
@ -1191,7 +1198,7 @@ private :
// two operations blocked, so the whole point does not need // two operations blocked, so the whole point does not need
// to be generated. // to be generated.
// So return false to indicate nothing is to be done. // 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; tp.operations[Index].operation = operation_opposite;
blocked = operation_opposite; blocked = operation_opposite;
@ -1285,7 +1292,7 @@ public:
*out++ = tp; *out++ = tp;
} }
if (BOOST_GEOMETRY_CONDITION(AssignPolicy::include_opposite)) if BOOST_GEOMETRY_CONSTEXPR (AssignPolicy::include_opposite)
{ {
// Handle cases not yet handled above // Handle cases not yet handled above
if ((arrival_q == -1 && arrival_p == 0) if ((arrival_q == -1 && arrival_p == 0)

View File

@ -1,7 +1,7 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // 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. // This file was modified by Oracle on 2013-2020.
// Modifications copyright (c) 2013-2020 Oracle and/or its affiliates. // Modifications copyright (c) 2013-2020 Oracle and/or its affiliates.
@ -19,7 +19,7 @@
#include <boost/geometry/core/assert.hpp> #include <boost/geometry/core/assert.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp> #include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp> #include <boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp>
@ -216,15 +216,17 @@ struct get_turn_info_linear_areal
tp.operations[0].operation, tp.operations[0].operation,
tp.operations[1].operation); tp.operations[1].operation);
bool ignore_spike bool const ignore_spike = calculate_spike_operation(tp.operations[0].operation,
= calculate_spike_operation(tp.operations[0].operation, inters,
inters, umbrella_strategy);
umbrella_strategy);
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes)
|| ignore_spike {
|| ! append_opposite_spikes<append_touches>( // for 'i' or 'c' i??? *out++ = tp;
tp, inters, out) ) }
else if (ignore_spike
// for 'i' or 'c' i???
|| ! append_opposite_spikes<append_touches>(tp, inters, out))
{ {
*out++ = tp; *out++ = tp;
} }
@ -256,9 +258,12 @@ struct get_turn_info_linear_areal
transformer(tp); transformer(tp);
// conditionally handle spikes // conditionally handle spikes
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes)
|| ! append_collinear_spikes(tp, inters, {
method_touch, append_equal, out) ) *out++ = tp;
}
else if (! append_collinear_spikes(tp, inters, method_touch,
append_equal, out))
{ {
*out++ = tp; // no spikes *out++ = tp; // no spikes
} }
@ -319,9 +324,12 @@ struct get_turn_info_linear_areal
transformer(tp); transformer(tp);
// conditionally handle spikes // conditionally handle spikes
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes)
|| ! append_collinear_spikes(tp, inters, {
method_replace, version, out) ) *out++ = tp;
}
else if (! append_collinear_spikes(tp, inters, method_replace,
version, out))
{ {
// no spikes // no spikes
*out++ = tp; *out++ = tp;
@ -333,10 +341,9 @@ struct get_turn_info_linear_areal
turn_transformer_ec<false> transformer(method_touch_interior); turn_transformer_ec<false> transformer(method_touch_interior);
// conditionally handle spikes // conditionally handle spikes
if ( BOOST_GEOMETRY_CONDITION(handle_spikes) ) if BOOST_GEOMETRY_CONSTEXPR (handle_spikes)
{ {
append_opposite_spikes<append_collinear_opposite>( append_opposite_spikes<append_collinear_opposite>(tp, inters, out);
tp, inters, out);
} }
// TODO: ignore for spikes? // TODO: ignore for spikes?
@ -357,7 +364,7 @@ struct get_turn_info_linear_areal
case '0' : case '0' :
{ {
// degenerate points // degenerate points
if ( BOOST_GEOMETRY_CONDITION(AssignPolicy::include_degenerate) ) if BOOST_GEOMETRY_CONSTEXPR (AssignPolicy::include_degenerate)
{ {
only_convert::apply(tp, inters.i_info()); only_convert::apply(tp, inters.i_info());
@ -542,26 +549,30 @@ struct get_turn_info_linear_areal
return false; return false;
} }
else*/ else*/
if ( is_p_spike ) if (is_p_spike)
{ {
if ( BOOST_GEOMETRY_CONDITION(is_version_touches) bool output_spike = false;
|| inters.d_info().arrival[0] == 1 ) 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.operations[0].is_collinear = true; tp.method = method_touch;
//tp.operations[1].is_collinear = false;
tp.method = method_touch;
}
else
{
tp.operations[0].is_collinear = true;
//tp.operations[1].is_collinear = false;
BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1); output_spike = true;
base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 1); }
} 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[0].operation = operation_blocked;
tp.operations[1].operation = operation_continue; // boundary tp.operations[1].operation = operation_continue; // boundary
*out++ = tp; *out++ = tp;
@ -636,9 +647,12 @@ struct get_turn_info_linear_areal
operation_type & op1 = turn.operations[1].operation; operation_type & op1 = turn.operations[1].operation;
// NOTE: probably only if methods are WRT IPs, not segments! // NOTE: probably only if methods are WRT IPs, not segments!
if ( BOOST_GEOMETRY_CONDITION(IsFront) if BOOST_GEOMETRY_CONSTEXPR (IsFront)
|| op0 == operation_intersection || op0 == operation_union {
|| op1 == operation_intersection || op1 == operation_union ) turn.method = m_method;
}
else if (op0 == operation_intersection || op0 == operation_union
|| op1 == operation_intersection || op1 == operation_union)
{ {
turn.method = m_method; turn.method = m_method;
} }
@ -724,145 +738,151 @@ struct get_turn_info_linear_areal
// IP on the first point of Linear Geometry // IP on the first point of Linear Geometry
bool was_first_point_handled = false; bool was_first_point_handled = false;
if ( BOOST_GEOMETRY_CONDITION(EnableFirst) if BOOST_GEOMETRY_CONSTEXPR (EnableFirst)
&& range_p.is_first_segment() && ip0.is_pi && !ip0.is_qi ) // !q0i prevents duplication
{ {
TurnInfo tp = tp_model; if (range_p.is_first_segment() && ip0.is_pi && ! ip0.is_qi ) // !q0i prevents duplication
tp.operations[0].position = position_front;
tp.operations[1].position = position_middle;
if ( opposite ) // opposite -> collinear
{ {
tp.operations[0].operation = operation_continue; TurnInfo tp = tp_model;
tp.operations[1].operation = operation_union; tp.operations[0].position = position_front;
tp.method = ip0.is_qj ? method_touch : method_touch_interior; tp.operations[1].position = position_middle;
}
else
{
auto const sides = strategy.side();
// pi is the intersection point at qj or in the middle of q1 if ( opposite ) // opposite -> collinear
// 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; tp.operations[0].operation = operation_continue;
side_pj_y = sides.apply(range_q.at(1), range_q.at(2), range_p.at(1)); // pj wrt q2 tp.operations[1].operation = operation_union;
side_pj_x = sides.apply(range_q.at(0), range_q.at(1), range_p.at(1)); // pj wrt q1 tp.method = ip0.is_qj ? method_touch : method_touch_interior;
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 else
{ {
replaced_method = method_touch_interior; auto const sides = strategy.side();
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 // pi is the intersection point at qj or in the middle of q1
side_qz_x = 0; // qj wrt 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<operation_type, operation_type> 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;
turn_transformer_ec<true> transformer(replaced_method);
transformer(tp);
} }
std::pair<operation_type, operation_type> operations // equals<> or collinear<> will assign the second point,
= get_info_e::operations_of_equal(side_pj_y, side_pj_x, side_qz_x); // we'd like to assign the first one
base_turn_handler::assign_point(tp, tp.method, inters.i_info(), 0);
tp.operations[0].operation = operations.first; // NOTE: is_collinear is not set for the first endpoint of L
tp.operations[1].operation = operations.second; // for which there is no preceding segment
// here is_p_first_ip == true
tp.operations[0].is_collinear = false;
turn_transformer_ec<true> transformer(replaced_method); *out++ = tp;
transformer(tp);
was_first_point_handled = true;
} }
// 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;
*out++ = tp;
was_first_point_handled = true;
} }
// ANALYSE AND ASSIGN LAST // ANALYSE AND ASSIGN LAST
// IP on the last point of Linear Geometry // IP on the last point of Linear Geometry
if ( BOOST_GEOMETRY_CONDITION(EnableLast) if BOOST_GEOMETRY_CONSTEXPR (EnableLast)
&& range_p.is_last_segment()
&& ( ip_count > 1 ? (ip1.is_pj && !ip1.is_qi) : (ip0.is_pj && !ip0.is_qi) ) ) // prevents duplication
{ {
TurnInfo tp = tp_model; if (range_p.is_last_segment()
&& (ip_count > 1
if ( inters.i_info().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 ); TurnInfo tp = tp_model;
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 if ( inters.i_info().count > 1 )
// 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 //BOOST_GEOMETRY_ASSERT( result.template get<1>().dir_a == 0 && result.template get<1>().dir_b == 0 );
side_pi_x = sides.apply(range_q.at(0), range_q.at(1), range_p.at(0)); // pi wrt q1 tp.operations[0].is_collinear = true;
side_qz_x = sides.apply(range_q.at(0), range_q.at(1), range_q.at(2)); // qk wrt q1 tp.operations[1].operation = opposite ? operation_continue : operation_union;
} }
// 2. ip0 or pj in the middle of q1 else //if ( result.template get<0>().count == 1 )
else
{ {
side_pi_y = sides.apply(range_q.at(0), range_q.at(1), range_p.at(0)); // pi wrt q1 auto const sides = strategy.side();
side_pi_x = side_pi_y; // pi wrt q1
side_qz_x = 0; // qj wrt q1 // 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<operation_type, operation_type> 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;
turn_transformer_ec<false> transformer(method_none);
transformer(tp);
tp.operations[0].is_collinear = tp.both(operation_continue);
} }
std::pair<operation_type, operation_type> operations tp.method = ( ip_count > 1 ? ip1.is_qj : ip0.is_qj ) ? method_touch : method_touch_interior;
= get_info_e::operations_of_equal(side_pi_y, side_pi_x, side_qz_x); tp.operations[0].operation = operation_blocked;
tp.operations[0].position = position_back;
tp.operations[1].position = position_middle;
tp.operations[0].operation = operations.first; // equals<> or collinear<> will assign the second point,
tp.operations[1].operation = operations.second; // 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);
turn_transformer_ec<false> transformer(method_none); *out++ = tp;
transformer(tp);
tp.operations[0].is_collinear = tp.both(operation_continue); // don't ignore the first IP if the segment is opposite
return !( opposite && ip_count > 1 ) || was_first_point_handled;
} }
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);
*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 anything for now // don't ignore anything for now

View File

@ -1,11 +1,10 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // 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. // This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates. // Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License, // Use, modification and distribution is subject to the Boost Software License,
@ -22,7 +21,7 @@
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp> #include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp> #include <boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
namespace boost { namespace geometry { namespace boost { namespace geometry {
@ -264,8 +263,11 @@ struct get_turn_info_linear_linear
tp.operations[0].operation, tp.operations[0].operation,
tp.operations[1].operation); tp.operations[1].operation);
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes)
|| ! append_opposite_spikes<append_touches>(tp, inters, out) ) {
*out++ = tp;
}
else if (! append_opposite_spikes<append_touches>(tp, inters, out))
{ {
*out++ = tp; *out++ = tp;
} }
@ -307,10 +309,12 @@ struct get_turn_info_linear_linear
transformer(tp); transformer(tp);
// conditionally handle spikes // conditionally handle spikes
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes)
|| ! append_collinear_spikes(tp, inters, {
method_touch, spike_op, *out++ = tp;
out) ) }
else if (! append_collinear_spikes(tp, inters, method_touch,
spike_op, out))
{ {
*out++ = tp; // no spikes *out++ = tp; // no spikes
} }
@ -381,10 +385,12 @@ struct get_turn_info_linear_linear
transformer(tp); transformer(tp);
// conditionally handle spikes // conditionally handle spikes
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes) if BOOST_GEOMETRY_CONSTEXPR (! handle_spikes)
|| ! append_collinear_spikes(tp, inters, {
method_replace, spike_op, *out++ = tp;
out) ) }
else if (! append_collinear_spikes(tp, inters, method_replace,
spike_op, out))
{ {
// no spikes // no spikes
*out++ = tp; *out++ = tp;
@ -396,7 +402,7 @@ struct get_turn_info_linear_linear
turn_transformer_ec transformer(method_touch_interior); turn_transformer_ec transformer(method_touch_interior);
// conditionally handle spikes // conditionally handle spikes
if ( BOOST_GEOMETRY_CONDITION(handle_spikes) ) if BOOST_GEOMETRY_CONSTEXPR (handle_spikes)
{ {
append_opposite_spikes<append_collinear_opposite>(tp, inters, out); append_opposite_spikes<append_collinear_opposite>(tp, inters, out);
} }
@ -419,7 +425,7 @@ struct get_turn_info_linear_linear
case '0' : case '0' :
{ {
// degenerate points // degenerate points
if ( BOOST_GEOMETRY_CONDITION(AssignPolicy::include_degenerate) ) if BOOST_GEOMETRY_CONSTEXPR (AssignPolicy::include_degenerate)
{ {
only_convert::apply(tp, inters.i_info()); only_convert::apply(tp, inters.i_info());
@ -553,65 +559,75 @@ struct get_turn_info_linear_linear
bool res = false; bool res = false;
if ( is_p_spike if (is_p_spike)
&& ( BOOST_GEOMETRY_CONDITION(is_version_touches)
|| inters.d_info().arrival[0] == 1 ) )
{ {
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[0].is_collinear = true;
tp.operations[1].is_collinear = false; tp.operations[1].is_collinear = false;
tp.method = method_touch; 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[0].is_collinear = true;
tp.operations[1].is_collinear = false; tp.operations[1].is_collinear = false;
BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1); BOOST_GEOMETRY_ASSERT(inters.i_info().count > 1);
base_turn_handler::assign_point(tp, method_touch_interior, base_turn_handler::assign_point(tp, method_touch_interior,
inters.i_info(), 1); inters.i_info(), 1);
output_spike = true;
} }
tp.operations[0].operation = operation_blocked; if (output_spike)
tp.operations[1].operation = operation_intersection; {
*out++ = tp; tp.operations[0].operation = operation_blocked;
tp.operations[0].operation = operation_intersection; tp.operations[1].operation = operation_intersection;
//tp.operations[1].operation = operation_intersection; *out++ = tp;
*out++ = tp; tp.operations[0].operation = operation_intersection;
//tp.operations[1].operation = operation_intersection;
*out++ = tp;
res = true; res = true;
}
} }
if ( is_q_spike if (is_q_spike)
&& ( BOOST_GEOMETRY_CONDITION(is_version_touches)
|| inters.d_info().arrival[1] == 1 ) )
{ {
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[0].is_collinear = false;
tp.operations[1].is_collinear = true; tp.operations[1].is_collinear = true;
tp.method = method_touch; 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[0].is_collinear = false;
tp.operations[1].is_collinear = true; tp.operations[1].is_collinear = true;
BOOST_GEOMETRY_ASSERT(inters.i_info().count > 0); BOOST_GEOMETRY_ASSERT(inters.i_info().count > 0);
base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 0); base_turn_handler::assign_point(tp, method_touch_interior, inters.i_info(), 0);
output_spike = true;
} }
tp.operations[0].operation = operation_intersection; if (output_spike)
tp.operations[1].operation = operation_blocked; {
*out++ = tp; tp.operations[0].operation = operation_intersection;
//tp.operations[0].operation = operation_intersection; tp.operations[1].operation = operation_blocked;
tp.operations[1].operation = operation_intersection; *out++ = tp;
*out++ = tp; //tp.operations[0].operation = operation_intersection;
tp.operations[1].operation = operation_intersection;
*out++ = tp;
res = true; res = true;
}
} }
return res; return res;

View File

@ -1,11 +1,10 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands. // 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. // This file was modified by Oracle on 2017-2020.
// Modifications copyright (c) 2017-2020 Oracle and/or its affiliates. // Modifications copyright (c) 2017-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License, // Use, modification and distribution is subject to the Boost Software License,
@ -37,7 +36,7 @@
#include <boost/geometry/algorithms/detail/overlay/sort_by_side.hpp> #include <boost/geometry/algorithms/detail/overlay/sort_by_side.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp> #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp> #include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#if defined(BOOST_GEOMETRY_DEBUG_HANDLE_COLOCATIONS) #if defined(BOOST_GEOMETRY_DEBUG_HANDLE_COLOCATIONS)
# include <iostream> # include <iostream>
@ -97,7 +96,6 @@ inline void cleanup_clusters(Turns& turns, Clusters& clusters)
} }
remove_clusters(turns, clusters); remove_clusters(turns, clusters);
colocate_clusters(clusters, turns);
} }
template <typename Turn, typename IndexSet> template <typename Turn, typename IndexSet>
@ -339,7 +337,7 @@ inline bool handle_colocations(Turns& turns, Clusters& clusters,
// on turns which are discarded afterwards // on turns which are discarded afterwards
set_colocation<OverlayType>(turns, clusters); set_colocation<OverlayType>(turns, clusters);
if (BOOST_GEOMETRY_CONDITION(target_operation == operation_intersection)) if BOOST_GEOMETRY_CONSTEXPR (target_operation == operation_intersection)
{ {
discard_interior_exterior_turns discard_interior_exterior_turns
< <
@ -427,12 +425,12 @@ template
typename Clusters, typename Clusters,
typename Geometry1, typename Geometry1,
typename Geometry2, typename Geometry2,
typename SideStrategy typename Strategy
> >
inline void gather_cluster_properties(Clusters& clusters, Turns& turns, inline void gather_cluster_properties(Clusters& clusters, Turns& turns,
operation_type for_operation, operation_type for_operation,
Geometry1 const& geometry1, Geometry2 const& geometry2, Geometry1 const& geometry1, Geometry2 const& geometry2,
SideStrategy const& strategy) Strategy const& strategy)
{ {
typedef typename boost::range_value<Turns>::type turn_type; typedef typename boost::range_value<Turns>::type turn_type;
typedef typename turn_type::point_type point_type; typedef typename turn_type::point_type point_type;
@ -442,7 +440,7 @@ inline void gather_cluster_properties(Clusters& clusters, Turns& turns,
// right side // right side
typedef sort_by_side::side_sorter typedef sort_by_side::side_sorter
< <
Reverse1, Reverse2, OverlayType, point_type, SideStrategy, std::less<int> Reverse1, Reverse2, OverlayType, point_type, Strategy, std::less<int>
> sbs_type; > sbs_type;
for (auto& pair : clusters) 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); 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; bool const set_startable = OverlayType != overlay_dissolve;
// Unset the startable flag for all 'closed' zones. This does not // 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]; turn_operation_type& op = turn.operations[ranked.operation_index];
if (set_startable if (set_startable
&& for_operation == operation_union && cinfo.open_count == 0) && for_operation == operation_union
&& cinfo.open_count == 0)
{ {
op.enriched.startable = false; op.enriched.startable = false;
} }
@ -495,11 +509,13 @@ inline void gather_cluster_properties(Clusters& clusters, Turns& turns,
continue; continue;
} }
if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_difference) if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_difference)
&& is_self_turn<OverlayType>(turn))
{ {
// TODO: investigate if (is_self_turn<OverlayType>(turn))
continue; {
// TODO: investigate
continue;
}
} }
if ((for_operation == operation_union if ((for_operation == operation_union

View File

@ -36,7 +36,7 @@
#include <boost/geometry/policies/compare.hpp> #include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -261,13 +261,15 @@ struct multipoint_multipoint_point
{ {
typedef geometry::less<void, -1, Strategy> less_type; typedef geometry::less<void, -1, Strategy> less_type;
if (BOOST_GEOMETRY_CONDITION(OverlayType != overlay_difference) if BOOST_GEOMETRY_CONSTEXPR (OverlayType != overlay_difference)
&& boost::size(multipoint1) > boost::size(multipoint2))
{ {
return multipoint_multipoint_point if (boost::size(multipoint1) > boost::size(multipoint2))
< {
MultiPoint2, MultiPoint1, PointOut, OverlayType return multipoint_multipoint_point
>::apply(multipoint2, multipoint1, robust_policy, oit, strategy); <
MultiPoint2, MultiPoint1, PointOut, OverlayType
>::apply(multipoint2, multipoint1, robust_policy, oit, strategy);
}
} }
typedef typename boost::range_value<MultiPoint2>::type point2_type; typedef typename boost::range_value<MultiPoint2>::type point2_type;

View File

@ -1,7 +1,7 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands. // 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. // This file was modified by Oracle on 2017-2023.
// Modifications copyright (c) 2017-2023 Oracle and/or its affiliates. // Modifications copyright (c) 2017-2023 Oracle and/or its affiliates.
@ -27,7 +27,7 @@
#include <boost/geometry/algorithms/detail/direction_code.hpp> #include <boost/geometry/algorithms/detail/direction_code.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp> #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp> #include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/util/select_most_precise.hpp> #include <boost/geometry/util/select_most_precise.hpp>
@ -39,35 +39,22 @@ namespace boost { namespace geometry
namespace detail { namespace overlay { namespace sort_by_side 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 }; 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 // Point-wrapper, adding some properties
template <typename Point> template <typename Point>
struct ranked_point 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, ranked_point(Point const& p, signed_size_type ti, int oi,
direction_type d, operation_type op, segment_identifier const& si) direction_type d, operation_type op, segment_identifier const& si)
: point(p) : point(p)
, rank(0)
, zone(-1)
, turn_index(ti) , turn_index(ti)
, operation_index(oi) , operation_index(oi)
, direction(d) , direction(d)
, count_left(0)
, count_right(0)
, operation(op) , operation(op)
, seg_id(si) , seg_id(si)
{} {}
@ -75,14 +62,19 @@ struct ranked_point
using point_type = Point; using point_type = Point;
Point point; Point point;
rank_type rank; rank_type rank{0};
signed_size_type zone; // index of closed zone, in uu turn there would be 2 zones signed_size_type zone{-1}; // index of closed zone, in uu turn there would be 2 zones
signed_size_type turn_index; signed_size_type turn_index{-1};
int operation_index; // 0,1 int operation_index{-1}; // 0,1
direction_type direction; direction_type direction{dir_unknown};
std::size_t count_left;
std::size_t count_right; // The number of polygons on the left side
operation_type operation; 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; segment_identifier seg_id;
}; };
@ -91,10 +83,8 @@ struct less_by_turn_index
template <typename T> template <typename T>
inline bool operator()(T const& first, T const& second) const inline bool operator()(T const& first, T const& second) const
{ {
return first.turn_index == second.turn_index return std::tie(first.turn_index, first.index)
? first.index < second.index < std::tie(second.turn_index, second.index);
: first.turn_index < second.turn_index
;
} }
}; };
@ -103,20 +93,13 @@ struct less_by_index
template <typename T> template <typename T>
inline bool operator()(T const& first, T const& second) const inline bool operator()(T const& first, T const& second) const
{ {
// Length might be considered too // First order by direction (from/to)
// First order by from/to
if (first.direction != second.direction)
{
return first.direction < second.direction;
}
// Then by turn index // 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 // This can also be the same (for example in buffer), but seg_id is
// never the same // 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 <typename PointOrigin, typename PointTurn, typename SideStrategy, typename LessOnSame, typename Compare> template <typename PointOrigin, typename PointTurn, typename Strategy, typename LessOnSame, typename Compare>
struct less_by_side 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_origin(p1)
, m_turn_point(p2) , m_turn_point(p2)
, m_strategy(strategy) , m_strategy(strategy)
@ -141,13 +124,14 @@ struct less_by_side
template <typename T> template <typename T>
inline bool operator()(T const& first, T const& second) const 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; LessOnSame on_same;
Compare compare; Compare compare;
int const side_first = m_strategy.apply(m_origin, m_turn_point, first.point); auto const side_strategy = m_strategy.side();
int const side_second = m_strategy.apply(m_origin, m_turn_point, second.point); 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) 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) // They are both left, both right, and/or both collinear (with each other and/or with p1,p2)
// Check mutual side // 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) if (side_second_wrt_first == 0)
{ {
return on_same(first, second); 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) if (side_second_wrt_first != -side_first_wrt_second)
{ {
// (FP) accuracy error in side calculation, the sides are not opposite. // (FP) accuracy error in side calculation, the sides are not opposite.
@ -213,22 +197,28 @@ struct less_by_side
private : private :
PointOrigin const& m_origin; PointOrigin const& m_origin;
PointTurn const& m_turn_point; 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) // 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 template
< <
bool Reverse1, bool Reverse1,
bool Reverse2, bool Reverse2,
overlay_type OverlayType, overlay_type OverlayType,
typename Point, typename Point,
typename SideStrategy, typename Strategy,
typename Compare typename Compare
> >
struct side_sorter struct side_sorter
{ {
typedef ranked_point<Point> rp; using rp = ranked_point<Point>;
private : private :
struct include_union struct include_union
@ -254,7 +244,7 @@ private :
}; };
public : public :
side_sorter(SideStrategy const& strategy) side_sorter(Strategy const& strategy)
: m_origin_count(0) : m_origin_count(0)
, m_origin_segment_distance(0) , m_origin_segment_distance(0)
, m_strategy(strategy) , m_strategy(strategy)
@ -289,6 +279,17 @@ public :
Point const& point_from, Point const& point_to, Point const& point_from, Point const& point_to,
Operation const& op, bool is_origin) 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_from(turn_index, op_index, point_from, op, is_origin);
add_segment_to(turn_index, op_index, point_to, op); add_segment_to(turn_index, op_index, point_to, op);
} }
@ -356,7 +357,7 @@ public :
Geometry2 const& geometry2, Geometry2 const& geometry2,
bool is_departure) 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) if (is_departure)
{ {
@ -392,8 +393,8 @@ public :
// to give colinear points // to give colinear points
// Sort by side and assign rank // Sort by side and assign rank
less_by_side<Point, PointTurn, SideStrategy, less_by_index, Compare> less_unique(m_origin, turn_point, m_strategy); less_by_side<Point, PointTurn, Strategy, less_by_index, Compare> less_unique(m_origin, turn_point, m_strategy);
less_by_side<Point, PointTurn, SideStrategy, less_false, Compare> less_non_unique(m_origin, turn_point, m_strategy); less_by_side<Point, PointTurn, Strategy, less_false, Compare> less_non_unique(m_origin, turn_point, m_strategy);
std::sort(m_ranked_points.begin(), m_ranked_points.end(), less_unique); std::sort(m_ranked_points.begin(), m_ranked_points.end(), less_unique);
@ -458,7 +459,7 @@ public :
void find_open() void find_open()
{ {
if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_buffer)) if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_buffer)
{ {
find_open_by_piece_index(); find_open_by_piece_index();
} }
@ -512,12 +513,14 @@ public :
//private : //private :
typedef std::vector<rp> container_type; using container_type = std::vector<rp>;
container_type m_ranked_points; container_type m_ranked_points;
Point m_origin; Point m_origin;
std::size_t m_origin_count; std::size_t m_origin_count;
signed_size_type m_origin_segment_distance; signed_size_type m_origin_segment_distance;
SideStrategy m_strategy;
// Umbrella strategy containing side strategy
Strategy m_strategy;
private : private :
@ -724,13 +727,13 @@ struct side_compare {};
template <> template <>
struct side_compare<operation_union> struct side_compare<operation_union>
{ {
typedef std::greater<int> type; using type = std::greater<int>;
}; };
template <> template <>
struct side_compare<operation_intersection> struct side_compare<operation_intersection>
{ {
typedef std::less<int> type; using type = std::less<int>;
}; };

View File

@ -1,10 +1,10 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // 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. // This file was modified by Oracle on 2017-2020.
// Modifications copyright (c) 2017-2020 Oracle and/or its affiliates. // Modifications copyright (c) 2017-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License, // Use, modification and distribution is subject to the Boost Software License,
@ -27,7 +27,7 @@
#include <boost/geometry/algorithms/detail/overlay/sort_by_side.hpp> #include <boost/geometry/algorithms/detail/overlay/sort_by_side.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp> #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/core/assert.hpp> #include <boost/geometry/core/assert.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) \ #if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) \
|| defined(BOOST_GEOMETRY_OVERLAY_REPORT_WKT) \ || defined(BOOST_GEOMETRY_OVERLAY_REPORT_WKT) \
@ -84,7 +84,7 @@ template
typename Turns, typename Turns,
typename Clusters, typename Clusters,
typename RobustPolicy, typename RobustPolicy,
typename SideStrategy, typename Strategy,
typename Visitor typename Visitor
> >
struct traversal struct traversal
@ -101,13 +101,13 @@ private :
typedef sort_by_side::side_sorter typedef sort_by_side::side_sorter
< <
Reverse1, Reverse2, OverlayType, Reverse1, Reverse2, OverlayType,
point_type, SideStrategy, side_compare_type point_type, Strategy, side_compare_type
> sbs_type; > sbs_type;
public : public :
inline traversal(Geometry1 const& geometry1, Geometry2 const& geometry2, inline traversal(Geometry1 const& geometry1, Geometry2 const& geometry2,
Turns& turns, Clusters const& clusters, Turns& turns, Clusters const& clusters,
RobustPolicy const& robust_policy, SideStrategy const& strategy, RobustPolicy const& robust_policy, Strategy const& strategy,
Visitor& visitor) Visitor& visitor)
: m_geometry1(geometry1) : m_geometry1(geometry1)
, m_geometry2(geometry2) , m_geometry2(geometry2)
@ -233,23 +233,25 @@ public :
{ {
// For uu/ii, only switch sources if indicated // 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). // Buffer does not use source_index (always 0).
return select_source_generic<&segment_identifier::multi_index>( return select_source_generic<&segment_identifier::multi_index>(
turn, candidate_seg_id, previous_seg_id); turn, candidate_seg_id, previous_seg_id);
} }
else // else prevents unreachable code warning
if (is_self_turn<OverlayType>(turn))
{ {
// Also, if it is a self-turn, stay on same ring (multi/ring) if (is_self_turn<OverlayType>(turn))
return select_source_generic<&segment_identifier::multi_index>( {
// 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); 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 inline bool traverse_possible(signed_size_type turn_index) const
@ -342,25 +344,27 @@ public :
return true; return true;
} }
if (BOOST_GEOMETRY_CONDITION(OverlayType == overlay_buffer) if BOOST_GEOMETRY_CONSTEXPR (OverlayType == overlay_buffer)
&& possible[0] && possible[1])
{ {
// Buffers sometimes have multiple overlapping pieces, where remaining if (possible[0] && possible[1])
// distance could lead to the wrong choice. Take the matching operation.
bool is_target[2] = {0};
for (int i = 0; i < 2; i++)
{ {
turn_operation_type const& next_op = m_turns[next[i]].operations[i]; // Buffers sometimes have multiple overlapping pieces, where remaining
is_target[i] = next_op.operation == target_operation; // distance could lead to the wrong choice. Take the matching operation.
}
if (is_target[0] != is_target[1]) bool is_target[2] = {0};
{ for (int i = 0; i < 2; i++)
// Take the matching operation {
selected_op_index = is_target[0] ? 0 : 1; turn_operation_type const& next_op = m_turns[next[i]].operations[i];
debug_traverse(turn, turn.operations[selected_op_index], "Candidate cc target"); is_target[i] = next_op.operation == target_operation;
return true; }
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, result = select_cc_operation(turn, start_turn_index,
selected_op_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, result = select_preferred_operation(turn, turn_index,
start_turn_index, selected_op_index); start_turn_index, selected_op_index);
@ -559,16 +563,18 @@ public :
return true; 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, inline int priority_of_turn_in_cluster_union(sort_by_side::rank_type selected_rank,
typename sbs_type::rp const& ranked_point, typename sbs_type::rp const& ranked_point,
std::set<signed_size_type> const& cluster_indices, cluster_info const& cinfo,
signed_size_type start_turn_index, int start_op_index) const 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 if (ranked_point.rank != selected_rank
|| ranked_point.direction != sort_by_side::dir_to) || ranked_point.direction != sort_by_side::dir_to)
{ {
@ -584,24 +590,30 @@ public :
return 0; return 0;
} }
if (BOOST_GEOMETRY_CONDITION(OverlayType != overlay_dissolve) if BOOST_GEOMETRY_CONSTEXPR (OverlayType != overlay_dissolve)
&& (op.enriched.count_left != 0 || op.enriched.count_right == 0))
{ {
// Check counts: in some cases interior rings might be generated with if (op.enriched.count_left != 0 || op.enriched.count_right == 0)
// polygons on both sides. For dissolve it can be anything. {
return 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 = ranked_point.turn_index == start_turn_index;
bool const to_start_index = ranked_point.operation_index == start_op_index; bool const to_start_index = ranked_point.operation_index == start_op_index;
bool const next_in_same_cluster 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 // Return the priority as described above
: to_start ? 3 return to_start && to_start_index ? 5
: next_in_same_cluster ? 1 : to_start ? 4
: 2 : next_in_same_cluster ? 2
: 3
; ;
} }
@ -647,7 +659,7 @@ public :
} }
inline bool select_from_cluster_union(signed_size_type& turn_index, inline bool select_from_cluster_union(signed_size_type& turn_index,
std::set<signed_size_type> const& cluster_indices, cluster_info const& cinfo,
int& op_index, sbs_type const& sbs, int& op_index, sbs_type const& sbs,
signed_size_type start_turn_index, int start_op_index) const signed_size_type start_turn_index, int start_op_index) const
{ {
@ -656,7 +668,7 @@ public :
int current_priority = 0; int current_priority = 0;
for (std::size_t i = 1; i < sbs.m_ranked_points.size(); i++) 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) if (ranked_point.rank > selected_rank)
{ {
@ -664,7 +676,7 @@ public :
} }
int const priority = priority_of_turn_in_cluster_union(selected_rank, 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) if (priority > current_priority)
{ {
@ -791,6 +803,27 @@ public :
return false; 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<OverlayType, Turns, sbs_type> exits(m_turns, cinfo.turn_indices, sbs); cluster_exits<OverlayType, Turns, sbs_type> exits(m_turns, cinfo.turn_indices, sbs);
if (exits.apply(turn_index, op_index)) if (exits.apply(turn_index, op_index))
@ -800,9 +833,9 @@ public :
bool result = false; 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, op_index, sbs,
start_turn_index, start_op_index); start_turn_index, start_op_index);
if (! result) if (! result)
@ -852,56 +885,58 @@ public :
turn_operation_type const& start_op, turn_operation_type const& start_op,
int start_op_index) const int start_op_index) const
{ {
if (BOOST_GEOMETRY_CONDITION(OverlayType != overlay_buffer if BOOST_GEOMETRY_CONSTEXPR (OverlayType != overlay_buffer
&& OverlayType != overlay_dissolve)) && OverlayType != overlay_dissolve)
{ {
return; return;
} }
else // else prevents unreachable code warning
{
const bool allow_uu = OverlayType != overlay_buffer;
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
// It travels to itself, can happen. If this is a buffer, it can turn_operation_type const& other_op
// sometimes travel to itself in the following configuration: = start_turn.operations[1 - start_op_index];
//
// +---->--+
// | |
// | +---*----+ *: 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 bool const correct
= start_turn.operations[1 - start_op_index]; = (allow_uu || ! start_turn.both(operation_union))
&& start_op.seg_id.source_index == other_op.seg_id.source_index
bool const correct && start_op.seg_id.multi_index == other_op.seg_id.multi_index
= (allow_uu || ! start_turn.both(operation_union)) && start_op.seg_id.ring_index == other_op.seg_id.ring_index
&& start_op.seg_id.source_index == other_op.seg_id.source_index && start_op.seg_id.segment_index == to_vertex_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) #if defined(BOOST_GEOMETRY_DEBUG_TRAVERSE)
std::cout << " WARNING: self-buffer " std::cout << " WARNING: self-buffer "
<< " correct=" << correct << " correct=" << correct
<< " turn=" << operation_char(start_turn.operations[0].operation) << " turn=" << operation_char(start_turn.operations[0].operation)
<< operation_char(start_turn.operations[1].operation) << operation_char(start_turn.operations[1].operation)
<< " start=" << start_op.seg_id.segment_index << " start=" << start_op.seg_id.segment_index
<< " from=" << to_vertex_index << " from=" << to_vertex_index
<< " to=" << other_op.enriched.travels_to_vertex_index << " to=" << other_op.enriched.travels_to_vertex_index
<< std::endl; << std::endl;
#endif #endif
if (correct) if (correct)
{ {
to_vertex_index = other_op.enriched.travels_to_vertex_index; to_vertex_index = other_op.enriched.travels_to_vertex_index;
}
} }
} }
@ -960,7 +995,7 @@ public :
= has_points = has_points
&& current_turn.is_clustered() && current_turn.is_clustered()
&& m_turns[start_turn_index].cluster_id == current_turn.cluster_id; && 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 // Intersection or difference
@ -1037,7 +1072,7 @@ private :
Turns& m_turns; Turns& m_turns;
Clusters const& m_clusters; Clusters const& m_clusters;
RobustPolicy const& m_robust_policy; RobustPolicy const& m_robust_policy;
SideStrategy m_strategy; Strategy m_strategy;
Visitor& m_visitor; Visitor& m_visitor;
}; };

View File

@ -56,7 +56,7 @@ struct traversal_ring_creator
Reverse1, Reverse2, OverlayType, Reverse1, Reverse2, OverlayType,
Geometry1, Geometry2, Turns, Clusters, Geometry1, Geometry2, Turns, Clusters,
RobustPolicy, RobustPolicy,
decltype(std::declval<Strategy>().side()), Strategy,
Visitor Visitor
> traversal_type; > traversal_type;
@ -72,7 +72,7 @@ struct traversal_ring_creator
Strategy const& strategy, Strategy const& strategy,
RobustPolicy const& robust_policy, Visitor& visitor) RobustPolicy const& robust_policy, Visitor& visitor)
: m_trav(geometry1, geometry2, turns, clusters, : m_trav(geometry1, geometry2, turns, clusters,
robust_policy, strategy.side(), visitor) robust_policy, strategy, visitor)
, m_geometry1(geometry1) , m_geometry1(geometry1)
, m_geometry2(geometry2) , m_geometry2(geometry2)
, m_turns(turns) , m_turns(turns)

View File

@ -1,10 +1,10 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2015-2016 Barend Gehrels, Amsterdam, the Netherlands. // 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. // This file was modified by Oracle on 2018-2020.
// Modifications copyright (c) 2018-2020 Oracle and/or its affiliates. // Modifications copyright (c) 2018-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License, // Use, modification and distribution is subject to the Boost Software License,
@ -26,7 +26,7 @@
#include <boost/geometry/core/access.hpp> #include <boost/geometry/core/access.hpp>
#endif #endif
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <cstddef> #include <cstddef>
#include <map> #include <map>
@ -391,11 +391,19 @@ struct traversal_switch_detector
{ {
for (turn_type& turn : m_turns) for (turn_type& turn : m_turns)
{ {
constexpr auto order1 = geometry::point_order<Geometry1>::value;
constexpr bool reverse1 = (order1 == boost::geometry::counterclockwise)
? ! Reverse1 : Reverse1;
constexpr auto order2 = geometry::point_order<Geometry2>::value;
constexpr bool reverse2 = (order2 == boost::geometry::counterclockwise)
? ! Reverse2 : Reverse2;
// For difference, for the input walked through in reverse, // For difference, for the input walked through in reverse,
// the meaning is reversed: what is isolated is actually not, // the meaning is reversed: what is isolated is actually not,
// and vice versa. // and vice versa.
bool const reverseMeaningInTurn bool const reverseMeaningInTurn
= (Reverse1 || Reverse2) = (reverse1 || reverse2)
&& ! turn.is_self() && ! turn.is_self()
&& ! turn.is_clustered() && ! turn.is_clustered()
&& uu_or_ii(turn) && uu_or_ii(turn)
@ -409,8 +417,8 @@ struct traversal_switch_detector
{ {
bool const reverseMeaningInOp bool const reverseMeaningInOp
= reverseMeaningInTurn = reverseMeaningInTurn
&& ((op.seg_id.source_index == 0 && Reverse1) && ((op.seg_id.source_index == 0 && reverse1)
|| (op.seg_id.source_index == 1 && Reverse2)); || (op.seg_id.source_index == 1 && reverse2));
// It is assigned to isolated if it's property is "Yes", // It is assigned to isolated if it's property is "Yes",
// (one connected interior, or chained). // (one connected interior, or chained).
@ -525,19 +533,21 @@ struct traversal_switch_detector
return ! uu_or_ii(turn); 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 // It is a cluster, check zones
// (assigned by sort_by_side/handle colocations) of both operations // (assigned by sort_by_side/handle colocations) of both operations
return turn.operations[0].enriched.zone return turn.operations[0].enriched.zone
== turn.operations[1].enriched.zone; == turn.operations[1].enriched.zone;
} }
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 // For an intersection, two regions connect if they are not ii
// when a multi-polygon is inside an interior ring and connecting it) // (ii-regions are isolated) or, in some cases, not iu (for example
return ! (turn.both(operation_intersection) // when a multi-polygon is inside an interior ring and connecting it)
|| turn.combination(operation_intersection, operation_union)); 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, 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]; turn_type const& turn = m_turns[turn_index];
if (turn.discarded if BOOST_GEOMETRY_CONSTEXPR (target_operation == operation_intersection)
&& BOOST_GEOMETRY_CONDITION(target_operation == operation_intersection))
{ {
// Discarded turn (union currently still needs it to determine regions) if (turn.discarded)
continue; {
// Discarded turn (union currently still needs it to determine regions)
continue;
}
} }
for (auto const& op : turn.operations) for (auto const& op : turn.operations)

View File

@ -3,11 +3,10 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // 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. // This file was modified by Oracle on 2015, 2017, 2019.
// Modifications copyright (c) 2015-2019 Oracle and/or its affiliates. // 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 Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -23,7 +22,7 @@
#include <boost/geometry/core/cs.hpp> #include <boost/geometry/core/cs.hpp>
#include <boost/geometry/policies/robustness/robust_point_type.hpp> #include <boost/geometry/policies/robustness/robust_point_type.hpp>
#include <boost/geometry/strategies/side.hpp> #include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
@ -85,30 +84,27 @@ inline bool point_is_spike_or_equal(Point1 const& last_point,
return true; return true;
} }
if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled)) if BOOST_GEOMETRY_CONSTEXPR (! RobustPolicy::enabled)
{ {
return false; return false;
} }
else // else prevents unreachable code warning
{
// Try using specified robust policy
using robust_point_type = typename geometry::robust_point_type
<
Point1,
RobustPolicy
>::type;
// Try using specified robust policy robust_point_type last_point_rob, segment_a_rob, segment_b_rob;
typedef typename geometry::robust_point_type geometry::recalculate(last_point_rob, last_point, robust_policy);
< geometry::recalculate(segment_a_rob, segment_a, robust_policy);
Point1, geometry::recalculate(segment_b_rob, segment_b, robust_policy);
RobustPolicy
>::type robust_point_type;
robust_point_type last_point_rob, segment_a_rob, segment_b_rob; return point_is_spike_or_equal(last_point_rob, segment_a_rob, segment_b_rob,
geometry::recalculate(last_point_rob, last_point, robust_policy); strategy);
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 template
@ -133,25 +129,27 @@ inline bool point_is_collinear(Point1 const& last_point,
// This part (or whole method, because it is then trivial) // This part (or whole method, because it is then trivial)
// will be removed after rescaling // will be removed after rescaling
if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled)) if BOOST_GEOMETRY_CONSTEXPR (! RobustPolicy::enabled)
{ {
return false; return false;
} }
else // else prevents unreachable code warning
{
// Redo, using specified robust policy
using robust_point_type = typename geometry::robust_point_type
<
Point1,
RobustPolicy
>::type;
// Redo, using specified robust policy robust_point_type last_point_rob, segment_a_rob, segment_b_rob;
typedef typename geometry::robust_point_type geometry::recalculate(last_point_rob, last_point, robust_policy);
< geometry::recalculate(segment_a_rob, segment_a, robust_policy);
Point1, geometry::recalculate(segment_b_rob, segment_b, robust_policy);
RobustPolicy
>::type robust_point_type;
robust_point_type last_point_rob, segment_a_rob, segment_b_rob; int const side_rob = strategy.apply(segment_a_rob, segment_b_rob, last_point_rob);
geometry::recalculate(last_point_rob, last_point, robust_policy); return side_rob == 0;
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;
} }

View File

@ -21,8 +21,6 @@
#include <boost/concept/requires.hpp> #include <boost/concept/requires.hpp>
#include <boost/concept_check.hpp> #include <boost/concept_check.hpp>
#include <boost/numeric/conversion/bounds.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/size.hpp> #include <boost/range/size.hpp>

View File

@ -31,6 +31,8 @@
#include <boost/geometry/geometries/helper_geometry.hpp> #include <boost/geometry/geometries/helper_geometry.hpp>
#include <boost/geometry/util/numeric_cast.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
{ {
@ -836,7 +838,7 @@ struct areal_areal
segment_identifier const& seg_id = turn.operations[OpId].seg_id; segment_identifier const& seg_id = turn.operations[OpId].seg_id;
signed_size_type signed_size_type
count = boost::numeric_cast<signed_size_type>( count = util::numeric_cast<signed_size_type>(
geometry::num_interior_rings( geometry::num_interior_rings(
detail::single_geometry(analyser.geometry, seg_id))); detail::single_geometry(analyser.geometry, seg_id)));

View File

@ -30,6 +30,7 @@
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
#include <boost/geometry/util/type_traits.hpp>
#include <type_traits> #include <type_traits>
@ -42,10 +43,12 @@ namespace detail { namespace relate {
// NOTE: This iterates through single geometries for which turns were not generated. // 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. // It doesn't mean that the geometry is disjoint, only that no turns were detected.
template <std::size_t OpId, template
typename Geometry, <
typename Tag = typename geometry::tag<Geometry>::type, std::size_t OpId,
bool IsMulti = std::is_base_of<multi_tag, Tag>::value typename Geometry,
typename Tag = typename geometry::tag<Geometry>::type,
bool IsMulti = util::is_multi<Geometry>::value
> >
struct for_each_disjoint_geometry_if struct for_each_disjoint_geometry_if
: public not_implemented<Tag> : public not_implemented<Tag>

View File

@ -17,25 +17,20 @@
#include <boost/core/ignore_unused.hpp> #include <boost/core/ignore_unused.hpp>
#include <boost/range/size.hpp> #include <boost/range/size.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/topological_dimension.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/util/type_traits.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>
#include <boost/geometry/algorithms/detail/point_on_border.hpp> #include <boost/geometry/algorithms/detail/point_on_border.hpp>
#include <boost/geometry/algorithms/detail/sub_range.hpp>
#include <boost/geometry/algorithms/detail/single_geometry.hpp>
#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
#include <boost/geometry/algorithms/detail/relate/turns.hpp>
#include <boost/geometry/algorithms/detail/relate/boundary_checker.hpp> #include <boost/geometry/algorithms/detail/relate/boundary_checker.hpp>
#include <boost/geometry/algorithms/detail/relate/follow_helpers.hpp> #include <boost/geometry/algorithms/detail/relate/follow_helpers.hpp>
#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
#include <boost/geometry/algorithms/detail/relate/turns.hpp>
#include <boost/geometry/algorithms/detail/single_geometry.hpp>
#include <boost/geometry/algorithms/detail/sub_range.hpp>
#include <boost/geometry/algorithms/num_interior_rings.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/topological_dimension.hpp>
#include <boost/geometry/geometries/helper_geometry.hpp> #include <boost/geometry/geometries/helper_geometry.hpp>
#include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/util/type_traits.hpp>
#include <boost/geometry/views/detail/closed_clockwise_view.hpp> #include <boost/geometry/views/detail/closed_clockwise_view.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
@ -854,30 +849,30 @@ struct linear_areal
m_exit_watcher.reset_detected_exit(); m_exit_watcher.reset_detected_exit();
} }
if ( BOOST_GEOMETRY_CONDITION( util::is_multi<OtherGeometry>::value ) if BOOST_GEOMETRY_CONSTEXPR (util::is_multi<OtherGeometry>::value)
&& m_first_from_unknown )
{ {
// For MultiPolygon many x/u operations may be generated as a first IP if (m_first_from_unknown)
// 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<op_id>(*m_previous_turn_ptr, *it,
strategy) )
)
{ {
update<interior, exterior, '1', TransposeResult>(res); // For MultiPolygon many x/u operations may be generated as a first IP
if ( m_first_from_unknown_boundary_detected ) // 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<op_id>(*m_previous_turn_ptr, *it, strategy)))
{ {
update<boundary, exterior, '0', TransposeResult>(res); update<interior, exterior, '1', TransposeResult>(res);
} if ( m_first_from_unknown_boundary_detected )
{
update<boundary, exterior, '0', TransposeResult>(res);
}
m_first_from_unknown = false; m_first_from_unknown = false;
m_first_from_unknown_boundary_detected = false; m_first_from_unknown_boundary_detected = false;
}
} }
} }
@ -1037,7 +1032,7 @@ struct linear_areal
} }
} }
if ( BOOST_GEOMETRY_CONDITION( util::is_multi<OtherGeometry>::value ) ) if BOOST_GEOMETRY_CONSTEXPR (util::is_multi<OtherGeometry>::value)
{ {
m_first_from_unknown = false; m_first_from_unknown = false;
m_first_from_unknown_boundary_detected = false; m_first_from_unknown_boundary_detected = false;
@ -1123,9 +1118,9 @@ struct linear_areal
} }
else else
{ {
if ( BOOST_GEOMETRY_CONDITION( util::is_multi<OtherGeometry>::value ) if BOOST_GEOMETRY_CONSTEXPR (util::is_multi<OtherGeometry>::value)
/*&& ( op == overlay::operation_blocked /*&& ( 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; m_first_from_unknown = true;
} }
@ -1150,9 +1145,9 @@ struct linear_areal
} }
else else
{ {
if ( BOOST_GEOMETRY_CONDITION( util::is_multi<OtherGeometry>::value ) if BOOST_GEOMETRY_CONSTEXPR (util::is_multi<OtherGeometry>::value)
/*&& ( op == overlay::operation_blocked /*&& ( 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); BOOST_GEOMETRY_ASSERT(m_first_from_unknown);
m_first_from_unknown_boundary_detected = true; 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 // 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 // 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 // then we know that the LineString is outside
if ( BOOST_GEOMETRY_CONDITION( util::is_multi<OtherGeometry>::value ) if BOOST_GEOMETRY_CONSTEXPR (util::is_multi<OtherGeometry>::value)
&& m_first_from_unknown )
{ {
update<interior, exterior, '1', TransposeResult>(res); if (m_first_from_unknown)
if ( m_first_from_unknown_boundary_detected )
{ {
update<boundary, exterior, '0', TransposeResult>(res); update<interior, exterior, '1', TransposeResult>(res);
} if ( m_first_from_unknown_boundary_detected )
{
update<boundary, exterior, '0', TransposeResult>(res);
}
// done below // done below
//m_first_from_unknown = false; //m_first_from_unknown = false;
//m_first_from_unknown_boundary_detected = false; //m_first_from_unknown_boundary_detected = false;
}
} }
// here, the possible exit is the real one // here, the possible exit is the real one

View File

@ -1,10 +1,10 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // 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. // This file was modified by Oracle on 2013-2022.
// Modifications copyright (c) 2013-2023, Oracle and/or its affiliates. // 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 Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, 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<exterior, interior, '0'>(result) ) || relate::may_update<exterior, interior, '0'>(result) )
{ {
// NlogN + MlogN // NlogN + MlogN
bool is_disjoint = search<Transpose, Strategy>(first_sorted_mpt, first_iterated_mpt, result); bool const is_disjoint = search<Transpose, Strategy>(first_sorted_mpt, first_iterated_mpt, result);
if ( BOOST_GEOMETRY_CONDITION(is_disjoint || result.interrupt) ) if (is_disjoint || BOOST_GEOMETRY_CONDITION(result.interrupt) )
{
return; return;
}
} }
if ( relate::may_update<interior, interior, '0'>(result) if ( relate::may_update<interior, interior, '0'>(result)

View File

@ -27,7 +27,7 @@
#include <boost/geometry/core/coordinate_dimension.hpp> #include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/exception.hpp> #include <boost/geometry/core/exception.hpp>
#include <boost/geometry/core/static_assert.hpp> #include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/sequence.hpp> #include <boost/geometry/util/sequence.hpp>
namespace boost { namespace geometry { namespace boost { namespace geometry {
@ -292,15 +292,18 @@ struct interrupt_dispatch<Mask, true>
template <char V> template <char V>
static inline bool check_element(char m) 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' ); 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 m == 'F';
} }
return false; else
{
return false;
}
} }
}; };

View File

@ -721,24 +721,31 @@ struct sectionalize_multi
template <typename Sections, typename Strategy> template <typename Sections, typename Strategy>
inline void enlarge_sections(Sections& sections, Strategy const&) inline void enlarge_sections(Sections& sections, Strategy const&)
{ {
// Expand the box to avoid missing any intersection. The amount is // Expand the box to avoid missing any intersection.
// should be larger than epsilon. About the value itself: the smaller // About the value itself: the smaller it is,
// it is, the higher the risk to miss intersections. The larger it is, // the higher the risk to miss intersections.
// the more comparisons are made, which is not harmful for the result // The larger it is, the more comparisons are made,
// (but it might be for the performance). // which is not harmful for the result,
// So it should be on the high side. // but it might be for the performance.
// So it should be on the higher side.
// Use a compilable and workable epsilon for all types, for example: //
// The current value:
// - for double :~ 2.22e-13 // - for double :~ 2.22e-13
// - for float :~ 1e-4 // - for float :~ 1e-4
// - for Boost.Multiprecision (50) :~ 5.35e-48 // - for Boost.Multiprecision (50) :~ 5.35e-48
// - for Boost.Rational : 0/1 // - 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<Sections>::type;
using box_t = typename section_t::box_type;
using coor_t = typename geometry::coordinate_type<box_t>::type;
static auto const eps = math::scaled_epsilon<coor_t>(1000);
for (auto& section : sections) for (auto& section : sections)
{ {
using gt = decltype(section.bounding_box);
using ct = typename geometry::coordinate_type<gt>::type;
static ct const eps = math::scaled_epsilon<ct>(1000);
expand_by_epsilon(section.bounding_box, eps); expand_by_epsilon(section.bounding_box, eps);
} }
} }

View File

@ -18,6 +18,7 @@
#include <boost/geometry/core/assert.hpp> #include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/tag.hpp> #include <boost/geometry/core/tag.hpp>
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry { namespace boost { namespace geometry {
@ -29,11 +30,7 @@ namespace detail_dispatch {
template template
< <
typename Geometry, typename Geometry,
bool IsMulti = std::is_base_of bool IsMulti = util::is_multi<Geometry>::value
<
multi_tag,
typename geometry::tag<Geometry>::type
>::value
> >
struct single_geometry struct single_geometry
{ {

View File

@ -25,6 +25,7 @@
#include <boost/geometry/core/tags.hpp> #include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
#include <boost/geometry/util/type_traits.hpp>
namespace boost { namespace geometry { namespace boost { namespace geometry {
@ -33,9 +34,12 @@ namespace boost { namespace geometry {
#ifndef DOXYGEN_NO_DISPATCH #ifndef DOXYGEN_NO_DISPATCH
namespace detail_dispatch { namespace detail_dispatch {
template <typename Geometry, template
typename Tag = typename geometry::tag<Geometry>::type, <
bool IsMulti = std::is_base_of<multi_tag, Tag>::value> typename Geometry,
typename Tag = typename geometry::tag<Geometry>::type,
bool IsMulti = util::is_multi<Geometry>::value
>
struct sub_range : not_implemented<Tag> struct sub_range : not_implemented<Tag>
{}; {};

View File

@ -42,7 +42,7 @@
#include <boost/geometry/strategies/covered_by.hpp> #include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/disjoint.hpp> #include <boost/geometry/strategies/disjoint.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/type_traits.hpp> #include <boost/geometry/util/type_traits.hpp>
@ -238,9 +238,16 @@ struct multi_point_multi_geometry
if (boundaries > 0) 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 else
{ {

View File

@ -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 <boost/geometry/algorithms/detail/point_on_border.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
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 <typename Geometry1,
typename Geometry2,
typename Tag1 = typename geometry::tag<Geometry1>::type,
typename Tag2 = typename geometry::tag<Geometry2>::type>
struct within_no_turns
{
template <typename Strategy> static inline
bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
typedef typename geometry::point_type<Geometry1>::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 <typename Geometry1, typename Geometry2>
struct within_no_turns<Geometry1, Geometry2, ring_tag, polygon_tag>
{
template <typename Strategy> static inline
bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
typedef typename geometry::point_type<Geometry1>::type point1_type;
typedef typename geometry::point_type<Geometry2>::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 <typename Geometry1, typename Geometry2>
struct within_no_turns<Geometry1, Geometry2, polygon_tag, polygon_tag>
{
template <typename Strategy> static inline
bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
typedef typename geometry::point_type<Geometry1>::type point1_type;
typedef typename geometry::point_type<Geometry2>::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 <typename Geometry1,
typename Geometry2,
typename Tag1 = typename geometry::tag<Geometry1>::type,
typename Tag2 = typename geometry::tag<Geometry2>::type,
bool IsMulti1 = boost::is_base_of<geometry::multi_tag, Tag1>::value,
bool IsMulti2 = boost::is_base_of<geometry::multi_tag, Tag2>::value>
struct within_no_turns_multi
{
template <typename Strategy> static inline
bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
return within_no_turns<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
}
};
template <typename Geometry1, typename Geometry2, typename Tag1, typename Tag2>
struct within_no_turns_multi<Geometry1, Geometry2, Tag1, Tag2, true, false>
{
template <typename Strategy> 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<Geometry1>::type subgeometry1;
for (auto it = boost::begin(geometry1) ; it != boost::end(geometry1) ; ++it )
{
if (! within_no_turns<subgeometry1, Geometry2>::apply(*it, geometry2, strategy))
{
return false;
}
}
return true;
}
};
template <typename Geometry1, typename Geometry2, typename Tag1, typename Tag2>
struct within_no_turns_multi<Geometry1, Geometry2, Tag1, Tag2, false, true>
{
template <typename Strategy> 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<Geometry2>::type subgeometry2;
for (auto it = boost::begin(geometry2); it != boost::end(geometry2); ++it)
{
if (within_no_turns<Geometry1, subgeometry2>::apply(geometry1, *it, strategy))
{
return true;
}
}
return false;
}
};
template <typename Geometry1, typename Geometry2, typename Tag1, typename Tag2>
struct within_no_turns_multi<Geometry1, Geometry2, Tag1, Tag2, true, true>
{
template <typename Strategy> 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<Geometry1>::type subgeometry1;
for (auto it = boost::begin(geometry1) ; it != boost::end(geometry1) ; ++it)
{
if (! within_no_turns_multi<subgeometry1, Geometry2>::apply(*it, geometry2, strategy))
{
return false;
}
}
return true;
}
};
}} // namespace detail_dispatch::within
namespace detail { namespace within {
template <typename Geometry1, typename Geometry2, typename Strategy>
inline bool within_no_turns(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
return detail_dispatch::within::within_no_turns_multi<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
}
}} // namespace detail::within
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_WITHIN_NO_TURNS_HPP

View File

@ -1,5 +1,7 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2023-2024 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2018-2023 Oracle and/or its affiliates. // 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 Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -35,7 +37,7 @@
#include <boost/geometry/strategies/line_interpolate/geographic.hpp> #include <boost/geometry/strategies/line_interpolate/geographic.hpp>
#include <boost/geometry/strategies/line_interpolate/spherical.hpp> #include <boost/geometry/strategies/line_interpolate/spherical.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
#include <boost/geometry/util/type_traits.hpp> #include <boost/geometry/util/type_traits.hpp>
@ -133,13 +135,16 @@ struct interpolate_range
p, p,
diff_distance); diff_distance);
Policy::apply(p, pointlike); Policy::apply(p, pointlike);
if ( BOOST_GEOMETRY_CONDITION(util::is_point<PointLike>::value) ) if BOOST_GEOMETRY_CONSTEXPR (util::is_point<PointLike>::value)
{ {
return; return;
} }
start_p = p; else // else prevents unreachable code warning
prev_distance = repeated_distance; {
repeated_distance += max_distance; start_p = p;
prev_distance = repeated_distance;
repeated_distance += max_distance;
}
} }
prev_distance = current_distance; prev_distance = current_distance;
prev = it; prev = it;

View File

@ -3,7 +3,7 @@
// Copyright (c) 2007-2013 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2013 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2013 Bruno Lalande, Paris, France. // Copyright (c) 2008-2013 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2013 Mateusz Loskot, London, UK. // 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. // This file was modified by Oracle on 2017-2023.
// Modifications copyright (c) 2017-2023 Oracle and/or its affiliates. // Modifications copyright (c) 2017-2023 Oracle and/or its affiliates.
@ -37,7 +37,7 @@
#include <boost/geometry/strategies/default_strategy.hpp> #include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
@ -104,7 +104,7 @@ struct range_remove_spikes
std::size_t cleaned_count = cleaned.size(); std::size_t cleaned_count = cleaned.size();
// For a closed-polygon, remove closing point, this makes checking first point(s) easier and consistent // For a closed-polygon, remove closing point, this makes checking first point(s) easier and consistent
if ( BOOST_GEOMETRY_CONDITION(geometry::closure<Range>::value == geometry::closed) ) if BOOST_GEOMETRY_CONSTEXPR (geometry::closure<Range>::value == geometry::closed)
{ {
--cleaned_e; --cleaned_e;
--cleaned_count; --cleaned_count;
@ -148,7 +148,7 @@ struct range_remove_spikes
} }
// Close if necessary // Close if necessary
if ( BOOST_GEOMETRY_CONDITION(geometry::closure<Range>::value == geometry::closed) ) if BOOST_GEOMETRY_CONSTEXPR (geometry::closure<Range>::value == geometry::closed)
{ {
BOOST_GEOMETRY_ASSERT(cleaned_e != cleaned.end()); BOOST_GEOMETRY_ASSERT(cleaned_e != cleaned.end());
*cleaned_e = *cleaned_b; *cleaned_e = *cleaned_b;

View File

@ -3,7 +3,7 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // 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. // This file was modified by Oracle on 2018-2023.
// Modifications copyright (c) 2018-2023 Oracle and/or its affiliates. // Modifications copyright (c) 2018-2023 Oracle and/or its affiliates.
@ -61,6 +61,7 @@
#include <boost/geometry/strategies/simplify/geographic.hpp> #include <boost/geometry/strategies/simplify/geographic.hpp>
#include <boost/geometry/strategies/simplify/spherical.hpp> #include <boost/geometry/strategies/simplify/spherical.hpp>
#include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/type_traits_std.hpp> #include <boost/geometry/util/type_traits_std.hpp>
#ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER #ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
@ -429,10 +430,10 @@ public :
return; return;
} }
bool const is_closed_in = geometry::closure<RingIn>::value == closed; constexpr bool is_closed_in = geometry::closure<RingIn>::value == closed;
bool const is_closed_out = geometry::closure<RingOut>::value == closed; constexpr bool is_closed_out = geometry::closure<RingOut>::value == closed;
bool const is_clockwise_in = geometry::point_order<RingIn>::value == clockwise; constexpr bool is_clockwise_in = geometry::point_order<RingIn>::value == clockwise;
bool const is_clockwise_out = geometry::point_order<RingOut>::value == clockwise; constexpr bool is_clockwise_out = geometry::point_order<RingOut>::value == clockwise;
// TODO: instead of area() use calculate_point_order() ? // TODO: instead of area() use calculate_point_order() ?
@ -482,10 +483,13 @@ public :
// Do not duplicate the closing point // Do not duplicate the closing point
auto rot_end = boost::end(ring); auto rot_end = boost::end(ring);
std::size_t rot_index = index; 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 (size > 1)
if (rot_index == size - 1) { rot_index = 0; } {
--rot_end;
if (rot_index == size - 1) { rot_index = 0; }
}
} }
std::rotate_copy(boost::begin(ring), range::pos(ring, rot_index), 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); simplify_range<0>::apply(rotated, out, max_distance, impl, strategies);
// Open output if needed // 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() ? // TODO: instead of area() use calculate_point_order() ?
@ -532,7 +539,7 @@ public :
rotated.clear(); 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)); std::reverse(boost::begin(out), boost::end(out));
} }

View File

@ -16,9 +16,9 @@
#include <boost/geometry/core/access.hpp> #include <boost/geometry/core/access.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp> #include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/util/numeric_cast.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp> #include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/numeric/conversion/cast.hpp>
namespace boost { namespace geometry namespace boost { namespace geometry
{ {
@ -33,7 +33,7 @@ class calculate_determinant
template <typename T> template <typename T>
static inline ReturnType rt(T const& v) static inline ReturnType rt(T const& v)
{ {
return boost::numeric_cast<ReturnType>(v); return util::numeric_cast<ReturnType>(v);
} }
public : public :

View File

@ -23,13 +23,12 @@
#include <cstddef> #include <cstddef>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/geometry/core/access.hpp> #include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/cs.hpp> #include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/coordinate_promotion.hpp> #include <boost/geometry/core/coordinate_promotion.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/numeric_cast.hpp>
@ -48,7 +47,7 @@ struct degree_radian_converter
static inline coordinate_type get(Geometry const& geometry) static inline coordinate_type get(Geometry const& geometry)
{ {
return boost::numeric_cast return util::numeric_cast
< <
coordinate_type coordinate_type
>(geometry::get<Dimension>(geometry) >(geometry::get<Dimension>(geometry)
@ -57,7 +56,7 @@ struct degree_radian_converter
static inline void set(Geometry& geometry, coordinate_type const& radians) static inline void set(Geometry& geometry, coordinate_type const& radians)
{ {
geometry::set<Dimension>(geometry, boost::numeric_cast geometry::set<Dimension>(geometry, util::numeric_cast
< <
coordinate_type coordinate_type
>(radians * math::r2d<coordinate_type>())); >(radians * math::r2d<coordinate_type>()));
@ -113,7 +112,7 @@ struct degree_radian_converter_box_segment
static inline coordinate_type get(Geometry const& geometry) static inline coordinate_type get(Geometry const& geometry)
{ {
return boost::numeric_cast return util::numeric_cast
< <
coordinate_type coordinate_type
>(geometry::get<Index, Dimension>(geometry) >(geometry::get<Index, Dimension>(geometry)
@ -122,7 +121,7 @@ struct degree_radian_converter_box_segment
static inline void set(Geometry& geometry, coordinate_type const& radians) static inline void set(Geometry& geometry, coordinate_type const& radians)
{ {
geometry::set<Index, Dimension>(geometry, boost::numeric_cast geometry::set<Index, Dimension>(geometry, util::numeric_cast
< <
coordinate_type coordinate_type
>(radians * math::r2d<coordinate_type>())); >(radians * math::r2d<coordinate_type>()));

View File

@ -1,9 +1,8 @@
// Boost.Geometry // 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. // Copyright (c) 2015-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License, // Use, modification and distribution is subject to the Boost Software License,
@ -18,7 +17,7 @@
#include <boost/geometry/core/radius.hpp> #include <boost/geometry/core/radius.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/formulas/differential_quantities.hpp> #include <boost/geometry/formulas/differential_quantities.hpp>
@ -98,7 +97,7 @@ public:
CT const d = acos(cos_d); // [0, pi] CT const d = acos(cos_d); // [0, pi]
CT const sin_d = sin(d); // [-1, 1] 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 K = math::sqr(sin_lat1-sin_lat2);
CT const L = math::sqr(sin_lat1+sin_lat2); CT const L = math::sqr(sin_lat1+sin_lat2);
@ -123,7 +122,7 @@ public:
result.distance = a * (d + dd); 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 // sin_d = 0 <=> antipodal points (incl. poles) or very close
if (math::equals(sin_d, c0)) if (math::equals(sin_d, c0))
@ -210,14 +209,14 @@ public:
// therefore dA and dB may be great and the resulting azimuths // therefore dA and dB may be great and the resulting azimuths
// may be some more or less arbitrary angles // may be some more or less arbitrary angles
if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth)) if BOOST_GEOMETRY_CONSTEXPR (CalcFwdAzimuth)
{ {
CT const dA = V*T - U; CT const dA = V*T - U;
result.azimuth = A - dA; result.azimuth = A - dA;
normalize_azimuth(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; CT const dB = -U*T + V;
if (B >= 0) if (B >= 0)
@ -229,7 +228,7 @@ public:
} }
} }
if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities)
{ {
CT const b = CT(get_radius<2>(spheroid)); CT const b = CT(get_radius<2>(spheroid));

View File

@ -1,6 +1,6 @@
// Boost.Geometry // 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. // Copyright (c) 2015-2022 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
@ -17,6 +17,7 @@
#include <boost/geometry/formulas/flattening.hpp> #include <boost/geometry/formulas/flattening.hpp>
#include <boost/geometry/formulas/mean_radius.hpp> #include <boost/geometry/formulas/mean_radius.hpp>
#include <boost/geometry/formulas/karney_inverse.hpp> #include <boost/geometry/formulas/karney_inverse.hpp>
#include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/math/special_functions/hypot.hpp> #include <boost/math/special_functions/hypot.hpp>
@ -381,26 +382,33 @@ public:
return pi; 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); if (lat1r != lat2r) // not for segments parallel to equator
CT const sbet1 = sin(lat1r); {
CT const cbet2 = cos(lat2r); CT const cbet1 = cos(lat1r);
CT const sbet2 = sin(lat2r); CT const sbet1 = sin(lat1r);
CT const cbet2 = cos(lat2r);
CT const sbet2 = sin(lat2r);
CT const omg12 = lon2r - lon1r; CT const omg12 = lon2r - lon1r;
CT const comg12 = cos(omg12); CT const comg12 = cos(omg12);
CT const somg12 = sin(omg12); CT const somg12 = sin(omg12);
CT const cbet1_sbet2 = cbet1 * sbet2; CT const cbet1_sbet2 = cbet1 * sbet2;
CT const sbet1_cbet2 = sbet1 * cbet2; CT const sbet1_cbet2 = sbet1 * cbet2;
CT const alp1 = atan2(cbet1_sbet2 - sbet1_cbet2 * comg12, cbet2 * somg12); CT const alp1 = atan2(cbet1_sbet2 - sbet1_cbet2 * comg12, cbet2 * somg12);
CT const alp2 = atan2(cbet1_sbet2 * comg12 - sbet1_cbet2, cbet1 * somg12); CT const alp2 = atan2(cbet1_sbet2 * comg12 - sbet1_cbet2, cbet1 * somg12);
excess = alp2 - alp1;
} else {
excess = alp2 - alp1;
}
else
{
excess = trapezoidal_formula(lat1r, lat2r, lon12r);
}
}
else
{
excess = trapezoidal_formula(lat1r, lat2r, lon12r); excess = trapezoidal_formula(lat1r, lat2r, lon12r);
} }

View File

@ -14,7 +14,7 @@
#include <boost/geometry/core/assert.hpp> #include <boost/geometry/core/assert.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
@ -73,7 +73,7 @@ public:
if (math::equals(sin_bet1, c0) && math::equals(sin_bet2, c0)) if (math::equals(sin_bet1, c0) && math::equals(sin_bet2, c0))
{ {
CT const sig_12 = dlon / one_minus_f; CT const sig_12 = dlon / one_minus_f;
if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength)
{ {
BOOST_GEOMETRY_ASSERT((-math::pi<CT>() <= azimuth && azimuth <= math::pi<CT>())); BOOST_GEOMETRY_ASSERT((-math::pi<CT>() <= azimuth && azimuth <= math::pi<CT>()));
@ -82,7 +82,7 @@ public:
reduced_length = m12; reduced_length = m12;
} }
if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) if BOOST_GEOMETRY_CONSTEXPR (EnableGeodesicScale)
{ {
CT M12 = cos(sig_12); CT M12 = cos(sig_12);
geodesic_scale = M12; geodesic_scale = M12;
@ -123,7 +123,7 @@ public:
CT const dn1 = math::sqrt(c1 + ep2 * math::sqr(sin_bet1)); CT const dn1 = math::sqrt(c1 + ep2 * math::sqr(sin_bet1));
CT const dn2 = math::sqrt(c1 + ep2 * math::sqr(sin_bet2)); 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) CT const m12_b = dn2 * (cos_sig1 * sin_sig2)
- dn1 * (sin_sig1 * cos_sig2) - dn1 * (sin_sig1 * cos_sig2)
@ -133,7 +133,7 @@ public:
reduced_length = m12; 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 cos_sig12 = cos_sig1 * cos_sig2 + sin_sig1 * sin_sig2;
CT const t = ep2 * (cos_bet1 - cos_bet2) * (cos_bet1 + cos_bet2) / (dn1 + dn2); CT const t = ep2 * (cos_bet1 - cos_bet2) * (cos_bet1 + cos_bet2) / (dn1 + dn2);

View File

@ -38,7 +38,7 @@
#include <boost/geometry/formulas/flattening.hpp> #include <boost/geometry/formulas/flattening.hpp>
#include <boost/geometry/formulas/result_direct.hpp> #include <boost/geometry/formulas/result_direct.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp> #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
#include <boost/geometry/util/series_expansion.hpp> #include <boost/geometry/util/series_expansion.hpp>
@ -162,7 +162,7 @@ public:
CT const sin_sigma2 = sin_sigma1 * cos_sigma12 + cos_sigma1 * sin_sigma12; CT const sin_sigma2 = sin_sigma1 * cos_sigma12 + cos_sigma1 * sin_sigma12;
CT const cos_sigma2 = cos_sigma1 * cos_sigma12 - sin_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 sin_alpha2 = sin_alpha0;
CT const cos_alpha2 = cos_alpha0 * cos_sigma2; CT const cos_alpha2 = cos_alpha0 * cos_sigma2;
@ -170,7 +170,7 @@ public:
result.reverse_azimuth = atan2(sin_alpha2, cos_alpha2); 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. // Find the latitude at the second point.
CT const sin_beta2 = cos_alpha0 * sin_sigma2; CT const sin_beta2 = cos_alpha0 * sin_sigma2;
@ -217,7 +217,7 @@ public:
result.lon2 *= math::d2r<CT>(); result.lon2 *= math::d2r<CT>();
} }
if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities)
{ {
// Evaluate the coefficients for C2. // Evaluate the coefficients for C2.
// Index zero element of coeffs_C2 is unused. // Index zero element of coeffs_C2 is unused.

View File

@ -36,7 +36,7 @@
#include <boost/math/constants/constants.hpp> #include <boost/math/constants/constants.hpp>
#include <boost/math/special_functions/hypot.hpp> #include <boost/math/special_functions/hypot.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/precise_math.hpp> #include <boost/geometry/util/precise_math.hpp>
#include <boost/geometry/util/series_expansion.hpp> #include <boost/geometry/util/series_expansion.hpp>
@ -309,7 +309,7 @@ public:
sigma12 = omega12 = lam12 / one_minus_f; sigma12 = omega12 = lam12 / one_minus_f;
m12x = b * sin(sigma12); m12x = b * sin(sigma12);
if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) if BOOST_GEOMETRY_CONSTEXPR (EnableGeodesicScale)
{ {
result.geodesic_scale = cos(sigma12); result.geodesic_scale = cos(sigma12);
} }
@ -335,7 +335,7 @@ public:
// Short lines case (newton_start sets sin_alpha2, cos_alpha2, dnm). // Short lines case (newton_start sets sin_alpha2, cos_alpha2, dnm).
s12x = sigma12 * b * dnm; s12x = sigma12 * b * dnm;
m12x = math::sqr(dnm) * b * sin(sigma12 / 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); result.geodesic_scale = cos(sigma12 / dnm);
} }
@ -460,25 +460,25 @@ public:
sin_alpha2 *= swap_point * lon12_sign; sin_alpha2 *= swap_point * lon12_sign;
cos_alpha2 *= swap_point * lat_sign; cos_alpha2 *= swap_point * lat_sign;
if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength)
{ {
result.reduced_length = m12x; 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); 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); result.reverse_azimuth = atan2(sin_alpha2, cos_alpha2);
} }
} }
if (BOOST_GEOMETRY_CONDITION(EnableDistance)) if BOOST_GEOMETRY_CONSTEXPR (EnableDistance)
{ {
result.distance = s12x; result.distance = s12x;
} }
@ -503,16 +503,13 @@ public:
// Evaluate the coefficients for C2. // Evaluate the coefficients for C2.
se::coeffs_C2<SeriesOrder, CT> coeffs_C2(epsilon); se::coeffs_C2<SeriesOrder, CT> coeffs_C2(epsilon);
if (BOOST_GEOMETRY_CONDITION(EnableDistance) || if BOOST_GEOMETRY_CONSTEXPR (EnableDistance || EnableReducedLength || EnableGeodesicScale)
BOOST_GEOMETRY_CONDITION(EnableReducedLength) ||
BOOST_GEOMETRY_CONDITION(EnableGeodesicScale))
{ {
// Find the coefficients for A1 by computing the // Find the coefficients for A1 by computing the
// series expansion using Horner scehme. // series expansion using Horner scehme.
expansion_A1 = se::evaluate_A1<SeriesOrder>(epsilon); expansion_A1 = se::evaluate_A1<SeriesOrder>(epsilon);
if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength || EnableGeodesicScale)
BOOST_GEOMETRY_CONDITION(EnableGeodesicScale))
{ {
// Find the coefficients for A2 by computing the // Find the coefficients for A2 by computing the
// series expansion using Horner scehme. // series expansion using Horner scehme.
@ -524,15 +521,14 @@ public:
expansion_A1 += c1; 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) CT B1 = se::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C1)
- se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C1); - se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C1);
s12x = expansion_A1 * (sigma12 + B1); s12x = expansion_A1 * (sigma12 + B1);
if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength || EnableGeodesicScale)
BOOST_GEOMETRY_CONDITION(EnableGeodesicScale))
{ {
CT B2 = se::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C2) CT B2 = se::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C2)
- se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2); - se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2);
@ -540,8 +536,7 @@ public:
J12 = A12x * sigma12 + (expansion_A1 * B1 - expansion_A2 * B2); J12 = A12x * sigma12 + (expansion_A1 * B1 - expansion_A2 * B2);
} }
} }
else if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || else if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength || EnableGeodesicScale)
BOOST_GEOMETRY_CONDITION(EnableGeodesicScale))
{ {
for (size_t i = 1; i <= SeriesOrder; ++i) for (size_t i = 1; i <= SeriesOrder; ++i)
{ {
@ -554,7 +549,7 @@ public:
- se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2)); - se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2));
} }
if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) if BOOST_GEOMETRY_CONSTEXPR (EnableReducedLength)
{ {
m0 = A12x; m0 = A12x;
@ -563,7 +558,7 @@ public:
cos_sigma1 * cos_sigma2 * J12; 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 cos_sigma12 = cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2;
CT t = ep2 * (cos_beta1 - cos_beta2) * CT t = ep2 * (cos_beta1 - cos_beta2) *

View File

@ -23,7 +23,7 @@
#include <boost/geometry/formulas/quarter_meridian.hpp> #include <boost/geometry/formulas/quarter_meridian.hpp>
#include <boost/geometry/formulas/result_direct.hpp> #include <boost/geometry/formulas/result_direct.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry { namespace formula namespace boost { namespace geometry { namespace formula
@ -66,7 +66,7 @@ public:
CT azimuth = north ? c0 : pi; CT azimuth = north ? c0 : pi;
if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates)
{ {
CT s0 = meridian_inverse<CT, Order>::apply(la1, spheroid); CT s0 = meridian_inverse<CT, Order>::apply(la1, spheroid);
int signed_distance = north ? distance : -distance; int signed_distance = north ? distance : -distance;
@ -74,7 +74,7 @@ public:
result.lat2 = apply(s0 + signed_distance, spheroid); result.lat2 = apply(s0 + signed_distance, spheroid);
} }
if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth)
{ {
result.reverse_azimuth = azimuth; result.reverse_azimuth = azimuth;
@ -92,7 +92,7 @@ public:
} }
if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities)
{ {
CT const b = CT(get_radius<2>(spheroid)); CT const b = CT(get_radius<2>(spheroid));
CT const f = formula::flattening<CT>(spheroid); CT const f = formula::flattening<CT>(spheroid);

View File

@ -1,7 +1,8 @@
// Boost.Geometry // 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 Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -18,7 +19,7 @@
#include <boost/geometry/core/assert.hpp> #include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/radius.hpp> #include <boost/geometry/core/radius.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp> #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
@ -108,7 +109,7 @@ public:
CT const C2 = f * (c1 - math::sqr(M)) / c4; // lower-case c2 in the technical report CT const C2 = f * (c1 - math::sqr(M)) / c4; // lower-case c2 in the technical report
CT D = 0; CT D = 0;
CT P = 0; CT P = 0;
if ( BOOST_GEOMETRY_CONDITION(SecondOrder) ) if BOOST_GEOMETRY_CONSTEXPR (SecondOrder)
{ {
D = (c1 - C2) * (c1 - C2 - C1 * M); D = (c1 - C2) * (c1 - C2 - C1 * M);
P = C2 * (c1 + C1 * M / c2) / D; P = C2 * (c1 + C1 * M / c2) / D;
@ -142,7 +143,7 @@ public:
CT const Y = c2 * P * V * W * sin_d; CT const Y = c2 * P * V * W * sin_d;
CT X = 0; CT X = 0;
CT d_sigma = d - Y; 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); X = math::sqr(C2) * sin_d * cos_d * (2 * math::sqr(V) - c1);
d_sigma += X; d_sigma += X;
@ -150,7 +151,7 @@ public:
CT const sin_d_sigma = sin(d_sigma); CT const sin_d_sigma = sin(d_sigma);
CT const cos_d_sigma = cos(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); result.reverse_azimuth = atan2(M, N * cos_d_sigma - sin_theta1 * sin_d_sigma);
@ -160,12 +161,12 @@ public:
} }
} }
if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates)
{ {
CT const S_sigma = c2 * sigma1 - d_sigma; CT const S_sigma = c2 * sigma1 - d_sigma;
CT cos_S_sigma = 0; CT cos_S_sigma = 0;
CT H = C1 * d_sigma; CT H = C1 * d_sigma;
if ( BOOST_GEOMETRY_CONDITION(SecondOrder) ) if BOOST_GEOMETRY_CONSTEXPR (SecondOrder)
{ {
cos_S_sigma = cos(S_sigma); cos_S_sigma = cos(S_sigma);
H = H * (c1 - C2) - C1 * C2 * sin_d_sigma * cos_S_sigma; H = H * (c1 - C2) - C1 * C2 * sin_d_sigma * cos_S_sigma;
@ -196,7 +197,7 @@ public:
} }
} }
if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities)
{ {
typedef differential_quantities<CT, EnableReducedLength, EnableGeodesicScale, 2> quantities; typedef differential_quantities<CT, EnableReducedLength, EnableGeodesicScale, 2> quantities;
quantities::apply(lon1, lat1, result.lon2, result.lat2, quantities::apply(lon1, lat1, result.lon2, result.lat2,
@ -205,7 +206,7 @@ public:
result.reduced_length, result.geodesic_scale); 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 // For longitudes close to the antimeridian the result can be out
// of range. Therefore normalize. // of range. Therefore normalize.

View File

@ -1,7 +1,8 @@
// Boost.Geometry // 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 Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -17,7 +18,7 @@
#include <boost/geometry/core/radius.hpp> #include <boost/geometry/core/radius.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/formulas/differential_quantities.hpp> #include <boost/geometry/formulas/differential_quantities.hpp>
@ -137,7 +138,7 @@ public:
CT const f_sqr = math::sqr(f); CT const f_sqr = math::sqr(f);
CT const f_sqr_per_64 = f_sqr / CT(64); 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 n1 = X * (A + C*X);
CT const n2 = Y * (B + E*Y); CT const n2 = Y * (B + E*Y);
@ -152,7 +153,7 @@ public:
result.distance = a * sin_d * (T - delta1d + delta2d); 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 // 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 // it's a situation when the endpoints are on the poles +-90 deg
@ -178,7 +179,7 @@ public:
CT const pi = math::pi<CT>(); CT const pi = math::pi<CT>();
if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth)) if BOOST_GEOMETRY_CONSTEXPR (CalcFwdAzimuth)
{ {
CT alpha1 = v + u; CT alpha1 = v + u;
if (alpha1 > pi) if (alpha1 > pi)
@ -189,7 +190,7 @@ public:
result.azimuth = alpha1; result.azimuth = alpha1;
} }
if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth)
{ {
CT alpha2 = pi - (v - u); CT alpha2 = pi - (v - u);
if (alpha2 > pi) if (alpha2 > pi)
@ -201,7 +202,7 @@ public:
} }
} }
if (BOOST_GEOMETRY_CONDITION(CalcQuantities)) if BOOST_GEOMETRY_CONSTEXPR (CalcQuantities)
{ {
typedef differential_quantities<CT, EnableReducedLength, EnableGeodesicScale, 2> quantities; typedef differential_quantities<CT, EnableReducedLength, EnableGeodesicScale, 2> quantities;
quantities::apply(lon1, lat1, lon2, lat2, quantities::apply(lon1, lat1, lon2, lat2,

View File

@ -1,10 +1,10 @@
// Boost.Geometry // Boost.Geometry
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // 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. // This file was modified by Oracle on 2014-2020.
// Modifications copyright (c) 2014-2020 Oracle and/or its affiliates. // Modifications copyright (c) 2014-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License, // Use, modification and distribution is subject to the Boost Software License,
@ -19,7 +19,7 @@
#include <boost/geometry/core/radius.hpp> #include <boost/geometry/core/radius.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp> #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
@ -136,7 +136,7 @@ public:
//&& geometry::math::abs(sigma) < pi //&& geometry::math::abs(sigma) < pi
&& counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness && counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness
if (BOOST_GEOMETRY_CONDITION(CalcCoordinates)) if BOOST_GEOMETRY_CONSTEXPR (CalcCoordinates)
{ {
result.lat2 result.lat2
= atan2( sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_azimuth12, = atan2( sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_azimuth12,
@ -151,13 +151,13 @@ public:
result.lon2 = lon1 + L; result.lon2 = lon1 + L;
} }
if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) if BOOST_GEOMETRY_CONSTEXPR (CalcRevAzimuth)
{ {
result.reverse_azimuth result.reverse_azimuth
= atan2(sin_alpha, -sin_U1 * sin_sigma + cos_U1 * cos_sigma * cos_azimuth12); // (12) = 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<CT, EnableReducedLength, EnableGeodesicScale, 2> quantities; typedef differential_quantities<CT, EnableReducedLength, EnableGeodesicScale, 2> quantities;
quantities::apply(lon1, lat1, result.lon2, result.lat2, quantities::apply(lon1, lat1, result.lon2, result.lat2,
@ -166,7 +166,7 @@ public:
result.reduced_length, result.geodesic_scale); 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 // For longitudes close to the antimeridian the result can be out
// of range. Therefore normalize. // of range. Therefore normalize.

View File

@ -1,11 +1,10 @@
// Boost.Geometry // Boost.Geometry
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // 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. // This file was modified by Oracle on 2014, 2016, 2017.
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. // Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License, // Use, modification and distribution is subject to the Boost Software License,
@ -20,7 +19,7 @@
#include <boost/geometry/core/radius.hpp> #include <boost/geometry/core/radius.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
#include <boost/geometry/util/math.hpp> #include <boost/geometry/util/math.hpp>
#include <boost/geometry/formulas/differential_quantities.hpp> #include <boost/geometry/formulas/differential_quantities.hpp>
@ -160,7 +159,7 @@ public:
&& geometry::math::abs(lambda) < pi && geometry::math::abs(lambda) < pi
&& counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness && counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness
if ( BOOST_GEOMETRY_CONDITION(EnableDistance) ) if BOOST_GEOMETRY_CONSTEXPR (EnableDistance)
{ {
// Some types cannot divide by doubles // Some types cannot divide by doubles
CT const c6 = 6; CT const c6 = 6;
@ -188,20 +187,20 @@ public:
result.distance = radius_b * A * (sigma - delta_sigma); // (19) 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) 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) 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<CT, EnableReducedLength, EnableGeodesicScale, 2> quantities; typedef differential_quantities<CT, EnableReducedLength, EnableGeodesicScale, 2> quantities;
quantities::apply(lon1, lat1, lon2, lat2, quantities::apply(lon1, lat1, lon2, lat2,

View File

@ -21,6 +21,8 @@
#include <boost/geometry/core/static_assert.hpp> #include <boost/geometry/core/static_assert.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/index/detail/varray.hpp> #include <boost/geometry/index/detail/varray.hpp>
#include <boost/geometry/index/detail/rtree/node/concept.hpp> #include <boost/geometry/index/detail/rtree/node/concept.hpp>
@ -36,14 +38,14 @@
#include <boost/geometry/index/detail/rtree/node/variant_dynamic.hpp> #include <boost/geometry/index/detail/rtree/node/variant_dynamic.hpp>
#include <boost/geometry/index/detail/rtree/node/variant_static.hpp> #include <boost/geometry/index/detail/rtree/node/variant_static.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/index/detail/rtree/visitors/destroy.hpp> #include <boost/geometry/index/detail/rtree/visitors/destroy.hpp>
#include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp> #include <boost/geometry/index/detail/rtree/visitors/is_leaf.hpp>
#include <boost/geometry/index/detail/algorithms/bounds.hpp> #include <boost/geometry/index/detail/algorithms/bounds.hpp>
#include <boost/geometry/index/detail/is_bounding_geometry.hpp> #include <boost/geometry/index/detail/is_bounding_geometry.hpp>
#include <boost/geometry/util/constexpr.hpp>
namespace boost { namespace geometry { namespace index { namespace boost { namespace geometry { namespace index {
namespace detail { namespace rtree { namespace detail { namespace rtree {
@ -92,11 +94,10 @@ inline Box values_box(FwdIter first, FwdIter last, Translator const& tr,
Box result = elements_box<Box>(first, last, tr, strategy); Box result = elements_box<Box>(first, last, tr, strategy);
#ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON #ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
if (BOOST_GEOMETRY_CONDITION(( if BOOST_GEOMETRY_CONSTEXPR (! index::detail::is_bounding_geometry
! is_bounding_geometry <
< typename indexable_type<Translator>::type
typename indexable_type<Translator>::type >::value)
>::value)))
{ {
geometry::detail::expand_by_epsilon(result); geometry::detail::expand_by_epsilon(result);
} }

View File

@ -31,6 +31,8 @@
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp> #include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/index/parameters.hpp> #include <boost/geometry/index/parameters.hpp>
#include <boost/geometry/util/constexpr.hpp>
namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree {
namespace pack_utils { namespace pack_utils {
@ -343,11 +345,10 @@ private:
// NOTE: this is done only if the Indexable is a different kind of Geometry // 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 // than the bounds (only Box for now). Spatial predicates are checked
// the same way for Geometry of the same kind. // the same way for Geometry of the same kind.
if ( BOOST_GEOMETRY_CONDITION(( if BOOST_GEOMETRY_CONSTEXPR (! index::detail::is_bounding_geometry
! index::detail::is_bounding_geometry <
< typename indexable_type<translator_type>::type
typename indexable_type<translator_type>::type >::value)
>::value )) )
{ {
elements_box.expand_by_epsilon(); elements_box.expand_by_epsilon();
} }

View File

@ -30,7 +30,7 @@
#include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp> #include <boost/geometry/index/detail/rtree/node/subtree_destroyer.hpp>
#include <boost/geometry/index/detail/rtree/options.hpp> #include <boost/geometry/index/detail/rtree/options.hpp>
#include <boost/geometry/util/condition.hpp> #include <boost/geometry/util/constexpr.hpp>
namespace boost { namespace geometry { namespace index { namespace boost { namespace geometry { namespace index {
@ -328,12 +328,11 @@ protected:
// Enlarge it in case if it's not bounding geometry type. // Enlarge it in case if it's not bounding geometry type.
// It's because Points and Segments are compared WRT machine epsilon // It's because Points and Segments are compared WRT machine epsilon
// This ensures that leafs bounds correspond to the stored elements // This ensures that leafs bounds correspond to the stored elements
if (BOOST_GEOMETRY_CONDITION(( if BOOST_GEOMETRY_CONSTEXPR ((std::is_same<Element, value_type>::value)
std::is_same<Element, value_type>::value && ! index::detail::is_bounding_geometry
&& ! index::detail::is_bounding_geometry <
< typename indexable_type<translator_type>::type
typename indexable_type<translator_type>::type >::value)
>::value )) )
{ {
geometry::detail::expand_by_epsilon(m_element_bounds); geometry::detail::expand_by_epsilon(m_element_bounds);
} }
@ -425,16 +424,16 @@ protected:
// Enlarge bounds of a leaf node. // Enlarge bounds of a leaf node.
// It's because Points and Segments are compared WRT machine epsilon // It's because Points and Segments are compared WRT machine epsilon
// This ensures that leafs' bounds correspond to the stored elements. // This ensures that leafs' bounds correspond to the stored elements.
if (BOOST_GEOMETRY_CONDITION(( if BOOST_GEOMETRY_CONSTEXPR ((std::is_same<Node, leaf>::value)
std::is_same<Node, leaf>::value && ! index::detail::is_bounding_geometry
&& ! index::detail::is_bounding_geometry <
< typename indexable_type<translator_type>::type
typename indexable_type<translator_type>::type >::value)
>::value )))
{ {
geometry::detail::expand_by_epsilon(n_box); geometry::detail::expand_by_epsilon(n_box);
geometry::detail::expand_by_epsilon(additional_nodes[0].first); geometry::detail::expand_by_epsilon(additional_nodes[0].first);
} }
#endif #endif
// node is not the root - just add the new node // node is not the root - just add the new node

View File

@ -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 <boost/geometry/core/tags.hpp>
#include <boost/geometry/domains/gis/io/wkt/write.hpp>
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in the future.")
#endif // BOOST_GEOMETRY_IO_WKT_MULTI_HPP

View File

@ -20,6 +20,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_APPEND_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/append.hpp> #include <boost/geometry/algorithms/append.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_AREA_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_AREA_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_AREA_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_AREA_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/area.hpp> #include <boost/geometry/algorithms/area.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CENTROID_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CENTROID_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_CENTROID_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_CENTROID_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/centroid.hpp> #include <boost/geometry/algorithms/centroid.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CLEAR_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CLEAR_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_CLEAR_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_CLEAR_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/clear.hpp> #include <boost/geometry/algorithms/clear.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CONVERT_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CONVERT_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_CONVERT_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_CONVERT_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/convert.hpp> #include <boost/geometry/algorithms/convert.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CORRECT_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CORRECT_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_CORRECT_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_CORRECT_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/correct.hpp> #include <boost/geometry/algorithms/correct.hpp>

View File

@ -20,6 +20,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/covered_by.hpp> #include <boost/geometry/algorithms/covered_by.hpp>

View File

@ -12,6 +12,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_EXTREME_POINTS_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_EXTREME_POINTS_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_EXTREME_POINTS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_EXTREME_POINTS_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/detail/extreme_points.hpp> #include <boost/geometry/algorithms/detail/extreme_points.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_FOR_EACH_RANGE_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/detail/for_each_range.hpp> #include <boost/geometry/algorithms/detail/for_each_range.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/detail/multi_modify.hpp> #include <boost/geometry/algorithms/detail/multi_modify.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MODIFY_WITH_PREDICATE_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/detail/multi_modify_with_predicate.hpp> #include <boost/geometry/algorithms/detail/multi_modify_with_predicate.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MULTI_SUM_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MULTI_SUM_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MULTI_SUM_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_MULTI_SUM_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/detail/multi_sum.hpp> #include <boost/geometry/algorithms/detail/multi_sum.hpp>

View File

@ -12,6 +12,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENT_POINT_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp> #include <boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp>

View File

@ -9,6 +9,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_COPY_SEGMENTS_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp> #include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>

View File

@ -9,6 +9,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_GET_TURNS_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp> #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>

View File

@ -9,6 +9,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_OVERLAY_SELF_TURN_POINTS_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp> #include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>

View File

@ -17,6 +17,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_POINT_ON_BORDER_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/detail/point_on_border.hpp> #include <boost/geometry/algorithms/detail/point_on_border.hpp>

View File

@ -19,6 +19,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_RANGE_BY_SECTION_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/detail/sections/range_by_section.hpp> #include <boost/geometry/algorithms/detail/sections/range_by_section.hpp>

View File

@ -17,6 +17,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DETAIL_SECTIONS_SECTIONALIZE_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/detail/sections/sectionalize.hpp> #include <boost/geometry/algorithms/detail/sections/sectionalize.hpp>

View File

@ -16,6 +16,9 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DISJOINT_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DISJOINT_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_DISJOINT_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_DISJOINT_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/disjoint.hpp> #include <boost/geometry/algorithms/disjoint.hpp>
#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DISJOINT_HPP #endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_DISJOINT_HPP

View File

@ -19,8 +19,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DISTANCE_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_DISTANCE_HPP
#define 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) #include <boost/config/pragma_message.hpp>
// it is used for backward compatinility and may be removed in the future BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/distance.hpp> #include <boost/geometry/algorithms/distance.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_ENVELOPE_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_ENVELOPE_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_ENVELOPE_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_ENVELOPE_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/envelope.hpp> #include <boost/geometry/algorithms/envelope.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_EQUALS_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_EQUALS_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_EQUALS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_EQUALS_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/equals.hpp> #include <boost/geometry/algorithms/equals.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_FOR_EACH_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_FOR_EACH_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_FOR_EACH_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_FOR_EACH_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/for_each.hpp> #include <boost/geometry/algorithms/for_each.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_INTERSECTION_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/intersection.hpp> #include <boost/geometry/algorithms/intersection.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_LENGTH_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_LENGTH_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_LENGTH_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_LENGTH_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/length.hpp> #include <boost/geometry/algorithms/length.hpp>

View File

@ -15,6 +15,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_GEOMETRIES_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_GEOMETRIES_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_GEOMETRIES_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_GEOMETRIES_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/num_geometries.hpp> #include <boost/geometry/algorithms/num_geometries.hpp>

View File

@ -19,6 +19,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_INTERIOR_RINGS_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/num_interior_rings.hpp> #include <boost/geometry/algorithms/num_interior_rings.hpp>

View File

@ -20,6 +20,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_NUM_POINTS_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/num_points.hpp> #include <boost/geometry/algorithms/num_points.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_PERIMETER_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_PERIMETER_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_PERIMETER_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_PERIMETER_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/perimeter.hpp> #include <boost/geometry/algorithms/perimeter.hpp>

View File

@ -12,6 +12,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_REMOVE_SPIKES_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_REMOVE_SPIKES_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_REMOVE_SPIKES_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_REMOVE_SPIKES_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/remove_spikes.hpp> #include <boost/geometry/algorithms/remove_spikes.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_REVERSE_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_REVERSE_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_REVERSE_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_REVERSE_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/reverse.hpp> #include <boost/geometry/algorithms/reverse.hpp>

View File

@ -14,6 +14,8 @@
#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_SIMPLIFY_HPP #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_SIMPLIFY_HPP
#define BOOST_GEOMETRY_MULTI_ALGORITHMS_SIMPLIFY_HPP #define BOOST_GEOMETRY_MULTI_ALGORITHMS_SIMPLIFY_HPP
#include <boost/config/pragma_message.hpp>
BOOST_PRAGMA_MESSAGE("This include file is deprecated and will be removed in Boost 1.86")
#include <boost/geometry/algorithms/simplify.hpp> #include <boost/geometry/algorithms/simplify.hpp>

Some files were not shown because too many files have changed in this diff Show More