1 // Boost.Geometry (aka GGL, Generic Geometry Library) 2 3 // Copyright (c) 2007-2016 Barend Gehrels, Amsterdam, the Netherlands. 4 5 // This file was modified by Oracle on 2014-2017. 6 // Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. 7 8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle 9 10 // Use, modification and distribution is subject to the Boost Software License, 11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 12 // http://www.boost.org/LICENSE_1_0.txt) 13 14 15 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP 16 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP 17 18 19 #include <boost/geometry/core/coordinate_type.hpp> 20 #include <boost/geometry/core/radian_access.hpp> 21 #include <boost/geometry/core/radius.hpp> 22 #include <boost/geometry/core/srs.hpp> 23 24 #include <boost/geometry/formulas/andoyer_inverse.hpp> 25 #include <boost/geometry/formulas/flattening.hpp> 26 27 #include <boost/geometry/strategies/distance.hpp> 28 #include <boost/geometry/strategies/geographic/parameters.hpp> 29 30 #include <boost/geometry/util/math.hpp> 31 #include <boost/geometry/util/promote_floating_point.hpp> 32 #include <boost/geometry/util/select_calculation_type.hpp> 33 34 35 namespace boost { namespace geometry 36 { 37 38 namespace strategy { namespace distance 39 { 40 41 template 42 < 43 typename FormulaPolicy = strategy::andoyer, 44 typename Spheroid = srs::spheroid<double>, 45 typename CalculationType = void 46 > 47 class geographic 48 { 49 public : 50 template <typename Point1, typename Point2> 51 struct calculation_type 52 : promote_floating_point 53 < 54 typename select_calculation_type 55 < 56 Point1, 57 Point2, 58 CalculationType 59 >::type 60 > 61 {}; 62 63 typedef Spheroid model_type; 64 geographic()65 inline geographic() 66 : m_spheroid() 67 {} 68 geographic(Spheroid const & spheroid)69 explicit inline geographic(Spheroid const& spheroid) 70 : m_spheroid(spheroid) 71 {} 72 73 template <typename Point1, typename Point2> 74 inline typename calculation_type<Point1, Point2>::type apply(Point1 const & point1,Point2 const & point2) const75 apply(Point1 const& point1, Point2 const& point2) const 76 { 77 return FormulaPolicy::template inverse 78 < 79 typename calculation_type<Point1, Point2>::type, 80 true, false, false, false, false 81 >::apply(get_as_radian<0>(point1), get_as_radian<1>(point1), 82 get_as_radian<0>(point2), get_as_radian<1>(point2), 83 m_spheroid).distance; 84 } 85 model() const86 inline Spheroid const& model() const 87 { 88 return m_spheroid; 89 } 90 91 private : 92 Spheroid m_spheroid; 93 }; 94 95 96 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS 97 namespace services 98 { 99 100 template 101 < 102 typename FormulaPolicy, 103 typename Spheroid, 104 typename CalculationType 105 > 106 struct tag<geographic<FormulaPolicy, Spheroid, CalculationType> > 107 { 108 typedef strategy_tag_distance_point_point type; 109 }; 110 111 112 template 113 < 114 typename FormulaPolicy, 115 typename Spheroid, 116 typename CalculationType, 117 typename P1, 118 typename P2 119 > 120 struct return_type<geographic<FormulaPolicy, Spheroid, CalculationType>, P1, P2> 121 : geographic<FormulaPolicy, Spheroid, CalculationType>::template calculation_type<P1, P2> 122 {}; 123 124 125 template 126 < 127 typename FormulaPolicy, 128 typename Spheroid, 129 typename CalculationType 130 > 131 struct comparable_type<geographic<FormulaPolicy, Spheroid, CalculationType> > 132 { 133 typedef geographic<FormulaPolicy, Spheroid, CalculationType> type; 134 }; 135 136 137 template 138 < 139 typename FormulaPolicy, 140 typename Spheroid, 141 typename CalculationType 142 > 143 struct get_comparable<geographic<FormulaPolicy, Spheroid, CalculationType> > 144 { 145 static inline geographic<FormulaPolicy, Spheroid, CalculationType> applyboost::geometry::strategy::distance::services::get_comparable146 apply(geographic<FormulaPolicy, Spheroid, CalculationType> const& input) 147 { 148 return input; 149 } 150 }; 151 152 template 153 < 154 typename FormulaPolicy, 155 typename Spheroid, 156 typename CalculationType, 157 typename P1, 158 typename P2 159 > 160 struct result_from_distance<geographic<FormulaPolicy, Spheroid, CalculationType>, P1, P2> 161 { 162 template <typename T> 163 static inline typename return_type<geographic<FormulaPolicy, Spheroid, CalculationType>, P1, P2>::type applyboost::geometry::strategy::distance::services::result_from_distance164 apply(geographic<FormulaPolicy, Spheroid, CalculationType> const& , T const& value) 165 { 166 return value; 167 } 168 }; 169 170 171 template <typename Point1, typename Point2> 172 struct default_strategy<point_tag, point_tag, Point1, Point2, geographic_tag, geographic_tag> 173 { 174 typedef strategy::distance::geographic 175 < 176 strategy::andoyer, 177 srs::spheroid 178 < 179 typename select_coordinate_type<Point1, Point2>::type 180 > 181 > type; 182 }; 183 184 185 } // namespace services 186 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS 187 188 189 }} // namespace strategy::distance 190 191 192 }} // namespace boost::geometry 193 194 195 #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_HPP 196