Chris@102
|
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
|
Chris@102
|
2
|
Chris@102
|
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
Chris@102
|
4
|
Chris@102
|
5 // This file was modified by Oracle on 2013, 2014.
|
Chris@102
|
6 // Modifications copyright (c) 2013-2014 Oracle and/or its affiliates.
|
Chris@102
|
7
|
Chris@102
|
8 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@102
|
9 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@102
|
10 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
11
|
Chris@102
|
12 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
Chris@102
|
13
|
Chris@102
|
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_HPP
|
Chris@102
|
15 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_HPP
|
Chris@102
|
16
|
Chris@102
|
17 #include <cstddef>
|
Chris@102
|
18
|
Chris@102
|
19 #include <boost/concept_check.hpp>
|
Chris@102
|
20 #include <boost/range.hpp>
|
Chris@102
|
21
|
Chris@102
|
22 #include <boost/mpl/if.hpp>
|
Chris@102
|
23 #include <boost/mpl/or.hpp>
|
Chris@102
|
24 #include <boost/type_traits/is_base_of.hpp>
|
Chris@102
|
25
|
Chris@102
|
26 #include <boost/geometry/algorithms/make.hpp>
|
Chris@102
|
27 #include <boost/geometry/algorithms/not_implemented.hpp>
|
Chris@102
|
28
|
Chris@102
|
29 #include <boost/geometry/core/access.hpp>
|
Chris@102
|
30 #include <boost/geometry/core/closure.hpp>
|
Chris@102
|
31 #include <boost/geometry/core/cs.hpp>
|
Chris@102
|
32 #include <boost/geometry/core/exterior_ring.hpp>
|
Chris@102
|
33 #include <boost/geometry/core/interior_rings.hpp>
|
Chris@102
|
34 #include <boost/geometry/core/point_order.hpp>
|
Chris@102
|
35 #include <boost/geometry/core/ring_type.hpp>
|
Chris@102
|
36 #include <boost/geometry/core/interior_rings.hpp>
|
Chris@102
|
37 #include <boost/geometry/core/tags.hpp>
|
Chris@102
|
38
|
Chris@102
|
39 #include <boost/geometry/geometries/concepts/check.hpp>
|
Chris@102
|
40 #include <boost/geometry/strategies/concepts/within_concept.hpp>
|
Chris@102
|
41 #include <boost/geometry/strategies/default_strategy.hpp>
|
Chris@102
|
42 #include <boost/geometry/strategies/within.hpp>
|
Chris@102
|
43 #include <boost/geometry/util/math.hpp>
|
Chris@102
|
44 #include <boost/geometry/util/order_as_direction.hpp>
|
Chris@102
|
45 #include <boost/geometry/views/closeable_view.hpp>
|
Chris@102
|
46 #include <boost/geometry/views/reversible_view.hpp>
|
Chris@102
|
47
|
Chris@102
|
48 #include <boost/geometry/algorithms/detail/relate/result.hpp>
|
Chris@102
|
49
|
Chris@102
|
50 #include <boost/geometry/algorithms/detail/relate/point_point.hpp>
|
Chris@102
|
51 #include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
|
Chris@102
|
52 #include <boost/geometry/algorithms/detail/relate/linear_linear.hpp>
|
Chris@102
|
53 #include <boost/geometry/algorithms/detail/relate/linear_areal.hpp>
|
Chris@102
|
54 #include <boost/geometry/algorithms/detail/relate/areal_areal.hpp>
|
Chris@102
|
55
|
Chris@102
|
56 namespace boost { namespace geometry
|
Chris@102
|
57 {
|
Chris@102
|
58
|
Chris@102
|
59 #ifndef DOXYGEN_NO_DETAIL
|
Chris@102
|
60 namespace detail { namespace relate {
|
Chris@102
|
61
|
Chris@102
|
62 // Those are used only to allow dispatch::relate to produce compile-time error
|
Chris@102
|
63
|
Chris@102
|
64 template <typename Geometry,
|
Chris@102
|
65 typename Tag = typename geometry::tag<Geometry>::type>
|
Chris@102
|
66 struct is_supported_by_generic
|
Chris@102
|
67 {
|
Chris@102
|
68 static const bool value
|
Chris@102
|
69 = boost::is_same<Tag, linestring_tag>::value
|
Chris@102
|
70 || boost::is_same<Tag, multi_linestring_tag>::value
|
Chris@102
|
71 || boost::is_same<Tag, ring_tag>::value
|
Chris@102
|
72 || boost::is_same<Tag, polygon_tag>::value
|
Chris@102
|
73 || boost::is_same<Tag, multi_polygon_tag>::value;
|
Chris@102
|
74 };
|
Chris@102
|
75
|
Chris@102
|
76 template <typename Geometry1,
|
Chris@102
|
77 typename Geometry2,
|
Chris@102
|
78 typename Tag1 = typename geometry::tag<Geometry1>::type,
|
Chris@102
|
79 typename Tag2 = typename geometry::tag<Geometry2>::type>
|
Chris@102
|
80 struct is_generic
|
Chris@102
|
81 {
|
Chris@102
|
82 static const bool value = is_supported_by_generic<Geometry1>::value
|
Chris@102
|
83 && is_supported_by_generic<Geometry2>::value;
|
Chris@102
|
84 };
|
Chris@102
|
85
|
Chris@102
|
86
|
Chris@102
|
87 template <typename Point, typename Geometry, typename Tag>
|
Chris@102
|
88 struct is_generic<Point, Geometry, point_tag, Tag>
|
Chris@102
|
89 {
|
Chris@102
|
90 static const bool value = is_supported_by_generic<Geometry>::value;
|
Chris@102
|
91 };
|
Chris@102
|
92
|
Chris@102
|
93 template <typename Geometry, typename Point, typename Tag>
|
Chris@102
|
94 struct is_generic<Geometry, Point, Tag, point_tag>
|
Chris@102
|
95 {
|
Chris@102
|
96 static const bool value = is_supported_by_generic<Geometry>::value;
|
Chris@102
|
97 };
|
Chris@102
|
98
|
Chris@102
|
99 template <typename Point1, typename Point2>
|
Chris@102
|
100 struct is_generic<Point1, Point2, point_tag, point_tag>
|
Chris@102
|
101 {
|
Chris@102
|
102 static const bool value = false;
|
Chris@102
|
103 };
|
Chris@102
|
104
|
Chris@102
|
105
|
Chris@102
|
106 }} // namespace detail::relate
|
Chris@102
|
107
|
Chris@102
|
108 #ifndef DOXYGEN_NO_DISPATCH
|
Chris@102
|
109 namespace detail_dispatch { namespace relate {
|
Chris@102
|
110
|
Chris@102
|
111
|
Chris@102
|
112 template <typename Geometry1,
|
Chris@102
|
113 typename Geometry2,
|
Chris@102
|
114 typename Tag1 = typename geometry::tag<Geometry1>::type,
|
Chris@102
|
115 typename Tag2 = typename geometry::tag<Geometry2>::type,
|
Chris@102
|
116 int TopDim1 = geometry::topological_dimension<Geometry1>::value,
|
Chris@102
|
117 int TopDim2 = geometry::topological_dimension<Geometry2>::value,
|
Chris@102
|
118 bool IsGeneric = detail::relate::is_generic<Geometry1, Geometry2>::value
|
Chris@102
|
119 >
|
Chris@102
|
120 struct relate : not_implemented<Tag1, Tag2>
|
Chris@102
|
121 {};
|
Chris@102
|
122
|
Chris@102
|
123
|
Chris@102
|
124 template <typename Point1, typename Point2>
|
Chris@102
|
125 struct relate<Point1, Point2, point_tag, point_tag, 0, 0, false>
|
Chris@102
|
126 : detail::relate::point_point<Point1, Point2>
|
Chris@102
|
127 {};
|
Chris@102
|
128
|
Chris@102
|
129 template <typename Point, typename MultiPoint>
|
Chris@102
|
130 struct relate<Point, MultiPoint, point_tag, multi_point_tag, 0, 0, false>
|
Chris@102
|
131 : detail::relate::point_multipoint<Point, MultiPoint>
|
Chris@102
|
132 {};
|
Chris@102
|
133
|
Chris@102
|
134 template <typename MultiPoint, typename Point>
|
Chris@102
|
135 struct relate<MultiPoint, Point, multi_point_tag, point_tag, 0, 0, false>
|
Chris@102
|
136 : detail::relate::multipoint_point<MultiPoint, Point>
|
Chris@102
|
137 {};
|
Chris@102
|
138
|
Chris@102
|
139 template <typename MultiPoint1, typename MultiPoint2>
|
Chris@102
|
140 struct relate<MultiPoint1, MultiPoint2, multi_point_tag, multi_point_tag, 0, 0, false>
|
Chris@102
|
141 : detail::relate::multipoint_multipoint<MultiPoint1, MultiPoint2>
|
Chris@102
|
142 {};
|
Chris@102
|
143
|
Chris@102
|
144 //template <typename Point, typename Box, int TopDim2>
|
Chris@102
|
145 //struct relate<Point, Box, point_tag, box_tag, 0, TopDim2, false>
|
Chris@102
|
146 // : detail::relate::point_box<Point, Box>
|
Chris@102
|
147 //{};
|
Chris@102
|
148 //
|
Chris@102
|
149 //template <typename Box, typename Point, int TopDim1>
|
Chris@102
|
150 //struct relate<Box, Point, box_tag, point_tag, TopDim1, 0, false>
|
Chris@102
|
151 // : detail::relate::box_point<Box, Point>
|
Chris@102
|
152 //{};
|
Chris@102
|
153
|
Chris@102
|
154
|
Chris@102
|
155 template <typename Point, typename Geometry, typename Tag2, int TopDim2>
|
Chris@102
|
156 struct relate<Point, Geometry, point_tag, Tag2, 0, TopDim2, true>
|
Chris@102
|
157 : detail::relate::point_geometry<Point, Geometry>
|
Chris@102
|
158 {};
|
Chris@102
|
159
|
Chris@102
|
160 template <typename Geometry, typename Point, typename Tag1, int TopDim1>
|
Chris@102
|
161 struct relate<Geometry, Point, Tag1, point_tag, TopDim1, 0, true>
|
Chris@102
|
162 : detail::relate::geometry_point<Geometry, Point>
|
Chris@102
|
163 {};
|
Chris@102
|
164
|
Chris@102
|
165
|
Chris@102
|
166 template <typename Linear1, typename Linear2, typename Tag1, typename Tag2>
|
Chris@102
|
167 struct relate<Linear1, Linear2, Tag1, Tag2, 1, 1, true>
|
Chris@102
|
168 : detail::relate::linear_linear<Linear1, Linear2>
|
Chris@102
|
169 {};
|
Chris@102
|
170
|
Chris@102
|
171
|
Chris@102
|
172 template <typename Linear, typename Areal, typename Tag1, typename Tag2>
|
Chris@102
|
173 struct relate<Linear, Areal, Tag1, Tag2, 1, 2, true>
|
Chris@102
|
174 : detail::relate::linear_areal<Linear, Areal>
|
Chris@102
|
175 {};
|
Chris@102
|
176
|
Chris@102
|
177 template <typename Areal, typename Linear, typename Tag1, typename Tag2>
|
Chris@102
|
178 struct relate<Areal, Linear, Tag1, Tag2, 2, 1, true>
|
Chris@102
|
179 : detail::relate::areal_linear<Areal, Linear>
|
Chris@102
|
180 {};
|
Chris@102
|
181
|
Chris@102
|
182
|
Chris@102
|
183 template <typename Areal1, typename Areal2, typename Tag1, typename Tag2>
|
Chris@102
|
184 struct relate<Areal1, Areal2, Tag1, Tag2, 2, 2, true>
|
Chris@102
|
185 : detail::relate::areal_areal<Areal1, Areal2>
|
Chris@102
|
186 {};
|
Chris@102
|
187
|
Chris@102
|
188
|
Chris@102
|
189 }} // namespace detail_dispatch::relate
|
Chris@102
|
190 #endif // DOXYGEN_NO_DISPATCH
|
Chris@102
|
191
|
Chris@102
|
192 namespace detail { namespace relate {
|
Chris@102
|
193
|
Chris@102
|
194 template <typename Geometry1, typename Geometry2>
|
Chris@102
|
195 struct interruption_enabled
|
Chris@102
|
196 {
|
Chris@102
|
197 static const bool value =
|
Chris@102
|
198 detail_dispatch::relate::relate<Geometry1, Geometry2>::interruption_enabled;
|
Chris@102
|
199 };
|
Chris@102
|
200
|
Chris@102
|
201 template <typename Geometry1,
|
Chris@102
|
202 typename Geometry2,
|
Chris@102
|
203 typename Result,
|
Chris@102
|
204 bool IsSequence = boost::mpl::is_sequence<Result>::value>
|
Chris@102
|
205 struct result_handler_type
|
Chris@102
|
206 : not_implemented<Result>
|
Chris@102
|
207 {};
|
Chris@102
|
208
|
Chris@102
|
209 template <typename Geometry1, typename Geometry2>
|
Chris@102
|
210 struct result_handler_type<Geometry1, Geometry2, matrix9, false>
|
Chris@102
|
211 {
|
Chris@102
|
212 typedef matrix_handler<matrix9> type;
|
Chris@102
|
213 };
|
Chris@102
|
214
|
Chris@102
|
215 template <typename Geometry1, typename Geometry2>
|
Chris@102
|
216 struct result_handler_type<Geometry1, Geometry2, mask9, false>
|
Chris@102
|
217 {
|
Chris@102
|
218 typedef mask_handler
|
Chris@102
|
219 <
|
Chris@102
|
220 mask9,
|
Chris@102
|
221 interruption_enabled
|
Chris@102
|
222 <
|
Chris@102
|
223 Geometry1,
|
Chris@102
|
224 Geometry2
|
Chris@102
|
225 >::value
|
Chris@102
|
226 > type;
|
Chris@102
|
227 };
|
Chris@102
|
228
|
Chris@102
|
229 template <typename Geometry1, typename Geometry2, typename Head, typename Tail>
|
Chris@102
|
230 struct result_handler_type<Geometry1, Geometry2, boost::tuples::cons<Head, Tail>, false>
|
Chris@102
|
231 {
|
Chris@102
|
232 typedef mask_handler
|
Chris@102
|
233 <
|
Chris@102
|
234 boost::tuples::cons<Head, Tail>,
|
Chris@102
|
235 interruption_enabled
|
Chris@102
|
236 <
|
Chris@102
|
237 Geometry1,
|
Chris@102
|
238 Geometry2
|
Chris@102
|
239 >::value
|
Chris@102
|
240 > type;
|
Chris@102
|
241 };
|
Chris@102
|
242
|
Chris@102
|
243 template <typename Geometry1, typename Geometry2,
|
Chris@102
|
244 char II, char IB, char IE,
|
Chris@102
|
245 char BI, char BB, char BE,
|
Chris@102
|
246 char EI, char EB, char EE>
|
Chris@102
|
247 struct result_handler_type<Geometry1, Geometry2, static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>, false>
|
Chris@102
|
248 {
|
Chris@102
|
249 typedef static_mask_handler
|
Chris@102
|
250 <
|
Chris@102
|
251 static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>,
|
Chris@102
|
252 interruption_enabled
|
Chris@102
|
253 <
|
Chris@102
|
254 Geometry1,
|
Chris@102
|
255 Geometry2
|
Chris@102
|
256 >::value
|
Chris@102
|
257 > type;
|
Chris@102
|
258 };
|
Chris@102
|
259
|
Chris@102
|
260 template <typename Geometry1, typename Geometry2, typename StaticSequence>
|
Chris@102
|
261 struct result_handler_type<Geometry1, Geometry2, StaticSequence, true>
|
Chris@102
|
262 {
|
Chris@102
|
263 typedef static_mask_handler
|
Chris@102
|
264 <
|
Chris@102
|
265 StaticSequence,
|
Chris@102
|
266 interruption_enabled
|
Chris@102
|
267 <
|
Chris@102
|
268 Geometry1,
|
Chris@102
|
269 Geometry2
|
Chris@102
|
270 >::value
|
Chris@102
|
271 > type;
|
Chris@102
|
272 };
|
Chris@102
|
273
|
Chris@102
|
274 template <typename MatrixOrMask, typename Geometry1, typename Geometry2>
|
Chris@102
|
275 inline
|
Chris@102
|
276 typename result_handler_type
|
Chris@102
|
277 <
|
Chris@102
|
278 Geometry1,
|
Chris@102
|
279 Geometry2,
|
Chris@102
|
280 MatrixOrMask
|
Chris@102
|
281 >::type::result_type
|
Chris@102
|
282 relate(Geometry1 const& geometry1,
|
Chris@102
|
283 Geometry2 const& geometry2,
|
Chris@102
|
284 MatrixOrMask const& matrix_or_mask = MatrixOrMask())
|
Chris@102
|
285 {
|
Chris@102
|
286 typedef typename result_handler_type
|
Chris@102
|
287 <
|
Chris@102
|
288 Geometry1,
|
Chris@102
|
289 Geometry2,
|
Chris@102
|
290 MatrixOrMask
|
Chris@102
|
291 >::type handler_type;
|
Chris@102
|
292
|
Chris@102
|
293 handler_type handler(matrix_or_mask);
|
Chris@102
|
294 detail_dispatch::relate::relate<Geometry1, Geometry2>::apply(geometry1, geometry2, handler);
|
Chris@102
|
295 return handler.result();
|
Chris@102
|
296 }
|
Chris@102
|
297
|
Chris@102
|
298 struct implemented_tag {};
|
Chris@102
|
299
|
Chris@102
|
300 template <template <typename, typename> class StaticMaskTrait,
|
Chris@102
|
301 typename Geometry1,
|
Chris@102
|
302 typename Geometry2>
|
Chris@102
|
303 struct relate_base
|
Chris@102
|
304 : boost::mpl::if_
|
Chris@102
|
305 <
|
Chris@102
|
306 boost::mpl::or_
|
Chris@102
|
307 <
|
Chris@102
|
308 boost::is_base_of
|
Chris@102
|
309 <
|
Chris@102
|
310 nyi::not_implemented_tag,
|
Chris@102
|
311 StaticMaskTrait<Geometry1, Geometry2>
|
Chris@102
|
312 >,
|
Chris@102
|
313 boost::is_base_of
|
Chris@102
|
314 <
|
Chris@102
|
315 nyi::not_implemented_tag,
|
Chris@102
|
316 detail_dispatch::relate::relate<Geometry1, Geometry2>
|
Chris@102
|
317 >
|
Chris@102
|
318 >,
|
Chris@102
|
319 not_implemented
|
Chris@102
|
320 <
|
Chris@102
|
321 typename geometry::tag<Geometry1>::type,
|
Chris@102
|
322 typename geometry::tag<Geometry2>::type
|
Chris@102
|
323 >,
|
Chris@102
|
324 implemented_tag
|
Chris@102
|
325 >::type
|
Chris@102
|
326 {
|
Chris@102
|
327 static inline bool apply(Geometry1 const& g1, Geometry2 const& g2)
|
Chris@102
|
328 {
|
Chris@102
|
329 typedef typename StaticMaskTrait<Geometry1, Geometry2>::type static_mask;
|
Chris@102
|
330 return detail::relate::relate<static_mask>(g1, g2);
|
Chris@102
|
331 }
|
Chris@102
|
332 };
|
Chris@102
|
333
|
Chris@102
|
334 }} // namespace detail::relate
|
Chris@102
|
335 #endif // DOXYGEN_NO_DETAIL
|
Chris@102
|
336
|
Chris@102
|
337 }} // namespace boost::geometry
|
Chris@102
|
338
|
Chris@102
|
339 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RELATE_HPP
|