assign_values.hpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  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. // This file was modified by Oracle on 2018.
  8. // Modifications copyright (c) 2018, Oracle and/or its affiliates.
  9. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
  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_ASSIGN_VALUES_HPP
  14. #define BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
  15. #include <cstddef>
  16. #include <boost/concept/requires.hpp>
  17. #include <boost/concept_check.hpp>
  18. #include <boost/mpl/assert.hpp>
  19. #include <boost/mpl/if.hpp>
  20. #include <boost/numeric/conversion/bounds.hpp>
  21. #include <boost/numeric/conversion/cast.hpp>
  22. #include <boost/geometry/arithmetic/arithmetic.hpp>
  23. #include <boost/geometry/algorithms/append.hpp>
  24. #include <boost/geometry/algorithms/clear.hpp>
  25. #include <boost/geometry/core/access.hpp>
  26. #include <boost/geometry/core/exterior_ring.hpp>
  27. #include <boost/geometry/core/tags.hpp>
  28. #include <boost/geometry/geometries/concepts/check.hpp>
  29. #include <boost/geometry/util/is_inverse_spheroidal_coordinates.hpp>
  30. #include <boost/geometry/util/for_each_coordinate.hpp>
  31. namespace boost { namespace geometry
  32. {
  33. #ifndef DOXYGEN_NO_DETAIL
  34. namespace detail { namespace assign
  35. {
  36. template <std::size_t Index, std::size_t Dimension, std::size_t DimensionCount>
  37. struct initialize
  38. {
  39. template <typename Box>
  40. static inline void apply(Box& box, typename coordinate_type<Box>::type const& value)
  41. {
  42. geometry::set<Index, Dimension>(box, value);
  43. initialize<Index, Dimension + 1, DimensionCount>::apply(box, value);
  44. }
  45. };
  46. template <std::size_t Index, std::size_t DimensionCount>
  47. struct initialize<Index, DimensionCount, DimensionCount>
  48. {
  49. template <typename Box>
  50. static inline void apply(Box&, typename coordinate_type<Box>::type const&)
  51. {}
  52. };
  53. struct assign_zero_point
  54. {
  55. template <typename Point>
  56. static inline void apply(Point& point)
  57. {
  58. geometry::assign_value(point, 0);
  59. }
  60. };
  61. struct assign_inverse_box_or_segment
  62. {
  63. template <typename BoxOrSegment>
  64. static inline void apply(BoxOrSegment& geometry)
  65. {
  66. typedef typename point_type<BoxOrSegment>::type point_type;
  67. typedef typename coordinate_type<point_type>::type bound_type;
  68. initialize<0, 0, dimension<BoxOrSegment>::type::value>::apply(
  69. geometry, geometry::bounds<bound_type>::highest()
  70. );
  71. initialize<1, 0, dimension<BoxOrSegment>::type::value>::apply(
  72. geometry, geometry::bounds<bound_type>::lowest()
  73. );
  74. }
  75. };
  76. struct assign_zero_box_or_segment
  77. {
  78. template <typename BoxOrSegment>
  79. static inline void apply(BoxOrSegment& geometry)
  80. {
  81. typedef typename coordinate_type<BoxOrSegment>::type coordinate_type;
  82. initialize<0, 0, dimension<BoxOrSegment>::type::value>::apply(
  83. geometry, coordinate_type()
  84. );
  85. initialize<1, 0, dimension<BoxOrSegment>::type::value>::apply(
  86. geometry, coordinate_type()
  87. );
  88. }
  89. };
  90. template
  91. <
  92. std::size_t Corner1, std::size_t Corner2,
  93. typename Box, typename Point
  94. >
  95. inline void assign_box_2d_corner(Box const& box, Point& point)
  96. {
  97. // Be sure both are 2-Dimensional
  98. assert_dimension<Box, 2>();
  99. assert_dimension<Point, 2>();
  100. // Copy coordinates
  101. typedef typename coordinate_type<Point>::type coordinate_type;
  102. geometry::set<0>(point, boost::numeric_cast<coordinate_type>(get<Corner1, 0>(box)));
  103. geometry::set<1>(point, boost::numeric_cast<coordinate_type>(get<Corner2, 1>(box)));
  104. }
  105. template
  106. <
  107. typename Geometry, typename Point,
  108. std::size_t Index,
  109. std::size_t Dimension, std::size_t DimensionCount
  110. >
  111. struct assign_point_to_index
  112. {
  113. static inline void apply(Point const& point, Geometry& geometry)
  114. {
  115. geometry::set<Index, Dimension>(geometry, boost::numeric_cast
  116. <
  117. typename coordinate_type<Geometry>::type
  118. >(geometry::get<Dimension>(point)));
  119. assign_point_to_index
  120. <
  121. Geometry, Point, Index, Dimension + 1, DimensionCount
  122. >::apply(point, geometry);
  123. }
  124. };
  125. template
  126. <
  127. typename Geometry, typename Point,
  128. std::size_t Index,
  129. std::size_t DimensionCount
  130. >
  131. struct assign_point_to_index
  132. <
  133. Geometry, Point,
  134. Index,
  135. DimensionCount, DimensionCount
  136. >
  137. {
  138. static inline void apply(Point const& , Geometry& )
  139. {
  140. }
  141. };
  142. template
  143. <
  144. typename Geometry, typename Point,
  145. std::size_t Index,
  146. std::size_t Dimension, std::size_t DimensionCount
  147. >
  148. struct assign_point_from_index
  149. {
  150. static inline void apply(Geometry const& geometry, Point& point)
  151. {
  152. geometry::set<Dimension>( point, boost::numeric_cast
  153. <
  154. typename coordinate_type<Point>::type
  155. >(geometry::get<Index, Dimension>(geometry)));
  156. assign_point_from_index
  157. <
  158. Geometry, Point, Index, Dimension + 1, DimensionCount
  159. >::apply(geometry, point);
  160. }
  161. };
  162. template
  163. <
  164. typename Geometry, typename Point,
  165. std::size_t Index,
  166. std::size_t DimensionCount
  167. >
  168. struct assign_point_from_index
  169. <
  170. Geometry, Point,
  171. Index,
  172. DimensionCount, DimensionCount
  173. >
  174. {
  175. static inline void apply(Geometry const&, Point&)
  176. {
  177. }
  178. };
  179. template <typename Geometry>
  180. struct assign_2d_box_or_segment
  181. {
  182. typedef typename coordinate_type<Geometry>::type coordinate_type;
  183. // Here we assign 4 coordinates to a box of segment
  184. // -> Most logical is: x1,y1,x2,y2
  185. // In case the user reverses x1/x2 or y1/y2, for a box, we could reverse them (THAT IS NOT IMPLEMENTED)
  186. template <typename Type>
  187. static inline void apply(Geometry& geometry,
  188. Type const& x1, Type const& y1, Type const& x2, Type const& y2)
  189. {
  190. geometry::set<0, 0>(geometry, boost::numeric_cast<coordinate_type>(x1));
  191. geometry::set<0, 1>(geometry, boost::numeric_cast<coordinate_type>(y1));
  192. geometry::set<1, 0>(geometry, boost::numeric_cast<coordinate_type>(x2));
  193. geometry::set<1, 1>(geometry, boost::numeric_cast<coordinate_type>(y2));
  194. }
  195. };
  196. }} // namespace detail::assign
  197. #endif // DOXYGEN_NO_DETAIL
  198. #ifndef DOXYGEN_NO_DISPATCH
  199. namespace dispatch
  200. {
  201. template <typename GeometryTag, typename Geometry, std::size_t DimensionCount>
  202. struct assign
  203. {
  204. BOOST_MPL_ASSERT_MSG
  205. (
  206. false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
  207. , (types<Geometry>)
  208. );
  209. };
  210. template <typename Point>
  211. struct assign<point_tag, Point, 2>
  212. {
  213. typedef typename coordinate_type<Point>::type coordinate_type;
  214. template <typename T>
  215. static inline void apply(Point& point, T const& c1, T const& c2)
  216. {
  217. set<0>(point, boost::numeric_cast<coordinate_type>(c1));
  218. set<1>(point, boost::numeric_cast<coordinate_type>(c2));
  219. }
  220. };
  221. template <typename Point>
  222. struct assign<point_tag, Point, 3>
  223. {
  224. typedef typename coordinate_type<Point>::type coordinate_type;
  225. template <typename T>
  226. static inline void apply(Point& point, T const& c1, T const& c2, T const& c3)
  227. {
  228. set<0>(point, boost::numeric_cast<coordinate_type>(c1));
  229. set<1>(point, boost::numeric_cast<coordinate_type>(c2));
  230. set<2>(point, boost::numeric_cast<coordinate_type>(c3));
  231. }
  232. };
  233. template <typename Box>
  234. struct assign<box_tag, Box, 2>
  235. : detail::assign::assign_2d_box_or_segment<Box>
  236. {};
  237. template <typename Segment>
  238. struct assign<segment_tag, Segment, 2>
  239. : detail::assign::assign_2d_box_or_segment<Segment>
  240. {};
  241. template <typename GeometryTag, typename Geometry>
  242. struct assign_zero {};
  243. template <typename Point>
  244. struct assign_zero<point_tag, Point>
  245. : detail::assign::assign_zero_point
  246. {};
  247. template <typename Box>
  248. struct assign_zero<box_tag, Box>
  249. : detail::assign::assign_zero_box_or_segment
  250. {};
  251. template <typename Segment>
  252. struct assign_zero<segment_tag, Segment>
  253. : detail::assign::assign_zero_box_or_segment
  254. {};
  255. template <typename GeometryTag, typename Geometry>
  256. struct assign_inverse {};
  257. template <typename Box>
  258. struct assign_inverse<box_tag, Box>
  259. : detail::assign::assign_inverse_box_or_segment
  260. {};
  261. template <typename Segment>
  262. struct assign_inverse<segment_tag, Segment>
  263. : detail::assign::assign_inverse_box_or_segment
  264. {};
  265. } // namespace dispatch
  266. #endif // DOXYGEN_NO_DISPATCH
  267. }} // namespace boost::geometry
  268. #endif // BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP