interface.hpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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. // This file was modified by Oracle on 2013, 2014, 2017, 2018.
  6. // Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
  7. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  8. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  9. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  10. // Use, modification and distribution is subject to the Boost Software License,
  11. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  12. // http://www.boost.org/LICENSE_1_0.txt)
  13. #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_INTERFACE_HPP
  14. #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_INTERFACE_HPP
  15. #include <boost/concept_check.hpp>
  16. #include <boost/variant/apply_visitor.hpp>
  17. #include <boost/variant/static_visitor.hpp>
  18. #include <boost/variant/variant_fwd.hpp>
  19. #include <boost/geometry/algorithms/not_implemented.hpp>
  20. #include <boost/geometry/core/tag.hpp>
  21. #include <boost/geometry/core/tag_cast.hpp>
  22. #include <boost/geometry/geometries/concepts/check.hpp>
  23. #include <boost/geometry/strategies/concepts/within_concept.hpp>
  24. #include <boost/geometry/strategies/default_strategy.hpp>
  25. #include <boost/geometry/strategies/within.hpp>
  26. namespace boost { namespace geometry
  27. {
  28. #ifndef DOXYGEN_NO_DISPATCH
  29. namespace dispatch
  30. {
  31. template
  32. <
  33. typename Geometry1,
  34. typename Geometry2,
  35. typename Tag1 = typename tag<Geometry1>::type,
  36. typename Tag2 = typename tag<Geometry2>::type
  37. >
  38. struct within
  39. : not_implemented<Tag1, Tag2>
  40. {};
  41. } // namespace dispatch
  42. #endif // DOXYGEN_NO_DISPATCH
  43. namespace resolve_strategy
  44. {
  45. struct within
  46. {
  47. template <typename Geometry1, typename Geometry2, typename Strategy>
  48. static inline bool apply(Geometry1 const& geometry1,
  49. Geometry2 const& geometry2,
  50. Strategy const& strategy)
  51. {
  52. concepts::within::check<Geometry1, Geometry2, Strategy>();
  53. return dispatch::within<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
  54. }
  55. template <typename Geometry1, typename Geometry2>
  56. static inline bool apply(Geometry1 const& geometry1,
  57. Geometry2 const& geometry2,
  58. default_strategy)
  59. {
  60. typedef typename strategy::within::services::default_strategy
  61. <
  62. Geometry1,
  63. Geometry2
  64. >::type strategy_type;
  65. return apply(geometry1, geometry2, strategy_type());
  66. }
  67. };
  68. } // namespace resolve_strategy
  69. namespace resolve_variant
  70. {
  71. template <typename Geometry1, typename Geometry2>
  72. struct within
  73. {
  74. template <typename Strategy>
  75. static inline bool apply(Geometry1 const& geometry1,
  76. Geometry2 const& geometry2,
  77. Strategy const& strategy)
  78. {
  79. concepts::check<Geometry1 const>();
  80. concepts::check<Geometry2 const>();
  81. assert_dimension_equal<Geometry1, Geometry2>();
  82. return resolve_strategy::within::apply(geometry1,
  83. geometry2,
  84. strategy);
  85. }
  86. };
  87. template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
  88. struct within<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
  89. {
  90. template <typename Strategy>
  91. struct visitor: boost::static_visitor<bool>
  92. {
  93. Geometry2 const& m_geometry2;
  94. Strategy const& m_strategy;
  95. visitor(Geometry2 const& geometry2, Strategy const& strategy)
  96. : m_geometry2(geometry2)
  97. , m_strategy(strategy)
  98. {}
  99. template <typename Geometry1>
  100. bool operator()(Geometry1 const& geometry1) const
  101. {
  102. return within<Geometry1, Geometry2>::apply(geometry1,
  103. m_geometry2,
  104. m_strategy);
  105. }
  106. };
  107. template <typename Strategy>
  108. static inline bool
  109. apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
  110. Geometry2 const& geometry2,
  111. Strategy const& strategy)
  112. {
  113. return boost::apply_visitor(visitor<Strategy>(geometry2, strategy),
  114. geometry1);
  115. }
  116. };
  117. template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
  118. struct within<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
  119. {
  120. template <typename Strategy>
  121. struct visitor: boost::static_visitor<bool>
  122. {
  123. Geometry1 const& m_geometry1;
  124. Strategy const& m_strategy;
  125. visitor(Geometry1 const& geometry1, Strategy const& strategy)
  126. : m_geometry1(geometry1)
  127. , m_strategy(strategy)
  128. {}
  129. template <typename Geometry2>
  130. bool operator()(Geometry2 const& geometry2) const
  131. {
  132. return within<Geometry1, Geometry2>::apply(m_geometry1,
  133. geometry2,
  134. m_strategy);
  135. }
  136. };
  137. template <typename Strategy>
  138. static inline bool
  139. apply(Geometry1 const& geometry1,
  140. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
  141. Strategy const& strategy)
  142. {
  143. return boost::apply_visitor(visitor<Strategy>(geometry1, strategy),
  144. geometry2
  145. );
  146. }
  147. };
  148. template <
  149. BOOST_VARIANT_ENUM_PARAMS(typename T1),
  150. BOOST_VARIANT_ENUM_PARAMS(typename T2)
  151. >
  152. struct within<
  153. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
  154. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
  155. >
  156. {
  157. template <typename Strategy>
  158. struct visitor: boost::static_visitor<bool>
  159. {
  160. Strategy const& m_strategy;
  161. visitor(Strategy const& strategy): m_strategy(strategy) {}
  162. template <typename Geometry1, typename Geometry2>
  163. bool operator()(Geometry1 const& geometry1,
  164. Geometry2 const& geometry2) const
  165. {
  166. return within<Geometry1, Geometry2>::apply(geometry1,
  167. geometry2,
  168. m_strategy);
  169. }
  170. };
  171. template <typename Strategy>
  172. static inline bool
  173. apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
  174. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
  175. Strategy const& strategy)
  176. {
  177. return boost::apply_visitor(visitor<Strategy>(strategy),
  178. geometry1,
  179. geometry2);
  180. }
  181. };
  182. }
  183. /*!
  184. \brief \brief_check12{is completely inside}
  185. \ingroup within
  186. \details \details_check12{within, is completely inside}.
  187. \tparam Geometry1 \tparam_geometry
  188. \tparam Geometry2 \tparam_geometry
  189. \param geometry1 \param_geometry which might be within the second geometry
  190. \param geometry2 \param_geometry which might contain the first geometry
  191. \return true if geometry1 is completely contained within geometry2,
  192. else false
  193. \note The default strategy is used for within detection
  194. \qbk{[include reference/algorithms/within.qbk]}
  195. \qbk{
  196. [heading Example]
  197. [within]
  198. [within_output]
  199. }
  200. */
  201. template<typename Geometry1, typename Geometry2>
  202. inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
  203. {
  204. return resolve_variant::within
  205. <
  206. Geometry1,
  207. Geometry2
  208. >::apply(geometry1, geometry2, default_strategy());
  209. }
  210. /*!
  211. \brief \brief_check12{is completely inside} \brief_strategy
  212. \ingroup within
  213. \details \details_check12{within, is completely inside}, \brief_strategy. \details_strategy_reasons
  214. \tparam Geometry1 \tparam_geometry
  215. \tparam Geometry2 \tparam_geometry
  216. \param geometry1 \param_geometry which might be within the second geometry
  217. \param geometry2 \param_geometry which might contain the first geometry
  218. \param strategy strategy to be used
  219. \return true if geometry1 is completely contained within geometry2,
  220. else false
  221. \qbk{distinguish,with strategy}
  222. \qbk{[include reference/algorithms/within.qbk]}
  223. \qbk{
  224. [heading Available Strategies]
  225. \* [link geometry.reference.strategies.strategy_within_winding Winding (coordinate system agnostic)]
  226. \* [link geometry.reference.strategies.strategy_within_franklin Franklin (cartesian)]
  227. \* [link geometry.reference.strategies.strategy_within_crossings_multiply Crossings Multiply (cartesian)]
  228. [heading Example]
  229. [within_strategy]
  230. [within_strategy_output]
  231. }
  232. */
  233. template<typename Geometry1, typename Geometry2, typename Strategy>
  234. inline bool within(Geometry1 const& geometry1,
  235. Geometry2 const& geometry2,
  236. Strategy const& strategy)
  237. {
  238. return resolve_variant::within
  239. <
  240. Geometry1,
  241. Geometry2
  242. >::apply(geometry1, geometry2, strategy);
  243. }
  244. }} // namespace boost::geometry
  245. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_INTERFACE_HPP