interface.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // This file was modified by Oracle on 2014, 2017, 2019.
  4. // Modifications copyright (c) 2014-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_INTERSECTION_INTERFACE_HPP
  10. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_INTERFACE_HPP
  11. #include <boost/variant/apply_visitor.hpp>
  12. #include <boost/variant/static_visitor.hpp>
  13. #include <boost/variant/variant_fwd.hpp>
  14. #include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
  15. #include <boost/geometry/algorithms/detail/tupled_output.hpp>
  16. #include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
  17. #include <boost/geometry/strategies/default_strategy.hpp>
  18. #include <boost/geometry/util/range.hpp>
  19. namespace boost { namespace geometry
  20. {
  21. #ifndef DOXYGEN_NO_DISPATCH
  22. namespace dispatch
  23. {
  24. // By default, all is forwarded to the intersection_insert-dispatcher
  25. template
  26. <
  27. typename Geometry1, typename Geometry2,
  28. typename Tag1 = typename geometry::tag<Geometry1>::type,
  29. typename Tag2 = typename geometry::tag<Geometry2>::type,
  30. bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
  31. >
  32. struct intersection
  33. {
  34. template <typename RobustPolicy, typename GeometryOut, typename Strategy>
  35. static inline bool apply(Geometry1 const& geometry1,
  36. Geometry2 const& geometry2,
  37. RobustPolicy const& robust_policy,
  38. GeometryOut& geometry_out,
  39. Strategy const& strategy)
  40. {
  41. typedef typename geometry::detail::output_geometry_value
  42. <
  43. GeometryOut
  44. >::type SingleOut;
  45. intersection_insert
  46. <
  47. Geometry1, Geometry2, SingleOut,
  48. overlay_intersection
  49. >::apply(geometry1, geometry2, robust_policy,
  50. geometry::detail::output_geometry_back_inserter(geometry_out),
  51. strategy);
  52. return true;
  53. }
  54. };
  55. // If reversal is needed, perform it
  56. template
  57. <
  58. typename Geometry1, typename Geometry2,
  59. typename Tag1, typename Tag2
  60. >
  61. struct intersection
  62. <
  63. Geometry1, Geometry2,
  64. Tag1, Tag2,
  65. true
  66. >
  67. : intersection<Geometry2, Geometry1, Tag2, Tag1, false>
  68. {
  69. template <typename RobustPolicy, typename GeometryOut, typename Strategy>
  70. static inline bool apply(
  71. Geometry1 const& g1,
  72. Geometry2 const& g2,
  73. RobustPolicy const& robust_policy,
  74. GeometryOut& out,
  75. Strategy const& strategy)
  76. {
  77. return intersection
  78. <
  79. Geometry2, Geometry1,
  80. Tag2, Tag1,
  81. false
  82. >::apply(g2, g1, robust_policy, out, strategy);
  83. }
  84. };
  85. } // namespace dispatch
  86. #endif // DOXYGEN_NO_DISPATCH
  87. namespace resolve_strategy {
  88. struct intersection
  89. {
  90. template
  91. <
  92. typename Geometry1,
  93. typename Geometry2,
  94. typename GeometryOut,
  95. typename Strategy
  96. >
  97. static inline bool apply(Geometry1 const& geometry1,
  98. Geometry2 const& geometry2,
  99. GeometryOut & geometry_out,
  100. Strategy const& strategy)
  101. {
  102. typedef typename geometry::rescale_overlay_policy_type
  103. <
  104. Geometry1,
  105. Geometry2,
  106. typename Strategy::cs_tag
  107. >::type rescale_policy_type;
  108. rescale_policy_type robust_policy
  109. = geometry::get_rescale_policy<rescale_policy_type>(
  110. geometry1, geometry2, strategy);
  111. return dispatch::intersection
  112. <
  113. Geometry1,
  114. Geometry2
  115. >::apply(geometry1, geometry2, robust_policy, geometry_out,
  116. strategy);
  117. }
  118. template
  119. <
  120. typename Geometry1,
  121. typename Geometry2,
  122. typename GeometryOut
  123. >
  124. static inline bool apply(Geometry1 const& geometry1,
  125. Geometry2 const& geometry2,
  126. GeometryOut & geometry_out,
  127. default_strategy)
  128. {
  129. typedef typename geometry::rescale_overlay_policy_type
  130. <
  131. Geometry1,
  132. Geometry2,
  133. typename geometry::cs_tag<Geometry1>::type
  134. >::type rescale_policy_type;
  135. typename strategy::relate::services::default_strategy
  136. <
  137. Geometry1, Geometry2
  138. >::type strategy;
  139. rescale_policy_type robust_policy
  140. = geometry::get_rescale_policy<rescale_policy_type>(
  141. geometry1, geometry2, strategy);
  142. return dispatch::intersection
  143. <
  144. Geometry1,
  145. Geometry2
  146. >::apply(geometry1, geometry2, robust_policy, geometry_out,
  147. strategy);
  148. }
  149. };
  150. } // resolve_strategy
  151. namespace resolve_variant
  152. {
  153. template <typename Geometry1, typename Geometry2>
  154. struct intersection
  155. {
  156. template <typename GeometryOut, typename Strategy>
  157. static inline bool apply(Geometry1 const& geometry1,
  158. Geometry2 const& geometry2,
  159. GeometryOut& geometry_out,
  160. Strategy const& strategy)
  161. {
  162. concepts::check<Geometry1 const>();
  163. concepts::check<Geometry2 const>();
  164. return resolve_strategy::intersection::apply(geometry1,
  165. geometry2,
  166. geometry_out,
  167. strategy);
  168. }
  169. };
  170. template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
  171. struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
  172. {
  173. template <typename GeometryOut, typename Strategy>
  174. struct visitor: static_visitor<bool>
  175. {
  176. Geometry2 const& m_geometry2;
  177. GeometryOut& m_geometry_out;
  178. Strategy const& m_strategy;
  179. visitor(Geometry2 const& geometry2,
  180. GeometryOut& geometry_out,
  181. Strategy const& strategy)
  182. : m_geometry2(geometry2)
  183. , m_geometry_out(geometry_out)
  184. , m_strategy(strategy)
  185. {}
  186. template <typename Geometry1>
  187. bool operator()(Geometry1 const& geometry1) const
  188. {
  189. return intersection
  190. <
  191. Geometry1,
  192. Geometry2
  193. >::apply(geometry1, m_geometry2, m_geometry_out, m_strategy);
  194. }
  195. };
  196. template <typename GeometryOut, typename Strategy>
  197. static inline bool
  198. apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
  199. Geometry2 const& geometry2,
  200. GeometryOut& geometry_out,
  201. Strategy const& strategy)
  202. {
  203. return boost::apply_visitor(visitor<GeometryOut, Strategy>(geometry2,
  204. geometry_out,
  205. strategy),
  206. geometry1);
  207. }
  208. };
  209. template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
  210. struct intersection<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
  211. {
  212. template <typename GeometryOut, typename Strategy>
  213. struct visitor: static_visitor<bool>
  214. {
  215. Geometry1 const& m_geometry1;
  216. GeometryOut& m_geometry_out;
  217. Strategy const& m_strategy;
  218. visitor(Geometry1 const& geometry1,
  219. GeometryOut& geometry_out,
  220. Strategy const& strategy)
  221. : m_geometry1(geometry1)
  222. , m_geometry_out(geometry_out)
  223. , m_strategy(strategy)
  224. {}
  225. template <typename Geometry2>
  226. bool operator()(Geometry2 const& geometry2) const
  227. {
  228. return intersection
  229. <
  230. Geometry1,
  231. Geometry2
  232. >::apply(m_geometry1, geometry2, m_geometry_out, m_strategy);
  233. }
  234. };
  235. template <typename GeometryOut, typename Strategy>
  236. static inline bool
  237. apply(Geometry1 const& geometry1,
  238. variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
  239. GeometryOut& geometry_out,
  240. Strategy const& strategy)
  241. {
  242. return boost::apply_visitor(visitor<GeometryOut, Strategy>(geometry1,
  243. geometry_out,
  244. strategy),
  245. geometry2);
  246. }
  247. };
  248. template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
  249. struct intersection<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
  250. {
  251. template <typename GeometryOut, typename Strategy>
  252. struct visitor: static_visitor<bool>
  253. {
  254. GeometryOut& m_geometry_out;
  255. Strategy const& m_strategy;
  256. visitor(GeometryOut& geometry_out, Strategy const& strategy)
  257. : m_geometry_out(geometry_out)
  258. , m_strategy(strategy)
  259. {}
  260. template <typename Geometry1, typename Geometry2>
  261. bool operator()(Geometry1 const& geometry1,
  262. Geometry2 const& geometry2) const
  263. {
  264. return intersection
  265. <
  266. Geometry1,
  267. Geometry2
  268. >::apply(geometry1, geometry2, m_geometry_out, m_strategy);
  269. }
  270. };
  271. template <typename GeometryOut, typename Strategy>
  272. static inline bool
  273. apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
  274. variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
  275. GeometryOut& geometry_out,
  276. Strategy const& strategy)
  277. {
  278. return boost::apply_visitor(visitor<GeometryOut, Strategy>(geometry_out,
  279. strategy),
  280. geometry1, geometry2);
  281. }
  282. };
  283. } // namespace resolve_variant
  284. /*!
  285. \brief \brief_calc2{intersection}
  286. \ingroup intersection
  287. \details \details_calc2{intersection, spatial set theoretic intersection}.
  288. \tparam Geometry1 \tparam_geometry
  289. \tparam Geometry2 \tparam_geometry
  290. \tparam GeometryOut Collection of geometries (e.g. std::vector, std::deque, boost::geometry::multi*) of which
  291. the value_type fulfills a \p_l_or_c concept, or it is the output geometry (e.g. for a box)
  292. \tparam Strategy \tparam_strategy{Intersection}
  293. \param geometry1 \param_geometry
  294. \param geometry2 \param_geometry
  295. \param geometry_out The output geometry, either a multi_point, multi_polygon,
  296. multi_linestring, or a box (for intersection of two boxes)
  297. \param strategy \param_strategy{intersection}
  298. \qbk{distinguish,with strategy}
  299. \qbk{[include reference/algorithms/intersection.qbk]}
  300. */
  301. template
  302. <
  303. typename Geometry1,
  304. typename Geometry2,
  305. typename GeometryOut,
  306. typename Strategy
  307. >
  308. inline bool intersection(Geometry1 const& geometry1,
  309. Geometry2 const& geometry2,
  310. GeometryOut& geometry_out,
  311. Strategy const& strategy)
  312. {
  313. return resolve_variant::intersection
  314. <
  315. Geometry1,
  316. Geometry2
  317. >::apply(geometry1, geometry2, geometry_out, strategy);
  318. }
  319. /*!
  320. \brief \brief_calc2{intersection}
  321. \ingroup intersection
  322. \details \details_calc2{intersection, spatial set theoretic intersection}.
  323. \tparam Geometry1 \tparam_geometry
  324. \tparam Geometry2 \tparam_geometry
  325. \tparam GeometryOut Collection of geometries (e.g. std::vector, std::deque, boost::geometry::multi*) of which
  326. the value_type fulfills a \p_l_or_c concept, or it is the output geometry (e.g. for a box)
  327. \param geometry1 \param_geometry
  328. \param geometry2 \param_geometry
  329. \param geometry_out The output geometry, either a multi_point, multi_polygon,
  330. multi_linestring, or a box (for intersection of two boxes)
  331. \qbk{[include reference/algorithms/intersection.qbk]}
  332. */
  333. template
  334. <
  335. typename Geometry1,
  336. typename Geometry2,
  337. typename GeometryOut
  338. >
  339. inline bool intersection(Geometry1 const& geometry1,
  340. Geometry2 const& geometry2,
  341. GeometryOut& geometry_out)
  342. {
  343. return resolve_variant::intersection
  344. <
  345. Geometry1,
  346. Geometry2
  347. >::apply(geometry1, geometry2, geometry_out, default_strategy());
  348. }
  349. }} // namespace boost::geometry
  350. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_INTERFACE_HPP