File indexing completed on 2025-02-22 10:06:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_MAPPING_SSF_HPP
0015 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_MAPPING_SSF_HPP
0016
0017
0018 #include <boost/core/ignore_unused.hpp>
0019
0020 #include <boost/geometry/core/coordinate_promotion.hpp>
0021 #include <boost/geometry/core/radius.hpp>
0022
0023 #include <boost/geometry/util/math.hpp>
0024 #include <boost/geometry/util/select_calculation_type.hpp>
0025
0026 #include <boost/geometry/strategies/side.hpp>
0027 #include <boost/geometry/strategies/spherical/ssf.hpp>
0028
0029
0030 namespace boost { namespace geometry
0031 {
0032
0033 namespace strategy { namespace side
0034 {
0035
0036
0037
0038
0039
0040
0041 enum mapping_type { mapping_geodetic, mapping_reduced, mapping_geocentric };
0042
0043
0044 #ifndef DOXYGEN_NO_DETAIL
0045 namespace detail
0046 {
0047
0048 template <typename Spheroid, mapping_type Mapping>
0049 struct mapper
0050 {
0051 explicit inline mapper(Spheroid const& ) {}
0052
0053 template <typename CalculationType>
0054 static inline CalculationType const& apply(CalculationType const& lat)
0055 {
0056 return lat;
0057 }
0058 };
0059
0060 template <typename Spheroid>
0061 struct mapper<Spheroid, mapping_reduced>
0062 {
0063 typedef typename promote_floating_point
0064 <
0065 typename radius_type<Spheroid>::type
0066 >::type fraction_type;
0067
0068 explicit inline mapper(Spheroid const& spheroid)
0069 {
0070 fraction_type const a = geometry::get_radius<0>(spheroid);
0071 fraction_type const b = geometry::get_radius<2>(spheroid);
0072 b_div_a = b / a;
0073 }
0074
0075 template <typename CalculationType>
0076 inline CalculationType apply(CalculationType const& lat) const
0077 {
0078 return atan(static_cast<CalculationType>(b_div_a) * tan(lat));
0079 }
0080
0081 fraction_type b_div_a;
0082 };
0083
0084 template <typename Spheroid>
0085 struct mapper<Spheroid, mapping_geocentric>
0086 {
0087 typedef typename promote_floating_point
0088 <
0089 typename radius_type<Spheroid>::type
0090 >::type fraction_type;
0091
0092 explicit inline mapper(Spheroid const& spheroid)
0093 {
0094 fraction_type const a = geometry::get_radius<0>(spheroid);
0095 fraction_type const b = geometry::get_radius<2>(spheroid);
0096 sqr_b_div_a = b / a;
0097 sqr_b_div_a *= sqr_b_div_a;
0098 }
0099
0100 template <typename CalculationType>
0101 inline CalculationType apply(CalculationType const& lat) const
0102 {
0103 return atan(static_cast<CalculationType>(sqr_b_div_a) * tan(lat));
0104 }
0105
0106 fraction_type sqr_b_div_a;
0107 };
0108
0109 }
0110 #endif
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 template <typename Spheroid,
0124 mapping_type Mapping = mapping_geodetic,
0125 typename CalculationType = void>
0126 class mapping_spherical_side_formula
0127 {
0128
0129 public :
0130 inline mapping_spherical_side_formula()
0131 : m_mapper(Spheroid())
0132 {}
0133
0134 explicit inline mapping_spherical_side_formula(Spheroid const& spheroid)
0135 : m_mapper(spheroid)
0136 {}
0137
0138 template <typename P1, typename P2, typename P>
0139 inline int apply(P1 const& p1, P2 const& p2, P const& p) const
0140 {
0141 typedef typename promote_floating_point
0142 <
0143 typename select_calculation_type_alt
0144 <
0145 CalculationType,
0146 P1, P2, P
0147 >::type
0148 >::type calculation_type;
0149
0150 calculation_type lon1 = get_as_radian<0>(p1);
0151 calculation_type lat1 = m_mapper.template apply<calculation_type>(get_as_radian<1>(p1));
0152 calculation_type lon2 = get_as_radian<0>(p2);
0153 calculation_type lat2 = m_mapper.template apply<calculation_type>(get_as_radian<1>(p2));
0154 calculation_type lon = get_as_radian<0>(p);
0155 calculation_type lat = m_mapper.template apply<calculation_type>(get_as_radian<1>(p));
0156
0157 return detail::spherical_side_formula(lon1, lat1, lon2, lat2, lon, lat);
0158 }
0159
0160 private:
0161 side::detail::mapper<Spheroid, Mapping> const m_mapper;
0162 };
0163
0164
0165 template <typename Spheroid,
0166 typename CalculationType>
0167 class mapping_spherical_side_formula<Spheroid, mapping_geodetic, CalculationType>
0168 {
0169
0170 public :
0171 inline mapping_spherical_side_formula() {}
0172 explicit inline mapping_spherical_side_formula(Spheroid const& ) {}
0173
0174 template <typename P1, typename P2, typename P>
0175 static inline int apply(P1 const& p1, P2 const& p2, P const& p)
0176 {
0177 return spherical_side_formula<CalculationType>::apply(p1, p2, p);
0178 }
0179 };
0180
0181 }}
0182
0183 }}
0184
0185 #endif