de9im.hpp 12 KB

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