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, 2018.
7 // Modifications copyright (c) 2017-2018, 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
46 #include <boost/geometry/srs/projections/exception.hpp>
48 #include <boost/geometry/srs/projections/impl/dms_parser.hpp>
49 #include <boost/geometry/srs/projections/impl/projects.hpp>
50 #include <boost/geometry/srs/projections/proj4.hpp>
51 #include <boost/geometry/srs/projections/dpar.hpp>
52 #include <boost/geometry/srs/projections/spar.hpp>
54 #include <boost/mpl/assert.hpp>
55 #include <boost/type_traits/is_integral.hpp>
56 #include <boost/type_traits/is_same.hpp>
60 namespace boost { namespace geometry { namespace projections {
65 inline bool pj_param_pred(srs::detail::proj4_parameter const& p, std::string const& name)
67 return p.name == name;
70 template <typename T, typename Id>
71 inline bool pj_param_pred(srs::dpar::parameter<T> const& p, Id const& id,
72 typename boost::disable_if_c<boost::is_convertible<Id, std::string>::value>::type * = 0)
74 return p.is_id_equal(id);
78 template <typename Params, typename Name>
79 inline typename Params::const_iterator
80 pj_param_find(Params const& params, Name const& name)
82 typedef typename Params::const_iterator iterator;
83 for (iterator it = params.begin(); it != params.end(); it++)
85 if (pj_param_pred(*it, name))
90 // TODO: needed for pipeline
91 /*else if (it->name == "step")
103 typename StaticParams,
104 typename IsParamPred,
105 int I = tuples_find_index_if<StaticParams, typename IsParamPred::pred>::value,
106 int N = boost::tuples::length<StaticParams>::value
108 struct pj_param_find_static
110 typedef boost::tuples::element<I, StaticParams> type;
111 typedef const type* result_type;
112 static result_type get(StaticParams const& params)
114 return boost::addressof(boost::get<I>(params));
118 template <typename StaticParams, typename IsParamPred, int N>
119 struct pj_param_find_static<StaticParams, IsParamPred, N>
122 typedef const type* result_type;
123 static result_type get(StaticParams const& ) { return NULL; }
128 template <typename Params, typename Name>
129 inline bool pj_param_exists(Params const& params, Name const& name)
131 return pj_param_find(params, name) != params.end();
134 template <typename Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
135 inline bool pj_param_exists(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& )
137 return srs::spar::detail::tuples_is_found
139 typename srs::spar::detail::tuples_find_if
141 srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>,
142 srs::spar::detail::is_param<Param>::template pred
147 template <template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
148 inline bool pj_param_exists(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& )
150 return srs::spar::detail::tuples_is_found
152 typename srs::spar::detail::tuples_find_if
154 srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>,
155 srs::spar::detail::is_param_t<Param>::template pred
161 template <typename T>
162 inline void set_value(T & val, srs::detail::proj4_parameter const& p)
164 val = geometry::str_cast<T>(p.value);
167 template <typename T, typename T2>
168 inline void set_value(T & val, srs::dpar::parameter<T2> const& p)
170 val = p.template get_value<T>();
173 template <typename T>
174 inline void set_value_r(T & val, srs::detail::proj4_parameter const& p)
176 val = dms_parser<T, true>::apply(p.value.c_str()).angle();
179 template <typename T>
180 inline void set_value_r(T & val, srs::dpar::parameter<T> const& p)
182 val = p.template get_value<T>() * math::d2r<T>();
185 template <typename Name>
186 inline void check_name(Name const&)
188 static const bool is_ok = boost::is_convertible<Name, std::string>::value
189 || boost::is_same<Name, srs::dpar::name_i>::value
190 || boost::is_same<Name, srs::dpar::name_f>::value
191 || boost::is_same<Name, srs::dpar::name_r>::value;
192 BOOST_MPL_ASSERT_MSG((is_ok), INVALID_ARGUMENT, (Name));
197 template <typename Params, typename Name>
198 inline bool _pj_param_i(Params const& params, Name const& name, int & par)
201 typename Params::const_iterator it = pj_param_find(params, name);
202 if (it != params.end())
210 /* floating point input */
211 template <typename T, typename Params, typename Name>
212 inline bool _pj_param_f(Params const& params, Name const& name, T & par)
215 typename Params::const_iterator it = pj_param_find(params, name);
216 if (it != params.end())
225 template <typename T, typename Params, typename Name>
226 inline bool _pj_param_r(Params const& params, Name const& name, T & par)
229 typename Params::const_iterator it = pj_param_find(params, name);
230 if (it != params.end())
232 set_value_r(par, *it);
239 inline bool _pj_get_param_b(srs::detail::proj4_parameters const& pl, std::string const& name)
241 srs::detail::proj4_parameters::const_iterator it = pj_param_find(pl, name);
244 switch (it->value[0])
246 case '\0': case 'T': case 't':
251 BOOST_THROW_EXCEPTION( projection_exception(error_invalid_boolean_param) );
258 template <typename T>
259 inline bool _pj_get_param_b(srs::dpar::parameters<T> const& pl, srs::dpar::name_be const& name)
262 typename srs::dpar::parameters<T>::const_iterator it = pj_param_find(pl, name);
264 set_value(result, *it);
269 inline bool pj_param_s(srs::detail::proj4_parameters const& pl, std::string const& name, std::string & par)
271 srs::detail::proj4_parameters::const_iterator it = pj_param_find(pl, name);
283 template <typename> class IsSamePred,
284 int I = srs::spar::detail::tuples_find_index_if<Params, IsSamePred>::value,
285 int N = boost::tuples::length<Params>::value
287 struct _pj_param_x_static
289 static const bool result = true;
290 template <typename T>
291 static void apply(Params const& params, T & out)
293 // TODO: int values could be extracted directly from the type
294 out = boost::tuples::get<I>(params).value;
301 template <typename> class IsSamePred,
304 struct _pj_param_x_static<Params, IsSamePred, N, N>
306 static const bool result = false;
307 template <typename T>
308 static void apply(Params const& , T & )
312 template <template <int> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
313 inline bool _pj_param_i(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params, int & par)
315 typedef _pj_param_x_static
317 srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>,
318 srs::spar::detail::is_param_i<Param>::template pred
320 impl::apply(params, par);
324 template <template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename T>
325 inline bool _pj_param_f(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params, T & par)
327 typedef _pj_param_x_static
329 srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>,
330 srs::spar::detail::is_param_t<Param>::template pred
332 impl::apply(params, par);
336 template <template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename T>
337 inline bool _pj_param_r(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params, T & par)
339 typedef _pj_param_x_static
341 srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>,
342 srs::spar::detail::is_param_t<Param>::template pred
344 impl::apply(params, par);
346 par *= math::d2r<T>();
350 template <typename Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
351 inline bool _pj_get_param_b(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params)
353 return pj_param_exists<Param>(params);
356 //template <typename T, typename Name, typename Value>
357 //inline bool pj_param_id(srs::dpar::parameters<T> const& pl, Name const& name, Value & par)
359 // typename srs::dpar::parameters<T>::const_iterator it = pj_param_find(pl, name);
360 // if (it != pl.end())
362 // par = static_cast<Value>(it->template get_value<int>());
368 // NOTE: In the original code, in pl_ell_set.c there is a function pj_get_param
369 // which behavior is similar to pj_param but it doesn't set `user` member to TRUE
370 // while pj_param does in the original code. In Boost.Geometry this member is not used.
371 template <typename Params, typename Name>
372 inline int _pj_get_param_i(Params const& pl, Name const& name)
375 _pj_param_i(pl, name, res);
379 template <template <int> class Param, typename Params>
380 inline int _pj_get_param_i(Params const& pl)
383 _pj_param_i<Param>(pl, res);
387 template <typename T, typename Params, typename Name>
388 inline T _pj_get_param_f(Params const& pl, Name const& name)
391 _pj_param_f(pl, name, res);
395 template <typename T, template <typename> class Param, typename Params>
396 inline T _pj_get_param_f(Params const& pl)
399 _pj_param_f<Param>(pl, res);
403 template <typename T, typename Params, typename Name>
404 inline T _pj_get_param_r(Params const& pl, Name const& name)
407 _pj_param_r(pl, name, res);
411 template <typename T, template <typename> class Param, typename Params>
412 inline T _pj_get_param_r(Params const& pl)
415 _pj_param_r<Param>(pl, res);
419 inline std::string pj_get_param_s(srs::detail::proj4_parameters const& pl, std::string const& name)
422 pj_param_s(pl, name, res);
427 // ------------------------------------------------------------------------- //
429 template <typename Param, typename Name>
430 inline bool pj_param_exists(srs::detail::proj4_parameters const& pl,
431 std::string const& sn,
434 return pj_param_exists(pl, sn);
436 template <template <typename> class Param, typename Name>
437 inline bool pj_param_exists(srs::detail::proj4_parameters const& pl,
438 std::string const& sn,
441 return pj_param_exists(pl, sn);
443 template <typename Param, typename T, typename Name>
444 inline bool pj_param_exists(srs::dpar::parameters<T> const& pl,
448 return pj_param_exists(pl, n);
450 template <template <typename> class Param, typename T, typename Name>
451 inline bool pj_param_exists(srs::dpar::parameters<T> const& pl,
455 return pj_param_exists(pl, n);
457 template <typename Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename Name>
458 inline bool pj_param_exists(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
462 return pj_param_exists<Param>(pl);
464 template <template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename Name>
465 inline bool pj_param_exists(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
469 return pj_param_exists<Param>(pl);
472 template <typename Param>
473 inline bool pj_get_param_b(srs::detail::proj4_parameters const& pl,
474 std::string const& sn,
475 srs::dpar::name_be const& )
477 return _pj_get_param_b(pl, sn);
479 template <typename Param, typename T>
480 inline bool pj_get_param_b(srs::dpar::parameters<T> const& pl,
482 srs::dpar::name_be const& n)
484 return _pj_get_param_b(pl, n);
486 template <typename Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
487 inline bool pj_get_param_b(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
489 srs::dpar::name_be const& )
491 return _pj_get_param_b<Param>(pl);
494 //#define BOOST_GEOMETRY_GET_PARAM_B(PARAMS, NAME) pj_get_param_b(PARAMS, #NAME, srs::dpar::NAME)
496 template <template <int> class Param>
497 inline bool pj_param_i(srs::detail::proj4_parameters const& pl,
498 std::string const& sn,
499 srs::dpar::name_i const& ,
502 return _pj_param_i(pl, sn, par);
504 template <template <int> class Param, typename T>
505 inline bool pj_param_i(srs::dpar::parameters<T> const& pl,
507 srs::dpar::name_i const& n,
510 return _pj_param_i(pl, n, par);
512 template <template <int> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
513 inline bool pj_param_i(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
515 srs::dpar::name_i const& ,
518 return _pj_param_i<Param>(pl, par);
521 //#define BOOST_GEOMETRY_PARAM_I(PARAMS, NAME, PAR) pj_param_i(PARAMS, #NAME, srs::dpar::NAME, PAR)
523 template <template <int> class Param>
524 inline int pj_get_param_i(srs::detail::proj4_parameters const& pl,
525 std::string const& sn,
526 srs::dpar::name_i const& )
528 return _pj_get_param_i(pl, sn);
530 template <template <int> class Param, typename T>
531 inline int pj_get_param_i(srs::dpar::parameters<T> const& pl,
533 srs::dpar::name_i const& n)
535 return _pj_get_param_i(pl, n);
537 template <template <int> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
538 inline bool pj_get_param_i(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
540 srs::dpar::name_i const& )
542 return _pj_get_param_i<Param>(pl);
545 //#define BOOST_GEOMETRY_GET_PARAM_I(PARAMS, NAME) pj_get_param_i(PARAMS, #NAME, srs::dpar::NAME)
547 template <template <typename> class Param, typename T>
548 inline bool pj_param_f(srs::detail::proj4_parameters const& pl,
549 std::string const& sn,
550 srs::dpar::name_f const& ,
553 return _pj_param_f(pl, sn, par);
555 template <template <typename> class Param, typename T>
556 inline bool pj_param_f(srs::dpar::parameters<T> const& pl,
558 srs::dpar::name_f const& n,
561 return _pj_param_f(pl, n, par);
563 template <template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename T>
564 inline bool pj_param_f(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
566 srs::dpar::name_f const& ,
569 return _pj_param_f<Param>(pl, par);
572 //#define BOOST_GEOMETRY_PARAM_F(PARAMS, NAME, PAR) pj_param_f(PARAMS, #NAME, srs::dpar::NAME, PAR)
574 template <typename T, template <typename> class Param>
575 inline T pj_get_param_f(srs::detail::proj4_parameters const& pl,
576 std::string const& sn,
577 srs::dpar::name_f const& )
579 return _pj_get_param_f<T>(pl, sn);
581 template <typename T, template <typename> class Param>
582 inline T pj_get_param_f(srs::dpar::parameters<T> const& pl,
584 srs::dpar::name_f const& n)
586 return _pj_get_param_f<T>(pl, n);
588 template <typename T, template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
589 inline T pj_get_param_f(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
591 srs::dpar::name_f const& )
593 return _pj_get_param_f<T, Param>(pl);
597 //#define BOOST_GEOMETRY_GET_PARAM_F(PARAMS, NAME) pj_get_param_f<T>(PARAMS, #NAME, srs::dpar::NAME)
599 template <template <typename> class Param, typename T>
600 inline bool pj_param_r(srs::detail::proj4_parameters const& pl,
601 std::string const& sn,
602 srs::dpar::name_r const& ,
605 return _pj_param_r(pl, sn, par);
607 template <template <typename> class Param, typename T>
608 inline bool pj_param_r(srs::dpar::parameters<T> const& pl,
610 srs::dpar::name_r const& n,
613 return _pj_param_r(pl, n, par);
615 template <template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename T>
616 inline bool pj_param_r(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
618 srs::dpar::name_r const& ,
621 return _pj_param_r<Param>(pl, par);
624 //#define BOOST_GEOMETRY_PARAM_R(PARAMS, NAME, PAR) pj_param_r(PARAMS, #NAME, srs::dpar::NAME, PAR)
626 template <typename T, template <typename> class Param>
627 inline T pj_get_param_r(srs::detail::proj4_parameters const& pl,
628 std::string const& sn,
629 srs::dpar::name_r const& )
631 return _pj_get_param_r<T>(pl, sn);
633 template <typename T, template <typename> class Param>
634 inline T pj_get_param_r(srs::dpar::parameters<T> const& pl,
636 srs::dpar::name_r const& n)
638 return _pj_get_param_r<T>(pl, n);
640 template <typename T, template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
641 inline T pj_get_param_r(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
643 srs::dpar::name_r const& )
645 return _pj_get_param_r<T, Param>(pl);
648 //#define BOOST_GEOMETRY_GET_PARAM_R(PARAMS, NAME) pj_get_param_r<T>(PARAMS, #NAME, srs::dpar::NAME)
650 } // namespace detail
651 }}} // namespace boost::geometry::projections