]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/include/boost/geometry/algorithms/within.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / algorithms / within.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
5// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
6
7// This file was modified by Oracle on 2013, 2014.
8// Modifications copyright (c) 2013, 2014 Oracle and/or its affiliates.
9
10// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
11// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
12
13// Use, modification and distribution is subject to the Boost Software License,
14// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
15// http://www.boost.org/LICENSE_1_0.txt)
16
17// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
18
19#ifndef BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
20#define BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP
21
22
23#include <cstddef>
24
25#include <boost/concept_check.hpp>
26#include <boost/range.hpp>
27
28#include <boost/variant/apply_visitor.hpp>
29#include <boost/variant/static_visitor.hpp>
30#include <boost/variant/variant_fwd.hpp>
31
32#include <boost/geometry/algorithms/make.hpp>
33#include <boost/geometry/algorithms/not_implemented.hpp>
34
35#include <boost/geometry/core/access.hpp>
36#include <boost/geometry/core/closure.hpp>
37#include <boost/geometry/core/cs.hpp>
38#include <boost/geometry/core/exterior_ring.hpp>
39#include <boost/geometry/core/interior_rings.hpp>
40#include <boost/geometry/core/point_order.hpp>
41#include <boost/geometry/core/ring_type.hpp>
42#include <boost/geometry/core/interior_rings.hpp>
43#include <boost/geometry/core/tags.hpp>
44
45#include <boost/geometry/geometries/concepts/check.hpp>
46#include <boost/geometry/strategies/concepts/within_concept.hpp>
47#include <boost/geometry/strategies/default_strategy.hpp>
48#include <boost/geometry/strategies/within.hpp>
49#include <boost/geometry/util/math.hpp>
50#include <boost/geometry/util/order_as_direction.hpp>
51#include <boost/geometry/views/closeable_view.hpp>
52#include <boost/geometry/views/reversible_view.hpp>
53
54#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
55
56#include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
57#include <boost/geometry/algorithms/detail/overlay/do_reverse.hpp>
58#include <deque>
59
60namespace boost { namespace geometry
61{
62
63#ifndef DOXYGEN_NO_DETAIL
64namespace detail { namespace within {
65
66struct use_point_in_geometry
67{
68 template <typename Geometry1, typename Geometry2, typename Strategy>
69 static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
70 {
71 return detail::within::point_in_geometry(geometry1, geometry2, strategy) == 1;
72 }
73};
74
75struct use_relate
76{
77 template <typename Geometry1, typename Geometry2, typename Strategy>
78 static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& /*strategy*/)
79 {
80 return Strategy::apply(geometry1, geometry2);
81 }
82};
83
84}} // namespace detail::within
85#endif // DOXYGEN_NO_DETAIL
86
87#ifndef DOXYGEN_NO_DISPATCH
88namespace dispatch
89{
90
91template
92<
93 typename Geometry1,
94 typename Geometry2,
95 typename Tag1 = typename tag<Geometry1>::type,
96 typename Tag2 = typename tag<Geometry2>::type
97>
98struct within
99 : not_implemented<Tag1, Tag2>
100{};
101
102
103template <typename Point, typename Box>
104struct within<Point, Box, point_tag, box_tag>
105{
106 template <typename Strategy>
107 static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
108 {
109 boost::ignore_unused_variable_warning(strategy);
110 return strategy.apply(point, box);
111 }
112};
113
114template <typename Box1, typename Box2>
115struct within<Box1, Box2, box_tag, box_tag>
116{
117 template <typename Strategy>
118 static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
119 {
120 assert_dimension_equal<Box1, Box2>();
121 boost::ignore_unused_variable_warning(strategy);
122 return strategy.apply(box1, box2);
123 }
124};
125
126// P/P
127
128template <typename Point1, typename Point2>
129struct within<Point1, Point2, point_tag, point_tag>
130 : public detail::within::use_point_in_geometry
131{};
132
133template <typename Point, typename MultiPoint>
134struct within<Point, MultiPoint, point_tag, multi_point_tag>
135 : public detail::within::use_point_in_geometry
136{};
137
138// P/L
139
140template <typename Point, typename Segment>
141struct within<Point, Segment, point_tag, segment_tag>
142 : public detail::within::use_point_in_geometry
143{};
144
145template <typename Point, typename Linestring>
146struct within<Point, Linestring, point_tag, linestring_tag>
147 : public detail::within::use_point_in_geometry
148{};
149
150template <typename Point, typename MultiLinestring>
151struct within<Point, MultiLinestring, point_tag, multi_linestring_tag>
152 : public detail::within::use_point_in_geometry
153{};
154
155// P/A
156
157template <typename Point, typename Ring>
158struct within<Point, Ring, point_tag, ring_tag>
159 : public detail::within::use_point_in_geometry
160{};
161
162template <typename Point, typename Polygon>
163struct within<Point, Polygon, point_tag, polygon_tag>
164 : public detail::within::use_point_in_geometry
165{};
166
167template <typename Point, typename MultiPolygon>
168struct within<Point, MultiPolygon, point_tag, multi_polygon_tag>
169 : public detail::within::use_point_in_geometry
170{};
171
172// L/L
173
174template <typename Linestring1, typename Linestring2>
175struct within<Linestring1, Linestring2, linestring_tag, linestring_tag>
176 : public detail::within::use_relate
177{};
178
179template <typename Linestring, typename MultiLinestring>
180struct within<Linestring, MultiLinestring, linestring_tag, multi_linestring_tag>
181 : public detail::within::use_relate
182{};
183
184template <typename MultiLinestring, typename Linestring>
185struct within<MultiLinestring, Linestring, multi_linestring_tag, linestring_tag>
186 : public detail::within::use_relate
187{};
188
189template <typename MultiLinestring1, typename MultiLinestring2>
190struct within<MultiLinestring1, MultiLinestring2, multi_linestring_tag, multi_linestring_tag>
191 : public detail::within::use_relate
192{};
193
194// L/A
195
196template <typename Linestring, typename Ring>
197struct within<Linestring, Ring, linestring_tag, ring_tag>
198 : public detail::within::use_relate
199{};
200
201template <typename MultiLinestring, typename Ring>
202struct within<MultiLinestring, Ring, multi_linestring_tag, ring_tag>
203 : public detail::within::use_relate
204{};
205
206template <typename Linestring, typename Polygon>
207struct within<Linestring, Polygon, linestring_tag, polygon_tag>
208 : public detail::within::use_relate
209{};
210
211template <typename MultiLinestring, typename Polygon>
212struct within<MultiLinestring, Polygon, multi_linestring_tag, polygon_tag>
213 : public detail::within::use_relate
214{};
215
216template <typename Linestring, typename MultiPolygon>
217struct within<Linestring, MultiPolygon, linestring_tag, multi_polygon_tag>
218 : public detail::within::use_relate
219{};
220
221template <typename MultiLinestring, typename MultiPolygon>
222struct within<MultiLinestring, MultiPolygon, multi_linestring_tag, multi_polygon_tag>
223 : public detail::within::use_relate
224{};
225
226// A/A
227
228template <typename Ring1, typename Ring2>
229struct within<Ring1, Ring2, ring_tag, ring_tag>
230 : public detail::within::use_relate
231{};
232
233template <typename Ring, typename Polygon>
234struct within<Ring, Polygon, ring_tag, polygon_tag>
235 : public detail::within::use_relate
236{};
237
238template <typename Polygon, typename Ring>
239struct within<Polygon, Ring, polygon_tag, ring_tag>
240 : public detail::within::use_relate
241{};
242
243template <typename Polygon1, typename Polygon2>
244struct within<Polygon1, Polygon2, polygon_tag, polygon_tag>
245 : public detail::within::use_relate
246{};
247
248template <typename Ring, typename MultiPolygon>
249struct within<Ring, MultiPolygon, ring_tag, multi_polygon_tag>
250 : public detail::within::use_relate
251{};
252
253template <typename MultiPolygon, typename Ring>
254struct within<MultiPolygon, Ring, multi_polygon_tag, ring_tag>
255 : public detail::within::use_relate
256{};
257
258template <typename Polygon, typename MultiPolygon>
259struct within<Polygon, MultiPolygon, polygon_tag, multi_polygon_tag>
260 : public detail::within::use_relate
261{};
262
263template <typename MultiPolygon, typename Polygon>
264struct within<MultiPolygon, Polygon, multi_polygon_tag, polygon_tag>
265 : public detail::within::use_relate
266{};
267
268template <typename MultiPolygon1, typename MultiPolygon2>
269struct within<MultiPolygon1, MultiPolygon2, multi_polygon_tag, multi_polygon_tag>
270 : public detail::within::use_relate
271{};
272
273} // namespace dispatch
274#endif // DOXYGEN_NO_DISPATCH
275
276
277namespace resolve_strategy
278{
279
280struct within
281{
282 template <typename Geometry1, typename Geometry2, typename Strategy>
283 static inline bool apply(Geometry1 const& geometry1,
284 Geometry2 const& geometry2,
285 Strategy const& strategy)
286 {
287 concepts::within::check
288 <
289 typename tag<Geometry1>::type,
290 typename tag<Geometry2>::type,
291 typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
292 Strategy
293 >();
294
295 return dispatch::within<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
296 }
297
298 template <typename Geometry1, typename Geometry2>
299 static inline bool apply(Geometry1 const& geometry1,
300 Geometry2 const& geometry2,
301 default_strategy)
302 {
303 typedef typename point_type<Geometry1>::type point_type1;
304 typedef typename point_type<Geometry2>::type point_type2;
305
306 typedef typename strategy::within::services::default_strategy
307 <
308 typename tag<Geometry1>::type,
309 typename tag<Geometry2>::type,
310 typename tag<Geometry1>::type,
311 typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
312 typename tag_cast
313 <
314 typename cs_tag<point_type1>::type, spherical_tag
315 >::type,
316 typename tag_cast
317 <
318 typename cs_tag<point_type2>::type, spherical_tag
319 >::type,
320 Geometry1,
321 Geometry2
322 >::type strategy_type;
323
324 return apply(geometry1, geometry2, strategy_type());
325 }
326};
327
328} // namespace resolve_strategy
329
330
331namespace resolve_variant
332{
333
334template <typename Geometry1, typename Geometry2>
335struct within
336{
337 template <typename Strategy>
338 static inline bool apply(Geometry1 const& geometry1,
339 Geometry2 const& geometry2,
340 Strategy const& strategy)
341 {
342 concepts::check<Geometry1 const>();
343 concepts::check<Geometry2 const>();
344 assert_dimension_equal<Geometry1, Geometry2>();
345
346 return resolve_strategy::within::apply(geometry1,
347 geometry2,
348 strategy);
349 }
350};
351
352template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
353struct within<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
354{
355 template <typename Strategy>
356 struct visitor: boost::static_visitor<bool>
357 {
358 Geometry2 const& m_geometry2;
359 Strategy const& m_strategy;
360
361 visitor(Geometry2 const& geometry2, Strategy const& strategy)
362 : m_geometry2(geometry2)
363 , m_strategy(strategy)
364 {}
365
366 template <typename Geometry1>
367 bool operator()(Geometry1 const& geometry1) const
368 {
369 return within<Geometry1, Geometry2>::apply(geometry1,
370 m_geometry2,
371 m_strategy);
372 }
373 };
374
375 template <typename Strategy>
376 static inline bool
377 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
378 Geometry2 const& geometry2,
379 Strategy const& strategy)
380 {
381 return boost::apply_visitor(visitor<Strategy>(geometry2, strategy),
382 geometry1);
383 }
384};
385
386template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
387struct within<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
388{
389 template <typename Strategy>
390 struct visitor: boost::static_visitor<bool>
391 {
392 Geometry1 const& m_geometry1;
393 Strategy const& m_strategy;
394
395 visitor(Geometry1 const& geometry1, Strategy const& strategy)
396 : m_geometry1(geometry1)
397 , m_strategy(strategy)
398 {}
399
400 template <typename Geometry2>
401 bool operator()(Geometry2 const& geometry2) const
402 {
403 return within<Geometry1, Geometry2>::apply(m_geometry1,
404 geometry2,
405 m_strategy);
406 }
407 };
408
409 template <typename Strategy>
410 static inline bool
411 apply(Geometry1 const& geometry1,
412 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
413 Strategy const& strategy)
414 {
415 return boost::apply_visitor(visitor<Strategy>(geometry1, strategy),
416 geometry2
417 );
418 }
419};
420
421template <
422 BOOST_VARIANT_ENUM_PARAMS(typename T1),
423 BOOST_VARIANT_ENUM_PARAMS(typename T2)
424>
425struct within<
426 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
427 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
428>
429{
430 template <typename Strategy>
431 struct visitor: boost::static_visitor<bool>
432 {
433 Strategy const& m_strategy;
434
435 visitor(Strategy const& strategy): m_strategy(strategy) {}
436
437 template <typename Geometry1, typename Geometry2>
438 bool operator()(Geometry1 const& geometry1,
439 Geometry2 const& geometry2) const
440 {
441 return within<Geometry1, Geometry2>::apply(geometry1,
442 geometry2,
443 m_strategy);
444 }
445 };
446
447 template <typename Strategy>
448 static inline bool
449 apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
450 boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
451 Strategy const& strategy)
452 {
453 return boost::apply_visitor(visitor<Strategy>(strategy),
454 geometry1,
455 geometry2);
456 }
457};
458
459}
460
461
462/*!
463\brief \brief_check12{is completely inside}
464\ingroup within
465\details \details_check12{within, is completely inside}.
466\tparam Geometry1 \tparam_geometry
467\tparam Geometry2 \tparam_geometry
468\param geometry1 \param_geometry which might be within the second geometry
469\param geometry2 \param_geometry which might contain the first geometry
470\return true if geometry1 is completely contained within geometry2,
471 else false
472\note The default strategy is used for within detection
473
474
475\qbk{[include reference/algorithms/within.qbk]}
476
477\qbk{
478[heading Example]
479[within]
480[within_output]
481}
482 */
483template<typename Geometry1, typename Geometry2>
484inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
485{
486 return resolve_variant::within
487 <
488 Geometry1,
489 Geometry2
490 >::apply(geometry1, geometry2, default_strategy());
491}
492
493/*!
494\brief \brief_check12{is completely inside} \brief_strategy
495\ingroup within
496\details \details_check12{within, is completely inside}, \brief_strategy. \details_strategy_reasons
497\tparam Geometry1 \tparam_geometry
498\tparam Geometry2 \tparam_geometry
499\param geometry1 \param_geometry which might be within the second geometry
500\param geometry2 \param_geometry which might contain the first geometry
501\param strategy strategy to be used
502\return true if geometry1 is completely contained within geometry2,
503 else false
504
505\qbk{distinguish,with strategy}
506\qbk{[include reference/algorithms/within.qbk]}
507\qbk{
508[heading Available Strategies]
509\* [link geometry.reference.strategies.strategy_within_winding Winding (coordinate system agnostic)]
510\* [link geometry.reference.strategies.strategy_within_franklin Franklin (cartesian)]
511\* [link geometry.reference.strategies.strategy_within_crossings_multiply Crossings Multiply (cartesian)]
512
513[heading Example]
514[within_strategy]
515[within_strategy_output]
516
517}
518*/
519template<typename Geometry1, typename Geometry2, typename Strategy>
520inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2,
521 Strategy const& strategy)
522{
523 return resolve_variant::within
524 <
525 Geometry1,
526 Geometry2
527 >::apply(geometry1, geometry2, strategy);
528}
529
530}} // namespace boost::geometry
531
532#endif // BOOST_GEOMETRY_ALGORITHMS_WITHIN_HPP