Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:06:53

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 
0003 // Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands.
0004 
0005 // This file was modified by Oracle on 2014, 2017.
0006 // Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
0007 
0008 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0009 
0010 // Use, modification and distribution is subject to the Boost Software License,
0011 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0012 // http://www.boost.org/LICENSE_1_0.txt)
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 // An enumeration type defining types of mapping of geographical
0038 // latitude to spherical latitude.
0039 // See: http://en.wikipedia.org/wiki/Great_ellipse
0040 //      http://en.wikipedia.org/wiki/Latitude#Auxiliary_latitudes
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& /*spheroid*/) {}
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 // DOXYGEN_NO_DETAIL
0111 
0112 
0113 /*!
0114 \brief Check at which side of a geographical segment a point lies
0115          left of segment (> 0), right of segment (< 0), on segment (0).
0116          The check is performed by mapping the geographical coordinates
0117          to spherical coordinates and using spherical_side_formula.
0118 \ingroup strategies
0119 \tparam Spheroid The reference spheroid model
0120 \tparam Mapping The type of mapping of geographical to spherical latitude
0121 \tparam CalculationType \tparam_calculation
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 // The specialization for geodetic latitude which can be used directly
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& /*spheroid*/) {}
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 }} // namespace strategy::side
0182 
0183 }} // namespace boost::geometry
0184 
0185 #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_MAPPING_SSF_HPP