1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
6
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
9
10 // This file was modified by Oracle on 2018.
11 // Modifications copyright (c) 2018, Oracle and/or its affiliates.
12
13 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
14
15 // Use, modification and distribution is subject to the Boost Software License,
16 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
17 // http://www.boost.org/LICENSE_1_0.txt)
18
19 #ifndef BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
20 #define BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
21
22
23 #include <cstddef>
24
25 #include <boost/concept/requires.hpp>
26 #include <boost/concept_check.hpp>
27 #include <boost/mpl/assert.hpp>
28 #include <boost/mpl/if.hpp>
29 #include <boost/numeric/conversion/bounds.hpp>
30 #include <boost/numeric/conversion/cast.hpp>
31
32 #include <boost/geometry/arithmetic/arithmetic.hpp>
33 #include <boost/geometry/algorithms/append.hpp>
34 #include <boost/geometry/algorithms/clear.hpp>
35 #include <boost/geometry/core/access.hpp>
36 #include <boost/geometry/core/exterior_ring.hpp>
37 #include <boost/geometry/core/tags.hpp>
38
39 #include <boost/geometry/geometries/concepts/check.hpp>
40
41
42 #include <boost/geometry/util/is_inverse_spheroidal_coordinates.hpp>
43 #include <boost/geometry/util/for_each_coordinate.hpp>
44
45
46 namespace boost { namespace geometry
47 {
48
49 #ifndef DOXYGEN_NO_DETAIL
50 namespace detail { namespace assign
51 {
52
53
54 template <std::size_t Index, std::size_t Dimension, std::size_t DimensionCount>
55 struct initialize
56 {
57 template <typename Box>
applyboost::geometry::detail::assign::initialize58 static inline void apply(Box& box, typename coordinate_type<Box>::type const& value)
59 {
60 geometry::set<Index, Dimension>(box, value);
61 initialize<Index, Dimension + 1, DimensionCount>::apply(box, value);
62 }
63 };
64
65
66 template <std::size_t Index, std::size_t DimensionCount>
67 struct initialize<Index, DimensionCount, DimensionCount>
68 {
69 template <typename Box>
applyboost::geometry::detail::assign::initialize70 static inline void apply(Box&, typename coordinate_type<Box>::type const&)
71 {}
72 };
73
74
75 struct assign_zero_point
76 {
77 template <typename Point>
applyboost::geometry::detail::assign::assign_zero_point78 static inline void apply(Point& point)
79 {
80 geometry::assign_value(point, 0);
81 }
82 };
83
84
85 struct assign_inverse_box_or_segment
86 {
87
88 template <typename BoxOrSegment>
applyboost::geometry::detail::assign::assign_inverse_box_or_segment89 static inline void apply(BoxOrSegment& geometry)
90 {
91 typedef typename point_type<BoxOrSegment>::type point_type;
92 typedef typename coordinate_type<point_type>::type bound_type;
93
94 initialize<0, 0, dimension<BoxOrSegment>::type::value>::apply(
95 geometry, geometry::bounds<bound_type>::highest()
96 );
97 initialize<1, 0, dimension<BoxOrSegment>::type::value>::apply(
98 geometry, geometry::bounds<bound_type>::lowest()
99 );
100 }
101
102 };
103
104
105 struct assign_zero_box_or_segment
106 {
107 template <typename BoxOrSegment>
applyboost::geometry::detail::assign::assign_zero_box_or_segment108 static inline void apply(BoxOrSegment& geometry)
109 {
110 typedef typename coordinate_type<BoxOrSegment>::type coordinate_type;
111
112 initialize<0, 0, dimension<BoxOrSegment>::type::value>::apply(
113 geometry, coordinate_type()
114 );
115 initialize<1, 0, dimension<BoxOrSegment>::type::value>::apply(
116 geometry, coordinate_type()
117 );
118 }
119 };
120
121
122 template
123 <
124 std::size_t Corner1, std::size_t Corner2,
125 typename Box, typename Point
126 >
assign_box_2d_corner(Box const & box,Point & point)127 inline void assign_box_2d_corner(Box const& box, Point& point)
128 {
129 // Be sure both are 2-Dimensional
130 assert_dimension<Box, 2>();
131 assert_dimension<Point, 2>();
132
133 // Copy coordinates
134 typedef typename coordinate_type<Point>::type coordinate_type;
135
136 geometry::set<0>(point, boost::numeric_cast<coordinate_type>(get<Corner1, 0>(box)));
137 geometry::set<1>(point, boost::numeric_cast<coordinate_type>(get<Corner2, 1>(box)));
138 }
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_to_index
149 {
150
applyboost::geometry::detail::assign::assign_point_to_index151 static inline void apply(Point const& point, Geometry& geometry)
152 {
153 geometry::set<Index, Dimension>(geometry, boost::numeric_cast
154 <
155 typename coordinate_type<Geometry>::type
156 >(geometry::get<Dimension>(point)));
157
158 assign_point_to_index
159 <
160 Geometry, Point, Index, Dimension + 1, DimensionCount
161 >::apply(point, geometry);
162 }
163 };
164
165 template
166 <
167 typename Geometry, typename Point,
168 std::size_t Index,
169 std::size_t DimensionCount
170 >
171 struct assign_point_to_index
172 <
173 Geometry, Point,
174 Index,
175 DimensionCount, DimensionCount
176 >
177 {
applyboost::geometry::detail::assign::assign_point_to_index178 static inline void apply(Point const& , Geometry& )
179 {
180 }
181 };
182
183
184 template
185 <
186 typename Geometry, typename Point,
187 std::size_t Index,
188 std::size_t Dimension, std::size_t DimensionCount
189 >
190 struct assign_point_from_index
191 {
192
applyboost::geometry::detail::assign::assign_point_from_index193 static inline void apply(Geometry const& geometry, Point& point)
194 {
195 geometry::set<Dimension>( point, boost::numeric_cast
196 <
197 typename coordinate_type<Point>::type
198 >(geometry::get<Index, Dimension>(geometry)));
199
200 assign_point_from_index
201 <
202 Geometry, Point, Index, Dimension + 1, DimensionCount
203 >::apply(geometry, point);
204 }
205 };
206
207 template
208 <
209 typename Geometry, typename Point,
210 std::size_t Index,
211 std::size_t DimensionCount
212 >
213 struct assign_point_from_index
214 <
215 Geometry, Point,
216 Index,
217 DimensionCount, DimensionCount
218 >
219 {
applyboost::geometry::detail::assign::assign_point_from_index220 static inline void apply(Geometry const&, Point&)
221 {
222 }
223 };
224
225
226 template <typename Geometry>
227 struct assign_2d_box_or_segment
228 {
229 typedef typename coordinate_type<Geometry>::type coordinate_type;
230
231 // Here we assign 4 coordinates to a box of segment
232 // -> Most logical is: x1,y1,x2,y2
233 // In case the user reverses x1/x2 or y1/y2, for a box, we could reverse them (THAT IS NOT IMPLEMENTED)
234
235 template <typename Type>
applyboost::geometry::detail::assign::assign_2d_box_or_segment236 static inline void apply(Geometry& geometry,
237 Type const& x1, Type const& y1, Type const& x2, Type const& y2)
238 {
239 geometry::set<0, 0>(geometry, boost::numeric_cast<coordinate_type>(x1));
240 geometry::set<0, 1>(geometry, boost::numeric_cast<coordinate_type>(y1));
241 geometry::set<1, 0>(geometry, boost::numeric_cast<coordinate_type>(x2));
242 geometry::set<1, 1>(geometry, boost::numeric_cast<coordinate_type>(y2));
243 }
244 };
245
246
247 }} // namespace detail::assign
248 #endif // DOXYGEN_NO_DETAIL
249
250 #ifndef DOXYGEN_NO_DISPATCH
251 namespace dispatch
252 {
253
254 template <typename GeometryTag, typename Geometry, std::size_t DimensionCount>
255 struct assign
256 {
257 BOOST_MPL_ASSERT_MSG
258 (
259 false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
260 , (types<Geometry>)
261 );
262 };
263
264 template <typename Point>
265 struct assign<point_tag, Point, 2>
266 {
267 typedef typename coordinate_type<Point>::type coordinate_type;
268
269 template <typename T>
applyboost::geometry::dispatch::assign270 static inline void apply(Point& point, T const& c1, T const& c2)
271 {
272 set<0>(point, boost::numeric_cast<coordinate_type>(c1));
273 set<1>(point, boost::numeric_cast<coordinate_type>(c2));
274 }
275 };
276
277 template <typename Point>
278 struct assign<point_tag, Point, 3>
279 {
280 typedef typename coordinate_type<Point>::type coordinate_type;
281
282 template <typename T>
applyboost::geometry::dispatch::assign283 static inline void apply(Point& point, T const& c1, T const& c2, T const& c3)
284 {
285 set<0>(point, boost::numeric_cast<coordinate_type>(c1));
286 set<1>(point, boost::numeric_cast<coordinate_type>(c2));
287 set<2>(point, boost::numeric_cast<coordinate_type>(c3));
288 }
289 };
290
291 template <typename Box>
292 struct assign<box_tag, Box, 2>
293 : detail::assign::assign_2d_box_or_segment<Box>
294 {};
295
296 template <typename Segment>
297 struct assign<segment_tag, Segment, 2>
298 : detail::assign::assign_2d_box_or_segment<Segment>
299 {};
300
301
302
303 template <typename GeometryTag, typename Geometry>
304 struct assign_zero {};
305
306
307 template <typename Point>
308 struct assign_zero<point_tag, Point>
309 : detail::assign::assign_zero_point
310 {};
311
312 template <typename Box>
313 struct assign_zero<box_tag, Box>
314 : detail::assign::assign_zero_box_or_segment
315 {};
316
317 template <typename Segment>
318 struct assign_zero<segment_tag, Segment>
319 : detail::assign::assign_zero_box_or_segment
320 {};
321
322
323 template <typename GeometryTag, typename Geometry>
324 struct assign_inverse {};
325
326 template <typename Box>
327 struct assign_inverse<box_tag, Box>
328 : detail::assign::assign_inverse_box_or_segment
329 {};
330
331 template <typename Segment>
332 struct assign_inverse<segment_tag, Segment>
333 : detail::assign::assign_inverse_box_or_segment
334 {};
335
336
337 } // namespace dispatch
338 #endif // DOXYGEN_NO_DISPATCH
339
340 }} // namespace boost::geometry
341
342
343 #endif // BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
344