1 // Boost.Geometry (aka GGL, Generic Geometry Library)
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.
8 // This file was modified by Oracle on 2020.
9 // Modifications copyright (c) 2020 Oracle and/or its affiliates.
10 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
12 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
13 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
19 #ifndef BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
20 #define BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
25 #include <boost/concept/requires.hpp>
26 #include <boost/concept_check.hpp>
27 #include <boost/numeric/conversion/bounds.hpp>
28 #include <boost/numeric/conversion/cast.hpp>
30 #include <boost/variant/apply_visitor.hpp>
31 #include <boost/variant/static_visitor.hpp>
32 #include <boost/variant/variant_fwd.hpp>
34 #include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
35 #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
36 #include <boost/geometry/algorithms/detail/assign_values.hpp>
37 #include <boost/geometry/algorithms/convert.hpp>
38 #include <boost/geometry/algorithms/append.hpp>
39 #include <boost/geometry/algorithms/clear.hpp>
40 #include <boost/geometry/arithmetic/arithmetic.hpp>
41 #include <boost/geometry/core/access.hpp>
42 #include <boost/geometry/core/exterior_ring.hpp>
43 #include <boost/geometry/core/static_assert.hpp>
44 #include <boost/geometry/core/tags.hpp>
46 #include <boost/geometry/geometries/concepts/check.hpp>
48 #include <boost/geometry/util/for_each_coordinate.hpp>
50 namespace boost { namespace geometry
54 \brief Assign a range of points to a linestring, ring or polygon
55 \note The point-type of the range might be different from the point-type of the geometry
57 \tparam Geometry \tparam_geometry
58 \tparam Range \tparam_range_point
59 \param geometry \param_geometry
60 \param range \param_range_point
64 [note Assign automatically clears the geometry before assigning (use append if you don't want that)]
66 [assign_points] [assign_points_output]
69 \* [link geometry.reference.algorithms.append append]
72 template <typename Geometry, typename Range>
73 inline void assign_points(Geometry& geometry, Range const& range)
75 concepts::check<Geometry>();
78 geometry::append(geometry, range, -1, 0);
83 \brief assign to a box inverse infinite
84 \details The assign_inverse function initialize a 2D or 3D box with large coordinates, the
85 min corner is very large, the max corner is very small. This is a convenient starting point to
86 collect the minimum bounding box of a geometry.
88 \tparam Geometry \tparam_geometry
89 \param geometry \param_geometry
93 [assign_inverse] [assign_inverse_output]
96 \* [link geometry.reference.algorithms.make.make_inverse make_inverse]
99 template <typename Geometry>
100 inline void assign_inverse(Geometry& geometry)
102 concepts::check<Geometry>();
104 dispatch::assign_inverse
106 typename tag<Geometry>::type,
112 \brief assign zero values to a box, point
114 \details The assign_zero function initializes a 2D or 3D point or box with coordinates of zero
115 \tparam Geometry \tparam_geometry
116 \param geometry \param_geometry
119 template <typename Geometry>
120 inline void assign_zero(Geometry& geometry)
122 concepts::check<Geometry>();
124 dispatch::assign_zero
126 typename tag<Geometry>::type,
132 \brief Assign two coordinates to a geometry (usually a 2D point)
134 \tparam Geometry \tparam_geometry
135 \tparam Type \tparam_numeric to specify the coordinates
136 \param geometry \param_geometry
140 \qbk{distinguish, 2 coordinate values}
143 [assign_2d_point] [assign_2d_point_output]
146 \* [link geometry.reference.algorithms.make.make_2_2_coordinate_values make]
149 template <typename Geometry, typename Type>
150 inline void assign_values(Geometry& geometry, Type const& c1, Type const& c2)
152 concepts::check<Geometry>();
156 typename tag<Geometry>::type,
158 geometry::dimension<Geometry>::type::value
159 >::apply(geometry, c1, c2);
163 \brief Assign three values to a geometry (usually a 3D point)
165 \tparam Geometry \tparam_geometry
166 \tparam Type \tparam_numeric to specify the coordinates
167 \param geometry \param_geometry
172 \qbk{distinguish, 3 coordinate values}
175 [assign_3d_point] [assign_3d_point_output]
178 \* [link geometry.reference.algorithms.make.make_3_3_coordinate_values make]
181 template <typename Geometry, typename Type>
182 inline void assign_values(Geometry& geometry,
183 Type const& c1, Type const& c2, Type const& c3)
185 concepts::check<Geometry>();
189 typename tag<Geometry>::type,
191 geometry::dimension<Geometry>::type::value
192 >::apply(geometry, c1, c2, c3);
196 \brief Assign four values to a geometry (usually a box or segment)
198 \tparam Geometry \tparam_geometry
199 \tparam Type \tparam_numeric to specify the coordinates
200 \param geometry \param_geometry
201 \param c1 First coordinate (usually x1)
202 \param c2 Second coordinate (usually y1)
203 \param c3 Third coordinate (usually x2)
204 \param c4 Fourth coordinate (usually y2)
206 \qbk{distinguish, 4 coordinate values}
208 template <typename Geometry, typename Type>
209 inline void assign_values(Geometry& geometry,
210 Type const& c1, Type const& c2, Type const& c3, Type const& c4)
212 concepts::check<Geometry>();
216 typename tag<Geometry>::type,
218 geometry::dimension<Geometry>::type::value
219 >::apply(geometry, c1, c2, c3, c4);
224 namespace resolve_variant
227 template <typename Geometry1, typename Geometry2>
231 apply(Geometry1& geometry1, const Geometry2& geometry2)
233 concepts::check<Geometry1>();
234 concepts::check<Geometry2 const>();
235 concepts::check_concepts_and_equal_dimensions<Geometry1, Geometry2 const>();
237 static bool const same_point_order
238 = point_order<Geometry1>::value == point_order<Geometry2>::value;
239 BOOST_GEOMETRY_STATIC_ASSERT(
241 "Assign is not supported for different point orders.",
242 Geometry1, Geometry2);
243 static bool const same_closure
244 = closure<Geometry1>::value == closure<Geometry2>::value;
245 BOOST_GEOMETRY_STATIC_ASSERT(
247 "Assign is not supported for different closures.",
248 Geometry1, Geometry2);
250 dispatch::convert<Geometry2, Geometry1>::apply(geometry2, geometry1);
255 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
256 struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
258 struct visitor: static_visitor<void>
260 Geometry2 const& m_geometry2;
262 visitor(Geometry2 const& geometry2)
263 : m_geometry2(geometry2)
266 template <typename Geometry1>
267 result_type operator()(Geometry1& geometry1) const
274 (geometry1, m_geometry2);
279 apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry1,
280 Geometry2 const& geometry2)
282 return boost::apply_visitor(visitor(geometry2), geometry1);
287 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
288 struct assign<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
290 struct visitor: static_visitor<void>
292 Geometry1& m_geometry1;
294 visitor(Geometry1 const& geometry1)
295 : m_geometry1(geometry1)
298 template <typename Geometry2>
299 result_type operator()(Geometry2 const& geometry2) const
306 (m_geometry1, geometry2);
311 apply(Geometry1& geometry1,
312 variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
314 return boost::apply_visitor(visitor(geometry1), geometry2);
319 template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
320 struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
322 struct visitor: static_visitor<void>
324 template <typename Geometry1, typename Geometry2>
325 result_type operator()(
326 Geometry1& geometry1,
327 Geometry2 const& geometry2) const
334 (geometry1, geometry2);
339 apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
340 variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
342 return boost::apply_visitor(visitor(), geometry1, geometry2);
346 } // namespace resolve_variant
350 \brief Assigns one geometry to another geometry
351 \details The assign algorithm assigns one geometry, e.g. a BOX, to another
352 geometry, e.g. a RING. This only works if it is possible and applicable.
354 \tparam Geometry1 \tparam_geometry
355 \tparam Geometry2 \tparam_geometry
356 \param geometry1 \param_geometry (target)
357 \param geometry2 \param_geometry (source)
361 [assign] [assign_output]
364 \* [link geometry.reference.algorithms.convert convert]
367 template <typename Geometry1, typename Geometry2>
368 inline void assign(Geometry1& geometry1, Geometry2 const& geometry2)
370 resolve_variant::assign<Geometry1, Geometry2>::apply(geometry1, geometry2);
374 }} // namespace boost::geometry
378 #endif // BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP