add boost on mac
This commit is contained in:
@@ -0,0 +1,575 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
|
||||
// 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.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP
|
||||
|
||||
|
||||
#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>
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/formulas/spherical.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/views/detail/normalized_view.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
|
||||
#include <boost/geometry/strategies/spherical/ssf.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
|
||||
>
|
||||
{
|
||||
typedef T type;
|
||||
|
||||
inline collected_vector()
|
||||
{}
|
||||
|
||||
inline collected_vector(T const& px, T const& py,
|
||||
T const& pdx, T const& pdy)
|
||||
: x(px)
|
||||
, y(py)
|
||||
, dx(pdx)
|
||||
, dy(pdy)
|
||||
//, dx_0(dx)
|
||||
//, dy_0(dy)
|
||||
{}
|
||||
|
||||
template <typename Point>
|
||||
inline collected_vector(Point const& p1, Point const& p2)
|
||||
: x(get<0>(p1))
|
||||
, y(get<1>(p1))
|
||||
, dx(get<0>(p2) - x)
|
||||
, dy(get<1>(p2) - y)
|
||||
//, dx_0(dx)
|
||||
//, dy_0(dy)
|
||||
{}
|
||||
|
||||
bool normalize()
|
||||
{
|
||||
T magnitude = math::sqrt(
|
||||
boost::numeric_cast<T>(dx * dx + dy * dy));
|
||||
|
||||
// NOTE: shouldn't here math::equals() be called?
|
||||
if (magnitude > 0)
|
||||
{
|
||||
dx /= magnitude;
|
||||
dy /= magnitude;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// For sorting
|
||||
inline bool operator<(collected_vector const& other) const
|
||||
{
|
||||
if (math::equals(x, other.x))
|
||||
{
|
||||
if (math::equals(y, other.y))
|
||||
{
|
||||
if (math::equals(dx, other.dx))
|
||||
{
|
||||
return dy < other.dy;
|
||||
}
|
||||
return dx < other.dx;
|
||||
}
|
||||
return y < other.y;
|
||||
}
|
||||
return x < other.x;
|
||||
}
|
||||
|
||||
inline bool next_is_collinear(collected_vector const& other) const
|
||||
{
|
||||
return same_direction(other);
|
||||
}
|
||||
|
||||
// For std::equals
|
||||
inline bool operator==(collected_vector const& other) const
|
||||
{
|
||||
return math::equals(x, other.x)
|
||||
&& math::equals(y, other.y)
|
||||
&& same_direction(other);
|
||||
}
|
||||
|
||||
private:
|
||||
inline bool same_direction(collected_vector 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)
|
||||
return math::equals_with_epsilon(dx, other.dx)
|
||||
&& math::equals_with_epsilon(dy, other.dy);
|
||||
}
|
||||
|
||||
T x, y;
|
||||
T dx, dy;
|
||||
//T dx_0, dy_0;
|
||||
};
|
||||
|
||||
// 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
|
||||
>
|
||||
{
|
||||
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()
|
||||
{}
|
||||
|
||||
template <typename Point>
|
||||
collected_vector(Point const& p1, Point const& p2)
|
||||
: origin(get<0>(p1), get<1>(p1))
|
||||
{
|
||||
origin = detail::return_normalized<point_type>(origin);
|
||||
|
||||
using namespace geometry::formula;
|
||||
prev = sph_to_cart3d<vector_type>(p1);
|
||||
next = sph_to_cart3d<vector_type>(p2);
|
||||
direction = cross_product(prev, next);
|
||||
}
|
||||
|
||||
bool normalize()
|
||||
{
|
||||
T magnitude_sqr = dot_product(direction, direction);
|
||||
|
||||
// NOTE: shouldn't here math::equals() be called?
|
||||
if (magnitude_sqr > 0)
|
||||
{
|
||||
divide_value(direction, math::sqrt(magnitude_sqr));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator<(collected_vector const& other) const
|
||||
{
|
||||
if (math::equals(get<0>(origin), get<0>(other.origin)))
|
||||
{
|
||||
if (math::equals(get<1>(origin), get<1>(other.origin)))
|
||||
{
|
||||
if (math::equals(get<0>(direction), get<0>(other.direction)))
|
||||
{
|
||||
if (math::equals(get<1>(direction), get<1>(other.direction)))
|
||||
{
|
||||
return get<2>(direction) < get<2>(other.direction);
|
||||
}
|
||||
return get<1>(direction) < get<1>(other.direction);
|
||||
}
|
||||
return get<0>(direction) < get<0>(other.direction);
|
||||
}
|
||||
return get<1>(origin) < get<1>(other.origin);
|
||||
}
|
||||
return get<0>(origin) < get<0>(other.origin);
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
return formula::sph_side_value(direction, other.next) == 0;
|
||||
}
|
||||
|
||||
// For std::equals
|
||||
bool operator==(collected_vector const& other) const
|
||||
{
|
||||
return math::equals(get<0>(origin), get<0>(other.origin))
|
||||
&& math::equals(get<1>(origin), get<1>(other.origin))
|
||||
&& is_collinear(other);
|
||||
}
|
||||
|
||||
private:
|
||||
// For consistency with side and intersection strategies used by relops
|
||||
bool is_collinear(collected_vector const& other) const
|
||||
{
|
||||
return formula::sph_side_value(direction, other.prev) == 0
|
||||
&& formula::sph_side_value(direction, 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
|
||||
vector_type direction; // used for sorting, only in operator<
|
||||
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
|
||||
>
|
||||
{
|
||||
typedef collected_vector
|
||||
<
|
||||
T, Geometry,
|
||||
strategy::side::spherical_side_formula<CT>,
|
||||
spherical_equatorial_tag
|
||||
> base_type;
|
||||
|
||||
collected_vector() {}
|
||||
|
||||
template <typename Point>
|
||||
collected_vector(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)
|
||||
{
|
||||
typedef typename coordinate_type<Point>::type coord_type;
|
||||
|
||||
typedef math::detail::constants_on_spheroid
|
||||
<
|
||||
coord_type,
|
||||
typename coordinate_system<Point>::type::units
|
||||
> constants;
|
||||
|
||||
coord_type const pi_2 = constants::half_period() / 2;
|
||||
|
||||
Point res = p;
|
||||
set<1>(res, pi_2 - get<1>(p));
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace collect_vectors
|
||||
{
|
||||
|
||||
|
||||
template <typename Range, typename Collection>
|
||||
struct range_collect_vectors
|
||||
{
|
||||
typedef typename boost::range_value<Collection>::type item_type;
|
||||
typedef typename item_type::type calculation_type;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename NormalizedRange>
|
||||
static inline void apply_impl(Collection& collection, NormalizedRange 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;
|
||||
|
||||
bool is_first = true;
|
||||
iterator it = boost::begin(range);
|
||||
|
||||
for (iterator prev = it++;
|
||||
it != boost::end(range);
|
||||
prev = it++)
|
||||
{
|
||||
typename boost::range_value<Collection>::type v(*prev, *it);
|
||||
|
||||
// Normalize the vector -> this results in points+direction
|
||||
// and is comparible between geometries
|
||||
// Avoid non-duplicate points (AND division by zero)
|
||||
if (v.normalize())
|
||||
{
|
||||
// Avoid non-direction changing points
|
||||
if (is_first || ! collection.back().next_is_collinear(v))
|
||||
{
|
||||
collection.push_back(v);
|
||||
}
|
||||
is_first = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
//collection.erase(first);
|
||||
// O(1) instead of O(N)
|
||||
*first = collection.back();
|
||||
collection.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Default version (cartesian)
|
||||
template <typename Box, typename Collection, typename CSTag = typename cs_tag<Box>::type>
|
||||
struct box_collect_vectors
|
||||
{
|
||||
// Calculate on coordinate type, but if it is integer,
|
||||
// then use double
|
||||
typedef typename boost::range_value<Collection>::type item_type;
|
||||
typedef typename item_type::type calculation_type;
|
||||
|
||||
static inline void apply(Collection& collection, Box const& box)
|
||||
{
|
||||
typename point_type<Box>::type lower_left, lower_right,
|
||||
upper_left, upper_right;
|
||||
geometry::detail::assign_box_corners(box, lower_left, lower_right,
|
||||
upper_left, upper_right);
|
||||
|
||||
typedef typename boost::range_value<Collection>::type item;
|
||||
|
||||
collection.push_back(item(get<0>(lower_left), get<1>(lower_left), 0, 1));
|
||||
collection.push_back(item(get<0>(upper_left), get<1>(upper_left), 1, 0));
|
||||
collection.push_back(item(get<0>(upper_right), get<1>(upper_right), 0, -1));
|
||||
collection.push_back(item(get<0>(lower_right), get<1>(lower_right), -1, 0));
|
||||
}
|
||||
};
|
||||
|
||||
// NOTE: This is not fully correct because Box in spherical and geographic
|
||||
// cordinate systems cannot be seen as Polygon
|
||||
template <typename Box, typename Collection>
|
||||
struct box_collect_vectors<Box, Collection, spherical_equatorial_tag>
|
||||
{
|
||||
static inline void apply(Collection& collection, Box const& box)
|
||||
{
|
||||
typename point_type<Box>::type lower_left, lower_right,
|
||||
upper_left, upper_right;
|
||||
geometry::detail::assign_box_corners(box, lower_left, lower_right,
|
||||
upper_left, upper_right);
|
||||
|
||||
typedef typename boost::range_value<Collection>::type item;
|
||||
|
||||
collection.push_back(item(lower_left, upper_left));
|
||||
collection.push_back(item(upper_left, upper_right));
|
||||
collection.push_back(item(upper_right, lower_right));
|
||||
collection.push_back(item(lower_right, lower_left));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box, typename Collection>
|
||||
struct box_collect_vectors<Box, Collection, spherical_polar_tag>
|
||||
: box_collect_vectors<Box, Collection, spherical_equatorial_tag>
|
||||
{};
|
||||
|
||||
template <typename Box, typename Collection>
|
||||
struct box_collect_vectors<Box, Collection, geographic_tag>
|
||||
: box_collect_vectors<Box, Collection, spherical_equatorial_tag>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename Collection>
|
||||
struct polygon_collect_vectors
|
||||
{
|
||||
static inline void apply(Collection& collection, Polygon const& polygon)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
|
||||
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)
|
||||
{
|
||||
per_range::apply(collection, *it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiGeometry, typename Collection, typename SinglePolicy>
|
||||
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)
|
||||
{
|
||||
SinglePolicy::apply(collection, *it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::collect_vectors
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Tag,
|
||||
typename Collection,
|
||||
typename Geometry
|
||||
>
|
||||
struct collect_vectors
|
||||
{
|
||||
static inline void apply(Collection&, Geometry const&)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template <typename Collection, typename Box>
|
||||
struct collect_vectors<box_tag, Collection, Box>
|
||||
: detail::collect_vectors::box_collect_vectors<Box, Collection>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
template <typename Collection, typename Ring>
|
||||
struct collect_vectors<ring_tag, Collection, Ring>
|
||||
: detail::collect_vectors::range_collect_vectors<Ring, Collection>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Collection, typename LineString>
|
||||
struct collect_vectors<linestring_tag, Collection, LineString>
|
||||
: detail::collect_vectors::range_collect_vectors<LineString, Collection>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Collection, typename Polygon>
|
||||
struct collect_vectors<polygon_tag, Collection, Polygon>
|
||||
: detail::collect_vectors::polygon_collect_vectors<Polygon, Collection>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Collection, typename MultiPolygon>
|
||||
struct collect_vectors<multi_polygon_tag, Collection, MultiPolygon>
|
||||
: detail::collect_vectors::multi_collect_vectors
|
||||
<
|
||||
MultiPolygon,
|
||||
Collection,
|
||||
detail::collect_vectors::polygon_collect_vectors
|
||||
<
|
||||
typename boost::range_value<MultiPolygon>::type,
|
||||
Collection
|
||||
>
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup collect_vectors
|
||||
\tparam Collection Collection type, should be e.g. std::vector<>
|
||||
\tparam Geometry geometry type
|
||||
\param collection the collection of vectors
|
||||
\param geometry the geometry to make collect_vectors
|
||||
*/
|
||||
template <typename Collection, typename Geometry>
|
||||
inline void collect_vectors(Collection& collection, Geometry const& geometry)
|
||||
{
|
||||
concepts::check<Geometry const>();
|
||||
|
||||
dispatch::collect_vectors
|
||||
<
|
||||
typename tag<Geometry>::type,
|
||||
Collection,
|
||||
Geometry
|
||||
>::apply(collection, geometry);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_COLLECT_VECTORS_HPP
|
||||
@@ -0,0 +1,401 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
// 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.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_IMPLEMENTATION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_IMPLEMENTATION_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/type_traits/is_base_of.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/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>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace equals
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct point_point
|
||||
{
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& )
|
||||
{
|
||||
return Strategy::apply(point1, point2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct box_box
|
||||
{
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
|
||||
{
|
||||
if (!geometry::math::equals(get<min_corner, Dimension>(box1), get<min_corner, Dimension>(box2))
|
||||
|| !geometry::math::equals(get<max_corner, Dimension>(box1), get<max_corner, Dimension>(box2)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return box_box<Dimension + 1, DimensionCount>::apply(box1, box2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t DimensionCount>
|
||||
struct box_box<DimensionCount, DimensionCount>
|
||||
{
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
static inline bool apply(Box1 const& , Box2 const& , Strategy const& )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct segment_segment
|
||||
{
|
||||
template <typename Segment1, typename Segment2, typename Strategy>
|
||||
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)
|
||||
? equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 1>(segment1),
|
||||
indexed_point_view<Segment2 const, 1>(segment2),
|
||||
pt_pt_strategy)
|
||||
: ( equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 0>(segment1),
|
||||
indexed_point_view<Segment2 const, 1>(segment2),
|
||||
pt_pt_strategy)
|
||||
&& equals::equals_point_point(
|
||||
indexed_point_view<Segment1 const, 1>(segment1),
|
||||
indexed_point_view<Segment2 const, 0>(segment2),
|
||||
pt_pt_strategy)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct area_check
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
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>()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct length_check
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
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>()));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2, typename IntersectionStrategy>
|
||||
struct collected_vector
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
template <typename TrivialCheck>
|
||||
struct equals_by_collection
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if (! TrivialCheck::apply(geometry1, geometry2, strategy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef typename collected_vector
|
||||
<
|
||||
Geometry1, Geometry2, Strategy
|
||||
>::type collected_vector_type;
|
||||
|
||||
std::vector<collected_vector_type> c1, c2;
|
||||
|
||||
geometry::collect_vectors(c1, geometry1);
|
||||
geometry::collect_vectors(c2, geometry2);
|
||||
|
||||
if (boost::size(c1) != boost::size(c2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::sort(c1.begin(), c1.end());
|
||||
std::sort(c2.begin(), c2.end());
|
||||
|
||||
// Just check if these vectors are equal.
|
||||
return std::equal(c1.begin(), c1.end(), c2.begin());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Geometry1, typename Geometry2>
|
||||
struct equals_by_relate
|
||||
: detail::relate::relate_impl
|
||||
<
|
||||
detail::de9im::static_mask_equals_type,
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>
|
||||
{};
|
||||
|
||||
// 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.
|
||||
// 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>
|
||||
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>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy,
|
||||
boost::true_type /*enable_relate*/)
|
||||
{
|
||||
return equals_by_relate<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::equals
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename P1, typename P2, std::size_t DimensionCount, bool Reverse>
|
||||
struct equals<P1, P2, point_tag, point_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>
|
||||
: 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>
|
||||
: 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>
|
||||
: detail::equals::box_box<0, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Ring1, typename Ring2, bool Reverse>
|
||||
struct equals<Ring1, Ring2, ring_tag, ring_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>
|
||||
: 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>
|
||||
: 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>
|
||||
: 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>
|
||||
: 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>
|
||||
: detail::equals::segment_segment
|
||||
{};
|
||||
|
||||
template <typename LineString1, typename LineString2, bool Reverse>
|
||||
struct equals<LineString1, LineString2, linestring_tag, linestring_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>
|
||||
: 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>
|
||||
: detail::equals::equals_by_relate<MultiLineString1, MultiLineString2>
|
||||
{};
|
||||
|
||||
|
||||
template <typename MultiPolygon1, typename MultiPolygon2, bool Reverse>
|
||||
struct equals
|
||||
<
|
||||
MultiPolygon1, MultiPolygon2,
|
||||
multi_polygon_tag, multi_polygon_tag,
|
||||
2,
|
||||
Reverse
|
||||
>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon, typename MultiPolygon, bool Reverse>
|
||||
struct equals
|
||||
<
|
||||
Polygon, MultiPolygon,
|
||||
polygon_tag, multi_polygon_tag,
|
||||
2,
|
||||
Reverse
|
||||
>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon, typename Ring, bool Reverse>
|
||||
struct equals
|
||||
<
|
||||
MultiPolygon, Ring,
|
||||
multi_polygon_tag, ring_tag,
|
||||
2,
|
||||
Reverse
|
||||
>
|
||||
: detail::equals::equals_by_collection_or_relate<detail::equals::area_check>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_IMPLEMENTATION_HPP
|
||||
|
||||
@@ -0,0 +1,317 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
// 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.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_INTERFACE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_INTERFACE_HPP
|
||||
|
||||
|
||||
#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/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/default_strategy.hpp>
|
||||
#include <boost/geometry/strategies/relate.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Tag1 = typename tag<Geometry1>::type,
|
||||
typename Tag2 = typename tag<Geometry2>::type,
|
||||
std::size_t DimensionCount = dimension<Geometry1>::type::value,
|
||||
bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
|
||||
>
|
||||
struct equals: not_implemented<Tag1, Tag2>
|
||||
{};
|
||||
|
||||
|
||||
// If reversal is needed, perform it
|
||||
template
|
||||
<
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename Tag1, typename Tag2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct equals<Geometry1, Geometry2, Tag1, Tag2, DimensionCount, true>
|
||||
: equals<Geometry2, Geometry1, Tag2, Tag1, DimensionCount, false>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
|
||||
{
|
||||
return equals
|
||||
<
|
||||
Geometry2, Geometry1,
|
||||
Tag2, Tag1,
|
||||
DimensionCount,
|
||||
false
|
||||
>::apply(g2, g1, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
namespace resolve_strategy
|
||||
{
|
||||
|
||||
struct equals
|
||||
{
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return dispatch::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
default_strategy)
|
||||
{
|
||||
typedef typename strategy::relate::services::default_strategy
|
||||
<
|
||||
Geometry1,
|
||||
Geometry2
|
||||
>::type strategy_type;
|
||||
|
||||
return dispatch::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy_type());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_strategy
|
||||
|
||||
|
||||
namespace resolve_variant {
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct equals
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concepts::check_concepts_and_equal_dimensions
|
||||
<
|
||||
Geometry1 const,
|
||||
Geometry2 const
|
||||
>();
|
||||
|
||||
return resolve_strategy::equals
|
||||
::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 Strategy>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct equals<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
template <typename Strategy>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
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 Strategy>
|
||||
struct visitor: static_visitor<bool>
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace resolve_variant
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check{are spatially equal}
|
||||
\details \details_check12{equals, is spatially equal}. Spatially equal means
|
||||
that the same point set is included. A box can therefore be spatially equal
|
||||
to a ring or a polygon, or a linestring can be spatially equal to a
|
||||
multi-linestring or a segment. This only works theoretically, not all
|
||||
combinations are implemented yet.
|
||||
\ingroup equals
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\tparam Strategy \tparam_strategy{Equals}
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param strategy \param_strategy{equals}
|
||||
\return \return_check2{are spatially equal}
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{[include reference/algorithms/equals.qbk]}
|
||||
*/
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool equals(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return resolve_variant::equals
|
||||
<
|
||||
Geometry1, Geometry2
|
||||
>::apply(geometry1, geometry2, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_check{are spatially equal}
|
||||
\details \details_check12{equals, is spatially equal}. Spatially equal means
|
||||
that the same point set is included. A box can therefore be spatially equal
|
||||
to a ring or a polygon, or a linestring can be spatially equal to a
|
||||
multi-linestring or a segment. This only works theoretically, not all
|
||||
combinations are implemented yet.
|
||||
\ingroup equals
|
||||
\tparam Geometry1 \tparam_geometry
|
||||
\tparam Geometry2 \tparam_geometry
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\return \return_check2{are spatially equal}
|
||||
|
||||
\qbk{[include reference/algorithms/equals.qbk]}
|
||||
*/
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_INTERFACE_HPP
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
|
||||
// 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.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
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>
|
||||
inline bool equals_point_point(Point1 const& point1, Point2 const& point2,
|
||||
Strategy const& )
|
||||
{
|
||||
return Strategy::apply(point1, point2);
|
||||
}
|
||||
|
||||
}} // namespace detail::equals
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP
|
||||
Reference in New Issue
Block a user