File indexing completed on 2025-01-18 09:36:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP
0012 #define BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP
0013
0014 #include <cstddef>
0015 #include <type_traits>
0016
0017 #include <boost/numeric/conversion/cast.hpp>
0018
0019 #include <boost/geometry/core/access.hpp>
0020 #include <boost/geometry/core/coordinate_system.hpp>
0021 #include <boost/geometry/core/coordinate_type.hpp>
0022 #include <boost/geometry/core/cs.hpp>
0023 #include <boost/geometry/core/tag.hpp>
0024 #include <boost/geometry/core/tags.hpp>
0025
0026 #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
0027 #include <boost/geometry/util/normalize_spheroidal_box_coordinates.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, boost::numeric_cast
0061 <
0062 typename coordinate_type<PointOut>::type
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, boost::numeric_cast
0094 <
0095 typename coordinate_type<PointOut>::type
0096 >(longitude));
0097
0098 assign_loop
0099 <
0100 1, DimensionCount
0101 >::apply(longitude, latitude, point_in, point_out);
0102 }
0103 };
0104
0105 template <std::size_t DimensionCount>
0106 struct assign_loop<1, DimensionCount>
0107 {
0108 template <typename CoordinateType, typename PointIn, typename PointOut>
0109 static inline void apply(CoordinateType const& longitude,
0110 CoordinateType const& latitude,
0111 PointIn const& point_in,
0112 PointOut& point_out)
0113 {
0114 geometry::set<1>(point_out, boost::numeric_cast
0115 <
0116 typename coordinate_type<PointOut>::type
0117 >(latitude));
0118
0119 assign_loop
0120 <
0121 2, DimensionCount
0122 >::apply(longitude, latitude, point_in, point_out);
0123 }
0124 };
0125
0126
0127 template <typename PointIn, typename PointOut, bool IsEquatorial = true>
0128 struct normalize_point
0129 {
0130 static inline void apply(PointIn const& point_in, PointOut& point_out)
0131 {
0132 typedef typename coordinate_type<PointIn>::type in_coordinate_type;
0133
0134 in_coordinate_type longitude = geometry::get<0>(point_in);
0135 in_coordinate_type latitude = geometry::get<1>(point_in);
0136
0137 math::normalize_spheroidal_coordinates
0138 <
0139 typename geometry::detail::cs_angular_units<PointIn>::type,
0140 IsEquatorial,
0141 in_coordinate_type
0142 >(longitude, latitude);
0143
0144 assign_loop
0145 <
0146 0, dimension<PointIn>::value
0147 >::apply(longitude, latitude, point_in, point_out);
0148 }
0149 };
0150
0151
0152 template <typename BoxIn, typename BoxOut, bool IsEquatorial = true>
0153 class normalize_box
0154 {
0155 template <typename UnitsIn, typename UnitsOut, typename CoordinateInType>
0156 static inline void apply_to_coordinates(CoordinateInType& lon_min,
0157 CoordinateInType& lat_min,
0158 CoordinateInType& lon_max,
0159 CoordinateInType& lat_max,
0160 BoxIn const& box_in,
0161 BoxOut& box_out)
0162 {
0163 geometry::detail::indexed_point_view<BoxOut, min_corner> p_min_out(box_out);
0164 assign_loop
0165 <
0166 0, dimension<BoxIn>::value
0167 >::apply(lon_min,
0168 lat_min,
0169 geometry::detail::indexed_point_view
0170 <
0171 BoxIn const, min_corner
0172 >(box_in),
0173 p_min_out);
0174
0175 geometry::detail::indexed_point_view<BoxOut, max_corner> p_max_out(box_out);
0176 assign_loop
0177 <
0178 0, dimension<BoxIn>::value
0179 >::apply(lon_max,
0180 lat_max,
0181 geometry::detail::indexed_point_view
0182 <
0183 BoxIn const, max_corner
0184 >(box_in),
0185 p_max_out);
0186 }
0187
0188 public:
0189 static inline void apply(BoxIn const& box_in, BoxOut& box_out)
0190 {
0191 typedef typename coordinate_type<BoxIn>::type in_coordinate_type;
0192
0193 in_coordinate_type lon_min = geometry::get<min_corner, 0>(box_in);
0194 in_coordinate_type lat_min = geometry::get<min_corner, 1>(box_in);
0195 in_coordinate_type lon_max = geometry::get<max_corner, 0>(box_in);
0196 in_coordinate_type lat_max = geometry::get<max_corner, 1>(box_in);
0197
0198 math::normalize_spheroidal_box_coordinates
0199 <
0200 typename geometry::detail::cs_angular_units<BoxIn>::type,
0201 IsEquatorial,
0202 in_coordinate_type
0203 >(lon_min, lat_min, lon_max, lat_max);
0204
0205 apply_to_coordinates
0206 <
0207 typename geometry::detail::cs_angular_units<BoxIn>::type,
0208 typename geometry::detail::cs_angular_units<BoxOut>::type
0209 >(lon_min, lat_min, lon_max, lat_max, box_in, box_out);
0210 }
0211 };
0212
0213
0214 }
0215 #endif
0216
0217 struct cartesian_point
0218 : detail::do_nothing
0219 {};
0220
0221 struct cartesian_box
0222 : detail::do_nothing
0223 {};
0224
0225 struct spherical_point
0226 {
0227 template <typename PointIn, typename PointOut>
0228 static inline void apply(PointIn const& point_in, PointOut& point_out)
0229 {
0230 detail::normalize_point
0231 <
0232 PointIn, PointOut,
0233 (! std::is_same
0234 <
0235 typename cs_tag<PointIn>::type,
0236 spherical_polar_tag
0237 >::value)
0238 >::apply(point_in, point_out);
0239 }
0240 };
0241
0242 struct spherical_box
0243 {
0244 template <typename BoxIn, typename BoxOut>
0245 static inline void apply(BoxIn const& box_in, BoxOut& box_out)
0246 {
0247 detail::normalize_box
0248 <
0249 BoxIn, BoxOut,
0250 (! std::is_same
0251 <
0252 typename cs_tag<BoxIn>::type,
0253 spherical_polar_tag
0254 >::value)
0255 >::apply(box_in, box_out);
0256 }
0257 };
0258
0259 }}
0260
0261 }}
0262
0263 #endif