Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / geometry / strategies / geographic / distance.hpp
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
65     inline geographic()
66         : m_spheroid()
67     {}
68
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
75     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
86     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>
146         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
164         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