1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // This file is manually converted from PROJ4
4 // Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
6 // This file was modified by Oracle on 2017-2020.
7 // Modifications copyright (c) 2017-2020, Oracle and/or its affiliates.
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
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)
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)
19 // Original copyright notice:
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:
28 // The above copyright notice and this permission notice shall be included
29 // in all copies or substantial portions of the Software.
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.
39 #ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_PARAM_HPP
40 #define BOOST_GEOMETRY_PROJECTIONS_PJ_PARAM_HPP
45 #include <type_traits>
48 #include <boost/geometry/core/static_assert.hpp>
50 #include <boost/geometry/srs/projections/exception.hpp>
52 #include <boost/geometry/srs/projections/impl/dms_parser.hpp>
53 #include <boost/geometry/srs/projections/impl/projects.hpp>
54 #include <boost/geometry/srs/projections/proj4.hpp>
55 #include <boost/geometry/srs/projections/dpar.hpp>
56 #include <boost/geometry/srs/projections/spar.hpp>
59 namespace boost { namespace geometry { namespace projections {
64 inline bool pj_param_pred(srs::detail::proj4_parameter const& p, std::string const& name)
66 return p.name == name;
71 typename T, typename Id,
72 std::enable_if_t<! std::is_convertible<Id, std::string>::value, int> = 0
74 inline bool pj_param_pred(srs::dpar::parameter<T> const& p, Id const& id)
76 return p.is_id_equal(id);
80 template <typename Params, typename Name>
81 inline typename Params::const_iterator
82 pj_param_find(Params const& params, Name const& name)
84 typedef typename Params::const_iterator iterator;
85 for (iterator it = params.begin(); it != params.end(); it++)
87 if (pj_param_pred(*it, name))
92 // TODO: needed for pipeline
93 /*else if (it->name == "step")
105 typename StaticParams,
106 typename IsParamPred,
107 int I = tuples_find_index_if<StaticParams, typename IsParamPred::pred>::value,
108 int N = geometry::tuples::size<StaticParams>::value
110 struct pj_param_find_static
112 typedef geometry::tuples::element<I, StaticParams> type;
113 typedef const type* result_type;
114 static result_type get(StaticParams const& params)
116 return boost::addressof(boost::get<I>(params));
120 template <typename StaticParams, typename IsParamPred, int N>
121 struct pj_param_find_static<StaticParams, IsParamPred, N>
124 typedef const type* result_type;
125 static result_type get(StaticParams const& ) { return NULL; }
130 template <typename Params, typename Name>
131 inline bool pj_param_exists(Params const& params, Name const& name)
133 return pj_param_find(params, name) != params.end();
136 template <typename Param, typename ...Ps>
137 inline bool pj_param_exists(srs::spar::parameters<Ps...> const& )
139 return geometry::tuples::is_found
141 typename geometry::tuples::find_if
143 srs::spar::parameters<Ps...>,
144 srs::spar::detail::is_param<Param>::template pred
149 template <template <typename> class Param, typename ...Ps>
150 inline bool pj_param_exists(srs::spar::parameters<Ps...> const& )
152 return geometry::tuples::is_found
154 typename geometry::tuples::find_if
156 srs::spar::parameters<Ps...>,
157 srs::spar::detail::is_param_t<Param>::template pred
163 template <typename T>
164 inline void set_value(T & val, srs::detail::proj4_parameter const& p)
166 val = geometry::str_cast<T>(p.value);
169 template <typename T, typename T2>
170 inline void set_value(T & val, srs::dpar::parameter<T2> const& p)
172 val = p.template get_value<T>();
175 template <typename T>
176 inline void set_value_r(T & val, srs::detail::proj4_parameter const& p)
178 val = dms_parser<T, true>::apply(p.value.c_str()).angle();
181 template <typename T>
182 inline void set_value_r(T & val, srs::dpar::parameter<T> const& p)
184 val = p.template get_value<T>() * math::d2r<T>();
187 template <typename Name>
188 inline void check_name(Name const&)
190 static const bool is_ok = std::is_convertible<Name, std::string>::value
191 || std::is_same<Name, srs::dpar::name_i>::value
192 || std::is_same<Name, srs::dpar::name_f>::value
193 || std::is_same<Name, srs::dpar::name_r>::value;
194 BOOST_GEOMETRY_STATIC_ASSERT((is_ok), "Invalid argument.", Name);
199 template <typename Params, typename Name>
200 inline bool _pj_param_i(Params const& params, Name const& name, int & par)
203 typename Params::const_iterator it = pj_param_find(params, name);
204 if (it != params.end())
212 /* floating point input */
213 template <typename T, typename Params, typename Name>
214 inline bool _pj_param_f(Params const& params, Name const& name, T & par)
217 typename Params::const_iterator it = pj_param_find(params, name);
218 if (it != params.end())
227 template <typename T, typename Params, typename Name>
228 inline bool _pj_param_r(Params const& params, Name const& name, T & par)
231 typename Params::const_iterator it = pj_param_find(params, name);
232 if (it != params.end())
234 set_value_r(par, *it);
241 inline bool _pj_get_param_b(srs::detail::proj4_parameters const& pl, std::string const& name)
243 srs::detail::proj4_parameters::const_iterator it = pj_param_find(pl, name);
246 switch (it->value[0])
248 case '\0': case 'T': case 't':
253 BOOST_THROW_EXCEPTION( projection_exception(error_invalid_boolean_param) );
260 template <typename T>
261 inline bool _pj_get_param_b(srs::dpar::parameters<T> const& pl, srs::dpar::name_be const& name)
264 typename srs::dpar::parameters<T>::const_iterator it = pj_param_find(pl, name);
266 set_value(result, *it);
271 inline bool pj_param_s(srs::detail::proj4_parameters const& pl, std::string const& name, std::string & par)
273 srs::detail::proj4_parameters::const_iterator it = pj_param_find(pl, name);
285 template <typename> class IsSamePred,
286 int I = geometry::tuples::find_index_if<Params, IsSamePred>::value,
287 int N = geometry::tuples::size<Params>::value
289 struct _pj_param_x_static
291 static const bool result = true;
292 template <typename T>
293 static void apply(Params const& params, T & out)
295 // TODO: int values could be extracted directly from the type
296 out = geometry::tuples::get<I>(params).value;
303 template <typename> class IsSamePred,
306 struct _pj_param_x_static<Params, IsSamePred, N, N>
308 static const bool result = false;
309 template <typename T>
310 static void apply(Params const& , T & )
314 template <template <int> class Param, typename ...Ps>
315 inline bool _pj_param_i(srs::spar::parameters<Ps...> const& params, int & par)
317 typedef _pj_param_x_static
319 srs::spar::parameters<Ps...>,
320 srs::spar::detail::is_param_i<Param>::template pred
322 impl::apply(params, par);
326 template <template <typename> class Param, typename ...Ps, typename T>
327 inline bool _pj_param_f(srs::spar::parameters<Ps...> const& params, T & par)
329 typedef _pj_param_x_static
331 srs::spar::parameters<Ps...>,
332 srs::spar::detail::is_param_t<Param>::template pred
334 impl::apply(params, par);
338 template <template <typename> class Param, typename ...Ps, typename T>
339 inline bool _pj_param_r(srs::spar::parameters<Ps...> const& params, T & par)
341 typedef _pj_param_x_static
343 srs::spar::parameters<Ps...>,
344 srs::spar::detail::is_param_t<Param>::template pred
346 impl::apply(params, par);
348 par *= math::d2r<T>();
352 template <typename Param, typename ...Ps>
353 inline bool _pj_get_param_b(srs::spar::parameters<Ps...> const& params)
355 return pj_param_exists<Param>(params);
358 //template <typename T, typename Name, typename Value>
359 //inline bool pj_param_id(srs::dpar::parameters<T> const& pl, Name const& name, Value & par)
361 // typename srs::dpar::parameters<T>::const_iterator it = pj_param_find(pl, name);
362 // if (it != pl.end())
364 // par = static_cast<Value>(it->template get_value<int>());
370 // NOTE: In the original code, in pl_ell_set.c there is a function pj_get_param
371 // which behavior is similar to pj_param but it doesn't set `user` member to TRUE
372 // while pj_param does in the original code. In Boost.Geometry this member is not used.
373 template <typename Params, typename Name>
374 inline int _pj_get_param_i(Params const& pl, Name const& name)
377 _pj_param_i(pl, name, res);
381 template <template <int> class Param, typename Params>
382 inline int _pj_get_param_i(Params const& pl)
385 _pj_param_i<Param>(pl, res);
389 template <typename T, typename Params, typename Name>
390 inline T _pj_get_param_f(Params const& pl, Name const& name)
393 _pj_param_f(pl, name, res);
397 template <typename T, template <typename> class Param, typename Params>
398 inline T _pj_get_param_f(Params const& pl)
401 _pj_param_f<Param>(pl, res);
405 template <typename T, typename Params, typename Name>
406 inline T _pj_get_param_r(Params const& pl, Name const& name)
409 _pj_param_r(pl, name, res);
413 template <typename T, template <typename> class Param, typename Params>
414 inline T _pj_get_param_r(Params const& pl)
417 _pj_param_r<Param>(pl, res);
421 inline std::string pj_get_param_s(srs::detail::proj4_parameters const& pl, std::string const& name)
424 pj_param_s(pl, name, res);
429 // ------------------------------------------------------------------------- //
431 template <typename Param, typename Name>
432 inline bool pj_param_exists(srs::detail::proj4_parameters const& pl,
433 std::string const& sn,
436 return pj_param_exists(pl, sn);
438 template <template <typename> class Param, typename Name>
439 inline bool pj_param_exists(srs::detail::proj4_parameters const& pl,
440 std::string const& sn,
443 return pj_param_exists(pl, sn);
445 template <typename Param, typename T, typename Name>
446 inline bool pj_param_exists(srs::dpar::parameters<T> const& pl,
450 return pj_param_exists(pl, n);
452 template <template <typename> class Param, typename T, typename Name>
453 inline bool pj_param_exists(srs::dpar::parameters<T> const& pl,
457 return pj_param_exists(pl, n);
459 template <typename Param, typename ...Ps, typename Name>
460 inline bool pj_param_exists(srs::spar::parameters<Ps...> const& pl,
464 return pj_param_exists<Param>(pl);
466 template <template <typename> class Param, typename ...Ps, typename Name>
467 inline bool pj_param_exists(srs::spar::parameters<Ps...> const& pl,
471 return pj_param_exists<Param>(pl);
474 template <typename Param>
475 inline bool pj_get_param_b(srs::detail::proj4_parameters const& pl,
476 std::string const& sn,
477 srs::dpar::name_be const& )
479 return _pj_get_param_b(pl, sn);
481 template <typename Param, typename T>
482 inline bool pj_get_param_b(srs::dpar::parameters<T> const& pl,
484 srs::dpar::name_be const& n)
486 return _pj_get_param_b(pl, n);
488 template <typename Param, typename ...Ps>
489 inline bool pj_get_param_b(srs::spar::parameters<Ps...> const& pl,
491 srs::dpar::name_be const& )
493 return _pj_get_param_b<Param>(pl);
496 //#define BOOST_GEOMETRY_GET_PARAM_B(PARAMS, NAME) pj_get_param_b(PARAMS, #NAME, srs::dpar::NAME)
498 template <template <int> class Param>
499 inline bool pj_param_i(srs::detail::proj4_parameters const& pl,
500 std::string const& sn,
501 srs::dpar::name_i const& ,
504 return _pj_param_i(pl, sn, par);
506 template <template <int> class Param, typename T>
507 inline bool pj_param_i(srs::dpar::parameters<T> const& pl,
509 srs::dpar::name_i const& n,
512 return _pj_param_i(pl, n, par);
514 template <template <int> class Param, typename ...Ps>
515 inline bool pj_param_i(srs::spar::parameters<Ps...> const& pl,
517 srs::dpar::name_i const& ,
520 return _pj_param_i<Param>(pl, par);
523 //#define BOOST_GEOMETRY_PARAM_I(PARAMS, NAME, PAR) pj_param_i(PARAMS, #NAME, srs::dpar::NAME, PAR)
525 template <template <int> class Param>
526 inline int pj_get_param_i(srs::detail::proj4_parameters const& pl,
527 std::string const& sn,
528 srs::dpar::name_i const& )
530 return _pj_get_param_i(pl, sn);
532 template <template <int> class Param, typename T>
533 inline int pj_get_param_i(srs::dpar::parameters<T> const& pl,
535 srs::dpar::name_i const& n)
537 return _pj_get_param_i(pl, n);
539 template <template <int> class Param, typename ...Ps>
540 inline bool pj_get_param_i(srs::spar::parameters<Ps...> const& pl,
542 srs::dpar::name_i const& )
544 return _pj_get_param_i<Param>(pl);
547 //#define BOOST_GEOMETRY_GET_PARAM_I(PARAMS, NAME) pj_get_param_i(PARAMS, #NAME, srs::dpar::NAME)
549 template <template <typename> class Param, typename T>
550 inline bool pj_param_f(srs::detail::proj4_parameters const& pl,
551 std::string const& sn,
552 srs::dpar::name_f const& ,
555 return _pj_param_f(pl, sn, par);
557 template <template <typename> class Param, typename T>
558 inline bool pj_param_f(srs::dpar::parameters<T> const& pl,
560 srs::dpar::name_f const& n,
563 return _pj_param_f(pl, n, par);
565 template <template <typename> class Param, typename ...Ps, typename T>
566 inline bool pj_param_f(srs::spar::parameters<Ps...> const& pl,
568 srs::dpar::name_f const& ,
571 return _pj_param_f<Param>(pl, par);
574 //#define BOOST_GEOMETRY_PARAM_F(PARAMS, NAME, PAR) pj_param_f(PARAMS, #NAME, srs::dpar::NAME, PAR)
576 template <typename T, template <typename> class Param>
577 inline T pj_get_param_f(srs::detail::proj4_parameters const& pl,
578 std::string const& sn,
579 srs::dpar::name_f const& )
581 return _pj_get_param_f<T>(pl, sn);
583 template <typename T, template <typename> class Param>
584 inline T pj_get_param_f(srs::dpar::parameters<T> const& pl,
586 srs::dpar::name_f const& n)
588 return _pj_get_param_f<T>(pl, n);
590 template <typename T, template <typename> class Param, typename ...Ps>
591 inline T pj_get_param_f(srs::spar::parameters<Ps...> const& pl,
593 srs::dpar::name_f const& )
595 return _pj_get_param_f<T, Param>(pl);
599 //#define BOOST_GEOMETRY_GET_PARAM_F(PARAMS, NAME) pj_get_param_f<T>(PARAMS, #NAME, srs::dpar::NAME)
601 template <template <typename> class Param, typename T>
602 inline bool pj_param_r(srs::detail::proj4_parameters const& pl,
603 std::string const& sn,
604 srs::dpar::name_r const& ,
607 return _pj_param_r(pl, sn, par);
609 template <template <typename> class Param, typename T>
610 inline bool pj_param_r(srs::dpar::parameters<T> const& pl,
612 srs::dpar::name_r const& n,
615 return _pj_param_r(pl, n, par);
617 template <template <typename> class Param, typename ...Ps, typename T>
618 inline bool pj_param_r(srs::spar::parameters<Ps...> const& pl,
620 srs::dpar::name_r const& ,
623 return _pj_param_r<Param>(pl, par);
626 //#define BOOST_GEOMETRY_PARAM_R(PARAMS, NAME, PAR) pj_param_r(PARAMS, #NAME, srs::dpar::NAME, PAR)
628 template <typename T, template <typename> class Param>
629 inline T pj_get_param_r(srs::detail::proj4_parameters const& pl,
630 std::string const& sn,
631 srs::dpar::name_r const& )
633 return _pj_get_param_r<T>(pl, sn);
635 template <typename T, template <typename> class Param>
636 inline T pj_get_param_r(srs::dpar::parameters<T> const& pl,
638 srs::dpar::name_r const& n)
640 return _pj_get_param_r<T>(pl, n);
642 template <typename T, template <typename> class Param, typename ...Ps>
643 inline T pj_get_param_r(srs::spar::parameters<Ps...> const& pl,
645 srs::dpar::name_r const& )
647 return _pj_get_param_r<T, Param>(pl);
650 //#define BOOST_GEOMETRY_GET_PARAM_R(PARAMS, NAME) pj_get_param_r<T>(PARAMS, #NAME, srs::dpar::NAME)
652 } // namespace detail
653 }}} // namespace boost::geometry::projections