interface.hpp 12 KB

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