interface.hpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  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.
  6. // Modifications copyright (c) 2013-2017 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
  53. <
  54. typename tag<Geometry1>::type,
  55. typename tag<Geometry2>::type,
  56. typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
  57. Strategy
  58. >();
  59. return dispatch::within<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
  60. }
  61. template <typename Geometry1, typename Geometry2>
  62. static inline bool apply(Geometry1 const& geometry1,
  63. Geometry2 const& geometry2,
  64. default_strategy)
  65. {
  66. typedef typename strategy::within::services::default_strategy
  67. <
  68. Geometry1,
  69. Geometry2
  70. >::type strategy_type;
  71. return apply(geometry1, geometry2, strategy_type());
  72. }
  73. };
  74. } // namespace resolve_strategy
  75. namespace resolve_variant
  76. {
  77. template <typename Geometry1, typename Geometry2>
  78. struct within
  79. {
  80. template <typename Strategy>
  81. static inline bool apply(Geometry1 const& geometry1,
  82. Geometry2 const& geometry2,
  83. Strategy const& strategy)
  84. {
  85. concepts::check<Geometry1 const>();
  86. concepts::check<Geometry2 const>();
  87. assert_dimension_equal<Geometry1, Geometry2>();
  88. return resolve_strategy::within::apply(geometry1,
  89. geometry2,
  90. strategy);
  91. }
  92. };
  93. template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
  94. struct within<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
  95. {
  96. template <typename Strategy>
  97. struct visitor: boost::static_visitor<bool>
  98. {
  99. Geometry2 const& m_geometry2;
  100. Strategy const& m_strategy;
  101. visitor(Geometry2 const& geometry2, Strategy const& strategy)
  102. : m_geometry2(geometry2)
  103. , m_strategy(strategy)
  104. {}
  105. template <typename Geometry1>
  106. bool operator()(Geometry1 const& geometry1) const
  107. {
  108. return within<Geometry1, Geometry2>::apply(geometry1,
  109. m_geometry2,
  110. m_strategy);
  111. }
  112. };
  113. template <typename Strategy>
  114. static inline bool
  115. apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry1,
  116. Geometry2 const& geometry2,
  117. Strategy const& strategy)
  118. {
  119. return boost::apply_visitor(visitor<Strategy>(geometry2, strategy),
  120. geometry1);
  121. }
  122. };
  123. template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
  124. struct within<Geometry1, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
  125. {
  126. template <typename Strategy>
  127. struct visitor: boost::static_visitor<bool>
  128. {
  129. Geometry1 const& m_geometry1;
  130. Strategy const& m_strategy;
  131. visitor(Geometry1 const& geometry1, Strategy const& strategy)
  132. : m_geometry1(geometry1)
  133. , m_strategy(strategy)
  134. {}
  135. template <typename Geometry2>
  136. bool operator()(Geometry2 const& geometry2) const
  137. {
  138. return within<Geometry1, Geometry2>::apply(m_geometry1,
  139. geometry2,
  140. m_strategy);
  141. }
  142. };
  143. template <typename Strategy>
  144. static inline bool
  145. apply(Geometry1 const& geometry1,
  146. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2,
  147. Strategy const& strategy)
  148. {
  149. return boost::apply_visitor(visitor<Strategy>(geometry1, strategy),
  150. geometry2
  151. );
  152. }
  153. };
  154. template <
  155. BOOST_VARIANT_ENUM_PARAMS(typename T1),
  156. BOOST_VARIANT_ENUM_PARAMS(typename T2)
  157. >
  158. struct within<
  159. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)>,
  160. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)>
  161. >
  162. {
  163. template <typename Strategy>
  164. struct visitor: boost::static_visitor<bool>
  165. {
  166. Strategy const& m_strategy;
  167. visitor(Strategy const& strategy): m_strategy(strategy) {}
  168. template <typename Geometry1, typename Geometry2>
  169. bool operator()(Geometry1 const& geometry1,
  170. Geometry2 const& geometry2) const
  171. {
  172. return within<Geometry1, Geometry2>::apply(geometry1,
  173. geometry2,
  174. m_strategy);
  175. }
  176. };
  177. template <typename Strategy>
  178. static inline bool
  179. apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T1)> const& geometry1,
  180. boost::variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2,
  181. Strategy const& strategy)
  182. {
  183. return boost::apply_visitor(visitor<Strategy>(strategy),
  184. geometry1,
  185. geometry2);
  186. }
  187. };
  188. }
  189. /*!
  190. \brief \brief_check12{is completely inside}
  191. \ingroup within
  192. \details \details_check12{within, is completely inside}.
  193. \tparam Geometry1 \tparam_geometry
  194. \tparam Geometry2 \tparam_geometry
  195. \param geometry1 \param_geometry which might be within the second geometry
  196. \param geometry2 \param_geometry which might contain the first geometry
  197. \return true if geometry1 is completely contained within geometry2,
  198. else false
  199. \note The default strategy is used for within detection
  200. \qbk{[include reference/algorithms/within.qbk]}
  201. \qbk{
  202. [heading Example]
  203. [within]
  204. [within_output]
  205. }
  206. */
  207. template<typename Geometry1, typename Geometry2>
  208. inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
  209. {
  210. return resolve_variant::within
  211. <
  212. Geometry1,
  213. Geometry2
  214. >::apply(geometry1, geometry2, default_strategy());
  215. }
  216. /*!
  217. \brief \brief_check12{is completely inside} \brief_strategy
  218. \ingroup within
  219. \details \details_check12{within, is completely inside}, \brief_strategy. \details_strategy_reasons
  220. \tparam Geometry1 \tparam_geometry
  221. \tparam Geometry2 \tparam_geometry
  222. \param geometry1 \param_geometry which might be within the second geometry
  223. \param geometry2 \param_geometry which might contain the first geometry
  224. \param strategy strategy to be used
  225. \return true if geometry1 is completely contained within geometry2,
  226. else false
  227. \qbk{distinguish,with strategy}
  228. \qbk{[include reference/algorithms/within.qbk]}
  229. \qbk{
  230. [heading Available Strategies]
  231. \* [link geometry.reference.strategies.strategy_within_winding Winding (coordinate system agnostic)]
  232. \* [link geometry.reference.strategies.strategy_within_franklin Franklin (cartesian)]
  233. \* [link geometry.reference.strategies.strategy_within_crossings_multiply Crossings Multiply (cartesian)]
  234. [heading Example]
  235. [within_strategy]
  236. [within_strategy_output]
  237. }
  238. */
  239. template<typename Geometry1, typename Geometry2, typename Strategy>
  240. inline bool within(Geometry1 const& geometry1,
  241. Geometry2 const& geometry2,
  242. Strategy const& strategy)
  243. {
  244. return resolve_variant::within
  245. <
  246. Geometry1,
  247. Geometry2
  248. >::apply(geometry1, geometry2, strategy);
  249. }
  250. }} // namespace boost::geometry
  251. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_INTERFACE_HPP