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>
28 #include <boost/variant/apply_visitor.hpp>
29 #include <boost/variant/static_visitor.hpp>
30 #include <boost/variant/variant_fwd.hpp>
32 #include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
33 #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
34 #include <boost/geometry/algorithms/detail/assign_values.hpp>
35 #include <boost/geometry/algorithms/convert.hpp>
36 #include <boost/geometry/algorithms/append.hpp>
37 #include <boost/geometry/algorithms/clear.hpp>
38 #include <boost/geometry/arithmetic/arithmetic.hpp>
39 #include <boost/geometry/core/access.hpp>
40 #include <boost/geometry/core/exterior_ring.hpp>
41 #include <boost/geometry/core/tags.hpp>
43 #include <boost/geometry/geometries/concepts/check.hpp>
45 #include <boost/geometry/util/for_each_coordinate.hpp>
47 namespace boost { namespace geometry
51 \brief Assign a range of points to a linestring, ring or polygon
52 \note The point-type of the range might be different from the point-type of the geometry
54 \tparam Geometry \tparam_geometry
55 \tparam Range \tparam_range_point
56 \param geometry \param_geometry
57 \param range \param_range_point
61 [note Assign automatically clears the geometry before assigning (use append if you don't want that)]
63 [assign_points] [assign_points_output]
66 \* [link geometry.reference.algorithms.append append]
69 template <typename Geometry, typename Range>
70 inline void assign_points(Geometry& geometry, Range const& range)
72 concepts::check<Geometry>();
75 geometry::append(geometry, range, -1, 0);
80 \brief assign to a box inverse infinite
81 \details The assign_inverse function initialize a 2D or 3D box with large coordinates, the
82 min corner is very large, the max corner is very small. This is a convenient starting point to
83 collect the minimum bounding box of a geometry.
85 \tparam Geometry \tparam_geometry
86 \param geometry \param_geometry
90 [assign_inverse] [assign_inverse_output]
93 \* [link geometry.reference.algorithms.make.make_inverse make_inverse]
96 template <typename Geometry>
97 inline void assign_inverse(Geometry& geometry)
99 concepts::check<Geometry>();
101 dispatch::assign_inverse
103 typename tag<Geometry>::type,
109 \brief assign zero values to a box, point
111 \details The assign_zero function initializes a 2D or 3D point or box with coordinates of zero
112 \tparam Geometry \tparam_geometry
113 \param geometry \param_geometry
116 template <typename Geometry>
117 inline void assign_zero(Geometry& geometry)
119 concepts::check<Geometry>();
121 dispatch::assign_zero
123 typename tag<Geometry>::type,
129 \brief Assign two coordinates to a geometry (usually a 2D point)
131 \tparam Geometry \tparam_geometry
132 \tparam Type \tparam_numeric to specify the coordinates
133 \param geometry \param_geometry
137 \qbk{distinguish, 2 coordinate values}
140 [assign_2d_point] [assign_2d_point_output]
143 \* [link geometry.reference.algorithms.make.make_2_2_coordinate_values make]
146 template <typename Geometry, typename Type>
147 inline void assign_values(Geometry& geometry, Type const& c1, Type const& c2)
149 concepts::check<Geometry>();
153 typename tag<Geometry>::type,
155 geometry::dimension<Geometry>::type::value
156 >::apply(geometry, c1, c2);
160 \brief Assign three values to a geometry (usually a 3D point)
162 \tparam Geometry \tparam_geometry
163 \tparam Type \tparam_numeric to specify the coordinates
164 \param geometry \param_geometry
169 \qbk{distinguish, 3 coordinate values}
172 [assign_3d_point] [assign_3d_point_output]
175 \* [link geometry.reference.algorithms.make.make_3_3_coordinate_values make]
178 template <typename Geometry, typename Type>
179 inline void assign_values(Geometry& geometry,
180 Type const& c1, Type const& c2, Type const& c3)
182 concepts::check<Geometry>();
186 typename tag<Geometry>::type,
188 geometry::dimension<Geometry>::type::value
189 >::apply(geometry, c1, c2, c3);
193 \brief Assign four values to a geometry (usually a box or segment)
195 \tparam Geometry \tparam_geometry
196 \tparam Type \tparam_numeric to specify the coordinates
197 \param geometry \param_geometry
198 \param c1 First coordinate (usually x1)
199 \param c2 Second coordinate (usually y1)
200 \param c3 Third coordinate (usually x2)
201 \param c4 Fourth coordinate (usually y2)
203 \qbk{distinguish, 4 coordinate values}
205 template <typename Geometry, typename Type>
206 inline void assign_values(Geometry& geometry,
207 Type const& c1, Type const& c2, Type const& c3, Type const& c4)
209 concepts::check<Geometry>();
213 typename tag<Geometry>::type,
215 geometry::dimension<Geometry>::type::value
216 >::apply(geometry, c1, c2, c3, c4);
221 namespace resolve_variant
224 template <typename Geometry1, typename Geometry2>
228 apply(Geometry1& geometry1, const Geometry2& geometry2)
230 concepts::check<Geometry1>();
231 concepts::check<Geometry2 const>();
232 concepts::check_concepts_and_equal_dimensions<Geometry1, Geometry2 const>();
234 static bool const same_point_order
235 = point_order<Geometry1>::value == point_order<Geometry2>::value;
239 ASSIGN_IS_NOT_SUPPORTED_FOR_DIFFERENT_POINT_ORDER,
240 (types<Geometry1, Geometry2>)
242 static bool const same_closure
243 = closure<Geometry1>::value == closure<Geometry2>::value;
247 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 boost::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 boost::apply_visitor(visitor(geometry1), geometry2);
320 template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
321 struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
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(T1)>& geometry1,
341 variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
343 return boost::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