]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/algorithms/detail/distance/multipoint_to_geometry.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / geometry / algorithms / detail / distance / multipoint_to_geometry.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2014, 2019, 2020 Oracle and/or its affiliates.
4
5 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
10
11 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP
12 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP
13
14 #include <boost/range/begin.hpp>
15 #include <boost/range/end.hpp>
16 #include <boost/range/size.hpp>
17
18 #include <boost/geometry/core/point_type.hpp>
19 #include <boost/geometry/core/tags.hpp>
20
21 #include <boost/geometry/strategies/distance.hpp>
22 #include <boost/geometry/strategies/tags.hpp>
23
24 #include <boost/geometry/algorithms/covered_by.hpp>
25
26 #include <boost/geometry/algorithms/dispatch/distance.hpp>
27
28 #include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
29 #include <boost/geometry/algorithms/detail/distance/range_to_geometry_rtree.hpp>
30
31
32 namespace boost { namespace geometry
33 {
34
35 #ifndef DOXYGEN_NO_DETAIL
36 namespace detail { namespace distance
37 {
38
39
40 template <typename MultiPoint1, typename MultiPoint2, typename Strategy>
41 struct multipoint_to_multipoint
42 {
43 typedef typename strategy::distance::services::return_type
44 <
45 Strategy,
46 typename point_type<MultiPoint1>::type,
47 typename point_type<MultiPoint2>::type
48 >::type return_type;
49
50 static inline return_type apply(MultiPoint1 const& multipoint1,
51 MultiPoint2 const& multipoint2,
52 Strategy const& strategy)
53 {
54 if (boost::size(multipoint2) < boost::size(multipoint1))
55
56 {
57 return point_or_segment_range_to_geometry_rtree
58 <
59 typename boost::range_iterator<MultiPoint2 const>::type,
60 MultiPoint1,
61 Strategy
62 >::apply(boost::begin(multipoint2),
63 boost::end(multipoint2),
64 multipoint1,
65 strategy);
66 }
67
68 return point_or_segment_range_to_geometry_rtree
69 <
70 typename boost::range_iterator<MultiPoint1 const>::type,
71 MultiPoint2,
72 Strategy
73 >::apply(boost::begin(multipoint1),
74 boost::end(multipoint1),
75 multipoint2,
76 strategy);
77 }
78 };
79
80
81 template <typename MultiPoint, typename Linear, typename Strategy>
82 struct multipoint_to_linear
83 {
84 typedef typename strategy::distance::services::return_type
85 <
86 Strategy,
87 typename point_type<MultiPoint>::type,
88 typename point_type<Linear>::type
89 >::type return_type;
90
91 static inline return_type apply(MultiPoint const& multipoint,
92 Linear const& linear,
93 Strategy const& strategy)
94 {
95 return detail::distance::point_or_segment_range_to_geometry_rtree
96 <
97 typename boost::range_iterator<MultiPoint const>::type,
98 Linear,
99 Strategy
100 >::apply(boost::begin(multipoint),
101 boost::end(multipoint),
102 linear,
103 strategy);
104 }
105
106 static inline return_type apply(Linear const& linear,
107 MultiPoint const& multipoint,
108 Strategy const& strategy)
109 {
110 return apply(multipoint, linear, strategy);
111 }
112 };
113
114
115 template <typename MultiPoint, typename Areal, typename Strategy>
116 class multipoint_to_areal
117 {
118 private:
119 template <typename CoveredByStrategy>
120 struct not_covered_by_areal
121 {
122 not_covered_by_areal(Areal const& areal, CoveredByStrategy const& strategy)
123 : m_areal(areal), m_strategy(strategy)
124 {}
125
126 template <typename Point>
127 inline bool apply(Point const& point) const
128 {
129 return !geometry::covered_by(point, m_areal, m_strategy);
130 }
131
132 Areal const& m_areal;
133 CoveredByStrategy const& m_strategy;
134 };
135
136 public:
137 typedef typename strategy::distance::services::return_type
138 <
139 Strategy,
140 typename point_type<MultiPoint>::type,
141 typename point_type<Areal>::type
142 >::type return_type;
143
144 static inline return_type apply(MultiPoint const& multipoint,
145 Areal const& areal,
146 Strategy const& strategy)
147 {
148 typedef typename Strategy::point_in_geometry_strategy_type pg_strategy_type;
149
150 typedef not_covered_by_areal<pg_strategy_type> predicate_type;
151
152 // predicate holds references so the strategy has to be created here
153 pg_strategy_type pg_strategy = strategy.get_point_in_geometry_strategy();
154 predicate_type predicate(areal, pg_strategy);
155
156 if (check_iterator_range
157 <
158 predicate_type, false
159 >::apply(boost::begin(multipoint),
160 boost::end(multipoint),
161 predicate))
162 {
163 return detail::distance::point_or_segment_range_to_geometry_rtree
164 <
165 typename boost::range_iterator<MultiPoint const>::type,
166 Areal,
167 Strategy
168 >::apply(boost::begin(multipoint),
169 boost::end(multipoint),
170 areal,
171 strategy);
172 }
173 return 0;
174 }
175
176 static inline return_type apply(Areal const& areal,
177 MultiPoint const& multipoint,
178 Strategy const& strategy)
179 {
180 return apply(multipoint, areal, strategy);
181 }
182 };
183
184
185 }} // namespace detail::distance
186 #endif // DOXYGEN_NO_DETAIL
187
188
189
190 #ifndef DOXYGEN_NO_DISPATCH
191 namespace dispatch
192 {
193
194
195 template <typename MultiPoint1, typename MultiPoint2, typename Strategy>
196 struct distance
197 <
198 MultiPoint1, MultiPoint2, Strategy,
199 multi_point_tag, multi_point_tag,
200 strategy_tag_distance_point_point, false
201 > : detail::distance::multipoint_to_multipoint
202 <
203 MultiPoint1, MultiPoint2, Strategy
204 >
205 {};
206
207
208 template <typename MultiPoint, typename Linear, typename Strategy>
209 struct distance
210 <
211 MultiPoint, Linear, Strategy, multi_point_tag, linear_tag,
212 strategy_tag_distance_point_segment, false
213 > : detail::distance::multipoint_to_linear<MultiPoint, Linear, Strategy>
214 {};
215
216
217 template <typename Linear, typename MultiPoint, typename Strategy>
218 struct distance
219 <
220 Linear, MultiPoint, Strategy, linear_tag, multi_point_tag,
221 strategy_tag_distance_point_segment, false
222 > : detail::distance::multipoint_to_linear<MultiPoint, Linear, Strategy>
223 {};
224
225
226 template <typename MultiPoint, typename Areal, typename Strategy>
227 struct distance
228 <
229 MultiPoint, Areal, Strategy, multi_point_tag, areal_tag,
230 strategy_tag_distance_point_segment, false
231 > : detail::distance::multipoint_to_areal<MultiPoint, Areal, Strategy>
232 {};
233
234
235 template <typename Areal, typename MultiPoint, typename Strategy>
236 struct distance
237 <
238 Areal, MultiPoint, Strategy, areal_tag, multi_point_tag,
239 strategy_tag_distance_point_segment, false
240 > : detail::distance::multipoint_to_areal<MultiPoint, Areal, Strategy>
241 {};
242
243
244 } // namespace dispatch
245 #endif // DOXYGEN_NO_DISPATCH
246
247
248 }} // namespace boost::geometry
249
250
251 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_MULTIPOINT_TO_GEOMETRY_HPP