Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 08:43:00

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
0004 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
0005 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
0006 // Copyright (c) 2014 Samuel Debionne, Grenoble, France.
0007 // Copyright (c) 2024 Adam Wulkiewicz, Lodz, Poland.
0008 
0009 // This file was modified by Oracle on 2020-2023.
0010 // Modifications copyright (c) 2020-2023 Oracle and/or its affiliates.
0011 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0012 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0013 
0014 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
0015 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
0016 
0017 // Use, modification and distribution is subject to the Boost Software License,
0018 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0019 // http://www.boost.org/LICENSE_1_0.txt)
0020 
0021 #ifndef BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
0022 #define BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP
0023 
0024 #include <boost/variant/static_visitor.hpp>
0025 #include <boost/variant/variant_fwd.hpp>
0026 
0027 #include <boost/geometry/algorithms/append.hpp>
0028 #include <boost/geometry/algorithms/clear.hpp>
0029 #include <boost/geometry/algorithms/convert.hpp>
0030 
0031 #include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
0032 #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
0033 #include <boost/geometry/algorithms/detail/assign_values.hpp>
0034 
0035 #include <boost/geometry/core/static_assert.hpp>
0036 
0037 #include <boost/geometry/geometries/concepts/check.hpp>
0038 
0039 namespace boost { namespace geometry
0040 {
0041 
0042 /*!
0043 \brief Assign a range of points to a linestring, ring or polygon
0044 \note The point-type of the range might be different from the point-type of the geometry
0045 \ingroup assign
0046 \tparam Geometry \tparam_geometry
0047 \tparam Range \tparam_range_point
0048 \param geometry \param_geometry
0049 \param range \param_range_point
0050 
0051 \qbk{
0052 [heading Notes]
0053 [note Assign automatically clears the geometry before assigning (use append if you don't want that)]
0054 [heading Example]
0055 [assign_points] [assign_points_output]
0056 
0057 [heading See also]
0058 \* [link geometry.reference.algorithms.append append]
0059 }
0060  */
0061 template <typename Geometry, typename Range>
0062 inline void assign_points(Geometry& geometry, Range const& range)
0063 {
0064     concepts::check<Geometry>();
0065 
0066     clear(geometry);
0067     geometry::append(geometry, range, -1, 0);
0068 }
0069 
0070 
0071 /*!
0072 \brief assign to a box inverse infinite
0073 \details The assign_inverse function initialize a 2D or 3D box with large coordinates, the
0074 min corner is very large, the max corner is very small. This is a convenient starting point to
0075 collect the minimum bounding box of a geometry.
0076 \ingroup assign
0077 \tparam Geometry \tparam_geometry
0078 \param geometry \param_geometry
0079 
0080 \qbk{
0081 [heading Example]
0082 [assign_inverse] [assign_inverse_output]
0083 
0084 [heading See also]
0085 \* [link geometry.reference.algorithms.make.make_inverse make_inverse]
0086 }
0087  */
0088 template <typename Geometry>
0089 inline void assign_inverse(Geometry& geometry)
0090 {
0091     concepts::check<Geometry>();
0092 
0093     dispatch::assign_inverse
0094         <
0095             tag_t<Geometry>,
0096             Geometry
0097         >::apply(geometry);
0098 }
0099 
0100 /*!
0101 \brief assign zero values to a box, point
0102 \ingroup assign
0103 \details The assign_zero function initializes a 2D or 3D point or box with coordinates of zero
0104 \tparam Geometry \tparam_geometry
0105 \param geometry \param_geometry
0106 
0107  */
0108 template <typename Geometry>
0109 inline void assign_zero(Geometry& geometry)
0110 {
0111     concepts::check<Geometry>();
0112 
0113     dispatch::assign_zero
0114         <
0115             tag_t<Geometry>,
0116             Geometry
0117         >::apply(geometry);
0118 }
0119 
0120 /*!
0121 \brief Assign two coordinates to a geometry (usually a 2D point)
0122 \ingroup assign
0123 \tparam Geometry \tparam_geometry
0124 \tparam Type \tparam_numeric to specify the coordinates
0125 \param geometry \param_geometry
0126 \param c1 \param_x
0127 \param c2 \param_y
0128 
0129 \qbk{distinguish, 2 coordinate values}
0130 \qbk{
0131 [heading Example]
0132 [assign_2d_point] [assign_2d_point_output]
0133 
0134 [heading See also]
0135 \* [link geometry.reference.algorithms.make.make_2_2_coordinate_values make]
0136 }
0137  */
0138 template <typename Geometry, typename Type>
0139 inline void assign_values(Geometry& geometry, Type const& c1, Type const& c2)
0140 {
0141     concepts::check<Geometry>();
0142 
0143     dispatch::assign
0144         <
0145             tag_t<Geometry>,
0146             Geometry,
0147             geometry::dimension<Geometry>::value
0148         >::apply(geometry, c1, c2);
0149 }
0150 
0151 /*!
0152 \brief Assign three values to a geometry (usually a 3D point)
0153 \ingroup assign
0154 \tparam Geometry \tparam_geometry
0155 \tparam Type \tparam_numeric to specify the coordinates
0156 \param geometry \param_geometry
0157 \param c1 \param_x
0158 \param c2 \param_y
0159 \param c3 \param_z
0160 
0161 \qbk{distinguish, 3 coordinate values}
0162 \qbk{
0163 [heading Example]
0164 [assign_3d_point] [assign_3d_point_output]
0165 
0166 [heading See also]
0167 \* [link geometry.reference.algorithms.make.make_3_3_coordinate_values make]
0168 }
0169  */
0170 template <typename Geometry, typename Type>
0171 inline void assign_values(Geometry& geometry,
0172             Type const& c1, Type const& c2, Type const& c3)
0173 {
0174     concepts::check<Geometry>();
0175 
0176     dispatch::assign
0177         <
0178             tag_t<Geometry>,
0179             Geometry,
0180             geometry::dimension<Geometry>::value
0181         >::apply(geometry, c1, c2, c3);
0182 }
0183 
0184 /*!
0185 \brief Assign four values to a geometry (usually a box or segment)
0186 \ingroup assign
0187 \tparam Geometry \tparam_geometry
0188 \tparam Type \tparam_numeric to specify the coordinates
0189 \param geometry \param_geometry
0190 \param c1 First coordinate (usually x1)
0191 \param c2 Second coordinate (usually y1)
0192 \param c3 Third coordinate (usually x2)
0193 \param c4 Fourth coordinate (usually y2)
0194 
0195 \qbk{distinguish, 4 coordinate values}
0196  */
0197 template <typename Geometry, typename Type>
0198 inline void assign_values(Geometry& geometry,
0199                 Type const& c1, Type const& c2, Type const& c3, Type const& c4)
0200 {
0201     concepts::check<Geometry>();
0202 
0203     dispatch::assign
0204         <
0205             tag_t<Geometry>,
0206             Geometry,
0207             geometry::dimension<Geometry>::value
0208         >::apply(geometry, c1, c2, c3, c4);
0209 }
0210 
0211 
0212 
0213 namespace resolve_variant
0214 {
0215 
0216 template <typename Geometry1, typename Geometry2>
0217 struct assign
0218 {
0219     static inline void
0220     apply(Geometry1& geometry1, Geometry2 const& geometry2)
0221     {
0222         concepts::check<Geometry1>();
0223         concepts::check<Geometry2 const>();
0224         concepts::check_concepts_and_equal_dimensions<Geometry1, Geometry2 const>();
0225 
0226         static bool const same_point_order
0227             = point_order<Geometry1>::value == point_order<Geometry2>::value;
0228         BOOST_GEOMETRY_STATIC_ASSERT(
0229             same_point_order,
0230             "Assign is not supported for different point orders.",
0231             Geometry1, Geometry2);
0232         static bool const same_closure
0233             = closure<Geometry1>::value == closure<Geometry2>::value;
0234         BOOST_GEOMETRY_STATIC_ASSERT(
0235             same_closure,
0236             "Assign is not supported for different closures.",
0237             Geometry1, Geometry2);
0238 
0239         dispatch::convert<Geometry2, Geometry1>::apply(geometry2, geometry1);
0240     }
0241 };
0242 
0243 
0244 template <BOOST_VARIANT_ENUM_PARAMS(typename T), typename Geometry2>
0245 struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Geometry2>
0246 {
0247     struct visitor: static_visitor<void>
0248     {
0249         Geometry2 const& m_geometry2;
0250 
0251         visitor(Geometry2 const& geometry2)
0252         : m_geometry2(geometry2)
0253         {}
0254 
0255         template <typename Geometry1>
0256         result_type operator()(Geometry1& geometry1) const
0257         {
0258             return assign
0259             <
0260                 Geometry1,
0261                 Geometry2
0262             >::apply
0263             (geometry1, m_geometry2);
0264         }
0265     };
0266 
0267     static inline void
0268     apply(variant<BOOST_VARIANT_ENUM_PARAMS(T)>& geometry1,
0269           Geometry2 const& geometry2)
0270     {
0271         return boost::apply_visitor(visitor(geometry2), geometry1);
0272     }
0273 };
0274 
0275 
0276 template <typename Geometry1, BOOST_VARIANT_ENUM_PARAMS(typename T)>
0277 struct assign<Geometry1, variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
0278 {
0279     struct visitor: static_visitor<void>
0280     {
0281         Geometry1& m_geometry1;
0282 
0283         visitor(Geometry1 const& geometry1)
0284         : m_geometry1(geometry1)
0285         {}
0286 
0287         template <typename Geometry2>
0288         result_type operator()(Geometry2 const& geometry2) const
0289         {
0290             return assign
0291             <
0292                 Geometry1,
0293                 Geometry2
0294             >::apply
0295             (m_geometry1, geometry2);
0296         }
0297     };
0298 
0299     static inline void
0300     apply(Geometry1& geometry1,
0301           variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry2)
0302     {
0303         return boost::apply_visitor(visitor(geometry1), geometry2);
0304     }
0305 };
0306 
0307 
0308 template <BOOST_VARIANT_ENUM_PARAMS(typename T1), BOOST_VARIANT_ENUM_PARAMS(typename T2)>
0309 struct assign<variant<BOOST_VARIANT_ENUM_PARAMS(T1)>, variant<BOOST_VARIANT_ENUM_PARAMS(T2)> >
0310 {
0311     struct visitor: static_visitor<void>
0312     {
0313         template <typename Geometry1, typename Geometry2>
0314         result_type operator()(
0315                                 Geometry1& geometry1,
0316                                 Geometry2 const& geometry2) const
0317         {
0318             return assign
0319             <
0320                 Geometry1,
0321                 Geometry2
0322             >::apply
0323             (geometry1, geometry2);
0324         }
0325     };
0326 
0327     static inline void
0328     apply(variant<BOOST_VARIANT_ENUM_PARAMS(T1)>& geometry1,
0329           variant<BOOST_VARIANT_ENUM_PARAMS(T2)> const& geometry2)
0330     {
0331         return boost::apply_visitor(visitor(), geometry1, geometry2);
0332     }
0333 };
0334 
0335 } // namespace resolve_variant
0336 
0337 
0338 /*!
0339 \brief Assigns one geometry to another geometry
0340 \details The assign algorithm assigns one geometry, e.g. a BOX, to another
0341 geometry, e.g. a RING. This only works if it is possible and applicable.
0342 \ingroup assign
0343 \tparam Geometry1 \tparam_geometry
0344 \tparam Geometry2 \tparam_geometry
0345 \param geometry1 \param_geometry (target)
0346 \param geometry2 \param_geometry (source)
0347 
0348 \qbk{
0349 [heading Example]
0350 [assign] [assign_output]
0351 
0352 [heading See also]
0353 \* [link geometry.reference.algorithms.convert convert]
0354 }
0355  */
0356 template <typename Geometry1, typename Geometry2>
0357 inline void assign(Geometry1& geometry1, Geometry2 const& geometry2)
0358 {
0359     resolve_variant::assign<Geometry1, Geometry2>::apply(geometry1, geometry2);
0360 }
0361 
0362 
0363 }} // namespace boost::geometry
0364 
0365 
0366 
0367 #endif // BOOST_GEOMETRY_ALGORITHMS_ASSIGN_HPP