File indexing completed on 2025-12-16 09:51:35
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DENSIFY_HPP
0011 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DENSIFY_HPP
0012
0013
0014 #include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
0015 #include <boost/geometry/algorithms/detail/signed_size_type.hpp>
0016 #include <boost/geometry/core/assert.hpp>
0017 #include <boost/geometry/core/coordinate_dimension.hpp>
0018 #include <boost/geometry/core/coordinate_type.hpp>
0019 #include <boost/geometry/core/radian_access.hpp>
0020 #include <boost/geometry/srs/spheroid.hpp>
0021 #include <boost/geometry/strategies/densify.hpp>
0022 #include <boost/geometry/strategies/geographic/parameters.hpp>
0023 #include <boost/geometry/util/select_most_precise.hpp>
0024
0025
0026 namespace boost { namespace geometry
0027 {
0028
0029 namespace strategy { namespace densify
0030 {
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 template
0047 <
0048 typename FormulaPolicy = strategy::andoyer,
0049 typename Spheroid = srs::spheroid<double>,
0050 typename CalculationType = void
0051 >
0052 class geographic
0053 {
0054 public:
0055 geographic()
0056 : m_spheroid()
0057 {}
0058
0059 explicit geographic(Spheroid const& spheroid)
0060 : m_spheroid(spheroid)
0061 {}
0062
0063 template <typename Point, typename AssignPolicy, typename T>
0064 inline void apply(Point const& p0, Point const& p1, AssignPolicy & policy, T const& length_threshold) const
0065 {
0066 using out_point_t = typename AssignPolicy::point_type;
0067 using calc_t = typename select_most_precise
0068 <
0069 coordinate_type_t<Point>,
0070 coordinate_type_t<out_point_t>,
0071 CalculationType
0072 >::type;
0073
0074 using direct_t = typename FormulaPolicy::template direct<calc_t, true, false, false, false>;
0075 using inverse_t = typename FormulaPolicy::template inverse<calc_t, true, true, false, false, false>;
0076
0077 typename inverse_t::result_type
0078 inv_r = inverse_t::apply(get_as_radian<0>(p0), get_as_radian<1>(p0),
0079 get_as_radian<0>(p1), get_as_radian<1>(p1),
0080 m_spheroid);
0081
0082 BOOST_GEOMETRY_ASSERT(length_threshold > T(0));
0083
0084 signed_size_type n = signed_size_type(inv_r.distance / length_threshold);
0085 if (n <= 0)
0086 return;
0087
0088 calc_t step = inv_r.distance / (n + 1);
0089
0090 calc_t current = step;
0091 for (signed_size_type i = 0 ; i < n ; ++i, current += step)
0092 {
0093 typename direct_t::result_type
0094 dir_r = direct_t::apply(get_as_radian<0>(p0), get_as_radian<1>(p0),
0095 current, inv_r.azimuth,
0096 m_spheroid);
0097
0098 out_point_t p;
0099 set_from_radian<0>(p, dir_r.lon2);
0100 set_from_radian<1>(p, dir_r.lat2);
0101 geometry::detail::conversion::point_to_point
0102 <
0103 Point, out_point_t,
0104 2, dimension<out_point_t>::value
0105 >::apply(p0, p);
0106
0107 policy.apply(p);
0108 }
0109 }
0110
0111 inline Spheroid const& model() const
0112 {
0113 return m_spheroid;
0114 }
0115
0116 private:
0117 Spheroid m_spheroid;
0118 };
0119
0120
0121 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0122 namespace services
0123 {
0124
0125 template <>
0126 struct default_strategy<geographic_tag>
0127 {
0128 typedef strategy::densify::geographic<> type;
0129 };
0130
0131
0132 }
0133 #endif
0134
0135
0136 }}
0137
0138
0139 }}
0140
0141 #endif