1 // Boost.Geometry 2 3 // Copyright (c) 2018, Oracle and/or its affiliates. 4 5 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle 6 7 // Licensed under the Boost Software License version 1.0. 8 // http://www.boost.org/users/license.html 9 10 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_LINE_INTERPOLATE_HPP 11 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_LINE_INTERPOLATE_HPP 12 13 #include <boost/geometry/core/assert.hpp> 14 #include <boost/geometry/core/coordinate_dimension.hpp> 15 #include <boost/geometry/core/coordinate_type.hpp> 16 #include <boost/geometry/core/radian_access.hpp> 17 #include <boost/geometry/srs/spheroid.hpp> 18 #include <boost/geometry/strategies/line_interpolate.hpp> 19 #include <boost/geometry/strategies/geographic/parameters.hpp> 20 #include <boost/geometry/util/select_calculation_type.hpp> 21 22 23 namespace boost { namespace geometry 24 { 25 26 namespace strategy { namespace line_interpolate 27 { 28 29 30 /*! 31 \brief Interpolate point on a geographic segment. 32 \ingroup strategies 33 \tparam FormulaPolicy The geodesic formulas used internally. 34 \tparam Spheroid The spheroid model. 35 \tparam CalculationType \tparam_calculation 36 37 \qbk{ 38 [heading See also] 39 \* [link geometry.reference.algorithms.line_interpolate.line_interpolate_4_with_strategy line_interpolate (with strategy)] 40 \* [link geometry.reference.srs.srs_spheroid srs::spheroid] 41 } 42 */ 43 template 44 < 45 typename FormulaPolicy = strategy::andoyer, 46 typename Spheroid = srs::spheroid<double>, 47 typename CalculationType = void 48 > 49 class geographic 50 { 51 public: geographic()52 geographic() 53 : m_spheroid() 54 {} 55 geographic(Spheroid const & spheroid)56 explicit geographic(Spheroid const& spheroid) 57 : m_spheroid(spheroid) 58 {} 59 60 // point-point strategy getters 61 struct distance_pp_strategy 62 { 63 typedef distance::geographic<FormulaPolicy, Spheroid, CalculationType> type; 64 }; 65 get_distance_pp_strategy() const66 inline typename distance_pp_strategy::type get_distance_pp_strategy() const 67 { 68 typedef typename distance_pp_strategy::type distance_type; 69 return distance_type(m_spheroid); 70 } 71 72 template <typename Point, typename Fraction, typename Distance> apply(Point const & p0,Point const & p1,Fraction const & fraction,Point & p,Distance const & distance) const73 inline void apply(Point const& p0, 74 Point const& p1, 75 Fraction const& fraction, //fraction of segment 76 Point & p, 77 Distance const& distance) const 78 { 79 typedef typename select_calculation_type_alt 80 < 81 CalculationType, 82 Point 83 >::type calc_t; 84 85 typedef typename FormulaPolicy::template inverse 86 <calc_t, false, true, false, false, false> inverse_t; 87 88 calc_t azimuth = inverse_t::apply(get_as_radian<0>(p0), get_as_radian<1>(p0), 89 get_as_radian<0>(p1), get_as_radian<1>(p1), 90 m_spheroid).azimuth; 91 92 typedef typename FormulaPolicy::template direct 93 <calc_t, true, false, false, false> direct_t; 94 95 typename direct_t::result_type 96 dir_r = direct_t::apply(get_as_radian<0>(p0), get_as_radian<1>(p0), 97 distance * fraction, azimuth, 98 m_spheroid); 99 100 set_from_radian<0>(p, dir_r.lon2); 101 set_from_radian<1>(p, dir_r.lat2); 102 } 103 104 private: 105 Spheroid m_spheroid; 106 }; 107 108 109 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS 110 namespace services 111 { 112 113 template <> 114 struct default_strategy<geographic_tag> 115 { 116 typedef strategy::line_interpolate::geographic<> type; 117 }; 118 119 120 } // namespace services 121 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS 122 123 124 }} // namespace strategy::line_interpolate 125 126 127 }} // namespace boost::geometry 128 129 #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_LINE_INTERPOLATE_HPP 130