1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
5 // This file was modified by Oracle on 2013, 2014, 2015.
6 // Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
15 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
17 #include <boost/mpl/is_sequence.hpp>
18 #include <boost/mpl/push_back.hpp>
19 #include <boost/mpl/vector.hpp>
20 #include <boost/mpl/vector_c.hpp>
21 #include <boost/static_assert.hpp>
22 #include <boost/tuple/tuple.hpp>
24 #include <boost/geometry/algorithms/detail/relate/result.hpp>
25 #include <boost/geometry/algorithms/not_implemented.hpp>
26 #include <boost/geometry/core/topological_dimension.hpp>
27 #include <boost/geometry/core/tag.hpp>
29 // TEMP - move this header to geometry/detail
30 #include <boost/geometry/index/detail/tuples.hpp>
32 namespace boost { namespace geometry
39 \brief DE-9IM model intersection matrix.
41 \details This matrix can be used to express spatial relations as defined in
42 Dimensionally Extended 9-Intersection Model.
44 \qbk{[heading See also]}
45 \qbk{* [link geometry.reference.algorithms.relation relation]}
48 : public detail::relate::matrix<3, 3>
50 #ifdef DOXYGEN_INVOKED
53 \brief Initializes all of the matrix elements to F
57 \brief Subscript operator
58 \param index The index of the element
61 char operator[](std::size_t index) const;
63 \brief Returns the iterator to the first element
64 \return const RandomAccessIterator
66 const_iterator begin() const;
68 \brief Returns the iterator past the last element
69 \return const RandomAccessIterator
71 const_iterator end() const;
73 \brief Returns the number of elements
76 static std::size_t size();
78 \brief Returns raw pointer to elements
79 \return const pointer to array of elements
81 inline const char * data() const;
83 \brief Returns std::string containing elements
84 \return string containing elements
86 inline std::string str() const;
91 \brief DE-9IM model intersection mask.
93 \details This mask can be used to check spatial relations as defined in
94 Dimensionally Extended 9-Intersection Model.
96 \qbk{[heading See also]}
97 \qbk{* [link geometry.reference.algorithms.relate relate]}
100 : public detail::relate::mask<3, 3>
102 typedef detail::relate::mask<3, 3> base_type;
106 \brief The constructor.
107 \param code The mask pattern.
109 inline explicit mask(const char* code)
114 \brief The constructor.
115 \param code The mask pattern.
117 inline explicit mask(std::string const& code)
118 : base_type(code.c_str(), code.size())
125 \brief DE-9IM model intersection mask (static version).
127 \details This mask can be used to check spatial relations as defined in
128 Dimensionally Extended 9-Intersection Model.
129 \tparam II Interior/Interior intersection mask element
130 \tparam IB Interior/Boundary intersection mask element
131 \tparam IE Interior/Exterior intersection mask element
132 \tparam BI Boundary/Interior intersection mask element
133 \tparam BB Boundary/Boundary intersection mask element
134 \tparam BE Boundary/Exterior intersection mask element
135 \tparam EI Exterior/Interior intersection mask element
136 \tparam EB Exterior/Boundary intersection mask element
137 \tparam EE Exterior/Exterior intersection mask element
139 \qbk{[heading See also]}
140 \qbk{* [link geometry.reference.algorithms.relate relate]}
144 char II = '*', char IB = '*', char IE = '*',
145 char BI = '*', char BB = '*', char BE = '*',
146 char EI = '*', char EB = '*', char EE = '*'
149 : public detail::relate::static_mask
153 char, II, IB, IE, BI, BB, BE, EI, EB, EE
161 namespace detail { namespace de9im
164 // a small helper util for ORing static masks
170 bool IsSeq = boost::mpl::is_sequence<Seq>::value
174 typedef typename boost::mpl::push_back
181 template <typename Seq, typename T>
182 struct push_back<Seq, T, false>
185 }} // namespace detail::de9im
194 boost::tuples::cons<mask, boost::tuples::null_type>
196 operator||(mask const& m1, mask const& m2)
198 namespace bt = boost::tuples;
200 return bt::cons<mask, bt::cons<mask, bt::null_type> >
201 ( m1, bt::cons<mask, bt::null_type>(m2, bt::null_type()) );
204 template <typename Tail>
206 typename index::detail::tuples::push_back
208 boost::tuples::cons<mask, Tail>,
211 operator||(boost::tuples::cons<mask, Tail> const& t, mask const& m)
213 namespace bt = boost::tuples;
215 return index::detail::tuples::push_back
217 bt::cons<mask, Tail>,
224 char II1, char IB1, char IE1,
225 char BI1, char BB1, char BE1,
226 char EI1, char EB1, char EE1,
227 char II2, char IB2, char IE2,
228 char BI2, char BB2, char BE2,
229 char EI2, char EB2, char EE2
233 static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1>,
234 static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2>
236 operator||(static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1> const& ,
237 static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2> const& )
239 return boost::mpl::vector
241 static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1>,
242 static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2>
249 char II, char IB, char IE,
250 char BI, char BB, char BE,
251 char EI, char EB, char EE
254 typename detail::de9im::push_back
257 static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
259 operator||(Seq const& ,
260 static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE> const& )
262 return typename detail::de9im::push_back
265 static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
272 #ifndef DOXYGEN_NO_DETAIL
273 namespace detail { namespace de9im
279 // 1. specialize for simplified masks if available
280 // e.g. for TOUCHES use 1 mask for A/A
281 // 2. Think about dimensions > 2 e.g. should TOUCHES be true
282 // if the interior of the Areal overlaps the boundary of the Volumetric
283 // like it's true for Linear/Areal
286 template <typename Geometry1, typename Geometry2>
287 struct static_mask_equals_type
289 typedef geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', 'F', 'F', '*'> type; // wikipedia
290 //typedef geometry::de9im::static_mask<'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F', 'T'> type; // OGC
294 template <typename Geometry1, typename Geometry2>
295 struct static_mask_disjoint_type
297 typedef geometry::de9im::static_mask<'F', 'F', '*', 'F', 'F', '*', '*', '*', '*'> type;
305 std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
306 std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value
308 struct static_mask_touches_impl
310 typedef boost::mpl::vector
312 geometry::de9im::static_mask<'F', 'T', '*', '*', '*', '*', '*', '*', '*'>,
313 geometry::de9im::static_mask<'F', '*', '*', 'T', '*', '*', '*', '*', '*'>,
314 geometry::de9im::static_mask<'F', '*', '*', '*', 'T', '*', '*', '*', '*'>
317 // According to OGC, doesn't apply to P/P
318 // Using the above mask the result would be always false
319 template <typename Geometry1, typename Geometry2>
320 struct static_mask_touches_impl<Geometry1, Geometry2, 0, 0>
321 : not_implemented<typename geometry::tag<Geometry1>::type,
322 typename geometry::tag<Geometry2>::type>
325 template <typename Geometry1, typename Geometry2>
326 struct static_mask_touches_type
327 : static_mask_touches_impl<Geometry1, Geometry2>
331 template <typename Geometry1, typename Geometry2>
332 struct static_mask_within_type
334 typedef geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'> type;
337 // COVERED_BY (non OGC)
338 template <typename Geometry1, typename Geometry2>
339 struct static_mask_covered_by_type
341 typedef boost::mpl::vector
343 geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'>,
344 geometry::de9im::static_mask<'*', 'T', 'F', '*', '*', 'F', '*', '*', '*'>,
345 geometry::de9im::static_mask<'*', '*', 'F', 'T', '*', 'F', '*', '*', '*'>,
346 geometry::de9im::static_mask<'*', '*', 'F', '*', 'T', 'F', '*', '*', '*'>
351 // dim(G1) < dim(G2) - P/L P/A L/A
356 std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
357 std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value,
358 bool D1LessD2 = (Dim1 < Dim2)
360 struct static_mask_crosses_impl
362 typedef geometry::de9im::static_mask<'T', '*', 'T', '*', '*', '*', '*', '*', '*'> type;
364 // TODO: I'm not sure if this one below should be available!
365 // dim(G1) > dim(G2) - L/P A/P A/L
368 typename Geometry1, typename Geometry2, std::size_t Dim1, std::size_t Dim2
370 struct static_mask_crosses_impl<Geometry1, Geometry2, Dim1, Dim2, false>
372 typedef geometry::de9im::static_mask<'T', '*', '*', '*', '*', '*', 'T', '*', '*'> type;
374 // dim(G1) == dim(G2) - P/P A/A
377 typename Geometry1, typename Geometry2, std::size_t Dim
379 struct static_mask_crosses_impl<Geometry1, Geometry2, Dim, Dim, false>
382 typename geometry::tag<Geometry1>::type,
383 typename geometry::tag<Geometry2>::type
386 // dim(G1) == 1 && dim(G2) == 1 - L/L
387 template <typename Geometry1, typename Geometry2>
388 struct static_mask_crosses_impl<Geometry1, Geometry2, 1, 1, false>
390 typedef geometry::de9im::static_mask<'0', '*', '*', '*', '*', '*', '*', '*', '*'> type;
393 template <typename Geometry1, typename Geometry2>
394 struct static_mask_crosses_type
395 : static_mask_crosses_impl<Geometry1, Geometry2>
400 // dim(G1) != dim(G2) - NOT P/P, L/L, A/A
405 std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
406 std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value
408 struct static_mask_overlaps_impl
411 typename geometry::tag<Geometry1>::type,
412 typename geometry::tag<Geometry2>::type
415 // dim(G1) == D && dim(G2) == D - P/P A/A
416 template <typename Geometry1, typename Geometry2, std::size_t Dim>
417 struct static_mask_overlaps_impl<Geometry1, Geometry2, Dim, Dim>
419 typedef geometry::de9im::static_mask<'T', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
421 // dim(G1) == 1 && dim(G2) == 1 - L/L
422 template <typename Geometry1, typename Geometry2>
423 struct static_mask_overlaps_impl<Geometry1, Geometry2, 1, 1>
425 typedef geometry::de9im::static_mask<'1', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
428 template <typename Geometry1, typename Geometry2>
429 struct static_mask_overlaps_type
430 : static_mask_overlaps_impl<Geometry1, Geometry2>
433 }} // namespace detail::de9im
434 #endif // DOXYGEN_NO_DETAIL
437 }} // namespace boost::geometry
439 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP