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-2020.
11 // Modifications copyright (c) 2018-2020, Oracle and/or its affiliates.
12
13 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
14 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
15
16 // Use, modification and distribution is subject to the Boost Software License,
17 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
18 // http://www.boost.org/LICENSE_1_0.txt)
19
20 #ifndef BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
21 #define BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
22
23
24 #include <cstddef>
25 #include <type_traits>
26
27 #include <boost/concept/requires.hpp>
28 #include <boost/concept_check.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/static_assert.hpp>
38 #include <boost/geometry/core/tags.hpp>
39
40 #include <boost/geometry/geometries/concepts/check.hpp>
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_GEOMETRY_STATIC_ASSERT_FALSE(
258 "Not or not yet implemented for this Geometry type.",
259 GeometryTag, Geometry, std::integral_constant<std::size_t, DimensionCount>);
260 };
261
262 template <typename Point>
263 struct assign<point_tag, Point, 2>
264 {
265 typedef typename coordinate_type<Point>::type coordinate_type;
266
267 template <typename T>
applyboost::geometry::dispatch::assign268 static inline void apply(Point& point, T const& c1, T const& c2)
269 {
270 set<0>(point, boost::numeric_cast<coordinate_type>(c1));
271 set<1>(point, boost::numeric_cast<coordinate_type>(c2));
272 }
273 };
274
275 template <typename Point>
276 struct assign<point_tag, Point, 3>
277 {
278 typedef typename coordinate_type<Point>::type coordinate_type;
279
280 template <typename T>
applyboost::geometry::dispatch::assign281 static inline void apply(Point& point, T const& c1, T const& c2, T const& c3)
282 {
283 set<0>(point, boost::numeric_cast<coordinate_type>(c1));
284 set<1>(point, boost::numeric_cast<coordinate_type>(c2));
285 set<2>(point, boost::numeric_cast<coordinate_type>(c3));
286 }
287 };
288
289 template <typename Box>
290 struct assign<box_tag, Box, 2>
291 : detail::assign::assign_2d_box_or_segment<Box>
292 {};
293
294 template <typename Segment>
295 struct assign<segment_tag, Segment, 2>
296 : detail::assign::assign_2d_box_or_segment<Segment>
297 {};
298
299
300
301 template <typename GeometryTag, typename Geometry>
302 struct assign_zero {};
303
304
305 template <typename Point>
306 struct assign_zero<point_tag, Point>
307 : detail::assign::assign_zero_point
308 {};
309
310 template <typename Box>
311 struct assign_zero<box_tag, Box>
312 : detail::assign::assign_zero_box_or_segment
313 {};
314
315 template <typename Segment>
316 struct assign_zero<segment_tag, Segment>
317 : detail::assign::assign_zero_box_or_segment
318 {};
319
320
321 template <typename GeometryTag, typename Geometry>
322 struct assign_inverse {};
323
324 template <typename Box>
325 struct assign_inverse<box_tag, Box>
326 : detail::assign::assign_inverse_box_or_segment
327 {};
328
329 template <typename Segment>
330 struct assign_inverse<segment_tag, Segment>
331 : detail::assign::assign_inverse_box_or_segment
332 {};
333
334
335 } // namespace dispatch
336 #endif // DOXYGEN_NO_DISPATCH
337
338 }} // namespace boost::geometry
339
340
341 #endif // BOOST_GEOMETRY_ALGORITHMS_ASSIGN_VALUES_HPP
342