update boost
This commit is contained in:
@@ -5,9 +5,8 @@
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2017.
|
||||
// Modifications copyright (c) 2017 Oracle and/or its affiliates.
|
||||
|
||||
// This file was modified by Oracle on 2017-2021.
|
||||
// Modifications copyright (c) 2017-2021 Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
@@ -23,7 +22,6 @@
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
|
||||
#include <boost/geometry/algorithms/detail/normalize.hpp>
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
@@ -38,45 +36,26 @@
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/views/detail/normalized_view.hpp>
|
||||
#include <boost/geometry/views/detail/closed_clockwise_view.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
|
||||
#include <boost/geometry/strategies/spherical/ssf.hpp>
|
||||
#include <boost/geometry/strategies/normalize.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
// TODO: dispatch only by SideStrategy instead of Geometry/CSTag?
|
||||
|
||||
// Since these vectors (though ray would be a better name) are used in the
|
||||
// implementation of equals() for Areal geometries the internal representation
|
||||
// should be consistent with the side strategy.
|
||||
template
|
||||
<
|
||||
typename T,
|
||||
typename Geometry,
|
||||
typename SideStrategy,
|
||||
typename CSTag = typename cs_tag<Geometry>::type
|
||||
>
|
||||
struct collected_vector
|
||||
: nyi::not_implemented_tag
|
||||
{};
|
||||
|
||||
// compatible with side_by_triangle cartesian strategy
|
||||
template <typename T, typename Geometry, typename CT, typename CSTag>
|
||||
struct collected_vector
|
||||
<
|
||||
T, Geometry, strategy::side::side_by_triangle<CT>, CSTag
|
||||
>
|
||||
template <typename T>
|
||||
struct collected_vector_cartesian
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
inline collected_vector()
|
||||
|
||||
inline collected_vector_cartesian()
|
||||
{}
|
||||
|
||||
inline collected_vector(T const& px, T const& py,
|
||||
T const& pdx, T const& pdy)
|
||||
inline collected_vector_cartesian(T const& px, T const& py,
|
||||
T const& pdx, T const& pdy)
|
||||
: x(px)
|
||||
, y(py)
|
||||
, dx(pdx)
|
||||
@@ -86,7 +65,7 @@ struct collected_vector
|
||||
{}
|
||||
|
||||
template <typename Point>
|
||||
inline collected_vector(Point const& p1, Point const& p2)
|
||||
inline collected_vector_cartesian(Point const& p1, Point const& p2)
|
||||
: x(get<0>(p1))
|
||||
, y(get<1>(p1))
|
||||
, dx(get<0>(p2) - x)
|
||||
@@ -97,8 +76,7 @@ struct collected_vector
|
||||
|
||||
bool normalize()
|
||||
{
|
||||
T magnitude = math::sqrt(
|
||||
boost::numeric_cast<T>(dx * dx + dy * dy));
|
||||
T magnitude = math::sqrt(boost::numeric_cast<T>(dx * dx + dy * dy));
|
||||
|
||||
// NOTE: shouldn't here math::equals() be called?
|
||||
if (magnitude > 0)
|
||||
@@ -112,7 +90,7 @@ struct collected_vector
|
||||
}
|
||||
|
||||
// For sorting
|
||||
inline bool operator<(collected_vector const& other) const
|
||||
inline bool operator<(collected_vector_cartesian const& other) const
|
||||
{
|
||||
if (math::equals(x, other.x))
|
||||
{
|
||||
@@ -129,13 +107,13 @@ struct collected_vector
|
||||
return x < other.x;
|
||||
}
|
||||
|
||||
inline bool next_is_collinear(collected_vector const& other) const
|
||||
inline bool next_is_collinear(collected_vector_cartesian const& other) const
|
||||
{
|
||||
return same_direction(other);
|
||||
}
|
||||
|
||||
// For std::equals
|
||||
inline bool operator==(collected_vector const& other) const
|
||||
inline bool operator==(collected_vector_cartesian const& other) const
|
||||
{
|
||||
return math::equals(x, other.x)
|
||||
&& math::equals(y, other.y)
|
||||
@@ -143,12 +121,12 @@ struct collected_vector
|
||||
}
|
||||
|
||||
private:
|
||||
inline bool same_direction(collected_vector const& other) const
|
||||
inline bool same_direction(collected_vector_cartesian const& other) const
|
||||
{
|
||||
// For high precision arithmetic, we have to be
|
||||
// more relaxed then using ==
|
||||
// Because 2/sqrt( (0,0)<->(2,2) ) == 1/sqrt( (0,0)<->(1,1) )
|
||||
// is not always true (at least, it is not for ttmath)
|
||||
// is not always true (at least, not for some user defined types)
|
||||
return math::equals_with_epsilon(dx, other.dx)
|
||||
&& math::equals_with_epsilon(dy, other.dy);
|
||||
}
|
||||
@@ -159,37 +137,34 @@ private:
|
||||
};
|
||||
|
||||
// Compatible with spherical_side_formula which currently
|
||||
// is the default spherical and geographical strategy
|
||||
template <typename T, typename Geometry, typename CT, typename CSTag>
|
||||
struct collected_vector
|
||||
<
|
||||
T, Geometry, strategy::side::spherical_side_formula<CT>, CSTag
|
||||
>
|
||||
// is the default spherical_equatorial and geographic strategy
|
||||
// so CSTag is spherical_equatorial_tag or geographic_tag
|
||||
template <typename T, typename Point>
|
||||
struct collected_vector_spherical
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
typedef typename coordinate_system<Geometry>::type cs_type;
|
||||
typedef model::point<T, 2, cs_type> point_type;
|
||||
|
||||
typedef model::point<T, 3, cs::cartesian> vector_type;
|
||||
|
||||
collected_vector()
|
||||
collected_vector_spherical()
|
||||
{}
|
||||
|
||||
template <typename Point>
|
||||
collected_vector(Point const& p1, Point const& p2)
|
||||
collected_vector_spherical(Point const& p1, Point const& p2)
|
||||
: origin(get<0>(p1), get<1>(p1))
|
||||
{
|
||||
origin = detail::return_normalized<point_type>(origin);
|
||||
origin = detail::return_normalized<Point>(
|
||||
origin,
|
||||
strategy::normalize::spherical_point());
|
||||
|
||||
using namespace geometry::formula;
|
||||
prev = sph_to_cart3d<vector_type>(p1);
|
||||
next = sph_to_cart3d<vector_type>(p2);
|
||||
direction = cross_product(prev, next);
|
||||
cross = direction = cross_product(prev, next);
|
||||
}
|
||||
|
||||
bool normalize()
|
||||
{
|
||||
T magnitude_sqr = dot_product(direction, direction);
|
||||
T const magnitude_sqr = dot_product(direction, direction);
|
||||
|
||||
// NOTE: shouldn't here math::equals() be called?
|
||||
if (magnitude_sqr > 0)
|
||||
@@ -201,7 +176,7 @@ struct collected_vector
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator<(collected_vector const& other) const
|
||||
bool operator<(collected_vector_spherical const& other) const
|
||||
{
|
||||
if (math::equals(get<0>(origin), get<0>(other.origin)))
|
||||
{
|
||||
@@ -225,13 +200,13 @@ struct collected_vector
|
||||
// For consistency with side and intersection strategies used by relops
|
||||
// IMPORTANT: this method should be called for previous vector
|
||||
// and next vector should be passed as parameter
|
||||
bool next_is_collinear(collected_vector const& other) const
|
||||
bool next_is_collinear(collected_vector_spherical const& other) const
|
||||
{
|
||||
return formula::sph_side_value(direction, other.next) == 0;
|
||||
return formula::sph_side_value(cross, other.next) == 0;
|
||||
}
|
||||
|
||||
// For std::equals
|
||||
bool operator==(collected_vector const& other) const
|
||||
bool operator==(collected_vector_spherical const& other) const
|
||||
{
|
||||
return math::equals(get<0>(origin), get<0>(other.origin))
|
||||
&& math::equals(get<1>(origin), get<1>(other.origin))
|
||||
@@ -240,74 +215,58 @@ struct collected_vector
|
||||
|
||||
private:
|
||||
// For consistency with side and intersection strategies used by relops
|
||||
bool is_collinear(collected_vector const& other) const
|
||||
// NOTE: alternative would be to equal-compare direction's coordinates
|
||||
// or to check if dot product of directions is equal to 1.
|
||||
bool is_collinear(collected_vector_spherical const& other) const
|
||||
{
|
||||
return formula::sph_side_value(direction, other.prev) == 0
|
||||
&& formula::sph_side_value(direction, other.next) == 0;
|
||||
return formula::sph_side_value(cross, other.prev) == 0
|
||||
&& formula::sph_side_value(cross, other.next) == 0;
|
||||
}
|
||||
|
||||
/*bool same_direction(collected_vector const& other) const
|
||||
{
|
||||
return math::equals_with_epsilon(get<0>(direction), get<0>(other.direction))
|
||||
&& math::equals_with_epsilon(get<1>(direction), get<1>(other.direction))
|
||||
&& math::equals_with_epsilon(get<2>(direction), get<2>(other.direction));
|
||||
}*/
|
||||
|
||||
point_type origin; // used for sorting and equality check
|
||||
Point origin; // used for sorting and equality check
|
||||
vector_type direction; // used for sorting, only in operator<
|
||||
vector_type cross; // used for sorting, used for collinearity check
|
||||
vector_type prev; // used for collinearity check, only in operator==
|
||||
vector_type next; // used for collinearity check
|
||||
};
|
||||
|
||||
// Specialization for spherical polar
|
||||
template <typename T, typename Geometry, typename CT>
|
||||
struct collected_vector
|
||||
<
|
||||
T, Geometry,
|
||||
strategy::side::spherical_side_formula<CT>,
|
||||
spherical_polar_tag
|
||||
>
|
||||
: public collected_vector
|
||||
<
|
||||
T, Geometry,
|
||||
strategy::side::spherical_side_formula<CT>,
|
||||
spherical_equatorial_tag
|
||||
>
|
||||
// Version for spherical polar
|
||||
template <typename T, typename Point>
|
||||
struct collected_vector_polar
|
||||
: public collected_vector_spherical<T, Point>
|
||||
{
|
||||
typedef collected_vector
|
||||
<
|
||||
T, Geometry,
|
||||
strategy::side::spherical_side_formula<CT>,
|
||||
spherical_equatorial_tag
|
||||
> base_type;
|
||||
using type = T;
|
||||
using base_point_type
|
||||
= model::point<T, 2, cs::spherical_equatorial<geometry::degree>>;
|
||||
using base_type = collected_vector_spherical<T, base_point_type>;
|
||||
|
||||
collected_vector() {}
|
||||
collected_vector_polar() {}
|
||||
|
||||
template <typename Point>
|
||||
collected_vector(Point const& p1, Point const& p2)
|
||||
collected_vector_polar(Point const& p1, Point const& p2)
|
||||
: base_type(to_equatorial(p1), to_equatorial(p2))
|
||||
{}
|
||||
|
||||
private:
|
||||
template <typename Point>
|
||||
Point polar_to_equatorial(Point const& p)
|
||||
static base_point_type to_equatorial(Point const& p)
|
||||
{
|
||||
typedef typename coordinate_type<Point>::type coord_type;
|
||||
|
||||
typedef math::detail::constants_on_spheroid
|
||||
using coord_type = typename coordinate_type<Point>::type;
|
||||
using constants = math::detail::constants_on_spheroid
|
||||
<
|
||||
coord_type,
|
||||
typename coordinate_system<Point>::type::units
|
||||
> constants;
|
||||
> ;
|
||||
|
||||
coord_type const pi_2 = constants::half_period() / 2;
|
||||
constexpr coord_type pi_2 = constants::half_period() / 2;
|
||||
|
||||
Point res = p;
|
||||
base_point_type res;
|
||||
set<0>(res, get<0>(p));
|
||||
set<1>(res, pi_2 - get<1>(p));
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: implement collected_vector type for geographic
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace collect_vectors
|
||||
@@ -322,34 +281,24 @@ struct range_collect_vectors
|
||||
|
||||
static inline void apply(Collection& collection, Range const& range)
|
||||
{
|
||||
typedef geometry::detail::normalized_view
|
||||
<
|
||||
Range const
|
||||
> normalized_range_type;
|
||||
|
||||
apply_impl(collection, normalized_range_type(range));
|
||||
apply_impl(collection,
|
||||
detail::closed_clockwise_view<Range const>(range));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename NormalizedRange>
|
||||
static inline void apply_impl(Collection& collection, NormalizedRange const& range)
|
||||
template <typename ClosedClockwiseRange>
|
||||
static inline void apply_impl(Collection& collection, ClosedClockwiseRange const& range)
|
||||
{
|
||||
if (boost::size(range) < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
typedef typename boost::range_size<Collection>::type collection_size_t;
|
||||
collection_size_t c_old_size = boost::size(collection);
|
||||
|
||||
typedef typename boost::range_iterator<NormalizedRange const>::type iterator;
|
||||
|
||||
auto c_old_size = boost::size(collection);
|
||||
bool is_first = true;
|
||||
iterator it = boost::begin(range);
|
||||
auto it = boost::begin(range);
|
||||
|
||||
for (iterator prev = it++;
|
||||
it != boost::end(range);
|
||||
prev = it++)
|
||||
for (auto prev = it++; it != boost::end(range); prev = it++)
|
||||
{
|
||||
typename boost::range_value<Collection>::type v(*prev, *it);
|
||||
|
||||
@@ -368,13 +317,10 @@ private:
|
||||
}
|
||||
|
||||
// If first one has same direction as last one, remove first one
|
||||
collection_size_t collected_count = boost::size(collection) - c_old_size;
|
||||
if ( collected_count > 1 )
|
||||
if (boost::size(collection) > c_old_size + 1)
|
||||
{
|
||||
typedef typename boost::range_iterator<Collection>::type c_iterator;
|
||||
c_iterator first = range::pos(collection, c_old_size);
|
||||
|
||||
if (collection.back().next_is_collinear(*first) )
|
||||
auto first = range::pos(collection, c_old_size);
|
||||
if (collection.back().next_is_collinear(*first))
|
||||
{
|
||||
//collection.erase(first);
|
||||
// O(1) instead of O(N)
|
||||
@@ -453,10 +399,8 @@ struct polygon_collect_vectors
|
||||
typedef range_collect_vectors<ring_type, Collection> per_range;
|
||||
per_range::apply(collection, exterior_ring(polygon));
|
||||
|
||||
typename interior_return_type<Polygon const>::type
|
||||
rings = interior_rings(polygon);
|
||||
for (typename detail::interior_iterator<Polygon const>::type
|
||||
it = boost::begin(rings); it != boost::end(rings); ++it)
|
||||
auto const& rings = interior_rings(polygon);
|
||||
for (auto it = boost::begin(rings); it != boost::end(rings); ++it)
|
||||
{
|
||||
per_range::apply(collection, *it);
|
||||
}
|
||||
@@ -469,10 +413,7 @@ struct multi_collect_vectors
|
||||
{
|
||||
static inline void apply(Collection& collection, MultiGeometry const& multi)
|
||||
{
|
||||
for (typename boost::range_iterator<MultiGeometry const>::type
|
||||
it = boost::begin(multi);
|
||||
it != boost::end(multi);
|
||||
++it)
|
||||
for (auto it = boost::begin(multi); it != boost::end(multi); ++it)
|
||||
{
|
||||
SinglePolicy::apply(collection, *it);
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2014, 2015, 2016, 2017, 2018.
|
||||
// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2014-2022.
|
||||
// Modifications copyright (c) 2014-2022 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
@@ -23,28 +23,30 @@
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/range/size.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
|
||||
|
||||
// For trivial checks
|
||||
#include <boost/geometry/algorithms/area.hpp>
|
||||
#include <boost/geometry/algorithms/length.hpp>
|
||||
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/equals/collect_vectors.hpp>
|
||||
#include <boost/geometry/algorithms/detail/equals/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/implementation.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/relate_impl.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/math.hpp>
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/equals/collect_vectors.hpp>
|
||||
#include <boost/geometry/algorithms/detail/equals/interface.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
|
||||
#include <boost/geometry/algorithms/relate.hpp>
|
||||
|
||||
#include <boost/geometry/views/detail/indexed_point_view.hpp>
|
||||
|
||||
|
||||
@@ -64,9 +66,11 @@ template
|
||||
struct point_point
|
||||
{
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& )
|
||||
static inline bool apply(Point1 const& point1, Point2 const& point2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return Strategy::apply(point1, point2);
|
||||
typedef decltype(strategy.relate(point1, point2)) strategy_type;
|
||||
return strategy_type::apply(point1, point2);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -107,25 +111,22 @@ struct segment_segment
|
||||
static inline bool apply(Segment1 const& segment1, Segment2 const& segment2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typename Strategy::point_in_point_strategy_type const&
|
||||
pt_pt_strategy = strategy.get_point_in_point_strategy();
|
||||
|
||||
return equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 0>(segment1),
|
||||
indexed_point_view<Segment2 const, 0>(segment2),
|
||||
pt_pt_strategy)
|
||||
strategy)
|
||||
? equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 1>(segment1),
|
||||
indexed_point_view<Segment2 const, 1>(segment2),
|
||||
pt_pt_strategy)
|
||||
strategy)
|
||||
: ( equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 0>(segment1),
|
||||
indexed_point_view<Segment2 const, 1>(segment2),
|
||||
pt_pt_strategy)
|
||||
strategy)
|
||||
&& equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 1>(segment1),
|
||||
indexed_point_view<Segment2 const, 0>(segment2),
|
||||
pt_pt_strategy)
|
||||
strategy)
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -138,15 +139,13 @@ struct area_check
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return geometry::math::equals(
|
||||
geometry::area(geometry1,
|
||||
strategy.template get_area_strategy<Geometry1>()),
|
||||
geometry::area(geometry2,
|
||||
strategy.template get_area_strategy<Geometry2>()));
|
||||
return geometry::math::equals(geometry::area(geometry1, strategy),
|
||||
geometry::area(geometry2, strategy));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
struct length_check
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
@@ -154,35 +153,39 @@ struct length_check
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return geometry::math::equals(
|
||||
geometry::length(geometry1,
|
||||
strategy.template get_distance_strategy<Geometry1>()),
|
||||
geometry::length(geometry2,
|
||||
strategy.template get_distance_strategy<Geometry2>()));
|
||||
return geometry::math::equals(geometry::length(geometry1, strategy),
|
||||
geometry::length(geometry2, strategy));
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename IntersectionStrategy>
|
||||
struct collected_vector
|
||||
// Small helper structure do decide to use collect_vectors, or not
|
||||
template <typename Strategy, typename CsTag>
|
||||
struct use_collect_vectors
|
||||
{
|
||||
typedef typename geometry::select_most_precise
|
||||
<
|
||||
typename select_coordinate_type
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type,
|
||||
double
|
||||
>::type calculation_type;
|
||||
|
||||
typedef geometry::collected_vector
|
||||
<
|
||||
calculation_type,
|
||||
Geometry1,
|
||||
typename IntersectionStrategy::side_strategy_type
|
||||
> type;
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct use_collect_vectors<Strategy, cartesian_tag>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
|
||||
template <typename T, typename Point>
|
||||
using type = collected_vector_cartesian<T>;
|
||||
};
|
||||
|
||||
template <typename CV>
|
||||
struct use_collect_vectors<strategy::side::spherical_side_formula<CV>, spherical_tag>
|
||||
{
|
||||
static constexpr bool value = true;
|
||||
|
||||
template <typename T, typename Point>
|
||||
using type = collected_vector_spherical<T, Point>;
|
||||
};
|
||||
|
||||
|
||||
template <typename TrivialCheck>
|
||||
struct equals_by_collection
|
||||
{
|
||||
@@ -196,10 +199,24 @@ struct equals_by_collection
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef typename collected_vector
|
||||
using calculation_type = typename geometry::select_most_precise
|
||||
<
|
||||
Geometry1, Geometry2, Strategy
|
||||
>::type collected_vector_type;
|
||||
typename select_coordinate_type
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::type,
|
||||
double
|
||||
>::type;
|
||||
|
||||
using collected_vector_type = typename use_collect_vectors
|
||||
<
|
||||
decltype(std::declval<Strategy>().side()),
|
||||
typename Strategy::cs_tag
|
||||
>::template type
|
||||
<
|
||||
calculation_type,
|
||||
typename geometry::point_type<Geometry1>::type
|
||||
>;
|
||||
|
||||
std::vector<collected_vector_type> c1, c2;
|
||||
|
||||
@@ -214,7 +231,7 @@ struct equals_by_collection
|
||||
std::sort(c1.begin(), c1.end());
|
||||
std::sort(c2.begin(), c2.end());
|
||||
|
||||
// Just check if these vectors are equal.
|
||||
// Check if these vectors are equal.
|
||||
return std::equal(c1.begin(), c1.end(), c2.begin());
|
||||
}
|
||||
};
|
||||
@@ -229,52 +246,54 @@ struct equals_by_relate
|
||||
>
|
||||
{};
|
||||
|
||||
// If collect_vectors which is a SideStrategy-dispatched optimization
|
||||
// is implemented in a way consistent with the Intersection/Side Strategy
|
||||
// then collect_vectors is used, otherwise relate is used.
|
||||
// Use either collect_vectors or relate
|
||||
// NOTE: the result could be conceptually different for invalid
|
||||
// geometries in different coordinate systems because collect_vectors
|
||||
// and relate treat invalid geometries differently.
|
||||
template<typename TrivialCheck>
|
||||
struct equals_by_collection_or_relate
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
template <typename Strategy>
|
||||
using use_vectors = use_collect_vectors
|
||||
<
|
||||
decltype(std::declval<Strategy>().side()),
|
||||
typename Strategy::cs_tag
|
||||
>;
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2, typename Strategy,
|
||||
std::enable_if_t<use_vectors<Strategy>::value, int> = 0
|
||||
>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename boost::is_base_of
|
||||
<
|
||||
nyi::not_implemented_tag,
|
||||
typename collected_vector
|
||||
<
|
||||
Geometry1, Geometry2, Strategy
|
||||
>::type
|
||||
>::type enable_relate_type;
|
||||
|
||||
return apply(geometry1, geometry2, strategy, enable_relate_type());
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy,
|
||||
boost::false_type /*enable_relate*/)
|
||||
{
|
||||
return equals_by_collection<TrivialCheck>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2, typename Strategy,
|
||||
std::enable_if_t<! use_vectors<Strategy>::value, int> = 0
|
||||
>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy,
|
||||
boost::true_type /*enable_relate*/)
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return equals_by_relate<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
struct equals_always_false
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& , Geometry2 const& , Strategy const& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::equals
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
@@ -285,81 +304,92 @@ namespace dispatch
|
||||
{
|
||||
|
||||
template <typename P1, typename P2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<P1, P2, point_tag, point_tag, DimensionCount, Reverse>
|
||||
struct equals<P1, P2, point_tag, point_tag, pointlike_tag, pointlike_tag, DimensionCount, Reverse>
|
||||
: detail::equals::point_point<0, DimensionCount>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint1, typename MultiPoint2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, DimensionCount, Reverse>
|
||||
struct equals<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, pointlike_tag, pointlike_tag, DimensionCount, Reverse>
|
||||
: detail::equals::equals_by_relate<MultiPoint1, MultiPoint2>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Point, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<Point, MultiPoint, point_tag, multi_point_tag, DimensionCount, Reverse>
|
||||
struct equals<Point, MultiPoint, point_tag, multi_point_tag, pointlike_tag, pointlike_tag, DimensionCount, Reverse>
|
||||
: detail::equals::equals_by_relate<Point, MultiPoint>
|
||||
{};
|
||||
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<Box1, Box2, box_tag, box_tag, DimensionCount, Reverse>
|
||||
struct equals<Box1, Box2, box_tag, box_tag, areal_tag, areal_tag, DimensionCount, Reverse>
|
||||
: detail::equals::box_box<0, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring1, typename Ring2, bool Reverse>
|
||||
struct equals<Ring1, Ring2, ring_tag, ring_tag, 2, Reverse>
|
||||
struct equals<Ring1, Ring2, ring_tag, ring_tag, areal_tag, areal_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon1, typename Polygon2, bool Reverse>
|
||||
struct equals<Polygon1, Polygon2, polygon_tag, polygon_tag, 2, Reverse>
|
||||
struct equals<Polygon1, Polygon2, polygon_tag, polygon_tag, areal_tag, areal_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Ring, bool Reverse>
|
||||
struct equals<Polygon, Ring, polygon_tag, ring_tag, 2, Reverse>
|
||||
struct equals<Polygon, Ring, polygon_tag, ring_tag, areal_tag, areal_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring, typename Box, bool Reverse>
|
||||
struct equals<Ring, Box, ring_tag, box_tag, 2, Reverse>
|
||||
struct equals<Ring, Box, ring_tag, box_tag, areal_tag, areal_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Box, bool Reverse>
|
||||
struct equals<Polygon, Box, polygon_tag, box_tag, 2, Reverse>
|
||||
struct equals<Polygon, Box, polygon_tag, box_tag, areal_tag, areal_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_collection<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
template <typename Segment1, typename Segment2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<Segment1, Segment2, segment_tag, segment_tag, DimensionCount, Reverse>
|
||||
struct equals<Segment1, Segment2, segment_tag, segment_tag, linear_tag, linear_tag, DimensionCount, Reverse>
|
||||
: detail::equals::segment_segment
|
||||
{};
|
||||
|
||||
template <typename LineString1, typename LineString2, bool Reverse>
|
||||
struct equals<LineString1, LineString2, linestring_tag, linestring_tag, 2, Reverse>
|
||||
struct equals<LineString1, LineString2, linestring_tag, linestring_tag, linear_tag, linear_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_relate<LineString1, LineString2>
|
||||
{};
|
||||
|
||||
template <typename LineString, typename MultiLineString, bool Reverse>
|
||||
struct equals<LineString, MultiLineString, linestring_tag, multi_linestring_tag, 2, Reverse>
|
||||
struct equals<LineString, MultiLineString, linestring_tag, multi_linestring_tag, linear_tag, linear_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_relate<LineString, MultiLineString>
|
||||
{};
|
||||
|
||||
template <typename MultiLineString1, typename MultiLineString2, bool Reverse>
|
||||
struct equals<MultiLineString1, MultiLineString2, multi_linestring_tag, multi_linestring_tag, 2, Reverse>
|
||||
struct equals<MultiLineString1, MultiLineString2, multi_linestring_tag, multi_linestring_tag, linear_tag, linear_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_relate<MultiLineString1, MultiLineString2>
|
||||
{};
|
||||
|
||||
template <typename LineString, typename Segment, bool Reverse>
|
||||
struct equals<LineString, Segment, linestring_tag, segment_tag, linear_tag, linear_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_relate<LineString, Segment>
|
||||
{};
|
||||
|
||||
template <typename MultiLineString, typename Segment, bool Reverse>
|
||||
struct equals<MultiLineString, Segment, multi_linestring_tag, segment_tag, linear_tag, linear_tag, 2, Reverse>
|
||||
: detail::equals::equals_by_relate<MultiLineString, Segment>
|
||||
{};
|
||||
|
||||
|
||||
template <typename MultiPolygon1, typename MultiPolygon2, bool Reverse>
|
||||
struct equals
|
||||
<
|
||||
MultiPolygon1, MultiPolygon2,
|
||||
multi_polygon_tag, multi_polygon_tag,
|
||||
areal_tag, areal_tag,
|
||||
2,
|
||||
Reverse
|
||||
>
|
||||
@@ -372,6 +402,7 @@ struct equals
|
||||
<
|
||||
Polygon, MultiPolygon,
|
||||
polygon_tag, multi_polygon_tag,
|
||||
areal_tag, areal_tag,
|
||||
2,
|
||||
Reverse
|
||||
>
|
||||
@@ -383,6 +414,7 @@ struct equals
|
||||
<
|
||||
MultiPolygon, Ring,
|
||||
multi_polygon_tag, ring_tag,
|
||||
areal_tag, areal_tag,
|
||||
2,
|
||||
Reverse
|
||||
>
|
||||
@@ -390,6 +422,42 @@ struct equals
|
||||
{};
|
||||
|
||||
|
||||
// NOTE: degenerated linear geometries, e.g. segment or linestring containing
|
||||
// 2 equal points, are considered to be invalid. Though theoretically
|
||||
// degenerated segments and linestrings could be treated as points and
|
||||
// multi-linestrings as multi-points.
|
||||
// This reasoning could also be applied to boxes.
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Tag1, typename Tag2, std::size_t DimensionCount>
|
||||
struct equals<Geometry1, Geometry2, Tag1, Tag2, pointlike_tag, linear_tag, DimensionCount, false>
|
||||
: detail::equals::equals_always_false
|
||||
{};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Tag1, typename Tag2, std::size_t DimensionCount>
|
||||
struct equals<Geometry1, Geometry2, Tag1, Tag2, linear_tag, pointlike_tag, DimensionCount, false>
|
||||
: detail::equals::equals_always_false
|
||||
{};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Tag1, typename Tag2, std::size_t DimensionCount>
|
||||
struct equals<Geometry1, Geometry2, Tag1, Tag2, pointlike_tag, areal_tag, DimensionCount, false>
|
||||
: detail::equals::equals_always_false
|
||||
{};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Tag1, typename Tag2, std::size_t DimensionCount>
|
||||
struct equals<Geometry1, Geometry2, Tag1, Tag2, areal_tag, pointlike_tag, DimensionCount, false>
|
||||
: detail::equals::equals_always_false
|
||||
{};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Tag1, typename Tag2, std::size_t DimensionCount>
|
||||
struct equals<Geometry1, Geometry2, Tag1, Tag2, linear_tag, areal_tag, DimensionCount, false>
|
||||
: detail::equals::equals_always_false
|
||||
{};
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename Tag1, typename Tag2, std::size_t DimensionCount>
|
||||
struct equals<Geometry1, Geometry2, Tag1, Tag2, areal_tag, linear_tag, DimensionCount, false>
|
||||
: detail::equals::equals_always_false
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// Copyright (c) 2022 Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_IMPLEMENTATION_GC_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_IMPLEMENTATION_GC_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/algorithms/detail/equals/implementation.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/implementation_gc.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2, std::size_t DimensionCount>
|
||||
struct equals
|
||||
<
|
||||
Geometry1, Geometry2,
|
||||
geometry_collection_tag, geometry_collection_tag,
|
||||
geometry_collection_tag, geometry_collection_tag,
|
||||
DimensionCount, false
|
||||
>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_equals_type,
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1, typename CastedTag1,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct equals
|
||||
<
|
||||
Geometry1, Geometry2,
|
||||
Tag1, geometry_collection_tag,
|
||||
CastedTag1, geometry_collection_tag,
|
||||
DimensionCount, false
|
||||
>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using gc1_view_t = detail::geometry_collection_view<Geometry1>;
|
||||
return equals
|
||||
<
|
||||
gc1_view_t, Geometry2
|
||||
>::apply(gc1_view_t(geometry1), geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag2, typename CastedTag2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct equals
|
||||
<
|
||||
Geometry1, Geometry2,
|
||||
geometry_collection_tag, Tag2,
|
||||
geometry_collection_tag, CastedTag2,
|
||||
DimensionCount, false
|
||||
>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using gc2_view_t = detail::geometry_collection_view<Geometry2>;
|
||||
return equals
|
||||
<
|
||||
Geometry1, gc2_view_t
|
||||
>::apply(geometry1, gc2_view_t(geometry2), strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_IMPLEMENTATION_GC_HPP
|
||||
@@ -5,9 +5,8 @@
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2014, 2015, 2016, 2017.
|
||||
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
|
||||
|
||||
// This file was modified by Oracle on 2014-2022.
|
||||
// Modifications copyright (c) 2014-2022 Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
@@ -24,19 +23,19 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tag_cast.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/adapted/boost_variant.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/relate.hpp>
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
#include <boost/geometry/strategies/relate/services.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -52,6 +51,8 @@ template
|
||||
typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type,
|
||||
typename CastedTag1 = typename tag_cast<Tag1, pointlike_tag, linear_tag, areal_tag>::type,
|
||||
typename CastedTag2 = typename tag_cast<Tag2, pointlike_tag, linear_tag, areal_tag>::type,
|
||||
std::size_t DimensionCount = dimension<Geometry1>::type::value,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
@@ -64,10 +65,11 @@ template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1, typename Tag2,
|
||||
typename CastedTag1, typename CastedTag2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct equals<Geometry1, Geometry2, Tag1, Tag2, DimensionCount, true>
|
||||
: equals<Geometry2, Geometry1, Tag2, Tag1, DimensionCount, false>
|
||||
struct equals<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, DimensionCount, true>
|
||||
: equals<Geometry2, Geometry1, Tag2, Tag1, CastedTag2, CastedTag1, DimensionCount, false>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
|
||||
@@ -76,6 +78,7 @@ struct equals<Geometry1, Geometry2, Tag1, Tag2, DimensionCount, true>
|
||||
<
|
||||
Geometry2, Geometry1,
|
||||
Tag2, Tag1,
|
||||
CastedTag2, CastedTag1,
|
||||
DimensionCount,
|
||||
false
|
||||
>::apply(g2, g1, strategy);
|
||||
@@ -90,9 +93,14 @@ struct equals<Geometry1, Geometry2, Tag1, Tag2, DimensionCount, true>
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Strategy,
|
||||
bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
|
||||
>
|
||||
struct equals
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
@@ -102,13 +110,35 @@ struct equals
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
struct equals<Strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
using strategies::relate::services::strategy_converter;
|
||||
|
||||
return dispatch::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2,
|
||||
strategy_converter<Strategy>::get(strategy));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct equals<default_strategy, false>
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
typedef typename strategies::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
@@ -124,9 +154,14 @@ struct equals
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
namespace resolve_dynamic {
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1 = typename geometry::tag<Geometry1>::type,
|
||||
typename Tag2 = typename geometry::tag<Geometry2>::type
|
||||
>
|
||||
struct equals
|
||||
{
|
||||
template <typename Strategy>
|
||||
@@ -141,118 +176,73 @@ struct equals
|
||||
>();
|
||||
|
||||
return resolve_strategy::equals
|
||||
::apply(geometry1, geometry2, strategy);
|
||||
<
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
|
||||
struct equals<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
|
||||
template <typename Geometry1, typename Geometry2, typename Tag2>
|
||||
struct equals<Geometry1, Geometry2, dynamic_geometry_tag, Tag2>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor<bool>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
Geometry2 const& m_geometry2;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry2 const& geometry2, Strategy const& strategy)
|
||||
: m_geometry2(geometry2)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1>
|
||||
inline bool operator()(Geometry1 const& geometry1) const
|
||||
bool result = false;
|
||||
traits::visit<Geometry1>::apply([&](auto const& g1)
|
||||
{
|
||||
return equals<Geometry1, Geometry2>
|
||||
::apply(geometry1, m_geometry2, m_strategy);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy
|
||||
)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry2, strategy), geometry1);
|
||||
result = equals
|
||||
<
|
||||
util::remove_cref_t<decltype(g1)>,
|
||||
Geometry2
|
||||
>::apply(g1, geometry2, strategy);
|
||||
}, geometry1);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct equals<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
template <typename Geometry1, typename Geometry2, typename Tag1>
|
||||
struct equals<Geometry1, Geometry2, Tag1, dynamic_geometry_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor<bool>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
Geometry1 const& m_geometry1;
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Geometry1 const& geometry1, Strategy const& strategy)
|
||||
: m_geometry1(geometry1)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry2>
|
||||
inline bool operator()(Geometry2 const& geometry2) const
|
||||
bool result = false;
|
||||
traits::visit<Geometry2>::apply([&](auto const& g2)
|
||||
{
|
||||
return equals<Geometry1, Geometry2>
|
||||
::apply(m_geometry1, geometry2, m_strategy);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(
|
||||
Geometry1 const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
|
||||
Strategy const& strategy
|
||||
)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(geometry1, strategy), geometry2);
|
||||
result = equals
|
||||
<
|
||||
Geometry1,
|
||||
util::remove_cref_t<decltype(g2)>
|
||||
>::apply(geometry1, g2, strategy);
|
||||
}, geometry2);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T1),
|
||||
BOOST_VARIANT_ENUM_PARAMS(typename T2)
|
||||
>
|
||||
struct equals<
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
|
||||
>
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct equals<Geometry1, Geometry2, dynamic_geometry_tag, dynamic_geometry_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor<bool>
|
||||
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
Strategy const& m_strategy;
|
||||
|
||||
visitor(Strategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool operator()(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2) const
|
||||
bool result = false;
|
||||
traits::visit<Geometry1, Geometry2>::apply([&](auto const& g1, auto const& g2)
|
||||
{
|
||||
return equals<Geometry1, Geometry2>
|
||||
::apply(geometry1, geometry2, m_strategy);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
|
||||
boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
|
||||
Strategy const& strategy
|
||||
)
|
||||
{
|
||||
return boost::apply_visitor(visitor<Strategy>(strategy), geometry1, geometry2);
|
||||
result = equals
|
||||
<
|
||||
util::remove_cref_t<decltype(g1)>,
|
||||
util::remove_cref_t<decltype(g2)>
|
||||
>::apply(g1, g2, strategy);
|
||||
}, geometry1, geometry2);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
} // namespace resolve_dynamic
|
||||
|
||||
|
||||
/*!
|
||||
@@ -279,10 +269,10 @@ inline bool equals(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_variant::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
return resolve_dynamic::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
|
||||
@@ -305,8 +295,10 @@ inline bool equals(Geometry1 const& geometry1,
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
|
||||
{
|
||||
return resolve_variant::equals<Geometry1, Geometry2>
|
||||
::apply(geometry1, geometry2, default_strategy());
|
||||
return resolve_dynamic::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, default_strategy());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland
|
||||
|
||||
// This file was modified by Oracle on 2013-2018.
|
||||
// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2020.
|
||||
// Modifications copyright (c) 2013-2020, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
@@ -22,6 +22,11 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP
|
||||
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/geometry/strategies/detail.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
@@ -33,7 +38,23 @@ namespace detail { namespace equals
|
||||
\brief Internal utility function to detect of points are disjoint
|
||||
\note To avoid circular references
|
||||
*/
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
template
|
||||
<
|
||||
typename Point1, typename Point2, typename Strategy,
|
||||
std::enable_if_t<strategies::detail::is_umbrella_strategy<Strategy>::value, int> = 0
|
||||
>
|
||||
inline bool equals_point_point(Point1 const& point1, Point2 const& point2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef decltype(strategy.relate(point1, point2)) strategy_type;
|
||||
return strategy_type::apply(point1, point2);
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1, typename Point2, typename Strategy,
|
||||
std::enable_if_t<! strategies::detail::is_umbrella_strategy<Strategy>::value, int> = 0
|
||||
>
|
||||
inline bool equals_point_point(Point1 const& point1, Point2 const& point2,
|
||||
Strategy const& )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user