Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-03 09:24:48

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2015-2025, Oracle and/or its affiliates.
0004 
0005 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
0006 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
0007 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0008 
0009 // Licensed under the Boost Software License version 1.0.
0010 // http://www.boost.org/users/license.html
0011 
0012 #ifndef BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP
0013 #define BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP
0014 
0015 #include <cstddef>
0016 #include <type_traits>
0017 
0018 #include <boost/geometry/core/access.hpp>
0019 #include <boost/geometry/core/coordinate_system.hpp>
0020 #include <boost/geometry/core/coordinate_type.hpp>
0021 #include <boost/geometry/core/cs.hpp>
0022 #include <boost/geometry/core/tag.hpp>
0023 #include <boost/geometry/core/tags.hpp>
0024 
0025 #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
0026 #include <boost/geometry/util/normalize_spheroidal_box_coordinates.hpp>
0027 #include <boost/geometry/util/numeric_cast.hpp>
0028 
0029 #include <boost/geometry/views/detail/indexed_point_view.hpp>
0030 
0031 
0032 namespace boost { namespace geometry
0033 {
0034 
0035 namespace strategy { namespace normalize
0036 {
0037 
0038 #ifndef DOXYGEN_NO_DETAIL
0039 namespace detail
0040 {
0041 
0042 struct do_nothing
0043 {
0044     template <typename GeometryIn, typename GeometryOut>
0045     static inline void apply(GeometryIn const&, GeometryOut&)
0046     {
0047     }
0048 };
0049 
0050 
0051 template <std::size_t Dimension, std::size_t DimensionCount>
0052 struct assign_loop
0053 {
0054     template <typename CoordinateType, typename PointIn, typename PointOut>
0055     static inline void apply(CoordinateType const& longitude,
0056                              CoordinateType const& latitude,
0057                              PointIn const& point_in,
0058                              PointOut& point_out)
0059     {
0060         geometry::set<Dimension>(point_out, util::numeric_cast
0061             <
0062                 coordinate_type_t<PointOut>
0063             >(geometry::get<Dimension>(point_in)));
0064 
0065         assign_loop
0066             <
0067                 Dimension + 1, DimensionCount
0068             >::apply(longitude, latitude, point_in, point_out);
0069     }
0070 };
0071 
0072 template <std::size_t DimensionCount>
0073 struct assign_loop<DimensionCount, DimensionCount>
0074 {
0075     template <typename CoordinateType, typename PointIn, typename PointOut>
0076     static inline void apply(CoordinateType const&,
0077                              CoordinateType const&,
0078                              PointIn const&,
0079                              PointOut&)
0080     {
0081     }
0082 };
0083 
0084 template <std::size_t DimensionCount>
0085 struct assign_loop<0, DimensionCount>
0086 {
0087     template <typename CoordinateType, typename PointIn, typename PointOut>
0088     static inline void apply(CoordinateType const& longitude,
0089                              CoordinateType const& latitude,
0090                              PointIn const& point_in,
0091                              PointOut& point_out)
0092     {
0093         geometry::set<0>(point_out, util::numeric_cast<coordinate_type_t<PointOut>>(longitude));
0094 
0095         assign_loop
0096             <
0097                 1, DimensionCount
0098             >::apply(longitude, latitude, point_in, point_out);
0099     }
0100 };
0101 
0102 template <std::size_t DimensionCount>
0103 struct assign_loop<1, DimensionCount>
0104 {
0105     template <typename CoordinateType, typename PointIn, typename PointOut>
0106     static inline void apply(CoordinateType const& longitude,
0107                              CoordinateType const& latitude,
0108                              PointIn const& point_in,
0109                              PointOut& point_out)
0110     {
0111         geometry::set<1>(point_out, util::numeric_cast
0112             <
0113                 coordinate_type_t<PointOut>
0114             >(latitude));
0115 
0116         assign_loop
0117             <
0118                 2, DimensionCount
0119             >::apply(longitude, latitude, point_in, point_out);
0120     }
0121 };
0122 
0123 
0124 template <typename PointIn, typename PointOut, bool IsEquatorial = true>
0125 struct normalize_point
0126 {
0127     static inline void apply(PointIn const& point_in, PointOut& point_out, bool exact = true)
0128     {
0129         using in_coordinate_type = coordinate_type_t<PointIn>;
0130 
0131         in_coordinate_type longitude = geometry::get<0>(point_in);
0132         in_coordinate_type latitude = geometry::get<1>(point_in);
0133 
0134         math::normalize_spheroidal_coordinates
0135             <
0136                 typename geometry::detail::cs_angular_units<PointIn>::type,
0137                 IsEquatorial,
0138                 in_coordinate_type
0139             >(longitude, latitude, exact);
0140 
0141         assign_loop
0142             <
0143                 0, dimension<PointIn>::value
0144             >::apply(longitude, latitude, point_in, point_out);
0145     }
0146 };
0147 
0148 
0149 template <typename BoxIn, typename BoxOut, bool IsEquatorial = true>
0150 class normalize_box
0151 {
0152     template <typename UnitsIn, typename UnitsOut, typename CoordinateInType>
0153     static inline void apply_to_coordinates(CoordinateInType& lon_min,
0154                                             CoordinateInType& lat_min,
0155                                             CoordinateInType& lon_max,
0156                                             CoordinateInType& lat_max,
0157                                             BoxIn const& box_in,
0158                                             BoxOut& box_out)
0159     {
0160         geometry::detail::indexed_point_view<BoxOut, min_corner> p_min_out(box_out);
0161         assign_loop
0162             <
0163                 0, dimension<BoxIn>::value
0164             >::apply(lon_min,
0165                      lat_min,
0166                      geometry::detail::indexed_point_view
0167                          <
0168                              BoxIn const, min_corner
0169                          >(box_in),
0170                      p_min_out);
0171 
0172         geometry::detail::indexed_point_view<BoxOut, max_corner> p_max_out(box_out);
0173         assign_loop
0174             <
0175                 0, dimension<BoxIn>::value
0176             >::apply(lon_max,
0177                      lat_max,
0178                      geometry::detail::indexed_point_view
0179                          <
0180                              BoxIn const, max_corner
0181                          >(box_in),
0182                      p_max_out);
0183     }
0184 
0185 public:
0186     static inline void apply(BoxIn const& box_in, BoxOut& box_out)
0187     {
0188         using in_coordinate_type = coordinate_type_t<BoxIn>;
0189 
0190         in_coordinate_type lon_min = geometry::get<min_corner, 0>(box_in);
0191         in_coordinate_type lat_min = geometry::get<min_corner, 1>(box_in);
0192         in_coordinate_type lon_max = geometry::get<max_corner, 0>(box_in);
0193         in_coordinate_type lat_max = geometry::get<max_corner, 1>(box_in);
0194 
0195         math::normalize_spheroidal_box_coordinates
0196             <
0197                 typename geometry::detail::cs_angular_units<BoxIn>::type,
0198                 IsEquatorial,
0199                 in_coordinate_type
0200             >(lon_min, lat_min, lon_max, lat_max);
0201 
0202         apply_to_coordinates
0203             <
0204                 typename geometry::detail::cs_angular_units<BoxIn>::type,
0205                 typename geometry::detail::cs_angular_units<BoxOut>::type
0206             >(lon_min, lat_min, lon_max, lat_max, box_in, box_out);
0207     }
0208 };
0209 
0210 
0211 } // namespace detail
0212 #endif // DOXYGEN_NO_DETAIL
0213 
0214 struct cartesian_point
0215     : detail::do_nothing
0216 {};
0217 
0218 struct cartesian_box
0219     : detail::do_nothing
0220 {};
0221 
0222 struct spherical_point
0223 {
0224     template <typename PointIn, typename PointOut>
0225     static inline void apply(PointIn const& point_in, PointOut& point_out, bool exact = true)
0226     {
0227         detail::normalize_point
0228             <
0229                 PointIn, PointOut,
0230                 (! std::is_same<cs_tag_t<PointIn>, spherical_polar_tag>::value)
0231             >::apply(point_in, point_out, exact);
0232     }
0233 };
0234 
0235 struct spherical_box
0236 {
0237     template <typename BoxIn, typename BoxOut>
0238     static inline void apply(BoxIn const& box_in, BoxOut& box_out)
0239     {
0240         detail::normalize_box
0241             <
0242                 BoxIn, BoxOut,
0243                 (! std::is_same<cs_tag_t<BoxIn>, spherical_polar_tag>::value)
0244             >::apply(box_in, box_out);
0245     }
0246 };
0247 
0248 }} // namespace strategy::normalize
0249 
0250 }} // namespace boost::geometry
0251 
0252 #endif // BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP