crosses.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // Copyright (c) 2014 Samuel Debionne, Grenoble, France.
  6. // This file was modified by Oracle on 2014-2022.
  7. // Modifications copyright (c) 2014-2022 Oracle and/or its affiliates.
  8. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  9. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  10. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  11. // Use, modification and distribution is subject to the Boost Software License,
  12. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  13. // http://www.boost.org/LICENSE_1_0.txt)
  14. #ifndef BOOST_GEOMETRY_ALGORITHMS_CROSSES_HPP
  15. #define BOOST_GEOMETRY_ALGORITHMS_CROSSES_HPP
  16. #include <cstddef>
  17. #include <boost/geometry/algorithms/detail/gc_topological_dimension.hpp>
  18. #include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
  19. #include <boost/geometry/algorithms/relate.hpp>
  20. #include <boost/geometry/core/access.hpp>
  21. #include <boost/geometry/geometries/adapted/boost_variant.hpp>
  22. #include <boost/geometry/geometries/concepts/check.hpp>
  23. #include <boost/geometry/strategies/default_strategy.hpp>
  24. #include <boost/geometry/strategies/detail.hpp>
  25. #include <boost/geometry/strategies/relate/cartesian.hpp>
  26. #include <boost/geometry/strategies/relate/geographic.hpp>
  27. #include <boost/geometry/strategies/relate/spherical.hpp>
  28. #include <boost/geometry/views/detail/geometry_collection_view.hpp>
  29. namespace boost { namespace geometry
  30. {
  31. #ifndef DOXYGEN_NO_DISPATCH
  32. namespace dispatch
  33. {
  34. template
  35. <
  36. typename Geometry1,
  37. typename Geometry2,
  38. typename Tag1 = typename tag<Geometry1>::type,
  39. typename Tag2 = typename tag<Geometry2>::type
  40. >
  41. struct crosses
  42. : detail::relate::relate_impl
  43. <
  44. detail::de9im::static_mask_crosses_type,
  45. Geometry1,
  46. Geometry2
  47. >
  48. {};
  49. template <typename Geometry1, typename Geometry2>
  50. struct crosses<Geometry1, Geometry2, geometry_collection_tag, geometry_collection_tag>
  51. {
  52. template <typename Strategy>
  53. static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
  54. Strategy const& strategy)
  55. {
  56. int const dimension1 = detail::gc_topological_dimension(geometry1);
  57. int const dimension2 = detail::gc_topological_dimension(geometry2);
  58. if (dimension1 >= 0 && dimension2 >= 0)
  59. {
  60. if (dimension1 < dimension2)
  61. {
  62. return detail::relate::relate_impl
  63. <
  64. detail::de9im::static_mask_crosses_d1_le_d2_type,
  65. Geometry1,
  66. Geometry2
  67. >::apply(geometry1, geometry2, strategy);
  68. }
  69. else if (dimension1 > dimension2)
  70. {
  71. return detail::relate::relate_impl
  72. <
  73. detail::de9im::static_mask_crosses_d2_le_d1_type,
  74. Geometry1,
  75. Geometry2
  76. >::apply(geometry1, geometry2, strategy);
  77. }
  78. else if (dimension1 == 1 && dimension2 == 1)
  79. {
  80. return detail::relate::relate_impl
  81. <
  82. detail::de9im::static_mask_crosses_d1_1_d2_1_type,
  83. Geometry1,
  84. Geometry2
  85. >::apply(geometry1, geometry2, strategy);
  86. }
  87. }
  88. return false;
  89. }
  90. };
  91. template <typename Geometry1, typename Geometry2, typename Tag1>
  92. struct crosses<Geometry1, Geometry2, Tag1, geometry_collection_tag>
  93. {
  94. template <typename Strategy>
  95. static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
  96. Strategy const& strategy)
  97. {
  98. using gc1_view_t = detail::geometry_collection_view<Geometry1>;
  99. return crosses
  100. <
  101. gc1_view_t, Geometry2
  102. >::apply(gc1_view_t(geometry1), geometry2, strategy);
  103. }
  104. };
  105. template <typename Geometry1, typename Geometry2, typename Tag2>
  106. struct crosses<Geometry1, Geometry2, geometry_collection_tag, Tag2>
  107. {
  108. template <typename Strategy>
  109. static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
  110. Strategy const& strategy)
  111. {
  112. using gc2_view_t = detail::geometry_collection_view<Geometry2>;
  113. return crosses
  114. <
  115. Geometry1, gc2_view_t
  116. >::apply(geometry1, gc2_view_t(geometry2), strategy);
  117. }
  118. };
  119. } // namespace dispatch
  120. #endif // DOXYGEN_NO_DISPATCH
  121. namespace resolve_strategy
  122. {
  123. template
  124. <
  125. typename Strategy,
  126. bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
  127. >
  128. struct crosses
  129. {
  130. template <typename Geometry1, typename Geometry2>
  131. static inline bool apply(Geometry1 const& geometry1,
  132. Geometry2 const& geometry2,
  133. Strategy const& strategy)
  134. {
  135. concepts::check<Geometry1 const>();
  136. concepts::check<Geometry2 const>();
  137. return dispatch::crosses
  138. <
  139. Geometry1, Geometry2
  140. >::apply(geometry1, geometry2, strategy);
  141. }
  142. };
  143. template <typename Strategy>
  144. struct crosses<Strategy, false>
  145. {
  146. template <typename Geometry1, typename Geometry2>
  147. static inline bool apply(Geometry1 const& geometry1,
  148. Geometry2 const& geometry2,
  149. Strategy const& strategy)
  150. {
  151. //using strategies::crosses::services::strategy_converter;
  152. using strategies::relate::services::strategy_converter;
  153. return crosses
  154. <
  155. decltype(strategy_converter<Strategy>::get(strategy))
  156. >::apply(geometry1, geometry2,
  157. strategy_converter<Strategy>::get(strategy));
  158. }
  159. };
  160. template <>
  161. struct crosses<default_strategy, false>
  162. {
  163. template <typename Geometry1, typename Geometry2>
  164. static inline bool apply(Geometry1 const& geometry1,
  165. Geometry2 const& geometry2,
  166. default_strategy)
  167. {
  168. //typedef typename strategies::crosses::services::default_strategy
  169. typedef typename strategies::relate::services::default_strategy
  170. <
  171. Geometry1,
  172. Geometry2
  173. >::type strategy_type;
  174. return crosses
  175. <
  176. strategy_type
  177. >::apply(geometry1, geometry2, strategy_type());
  178. }
  179. };
  180. } // namespace resolve_strategy
  181. namespace resolve_dynamic
  182. {
  183. template
  184. <
  185. typename Geometry1, typename Geometry2,
  186. typename Tag1 = typename geometry::tag<Geometry1>::type,
  187. typename Tag2 = typename geometry::tag<Geometry2>::type
  188. >
  189. struct crosses
  190. {
  191. template <typename Strategy>
  192. static inline bool apply(Geometry1 const& geometry1,
  193. Geometry2 const& geometry2,
  194. Strategy const& strategy)
  195. {
  196. return resolve_strategy::crosses
  197. <
  198. Strategy
  199. >::apply(geometry1, geometry2, strategy);
  200. }
  201. };
  202. template <typename DynamicGeometry1, typename Geometry2, typename Tag2>
  203. struct crosses<DynamicGeometry1, Geometry2, dynamic_geometry_tag, Tag2>
  204. {
  205. template <typename Strategy>
  206. static inline bool apply(DynamicGeometry1 const& geometry1,
  207. Geometry2 const& geometry2,
  208. Strategy const& strategy)
  209. {
  210. bool result = false;
  211. traits::visit<DynamicGeometry1>::apply([&](auto const& g1)
  212. {
  213. result = resolve_strategy::crosses
  214. <
  215. Strategy
  216. >::apply(g1, geometry2, strategy);
  217. }, geometry1);
  218. return result;
  219. }
  220. };
  221. template <typename Geometry1, typename DynamicGeometry2, typename Tag1>
  222. struct crosses<Geometry1, DynamicGeometry2, Tag1, dynamic_geometry_tag>
  223. {
  224. template <typename Strategy>
  225. static inline bool apply(Geometry1 const& geometry1,
  226. DynamicGeometry2 const& geometry2,
  227. Strategy const& strategy)
  228. {
  229. bool result = false;
  230. traits::visit<DynamicGeometry2>::apply([&](auto const& g2)
  231. {
  232. result = resolve_strategy::crosses
  233. <
  234. Strategy
  235. >::apply(geometry1, g2, strategy);
  236. }, geometry2);
  237. return result;
  238. }
  239. };
  240. template <typename DynamicGeometry1, typename DynamicGeometry2>
  241. struct crosses<DynamicGeometry1, DynamicGeometry2, dynamic_geometry_tag, dynamic_geometry_tag>
  242. {
  243. template <typename Strategy>
  244. static inline bool apply(DynamicGeometry1 const& geometry1,
  245. DynamicGeometry2 const& geometry2,
  246. Strategy const& strategy)
  247. {
  248. bool result = false;
  249. traits::visit<DynamicGeometry1, DynamicGeometry2>::apply([&](auto const& g1, auto const& g2)
  250. {
  251. result = resolve_strategy::crosses
  252. <
  253. Strategy
  254. >::apply(g1, g2, strategy);
  255. }, geometry1, geometry2);
  256. return result;
  257. }
  258. };
  259. } // namespace resolve_dynamic
  260. /*!
  261. \brief \brief_check2{crosses}
  262. \ingroup crosses
  263. \tparam Geometry1 \tparam_geometry
  264. \tparam Geometry2 \tparam_geometry
  265. \tparam Strategy \tparam_strategy{Crosses}
  266. \param geometry1 \param_geometry
  267. \param geometry2 \param_geometry
  268. \param strategy \param_strategy{crosses}
  269. \return \return_check2{crosses}
  270. \qbk{distinguish,with strategy}
  271. \qbk{[include reference/algorithms/crosses.qbk]}
  272. */
  273. template <typename Geometry1, typename Geometry2, typename Strategy>
  274. inline bool crosses(Geometry1 const& geometry1,
  275. Geometry2 const& geometry2,
  276. Strategy const& strategy)
  277. {
  278. return resolve_dynamic::crosses
  279. <
  280. Geometry1, Geometry2
  281. >::apply(geometry1, geometry2, strategy);
  282. }
  283. /*!
  284. \brief \brief_check2{crosses}
  285. \ingroup crosses
  286. \tparam Geometry1 \tparam_geometry
  287. \tparam Geometry2 \tparam_geometry
  288. \param geometry1 \param_geometry
  289. \param geometry2 \param_geometry
  290. \return \return_check2{crosses}
  291. \qbk{[include reference/algorithms/crosses.qbk]}
  292. \qbk{
  293. [heading Examples]
  294. [crosses]
  295. [crosses_output]
  296. }
  297. */
  298. template <typename Geometry1, typename Geometry2>
  299. inline bool crosses(Geometry1 const& geometry1, Geometry2 const& geometry2)
  300. {
  301. return resolve_dynamic::crosses
  302. <
  303. Geometry1, Geometry2
  304. >::apply(geometry1, geometry2, default_strategy());
  305. }
  306. }} // namespace boost::geometry
  307. #endif // BOOST_GEOMETRY_ALGORITHMS_CROSSES_HPP