expand.hpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  6. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  7. // Use, modification and distribution is subject to the Boost Software License,
  8. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
  11. #define BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
  12. #include <cstddef>
  13. #include <boost/numeric/conversion/cast.hpp>
  14. #include <boost/geometry/algorithms/not_implemented.hpp>
  15. #include <boost/geometry/core/coordinate_dimension.hpp>
  16. #include <boost/geometry/geometries/concepts/check.hpp>
  17. #include <boost/geometry/util/select_coordinate_type.hpp>
  18. #include <boost/geometry/strategies/compare.hpp>
  19. #include <boost/geometry/policies/compare.hpp>
  20. namespace boost { namespace geometry
  21. {
  22. #ifndef DOXYGEN_NO_DETAIL
  23. namespace detail { namespace expand
  24. {
  25. template
  26. <
  27. typename StrategyLess, typename StrategyGreater,
  28. std::size_t Dimension, std::size_t DimensionCount
  29. >
  30. struct point_loop
  31. {
  32. template <typename Box, typename Point>
  33. static inline void apply(Box& box, Point const& source)
  34. {
  35. typedef typename strategy::compare::detail::select_strategy
  36. <
  37. StrategyLess, 1, Point, Dimension
  38. >::type less_type;
  39. typedef typename strategy::compare::detail::select_strategy
  40. <
  41. StrategyGreater, -1, Point, Dimension
  42. >::type greater_type;
  43. typedef typename select_coordinate_type<Point, Box>::type coordinate_type;
  44. less_type less;
  45. greater_type greater;
  46. coordinate_type const coord = get<Dimension>(source);
  47. if (less(coord, get<min_corner, Dimension>(box)))
  48. {
  49. set<min_corner, Dimension>(box, coord);
  50. }
  51. if (greater(coord, get<max_corner, Dimension>(box)))
  52. {
  53. set<max_corner, Dimension>(box, coord);
  54. }
  55. point_loop
  56. <
  57. StrategyLess, StrategyGreater,
  58. Dimension + 1, DimensionCount
  59. >::apply(box, source);
  60. }
  61. };
  62. template
  63. <
  64. typename StrategyLess, typename StrategyGreater,
  65. std::size_t DimensionCount
  66. >
  67. struct point_loop
  68. <
  69. StrategyLess, StrategyGreater,
  70. DimensionCount, DimensionCount
  71. >
  72. {
  73. template <typename Box, typename Point>
  74. static inline void apply(Box&, Point const&) {}
  75. };
  76. template
  77. <
  78. typename StrategyLess, typename StrategyGreater,
  79. std::size_t Index,
  80. std::size_t Dimension, std::size_t DimensionCount
  81. >
  82. struct indexed_loop
  83. {
  84. template <typename Box, typename Geometry>
  85. static inline void apply(Box& box, Geometry const& source)
  86. {
  87. typedef typename strategy::compare::detail::select_strategy
  88. <
  89. StrategyLess, 1, Box, Dimension
  90. >::type less_type;
  91. typedef typename strategy::compare::detail::select_strategy
  92. <
  93. StrategyGreater, -1, Box, Dimension
  94. >::type greater_type;
  95. typedef typename select_coordinate_type
  96. <
  97. Box,
  98. Geometry
  99. >::type coordinate_type;
  100. less_type less;
  101. greater_type greater;
  102. coordinate_type const coord = get<Index, Dimension>(source);
  103. if (less(coord, get<min_corner, Dimension>(box)))
  104. {
  105. set<min_corner, Dimension>(box, coord);
  106. }
  107. if (greater(coord, get<max_corner, Dimension>(box)))
  108. {
  109. set<max_corner, Dimension>(box, coord);
  110. }
  111. indexed_loop
  112. <
  113. StrategyLess, StrategyGreater,
  114. Index, Dimension + 1, DimensionCount
  115. >::apply(box, source);
  116. }
  117. };
  118. template
  119. <
  120. typename StrategyLess, typename StrategyGreater,
  121. std::size_t Index, std::size_t DimensionCount
  122. >
  123. struct indexed_loop
  124. <
  125. StrategyLess, StrategyGreater,
  126. Index, DimensionCount, DimensionCount
  127. >
  128. {
  129. template <typename Box, typename Geometry>
  130. static inline void apply(Box&, Geometry const&) {}
  131. };
  132. // Changes a box such that the other box is also contained by the box
  133. template
  134. <
  135. typename StrategyLess, typename StrategyGreater
  136. >
  137. struct expand_indexed
  138. {
  139. template <typename Box, typename Geometry>
  140. static inline void apply(Box& box, Geometry const& geometry)
  141. {
  142. indexed_loop
  143. <
  144. StrategyLess, StrategyGreater,
  145. 0, 0, dimension<Geometry>::type::value
  146. >::apply(box, geometry);
  147. indexed_loop
  148. <
  149. StrategyLess, StrategyGreater,
  150. 1, 0, dimension<Geometry>::type::value
  151. >::apply(box, geometry);
  152. }
  153. };
  154. }} // namespace detail::expand
  155. #endif // DOXYGEN_NO_DETAIL
  156. #ifndef DOXYGEN_NO_DISPATCH
  157. namespace dispatch
  158. {
  159. template
  160. <
  161. typename GeometryOut, typename Geometry,
  162. typename StrategyLess = strategy::compare::default_strategy,
  163. typename StrategyGreater = strategy::compare::default_strategy,
  164. typename TagOut = typename tag<GeometryOut>::type,
  165. typename Tag = typename tag<Geometry>::type
  166. >
  167. struct expand: not_implemented<TagOut, Tag>
  168. {};
  169. // Box + point -> new box containing also point
  170. template
  171. <
  172. typename BoxOut, typename Point,
  173. typename StrategyLess, typename StrategyGreater
  174. >
  175. struct expand<BoxOut, Point, StrategyLess, StrategyGreater, box_tag, point_tag>
  176. : detail::expand::point_loop
  177. <
  178. StrategyLess, StrategyGreater,
  179. 0, dimension<Point>::type::value
  180. >
  181. {};
  182. // Box + box -> new box containing two input boxes
  183. template
  184. <
  185. typename BoxOut, typename BoxIn,
  186. typename StrategyLess, typename StrategyGreater
  187. >
  188. struct expand<BoxOut, BoxIn, StrategyLess, StrategyGreater, box_tag, box_tag>
  189. : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
  190. {};
  191. template
  192. <
  193. typename Box, typename Segment,
  194. typename StrategyLess, typename StrategyGreater
  195. >
  196. struct expand<Box, Segment, StrategyLess, StrategyGreater, box_tag, segment_tag>
  197. : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
  198. {};
  199. } // namespace dispatch
  200. #endif // DOXYGEN_NO_DISPATCH
  201. /***
  202. *!
  203. \brief Expands a box using the extend (envelope) of another geometry (box, point)
  204. \ingroup expand
  205. \tparam Box type of the box
  206. \tparam Geometry of second geometry, to be expanded with the box
  207. \param box box to expand another geometry with, might be changed
  208. \param geometry other geometry
  209. \param strategy_less
  210. \param strategy_greater
  211. \note Strategy is currently ignored
  212. *
  213. template
  214. <
  215. typename Box, typename Geometry,
  216. typename StrategyLess, typename StrategyGreater
  217. >
  218. inline void expand(Box& box, Geometry const& geometry,
  219. StrategyLess const& strategy_less,
  220. StrategyGreater const& strategy_greater)
  221. {
  222. concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
  223. dispatch::expand<Box, Geometry>::apply(box, geometry);
  224. }
  225. ***/
  226. /*!
  227. \brief Expands a box using the bounding box (envelope) of another geometry (box, point)
  228. \ingroup expand
  229. \tparam Box type of the box
  230. \tparam Geometry \tparam_geometry
  231. \param box box to be expanded using another geometry, mutable
  232. \param geometry \param_geometry geometry which envelope (bounding box) will be added to the box
  233. \qbk{[include reference/algorithms/expand.qbk]}
  234. */
  235. template <typename Box, typename Geometry>
  236. inline void expand(Box& box, Geometry const& geometry)
  237. {
  238. concept::check_concepts_and_equal_dimensions<Box, Geometry const>();
  239. dispatch::expand<Box, Geometry>::apply(box, geometry);
  240. }
  241. }} // namespace boost::geometry
  242. #endif // BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP