]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/algorithms/detail/overlay/range_in_geometry.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / overlay / range_in_geometry.hpp
1 // Boost.Geometry
2
3 // Copyright (c) 2017-2020 Oracle and/or its affiliates.
4 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
5
6 // Use, modification and distribution is subject to the Boost Software License,
7 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9
10
11 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RANGE_IN_GEOMETRY_HPP
12 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RANGE_IN_GEOMETRY_HPP
13
14
15 #include <boost/geometry/algorithms/covered_by.hpp>
16 #include <boost/geometry/core/access.hpp>
17 #include <boost/geometry/core/tags.hpp>
18 #include <boost/geometry/iterators/point_iterator.hpp>
19
20
21 namespace boost { namespace geometry
22 {
23
24
25 #ifndef DOXYGEN_NO_DETAIL
26 namespace detail { namespace overlay
27 {
28
29
30 template
31 <
32 typename Geometry,
33 typename Tag = typename geometry::tag<Geometry>::type
34 >
35 struct points_range
36 {
37 typedef geometry::point_iterator<Geometry const> iterator_type;
38
39 explicit points_range(Geometry const& geometry)
40 : m_geometry(geometry)
41 {}
42
43 iterator_type begin() const
44 {
45 return geometry::points_begin(m_geometry);
46 }
47
48 iterator_type end() const
49 {
50 return geometry::points_end(m_geometry);
51 }
52
53 Geometry const& m_geometry;
54 };
55 // Specialized because point_iterator doesn't support boxes
56 template <typename Box>
57 struct points_range<Box, box_tag>
58 {
59 typedef typename geometry::point_type<Box>::type point_type;
60 typedef const point_type * iterator_type;
61
62 explicit points_range(Box const& box)
63 {
64 detail::assign_box_corners(box,
65 m_corners[0], m_corners[1], m_corners[2], m_corners[3]);
66 }
67
68 iterator_type begin() const
69 {
70 return m_corners;
71 }
72
73 iterator_type end() const
74 {
75 return m_corners + 4;
76 }
77
78 point_type m_corners[4];
79 };
80
81 template
82 <
83 typename Geometry,
84 typename Tag = typename geometry::tag<Geometry>::type
85 >
86 struct point_in_geometry_helper
87 {
88 template <typename Point, typename Strategy>
89 static inline int apply(Point const& point, Geometry const& geometry,
90 Strategy const& strategy)
91 {
92 return detail::within::point_in_geometry(point, geometry, strategy);
93 }
94 };
95 // Specialized because point_in_geometry doesn't support Boxes
96 template <typename Box>
97 struct point_in_geometry_helper<Box, box_tag>
98 {
99 template <typename Point, typename Strategy>
100 static inline int apply(Point const& point, Box const& box,
101 Strategy const& strategy)
102 {
103 return geometry::covered_by(point, box, strategy) ? 1 : -1;
104 }
105 };
106
107 // This function returns
108 // when it finds a point of geometry1 inside or outside geometry2
109 template <typename Geometry1, typename Geometry2, typename Strategy>
110 static inline int range_in_geometry(Geometry1 const& geometry1,
111 Geometry2 const& geometry2,
112 Strategy const& strategy,
113 bool skip_first = false)
114 {
115 int result = 0;
116 points_range<Geometry1> points(geometry1);
117 typedef typename points_range<Geometry1>::iterator_type iterator_type;
118 iterator_type const end = points.end();
119 iterator_type it = points.begin();
120 if (it == end)
121 {
122 return result;
123 }
124 else if (skip_first)
125 {
126 ++it;
127 }
128
129 for ( ; it != end; ++it)
130 {
131 result = point_in_geometry_helper<Geometry2>::apply(*it, geometry2, strategy);
132 if (result != 0)
133 {
134 return result;
135 }
136 }
137 // all points contained entirely by the boundary
138 return result;
139 }
140
141 // This function returns if first_point1 is inside or outside geometry2 or
142 // when it finds a point of geometry1 inside or outside geometry2
143 template <typename Point1, typename Geometry1, typename Geometry2, typename Strategy>
144 inline int range_in_geometry(Point1 const& first_point1,
145 Geometry1 const& geometry1,
146 Geometry2 const& geometry2,
147 Strategy const& strategy)
148 {
149 // check a point on border of geometry1 first
150 int result = point_in_geometry_helper<Geometry2>::apply(first_point1, geometry2, strategy);
151 if (result == 0)
152 {
153 // if a point is on boundary of geometry2
154 // check points of geometry1 until point inside/outside is found
155 // NOTE: skip first point because it should be already tested above
156 result = range_in_geometry(geometry1, geometry2, strategy, true);
157 }
158 return result;
159 }
160
161
162 }} // namespace detail::overlay
163 #endif // DOXYGEN_NO_DETAIL
164
165
166 }} // namespace boost::geometry
167
168
169 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_RANGE_IN_GEOMETRY_HPP