1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
5
6 // This file was modified by Oracle on 2017, 2018.
7 // Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
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 #if defined(_MSC_VER)
16 #pragma warning( disable : 4305 ) // truncation double -> float
17 #endif // defined(_MSC_VER)
18
19 #include <geometry_test_common.hpp>
20
21 #include <boost/geometry/srs/projection.hpp>
22
23 #include <boost/geometry/core/coordinate_type.hpp>
24 #include <boost/geometry/algorithms/make.hpp>
25
26 #include <boost/geometry.hpp>
27 #include <boost/geometry/geometries/geometries.hpp>
28 #include <boost/geometry/geometries/point_xy.hpp>
29
30
31 template <template <typename, typename> class Projection, typename GeoPoint>
test_forward(GeoPoint const & geo_point1,GeoPoint const & geo_point2,std::string const & sparams,int deviation=1)32 void test_forward(GeoPoint const& geo_point1, GeoPoint const& geo_point2,
33 std::string const& sparams, int deviation = 1)
34 {
35 typedef typename bg::coordinate_type<GeoPoint>::type coordinate_type;
36 typedef bg::model::d2::point_xy<coordinate_type> cartesian_point_type;
37 typedef bg::projections::parameters<double> parameters_type;
38 typedef bg::projections::detail::static_wrapper_f
39 <
40 Projection<coordinate_type, parameters_type>,
41 parameters_type
42 > projection_type;
43
44 try
45 {
46 bg::srs::detail::proj4_parameters params(sparams);
47 parameters_type par = bg::projections::detail::pj_init<double>(params);
48
49 projection_type prj(params, par);
50
51 cartesian_point_type xy1, xy2;
52 prj.forward(geo_point1, xy1);
53 prj.forward(geo_point2, xy2);
54
55 // Calculate distances in KM
56 int const distance_expected = static_cast<int>(bg::distance(geo_point1, geo_point2) / 1000.0);
57 int const distance_found = static_cast<int>(bg::distance(xy1, xy2) / 1000.0);
58
59 int const difference = std::abs(distance_expected - distance_found);
60 BOOST_CHECK_MESSAGE(difference <= 1 || difference == deviation,
61 " projection: " << projection_type::get_name()
62 << " distance found: " << distance_found
63 << " expected: " << distance_expected);
64
65 // For debug:
66 // std::cout << projection_type::get_name() << " " << distance_expected
67 // << " " << distance_found
68 // << " " << (difference > 1 && difference != deviation ? " *** WRONG ***" : "")
69 // << " " << difference
70 // << std::endl;
71 }
72 catch(bg::projection_exception const& e)
73 {
74 std::cout << "Exception in " << projection_type::get_name() << " : " << e.what() << std::endl;
75 }
76 catch(...)
77 {
78 std::cout << "Exception (unknown) in " << projection_type::get_name() << std::endl;
79 }
80 }
81
82 template <typename T>
test_all()83 void test_all()
84 {
85 typedef bg::model::point<T, 2, bg::cs::geographic<bg::degree> > geo_point_type;
86
87 geo_point_type amsterdam = bg::make<geo_point_type>(4.8925, 52.3731);
88 geo_point_type utrecht = bg::make<geo_point_type>(5.1213, 52.0907);
89
90 // IMPORTANT: Compatible model has to be passed in order to assure correct initialization
91
92 test_forward<bg::projections::aea_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m +lat_1=55 +lat_2=65");
93 test_forward<bg::projections::aeqd_e>(amsterdam, utrecht, "+ellps=WGS84 +units=m");
94 test_forward<bg::projections::aeqd_s>(amsterdam, utrecht, "+ellps=sphere +units=m");
95
96 test_forward<bg::projections::airy_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 4);
97 test_forward<bg::projections::aitoff_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
98 test_forward<bg::projections::apian_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lon_0=11d32'00E");
99 test_forward<bg::projections::august_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 14);
100
101 test_forward<bg::projections::bacon_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lon_0=11d32'00E", 5);
102 test_forward<bg::projections::bipc_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 7);
103 test_forward<bg::projections::boggs_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lon_0=11d32'00E", 2);
104
105 test_forward<bg::projections::bonne_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m +lat_1=50");
106 test_forward<bg::projections::bonne_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lat_1=50", 33);
107
108 test_forward<bg::projections::cass_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m");
109 test_forward<bg::projections::cass_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
110 test_forward<bg::projections::cc_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 52);
111
112 test_forward<bg::projections::cea_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m +lon_0=11d32'00E", 4);
113 test_forward<bg::projections::cea_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lon_0=11d32'00E", 4);
114
115 test_forward<bg::projections::chamb_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lat_1=52 +lon_1=5 +lat_2=30 +lon_2=80 +lat_3=20 +lon_3=-50", 2);
116 test_forward<bg::projections::collg_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 5);
117 test_forward<bg::projections::crast_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
118 test_forward<bg::projections::denoy_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
119 test_forward<bg::projections::eck1_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
120 test_forward<bg::projections::eck2_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
121 test_forward<bg::projections::eck3_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
122 test_forward<bg::projections::eck4_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
123 test_forward<bg::projections::eck5_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
124
125 test_forward<bg::projections::eck6_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
126
127 test_forward<bg::projections::eqc_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 5);
128 test_forward<bg::projections::eqdc_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m +lat_1=60 +lat_2=0");
129 test_forward<bg::projections::etmerc_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m");
130 test_forward<bg::projections::euler_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lat_1=60 +lat_2=0");
131
132 test_forward<bg::projections::fahey_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 5);
133 test_forward<bg::projections::fouc_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 6);
134 test_forward<bg::projections::fouc_s_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 4);
135 test_forward<bg::projections::gall_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
136 test_forward<bg::projections::geocent_other>(amsterdam, utrecht, "+ellps=WGS84 +units=m", 5);
137 test_forward<bg::projections::geos_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +h=40000000", 13);
138 test_forward<bg::projections::gins8_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 7);
139
140 test_forward<bg::projections::gn_sinu_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +m=0.5 +n=1.785");
141
142 test_forward<bg::projections::gnom_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 50);
143 test_forward<bg::projections::goode_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
144 test_forward<bg::projections::gstmerc_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
145 test_forward<bg::projections::hammer_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
146 test_forward<bg::projections::hatano_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
147
148 test_forward<bg::projections::healpix_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m", 6);
149 test_forward<bg::projections::healpix_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 6);
150 test_forward<bg::projections::rhealpix_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m", 6);
151 test_forward<bg::projections::rhealpix_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 6);
152
153 test_forward<bg::projections::imw_p_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m +lat_1=20n +lat_2=60n +lon_1=5");
154 test_forward<bg::projections::isea_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
155 test_forward<bg::projections::kav5_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
156 test_forward<bg::projections::kav7_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
157 test_forward<bg::projections::krovak_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m");
158 test_forward<bg::projections::laea_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
159 test_forward<bg::projections::lagrng_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +W=1", 8);
160 test_forward<bg::projections::larr_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 13);
161 test_forward<bg::projections::lask_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 5);
162 test_forward<bg::projections::lcc_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m +lat_1=20n +lat_2=60n", 2);
163 test_forward<bg::projections::lcca_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m +lat_0=30n +lat_1=55n +lat_2=60n", 2);
164 test_forward<bg::projections::leac_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m", 8);
165 test_forward<bg::projections::loxim_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 3);
166 test_forward<bg::projections::lsat_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m +lsat=1 +path=1", 3);
167 test_forward<bg::projections::mbt_fps_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
168 test_forward<bg::projections::mbt_s_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
169 test_forward<bg::projections::mbtfpp_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
170 test_forward<bg::projections::mbtfpq_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
171
172 test_forward<bg::projections::mbtfps_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
173
174 test_forward<bg::projections::merc_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m", 22);
175 test_forward<bg::projections::merc_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 22);
176
177 test_forward<bg::projections::mil_os_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m");
178 test_forward<bg::projections::mill_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 14);
179 test_forward<bg::projections::moll_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
180 test_forward<bg::projections::murd1_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lat_1=20n +lat_2=60n");
181 test_forward<bg::projections::murd2_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lat_1=20n +lat_2=60n");
182 test_forward<bg::projections::murd3_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lat_1=20n +lat_2=60n");
183 test_forward<bg::projections::natearth_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
184 test_forward<bg::projections::nell_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 4);
185 test_forward<bg::projections::nell_h_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 3);
186 test_forward<bg::projections::nicol_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
187
188 test_forward<bg::projections::oea_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lat_1=20n +lat_2=60n +lon_1=1e +lon_2=30e +m=1 +n=1", 4);
189 test_forward<bg::projections::omerc_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m +lat_1=20n +lat_2=60n +lon_1=1e +lon_2=30e");
190 test_forward<bg::projections::ortel_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
191 test_forward<bg::projections::ortho_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 9);
192 test_forward<bg::projections::pconic_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lat_1=20n +lat_2=60n +lon_0=10E");
193 test_forward<bg::projections::qsc_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m", 10);
194 test_forward<bg::projections::poly_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
195 test_forward<bg::projections::putp1_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
196 test_forward<bg::projections::putp2_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
197 test_forward<bg::projections::putp3_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 6);
198 test_forward<bg::projections::putp3p_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 5);
199 test_forward<bg::projections::putp4p_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
200 test_forward<bg::projections::putp5_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
201 test_forward<bg::projections::putp5p_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 3);
202 test_forward<bg::projections::putp6_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
203 test_forward<bg::projections::putp6p_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
204 test_forward<bg::projections::qua_aut_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
205 test_forward<bg::projections::robin_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
206 test_forward<bg::projections::rouss_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m", 8);
207 test_forward<bg::projections::rpoly_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
208
209 test_forward<bg::projections::sinu_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m");
210 test_forward<bg::projections::sinu_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
211
212 test_forward<bg::projections::somerc_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m", 22);
213 test_forward<bg::projections::stere_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lat_ts=50n", 8);
214 test_forward<bg::projections::sterea_ellipsoid>(amsterdam, utrecht, "+lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +units=m");
215 test_forward<bg::projections::tcc_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
216 test_forward<bg::projections::tcea_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
217 test_forward<bg::projections::tissot_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lat_1=20n +lat_2=60n", 2);
218
219 test_forward<bg::projections::tmerc_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
220 test_forward<bg::projections::tmerc_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m");
221
222 test_forward<bg::projections::tpeqd_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lat_1=20n +lat_2=60n +lon_1=0 +lon_2=30e");
223 test_forward<bg::projections::tpers_spheroid>(amsterdam, utrecht, "+ellps=WGS84 +units=m +tilt=50 +azi=20 +h=40000000", 14);
224
225 // Elliptical usage required
226 // TODO: if spherical UPS is not supported then ups_spheroid should be removed
227 //test_forward<bg::projections::ups_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 3);
228 test_forward<bg::projections::ups_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m", 3);
229
230 test_forward<bg::projections::urm5_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +n=.3 +q=.3 +alpha=10", 4);
231 test_forward<bg::projections::urmfps_spheroid>(amsterdam, utrecht, "+ellps=WGS84 +units=m +n=0.50", 4);
232
233 test_forward<bg::projections::utm_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m +lon_0=11d32'00E");
234
235 test_forward<bg::projections::vandg_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 13);
236 test_forward<bg::projections::vandg2_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 13);
237 test_forward<bg::projections::vandg3_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 13);
238 test_forward<bg::projections::vandg4_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
239 test_forward<bg::projections::vitk1_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m +lat_1=20n +lat_2=60n");
240 test_forward<bg::projections::wag1_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
241 test_forward<bg::projections::wag2_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
242 test_forward<bg::projections::wag3_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 3);
243 test_forward<bg::projections::wag4_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
244 test_forward<bg::projections::wag5_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
245 test_forward<bg::projections::wag6_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
246 test_forward<bg::projections::wag7_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 2);
247 test_forward<bg::projections::weren_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 4);
248 test_forward<bg::projections::wink1_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 3);
249 test_forward<bg::projections::wink2_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m", 4);
250 test_forward<bg::projections::wintri_spheroid>(amsterdam, utrecht, "+ellps=sphere +units=m");
251
252 // We SKIP ob_tran because it internally requires the factory and is, in that sense, not a static test
253 // test_forward<bg::projections::ob_tran_oblique>(amsterdam, utrecht, "+ellps=WGS84 +units=m +o_proj=moll +o_lat_p=10 +o_lon_p=90 +o_lon_o=11.50");
254 // test_forward<bg::projections::ob_tran_transverse>(amsterdam, utrecht, "+ellps=WGS84 +units=m +o_proj=moll +o_lat_p=10 +o_lon_p=90 +o_lon_o=11.50");
255
256 // TODO: wrong projections or parameters or input points
257 // test_forward<bg::projections::ocea_spheroid>(auckland, wellington, "+ellps=sphere +units=m +lat_1=20s +lat_2=60s +lon_1=165e +lon_2=175e"); => distance is very large
258 // test_forward<bg::projections::nsper_spheroid>(amsterdam, utrecht, "+ellps=WGS84 +units=m +a=10 +h=40000000"); => distance is 0
259 // test_forward<bg::projections::lee_os_ellipsoid>(amsterdam, utrecht, "+ellps=WGS84 +units=m"); => distance is 407
260
261
262 // Alaska
263 {
264 geo_point_type anchorage = bg::make<geo_point_type>(-149.90, 61.22);
265 geo_point_type juneau = bg::make<geo_point_type>(-134.42, 58.30);
266 test_forward<bg::projections::alsk_ellipsoid>(anchorage, juneau, "+ellps=WGS84 +units=m +lon_0=-150W", 1);
267 }
268 // New Zealand
269 {
270 geo_point_type auckland = bg::make<geo_point_type>(174.74, -36.84);
271 geo_point_type wellington = bg::make<geo_point_type>(177.78, -41.29);
272 test_forward<bg::projections::nzmg_ellipsoid>(auckland, wellington, "+ellps=WGS84 +units=m", 0);
273 }
274
275 // US
276 {
277 geo_point_type aspen = bg::make<geo_point_type>(-106.84, 39.19);
278 geo_point_type denver = bg::make<geo_point_type>(-104.88, 39.76);
279 // TODO: test_forward<bg::projections::gs48_ellipsoid>(aspen, denver, "+ellps=WGS84 +units=m +lon1=-48");=> distance is > 1000
280 test_forward<bg::projections::gs50_ellipsoid>(aspen, denver, "+ellps=WGS84 +units=m +lon1=-50", 2);
281 }
282
283 }
284
test_main(int,char * [])285 int test_main(int, char* [])
286 {
287 test_all<double>();
288
289 return 0;
290 }
291