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// Copyright (c) 2014 Samuel Debionne, Grenoble, France.
7
8// This file was modified by Oracle on 2020-2023.
9// Modifications copyright (c) 2020-2023 Oracle and/or its affiliates.
10// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
11// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
12
13// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
14// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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_HPP
21#define BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
22
23#include <boost/variant/static_visitor.hpp>
24#include <boost/variant/variant_fwd.hpp>
25
26#include <boost/geometry/algorithms/append.hpp>
27#include <boost/geometry/algorithms/clear.hpp>
28#include <boost/geometry/algorithms/convert.hpp>
29
30#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
31#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
32#include <boost/geometry/algorithms/detail/assign_values.hpp>
33
34#include <boost/geometry/core/static_assert.hpp>
35
36#include <boost/geometry/geometries/concepts/check.hpp>
37
38namespace boost { namespace geometry
39{
40
41/*!
42\brief Assign a range of points to a linestring, ring or polygon
43\note The point-type of the range might be different from the point-type of the geometry
44\ingroup assign
45\tparam Geometry \tparam_geometry
46\tparam Range \tparam_range_point
47\param geometry \param_geometry
48\param range \param_range_point
49
50\qbk{
51[heading Notes]
52[note Assign automatically clears the geometry before assigning (use append if you don't want that)]
53[heading Example]
54[assign_points] [assign_points_output]
55
56[heading See also]
57\* [link geometry.reference.algorithms.append append]
58}
59 */
60template <typename Geometry, typename Range>
61inline void assign_points(Geometry& geometry, Range const& range)
62{
63 concepts::check<Geometry>();
64
65 clear(geometry);
66 geometry::append(geometry, range, -1, 0);
67}
68
69
70/*!
71\brief assign to a box inverse infinite
72\details The assign_inverse function initialize a 2D or 3D box with large coordinates, the
73min corner is very large, the max corner is very small. This is a convenient starting point to
74collect the minimum bounding box of a geometry.
75\ingroup assign
76\tparam Geometry \tparam_geometry
77\param geometry \param_geometry
78
79\qbk{
80[heading Example]
81[assign_inverse] [assign_inverse_output]
82
83[heading See also]
84\* [link geometry.reference.algorithms.make.make_inverse make_inverse]
85}
86 */
87template <typename Geometry>
88inline void assign_inverse(Geometry& geometry)
89{
90 concepts::check<Geometry>();
91
92 dispatch::assign_inverse
93 <
94 typename tag<Geometry>::type,
95 Geometry
96 >::apply(geometry);
97}
98
99/*!
100\brief assign zero values to a box, point
101\ingroup assign
102\details The assign_zero function initializes a 2D or 3D point or box with coordinates of zero
103\tparam Geometry \tparam_geometry
104\param geometry \param_geometry
105
106 */
107template <typename Geometry>
108inline void assign_zero(Geometry& geometry)
109{
110 concepts::check<Geometry>();
111
112 dispatch::assign_zero
113 <
114 typename tag<Geometry>::type,
115 Geometry
116 >::apply(geometry);
117}
118
119/*!
120\brief Assign two coordinates to a geometry (usually a 2D point)
121\ingroup assign
122\tparam Geometry \tparam_geometry
123\tparam Type \tparam_numeric to specify the coordinates
124\param geometry \param_geometry
125\param c1 \param_x
126\param c2 \param_y
127
128\qbk{distinguish, 2 coordinate values}
129\qbk{
130[heading Example]
131[assign_2d_point] [assign_2d_point_output]
132
133[heading See also]
134\* [link geometry.reference.algorithms.make.make_2_2_coordinate_values make]
135}
136 */
137template <typename Geometry, typename Type>
138inline void assign_values(Geometry& geometry, Type const& c1, Type const& c2)
139{
140 concepts::check<Geometry>();
141
142 dispatch::assign
143 <
144 typename tag<Geometry>::type,
145 Geometry,
146 geometry::dimension<Geometry>::type::value
147 >::apply(geometry, c1, c2);
148}
149
150/*!
151\brief Assign three values to a geometry (usually a 3D point)
152\ingroup assign
153\tparam Geometry \tparam_geometry
154\tparam Type \tparam_numeric to specify the coordinates
155\param geometry \param_geometry
156\param c1 \param_x
157\param c2 \param_y
158\param c3 \param_z
159
160\qbk{distinguish, 3 coordinate values}
161\qbk{
162[heading Example]
163[assign_3d_point] [assign_3d_point_output]
164
165[heading See also]
166\* [link geometry.reference.algorithms.make.make_3_3_coordinate_values make]
167}
168 */
169template <typename Geometry, typename Type>
170inline void assign_values(Geometry& geometry,
171 Type const& c1, Type const& c2, Type const& c3)
172{
173 concepts::check<Geometry>();
174
175 dispatch::assign
176 <
177 typename tag<Geometry>::type,
178 Geometry,
179 geometry::dimension<Geometry>::type::value
180 >::apply(geometry, c1, c2, c3);
181}
182
183/*!
184\brief Assign four values to a geometry (usually a box or segment)
185\ingroup assign
186\tparam Geometry \tparam_geometry
187\tparam Type \tparam_numeric to specify the coordinates
188\param geometry \param_geometry
189\param c1 First coordinate (usually x1)
190\param c2 Second coordinate (usually y1)
191\param c3 Third coordinate (usually x2)
192\param c4 Fourth coordinate (usually y2)
193
194\qbk{distinguish, 4 coordinate values}
195 */
196template <typename Geometry, typename Type>
197inline void assign_values(Geometry& geometry,
198 Type const& c1, Type const& c2, Type const& c3, Type const& c4)
199{
200 concepts::check<Geometry>();
201
202 dispatch::assign
203 <
204 typename tag<Geometry>::type,
205 Geometry,
206 geometry::dimension<Geometry>::type::value
207 >::apply(geometry, c1, c2, c3, c4);
208}
209
210
211
212namespace resolve_variant
213{
214
215template <typename Geometry1, typename Geometry2>
216struct assign
217{
218 static inline void
219 apply(Geometry1& geometry1, Geometry2 const& geometry2)
220 {
221 concepts::check<Geometry1>();
222 concepts::check<Geometry2 const>();
223 concepts::check_concepts_and_equal_dimensions<Geometry1, Geometry2 const>();
224
225 static bool const same_point_order
226 = point_order<Geometry1>::value == point_order<Geometry2>::value;
227 BOOST_GEOMETRY_STATIC_ASSERT(
228 same_point_order,
229 "Assign is not supported for different point orders.",
230 Geometry1, Geometry2);
231 static bool const same_closure
232 = closure<Geometry1>::value == closure<Geometry2>::value;
233 BOOST_GEOMETRY_STATIC_ASSERT(
234 same_closure,
235 "Assign is not supported for different closures.",
236 Geometry1, Geometry2);
237
238 dispatch::convert<Geometry2, Geometry1>::apply(geometry2, geometry1);
239 }
240};
241
242
243template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
244struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
245{
246 struct visitor: static_visitor<void>
247 {
248 Geometry2 const& m_geometry2;
249
250 visitor(Geometry2 const& geometry2)
251 : m_geometry2(geometry2)
252 {}
253
254 template <typename Geometry1>
255 result_type operator()(Geometry1& geometry1) const
256 {
257 return assign
258 <
259 Geometry1,
260 Geometry2
261 >::apply
262 (geometry1, m_geometry2);
263 }
264 };
265
266 static inline void
267 apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry1,
268 Geometry2 const& geometry2)
269 {
270 return boost::apply_visitor(visitor(geometry2), geometry1);
271 }
272};
273
274
275template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
276struct assign<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
277{
278 struct visitor: static_visitor<void>
279 {
280 Geometry1& m_geometry1;
281
282 visitor(Geometry1 const& geometry1)
283 : m_geometry1(geometry1)
284 {}
285
286 template <typename Geometry2>
287 result_type operator()(Geometry2 const& geometry2) const
288 {
289 return assign
290 <
291 Geometry1,
292 Geometry2
293 >::apply
294 (m_geometry1, geometry2);
295 }
296 };
297
298 static inline void
299 apply(Geometry1& geometry1,
300 variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
301 {
302 return boost::apply_visitor(visitor(geometry1), geometry2);
303 }
304};
305
306
307template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
308struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
309{
310 struct visitor: static_visitor<void>
311 {
312 template <typename Geometry1, typename Geometry2>
313 result_type operator()(
314 Geometry1& geometry1,
315 Geometry2 const& geometry2) const
316 {
317 return assign
318 <
319 Geometry1,
320 Geometry2
321 >::apply
322 (geometry1, geometry2);
323 }
324 };
325
326 static inline void
327 apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
328 variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
329 {
330 return boost::apply_visitor(visitor(), geometry1, geometry2);
331 }
332};
333
334} // namespace resolve_variant
335
336
337/*!
338\brief Assigns one geometry to another geometry
339\details The assign algorithm assigns one geometry, e.g. a BOX, to another
340geometry, e.g. a RING. This only works if it is possible and applicable.
341\ingroup assign
342\tparam Geometry1 \tparam_geometry
343\tparam Geometry2 \tparam_geometry
344\param geometry1 \param_geometry (target)
345\param geometry2 \param_geometry (source)
346
347\qbk{
348[heading Example]
349[assign] [assign_output]
350
351[heading See also]
352\* [link geometry.reference.algorithms.convert convert]
353}
354 */
355template <typename Geometry1, typename Geometry2>
356inline void assign(Geometry1& geometry1, Geometry2 const& geometry2)
357{
358 resolve_variant::assign<Geometry1, Geometry2>::apply(geometry1, geometry2);
359}
360
361
362}} // namespace boost::geometry
363
364
365
366#endif // BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
367

source code of boost/libs/geometry/include/boost/geometry/algorithms/assign.hpp