Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:45

0001 // Boost.Geometry
0002 
0003 // Copyright (c) 2022 Barend Gehrels, Amsterdam, the Netherlands.
0004 
0005 // Use, modification and distribution is subject to the Boost Software License,
0006 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0007 // http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_HELPER_HPP
0010 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_HELPER_HPP
0011 
0012 #include <boost/geometry/core/assert.hpp>
0013 #include <boost/geometry/core/radian_access.hpp>
0014 #include <boost/geometry/strategies/geographic/parameters.hpp>
0015 #include <boost/geometry/util/math.hpp>
0016 
0017 
0018 namespace boost { namespace geometry
0019 {
0020 
0021 namespace strategy { namespace buffer
0022 {
0023 
0024 #ifndef DOXYGEN_SHOULD_SKIP_THIS
0025 template <typename FormulaPolicy, typename CalculationType>
0026 struct geographic_buffer_helper
0027 {
0028     static bool const enable_azimuth = true;
0029     static bool const enable_coordinates = true;
0030 
0031     using inverse = typename FormulaPolicy::template inverse
0032         <
0033             CalculationType, false, enable_azimuth, false, false, false
0034         >;
0035 
0036     using direct = typename FormulaPolicy::template direct
0037         <
0038             CalculationType, enable_coordinates, false, false, false
0039         >;
0040 
0041     // Calculates the azimuth using the inverse formula, where the first point
0042     // is specified by lon/lat (for pragmatic reasons) and the second point as a point.
0043     template <typename T, typename Point, typename Spheroid>
0044     static inline CalculationType azimuth(T const& lon_rad, T const& lat_rad,
0045                                           Point const& p, Spheroid const& spheroid)
0046     {
0047         return inverse::apply(lon_rad, lat_rad, get_as_radian<0>(p), get_as_radian<1>(p), spheroid).azimuth;
0048     }
0049 
0050     // Using specified points, distance and azimuth it calculates a new point
0051     // and appends it to the range
0052     template <typename T, typename Spheroid, typename RangeOut>
0053     static inline void append_point(T const& lon_rad, T const& lat_rad,
0054                                     T const& distance, T const& angle,
0055                                     Spheroid const& spheroid, RangeOut& range_out)
0056     {
0057         using point_t = typename boost::range_value<RangeOut>::type;
0058         point_t point;
0059         auto const d = direct::apply(lon_rad, lat_rad, distance, angle, spheroid);
0060         set_from_radian<0>(point, d.lon2);
0061         set_from_radian<1>(point, d.lat2);
0062         range_out.emplace_back(point);
0063     }
0064 
0065     // Calculates the angle diff and azimuth of a point (specified as lon/lat)
0066     // and two points, perpendicular in the buffer context.
0067     template <typename T, typename Point, typename Spheroid>
0068     static inline bool calculate_angles(T const& lon_rad, T const& lat_rad, Point const& perp1,
0069                                         Point const& perp2, Spheroid const& spheroid,
0070                                         T& angle_diff, T& first_azimuth)
0071     {
0072         T const inv1 = azimuth(lon_rad, lat_rad, perp1, spheroid);
0073         T const inv2 = azimuth(lon_rad, lat_rad, perp2, spheroid);
0074 
0075         static CalculationType const two_pi = geometry::math::two_pi<CalculationType>();
0076         static CalculationType const pi = geometry::math::pi<CalculationType>();
0077 
0078         // For a sharp corner, perpendicular points are nearly opposite and the
0079         // angle between the two azimuths can be nearly 180, but not more.
0080         angle_diff = inv2 < inv1 ? (two_pi + inv2) - inv1 : inv2 - inv1;
0081 
0082         if (angle_diff < 0 || angle_diff > pi)
0083         {
0084             // Defensive check with asserts
0085             BOOST_GEOMETRY_ASSERT(angle_diff >= 0);
0086             BOOST_GEOMETRY_ASSERT(angle_diff <= pi);
0087             return false;
0088         }
0089 
0090         first_azimuth = inv1;
0091 
0092         return true;
0093     }
0094 };
0095 #endif // DOXYGEN_SHOULD_SKIP_THIS
0096 
0097 }} // namespace strategy::buffer
0098 
0099 }} // namespace boost::geometry
0100 
0101 #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_HELPER_HPP