de9im.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
  3. // This file was modified by Oracle on 2013, 2014, 2015, 2019.
  4. // Modifications copyright (c) 2013-2019 Oracle and/or its affiliates.
  5. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  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. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
  10. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP
  11. #include <boost/mpl/is_sequence.hpp>
  12. #include <boost/mpl/push_back.hpp>
  13. #include <boost/mpl/vector.hpp>
  14. #include <boost/mpl/vector_c.hpp>
  15. #include <boost/static_assert.hpp>
  16. #include <boost/tuple/tuple.hpp>
  17. #include <boost/geometry/algorithms/detail/relate/result.hpp>
  18. #include <boost/geometry/core/topological_dimension.hpp>
  19. #include <boost/geometry/core/tag.hpp>
  20. #include <boost/geometry/util/tuples.hpp>
  21. namespace boost { namespace geometry
  22. {
  23. namespace de9im
  24. {
  25. /*!
  26. \brief DE-9IM model intersection matrix.
  27. \ingroup de9im
  28. \details This matrix can be used to express spatial relations as defined in
  29. Dimensionally Extended 9-Intersection Model.
  30. \qbk{[heading See also]}
  31. \qbk{* [link geometry.reference.algorithms.relation relation]}
  32. */
  33. class matrix
  34. : public detail::relate::matrix<3, 3>
  35. {
  36. #ifdef DOXYGEN_INVOKED
  37. public:
  38. /*!
  39. \brief Initializes all of the matrix elements to F
  40. */
  41. matrix();
  42. /*!
  43. \brief Subscript operator
  44. \param index The index of the element
  45. \return The element
  46. */
  47. char operator[](std::size_t index) const;
  48. /*!
  49. \brief Returns the iterator to the first element
  50. \return const RandomAccessIterator
  51. */
  52. const_iterator begin() const;
  53. /*!
  54. \brief Returns the iterator past the last element
  55. \return const RandomAccessIterator
  56. */
  57. const_iterator end() const;
  58. /*!
  59. \brief Returns the number of elements
  60. \return 9
  61. */
  62. static std::size_t size();
  63. /*!
  64. \brief Returns raw pointer to elements
  65. \return const pointer to array of elements
  66. */
  67. inline const char * data() const;
  68. /*!
  69. \brief Returns std::string containing elements
  70. \return string containing elements
  71. */
  72. inline std::string str() const;
  73. #endif
  74. };
  75. /*!
  76. \brief DE-9IM model intersection mask.
  77. \ingroup de9im
  78. \details This mask can be used to check spatial relations as defined in
  79. Dimensionally Extended 9-Intersection Model.
  80. \qbk{[heading See also]}
  81. \qbk{* [link geometry.reference.algorithms.relate relate]}
  82. */
  83. class mask
  84. : public detail::relate::mask<3, 3>
  85. {
  86. typedef detail::relate::mask<3, 3> base_type;
  87. public:
  88. /*!
  89. \brief The constructor.
  90. \param code The mask pattern.
  91. */
  92. inline explicit mask(const char* code)
  93. : base_type(code)
  94. {}
  95. /*!
  96. \brief The constructor.
  97. \param code The mask pattern.
  98. */
  99. inline explicit mask(std::string const& code)
  100. : base_type(code.c_str(), code.size())
  101. {}
  102. };
  103. // static_mask
  104. /*!
  105. \brief DE-9IM model intersection mask (static version).
  106. \ingroup de9im
  107. \details This mask can be used to check spatial relations as defined in
  108. Dimensionally Extended 9-Intersection Model.
  109. \tparam II Interior/Interior intersection mask element
  110. \tparam IB Interior/Boundary intersection mask element
  111. \tparam IE Interior/Exterior intersection mask element
  112. \tparam BI Boundary/Interior intersection mask element
  113. \tparam BB Boundary/Boundary intersection mask element
  114. \tparam BE Boundary/Exterior intersection mask element
  115. \tparam EI Exterior/Interior intersection mask element
  116. \tparam EB Exterior/Boundary intersection mask element
  117. \tparam EE Exterior/Exterior intersection mask element
  118. \qbk{[heading See also]}
  119. \qbk{* [link geometry.reference.algorithms.relate relate]}
  120. */
  121. template
  122. <
  123. char II = '*', char IB = '*', char IE = '*',
  124. char BI = '*', char BB = '*', char BE = '*',
  125. char EI = '*', char EB = '*', char EE = '*'
  126. >
  127. class static_mask
  128. : public detail::relate::static_mask
  129. <
  130. boost::mpl::vector_c
  131. <
  132. char, II, IB, IE, BI, BB, BE, EI, EB, EE
  133. >,
  134. 3, 3
  135. >
  136. {};
  137. } // namespace de9im
  138. namespace detail { namespace de9im
  139. {
  140. // a small helper util for ORing static masks
  141. template
  142. <
  143. typename Seq,
  144. typename T,
  145. bool IsSeq = boost::mpl::is_sequence<Seq>::value
  146. >
  147. struct push_back
  148. {
  149. typedef typename boost::mpl::push_back
  150. <
  151. Seq,
  152. T
  153. >::type type;
  154. };
  155. template <typename Seq, typename T>
  156. struct push_back<Seq, T, false>
  157. {};
  158. }} // namespace detail::de9im
  159. namespace de9im
  160. {
  161. inline
  162. boost::tuples::cons
  163. <
  164. mask,
  165. boost::tuples::cons<mask, boost::tuples::null_type>
  166. >
  167. operator||(mask const& m1, mask const& m2)
  168. {
  169. namespace bt = boost::tuples;
  170. return bt::cons<mask, bt::cons<mask, bt::null_type> >
  171. ( m1, bt::cons<mask, bt::null_type>(m2, bt::null_type()) );
  172. }
  173. template <typename Tail>
  174. inline
  175. typename geometry::tuples::push_back
  176. <
  177. boost::tuples::cons<mask, Tail>,
  178. mask
  179. >::type
  180. operator||(boost::tuples::cons<mask, Tail> const& t, mask const& m)
  181. {
  182. namespace bt = boost::tuples;
  183. return geometry::tuples::push_back
  184. <
  185. bt::cons<mask, Tail>,
  186. mask
  187. >::apply(t, m);
  188. }
  189. template
  190. <
  191. char II1, char IB1, char IE1,
  192. char BI1, char BB1, char BE1,
  193. char EI1, char EB1, char EE1,
  194. char II2, char IB2, char IE2,
  195. char BI2, char BB2, char BE2,
  196. char EI2, char EB2, char EE2
  197. >
  198. inline
  199. boost::mpl::vector<
  200. static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1>,
  201. static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2>
  202. >
  203. operator||(static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1> const& ,
  204. static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2> const& )
  205. {
  206. return boost::mpl::vector
  207. <
  208. static_mask<II1, IB1, IE1, BI1, BB1, BE1, EI1, EB1, EE1>,
  209. static_mask<II2, IB2, IE2, BI2, BB2, BE2, EI2, EB2, EE2>
  210. >();
  211. }
  212. template
  213. <
  214. typename Seq,
  215. char II, char IB, char IE,
  216. char BI, char BB, char BE,
  217. char EI, char EB, char EE
  218. >
  219. inline
  220. typename detail::de9im::push_back
  221. <
  222. Seq,
  223. static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
  224. >::type
  225. operator||(Seq const& ,
  226. static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE> const& )
  227. {
  228. return typename detail::de9im::push_back
  229. <
  230. Seq,
  231. static_mask<II, IB, IE, BI, BB, BE, EI, EB, EE>
  232. >::type();
  233. }
  234. } // namespace de9im
  235. #ifndef DOXYGEN_NO_DETAIL
  236. namespace detail { namespace de9im
  237. {
  238. // PREDEFINED MASKS
  239. // TODO:
  240. // 1. specialize for simplified masks if available
  241. // e.g. for TOUCHES use 1 mask for A/A
  242. // 2. Think about dimensions > 2 e.g. should TOUCHES be true
  243. // if the interior of the Areal overlaps the boundary of the Volumetric
  244. // like it's true for Linear/Areal
  245. // EQUALS
  246. template <typename Geometry1, typename Geometry2>
  247. struct static_mask_equals_type
  248. {
  249. typedef geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', 'F', 'F', '*'> type; // wikipedia
  250. //typedef geometry::de9im::static_mask<'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F', 'T'> type; // OGC
  251. };
  252. // DISJOINT
  253. template <typename Geometry1, typename Geometry2>
  254. struct static_mask_disjoint_type
  255. {
  256. typedef geometry::de9im::static_mask<'F', 'F', '*', 'F', 'F', '*', '*', '*', '*'> type;
  257. };
  258. // TOUCHES - NOT P/P
  259. template
  260. <
  261. typename Geometry1,
  262. typename Geometry2,
  263. std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
  264. std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value
  265. >
  266. struct static_mask_touches_impl
  267. {
  268. typedef boost::mpl::vector
  269. <
  270. geometry::de9im::static_mask<'F', 'T', '*', '*', '*', '*', '*', '*', '*'>,
  271. geometry::de9im::static_mask<'F', '*', '*', 'T', '*', '*', '*', '*', '*'>,
  272. geometry::de9im::static_mask<'F', '*', '*', '*', 'T', '*', '*', '*', '*'>
  273. > type;
  274. };
  275. // According to OGC, doesn't apply to P/P
  276. // Using the above mask the result would be always false
  277. template <typename Geometry1, typename Geometry2>
  278. struct static_mask_touches_impl<Geometry1, Geometry2, 0, 0>
  279. {
  280. typedef geometry::detail::relate::false_mask type;
  281. };
  282. template <typename Geometry1, typename Geometry2>
  283. struct static_mask_touches_type
  284. : static_mask_touches_impl<Geometry1, Geometry2>
  285. {};
  286. // WITHIN
  287. template <typename Geometry1, typename Geometry2>
  288. struct static_mask_within_type
  289. {
  290. typedef geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'> type;
  291. };
  292. // COVERED_BY (non OGC)
  293. template <typename Geometry1, typename Geometry2>
  294. struct static_mask_covered_by_type
  295. {
  296. typedef boost::mpl::vector
  297. <
  298. geometry::de9im::static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'>,
  299. geometry::de9im::static_mask<'*', 'T', 'F', '*', '*', 'F', '*', '*', '*'>,
  300. geometry::de9im::static_mask<'*', '*', 'F', 'T', '*', 'F', '*', '*', '*'>,
  301. geometry::de9im::static_mask<'*', '*', 'F', '*', 'T', 'F', '*', '*', '*'>
  302. > type;
  303. };
  304. // CROSSES
  305. // dim(G1) < dim(G2) - P/L P/A L/A
  306. template
  307. <
  308. typename Geometry1,
  309. typename Geometry2,
  310. std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
  311. std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value,
  312. bool D1LessD2 = (Dim1 < Dim2)
  313. >
  314. struct static_mask_crosses_impl
  315. {
  316. typedef geometry::de9im::static_mask<'T', '*', 'T', '*', '*', '*', '*', '*', '*'> type;
  317. };
  318. // TODO: I'm not sure if this one below should be available!
  319. // dim(G1) > dim(G2) - L/P A/P A/L
  320. template
  321. <
  322. typename Geometry1, typename Geometry2, std::size_t Dim1, std::size_t Dim2
  323. >
  324. struct static_mask_crosses_impl<Geometry1, Geometry2, Dim1, Dim2, false>
  325. {
  326. typedef geometry::de9im::static_mask<'T', '*', '*', '*', '*', '*', 'T', '*', '*'> type;
  327. };
  328. // dim(G1) == dim(G2) - P/P A/A
  329. template
  330. <
  331. typename Geometry1, typename Geometry2, std::size_t Dim
  332. >
  333. struct static_mask_crosses_impl<Geometry1, Geometry2, Dim, Dim, false>
  334. {
  335. typedef geometry::detail::relate::false_mask type;
  336. };
  337. // dim(G1) == 1 && dim(G2) == 1 - L/L
  338. template <typename Geometry1, typename Geometry2>
  339. struct static_mask_crosses_impl<Geometry1, Geometry2, 1, 1, false>
  340. {
  341. typedef geometry::de9im::static_mask<'0', '*', '*', '*', '*', '*', '*', '*', '*'> type;
  342. };
  343. template <typename Geometry1, typename Geometry2>
  344. struct static_mask_crosses_type
  345. : static_mask_crosses_impl<Geometry1, Geometry2>
  346. {};
  347. // OVERLAPS
  348. // dim(G1) != dim(G2) - NOT P/P, L/L, A/A
  349. template
  350. <
  351. typename Geometry1,
  352. typename Geometry2,
  353. std::size_t Dim1 = geometry::topological_dimension<Geometry1>::value,
  354. std::size_t Dim2 = geometry::topological_dimension<Geometry2>::value
  355. >
  356. struct static_mask_overlaps_impl
  357. {
  358. typedef geometry::detail::relate::false_mask type;
  359. };
  360. // dim(G1) == D && dim(G2) == D - P/P A/A
  361. template <typename Geometry1, typename Geometry2, std::size_t Dim>
  362. struct static_mask_overlaps_impl<Geometry1, Geometry2, Dim, Dim>
  363. {
  364. typedef geometry::de9im::static_mask<'T', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
  365. };
  366. // dim(G1) == 1 && dim(G2) == 1 - L/L
  367. template <typename Geometry1, typename Geometry2>
  368. struct static_mask_overlaps_impl<Geometry1, Geometry2, 1, 1>
  369. {
  370. typedef geometry::de9im::static_mask<'1', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
  371. };
  372. template <typename Geometry1, typename Geometry2>
  373. struct static_mask_overlaps_type
  374. : static_mask_overlaps_impl<Geometry1, Geometry2>
  375. {};
  376. }} // namespace detail::de9im
  377. #endif // DOXYGEN_NO_DETAIL
  378. }} // namespace boost::geometry
  379. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_DE9IM_HPP