File indexing completed on 2025-11-03 09:24:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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 }
0212 #endif
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 }}
0249
0250 }}
0251
0252 #endif