• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Geometry
2 
3 // Copyright (c) 2017 Oracle and/or its affiliates.
4 
5 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
6 
7 // Use, modification and distribution is subject to the Boost Software License,
8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 
11 #include <geometry_test_common.hpp>
12 
13 #include <boost/concept_check.hpp>
14 
15 #include <boost/geometry/srs/srs.hpp>
16 #include <boost/geometry/algorithms/assign.hpp>
17 #include <boost/geometry/geometries/point.hpp>
18 #include <boost/geometry/strategies/strategies.hpp>
19 
20 #include <test_common/test_point.hpp>
21 
22 #ifdef HAVE_TTMATH
23 #  include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
24 #endif
25 
26 typedef bg::srs::spheroid<double> stype;
27 
28 typedef bg::strategy::andoyer andoyer_formula;
29 typedef bg::strategy::thomas thomas_formula;
30 typedef bg::strategy::vincenty vincenty_formula;
31 
32 template <typename P>
non_precise_ct()33 bool non_precise_ct()
34 {
35     typedef typename bg::coordinate_type<P>::type ct;
36     return boost::is_integral<ct>::value || boost::is_float<ct>::value;
37 }
38 
39 template <typename P1, typename P2, typename FormulaPolicy>
test_distance(double lon1,double lat1,double lon2,double lat2)40 void test_distance(double lon1, double lat1, double lon2, double lat2)
41 {
42     typedef typename bg::promote_floating_point
43         <
44             typename bg::select_calculation_type<P1, P2, void>::type
45         >::type calc_t;
46 
47     calc_t tolerance = non_precise_ct<P1>() || non_precise_ct<P2>() ?
48                        5.0 : 0.001;
49 
50     P1 p1;
51     P2 p2;
52 
53     bg::assign_values(p1, lon1, lat1);
54     bg::assign_values(p2, lon2, lat2);
55 
56     // Test strategy that implements meridian distance against formula
57     // that implements general distance
58     // That may change in the future but in any case these calls must return
59     // the same result
60 
61     calc_t dist_formula = FormulaPolicy::template inverse
62             <
63                 double, true, false, false, false, false
64             >::apply(lon1 * bg::math::d2r<double>(),
65                      lat1 * bg::math::d2r<double>(),
66                      lon2 * bg::math::d2r<double>(),
67                      lat2 * bg::math::d2r<double>(),
68                      stype()).distance;
69 
70     bg::strategy::distance::geographic<FormulaPolicy, stype> strategy;
71     calc_t dist_strategy = strategy.apply(p1, p2);
72     BOOST_CHECK_CLOSE(dist_formula, dist_strategy, tolerance);
73 }
74 
75 template <typename P1, typename P2, typename FormulaPolicy>
test_distance_reverse(double lon1,double lat1,double lon2,double lat2)76 void test_distance_reverse(double lon1, double lat1,
77                            double lon2, double lat2)
78 {
79     test_distance<P1, P2, FormulaPolicy>(lon1, lat1, lon2, lat2);
80     test_distance<P1, P2, FormulaPolicy>(lon2, lat2, lon1, lat1);
81 }
82 
83 template <typename P1, typename P2, typename FormulaPolicy>
test_meridian()84 void test_meridian()
85 {
86     test_distance_reverse<P1, P2, FormulaPolicy>(0., 70., 0., 80.);
87     test_distance_reverse<P1, P2, FormulaPolicy>(0, 70, 0., -80.);
88     test_distance_reverse<P1, P2, FormulaPolicy>(0., -70., 0., 80.);
89     test_distance_reverse<P1, P2, FormulaPolicy>(0., -70., 0., -80.);
90 
91     test_distance_reverse<P1, P2, FormulaPolicy>(0., 70., 180., 80.);
92     test_distance_reverse<P1, P2, FormulaPolicy>(0., 70., 180., -80.);
93     test_distance_reverse<P1, P2, FormulaPolicy>(0., -70., 180., 80.);
94     test_distance_reverse<P1, P2, FormulaPolicy>(0., -70., 180., -80.);
95 
96     test_distance_reverse<P1, P2, FormulaPolicy>(350., 70., 170., 80.);
97     test_distance_reverse<P1, P2, FormulaPolicy>(350., 70., 170., -80.);
98     test_distance_reverse<P1, P2, FormulaPolicy>(350., -70., 170., 80.);
99     test_distance_reverse<P1, P2, FormulaPolicy>(350., -70., 170., -80.);
100 }
101 
102 template <typename P>
test_all()103 void test_all()
104 {
105     test_meridian<P, P, andoyer_formula>();
106     test_meridian<P, P, thomas_formula>();
107     test_meridian<P, P, vincenty_formula>();
108 }
109 
test_main(int,char * [])110 int test_main(int, char* [])
111 {
112     test_all<bg::model::point<double, 2, bg::cs::geographic<bg::degree> > >();
113     test_all<bg::model::point<float, 2, bg::cs::geographic<bg::degree> > >();
114     test_all<bg::model::point<int, 2, bg::cs::geographic<bg::degree> > >();
115 
116     return 0;
117 }
118