annotate DEPENDENCIES/generic/include/boost/geometry/algorithms/equals.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // Boost.Geometry (aka GGL, Generic Geometry Library)
Chris@16 2
Chris@101 3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
Chris@101 4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
Chris@101 5 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
Chris@101 6 // Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
Chris@101 7
Chris@101 8 // This file was modified by Oracle on 2014, 2015.
Chris@101 9 // Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
Chris@101 10
Chris@101 11 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
Chris@101 12 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
Chris@16 13
Chris@16 14 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
Chris@16 15 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
Chris@16 16
Chris@16 17 // Use, modification and distribution is subject to the Boost Software License,
Chris@16 18 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 19 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 20
Chris@16 21 #ifndef BOOST_GEOMETRY_ALGORITHMS_EQUALS_HPP
Chris@16 22 #define BOOST_GEOMETRY_ALGORITHMS_EQUALS_HPP
Chris@16 23
Chris@16 24
Chris@16 25 #include <cstddef>
Chris@16 26 #include <vector>
Chris@16 27
Chris@16 28 #include <boost/range.hpp>
Chris@16 29
Chris@101 30 #include <boost/variant/apply_visitor.hpp>
Chris@101 31 #include <boost/variant/static_visitor.hpp>
Chris@101 32 #include <boost/variant/variant_fwd.hpp>
Chris@101 33
Chris@16 34 #include <boost/geometry/core/access.hpp>
Chris@16 35 #include <boost/geometry/core/coordinate_dimension.hpp>
Chris@101 36 #include <boost/geometry/core/geometry_id.hpp>
Chris@16 37 #include <boost/geometry/core/reverse_dispatch.hpp>
Chris@101 38 #include <boost/geometry/core/tags.hpp>
Chris@16 39
Chris@16 40 #include <boost/geometry/geometries/concepts/check.hpp>
Chris@16 41
Chris@101 42 #include <boost/geometry/algorithms/detail/equals/point_point.hpp>
Chris@16 43 #include <boost/geometry/algorithms/detail/not.hpp>
Chris@16 44 #include <boost/geometry/algorithms/not_implemented.hpp>
Chris@16 45
Chris@16 46 // For trivial checks
Chris@16 47 #include <boost/geometry/algorithms/area.hpp>
Chris@16 48 #include <boost/geometry/algorithms/length.hpp>
Chris@16 49 #include <boost/geometry/util/math.hpp>
Chris@16 50 #include <boost/geometry/util/select_coordinate_type.hpp>
Chris@16 51 #include <boost/geometry/util/select_most_precise.hpp>
Chris@16 52
Chris@16 53 #include <boost/geometry/algorithms/detail/equals/collect_vectors.hpp>
Chris@101 54 #include <boost/geometry/algorithms/detail/relate/relate.hpp>
Chris@16 55
Chris@101 56 #include <boost/geometry/views/detail/indexed_point_view.hpp>
Chris@16 57
Chris@16 58
Chris@16 59 namespace boost { namespace geometry
Chris@16 60 {
Chris@16 61
Chris@16 62 #ifndef DOXYGEN_NO_DETAIL
Chris@16 63 namespace detail { namespace equals
Chris@16 64 {
Chris@16 65
Chris@16 66
Chris@16 67 template
Chris@16 68 <
Chris@16 69 std::size_t Dimension,
Chris@16 70 std::size_t DimensionCount
Chris@16 71 >
Chris@16 72 struct box_box
Chris@16 73 {
Chris@16 74 template <typename Box1, typename Box2>
Chris@16 75 static inline bool apply(Box1 const& box1, Box2 const& box2)
Chris@16 76 {
Chris@16 77 if (!geometry::math::equals(get<min_corner, Dimension>(box1), get<min_corner, Dimension>(box2))
Chris@16 78 || !geometry::math::equals(get<max_corner, Dimension>(box1), get<max_corner, Dimension>(box2)))
Chris@16 79 {
Chris@16 80 return false;
Chris@16 81 }
Chris@16 82 return box_box<Dimension + 1, DimensionCount>::apply(box1, box2);
Chris@16 83 }
Chris@16 84 };
Chris@16 85
Chris@16 86 template <std::size_t DimensionCount>
Chris@16 87 struct box_box<DimensionCount, DimensionCount>
Chris@16 88 {
Chris@16 89 template <typename Box1, typename Box2>
Chris@16 90 static inline bool apply(Box1 const& , Box2 const& )
Chris@16 91 {
Chris@16 92 return true;
Chris@16 93 }
Chris@16 94 };
Chris@16 95
Chris@16 96
Chris@101 97 struct segment_segment
Chris@101 98 {
Chris@101 99 template <typename Segment1, typename Segment2>
Chris@101 100 static inline bool apply(Segment1 const& segment1, Segment2 const& segment2)
Chris@101 101 {
Chris@101 102 return equals::equals_point_point(
Chris@101 103 indexed_point_view<Segment1 const, 0>(segment1),
Chris@101 104 indexed_point_view<Segment2 const, 0>(segment2) )
Chris@101 105 ? equals::equals_point_point(
Chris@101 106 indexed_point_view<Segment1 const, 1>(segment1),
Chris@101 107 indexed_point_view<Segment2 const, 1>(segment2) )
Chris@101 108 : ( equals::equals_point_point(
Chris@101 109 indexed_point_view<Segment1 const, 0>(segment1),
Chris@101 110 indexed_point_view<Segment2 const, 1>(segment2) )
Chris@101 111 && equals::equals_point_point(
Chris@101 112 indexed_point_view<Segment1 const, 1>(segment1),
Chris@101 113 indexed_point_view<Segment2 const, 0>(segment2) )
Chris@101 114 );
Chris@101 115 }
Chris@101 116 };
Chris@101 117
Chris@101 118
Chris@16 119 struct area_check
Chris@16 120 {
Chris@16 121 template <typename Geometry1, typename Geometry2>
Chris@16 122 static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
Chris@16 123 {
Chris@16 124 return geometry::math::equals(
Chris@16 125 geometry::area(geometry1),
Chris@16 126 geometry::area(geometry2));
Chris@16 127 }
Chris@16 128 };
Chris@16 129
Chris@16 130
Chris@16 131 struct length_check
Chris@16 132 {
Chris@16 133 template <typename Geometry1, typename Geometry2>
Chris@16 134 static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
Chris@16 135 {
Chris@16 136 return geometry::math::equals(
Chris@16 137 geometry::length(geometry1),
Chris@16 138 geometry::length(geometry2));
Chris@16 139 }
Chris@16 140 };
Chris@16 141
Chris@16 142
Chris@16 143 template <typename TrivialCheck>
Chris@16 144 struct equals_by_collection
Chris@16 145 {
Chris@16 146 template <typename Geometry1, typename Geometry2>
Chris@16 147 static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
Chris@16 148 {
Chris@16 149 if (! TrivialCheck::apply(geometry1, geometry2))
Chris@16 150 {
Chris@16 151 return false;
Chris@16 152 }
Chris@16 153
Chris@16 154 typedef typename geometry::select_most_precise
Chris@16 155 <
Chris@16 156 typename select_coordinate_type
Chris@16 157 <
Chris@16 158 Geometry1, Geometry2
Chris@16 159 >::type,
Chris@16 160 double
Chris@16 161 >::type calculation_type;
Chris@16 162
Chris@16 163 typedef std::vector<collected_vector<calculation_type> > v;
Chris@16 164 v c1, c2;
Chris@16 165
Chris@16 166 geometry::collect_vectors(c1, geometry1);
Chris@16 167 geometry::collect_vectors(c2, geometry2);
Chris@16 168
Chris@16 169 if (boost::size(c1) != boost::size(c2))
Chris@16 170 {
Chris@16 171 return false;
Chris@16 172 }
Chris@16 173
Chris@16 174 std::sort(c1.begin(), c1.end());
Chris@16 175 std::sort(c2.begin(), c2.end());
Chris@16 176
Chris@16 177 // Just check if these vectors are equal.
Chris@16 178 return std::equal(c1.begin(), c1.end(), c2.begin());
Chris@16 179 }
Chris@16 180 };
Chris@16 181
Chris@101 182 template<typename Geometry1, typename Geometry2>
Chris@101 183 struct equals_by_relate
Chris@101 184 : detail::relate::relate_base
Chris@101 185 <
Chris@101 186 detail::relate::static_mask_equals_type,
Chris@101 187 Geometry1,
Chris@101 188 Geometry2
Chris@101 189 >
Chris@101 190 {};
Chris@16 191
Chris@16 192 }} // namespace detail::equals
Chris@16 193 #endif // DOXYGEN_NO_DETAIL
Chris@16 194
Chris@16 195
Chris@16 196 #ifndef DOXYGEN_NO_DISPATCH
Chris@16 197 namespace dispatch
Chris@16 198 {
Chris@16 199
Chris@16 200 template
Chris@16 201 <
Chris@16 202 typename Geometry1,
Chris@16 203 typename Geometry2,
Chris@16 204 typename Tag1 = typename tag<Geometry1>::type,
Chris@16 205 typename Tag2 = typename tag<Geometry2>::type,
Chris@16 206 std::size_t DimensionCount = dimension<Geometry1>::type::value,
Chris@16 207 bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
Chris@16 208 >
Chris@16 209 struct equals: not_implemented<Tag1, Tag2>
Chris@16 210 {};
Chris@16 211
Chris@16 212
Chris@16 213 // If reversal is needed, perform it
Chris@16 214 template
Chris@16 215 <
Chris@16 216 typename Geometry1, typename Geometry2,
Chris@16 217 typename Tag1, typename Tag2,
Chris@16 218 std::size_t DimensionCount
Chris@16 219 >
Chris@16 220 struct equals<Geometry1, Geometry2, Tag1, Tag2, DimensionCount, true>
Chris@16 221 : equals<Geometry2, Geometry1, Tag2, Tag1, DimensionCount, false>
Chris@16 222 {
Chris@16 223 static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
Chris@16 224 {
Chris@16 225 return equals
Chris@16 226 <
Chris@16 227 Geometry2, Geometry1,
Chris@16 228 Tag2, Tag1,
Chris@16 229 DimensionCount,
Chris@16 230 false
Chris@16 231 >::apply(g2, g1);
Chris@16 232 }
Chris@16 233 };
Chris@16 234
Chris@16 235
Chris@16 236 template <typename P1, typename P2, std::size_t DimensionCount, bool Reverse>
Chris@16 237 struct equals<P1, P2, point_tag, point_tag, DimensionCount, Reverse>
Chris@16 238 : geometry::detail::not_
Chris@16 239 <
Chris@16 240 detail::disjoint::point_point<P1, P2, 0, DimensionCount>
Chris@16 241 >
Chris@16 242 {};
Chris@16 243
Chris@16 244
Chris@16 245 template <typename Box1, typename Box2, std::size_t DimensionCount, bool Reverse>
Chris@16 246 struct equals<Box1, Box2, box_tag, box_tag, DimensionCount, Reverse>
Chris@16 247 : detail::equals::box_box<0, DimensionCount>
Chris@16 248 {};
Chris@16 249
Chris@16 250
Chris@16 251 template <typename Ring1, typename Ring2, bool Reverse>
Chris@16 252 struct equals<Ring1, Ring2, ring_tag, ring_tag, 2, Reverse>
Chris@16 253 : detail::equals::equals_by_collection<detail::equals::area_check>
Chris@16 254 {};
Chris@16 255
Chris@16 256
Chris@16 257 template <typename Polygon1, typename Polygon2, bool Reverse>
Chris@16 258 struct equals<Polygon1, Polygon2, polygon_tag, polygon_tag, 2, Reverse>
Chris@16 259 : detail::equals::equals_by_collection<detail::equals::area_check>
Chris@16 260 {};
Chris@16 261
Chris@16 262
Chris@16 263 template <typename Polygon, typename Ring, bool Reverse>
Chris@16 264 struct equals<Polygon, Ring, polygon_tag, ring_tag, 2, Reverse>
Chris@16 265 : detail::equals::equals_by_collection<detail::equals::area_check>
Chris@16 266 {};
Chris@16 267
Chris@16 268
Chris@16 269 template <typename Ring, typename Box, bool Reverse>
Chris@16 270 struct equals<Ring, Box, ring_tag, box_tag, 2, Reverse>
Chris@16 271 : detail::equals::equals_by_collection<detail::equals::area_check>
Chris@16 272 {};
Chris@16 273
Chris@16 274
Chris@16 275 template <typename Polygon, typename Box, bool Reverse>
Chris@16 276 struct equals<Polygon, Box, polygon_tag, box_tag, 2, Reverse>
Chris@16 277 : detail::equals::equals_by_collection<detail::equals::area_check>
Chris@16 278 {};
Chris@16 279
Chris@101 280 template <typename Segment1, typename Segment2, std::size_t DimensionCount, bool Reverse>
Chris@101 281 struct equals<Segment1, Segment2, segment_tag, segment_tag, DimensionCount, Reverse>
Chris@101 282 : detail::equals::segment_segment
Chris@101 283 {};
Chris@101 284
Chris@101 285 template <typename LineString1, typename LineString2, bool Reverse>
Chris@101 286 struct equals<LineString1, LineString2, linestring_tag, linestring_tag, 2, Reverse>
Chris@101 287 //: detail::equals::equals_by_collection<detail::equals::length_check>
Chris@101 288 : detail::equals::equals_by_relate<LineString1, LineString2>
Chris@101 289 {};
Chris@101 290
Chris@101 291 template <typename LineString, typename MultiLineString, bool Reverse>
Chris@101 292 struct equals<LineString, MultiLineString, linestring_tag, multi_linestring_tag, 2, Reverse>
Chris@101 293 : detail::equals::equals_by_relate<LineString, MultiLineString>
Chris@101 294 {};
Chris@101 295
Chris@101 296 template <typename MultiLineString1, typename MultiLineString2, bool Reverse>
Chris@101 297 struct equals<MultiLineString1, MultiLineString2, multi_linestring_tag, multi_linestring_tag, 2, Reverse>
Chris@101 298 : detail::equals::equals_by_relate<MultiLineString1, MultiLineString2>
Chris@101 299 {};
Chris@101 300
Chris@101 301
Chris@101 302 template <typename MultiPolygon1, typename MultiPolygon2, bool Reverse>
Chris@101 303 struct equals
Chris@101 304 <
Chris@101 305 MultiPolygon1, MultiPolygon2,
Chris@101 306 multi_polygon_tag, multi_polygon_tag,
Chris@101 307 2,
Chris@101 308 Reverse
Chris@101 309 >
Chris@101 310 : detail::equals::equals_by_collection<detail::equals::area_check>
Chris@101 311 {};
Chris@101 312
Chris@101 313
Chris@101 314 template <typename Polygon, typename MultiPolygon, bool Reverse>
Chris@101 315 struct equals
Chris@101 316 <
Chris@101 317 Polygon, MultiPolygon,
Chris@101 318 polygon_tag, multi_polygon_tag,
Chris@101 319 2,
Chris@101 320 Reverse
Chris@101 321 >
Chris@101 322 : detail::equals::equals_by_collection<detail::equals::area_check>
Chris@101 323 {};
Chris@101 324
Chris@101 325
Chris@101 326 } // namespace dispatch
Chris@101 327 #endif // DOXYGEN_NO_DISPATCH
Chris@101 328
Chris@101 329
Chris@101 330 namespace resolve_variant {
Chris@16 331
Chris@16 332 template <typename Geometry1, typename Geometry2>
Chris@101 333 struct equals
Chris@16 334 {
Chris@16 335 static inline bool apply(Geometry1 const& geometry1,
Chris@16 336 Geometry2 const& geometry2)
Chris@16 337 {
Chris@16 338 concept::check_concepts_and_equal_dimensions
Chris@16 339 <
Chris@16 340 Geometry1 const,
Chris@16 341 Geometry2 const
Chris@16 342 >();
Chris@101 343
Chris@101 344 return dispatch::equals<Geometry1, Geometry2>
Chris@101 345 ::apply(geometry1, geometry2);
Chris@16 346 }
Chris@16 347 };
Chris@16 348
Chris@16 349 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
Chris@101 350 struct equals<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Chris@16 351 {
Chris@16 352 struct visitor: static_visitor<bool>
Chris@16 353 {
Chris@16 354 Geometry2 const& m_geometry2;
Chris@16 355
Chris@16 356 visitor(Geometry2 const& geometry2)
Chris@16 357 : m_geometry2(geometry2)
Chris@16 358 {}
Chris@16 359
Chris@16 360 template <typename Geometry1>
Chris@16 361 inline bool operator()(Geometry1 const& geometry1) const
Chris@16 362 {
Chris@101 363 return equals<Geometry1, Geometry2>
Chris@101 364 ::apply(geometry1, m_geometry2);
Chris@16 365 }
Chris@16 366
Chris@16 367 };
Chris@16 368
Chris@16 369 static inline bool apply(
Chris@16 370 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Chris@16 371 Geometry2 const& geometry2
Chris@16 372 )
Chris@16 373 {
Chris@16 374 return apply_visitor(visitor(geometry2), geometry1);
Chris@16 375 }
Chris@16 376 };
Chris@16 377
Chris@16 378 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
Chris@101 379 struct equals<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
Chris@16 380 {
Chris@16 381 struct visitor: static_visitor<bool>
Chris@16 382 {
Chris@16 383 Geometry1 const& m_geometry1;
Chris@16 384
Chris@16 385 visitor(Geometry1 const& geometry1)
Chris@16 386 : m_geometry1(geometry1)
Chris@16 387 {}
Chris@16 388
Chris@16 389 template <typename Geometry2>
Chris@16 390 inline bool operator()(Geometry2 const& geometry2) const
Chris@16 391 {
Chris@101 392 return equals<Geometry1, Geometry2>
Chris@101 393 ::apply(m_geometry1, geometry2);
Chris@16 394 }
Chris@16 395
Chris@16 396 };
Chris@16 397
Chris@16 398 static inline bool apply(
Chris@16 399 Geometry1 const& geometry1,
Chris@16 400 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2
Chris@16 401 )
Chris@16 402 {
Chris@16 403 return apply_visitor(visitor(geometry1), geometry2);
Chris@16 404 }
Chris@16 405 };
Chris@16 406
Chris@16 407 template <
Chris@16 408 BOOST_VARIANT_ENUM_PARAMS(typename T1),
Chris@16 409 BOOST_VARIANT_ENUM_PARAMS(typename T2)
Chris@16 410 >
Chris@101 411 struct equals<
Chris@16 412 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
Chris@16 413 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
Chris@16 414 >
Chris@16 415 {
Chris@16 416 struct visitor: static_visitor<bool>
Chris@16 417 {
Chris@16 418 template <typename Geometry1, typename Geometry2>
Chris@16 419 inline bool operator()(Geometry1 const& geometry1,
Chris@16 420 Geometry2 const& geometry2) const
Chris@16 421 {
Chris@101 422 return equals<Geometry1, Geometry2>
Chris@101 423 ::apply(geometry1, geometry2);
Chris@16 424 }
Chris@16 425
Chris@16 426 };
Chris@16 427
Chris@16 428 static inline bool apply(
Chris@16 429 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
Chris@16 430 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2
Chris@16 431 )
Chris@16 432 {
Chris@16 433 return apply_visitor(visitor(), geometry1, geometry2);
Chris@16 434 }
Chris@16 435 };
Chris@16 436
Chris@101 437 } // namespace resolve_variant
Chris@16 438
Chris@16 439
Chris@16 440 /*!
Chris@16 441 \brief \brief_check{are spatially equal}
Chris@101 442 \details \details_check12{equals, is spatially equal}. Spatially equal means
Chris@16 443 that the same point set is included. A box can therefore be spatially equal
Chris@101 444 to a ring or a polygon, or a linestring can be spatially equal to a
Chris@16 445 multi-linestring or a segment. This only works theoretically, not all
Chris@16 446 combinations are implemented yet.
Chris@16 447 \ingroup equals
Chris@16 448 \tparam Geometry1 \tparam_geometry
Chris@16 449 \tparam Geometry2 \tparam_geometry
Chris@16 450 \param geometry1 \param_geometry
Chris@16 451 \param geometry2 \param_geometry
Chris@16 452 \return \return_check2{are spatially equal}
Chris@16 453
Chris@16 454 \qbk{[include reference/algorithms/equals.qbk]}
Chris@16 455
Chris@16 456 */
Chris@16 457 template <typename Geometry1, typename Geometry2>
Chris@16 458 inline bool equals(Geometry1 const& geometry1, Geometry2 const& geometry2)
Chris@16 459 {
Chris@101 460 return resolve_variant::equals<Geometry1, Geometry2>
Chris@101 461 ::apply(geometry1, geometry2);
Chris@16 462 }
Chris@16 463
Chris@16 464
Chris@16 465 }} // namespace boost::geometry
Chris@16 466
Chris@16 467
Chris@16 468 #endif // BOOST_GEOMETRY_ALGORITHMS_EQUALS_HPP
Chris@16 469