]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | // This file is manually converted from PROJ4 | |
3 | ||
4 | // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. | |
5 | ||
20effc67 TL |
6 | // This file was modified by Oracle on 2017-2020. |
7 | // Modifications copyright (c) 2017-2020, Oracle and/or its affiliates. | |
11fdf7f2 TL |
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 | // This file is converted from PROJ4, http://trac.osgeo.org/proj | |
15 | // PROJ4 is originally written by Gerald Evenden (then of the USGS) | |
16 | // PROJ4 is maintained by Frank Warmerdam | |
17 | // PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam) | |
18 | ||
19 | // Original copyright notice: | |
20 | ||
21 | // Permission is hereby granted, free of charge, to any person obtaining a | |
22 | // copy of this software and associated documentation files (the "Software"), | |
23 | // to deal in the Software without restriction, including without limitation | |
24 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
25 | // and/or sell copies of the Software, and to permit persons to whom the | |
26 | // Software is furnished to do so, subject to the following conditions: | |
27 | ||
28 | // The above copyright notice and this permission notice shall be included | |
29 | // in all copies or substantial portions of the Software. | |
30 | ||
31 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
32 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
33 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
34 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
35 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
36 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
37 | // DEALINGS IN THE SOFTWARE. | |
38 | ||
39 | #ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_INIT_HPP | |
40 | #define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_INIT_HPP | |
41 | ||
42 | #include <cstdlib> | |
43 | #include <string> | |
20effc67 | 44 | #include <type_traits> |
11fdf7f2 TL |
45 | #include <vector> |
46 | ||
47 | #include <boost/algorithm/string.hpp> | |
20effc67 | 48 | #include <boost/tuple/tuple.hpp> |
11fdf7f2 | 49 | |
20effc67 | 50 | #include <boost/geometry/core/static_assert.hpp> |
11fdf7f2 | 51 | |
92f5a8d4 | 52 | #include <boost/geometry/srs/projections/dpar.hpp> |
11fdf7f2 TL |
53 | #include <boost/geometry/srs/projections/impl/dms_parser.hpp> |
54 | #include <boost/geometry/srs/projections/impl/pj_datum_set.hpp> | |
55 | #include <boost/geometry/srs/projections/impl/pj_datums.hpp> | |
56 | #include <boost/geometry/srs/projections/impl/pj_ell_set.hpp> | |
57 | #include <boost/geometry/srs/projections/impl/pj_param.hpp> | |
58 | #include <boost/geometry/srs/projections/impl/pj_units.hpp> | |
59 | #include <boost/geometry/srs/projections/impl/projects.hpp> | |
60 | #include <boost/geometry/srs/projections/proj4.hpp> | |
92f5a8d4 | 61 | #include <boost/geometry/srs/projections/spar.hpp> |
11fdf7f2 | 62 | |
20effc67 TL |
63 | #include <boost/geometry/util/math.hpp> |
64 | #include <boost/geometry/util/condition.hpp> | |
65 | ||
11fdf7f2 TL |
66 | |
67 | namespace boost { namespace geometry { namespace projections | |
68 | { | |
69 | ||
70 | ||
71 | namespace detail | |
72 | { | |
73 | ||
92f5a8d4 TL |
74 | /************************************************************************/ |
75 | /* pj_init_proj() */ | |
76 | /************************************************************************/ | |
77 | ||
78 | template <typename T> | |
79 | inline void pj_init_proj(srs::detail::proj4_parameters const& params, | |
80 | parameters<T> & par) | |
11fdf7f2 | 81 | { |
92f5a8d4 TL |
82 | par.id = pj_get_param_s(params, "proj"); |
83 | } | |
11fdf7f2 | 84 | |
92f5a8d4 TL |
85 | template <typename T> |
86 | inline void pj_init_proj(srs::dpar::parameters<T> const& params, | |
87 | parameters<T> & par) | |
88 | { | |
89 | typename srs::dpar::parameters<T>::const_iterator it = pj_param_find(params, srs::dpar::proj); | |
90 | if (it != params.end()) | |
11fdf7f2 | 91 | { |
92f5a8d4 | 92 | par.id = static_cast<srs::dpar::value_proj>(it->template get_value<int>()); |
11fdf7f2 TL |
93 | } |
94 | } | |
95 | ||
20effc67 TL |
96 | template <typename T, typename ...Ps> |
97 | inline void pj_init_proj(srs::spar::parameters<Ps...> const& , | |
92f5a8d4 | 98 | parameters<T> & par) |
11fdf7f2 | 99 | { |
20effc67 | 100 | typedef srs::spar::parameters<Ps...> params_type; |
f67539c2 | 101 | typedef typename geometry::tuples::find_if |
11fdf7f2 | 102 | < |
92f5a8d4 TL |
103 | params_type, |
104 | srs::spar::detail::is_param_tr<srs::spar::detail::proj_traits>::pred | |
105 | >::type proj_type; | |
11fdf7f2 | 106 | |
f67539c2 | 107 | static const bool is_found = geometry::tuples::is_found<proj_type>::value; |
11fdf7f2 | 108 | |
20effc67 | 109 | BOOST_GEOMETRY_STATIC_ASSERT((is_found), "Projection not named.", params_type); |
92f5a8d4 TL |
110 | |
111 | par.id = srs::spar::detail::proj_traits<proj_type>::id; | |
11fdf7f2 TL |
112 | } |
113 | ||
92f5a8d4 TL |
114 | /************************************************************************/ |
115 | /* pj_init_units() */ | |
116 | /************************************************************************/ | |
117 | ||
118 | template <typename T, bool Vertical> | |
119 | inline void pj_init_units(srs::detail::proj4_parameters const& params, | |
11fdf7f2 TL |
120 | T & to_meter, |
121 | T & fr_meter, | |
122 | T const& default_to_meter, | |
123 | T const& default_fr_meter) | |
124 | { | |
125 | std::string s; | |
92f5a8d4 | 126 | std::string units = pj_get_param_s(params, Vertical ? "vunits" : "units"); |
11fdf7f2 TL |
127 | if (! units.empty()) |
128 | { | |
92f5a8d4 | 129 | static const int n = sizeof(pj_units) / sizeof(pj_units[0]); |
11fdf7f2 TL |
130 | int index = -1; |
131 | for (int i = 0; i < n && index == -1; i++) | |
132 | { | |
133 | if(pj_units[i].id == units) | |
134 | { | |
135 | index = i; | |
136 | } | |
137 | } | |
138 | ||
139 | if (index == -1) { | |
92f5a8d4 | 140 | BOOST_THROW_EXCEPTION( projection_exception(error_unknow_unit_id) ); |
11fdf7f2 TL |
141 | } |
142 | s = pj_units[index].to_meter; | |
143 | } | |
144 | ||
145 | if (s.empty()) | |
146 | { | |
92f5a8d4 | 147 | s = pj_get_param_s(params, Vertical ? "vto_meter" : "to_meter"); |
11fdf7f2 TL |
148 | } |
149 | ||
92f5a8d4 | 150 | // TODO: numerator and denominator could be taken from pj_units |
11fdf7f2 TL |
151 | if (! s.empty()) |
152 | { | |
153 | std::size_t const pos = s.find('/'); | |
154 | if (pos == std::string::npos) | |
155 | { | |
92f5a8d4 | 156 | to_meter = geometry::str_cast<T>(s); |
11fdf7f2 TL |
157 | } |
158 | else | |
159 | { | |
92f5a8d4 TL |
160 | T const numerator = geometry::str_cast<T>(s.substr(0, pos)); |
161 | T const denominator = geometry::str_cast<T>(s.substr(pos + 1)); | |
11fdf7f2 TL |
162 | if (numerator == 0.0 || denominator == 0.0) |
163 | { | |
92f5a8d4 | 164 | BOOST_THROW_EXCEPTION( projection_exception(error_unit_factor_less_than_0) ); |
11fdf7f2 TL |
165 | } |
166 | to_meter = numerator / denominator; | |
167 | } | |
168 | if (to_meter == 0.0) | |
169 | { | |
92f5a8d4 | 170 | BOOST_THROW_EXCEPTION( projection_exception(error_unit_factor_less_than_0) ); |
11fdf7f2 TL |
171 | } |
172 | fr_meter = 1. / to_meter; | |
173 | } | |
174 | else | |
175 | { | |
176 | to_meter = default_to_meter; | |
177 | fr_meter = default_fr_meter; | |
178 | } | |
179 | } | |
180 | ||
92f5a8d4 TL |
181 | template <typename T, bool Vertical> |
182 | inline void pj_init_units(srs::dpar::parameters<T> const& params, | |
183 | T & to_meter, | |
184 | T & fr_meter, | |
185 | T const& default_to_meter, | |
186 | T const& default_fr_meter) | |
187 | { | |
188 | typename srs::dpar::parameters<T>::const_iterator | |
189 | it = pj_param_find(params, Vertical ? srs::dpar::vunits : srs::dpar::units); | |
190 | if (it != params.end()) | |
191 | { | |
192 | static const int n = sizeof(pj_units) / sizeof(pj_units[0]); | |
193 | const int i = it->template get_value<int>(); | |
194 | if (i >= 0 && i < n) | |
195 | { | |
196 | T const numerator = pj_units[i].numerator; | |
197 | T const denominator = pj_units[i].denominator; | |
198 | if (numerator == 0.0 || denominator == 0.0) | |
199 | { | |
200 | BOOST_THROW_EXCEPTION( projection_exception(error_unit_factor_less_than_0) ); | |
201 | } | |
202 | to_meter = numerator / denominator; | |
203 | fr_meter = 1. / to_meter; | |
204 | } | |
205 | else | |
206 | { | |
207 | BOOST_THROW_EXCEPTION( projection_exception(error_unknow_unit_id) ); | |
208 | } | |
209 | } | |
210 | else | |
211 | { | |
212 | it = pj_param_find(params, Vertical ? srs::dpar::vto_meter : srs::dpar::to_meter); | |
213 | if (it != params.end()) | |
214 | { | |
215 | to_meter = it->template get_value<T>(); | |
216 | fr_meter = 1. / to_meter; | |
217 | } | |
218 | else | |
219 | { | |
220 | to_meter = default_to_meter; | |
221 | fr_meter = default_fr_meter; | |
222 | } | |
223 | } | |
224 | } | |
225 | ||
226 | template | |
227 | < | |
228 | typename Params, | |
229 | bool Vertical, | |
f67539c2 | 230 | int UnitsI = geometry::tuples::find_index_if |
92f5a8d4 TL |
231 | < |
232 | Params, | |
20effc67 | 233 | std::conditional_t |
92f5a8d4 TL |
234 | < |
235 | Vertical, | |
236 | srs::spar::detail::is_param_t<srs::spar::vunits>, | |
237 | srs::spar::detail::is_param_tr<srs::spar::detail::units_traits> | |
20effc67 | 238 | >::template pred |
92f5a8d4 | 239 | >::value, |
f67539c2 | 240 | int ToMeterI = geometry::tuples::find_index_if |
92f5a8d4 TL |
241 | < |
242 | Params, | |
20effc67 | 243 | std::conditional_t |
92f5a8d4 TL |
244 | < |
245 | Vertical, | |
246 | srs::spar::detail::is_param_t<srs::spar::vto_meter>, | |
247 | srs::spar::detail::is_param_t<srs::spar::to_meter> | |
20effc67 | 248 | >::template pred |
92f5a8d4 | 249 | >::value, |
20effc67 | 250 | int N = geometry::tuples::size<Params>::value |
92f5a8d4 TL |
251 | > |
252 | struct pj_init_units_static | |
253 | : pj_init_units_static<Params, Vertical, UnitsI, N, N> | |
254 | {}; | |
255 | ||
256 | template <typename Params, bool Vertical, int UnitsI, int N> | |
257 | struct pj_init_units_static<Params, Vertical, UnitsI, N, N> | |
258 | { | |
259 | static const int n = sizeof(pj_units) / sizeof(pj_units[0]); | |
260 | static const int i = srs::spar::detail::units_traits | |
261 | < | |
20effc67 | 262 | typename geometry::tuples::element<UnitsI, Params>::type |
92f5a8d4 TL |
263 | >::id; |
264 | static const bool is_valid = i >= 0 && i < n; | |
265 | ||
20effc67 | 266 | BOOST_GEOMETRY_STATIC_ASSERT((is_valid), "Unknown unit ID.", Params); |
92f5a8d4 TL |
267 | |
268 | template <typename T> | |
269 | static void apply(Params const& , | |
270 | T & to_meter, T & fr_meter, | |
271 | T const& , T const& ) | |
272 | { | |
273 | T const numerator = pj_units[i].numerator; | |
274 | T const denominator = pj_units[i].denominator; | |
275 | if (numerator == 0.0 || denominator == 0.0) | |
276 | { | |
277 | BOOST_THROW_EXCEPTION( projection_exception(error_unit_factor_less_than_0) ); | |
278 | } | |
279 | to_meter = numerator / denominator; | |
280 | fr_meter = 1. / to_meter; | |
281 | } | |
282 | }; | |
283 | ||
284 | template <typename Params, bool Vertical, int ToMeterI, int N> | |
285 | struct pj_init_units_static<Params, Vertical, N, ToMeterI, N> | |
286 | { | |
287 | template <typename T> | |
288 | static void apply(Params const& params, | |
289 | T & to_meter, T & fr_meter, | |
290 | T const& , T const& ) | |
291 | { | |
20effc67 | 292 | to_meter = geometry::tuples::get<ToMeterI>(params).value; |
92f5a8d4 TL |
293 | fr_meter = 1. / to_meter; |
294 | } | |
295 | }; | |
296 | ||
297 | template <typename Params, bool Vertical, int N> | |
298 | struct pj_init_units_static<Params, Vertical, N, N, N> | |
299 | { | |
300 | template <typename T> | |
301 | static void apply(Params const& , | |
302 | T & to_meter, T & fr_meter, | |
303 | T const& default_to_meter, T const& default_fr_meter) | |
304 | { | |
305 | to_meter = default_to_meter; | |
306 | fr_meter = default_fr_meter; | |
307 | } | |
308 | }; | |
309 | ||
20effc67 TL |
310 | template <typename T, bool Vertical, typename ...Ps> |
311 | inline void pj_init_units(srs::spar::parameters<Ps...> const& params, | |
92f5a8d4 TL |
312 | T & to_meter, |
313 | T & fr_meter, | |
314 | T const& default_to_meter, | |
315 | T const& default_fr_meter) | |
316 | { | |
317 | pj_init_units_static | |
318 | < | |
20effc67 | 319 | srs::spar::parameters<Ps...>, |
92f5a8d4 TL |
320 | Vertical |
321 | >::apply(params, to_meter, fr_meter, default_to_meter, default_fr_meter); | |
322 | } | |
323 | ||
11fdf7f2 | 324 | /************************************************************************/ |
92f5a8d4 | 325 | /* pj_init_pm() */ |
11fdf7f2 | 326 | /************************************************************************/ |
92f5a8d4 TL |
327 | |
328 | template <typename T> | |
329 | inline void pj_init_pm(srs::detail::proj4_parameters const& params, T& val) | |
11fdf7f2 | 330 | { |
92f5a8d4 TL |
331 | std::string pm = pj_get_param_s(params, "pm"); |
332 | if (! pm.empty()) | |
11fdf7f2 | 333 | { |
92f5a8d4 TL |
334 | int n = sizeof(pj_prime_meridians) / sizeof(pj_prime_meridians[0]); |
335 | for (int i = 0; i < n ; i++) | |
336 | { | |
337 | if(pj_prime_meridians[i].id == pm) | |
338 | { | |
339 | val = pj_prime_meridians[i].deg * math::d2r<T>(); | |
340 | return; | |
341 | } | |
342 | } | |
343 | ||
344 | // TODO: Is this try-catch needed? | |
345 | // In other cases the bad_str_cast exception is simply thrown | |
346 | BOOST_TRY | |
347 | { | |
348 | val = dms_parser<T, true>::apply(pm).angle(); | |
349 | return; | |
350 | } | |
351 | BOOST_CATCH(geometry::bad_str_cast const&) | |
352 | { | |
353 | BOOST_THROW_EXCEPTION( projection_exception(error_unknown_prime_meridian) ); | |
354 | } | |
355 | BOOST_CATCH_END | |
356 | } | |
357 | ||
358 | val = 0.0; | |
359 | } | |
360 | ||
361 | template <typename T> | |
362 | inline void pj_init_pm(srs::dpar::parameters<T> const& params, T& val) | |
363 | { | |
364 | typename srs::dpar::parameters<T>::const_iterator it = pj_param_find(params, srs::dpar::pm); | |
365 | if (it != params.end()) | |
366 | { | |
367 | if (it->template is_value_set<int>()) | |
368 | { | |
369 | int n = sizeof(pj_prime_meridians) / sizeof(pj_prime_meridians[0]); | |
370 | int i = it->template get_value<int>(); | |
371 | if (i >= 0 && i < n) | |
372 | { | |
373 | val = pj_prime_meridians[i].deg * math::d2r<T>(); | |
374 | return; | |
375 | } | |
376 | else | |
377 | { | |
378 | BOOST_THROW_EXCEPTION( projection_exception(error_unknown_prime_meridian) ); | |
379 | } | |
380 | } | |
381 | else if (it->template is_value_set<T>()) | |
382 | { | |
383 | val = it->template get_value<T>() * math::d2r<T>(); | |
384 | return; | |
385 | } | |
11fdf7f2 TL |
386 | } |
387 | ||
92f5a8d4 TL |
388 | val = 0.0; |
389 | } | |
390 | ||
391 | template | |
392 | < | |
393 | typename Params, | |
f67539c2 | 394 | int I = geometry::tuples::find_index_if |
92f5a8d4 TL |
395 | < |
396 | Params, | |
397 | srs::spar::detail::is_param_tr<srs::spar::detail::pm_traits>::pred | |
398 | >::value, | |
20effc67 | 399 | int N = geometry::tuples::size<Params>::value |
92f5a8d4 TL |
400 | > |
401 | struct pj_init_pm_static | |
402 | { | |
403 | template <typename T> | |
404 | static void apply(Params const& params, T & val) | |
11fdf7f2 | 405 | { |
20effc67 | 406 | typedef typename geometry::tuples::element<I, Params>::type param_type; |
92f5a8d4 | 407 | |
20effc67 | 408 | val = srs::spar::detail::pm_traits<param_type>::value(geometry::tuples::get<I>(params)); |
11fdf7f2 | 409 | } |
92f5a8d4 TL |
410 | }; |
411 | template <typename Params, int N> | |
412 | struct pj_init_pm_static<Params, N, N> | |
413 | { | |
414 | template <typename T> | |
415 | static void apply(Params const& , T & val) | |
416 | { | |
417 | val = 0; | |
418 | } | |
419 | }; | |
420 | ||
20effc67 TL |
421 | template <typename T, typename ...Ps> |
422 | inline void pj_init_pm(srs::spar::parameters<Ps...> const& params, T& val) | |
92f5a8d4 TL |
423 | { |
424 | pj_init_pm_static | |
425 | < | |
20effc67 | 426 | srs::spar::parameters<Ps...> |
92f5a8d4 TL |
427 | >::apply(params, val); |
428 | } | |
429 | ||
430 | /************************************************************************/ | |
431 | /* pj_init() */ | |
432 | /* */ | |
433 | /* Main entry point for initialing a PJ projections */ | |
434 | /* definition. */ | |
435 | /************************************************************************/ | |
436 | template <typename T, typename Params> | |
437 | inline parameters<T> pj_init(Params const& params) | |
438 | { | |
439 | parameters<T> pin; | |
11fdf7f2 TL |
440 | |
441 | // find projection -> implemented in projection factory | |
92f5a8d4 | 442 | pj_init_proj(params, pin); |
11fdf7f2 TL |
443 | // exception thrown in projection<> |
444 | // TODO: consider throwing here both projection_unknown_id_exception and | |
445 | // projection_not_named_exception in order to throw before other exceptions | |
446 | //if (pin.name.empty()) | |
447 | //{ BOOST_THROW_EXCEPTION( projection_not_named_exception() ); } | |
448 | ||
92f5a8d4 TL |
449 | // NOTE: proj4 gets defaults from "proj_def.dat". |
450 | // In Boost.Geometry this is emulated by manually setting them in | |
451 | // pj_ell_init and projections aea, lcc and lagrng | |
452 | ||
11fdf7f2 | 453 | /* set datum parameters */ |
92f5a8d4 | 454 | pj_datum_init(params, pin); |
11fdf7f2 TL |
455 | |
456 | /* set ellipsoid/sphere parameters */ | |
92f5a8d4 | 457 | pj_ell_init(params, pin.a, pin.es); |
11fdf7f2 TL |
458 | |
459 | pin.a_orig = pin.a; | |
460 | pin.es_orig = pin.es; | |
461 | ||
462 | pin.e = sqrt(pin.es); | |
463 | pin.ra = 1. / pin.a; | |
464 | pin.one_es = 1. - pin.es; | |
465 | if (pin.one_es == 0.) { | |
92f5a8d4 | 466 | BOOST_THROW_EXCEPTION( projection_exception(error_eccentricity_is_one) ); |
11fdf7f2 TL |
467 | } |
468 | pin.rone_es = 1./pin.one_es; | |
469 | ||
470 | /* Now that we have ellipse information check for WGS84 datum */ | |
92f5a8d4 | 471 | if( pin.datum_type == datum_3param |
11fdf7f2 TL |
472 | && pin.datum_params[0] == 0.0 |
473 | && pin.datum_params[1] == 0.0 | |
474 | && pin.datum_params[2] == 0.0 | |
475 | && pin.a == 6378137.0 | |
476 | && geometry::math::abs(pin.es - 0.006694379990) < 0.000000000050 )/*WGS84/GRS80*/ | |
477 | { | |
92f5a8d4 | 478 | pin.datum_type = datum_wgs84; |
11fdf7f2 TL |
479 | } |
480 | ||
481 | /* set pin.geoc coordinate system */ | |
92f5a8d4 | 482 | pin.geoc = (pin.es && pj_get_param_b<srs::spar::geoc>(params, "geoc", srs::dpar::geoc)); |
11fdf7f2 TL |
483 | |
484 | /* over-ranging flag */ | |
92f5a8d4 | 485 | pin.over = pj_get_param_b<srs::spar::over>(params, "over", srs::dpar::over); |
11fdf7f2 TL |
486 | |
487 | /* longitude center for wrapping */ | |
92f5a8d4 | 488 | pin.is_long_wrap_set = pj_param_r<srs::spar::lon_wrap>(params, "lon_wrap", srs::dpar::lon_wrap, pin.long_wrap_center); |
11fdf7f2 TL |
489 | |
490 | /* central meridian */ | |
92f5a8d4 | 491 | pin.lam0 = pj_get_param_r<T, srs::spar::lon_0>(params, "lon_0", srs::dpar::lon_0); |
11fdf7f2 TL |
492 | |
493 | /* central latitude */ | |
92f5a8d4 | 494 | pin.phi0 = pj_get_param_r<T, srs::spar::lat_0>(params, "lat_0", srs::dpar::lat_0); |
11fdf7f2 TL |
495 | |
496 | /* false easting and northing */ | |
92f5a8d4 TL |
497 | pin.x0 = pj_get_param_f<T, srs::spar::x_0>(params, "x_0", srs::dpar::x_0); |
498 | pin.y0 = pj_get_param_f<T, srs::spar::y_0>(params, "y_0", srs::dpar::y_0); | |
11fdf7f2 TL |
499 | |
500 | /* general scaling factor */ | |
92f5a8d4 TL |
501 | if (pj_param_f<srs::spar::k_0>(params, "k_0", srs::dpar::k_0, pin.k0)) { |
502 | /* empty */ | |
503 | } else if (pj_param_f<srs::spar::k>(params, "k", srs::dpar::k, pin.k0)) { | |
504 | /* empty */ | |
505 | } else | |
11fdf7f2 TL |
506 | pin.k0 = 1.; |
507 | if (pin.k0 <= 0.) { | |
92f5a8d4 | 508 | BOOST_THROW_EXCEPTION( projection_exception(error_k_less_than_zero) ); |
11fdf7f2 TL |
509 | } |
510 | ||
511 | /* set units */ | |
92f5a8d4 TL |
512 | pj_init_units<T, false>(params, pin.to_meter, pin.fr_meter, 1., 1.); |
513 | pj_init_units<T, true>(params, pin.vto_meter, pin.vfr_meter, pin.to_meter, pin.fr_meter); | |
11fdf7f2 TL |
514 | |
515 | /* prime meridian */ | |
92f5a8d4 | 516 | pj_init_pm(params, pin.from_greenwich); |
11fdf7f2 TL |
517 | |
518 | return pin; | |
519 | } | |
520 | ||
11fdf7f2 TL |
521 | |
522 | } // namespace detail | |
523 | }}} // namespace boost::geometry::projections | |
524 | ||
525 | #endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_INIT_HPP |