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 // Copyright (c) 2023 Adam Wulkiewicz, Lodz, Poland.
0005 
0006 // Use, modification and distribution is subject to the Boost Software License,
0007 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0008 // http://www.boost.org/LICENSE_1_0.txt)
0009 
0010 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_JOIN_ROUND_HPP
0011 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_JOIN_ROUND_HPP
0012 
0013 #include <boost/range/value_type.hpp>
0014 
0015 #include <boost/geometry/core/radian_access.hpp>
0016 
0017 #include <boost/geometry/srs/spheroid.hpp>
0018 #include <boost/geometry/strategies/buffer.hpp>
0019 #include <boost/geometry/strategies/geographic/buffer_helper.hpp>
0020 #include <boost/geometry/strategies/geographic/parameters.hpp>
0021 #include <boost/geometry/util/math.hpp>
0022 #include <boost/geometry/util/select_calculation_type.hpp>
0023 
0024 
0025 namespace boost { namespace geometry
0026 {
0027 
0028 namespace strategy { namespace buffer
0029 {
0030 
0031 template
0032 <
0033     typename FormulaPolicy = strategy::andoyer,
0034     typename Spheroid = srs::spheroid<double>,
0035     typename CalculationType = void
0036 >
0037 class geographic_join_round
0038 {
0039 public :
0040 
0041     //! \brief Constructs the strategy with a spheroid
0042     //! \param spheroid The spheroid to be used
0043     //! \param points_per_circle Number of points (minimum 4) that would be used for a full circle
0044     explicit inline geographic_join_round(Spheroid const& spheroid,
0045                                           std::size_t points_per_circle = default_points_per_circle)
0046         : m_spheroid(spheroid)
0047         , m_points_per_circle(get_point_count_for_join(points_per_circle))
0048     {}
0049 
0050     //! \brief Constructs the strategy
0051     //! \param points_per_circle Number of points (minimum 4) that would be used for a full circle
0052     explicit inline geographic_join_round(std::size_t points_per_circle = default_points_per_circle)
0053         : m_points_per_circle(get_point_count_for_join(points_per_circle))
0054     {}
0055 
0056 #ifndef DOXYGEN_SHOULD_SKIP_THIS
0057     //! Fills output_range with a rounded shape around a vertex
0058     template <typename Point, typename DistanceType, typename RangeOut>
0059     inline bool apply(Point const& /*ip*/, Point const& vertex,
0060                       Point const& perp1, Point const& perp2,
0061                       DistanceType const& buffer_distance,
0062                       RangeOut& range_out) const
0063     {
0064         using calc_t = typename select_calculation_type
0065             <
0066                 Point,
0067                 typename boost::range_value<RangeOut>::type,
0068                 CalculationType
0069             >::type;
0070 
0071         using helper = geographic_buffer_helper<FormulaPolicy, calc_t>;
0072 
0073         calc_t const lon_rad = get_as_radian<0>(vertex);
0074         calc_t const lat_rad = get_as_radian<1>(vertex);
0075 
0076         calc_t first_azimuth;
0077         calc_t angle_diff;
0078         if (! helper::calculate_angles(lon_rad, lat_rad, perp1, perp2, m_spheroid,
0079                                        angle_diff, first_azimuth))
0080         {
0081             return false;
0082         }
0083 
0084         static calc_t const two_pi = geometry::math::two_pi<calc_t>();
0085         calc_t const circle_fraction = angle_diff / two_pi;
0086         std::size_t const n = (std::max)(static_cast<std::size_t>(
0087             std::ceil(m_points_per_circle * circle_fraction)), std::size_t(1));
0088 
0089         calc_t const diff = angle_diff / static_cast<calc_t>(n);
0090         calc_t azi = math::wrap_azimuth_in_radian(first_azimuth + diff);
0091 
0092         range_out.push_back(perp1);
0093 
0094         // Generate points between 0 and n, not including them
0095         // because perp1 and perp2 are inserted before and after this range.
0096         for (std::size_t i = 1; i < n; i++)
0097         {
0098             helper::append_point(lon_rad, lat_rad, buffer_distance, azi, m_spheroid, range_out);
0099             azi = math::wrap_azimuth_in_radian(azi + diff);
0100         }
0101 
0102         range_out.push_back(perp2);
0103         return true;
0104     }
0105 
0106     template <typename NumericType>
0107     static inline NumericType max_distance(NumericType const& distance)
0108     {
0109         return distance;
0110     }
0111 
0112 #endif // DOXYGEN_SHOULD_SKIP_THIS
0113 
0114 private :
0115     Spheroid m_spheroid;
0116     std::size_t m_points_per_circle;
0117 };
0118 
0119 }} // namespace strategy::buffer
0120 
0121 }} // namespace boost::geometry
0122 
0123 #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_BUFFER_JOIN_ROUND_HPP