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 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
9 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
11 // Use, modification and distribution is subject to the Boost Software License,
12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
13 // http://www.boost.org/LICENSE_1_0.txt)
15 #ifndef BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
16 #define BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
21 #include <boost/concept/requires.hpp>
22 #include <boost/concept_check.hpp>
23 #include <boost/mpl/assert.hpp>
24 #include <boost/mpl/if.hpp>
25 #include <boost/numeric/conversion/bounds.hpp>
26 #include <boost/numeric/conversion/cast.hpp>
27 #include <boost/type_traits.hpp>
29 #include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
30 #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
31 #include <boost/geometry/algorithms/detail/assign_values.hpp>
32 #include <boost/geometry/algorithms/convert.hpp>
33 #include <boost/geometry/algorithms/append.hpp>
34 #include <boost/geometry/algorithms/clear.hpp>
35 #include <boost/geometry/arithmetic/arithmetic.hpp>
36 #include <boost/geometry/core/access.hpp>
37 #include <boost/geometry/core/exterior_ring.hpp>
38 #include <boost/geometry/core/tags.hpp>
40 #include <boost/geometry/geometries/concepts/check.hpp>
42 #include <boost/geometry/util/for_each_coordinate.hpp>
44 #include <boost/variant/variant_fwd.hpp>
46 namespace boost { namespace geometry
50 \brief Assign a range of points to a linestring, ring or polygon
51 \note The point-type of the range might be different from the point-type of the geometry
53 \tparam Geometry \tparam_geometry
54 \tparam Range \tparam_range_point
55 \param geometry \param_geometry
56 \param range \param_range_point
60 [note Assign automatically clears the geometry before assigning (use append if you don't want that)]
62 [assign_points] [assign_points_output]
65 \* [link geometry.reference.algorithms.append append]
68 template <typename Geometry, typename Range>
69 inline void assign_points(Geometry& geometry, Range const& range)
71 concept::check<Geometry>();
74 geometry::append(geometry, range, -1, 0);
79 \brief assign to a box inverse infinite
80 \details The assign_inverse function initialize a 2D or 3D box with large coordinates, the
81 min corner is very large, the max corner is very small. This is a convenient starting point to
82 collect the minimum bounding box of a geometry.
84 \tparam Geometry \tparam_geometry
85 \param geometry \param_geometry
89 [assign_inverse] [assign_inverse_output]
92 \* [link geometry.reference.algorithms.make.make_inverse make_inverse]
95 template <typename Geometry>
96 inline void assign_inverse(Geometry& geometry)
98 concept::check<Geometry>();
100 dispatch::assign_inverse
102 typename tag<Geometry>::type,
108 \brief assign zero values to a box, point
110 \details The assign_zero function initializes a 2D or 3D point or box with coordinates of zero
111 \tparam Geometry \tparam_geometry
112 \param geometry \param_geometry
115 template <typename Geometry>
116 inline void assign_zero(Geometry& geometry)
118 concept::check<Geometry>();
120 dispatch::assign_zero
122 typename tag<Geometry>::type,
128 \brief Assign two coordinates to a geometry (usually a 2D point)
130 \tparam Geometry \tparam_geometry
131 \tparam Type \tparam_numeric to specify the coordinates
132 \param geometry \param_geometry
136 \qbk{distinguish, 2 coordinate values}
139 [assign_2d_point] [assign_2d_point_output]
142 \* [link geometry.reference.algorithms.make.make_2_2_coordinate_values make]
145 template <typename Geometry, typename Type>
146 inline void assign_values(Geometry& geometry, Type const& c1, Type const& c2)
148 concept::check<Geometry>();
152 typename tag<Geometry>::type,
154 geometry::dimension<Geometry>::type::value
155 >::apply(geometry, c1, c2);
159 \brief Assign three values to a geometry (usually a 3D point)
161 \tparam Geometry \tparam_geometry
162 \tparam Type \tparam_numeric to specify the coordinates
163 \param geometry \param_geometry
168 \qbk{distinguish, 3 coordinate values}
171 [assign_3d_point] [assign_3d_point_output]
174 \* [link geometry.reference.algorithms.make.make_3_3_coordinate_values make]
177 template <typename Geometry, typename Type>
178 inline void assign_values(Geometry& geometry,
179 Type const& c1, Type const& c2, Type const& c3)
181 concept::check<Geometry>();
185 typename tag<Geometry>::type,
187 geometry::dimension<Geometry>::type::value
188 >::apply(geometry, c1, c2, c3);
192 \brief Assign four values to a geometry (usually a box or segment)
194 \tparam Geometry \tparam_geometry
195 \tparam Type \tparam_numeric to specify the coordinates
196 \param geometry \param_geometry
197 \param c1 First coordinate (usually x1)
198 \param c2 Second coordinate (usually y1)
199 \param c3 Third coordinate (usually x2)
200 \param c4 Fourth coordinate (usually y2)
202 \qbk{distinguish, 4 coordinate values}
204 template <typename Geometry, typename Type>
205 inline void assign_values(Geometry& geometry,
206 Type const& c1, Type const& c2, Type const& c3, Type const& c4)
208 concept::check<Geometry>();
212 typename tag<Geometry>::type,
214 geometry::dimension<Geometry>::type::value
215 >::apply(geometry, c1, c2, c3, c4);
220 namespace resolve_variant
223 template <typename Geometry1, typename Geometry2>
228 Geometry1& geometry1,
229 const Geometry2& geometry2)
231 concept::check<Geometry1>();
232 concept::check<Geometry2 const>();
233 concept::check_concepts_and_equal_dimensions<Geometry1, Geometry2 const>();
235 bool const same_point_order =
236 point_order<Geometry1>::value == point_order<Geometry2>::value;
237 bool const same_closure =
238 closure<Geometry1>::value == closure<Geometry2>::value;
242 same_point_order, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER
243 , (types<Geometry1, Geometry2>)
247 same_closure, ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_CLOSURE
248 , (types<Geometry1, Geometry2>)
251 dispatch::convert<Geometry2, Geometry1>::apply(geometry2, geometry1);
256 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
257 struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
259 struct visitor: static_visitor<void>
261 Geometry2 const& m_geometry2;
263 visitor(Geometry2 const& geometry2)
264 : m_geometry2(geometry2)
267 template <typename Geometry1>
268 result_type operator()(Geometry1& geometry1) const
275 (geometry1, m_geometry2);
280 apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry1,
281 Geometry2 const& geometry2)
283 return apply_visitor(visitor(geometry2), geometry1);
288 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
289 struct assign<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
291 struct visitor: static_visitor<void>
293 Geometry1& m_geometry1;
295 visitor(Geometry1 const& geometry1)
296 : m_geometry1(geometry1)
299 template <typename Geometry2>
300 result_type operator()(Geometry2 const& geometry2) const
307 (m_geometry1, geometry2);
312 apply(Geometry1& geometry1,
313 variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
315 return apply_visitor(visitor(geometry1), geometry2);
320 template <BOOST_VARIANT_ENUM_PARAMS(typename A), BOOST_VARIANT_ENUM_PARAMS(typename B)>
321 struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(A)>, variant<BOOST_VARIANT_ENUM_PARAMS(B)> >
323 struct visitor: static_visitor<void>
325 template <typename Geometry1, typename Geometry2>
326 result_type operator()(
327 Geometry1& geometry1,
328 Geometry2 const& geometry2) const
335 (geometry1, geometry2);
340 apply(variant<BOOST_VARIANT_ENUM_PARAMS(A)>& geometry1,
341 variant<BOOST_VARIANT_ENUM_PARAMS(B)> const& geometry2)
343 return apply_visitor(visitor(), geometry1, geometry2);
347 } // namespace resolve_variant
351 \brief Assigns one geometry to another geometry
352 \details The assign algorithm assigns one geometry, e.g. a BOX, to another
353 geometry, e.g. a RING. This only works if it is possible and applicable.
355 \tparam Geometry1 \tparam_geometry
356 \tparam Geometry2 \tparam_geometry
357 \param geometry1 \param_geometry (target)
358 \param geometry2 \param_geometry (source)
362 [assign] [assign_output]
365 \* [link geometry.reference.algorithms.convert convert]
368 template <typename Geometry1, typename Geometry2>
369 inline void assign(Geometry1& geometry1, Geometry2 const& geometry2)
371 resolve_variant::assign<Geometry1, Geometry2>::apply(geometry1, geometry2);
375 }} // namespace boost::geometry
379 #endif // BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP