Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:19

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