summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/equals.hpp
diff options
context:
space:
mode:
authorChanho Park <chanho61.park@samsung.com>2014-12-11 18:55:56 +0900
committerChanho Park <chanho61.park@samsung.com>2014-12-11 18:55:56 +0900
commit08c1e93fa36a49f49325a07fe91ff92c964c2b6c (patch)
tree7a7053ceb8874b28ec4b868d4c49b500008a102e /boost/geometry/algorithms/equals.hpp
parentbb4dd8289b351fae6b55e303f189127a394a1edd (diff)
downloadboost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.gz
boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.tar.bz2
boost-08c1e93fa36a49f49325a07fe91ff92c964c2b6c.zip
Imported Upstream version 1.57.0upstream/1.57.0
Diffstat (limited to 'boost/geometry/algorithms/equals.hpp')
-rw-r--r--boost/geometry/algorithms/equals.hpp361
1 files changed, 255 insertions, 106 deletions
diff --git a/boost/geometry/algorithms/equals.hpp b/boost/geometry/algorithms/equals.hpp
index 6b094f76d0..c6b718da1b 100644
--- a/boost/geometry/algorithms/equals.hpp
+++ b/boost/geometry/algorithms/equals.hpp
@@ -3,6 +3,12 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 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.
@@ -18,18 +24,19 @@
#include <cstddef>
#include <vector>
-#include <boost/mpl/if.hpp>
-#include <boost/static_assert.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/geometry_id.hpp>
#include <boost/geometry/core/reverse_dispatch.hpp>
+#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
-#include <boost/geometry/algorithms/detail/disjoint.hpp>
+#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/not.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
// For trivial checks
#include <boost/geometry/algorithms/area.hpp>
@@ -39,7 +46,12 @@
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/geometry/algorithms/detail/equals/collect_vectors.hpp>
+#include <boost/geometry/algorithms/detail/relate/relate.hpp>
+#include <boost/geometry/views/detail/indexed_point_view.hpp>
+
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/apply_visitor.hpp>
namespace boost { namespace geometry
{
@@ -51,13 +63,12 @@ namespace detail { namespace equals
template
<
- typename Box1,
- typename Box2,
std::size_t Dimension,
std::size_t DimensionCount
>
struct box_box
{
+ template <typename Box1, typename Box2>
static inline bool apply(Box1 const& box1, Box2 const& box2)
{
if (!geometry::math::equals(get<min_corner, Dimension>(box1), get<min_corner, Dimension>(box2))
@@ -65,13 +76,14 @@ struct box_box
{
return false;
}
- return box_box<Box1, Box2, Dimension + 1, DimensionCount>::apply(box1, box2);
+ return box_box<Dimension + 1, DimensionCount>::apply(box1, box2);
}
};
-template <typename Box1, typename Box2, std::size_t DimensionCount>
-struct box_box<Box1, Box2, DimensionCount, DimensionCount>
+template <std::size_t DimensionCount>
+struct box_box<DimensionCount, DimensionCount>
{
+ template <typename Box1, typename Box2>
static inline bool apply(Box1 const& , Box2 const& )
{
return true;
@@ -79,6 +91,28 @@ struct box_box<Box1, Box2, DimensionCount, DimensionCount>
};
+struct segment_segment
+{
+ template <typename Segment1, typename Segment2>
+ static inline bool apply(Segment1 const& segment1, Segment2 const& segment2)
+ {
+ return equals::equals_point_point(
+ indexed_point_view<Segment1 const, 0>(segment1),
+ indexed_point_view<Segment2 const, 0>(segment2) )
+ ? equals::equals_point_point(
+ indexed_point_view<Segment1 const, 1>(segment1),
+ indexed_point_view<Segment2 const, 1>(segment2) )
+ : ( equals::equals_point_point(
+ indexed_point_view<Segment1 const, 0>(segment1),
+ indexed_point_view<Segment2 const, 1>(segment2) )
+ && equals::equals_point_point(
+ indexed_point_view<Segment1 const, 1>(segment1),
+ indexed_point_view<Segment2 const, 0>(segment2) )
+ );
+ }
+};
+
+
struct area_check
{
template <typename Geometry1, typename Geometry2>
@@ -103,9 +137,10 @@ struct length_check
};
-template <typename Geometry1, typename Geometry2, typename TrivialCheck>
+template <typename TrivialCheck>
struct equals_by_collection
{
+ template <typename Geometry1, typename Geometry2>
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
if (! TrivialCheck::apply(geometry1, geometry2))
@@ -141,6 +176,15 @@ struct equals_by_collection
}
};
+template<typename Geometry1, typename Geometry2>
+struct equals_by_relate
+ : detail::relate::relate_base
+ <
+ detail::relate::static_mask_equals_type,
+ Geometry1,
+ Geometry2
+ >
+{};
}} // namespace detail::equals
#endif // DOXYGEN_NO_DETAIL
@@ -152,17 +196,42 @@ namespace dispatch
template
<
- typename Tag1, typename Tag2,
typename Geometry1,
typename Geometry2,
- std::size_t DimensionCount
+ 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
+struct equals: not_implemented<Tag1, Tag2>
{};
-template <typename P1, typename P2, std::size_t DimensionCount>
-struct equals<point_tag, point_tag, P1, P2, DimensionCount>
+// 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>
+{
+ static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ {
+ return equals
+ <
+ Geometry2, Geometry1,
+ Tag2, Tag1,
+ DimensionCount,
+ false
+ >::apply(g2, g1);
+ }
+};
+
+
+template <typename P1, typename P2, std::size_t DimensionCount, bool Reverse>
+struct equals<P1, P2, point_tag, point_tag, DimensionCount, Reverse>
: geometry::detail::not_
<
P1,
@@ -172,104 +241,208 @@ struct equals<point_tag, point_tag, P1, P2, DimensionCount>
{};
-template <typename Box1, typename Box2, std::size_t DimensionCount>
-struct equals<box_tag, box_tag, Box1, Box2, DimensionCount>
- : detail::equals::box_box<Box1, Box2, 0, DimensionCount>
+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>
-struct equals<ring_tag, ring_tag, Ring1, Ring2, 2>
- : detail::equals::equals_by_collection
- <
- Ring1, Ring2,
- detail::equals::area_check
- >
+template <typename Ring1, typename Ring2, bool Reverse>
+struct equals<Ring1, Ring2, ring_tag, ring_tag, 2, Reverse>
+ : detail::equals::equals_by_collection<detail::equals::area_check>
{};
-template <typename Polygon1, typename Polygon2>
-struct equals<polygon_tag, polygon_tag, Polygon1, Polygon2, 2>
- : detail::equals::equals_by_collection
- <
- Polygon1, Polygon2,
- 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<detail::equals::area_check>
{};
-template <typename LineString1, typename LineString2>
-struct equals<linestring_tag, linestring_tag, LineString1, LineString2, 2>
- : detail::equals::equals_by_collection
- <
- LineString1, LineString2,
- detail::equals::length_check
- >
+template <typename Polygon, typename Ring, bool Reverse>
+struct equals<Polygon, Ring, polygon_tag, ring_tag, 2, Reverse>
+ : detail::equals::equals_by_collection<detail::equals::area_check>
{};
-template <typename Polygon, typename Ring>
-struct equals<polygon_tag, ring_tag, Polygon, Ring, 2>
- : detail::equals::equals_by_collection
- <
- Polygon, Ring,
- 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 Ring, typename Box>
-struct equals<ring_tag, box_tag, Ring, Box, 2>
- : detail::equals::equals_by_collection
- <
- Ring, Box,
- 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 Polygon, typename Box>
-struct equals<polygon_tag, box_tag, Polygon, Box, 2>
- : detail::equals::equals_by_collection
- <
- Polygon, Box,
- detail::equals::area_check
- >
+template <typename LineString1, typename LineString2, bool Reverse>
+struct equals<LineString1, LineString2, linestring_tag, linestring_tag, 2, Reverse>
+ //: detail::equals::equals_by_collection<detail::equals::length_check>
+ : 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 Tag1, typename Tag2,
- typename Geometry1,
- typename Geometry2,
- std::size_t DimensionCount
->
-struct equals_reversed
+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<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<detail::equals::area_check>
+{};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+namespace resolve_variant {
+
+template <typename Geometry1, typename Geometry2>
+struct equals
{
- static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
+ static inline bool apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2)
{
- return equals
- <
- Tag2, Tag1,
- Geometry2, Geometry1,
- DimensionCount
- >::apply(g2, g1);
+ concept::check_concepts_and_equal_dimensions
+ <
+ Geometry1 const,
+ Geometry2 const
+ >();
+
+ return dispatch::equals<Geometry1, Geometry2>
+ ::apply(geometry1, geometry2);
}
};
+template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
+struct equals<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
+{
+ struct visitor: static_visitor<bool>
+ {
+ Geometry2 const& m_geometry2;
+
+ visitor(Geometry2 const& geometry2)
+ : m_geometry2(geometry2)
+ {}
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
+ template <typename Geometry1>
+ inline bool operator()(Geometry1 const& geometry1) const
+ {
+ return equals<Geometry1, Geometry2>
+ ::apply(geometry1, m_geometry2);
+ }
+
+ };
+
+ static inline bool apply(
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
+ Geometry2 const& geometry2
+ )
+ {
+ return apply_visitor(visitor(geometry2), geometry1);
+ }
+};
+
+template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
+struct equals<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+{
+ struct visitor: static_visitor<bool>
+ {
+ Geometry1 const& m_geometry1;
+
+ visitor(Geometry1 const& geometry1)
+ : m_geometry1(geometry1)
+ {}
+
+ template <typename Geometry2>
+ inline bool operator()(Geometry2 const& geometry2) const
+ {
+ return equals<Geometry1, Geometry2>
+ ::apply(m_geometry1, geometry2);
+ }
+
+ };
+
+ static inline bool apply(
+ Geometry1 const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2
+ )
+ {
+ return apply_visitor(visitor(geometry1), 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)>
+>
+{
+ struct visitor: static_visitor<bool>
+ {
+ template <typename Geometry1, typename Geometry2>
+ inline bool operator()(Geometry1 const& geometry1,
+ Geometry2 const& geometry2) const
+ {
+ return equals<Geometry1, Geometry2>
+ ::apply(geometry1, geometry2);
+ }
+
+ };
+
+ static inline bool apply(
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
+ boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2
+ )
+ {
+ return apply_visitor(visitor(), geometry1, geometry2);
+ }
+};
+
+} // namespace resolve_variant
/*!
\brief \brief_check{are spatially equal}
-\details \details_check12{equals, is spatially equal}. Spatially equal means
+\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 theoretically, not all combinations
- are implemented yet.
+ 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
@@ -283,32 +456,8 @@ struct equals_reversed
template <typename Geometry1, typename Geometry2>
inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
{
- concept::check_concepts_and_equal_dimensions
- <
- Geometry1 const,
- Geometry2 const
- >();
-
- return boost::mpl::if_c
- <
- reverse_dispatch<Geometry1, Geometry2>::type::value,
- dispatch::equals_reversed
- <
- typename tag<Geometry1>::type,
- typename tag<Geometry2>::type,
- Geometry1,
- Geometry2,
- dimension<Geometry1>::type::value
- >,
- dispatch::equals
- <
- typename tag<Geometry1>::type,
- typename tag<Geometry2>::type,
- Geometry1,
- Geometry2,
- dimension<Geometry1>::type::value
- >
- >::type::apply(geometry1, geometry2);
+ return resolve_variant::equals<Geometry1, Geometry2>
+ ::apply(geometry1, geometry2);
}