de9im.hpp 12 KB

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