Merge pull request #1162 from vissarion/fix/convex_hull_compare_strategies

Fix convex hull issue by passing compare strategies
This commit is contained in:
Vissarion Fisikopoulos 2023-07-28 11:38:21 +03:00 committed by GitHub
commit efec40628b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 483 additions and 180 deletions

View File

@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014-2021. // This file was modified by Oracle on 2014-2023.
// Modifications copyright (c) 2014-2021 Oracle and/or its affiliates. // Modifications 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
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -190,8 +190,7 @@ private:
point_type most_left, most_right; point_type most_left, most_right;
// TODO: User-defined CS-specific less-compare geometry::less_exact<point_type, -1, Strategy> less;
geometry::less<point_type> less;
detail::convex_hull::get_extremes(in_proxy, most_left, most_right, less); detail::convex_hull::get_extremes(in_proxy, most_left, most_right, less);

View File

@ -2,7 +2,7 @@
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2014-2021, 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
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@ -63,16 +63,16 @@ namespace detail { namespace disjoint
class multipoint_multipoint class multipoint_multipoint
{ {
private: private:
template <typename Iterator, typename CSTag> template <typename Iterator, typename Strategy>
class unary_not_disjoint_predicate class unary_not_disjoint_predicate
: geometry::less<void, -1, CSTag> : geometry::less<void, -1, Strategy>
{ {
private: private:
typedef geometry::less<void, -1, CSTag> base_type; using less_type = geometry::less<void, -1, Strategy>;
public: public:
unary_not_disjoint_predicate(Iterator first, Iterator last) unary_not_disjoint_predicate(Iterator first, Iterator last)
: base_type(), m_first(first), m_last(last) : less_type(), m_first(first), m_last(last)
{} {}
template <typename Point> template <typename Point>
@ -81,7 +81,7 @@ private:
return std::binary_search(m_first, return std::binary_search(m_first,
m_last, m_last,
point, point,
static_cast<base_type const&>(*this)); static_cast<less_type const&>(*this));
} }
private: private:
@ -96,8 +96,7 @@ public:
{ {
BOOST_GEOMETRY_ASSERT( boost::size(multipoint1) <= boost::size(multipoint2) ); BOOST_GEOMETRY_ASSERT( boost::size(multipoint1) <= boost::size(multipoint2) );
using cs_tag = typename Strategy::cs_tag; using less_type = geometry::less<void, -1, Strategy>;
using less_type = geometry::less<void, -1, cs_tag>;
using point1_type = typename boost::range_value<MultiPoint1>::type; using point1_type = typename boost::range_value<MultiPoint1>::type;
std::vector<point1_type> points1(boost::begin(multipoint1), std::vector<point1_type> points1(boost::begin(multipoint1),
@ -108,7 +107,7 @@ public:
using predicate_type = unary_not_disjoint_predicate using predicate_type = unary_not_disjoint_predicate
< <
typename std::vector<point1_type>::const_iterator, typename std::vector<point1_type>::const_iterator,
cs_tag Strategy
>; >;
return none_of(boost::begin(multipoint2), return none_of(boost::begin(multipoint2),

View File

@ -1,6 +1,6 @@
// 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) 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
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@ -658,7 +658,7 @@ public:
BoxPoint const& bottom_right, BoxPoint const& bottom_right,
Strategies const& strategies) Strategies const& strategies)
{ {
BOOST_GEOMETRY_ASSERT( (geometry::less<SegmentPoint, -1, typename Strategies::cs_tag>()(p0, p1)) BOOST_GEOMETRY_ASSERT( (geometry::less<SegmentPoint, -1, Strategies>()(p0, p1))
|| geometry::has_nan_coordinate(p0) || geometry::has_nan_coordinate(p0)
|| geometry::has_nan_coordinate(p1) ); || geometry::has_nan_coordinate(p1) );
@ -753,7 +753,7 @@ public:
bottom_left, bottom_right, bottom_left, bottom_right,
top_left, top_right); top_left, top_right);
typedef geometry::less<segment_point, -1, typename Strategies::cs_tag> less_type; typedef geometry::less<segment_point, -1, Strategies> less_type;
if (less_type()(p[0], p[1])) if (less_type()(p[0], p[1]))
{ {
return segment_to_box_2D return segment_to_box_2D

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) 2014-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by 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
@ -44,12 +45,11 @@ struct is_simple_multipoint
template <typename Strategy> template <typename Strategy>
static inline bool apply(MultiPoint const& multipoint, Strategy const& strategy) static inline bool apply(MultiPoint const& multipoint, Strategy const& strategy)
{ {
typedef typename Strategy::cs_tag cs_tag;
typedef geometry::less typedef geometry::less
< <
typename point_type<MultiPoint>::type, typename point_type<MultiPoint>::type,
-1, -1,
cs_tag Strategy
> less_type; > less_type;
if (boost::empty(multipoint)) if (boost::empty(multipoint))

View File

@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, 2018, 2019, 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 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
@ -32,7 +33,7 @@ namespace detail { namespace is_valid
{ {
template <typename TurnPoint, typename CSTag> template <typename TurnPoint, typename Strategy>
class complement_graph_vertex class complement_graph_vertex
{ {
public: public:
@ -55,7 +56,7 @@ public:
{ {
return geometry::less return geometry::less
< <
TurnPoint, -1, CSTag TurnPoint, -1, Strategy
>()(*m_turn_point, *other.m_turn_point); >()(*m_turn_point, *other.m_turn_point);
} }
if ( m_turn_point == NULL && other.m_turn_point == NULL ) if ( m_turn_point == NULL && other.m_turn_point == NULL )
@ -77,11 +78,11 @@ private:
template <typename TurnPoint, typename CSTag> template <typename TurnPoint, typename Strategy>
class complement_graph class complement_graph
{ {
private: private:
typedef complement_graph_vertex<TurnPoint, CSTag> vertex; typedef complement_graph_vertex<TurnPoint, Strategy> vertex;
typedef std::set<vertex> vertex_container; typedef std::set<vertex> vertex_container;
public: public:
@ -224,9 +225,10 @@ public:
} }
#ifdef BOOST_GEOMETRY_TEST_DEBUG #ifdef BOOST_GEOMETRY_TEST_DEBUG
template <typename OStream, typename TP> template <typename OutputStream>
friend inline friend inline
void debug_print_complement_graph(OStream&, complement_graph<TP> const&); void debug_print_complement_graph(OutputStream&,
complement_graph<TurnPoint, Strategy> const&);
#endif // BOOST_GEOMETRY_TEST_DEBUG #endif // BOOST_GEOMETRY_TEST_DEBUG
private: private:

View File

@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014, 2018, 2019, 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 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
@ -25,12 +26,12 @@ namespace detail { namespace is_valid
#ifdef BOOST_GEOMETRY_TEST_DEBUG #ifdef BOOST_GEOMETRY_TEST_DEBUG
template <typename OutputStream, typename TurnPoint, typename CSTag> template <typename OutputStream, typename TurnPoint, typename Strategy>
inline void inline void
debug_print_complement_graph(OutputStream& os, debug_print_complement_graph(OutputStream& os,
complement_graph<TurnPoint, CSTag> const& graph) complement_graph<TurnPoint, Strategy> const& graph)
{ {
typedef typename complement_graph<TurnPoint>::vertex_handle vertex_handle; typedef typename complement_graph<TurnPoint, Strategy>::vertex_handle vertex_handle;
os << "num rings: " << graph.m_num_rings << std::endl; os << "num rings: " << graph.m_num_rings << std::endl;
os << "vertex ids: {"; os << "vertex ids: {";
@ -47,7 +48,7 @@ debug_print_complement_graph(OutputStream& os,
os << "neighbors of " << it->id() << ": {"; os << "neighbors of " << it->id() << ": {";
for (typename complement_graph for (typename complement_graph
< <
TurnPoint TurnPoint, Strategy
>::neighbor_container::const_iterator >::neighbor_container::const_iterator
nit = graph.m_neighbors[it->id()].begin(); nit = graph.m_neighbors[it->id()].begin();
nit != graph.m_neighbors[it->id()].end(); ++nit) nit != graph.m_neighbors[it->id()].end(); ++nit)
@ -58,9 +59,9 @@ debug_print_complement_graph(OutputStream& os,
} }
} }
#else #else
template <typename OutputStream, typename TurnPoint, typename CSTag> template <typename OutputStream, typename TurnPoint, typename Strategy>
inline void debug_print_complement_graph(OutputStream&, inline void debug_print_complement_graph(OutputStream&,
complement_graph<TurnPoint, CSTag> const&) complement_graph<TurnPoint, Strategy> const&)
{ {
} }
#endif #endif

View File

@ -2,7 +2,7 @@
// Copyright (c) 2017-2023 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2017-2023 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2014-2021, 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
// 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
@ -404,7 +404,7 @@ protected:
typedef complement_graph typedef complement_graph
< <
typename turn_type::point_type, typename turn_type::point_type,
typename Strategy::cs_tag Strategy
> graph; > graph;
graph g(geometry::num_interior_rings(polygon) + 1); graph g(geometry::num_interior_rings(polygon) + 1);

View File

@ -2,7 +2,9 @@
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2014-2020, 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 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
@ -257,7 +259,7 @@ struct multipoint_multipoint_point
OutputIterator oit, OutputIterator oit,
Strategy const& strategy) Strategy const& strategy)
{ {
typedef geometry::less<void, -1, typename Strategy::cs_tag> less_type; typedef geometry::less<void, -1, Strategy> less_type;
if (BOOST_GEOMETRY_CONDITION(OverlayType != overlay_difference) if (BOOST_GEOMETRY_CONDITION(OverlayType != overlay_difference)
&& boost::size(multipoint1) > boost::size(multipoint2)) && boost::size(multipoint1) > boost::size(multipoint2))

View File

@ -1,7 +1,8 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2022 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 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,
@ -21,6 +22,10 @@
#include <boost/geometry/policies/compare.hpp> #include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/strategies/relate/cartesian.hpp>
#include <boost/geometry/strategies/relate/geographic.hpp>
#include <boost/geometry/strategies/relate/spherical.hpp>
#include <boost/geometry/util/has_nan_coordinate.hpp> #include <boost/geometry/util/has_nan_coordinate.hpp>
#include <boost/geometry/util/range.hpp> #include <boost/geometry/util/range.hpp>
@ -157,7 +162,7 @@ public:
template <typename Point> template <typename Point>
bool is_endpoint_boundary(Point const& pt) const bool is_endpoint_boundary(Point const& pt) const
{ {
using less_type = geometry::less<mutable_point_type, -1, typename Strategy::cs_tag>; using less_type = geometry::less<mutable_point_type, -1, Strategy>;
auto const multi_count = boost::size(m_geometry); auto const multi_count = boost::size(m_geometry);

View File

@ -1,7 +1,8 @@
// Boost.Geometry // Boost.Geometry
// Copyright (c) 2017-2022 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 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,
@ -134,7 +135,7 @@ struct multi_point_geometry_eb<Geometry, multi_linestring_tag>
template <typename Point, typename Strategy> template <typename Point, typename Strategy>
bool apply(Point const& boundary_point, Strategy const&) bool apply(Point const& boundary_point, Strategy const&)
{ {
typedef geometry::less<void, -1, typename Strategy::cs_tag> less_type; typedef geometry::less<void, -1, Strategy> less_type;
if (! std::binary_search(m_points.begin(), m_points.end(), if (! std::binary_search(m_points.begin(), m_points.end(),
boundary_point, less_type()) ) boundary_point, less_type()) )
@ -158,7 +159,7 @@ struct multi_point_geometry_eb<Geometry, multi_linestring_tag>
{ {
typedef typename boost::range_value<MultiPoint>::type point_type; typedef typename boost::range_value<MultiPoint>::type point_type;
typedef std::vector<point_type> points_type; typedef std::vector<point_type> points_type;
typedef geometry::less<void, -1, typename Strategy::cs_tag> less_type; typedef geometry::less<void, -1, Strategy> less_type;
points_type points(boost::begin(multi_point), boost::end(multi_point)); points_type points(boost::begin(multi_point), boost::end(multi_point));
std::sort(points.begin(), points.end(), less_type()); std::sort(points.begin(), points.end(), less_type());

View File

@ -3,8 +3,9 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013-2022. // This file was modified by Oracle on 2013-2022.
// Modifications copyright (c) 2013-2022, 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 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,
@ -67,7 +68,7 @@ std::pair<bool, bool> point_multipoint_check(Point const& point,
// point_in_geometry could be used here but why iterate over MultiPoint twice? // point_in_geometry could be used here but why iterate over MultiPoint twice?
// we must search for a point in the exterior because all points in MultiPoint can be equal // we must search for a point in the exterior because all points in MultiPoint can be equal
auto const end = boost::end(multi_point); auto const end = boost::end(multi_point);
for (auto it = boost::begin(multi_point); it != end; ++it) for (auto it = boost::begin(multi_point); it != end; ++it)
{ {
@ -153,8 +154,6 @@ struct multipoint_multipoint
Result & result, Result & result,
Strategy const& /*strategy*/) Strategy const& /*strategy*/)
{ {
typedef typename Strategy::cs_tag cs_tag;
{ {
// TODO: throw on empty input? // TODO: throw on empty input?
bool empty1 = boost::empty(multi_point1); bool empty1 = boost::empty(multi_point1);
@ -178,17 +177,17 @@ struct multipoint_multipoint
// The geometry containing smaller number of points will be analysed first // The geometry containing smaller number of points will be analysed first
if ( boost::size(multi_point1) < boost::size(multi_point2) ) if ( boost::size(multi_point1) < boost::size(multi_point2) )
{ {
search_both<false, cs_tag>(multi_point1, multi_point2, result); search_both<false, Strategy>(multi_point1, multi_point2, result);
} }
else else
{ {
search_both<true, cs_tag>(multi_point2, multi_point1, result); search_both<true, Strategy>(multi_point2, multi_point1, result);
} }
update<exterior, exterior, result_dimension<MultiPoint1>::value>(result); update<exterior, exterior, result_dimension<MultiPoint1>::value>(result);
} }
template <bool Transpose, typename CSTag, typename MPt1, typename MPt2, typename Result> template <bool Transpose, typename Strategy, typename MPt1, typename MPt2, typename Result>
static inline void search_both(MPt1 const& first_sorted_mpt, MPt2 const& first_iterated_mpt, static inline void search_both(MPt1 const& first_sorted_mpt, MPt2 const& first_iterated_mpt,
Result & result) Result & result)
{ {
@ -197,7 +196,7 @@ 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, CSTag>(first_sorted_mpt, first_iterated_mpt, result); bool is_disjoint = search<Transpose, Strategy>(first_sorted_mpt, first_iterated_mpt, result);
if ( BOOST_GEOMETRY_CONDITION(is_disjoint || result.interrupt) ) if ( BOOST_GEOMETRY_CONDITION(is_disjoint || result.interrupt) )
return; return;
@ -208,12 +207,12 @@ struct multipoint_multipoint
|| relate::may_update<exterior, interior, '0'>(result) ) || relate::may_update<exterior, interior, '0'>(result) )
{ {
// MlogM + NlogM // MlogM + NlogM
search<! Transpose, CSTag>(first_iterated_mpt, first_sorted_mpt, result); search<! Transpose, Strategy>(first_iterated_mpt, first_sorted_mpt, result);
} }
} }
template <bool Transpose, template <bool Transpose,
typename CSTag, typename Strategy,
typename SortedMultiPoint, typename SortedMultiPoint,
typename IteratedMultiPoint, typename IteratedMultiPoint,
typename Result> typename Result>
@ -223,7 +222,7 @@ struct multipoint_multipoint
{ {
// sort points from the 1 MPt // sort points from the 1 MPt
typedef typename geometry::point_type<SortedMultiPoint>::type point_type; typedef typename geometry::point_type<SortedMultiPoint>::type point_type;
typedef geometry::less<void, -1, CSTag> less_type; typedef geometry::less<void, -1, Strategy> less_type;
std::vector<point_type> points(boost::begin(sorted_mpt), boost::end(sorted_mpt)); std::vector<point_type> points(boost::begin(sorted_mpt), boost::end(sorted_mpt));

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) 2014-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // 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,
@ -170,7 +171,7 @@ struct topology_check<MultiLinestring, Strategy, multi_linestring_tag>
} }
private: private:
typedef geometry::less<void, -1, typename Strategy::cs_tag> less_type; typedef geometry::less<void, -1, Strategy> less_type;
void init() const void init() const
{ {

View File

@ -2,7 +2,9 @@
// Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2017-2020, Oracle and/or its affiliates. // Copyright (c) 2017-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // 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,
@ -80,8 +82,7 @@ struct multi_point_multi_point
Strategy const& /*strategy*/) Strategy const& /*strategy*/)
{ {
typedef typename boost::range_value<MultiPoint2>::type point2_type; typedef typename boost::range_value<MultiPoint2>::type point2_type;
typedef typename Strategy::cs_tag cs_tag; typedef geometry::less<void, -1, Strategy> less_type;
typedef geometry::less<void, -1, cs_tag> less_type;
less_type const less = less_type(); less_type const less = less_type();

View File

@ -172,7 +172,7 @@ inline void merge(RandomIt const first, RandomIt const last, MultiGeometry& out,
auto const less = [](auto const& l, auto const& r) auto const less = [](auto const& l, auto const& r)
{ {
return geometry::less<void, -1, typename Strategy::cs_tag>()(l.first, r.first); return geometry::less<void, -1, Strategy>()(l.first, r.first);
}; };
std::vector<merge_data<RandomIt>> stack_in; std::vector<merge_data<RandomIt>> stack_in;

View File

@ -2,9 +2,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017-2022. // This file was modified by Oracle on 2017-2023.
// Modifications copyright (c) 2017-2022, Oracle and/or its affiliates. // Modifications copyright (c) 2017-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // 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,91 +38,243 @@ namespace boost { namespace geometry
on equal x-es then on y, etc. on equal x-es then on y, etc.
If a dimension is specified, only that dimension is considered If a dimension is specified, only that dimension is considered
*/ */
template template
< <
typename Point = void, typename Point = void,
int Dimension = -1, int Dimension = -1,
typename CSTag = void typename StrategyOrTag = void
> >
struct less struct less_exact
{ {
typedef Point first_argument_type; using first_argument_type = Point;
typedef Point second_argument_type; using second_argument_type = Point;
typedef bool result_type; using result_type = bool;
inline bool operator()(Point const& left, Point const& right) const inline bool operator()(Point const& left, Point const& right) const
{ {
typedef typename strategy::compare::services::default_strategy return StrategyOrTag::template compare_type
< <
strategy::compare::less, strategy::compare::less,
strategy::compare::equals_exact
>::apply(left, right);
}
};
template
<
typename Point = void,
int Dimension = -1,
typename StrategyOrTag = void
>
struct less
{
using first_argument_type = Point;
using second_argument_type = Point;
using result_type = bool;
inline bool operator()(Point const& left, Point const& right) const
{
return StrategyOrTag::template compare_type
<
strategy::compare::less,
strategy::compare::equals_epsilon
>::apply(left, right);
}
};
template <typename Point, int Dimension>
struct less<Point, Dimension, void>
{
using first_argument_type = Point;
using second_argument_type = Point;
using result_type = bool;
inline bool operator()(Point const& left, Point const& right) const
{
using strategy_type = typename strategy::compare::services::default_strategy
<
strategy::compare::less,
strategy::compare::equals_epsilon,
Point, Point, Point, Point,
Dimension, Dimension
CSTag, CSTag >::type;
>::type strategy_type;
return strategy_type::apply(left, right); return strategy_type::apply(left, right);
} }
}; };
template <int Dimension, typename CSTag> template <int Dimension, typename Strategy>
struct less<void, Dimension, CSTag> struct less<void, Dimension, Strategy>
{ {
typedef bool result_type; using result_type = bool;
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
inline bool operator()(Point1 const& left, Point2 const& right) const inline bool operator()(Point1 const& left, Point2 const& right) const
{ {
typedef typename strategy::compare::services::default_strategy return Strategy::template compare_type
< <
strategy::compare::less, strategy::compare::less,
Point1, Point2, strategy::compare::equals_epsilon
>::apply(left, right);
}
};
// for backward compatibility
template <typename Point, int Dimension>
struct less<Point, Dimension, boost::geometry::cartesian_tag>
{
using first_argument_type = Point;
using second_argument_type = Point;
using result_type = bool;
inline bool operator()(Point const& left, Point const& right) const
{
using strategy_type = typename strategy::compare::services::default_strategy
<
strategy::compare::less,
strategy::compare::equals_epsilon,
Point, Point,
Dimension, Dimension,
CSTag, CSTag boost::geometry::cartesian_tag, boost::geometry::cartesian_tag
>::type strategy_type; >::type;
return strategy_type::apply(left, right); return strategy_type::apply(left, right);
} }
}; };
template <typename Point, int Dimension> template <typename Point, int Dimension>
struct less<Point, Dimension, void> struct less<Point, Dimension, boost::geometry::spherical_tag>
{ {
typedef Point first_argument_type; using first_argument_type = Point;
typedef Point second_argument_type; using second_argument_type = Point;
typedef bool result_type; using result_type = bool;
inline bool operator()(Point const& left, Point const& right) const inline bool operator()(Point const& left, Point const& right) const
{ {
typedef typename strategy::compare::services::default_strategy using strategy_type = typename strategy::compare::services::default_strategy
< <
strategy::compare::less, strategy::compare::less,
strategy::compare::equals_epsilon,
Point, Point, Point, Point,
Dimension Dimension,
>::type strategy_type; boost::geometry::spherical_tag, boost::geometry::spherical_tag
>::type;
return strategy_type::apply(left, right);
}
};
template <typename Point, int Dimension>
struct less<Point, Dimension, boost::geometry::geographic_tag>
{
using first_argument_type = Point;
using second_argument_type = Point;
using result_type = bool;
inline bool operator()(Point const& left, Point const& right) const
{
using strategy_type = typename strategy::compare::services::default_strategy
<
strategy::compare::less,
strategy::compare::equals_epsilon,
Point, Point,
Dimension,
boost::geometry::geographic_tag, boost::geometry::geographic_tag
>::type;
return strategy_type::apply(left, right); return strategy_type::apply(left, right);
} }
}; };
template <int Dimension> template <int Dimension>
struct less<void, Dimension, void> struct less<void, Dimension, boost::geometry::cartesian_tag>
{ {
typedef bool result_type; using result_type = bool;
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
inline bool operator()(Point1 const& left, Point2 const& right) const inline bool operator()(Point1 const& left, Point2 const& right) const
{ {
typedef typename strategy::compare::services::default_strategy using strategy_type = typename strategy::compare::services::default_strategy
< <
strategy::compare::less, strategy::compare::less,
strategy::compare::equals_epsilon,
Point1, Point2, Point1, Point2,
Dimension Dimension,
>::type strategy_type; boost::geometry::cartesian_tag, boost::geometry::cartesian_tag
>::type;
return strategy_type::apply(left, right); return strategy_type::apply(left, right);
} }
}; };
template <int Dimension>
struct less<void, Dimension, boost::geometry::spherical_tag>
{
using result_type = bool;
template <typename Point1, typename Point2>
inline bool operator()(Point1 const& left, Point2 const& right) const
{
using strategy_type = typename strategy::compare::services::default_strategy
<
strategy::compare::less,
strategy::compare::equals_epsilon,
Point1, Point2,
Dimension,
boost::geometry::spherical_tag, boost::geometry::spherical_tag
>::type;
return strategy_type::apply(left, right);
}
};
template <int Dimension>
struct less<void, Dimension, boost::geometry::geographic_tag>
{
using result_type = bool;
template <typename Point1, typename Point2>
inline bool operator()(Point1 const& left, Point2 const& right) const
{
using strategy_type = typename strategy::compare::services::default_strategy
<
strategy::compare::less,
strategy::compare::equals_epsilon,
Point1, Point2,
Dimension,
boost::geometry::geographic_tag, boost::geometry::geographic_tag
>::type;
return strategy_type::apply(left, right);
}
};
template <int Dimension>
struct less<void, Dimension, void>
{
using result_type = bool;
template <typename Point1, typename Point2>
inline bool operator()(Point1 const& left, Point2 const& right) const
{
using strategy_type = typename strategy::compare::services::default_strategy
<
strategy::compare::less,
strategy::compare::equals_epsilon,
Point1, Point2,
Dimension
>::type;
return strategy_type::apply(left, right);
}
};
/*! /*!
\brief Greater functor \brief Greater functor
@ -137,19 +290,20 @@ template
> >
struct greater struct greater
{ {
typedef Point first_argument_type; using first_argument_type = Point;
typedef Point second_argument_type; using second_argument_type = Point;
typedef bool result_type; using result_type = bool;
bool operator()(Point const& left, Point const& right) const bool operator()(Point const& left, Point const& right) const
{ {
typedef typename strategy::compare::services::default_strategy using strategy_type = typename strategy::compare::services::default_strategy
< <
strategy::compare::greater, strategy::compare::greater,
strategy::compare::equals_epsilon,
Point, Point, Point, Point,
Dimension, Dimension,
CSTag, CSTag CSTag, CSTag
>::type strategy_type; >::type;
return strategy_type::apply(left, right); return strategy_type::apply(left, right);
} }
@ -158,18 +312,19 @@ struct greater
template <int Dimension, typename CSTag> template <int Dimension, typename CSTag>
struct greater<void, Dimension, CSTag> struct greater<void, Dimension, CSTag>
{ {
typedef bool result_type; using result_type = bool;
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
bool operator()(Point1 const& left, Point2 const& right) const bool operator()(Point1 const& left, Point2 const& right) const
{ {
typedef typename strategy::compare::services::default_strategy using strategy_type = typename strategy::compare::services::default_strategy
< <
strategy::compare::greater, strategy::compare::greater,
strategy::compare::equals_epsilon,
Point1, Point2, Point1, Point2,
Dimension, Dimension,
CSTag, CSTag CSTag, CSTag
>::type strategy_type; >::type;
return strategy_type::apply(left, right); return strategy_type::apply(left, right);
} }
@ -178,18 +333,19 @@ struct greater<void, Dimension, CSTag>
template <typename Point, int Dimension> template <typename Point, int Dimension>
struct greater<Point, Dimension, void> struct greater<Point, Dimension, void>
{ {
typedef Point first_argument_type; using first_argument_type = Point;
typedef Point second_argument_type; using second_argument_type = Point;
typedef bool result_type; using result_type = bool;
bool operator()(Point const& left, Point const& right) const bool operator()(Point const& left, Point const& right) const
{ {
typedef typename strategy::compare::services::default_strategy using strategy_type = typename strategy::compare::services::default_strategy
< <
strategy::compare::greater, strategy::compare::greater,
strategy::compare::equals_epsilon,
Point, Point, Point, Point,
Dimension Dimension
>::type strategy_type; >::type;
return strategy_type::apply(left, right); return strategy_type::apply(left, right);
} }
@ -198,17 +354,18 @@ struct greater<Point, Dimension, void>
template <int Dimension> template <int Dimension>
struct greater<void, Dimension, void> struct greater<void, Dimension, void>
{ {
typedef bool result_type; using result_type = bool;
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
bool operator()(Point1 const& left, Point2 const& right) const bool operator()(Point1 const& left, Point2 const& right) const
{ {
typedef typename strategy::compare::services::default_strategy using strategy_type = typename strategy::compare::services::default_strategy
< <
strategy::compare::greater, strategy::compare::greater,
strategy::compare::equals_epsilon,
Point1, Point2, Point1, Point2,
Dimension Dimension
>::type strategy_type; >::type;
return strategy_type::apply(left, right); return strategy_type::apply(left, right);
} }
@ -231,19 +388,20 @@ template
> >
struct equal_to struct equal_to
{ {
typedef Point first_argument_type; using first_argument_type = Point;
typedef Point second_argument_type; using second_argument_type = Point;
typedef bool result_type; using result_type = bool;
bool operator()(Point const& left, Point const& right) const bool operator()(Point const& left, Point const& right) const
{ {
typedef typename strategy::compare::services::default_strategy using strategy_type = typename strategy::compare::services::default_strategy
< <
strategy::compare::equal_to, strategy::compare::equal_to,
strategy::compare::equals_epsilon,
Point, Point, Point, Point,
Dimension, Dimension,
CSTag, CSTag CSTag, CSTag
>::type strategy_type; >::type;
return strategy_type::apply(left, right); return strategy_type::apply(left, right);
} }
@ -252,18 +410,19 @@ struct equal_to
template <int Dimension, typename CSTag> template <int Dimension, typename CSTag>
struct equal_to<void, Dimension, CSTag> struct equal_to<void, Dimension, CSTag>
{ {
typedef bool result_type; using result_type = bool;
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
bool operator()(Point1 const& left, Point2 const& right) const bool operator()(Point1 const& left, Point2 const& right) const
{ {
typedef typename strategy::compare::services::default_strategy using strategy_type = typename strategy::compare::services::default_strategy
< <
strategy::compare::equal_to, strategy::compare::equal_to,
strategy::compare::equals_epsilon,
Point1, Point2, Point1, Point2,
Dimension, Dimension,
CSTag, CSTag CSTag, CSTag
>::type strategy_type; >::type;
return strategy_type::apply(left, right); return strategy_type::apply(left, right);
} }
@ -272,18 +431,19 @@ struct equal_to<void, Dimension, CSTag>
template <typename Point, int Dimension> template <typename Point, int Dimension>
struct equal_to<Point, Dimension, void> struct equal_to<Point, Dimension, void>
{ {
typedef Point first_argument_type; using first_argument_type = Point;
typedef Point second_argument_type; using second_argument_type = Point;
typedef bool result_type; using result_type = bool;
bool operator()(Point const& left, Point const& right) const bool operator()(Point const& left, Point const& right) const
{ {
typedef typename strategy::compare::services::default_strategy using strategy_type = typename strategy::compare::services::default_strategy
< <
strategy::compare::equal_to, strategy::compare::equal_to,
strategy::compare::equals_epsilon,
Point, Point, Point, Point,
Dimension Dimension
>::type strategy_type; >::type;
return strategy_type::apply(left, right); return strategy_type::apply(left, right);
} }
@ -292,17 +452,18 @@ struct equal_to<Point, Dimension, void>
template <int Dimension> template <int Dimension>
struct equal_to<void, Dimension, void> struct equal_to<void, Dimension, void>
{ {
typedef bool result_type; using result_type = bool;
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
bool operator()(Point1 const& left, Point2 const& right) const bool operator()(Point1 const& left, Point2 const& right) const
{ {
typedef typename strategy::compare::services::default_strategy using strategy_type = typename strategy::compare::services::default_strategy
< <
strategy::compare::equal_to, strategy::compare::equal_to,
strategy::compare::equals_epsilon,
Point1, Point2, Point1, Point2,
Dimension Dimension
>::type strategy_type; >::type;
return strategy_type::apply(left, right); return strategy_type::apply(left, right);
} }

View File

@ -4,8 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2017-2020. // This file was modified by Oracle on 2017-2023.
// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates. // Modifications copyright (c) 2017-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@ -68,6 +70,24 @@ struct equal_to
} }
}; };
struct equals_epsilon
{
template <typename T1, typename T2>
static inline bool apply(T1 const& l, T2 const& r)
{
return math::equals(l, r);
}
};
struct equals_exact
{
template <typename T1, typename T2>
static inline bool apply(T1 const& l, T2 const& r)
{
return l == r;
}
};
#ifndef DOXYGEN_NO_DETAIL #ifndef DOXYGEN_NO_DETAIL
namespace detail namespace detail
@ -77,6 +97,7 @@ namespace detail
template template
< <
typename ComparePolicy, typename ComparePolicy,
typename EqualsPolicy,
std::size_t Dimension, std::size_t Dimension,
std::size_t DimensionCount std::size_t DimensionCount
> >
@ -90,11 +111,12 @@ struct compare_loop
typename geometry::coordinate_type<Point2>::type const& typename geometry::coordinate_type<Point2>::type const&
cright = geometry::get<Dimension>(right); cright = geometry::get<Dimension>(right);
if (math::equals(cleft, cright)) if (EqualsPolicy::apply(cleft, cright))
{ {
return compare_loop return compare_loop
< <
ComparePolicy, ComparePolicy,
EqualsPolicy,
Dimension + 1, DimensionCount Dimension + 1, DimensionCount
>::apply(left, right); >::apply(left, right);
} }
@ -108,9 +130,10 @@ struct compare_loop
template template
< <
typename ComparePolicy, typename ComparePolicy,
typename EqualsPolicy,
std::size_t DimensionCount std::size_t DimensionCount
> >
struct compare_loop<ComparePolicy, DimensionCount, DimensionCount> struct compare_loop<ComparePolicy, EqualsPolicy, DimensionCount, DimensionCount>
{ {
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
static inline bool apply(Point1 const& , Point2 const& ) static inline bool apply(Point1 const& , Point2 const& )
@ -123,9 +146,10 @@ struct compare_loop<ComparePolicy, DimensionCount, DimensionCount>
template template
< <
typename EqualsPolicy,
std::size_t DimensionCount std::size_t DimensionCount
> >
struct compare_loop<strategy::compare::equal_to, DimensionCount, DimensionCount> struct compare_loop<strategy::compare::equal_to, EqualsPolicy, DimensionCount, DimensionCount>
{ {
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
static inline bool apply(Point1 const& , Point2 const& ) static inline bool apply(Point1 const& , Point2 const& )
@ -143,6 +167,7 @@ struct compare_loop<strategy::compare::equal_to, DimensionCount, DimensionCount>
template template
< <
typename ComparePolicy, typename ComparePolicy,
typename EqualsPolicy,
int Dimension = -1 int Dimension = -1
> >
struct cartesian struct cartesian
@ -152,7 +177,7 @@ struct cartesian
{ {
return compare::detail::compare_loop return compare::detail::compare_loop
< <
ComparePolicy, Dimension, Dimension + 1 ComparePolicy, EqualsPolicy, Dimension, Dimension + 1
>::apply(left, right); >::apply(left, right);
} }
}; };
@ -160,9 +185,10 @@ struct cartesian
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
template template
< <
typename ComparePolicy typename ComparePolicy,
typename EqualsPolicy
> >
struct cartesian<ComparePolicy, -1> struct cartesian<ComparePolicy, EqualsPolicy, -1>
{ {
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
static inline bool apply(Point1 const& left, Point2 const& right) static inline bool apply(Point1 const& left, Point2 const& right)
@ -170,6 +196,7 @@ struct cartesian<ComparePolicy, -1>
return compare::detail::compare_loop return compare::detail::compare_loop
< <
ComparePolicy, ComparePolicy,
EqualsPolicy,
0, 0,
((std::min)(geometry::dimension<Point1>::value, ((std::min)(geometry::dimension<Point1>::value,
geometry::dimension<Point2>::value)) geometry::dimension<Point2>::value))
@ -185,6 +212,7 @@ namespace services
template template
< <
typename ComparePolicy, typename ComparePolicy,
typename EqualsPolicy,
typename Point1, typename Point1,
typename Point2 = Point1, typename Point2 = Point1,
int Dimension = -1, int Dimension = -1,
@ -199,10 +227,17 @@ struct default_strategy
}; };
template <typename ComparePolicy, typename Point1, typename Point2, int Dimension> template
struct default_strategy<ComparePolicy, Point1, Point2, Dimension, cartesian_tag, cartesian_tag> <
typename ComparePolicy,
typename EqualsPolicy,
typename Point1,
typename Point2,
int Dimension
>
struct default_strategy<ComparePolicy, EqualsPolicy, Point1, Point2, Dimension, cartesian_tag, cartesian_tag>
{ {
typedef compare::cartesian<ComparePolicy, Dimension> type; typedef compare::cartesian<ComparePolicy, EqualsPolicy, Dimension> type;
}; };

View File

@ -1,6 +1,6 @@
// Boost.Geometry // Boost.Geometry
// Copyright (c) 2020-2021, Oracle and/or its affiliates. // Copyright (c) 2020-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
@ -11,12 +11,14 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP #ifndef BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP
#define BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP #define BOOST_GEOMETRY_STRATEGIES_CONVEX_HULL_CARTESIAN_HPP
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp> #include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/convex_hull/services.hpp> #include <boost/geometry/strategies/convex_hull/services.hpp>
#include <boost/geometry/strategies/compare.hpp>
#include <boost/geometry/strategies/detail.hpp> #include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/side.hpp>
#include <boost/geometry/strategy/cartesian/side_robust.hpp>
#include <boost/geometry/util/type_traits.hpp> #include <boost/geometry/util/type_traits.hpp>
@ -47,6 +49,14 @@ public:
= strategy::side::side_robust<CalculationType>; = strategy::side::side_robust<CalculationType>;
return side_strategy_type(); return side_strategy_type();
} }
template <typename ComparePolicy, typename EqualsPolicy>
using compare_type = typename strategy::compare::cartesian
<
ComparePolicy,
EqualsPolicy,
-1
>;
}; };
namespace services namespace services

View File

@ -1,6 +1,6 @@
// Boost.Geometry // Boost.Geometry
// Copyright (c) 2020-2021, Oracle and/or its affiliates. // Copyright (c) 2020-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
@ -13,9 +13,11 @@
#include <boost/geometry/strategies/convex_hull/services.hpp> #include <boost/geometry/strategies/convex_hull/services.hpp>
#include <boost/geometry/strategies/compare.hpp>
#include <boost/geometry/strategies/detail.hpp> #include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/geographic/side.hpp> #include <boost/geometry/strategies/geographic/side.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp> #include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/util/type_traits.hpp> #include <boost/geometry/util/type_traits.hpp>
@ -62,6 +64,14 @@ public:
CalculationType CalculationType
>(base_t::m_spheroid); >(base_t::m_spheroid);
} }
template <typename ComparePolicy, typename EqualsPolicy>
using compare_type = typename strategy::compare::spherical
<
ComparePolicy,
EqualsPolicy,
-1
>;
}; };
namespace services namespace services

View File

@ -1,6 +1,6 @@
// Boost.Geometry // Boost.Geometry
// Copyright (c) 2020-2021, Oracle and/or its affiliates. // Copyright (c) 2020-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
@ -13,9 +13,11 @@
#include <boost/geometry/strategies/convex_hull/services.hpp> #include <boost/geometry/strategies/convex_hull/services.hpp>
#include <boost/geometry/strategies/compare.hpp>
#include <boost/geometry/strategies/detail.hpp> #include <boost/geometry/strategies/detail.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp> #include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/strategies/spherical/ssf.hpp> #include <boost/geometry/strategies/spherical/ssf.hpp>
#include <boost/geometry/util/type_traits.hpp> #include <boost/geometry/util/type_traits.hpp>
@ -44,6 +46,14 @@ public:
{ {
return strategy::side::spherical_side_formula<CalculationType>(); return strategy::side::spherical_side_formula<CalculationType>();
} }
template <typename ComparePolicy, typename EqualsPolicy>
using compare_type = typename strategy::compare::spherical
<
ComparePolicy,
EqualsPolicy,
-1
>;
}; };
namespace services namespace services

View File

@ -1,7 +1,8 @@
// Boost.Geometry // Boost.Geometry
// Copyright (c) 2020, Oracle and/or its affiliates. // Copyright (c) 2020-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0. // Licensed under the Boost Software License version 1.0.
@ -187,6 +188,14 @@ public:
{ {
return strategy::within::cartesian_box_box(); return strategy::within::cartesian_box_box();
} }
template <typename ComparePolicy, typename EqualsPolicy>
using compare_type = typename strategy::compare::cartesian
<
ComparePolicy,
EqualsPolicy,
-1
>;
}; };

View File

@ -1,7 +1,8 @@
// Boost.Geometry // Boost.Geometry
// Copyright (c) 2020-2021, Oracle and/or its affiliates. // Copyright (c) 2020-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0. // Licensed under the Boost Software License version 1.0.
@ -209,6 +210,14 @@ public:
{ {
return strategy::within::spherical_box_box(); return strategy::within::spherical_box_box();
} }
template <typename ComparePolicy, typename EqualsPolicy>
using compare_type = typename strategy::compare::spherical
<
ComparePolicy,
EqualsPolicy,
-1
>;
}; };
@ -280,6 +289,14 @@ struct strategy_converter<strategy::intersection::geographic_segments<FormulaPol
FormulaPolicy, SeriesOrder, Spheroid, CalculationType FormulaPolicy, SeriesOrder, Spheroid, CalculationType
>(base_t::m_spheroid); >(base_t::m_spheroid);
} }
template <typename ComparePolicy, typename EqualsPolicy>
using compare_type = typename strategy::compare::spherical
<
ComparePolicy,
EqualsPolicy,
-1
>;
}; };
static auto get(strategy::intersection::geographic_segments<FormulaPolicy, SeriesOrder, Spheroid, CalculationType> const& s) static auto get(strategy::intersection::geographic_segments<FormulaPolicy, SeriesOrder, Spheroid, CalculationType> const& s)

View File

@ -1,7 +1,8 @@
// Boost.Geometry // Boost.Geometry
// Copyright (c) 2020-2021, Oracle and/or its affiliates. // Copyright (c) 2020-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0. // Licensed under the Boost Software License version 1.0.
@ -193,6 +194,14 @@ public:
{ {
return strategy::within::spherical_box_box(); return strategy::within::spherical_box_box();
} }
template <typename ComparePolicy, typename EqualsPolicy>
using compare_type = typename strategy::compare::spherical
<
ComparePolicy,
EqualsPolicy,
-1
>;
}; };

View File

@ -2,9 +2,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017-2020. // This file was modified by Oracle on 2017-2023.
// Modifications copyright (c) 2017-2020, Oracle and/or its affiliates. // Modifications copyright (c) 2017-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // 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,
@ -60,6 +61,7 @@ get(P const& p, std::false_type /*different units*/)
template template
< <
typename ComparePolicy, typename ComparePolicy,
typename EqualsPolicy,
typename Point1, typename Point1,
typename Point2, typename Point2,
std::size_t DimensionCount std::size_t DimensionCount
@ -77,11 +79,11 @@ struct spherical_latitude
T1 const& l1, T2 const& r1) T1 const& l1, T2 const& r1)
{ {
// latitudes equal // latitudes equal
if (math::equals(l1, r1)) if (EqualsPolicy::apply(l1, r1))
{ {
return compare::detail::compare_loop return compare::detail::compare_loop
< <
ComparePolicy, 2, DimensionCount ComparePolicy, EqualsPolicy, 2, DimensionCount
>::apply(left, right); >::apply(left, right);
} }
else else
@ -102,10 +104,11 @@ struct spherical_latitude
template template
< <
typename ComparePolicy, typename ComparePolicy,
typename EqualsPolicy,
typename Point1, typename Point1,
typename Point2 typename Point2
> >
struct spherical_latitude<ComparePolicy, Point1, Point2, 1> struct spherical_latitude<ComparePolicy, EqualsPolicy, Point1, Point2, 1>
{ {
template <typename T1, typename T2> template <typename T1, typename T2>
static inline bool apply(Point1 const& left, Point2 const& right, static inline bool apply(Point1 const& left, Point2 const& right,
@ -118,7 +121,7 @@ struct spherical_latitude<ComparePolicy, Point1, Point2, 1>
{ {
return compare::detail::compare_loop return compare::detail::compare_loop
< <
ComparePolicy, 1, 1 ComparePolicy, EqualsPolicy, 1, 1
>::apply(left, right); >::apply(left, right);
} }
}; };
@ -126,6 +129,7 @@ struct spherical_latitude<ComparePolicy, Point1, Point2, 1>
template template
< <
typename ComparePolicy, typename ComparePolicy,
typename EqualsPolicy,
typename Point1, typename Point1,
typename Point2, typename Point2,
std::size_t DimensionCount std::size_t DimensionCount
@ -167,16 +171,16 @@ struct spherical_longitude
bool is_right_at_antimeridian = false; bool is_right_at_antimeridian = false;
// longitudes equal // longitudes equal
if (math::equals(l0, r0) if (EqualsPolicy::apply(l0, r0)
// both at antimeridian // both at antimeridian
|| are_both_at_antimeridian(l0, r0, is_left_at_antimeridian, is_right_at_antimeridian) || are_both_at_antimeridian(l0, r0, is_left_at_antimeridian, is_right_at_antimeridian)
// both at pole // both at pole
|| (math::equals(l1, r1) || (EqualsPolicy::apply(l1, r1)
&& math::is_latitude_pole<units_type, is_equatorial>(l1))) && math::is_latitude_pole<units_type, is_equatorial>(l1)))
{ {
return spherical_latitude return spherical_latitude
< <
ComparePolicy, Point1, Point2, DimensionCount ComparePolicy, EqualsPolicy, Point1, Point2, DimensionCount
>::apply(left, right, l1, r1); >::apply(left, right, l1, r1);
} }
// if left is at antimeridian and right is not at antimeridian // if left is at antimeridian and right is not at antimeridian
@ -214,16 +218,17 @@ struct spherical_longitude
template template
< <
typename ComparePolicy, typename ComparePolicy,
typename EqualsPolicy,
int Dimension = -1 int Dimension = -1
> >
struct spherical struct spherical
: cartesian<ComparePolicy, Dimension> : cartesian<ComparePolicy, EqualsPolicy, Dimension>
{}; {};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
// all dimensions starting from longitude // all dimensions starting from longitude
template <typename ComparePolicy> template <typename ComparePolicy, typename EqualsPolicy>
struct spherical<ComparePolicy, -1> struct spherical<ComparePolicy, EqualsPolicy, -1>
{ {
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
static inline bool apply(Point1 const& left, Point2 const& right) static inline bool apply(Point1 const& left, Point2 const& right)
@ -231,6 +236,7 @@ struct spherical<ComparePolicy, -1>
return compare::detail::spherical_longitude return compare::detail::spherical_longitude
< <
ComparePolicy, ComparePolicy,
EqualsPolicy,
Point1, Point1,
Point2, Point2,
std::conditional_t std::conditional_t
@ -244,29 +250,29 @@ struct spherical<ComparePolicy, -1>
}; };
// only longitudes (and latitudes to check poles) // only longitudes (and latitudes to check poles)
template <typename ComparePolicy> template <typename ComparePolicy, typename EqualsPolicy>
struct spherical<ComparePolicy, 0> struct spherical<ComparePolicy, EqualsPolicy, 0>
{ {
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
static inline bool apply(Point1 const& left, Point2 const& right) static inline bool apply(Point1 const& left, Point2 const& right)
{ {
return compare::detail::spherical_longitude return compare::detail::spherical_longitude
< <
ComparePolicy, Point1, Point2, 1 ComparePolicy, EqualsPolicy, Point1, Point2, 1
>::apply(left, right); >::apply(left, right);
} }
}; };
// only latitudes // only latitudes
template <typename ComparePolicy> template <typename ComparePolicy, typename EqualsPolicy>
struct spherical<ComparePolicy, 1> struct spherical<ComparePolicy, EqualsPolicy, 1>
{ {
template <typename Point1, typename Point2> template <typename Point1, typename Point2>
static inline bool apply(Point1 const& left, Point2 const& right) static inline bool apply(Point1 const& left, Point2 const& right)
{ {
return compare::detail::spherical_latitude return compare::detail::spherical_latitude
< <
ComparePolicy, Point1, Point2, 2 ComparePolicy, EqualsPolicy, Point1, Point2, 2
>::apply(left, right); >::apply(left, right);
} }
}; };
@ -278,44 +284,48 @@ namespace services
{ {
template <typename ComparePolicy, typename Point1, typename Point2, int Dimension> template <typename ComparePolicy, typename EqualsPolicy, typename Point1, typename Point2, int Dimension>
struct default_strategy struct default_strategy
< <
ComparePolicy, Point1, Point2, Dimension, ComparePolicy, EqualsPolicy,
Point1, Point2, Dimension,
spherical_tag, spherical_tag spherical_tag, spherical_tag
> >
{ {
typedef compare::spherical<ComparePolicy, Dimension> type; typedef compare::spherical<ComparePolicy, EqualsPolicy, Dimension> type;
}; };
template <typename ComparePolicy, typename Point1, typename Point2, int Dimension> template <typename ComparePolicy, typename EqualsPolicy, typename Point1, typename Point2, int Dimension>
struct default_strategy struct default_strategy
< <
ComparePolicy, Point1, Point2, Dimension, ComparePolicy, EqualsPolicy,
Point1, Point2, Dimension,
spherical_polar_tag, spherical_polar_tag spherical_polar_tag, spherical_polar_tag
> >
{ {
typedef compare::spherical<ComparePolicy, Dimension> type; typedef compare::spherical<ComparePolicy, EqualsPolicy, Dimension> type;
}; };
template <typename ComparePolicy, typename Point1, typename Point2, int Dimension> template <typename ComparePolicy, typename EqualsPolicy, typename Point1, typename Point2, int Dimension>
struct default_strategy struct default_strategy
< <
ComparePolicy, Point1, Point2, Dimension, ComparePolicy, EqualsPolicy,
Point1, Point2, Dimension,
spherical_equatorial_tag, spherical_equatorial_tag spherical_equatorial_tag, spherical_equatorial_tag
> >
{ {
typedef compare::spherical<ComparePolicy, Dimension> type; typedef compare::spherical<ComparePolicy, EqualsPolicy, Dimension> type;
}; };
template <typename ComparePolicy, typename Point1, typename Point2, int Dimension> template <typename ComparePolicy, typename EqualsPolicy, typename Point1, typename Point2, int Dimension>
struct default_strategy struct default_strategy
< <
ComparePolicy, Point1, Point2, Dimension, ComparePolicy, EqualsPolicy,
Point1, Point2, Dimension,
geographic_tag, geographic_tag geographic_tag, geographic_tag
> >
{ {
typedef compare::spherical<ComparePolicy, Dimension> type; typedef compare::spherical<ComparePolicy, EqualsPolicy, Dimension> type;
}; };

View File

@ -4,8 +4,8 @@
// 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.
// This file was modified by Oracle on 2015-2021. // This file was modified by Oracle on 2015-2023.
// Modifications copyright (c) 2015-2021, Oracle and/or its affiliates. // Modifications copyright (c) 2015-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 Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@ -172,7 +172,7 @@ public :
// arguments, we cyclically permute them so that the first // arguments, we cyclically permute them so that the first
// argument is always the lexicographically smallest point. // argument is always the lexicographically smallest point.
using less = compare::cartesian<compare::less>; using less = compare::cartesian<compare::less, compare::equals_epsilon>;
if (less::apply(p, p1)) if (less::apply(p, p1))
{ {

View File

@ -1,7 +1,7 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test // Unit Test
// Copyright (c) 2020 Oracle and/or its affiliates. // Copyright (c) 2020-2023 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle // Contributed and/or modified by Vissarion Fisikopoulos, 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,
@ -97,6 +97,24 @@ void test_all()
polygon_wkt4, 5, 4, -0.015); polygon_wkt4, 5, 4, -0.015);
test_geometry<bg::model::polygon<Pmp>, non_robust_cartesian_sbt>( test_geometry<bg::model::polygon<Pmp>, non_robust_cartesian_sbt>(
polygon_wkt4, 5, 5, 3.472078301e+13); polygon_wkt4, 5, 5, 3.472078301e+13);
// github issue https://github.com/boostorg/geometry/issues/1158
auto polygon_wkt5 = "polygon((1941.6475737576565734 554.21197550796682663,\
2201.1796067026721175 604.83253590728611471,\
2367.1836939680897558 1898.3918136409306499,\
1856.9044662310534477 2320.8057089752910542,\
2000.0000000000002274 551.77450949119793222,\
1999.9999999999995453 1721.4008337980080796,\
1999.9999999999993179 1966.6530570371892281,\
1941.6475737576565734 554.21197550796682663))";
test_geometry<bg::model::polygon<P>, robust_cartesian, precise_cartesian>(
polygon_wkt5, 8, 6, 598281.35103625199);
test_geometry<bg::model::polygon<P>, non_robust_cartesian_sbt, precise_cartesian>(
polygon_wkt5, 8, 6, 598281.35103625199);
test_geometry<bg::model::polygon<P>, non_robust_cartesian_fast, precise_cartesian>(
polygon_wkt5, 8, 6, 598281.35103625199);
test_geometry<bg::model::polygon<Pmp>, non_robust_cartesian_sbt>(
polygon_wkt5, 8, 6, 598281.35103625199);
} }

View File

@ -1,11 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library) // Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2015, 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 Menelaos Karavelas, on behalf of Oracle
// Licensed under the Boost Software License version 1.0. // Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html // http://www.boost.org/users/license.html
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
#include <iostream> #include <iostream>
@ -1381,7 +1383,7 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_spikes )
{ {
#ifdef BOOST_GEOMETRY_TEST_DEBUG #ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << std::endl << std::endl << std::endl; std::cout << std::endl << std::endl << std::endl;
std::cout << "*** MULTILINESTRING / MULTILINESTRING INTERSECTION" std::cout << "*** MULTILINESTRING / MULTILINESTRING INTERSECTION"
<< " (WITH SPIKES) ***" << " (WITH SPIKES) ***"
<< std::endl; << std::endl;
std::cout << std::endl; std::cout << std::endl;

View File

@ -1,6 +1,8 @@
// Boost.Geometry // Boost.Geometry
// Copyright (c) 2019-2021, Oracle and/or its affiliates. // Copyright (c) 2019-2023, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0. // Licensed under the Boost Software License version 1.0.
@ -130,7 +132,7 @@ inline void rel(G1 const& g1, G2 const& g2, S const& s)
call_crosses<G1, G2>::apply(g1, g2, s); call_crosses<G1, G2>::apply(g1, g2, s);
bg::disjoint(g1, g2, s); bg::disjoint(g1, g2, s);
call_equals<G1, G2>::apply(g1, g2, s); call_equals<G1, G2>::apply(g1, g2, s);
bg::intersects(g1, g2, s); bg::intersects(g1, g2, s);
call_overlaps<G1, G2>::apply(g1, g2, s); call_overlaps<G1, G2>::apply(g1, g2, s);
call_touches<G1, G2>::apply(g1, g2, s); call_touches<G1, G2>::apply(g1, g2, s);
bg::within(g1, g2, s); bg::within(g1, g2, s);