annotate DEPENDENCIES/generic/include/boost/geometry/algorithms/touches.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // Boost.Geometry (aka GGL, Generic Geometry Library)
Chris@16 2
Chris@16 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
Chris@16 4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
Chris@16 5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
Chris@101 6 // Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
Chris@101 7
Chris@101 8 // This file was modified by Oracle on 2013, 2014.
Chris@101 9 // Modifications copyright (c) 2013, 2014, Oracle and/or its affiliates.
Chris@16 10
Chris@16 11 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
Chris@16 12 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
Chris@16 13
Chris@16 14 // Use, modification and distribution is subject to the Boost Software License,
Chris@16 15 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 16 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 17
Chris@101 18 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
Chris@101 19
Chris@16 20 #ifndef BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP
Chris@16 21 #define BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP
Chris@16 22
Chris@16 23
Chris@16 24 #include <deque>
Chris@16 25
Chris@101 26 #include <boost/variant/apply_visitor.hpp>
Chris@101 27 #include <boost/variant/static_visitor.hpp>
Chris@101 28 #include <boost/variant/variant_fwd.hpp>
Chris@101 29
Chris@16 30 #include <boost/geometry/geometries/concepts/check.hpp>
Chris@101 31 #include <boost/geometry/algorithms/detail/for_each_range.hpp>
Chris@101 32 #include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
Chris@16 33 #include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
Chris@16 34 #include <boost/geometry/algorithms/disjoint.hpp>
Chris@16 35 #include <boost/geometry/algorithms/intersects.hpp>
Chris@16 36 #include <boost/geometry/algorithms/num_geometries.hpp>
Chris@101 37 #include <boost/geometry/algorithms/detail/sub_range.hpp>
Chris@101 38 #include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
Chris@16 39
Chris@101 40 #include <boost/geometry/algorithms/detail/relate/relate.hpp>
Chris@16 41
Chris@16 42 namespace boost { namespace geometry
Chris@16 43 {
Chris@16 44
Chris@101 45 #ifndef DOXYGEN_NO_DETAIL
Chris@101 46 namespace detail { namespace touches
Chris@16 47 {
Chris@16 48
Chris@101 49 // Box/Box
Chris@101 50
Chris@101 51 template
Chris@101 52 <
Chris@101 53 std::size_t Dimension,
Chris@101 54 std::size_t DimensionCount
Chris@101 55 >
Chris@101 56 struct box_box_loop
Chris@16 57 {
Chris@101 58 template <typename Box1, typename Box2>
Chris@101 59 static inline bool apply(Box1 const& b1, Box2 const& b2, bool & touch)
Chris@101 60 {
Chris@101 61 typedef typename coordinate_type<Box1>::type coordinate_type1;
Chris@101 62 typedef typename coordinate_type<Box2>::type coordinate_type2;
Chris@16 63
Chris@101 64 coordinate_type1 const& min1 = get<min_corner, Dimension>(b1);
Chris@101 65 coordinate_type1 const& max1 = get<max_corner, Dimension>(b1);
Chris@101 66 coordinate_type2 const& min2 = get<min_corner, Dimension>(b2);
Chris@101 67 coordinate_type2 const& max2 = get<max_corner, Dimension>(b2);
Chris@101 68
Chris@101 69 // TODO assert or exception?
Chris@101 70 //BOOST_ASSERT(min1 <= max1 && min2 <= max2);
Chris@101 71
Chris@101 72 if ( max1 < min2 || max2 < min1 )
Chris@16 73 {
Chris@16 74 return false;
Chris@16 75 }
Chris@16 76
Chris@101 77 if ( max1 == min2 || max2 == min1 )
Chris@16 78 {
Chris@101 79 touch = true;
Chris@101 80 }
Chris@101 81
Chris@101 82 return box_box_loop
Chris@101 83 <
Chris@101 84 Dimension + 1,
Chris@101 85 DimensionCount
Chris@101 86 >::apply(b1, b2, touch);
Chris@101 87 }
Chris@101 88 };
Chris@101 89
Chris@101 90 template
Chris@101 91 <
Chris@101 92 std::size_t DimensionCount
Chris@101 93 >
Chris@101 94 struct box_box_loop<DimensionCount, DimensionCount>
Chris@101 95 {
Chris@101 96 template <typename Box1, typename Box2>
Chris@101 97 static inline bool apply(Box1 const& , Box2 const&, bool &)
Chris@101 98 {
Chris@101 99 return true;
Chris@101 100 }
Chris@101 101 };
Chris@101 102
Chris@101 103 struct box_box
Chris@101 104 {
Chris@101 105 template <typename Box1, typename Box2>
Chris@101 106 static inline bool apply(Box1 const& b1, Box2 const& b2)
Chris@101 107 {
Chris@101 108 BOOST_STATIC_ASSERT((boost::is_same
Chris@101 109 <
Chris@101 110 typename geometry::coordinate_system<Box1>::type,
Chris@101 111 typename geometry::coordinate_system<Box2>::type
Chris@101 112 >::value
Chris@101 113 ));
Chris@101 114 assert_dimension_equal<Box1, Box2>();
Chris@101 115
Chris@101 116 bool touches = false;
Chris@101 117 bool ok = box_box_loop
Chris@101 118 <
Chris@101 119 0,
Chris@101 120 dimension<Box1>::type::value
Chris@101 121 >::apply(b1, b2, touches);
Chris@101 122
Chris@101 123 return ok && touches;
Chris@101 124 }
Chris@101 125 };
Chris@101 126
Chris@101 127 // Areal/Areal
Chris@101 128
Chris@101 129 struct areal_interrupt_policy
Chris@101 130 {
Chris@101 131 static bool const enabled = true;
Chris@101 132 bool found_touch;
Chris@101 133 bool found_not_touch;
Chris@101 134
Chris@101 135 // dummy variable required by self_get_turn_points::get_turns
Chris@101 136 static bool const has_intersections = false;
Chris@101 137
Chris@101 138 inline bool result()
Chris@101 139 {
Chris@101 140 return found_touch && !found_not_touch;
Chris@101 141 }
Chris@101 142
Chris@101 143 inline areal_interrupt_policy()
Chris@101 144 : found_touch(false), found_not_touch(false)
Chris@101 145 {}
Chris@101 146
Chris@101 147 template <typename Range>
Chris@101 148 inline bool apply(Range const& range)
Chris@101 149 {
Chris@101 150 // if already rejected (temp workaround?)
Chris@101 151 if ( found_not_touch )
Chris@101 152 return true;
Chris@101 153
Chris@101 154 typedef typename boost::range_iterator<Range const>::type iterator;
Chris@101 155 for ( iterator it = boost::begin(range) ; it != boost::end(range) ; ++it )
Chris@101 156 {
Chris@101 157 if ( it->has(overlay::operation_intersection) )
Chris@101 158 {
Chris@101 159 found_not_touch = true;
Chris@101 160 return true;
Chris@101 161 }
Chris@101 162
Chris@101 163 switch(it->method)
Chris@101 164 {
Chris@101 165 case overlay::method_crosses:
Chris@101 166 found_not_touch = true;
Chris@101 167 return true;
Chris@101 168 case overlay::method_equal:
Chris@101 169 // Segment spatially equal means: at the right side
Chris@101 170 // the polygon internally overlaps. So return false.
Chris@101 171 found_not_touch = true;
Chris@101 172 return true;
Chris@101 173 case overlay::method_touch:
Chris@101 174 case overlay::method_touch_interior:
Chris@101 175 case overlay::method_collinear:
Chris@101 176 if ( ok_for_touch(*it) )
Chris@101 177 {
Chris@101 178 found_touch = true;
Chris@101 179 }
Chris@101 180 else
Chris@101 181 {
Chris@101 182 found_not_touch = true;
Chris@101 183 return true;
Chris@101 184 }
Chris@101 185 break;
Chris@101 186 case overlay::method_none :
Chris@101 187 case overlay::method_disjoint :
Chris@101 188 case overlay::method_error :
Chris@101 189 break;
Chris@101 190 }
Chris@101 191 }
Chris@101 192
Chris@101 193 return false;
Chris@101 194 }
Chris@101 195
Chris@101 196 template <typename Turn>
Chris@101 197 inline bool ok_for_touch(Turn const& turn)
Chris@101 198 {
Chris@101 199 return turn.both(overlay::operation_union)
Chris@101 200 || turn.both(overlay::operation_blocked)
Chris@101 201 || turn.combination(overlay::operation_union, overlay::operation_blocked)
Chris@101 202 ;
Chris@101 203 }
Chris@101 204 };
Chris@101 205
Chris@101 206 template<typename Geometry>
Chris@101 207 struct check_each_ring_for_within
Chris@101 208 {
Chris@101 209 bool has_within;
Chris@101 210 Geometry const& m_geometry;
Chris@101 211
Chris@101 212 inline check_each_ring_for_within(Geometry const& g)
Chris@101 213 : has_within(false)
Chris@101 214 , m_geometry(g)
Chris@101 215 {}
Chris@101 216
Chris@101 217 template <typename Range>
Chris@101 218 inline void apply(Range const& range)
Chris@101 219 {
Chris@101 220 typename geometry::point_type<Range>::type p;
Chris@101 221 geometry::point_on_border(p, range);
Chris@101 222 if ( !has_within && geometry::within(p, m_geometry) )
Chris@101 223 {
Chris@101 224 has_within = true;
Chris@16 225 }
Chris@16 226 }
Chris@101 227 };
Chris@101 228
Chris@101 229 template <typename FirstGeometry, typename SecondGeometry>
Chris@101 230 inline bool rings_containing(FirstGeometry const& geometry1,
Chris@101 231 SecondGeometry const& geometry2)
Chris@101 232 {
Chris@101 233 check_each_ring_for_within<FirstGeometry> checker(geometry1);
Chris@101 234 geometry::detail::for_each_range(geometry2, checker);
Chris@101 235 return checker.has_within;
Chris@16 236 }
Chris@16 237
Chris@101 238 template <typename Geometry1, typename Geometry2>
Chris@101 239 struct areal_areal
Chris@101 240 {
Chris@101 241 static inline
Chris@101 242 bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
Chris@101 243 {
Chris@101 244 typedef detail::no_rescale_policy rescale_policy_type;
Chris@101 245 typedef typename geometry::point_type<Geometry1>::type point_type;
Chris@101 246 typedef detail::overlay::turn_info
Chris@101 247 <
Chris@101 248 point_type,
Chris@101 249 typename segment_ratio_type<point_type, rescale_policy_type>::type
Chris@101 250 > turn_info;
Chris@101 251
Chris@101 252 std::deque<turn_info> turns;
Chris@101 253 detail::touches::areal_interrupt_policy policy;
Chris@101 254 rescale_policy_type robust_policy;
Chris@101 255 boost::geometry::get_turns
Chris@101 256 <
Chris@101 257 detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
Chris@101 258 detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
Chris@101 259 detail::overlay::assign_null_policy
Chris@101 260 >(geometry1, geometry2, robust_policy, turns, policy);
Chris@101 261
Chris@101 262 return policy.result()
Chris@101 263 && ! geometry::detail::touches::rings_containing(geometry1, geometry2)
Chris@101 264 && ! geometry::detail::touches::rings_containing(geometry2, geometry1);
Chris@101 265 }
Chris@101 266 };
Chris@101 267
Chris@101 268 // P/*
Chris@101 269
Chris@101 270 struct use_point_in_geometry
Chris@101 271 {
Chris@101 272 template <typename Point, typename Geometry>
Chris@101 273 static inline bool apply(Point const& point, Geometry const& geometry)
Chris@101 274 {
Chris@101 275 return detail::within::point_in_geometry(point, geometry) == 0;
Chris@101 276 }
Chris@101 277 };
Chris@101 278
Chris@16 279 }}
Chris@101 280 #endif // DOXYGEN_NO_DETAIL
Chris@101 281
Chris@101 282 #ifndef DOXYGEN_NO_DISPATCH
Chris@101 283 namespace dispatch {
Chris@101 284
Chris@101 285 // TODO: Since CastedTags are used is Reverse needed?
Chris@101 286
Chris@101 287 template
Chris@101 288 <
Chris@101 289 typename Geometry1, typename Geometry2,
Chris@101 290 typename Tag1 = typename tag<Geometry1>::type,
Chris@101 291 typename Tag2 = typename tag<Geometry2>::type,
Chris@101 292 typename CastedTag1 = typename tag_cast<Tag1, pointlike_tag, linear_tag, areal_tag>::type,
Chris@101 293 typename CastedTag2 = typename tag_cast<Tag2, pointlike_tag, linear_tag, areal_tag>::type,
Chris@101 294 bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
Chris@101 295 >
Chris@101 296 struct touches
Chris@101 297 : not_implemented<Tag1, Tag2>
Chris@101 298 {};
Chris@101 299
Chris@101 300 // If reversal is needed, perform it
Chris@101 301 template
Chris@101 302 <
Chris@101 303 typename Geometry1, typename Geometry2,
Chris@101 304 typename Tag1, typename Tag2,
Chris@101 305 typename CastedTag1, typename CastedTag2
Chris@101 306 >
Chris@101 307 struct touches<Geometry1, Geometry2, Tag1, Tag2, CastedTag1, CastedTag2, true>
Chris@101 308 : touches<Geometry2, Geometry1, Tag2, Tag1, CastedTag2, CastedTag1, false>
Chris@101 309 {
Chris@101 310 static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
Chris@101 311 {
Chris@101 312 return touches<Geometry2, Geometry1>::apply(g2, g1);
Chris@101 313 }
Chris@101 314 };
Chris@101 315
Chris@101 316 // P/P
Chris@101 317
Chris@101 318 template <typename Geometry1, typename Geometry2, typename Tag1, typename Tag2>
Chris@101 319 struct touches<Geometry1, Geometry2, Tag1, Tag2, pointlike_tag, pointlike_tag, false>
Chris@101 320 {
Chris@101 321 static inline bool apply(Geometry1 const& , Geometry2 const& )
Chris@101 322 {
Chris@101 323 return false;
Chris@101 324 }
Chris@101 325 };
Chris@101 326
Chris@101 327 // P/*
Chris@101 328
Chris@101 329 template <typename Point, typename Geometry, typename Tag2, typename CastedTag2>
Chris@101 330 struct touches<Point, Geometry, point_tag, Tag2, pointlike_tag, CastedTag2, false>
Chris@101 331 : detail::touches::use_point_in_geometry
Chris@101 332 {};
Chris@101 333
Chris@101 334 // TODO: support touches(MPt, Linear/Areal)
Chris@101 335
Chris@101 336 // Box/Box
Chris@101 337
Chris@101 338 template <typename Box1, typename Box2, typename CastedTag1, typename CastedTag2>
Chris@101 339 struct touches<Box1, Box2, box_tag, box_tag, CastedTag1, CastedTag2, false>
Chris@101 340 : detail::touches::box_box
Chris@101 341 {};
Chris@101 342
Chris@101 343 template <typename Box1, typename Box2>
Chris@101 344 struct touches<Box1, Box2, box_tag, box_tag, areal_tag, areal_tag, false>
Chris@101 345 : detail::touches::box_box
Chris@101 346 {};
Chris@101 347
Chris@101 348 // L/L
Chris@101 349
Chris@101 350 template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
Chris@101 351 struct touches<Linear1, Linear2, Tag1, Tag2, linear_tag, linear_tag, false>
Chris@101 352 : detail::relate::relate_base
Chris@101 353 <
Chris@101 354 detail::relate::static_mask_touches_type,
Chris@101 355 Linear1,
Chris@101 356 Linear2
Chris@101 357 >
Chris@101 358 {};
Chris@101 359
Chris@101 360 // L/A
Chris@101 361
Chris@101 362 template <typename Linear, typename Areal, typename Tag1, typename Tag2>
Chris@101 363 struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, false>
Chris@101 364 : detail::relate::relate_base
Chris@101 365 <
Chris@101 366 detail::relate::static_mask_touches_type,
Chris@101 367 Linear,
Chris@101 368 Areal
Chris@101 369 >
Chris@101 370 {};
Chris@101 371
Chris@101 372 // A/L
Chris@101 373 template <typename Linear, typename Areal, typename Tag1, typename Tag2>
Chris@101 374 struct touches<Linear, Areal, Tag1, Tag2, linear_tag, areal_tag, true>
Chris@101 375 : detail::relate::relate_base
Chris@101 376 <
Chris@101 377 detail::relate::static_mask_touches_type,
Chris@101 378 Areal,
Chris@101 379 Linear
Chris@101 380 >
Chris@101 381 {};
Chris@101 382
Chris@101 383 // A/A
Chris@101 384
Chris@101 385 template <typename Areal1, typename Areal2, typename Tag1, typename Tag2>
Chris@101 386 struct touches<Areal1, Areal2, Tag1, Tag2, areal_tag, areal_tag, false>
Chris@101 387 : detail::touches::areal_areal<Areal1, Areal2>
Chris@101 388 {};
Chris@101 389
Chris@101 390 } // namespace dispatch
Chris@101 391 #endif // DOXYGEN_NO_DISPATCH
Chris@101 392
Chris@101 393
Chris@101 394 namespace resolve_variant {
Chris@101 395
Chris@101 396 template <typename Geometry1, typename Geometry2>
Chris@101 397 struct touches
Chris@101 398 {
Chris@101 399 static bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2)
Chris@101 400 {
Chris@101 401 concept::check<Geometry1 const>();
Chris@101 402 concept::check<Geometry2 const>();
Chris@101 403
Chris@101 404 return dispatch::touches<Geometry1, Geometry2>
Chris@101 405 ::apply(geometry1, geometry2);
Chris@101 406 }
Chris@101 407 };
Chris@101 408
Chris@101 409 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
Chris@101 410 struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
Chris@101 411 {
Chris@101 412 struct visitor: boost::static_visitor<bool>
Chris@101 413 {
Chris@101 414 Geometry2 const& m_geometry2;
Chris@101 415
Chris@101 416 visitor(Geometry2 const& geometry2): m_geometry2(geometry2) {}
Chris@101 417
Chris@101 418 template <typename Geometry1>
Chris@101 419 bool operator()(Geometry1 const& geometry1) const
Chris@101 420 {
Chris@101 421 return touches<Geometry1, Geometry2>::apply(geometry1, m_geometry2);
Chris@101 422 }
Chris@101 423 };
Chris@101 424
Chris@101 425 static inline bool
Chris@101 426 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
Chris@101 427 Geometry2 const& geometry2)
Chris@101 428 {
Chris@101 429 return boost::apply_visitor(visitor(geometry2), geometry1);
Chris@101 430 }
Chris@101 431 };
Chris@101 432
Chris@101 433 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
Chris@101 434 struct touches<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
Chris@101 435 {
Chris@101 436 struct visitor: boost::static_visitor<bool>
Chris@101 437 {
Chris@101 438 Geometry1 const& m_geometry1;
Chris@101 439
Chris@101 440 visitor(Geometry1 const& geometry1): m_geometry1(geometry1) {}
Chris@101 441
Chris@101 442 template <typename Geometry2>
Chris@101 443 bool operator()(Geometry2 const& geometry2) const
Chris@101 444 {
Chris@101 445 return touches<Geometry1, Geometry2>::apply(m_geometry1, geometry2);
Chris@101 446 }
Chris@101 447 };
Chris@101 448
Chris@101 449 static inline bool
Chris@101 450 apply(Geometry1 const& geometry1,
Chris@101 451 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
Chris@101 452 {
Chris@101 453 return boost::apply_visitor(visitor(geometry1), geometry2);
Chris@101 454 }
Chris@101 455 };
Chris@101 456
Chris@101 457 template <BOOST_VARIANT_ENUM_PARAMS(typename T1),
Chris@101 458 BOOST_VARIANT_ENUM_PARAMS(typename T2)>
Chris@101 459 struct touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
Chris@101 460 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
Chris@101 461 {
Chris@101 462 struct visitor: boost::static_visitor<bool>
Chris@101 463 {
Chris@101 464 template <typename Geometry1, typename Geometry2>
Chris@101 465 bool operator()(Geometry1 const& geometry1,
Chris@101 466 Geometry2 const& geometry2) const
Chris@101 467 {
Chris@101 468 return touches<Geometry1, Geometry2>::apply(geometry1, geometry2);
Chris@101 469 }
Chris@101 470 };
Chris@101 471
Chris@101 472 static inline bool
Chris@101 473 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
Chris@101 474 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
Chris@101 475 {
Chris@101 476 return boost::apply_visitor(visitor(), geometry1, geometry2);
Chris@101 477 }
Chris@101 478 };
Chris@101 479
Chris@101 480 template <typename Geometry>
Chris@101 481 struct self_touches
Chris@101 482 {
Chris@101 483 static bool apply(Geometry const& geometry)
Chris@101 484 {
Chris@101 485 concept::check<Geometry const>();
Chris@101 486
Chris@101 487 typedef detail::no_rescale_policy rescale_policy_type;
Chris@101 488 typedef typename geometry::point_type<Geometry>::type point_type;
Chris@101 489 typedef detail::overlay::turn_info
Chris@101 490 <
Chris@101 491 point_type,
Chris@101 492 typename segment_ratio_type<point_type, rescale_policy_type>::type
Chris@101 493 > turn_info;
Chris@101 494
Chris@101 495 typedef detail::overlay::get_turn_info
Chris@101 496 <
Chris@101 497 detail::overlay::assign_null_policy
Chris@101 498 > policy_type;
Chris@101 499
Chris@101 500 std::deque<turn_info> turns;
Chris@101 501 detail::touches::areal_interrupt_policy policy;
Chris@101 502 rescale_policy_type robust_policy;
Chris@101 503 detail::self_get_turn_points::get_turns
Chris@101 504 <
Chris@101 505 policy_type
Chris@101 506 >::apply(geometry, robust_policy, turns, policy);
Chris@101 507
Chris@101 508 return policy.result();
Chris@101 509 }
Chris@101 510 };
Chris@101 511
Chris@101 512 template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
Chris@101 513 struct self_touches<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
Chris@101 514 {
Chris@101 515 struct visitor: boost::static_visitor<bool>
Chris@101 516 {
Chris@101 517 template <typename Geometry>
Chris@101 518 bool operator()(Geometry const& geometry) const
Chris@101 519 {
Chris@101 520 return self_touches<Geometry>::apply(geometry);
Chris@101 521 }
Chris@101 522 };
Chris@101 523
Chris@101 524 static inline bool
Chris@101 525 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry)
Chris@101 526 {
Chris@101 527 return boost::apply_visitor(visitor(), geometry);
Chris@101 528 }
Chris@101 529 };
Chris@101 530
Chris@101 531 } // namespace resolve_variant
Chris@101 532
Chris@16 533
Chris@16 534 /*!
Chris@16 535 \brief \brief_check{has at least one touching point (self-tangency)}
Chris@16 536 \note This function can be called for one geometry (self-tangency) and
Chris@16 537 also for two geometries (touch)
Chris@16 538 \ingroup touches
Chris@16 539 \tparam Geometry \tparam_geometry
Chris@16 540 \param geometry \param_geometry
Chris@16 541 \return \return_check{is self-touching}
Chris@16 542
Chris@16 543 \qbk{distinguish,one geometry}
Chris@16 544 \qbk{[def __one_parameter__]}
Chris@16 545 \qbk{[include reference/algorithms/touches.qbk]}
Chris@16 546 */
Chris@16 547 template <typename Geometry>
Chris@16 548 inline bool touches(Geometry const& geometry)
Chris@16 549 {
Chris@101 550 return resolve_variant::self_touches<Geometry>::apply(geometry);
Chris@16 551 }
Chris@16 552
Chris@16 553
Chris@16 554 /*!
Chris@16 555 \brief \brief_check2{have at least one touching point (tangent - non overlapping)}
Chris@16 556 \ingroup touches
Chris@16 557 \tparam Geometry1 \tparam_geometry
Chris@16 558 \tparam Geometry2 \tparam_geometry
Chris@16 559 \param geometry1 \param_geometry
Chris@16 560 \param geometry2 \param_geometry
Chris@16 561 \return \return_check2{touch each other}
Chris@16 562
Chris@16 563 \qbk{distinguish,two geometries}
Chris@16 564 \qbk{[include reference/algorithms/touches.qbk]}
Chris@16 565 */
Chris@16 566 template <typename Geometry1, typename Geometry2>
Chris@16 567 inline bool touches(Geometry1 const& geometry1, Geometry2 const& geometry2)
Chris@16 568 {
Chris@101 569 return resolve_variant::touches<Geometry1, Geometry2>::apply(geometry1, geometry2);
Chris@16 570 }
Chris@16 571
Chris@16 572
Chris@16 573 }} // namespace boost::geometry
Chris@16 574
Chris@16 575 #endif // BOOST_GEOMETRY_ALGORITHMS_TOUCHES_HPP