interface.hpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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-2022.
  6. // Modifications copyright (c) 2013-2022 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/geometry/algorithms/not_implemented.hpp>
  17. #include <boost/geometry/core/tag.hpp>
  18. #include <boost/geometry/core/tag_cast.hpp>
  19. #include <boost/geometry/geometries/adapted/boost_variant.hpp>
  20. #include <boost/geometry/geometries/concepts/check.hpp>
  21. #include <boost/geometry/strategies/concepts/within_concept.hpp>
  22. #include <boost/geometry/strategies/default_strategy.hpp>
  23. #include <boost/geometry/strategies/detail.hpp>
  24. #include <boost/geometry/strategies/relate/services.hpp>
  25. namespace boost { namespace geometry
  26. {
  27. #ifndef DOXYGEN_NO_DISPATCH
  28. namespace dispatch
  29. {
  30. template
  31. <
  32. typename Geometry1,
  33. typename Geometry2,
  34. typename Tag1 = typename tag<Geometry1>::type,
  35. typename Tag2 = typename tag<Geometry2>::type
  36. >
  37. struct within
  38. : not_implemented<Tag1, Tag2>
  39. {};
  40. } // namespace dispatch
  41. #endif // DOXYGEN_NO_DISPATCH
  42. namespace resolve_strategy
  43. {
  44. template
  45. <
  46. typename Strategy,
  47. bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
  48. >
  49. struct within
  50. {
  51. template <typename Geometry1, typename Geometry2>
  52. static inline bool apply(Geometry1 const& geometry1,
  53. Geometry2 const& geometry2,
  54. Strategy const& strategy)
  55. {
  56. concepts::within::check<Geometry1, Geometry2, Strategy>();
  57. return dispatch::within
  58. <
  59. Geometry1, Geometry2
  60. >::apply(geometry1, geometry2, strategy);
  61. }
  62. };
  63. template <typename Strategy>
  64. struct within<Strategy, false>
  65. {
  66. template <typename Geometry1, typename Geometry2>
  67. static inline bool apply(Geometry1 const& geometry1,
  68. Geometry2 const& geometry2,
  69. Strategy const& strategy)
  70. {
  71. using strategies::relate::services::strategy_converter;
  72. return within
  73. <
  74. decltype(strategy_converter<Strategy>::get(strategy))
  75. >::apply(geometry1, geometry2,
  76. strategy_converter<Strategy>::get(strategy));
  77. }
  78. };
  79. template <>
  80. struct within<default_strategy, false>
  81. {
  82. template <typename Geometry1, typename Geometry2>
  83. static inline bool apply(Geometry1 const& geometry1,
  84. Geometry2 const& geometry2,
  85. default_strategy)
  86. {
  87. typedef typename strategies::relate::services::default_strategy
  88. <
  89. Geometry1,
  90. Geometry2
  91. >::type strategy_type;
  92. return within
  93. <
  94. strategy_type
  95. >::apply(geometry1, geometry2, strategy_type());
  96. }
  97. };
  98. } // namespace resolve_strategy
  99. namespace resolve_dynamic
  100. {
  101. template
  102. <
  103. typename Geometry1, typename Geometry2,
  104. typename Tag1 = typename geometry::tag<Geometry1>::type,
  105. typename Tag2 = typename geometry::tag<Geometry2>::type
  106. >
  107. struct within
  108. {
  109. template <typename Strategy>
  110. static inline bool apply(Geometry1 const& geometry1,
  111. Geometry2 const& geometry2,
  112. Strategy const& strategy)
  113. {
  114. concepts::check<Geometry1 const>();
  115. concepts::check<Geometry2 const>();
  116. assert_dimension_equal<Geometry1, Geometry2>();
  117. return resolve_strategy::within
  118. <
  119. Strategy
  120. >::apply(geometry1, geometry2, strategy);
  121. }
  122. };
  123. template <typename Geometry1, typename Geometry2, typename Tag2>
  124. struct within<Geometry1, Geometry2, dynamic_geometry_tag, Tag2>
  125. {
  126. template <typename Strategy>
  127. static inline bool apply(Geometry1 const& geometry1,
  128. Geometry2 const& geometry2,
  129. Strategy const& strategy)
  130. {
  131. bool result = false;
  132. traits::visit<Geometry1>::apply([&](auto const& g1)
  133. {
  134. result = within
  135. <
  136. util::remove_cref_t<decltype(g1)>,
  137. Geometry2
  138. >::apply(g1, geometry2, strategy);
  139. }, geometry1);
  140. return result;
  141. }
  142. };
  143. template <typename Geometry1, typename Geometry2, typename Tag1>
  144. struct within<Geometry1, Geometry2, Tag1, dynamic_geometry_tag>
  145. {
  146. template <typename Strategy>
  147. static inline bool apply(Geometry1 const& geometry1,
  148. Geometry2 const& geometry2,
  149. Strategy const& strategy)
  150. {
  151. bool result = false;
  152. traits::visit<Geometry2>::apply([&](auto const& g2)
  153. {
  154. result = within
  155. <
  156. Geometry1,
  157. util::remove_cref_t<decltype(g2)>
  158. >::apply(geometry1, g2, strategy);
  159. }, geometry2);
  160. return result;
  161. }
  162. };
  163. template <typename Geometry1, typename Geometry2>
  164. struct within<Geometry1, Geometry2, dynamic_geometry_tag, dynamic_geometry_tag>
  165. {
  166. template <typename Strategy>
  167. static inline bool apply(Geometry1 const& geometry1,
  168. Geometry2 const& geometry2,
  169. Strategy const& strategy)
  170. {
  171. bool result = false;
  172. traits::visit<Geometry1, Geometry2>::apply([&](auto const& g1, auto const& g2)
  173. {
  174. result = within
  175. <
  176. util::remove_cref_t<decltype(g1)>,
  177. util::remove_cref_t<decltype(g2)>
  178. >::apply(g1, g2, strategy);
  179. }, geometry1, geometry2);
  180. return result;
  181. }
  182. };
  183. }
  184. /*!
  185. \brief \brief_check12{is completely inside}
  186. \ingroup within
  187. \details \details_check12{within, is completely inside}.
  188. \tparam Geometry1 \tparam_geometry
  189. \tparam Geometry2 \tparam_geometry
  190. \param geometry1 \param_geometry which might be within the second geometry
  191. \param geometry2 \param_geometry which might contain the first geometry
  192. \return true if geometry1 is completely contained within geometry2,
  193. else false
  194. \note The default strategy is used for within detection
  195. \qbk{[include reference/algorithms/within.qbk]}
  196. \qbk{
  197. [heading Example]
  198. [within]
  199. [within_output]
  200. }
  201. */
  202. template<typename Geometry1, typename Geometry2>
  203. inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2)
  204. {
  205. return resolve_dynamic::within
  206. <
  207. Geometry1,
  208. Geometry2
  209. >::apply(geometry1, geometry2, default_strategy());
  210. }
  211. /*!
  212. \brief \brief_check12{is completely inside} \brief_strategy
  213. \ingroup within
  214. \details \details_check12{within, is completely inside}, \brief_strategy. \details_strategy_reasons
  215. \tparam Geometry1 \tparam_geometry
  216. \tparam Geometry2 \tparam_geometry
  217. \param geometry1 \param_geometry which might be within the second geometry
  218. \param geometry2 \param_geometry which might contain the first geometry
  219. \param strategy strategy to be used
  220. \return true if geometry1 is completely contained within geometry2,
  221. else false
  222. \qbk{distinguish,with strategy}
  223. \qbk{[include reference/algorithms/within.qbk]}
  224. \qbk{
  225. [heading Available Strategies]
  226. \* [link geometry.reference.strategies.strategy_within_winding Winding (coordinate system agnostic)]
  227. \* [link geometry.reference.strategies.strategy_within_franklin Franklin (cartesian)]
  228. \* [link geometry.reference.strategies.strategy_within_crossings_multiply Crossings Multiply (cartesian)]
  229. [heading Example]
  230. [within_strategy]
  231. [within_strategy_output]
  232. }
  233. */
  234. template<typename Geometry1, typename Geometry2, typename Strategy>
  235. inline bool within(Geometry1 const& geometry1,
  236. Geometry2 const& geometry2,
  237. Strategy const& strategy)
  238. {
  239. return resolve_dynamic::within
  240. <
  241. Geometry1,
  242. Geometry2
  243. >::apply(geometry1, geometry2, strategy);
  244. }
  245. }} // namespace boost::geometry
  246. #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_WITHIN_INTERFACE_HPP