interface.hpp 12 KB

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