add boost on mac

This commit is contained in:
Bassem Girgis
2019-08-10 16:38:17 -05:00
parent 861b918727
commit be945cb63b
14105 changed files with 2714968 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2018.
// Modifications copyright (c) 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_AASINCOS_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_AASINCOS_HPP
#include <cmath>
#include <boost/geometry/srs/projections/exception.hpp>
#include <boost/geometry/srs/projections/impl/pj_strerrno.hpp>
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
namespace aasincos
{
template <typename T>
inline T ONE_TOL() { return 1.00000000000001; }
//template <typename T>
//inline T TOL() { return 0.000000001; }
template <typename T>
inline T ATOL() { return 1e-50; }
}
template <typename T>
inline T aasin(T const& v)
{
T av = 0;
if ((av = geometry::math::abs(v)) >= 1.0)
{
if (av > aasincos::ONE_TOL<T>())
{
BOOST_THROW_EXCEPTION( projection_exception(error_acos_asin_arg_too_large) );
}
return (v < 0.0 ? -geometry::math::half_pi<T>() : geometry::math::half_pi<T>());
}
return asin(v);
}
template <typename T>
inline T aacos(T const& v)
{
T av = 0;
if ((av = geometry::math::abs(v)) >= 1.0)
{
if (av > aasincos::ONE_TOL<T>())
{
BOOST_THROW_EXCEPTION( projection_exception(error_acos_asin_arg_too_large) );
}
return (v < 0.0 ? geometry::math::pi<T>() : 0.0);
}
return acos(v);
}
template <typename T>
inline T asqrt(T const& v)
{
return ((v <= 0) ? 0 : sqrt(v));
}
template <typename T>
inline T aatan2(T const& n, T const& d)
{
return ((geometry::math::abs(n) < aasincos::ATOL<T>()
&& geometry::math::abs(d) < aasincos::ATOL<T>()) ? 0.0 : atan2(n, d));
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_AASINCOS_HPP

View File

@@ -0,0 +1,70 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_ADJLON_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_ADJLON_HPP
#include <boost/math/constants/constants.hpp>
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
/* reduce argument to range +/- PI */
template <typename T>
inline T adjlon (T lon)
{
if (geometry::math::abs(lon) <= boost::math::constants::pi<T>())
{
return lon;
}
/* adjust to 0..2pi rad */
lon += boost::math::constants::pi<T>();
/* remove integral # of 'revolutions'*/
lon -= boost::math::constants::two_pi<T>() *
std::floor(lon / boost::math::constants::two_pi<T>());
/* adjust back to -pi..pi rad */
lon -= boost::math::constants::pi<T>();
return lon;
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_ADJLON_HPP

View File

@@ -0,0 +1,162 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_DYNAMIC_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_DYNAMIC_HPP
#include <string>
#include <boost/geometry/srs/projections/exception.hpp>
#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry { namespace projections
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
/*!
\brief projection virtual base class
\details class containing virtual methods
\ingroup projection
\tparam CT calculation type
\tparam P parameters type
*/
template <typename CT, typename P>
class base_v
{
public :
/// Forward projection, from Latitude-Longitude to Cartesian
template <typename LL, typename XY>
inline bool forward(LL const& lp, XY& xy) const
{
try
{
pj_fwd(*this, this->params(), lp, xy);
return true;
}
catch (...)
{
return false;
}
}
/// Inverse projection, from Cartesian to Latitude-Longitude
template <typename LL, typename XY>
inline bool inverse(XY const& xy, LL& lp) const
{
try
{
pj_inv(*this, this->params(), xy, lp);
return true;
}
catch (projection_not_invertible_exception &)
{
BOOST_RETHROW
}
catch (...)
{
return false;
}
}
/// Forward projection using lon / lat and x / y separately
virtual void fwd(CT const& lp_lon, CT const& lp_lat, CT& xy_x, CT& xy_y) const = 0;
/// Inverse projection using x / y and lon / lat
virtual void inv(CT const& xy_x, CT const& xy_y, CT& lp_lon, CT& lp_lat) const = 0;
/// Returns name of projection
virtual std::string name() const = 0;
/// Returns parameters of projection
virtual P const& params() const = 0;
/// Returns mutable parameters of projection
virtual P& mutable_params() = 0;
virtual ~base_v() {}
};
// Base-virtual-forward
template <typename Prj, typename CT, typename P>
class base_v_f : public base_v<CT, P>
{
public:
explicit base_v_f(P const& p)
: m_proj(p)
{}
template <typename P1, typename P2>
base_v_f(P1 const& p1, P2 const& p2)
: m_proj(p1, p2)
{}
template <typename P1, typename P2, typename P3>
base_v_f(P1 const& p1, P2 const& p2, P3 const& p3)
: m_proj(p1, p2, p3)
{}
virtual void fwd(CT const& lp_lon, CT const& lp_lat, CT& xy_x, CT& xy_y) const
{
m_proj.fwd(lp_lon, lp_lat, xy_x, xy_y);
}
virtual void inv(CT const& , CT const& , CT& , CT& ) const
{
BOOST_THROW_EXCEPTION(projection_not_invertible_exception(params().id.name));
}
virtual std::string name() const { return m_proj.name(); }
virtual P const& params() const { return m_proj.params(); }
virtual P& mutable_params() { return m_proj.mutable_params(); }
protected:
Prj m_proj;
};
// Base-virtual-forward/inverse
template <typename Prj, typename CT, typename P>
class base_v_fi : public base_v_f<Prj, CT, P>
{
typedef base_v_f<Prj, CT, P> base_t;
public:
explicit base_v_fi(P const& p)
: base_t(p)
{}
template <typename P1, typename P2>
base_v_fi(P1 const& p1, P2 const& p2)
: base_t(p1, p2)
{}
template <typename P1, typename P2, typename P3>
base_v_fi(P1 const& p1, P2 const& p2, P3 const& p3)
: base_t(p1, p2, p3)
{}
virtual void inv(CT const& xy_x, CT const& xy_y, CT& lp_lon, CT& lp_lat) const
{
this->m_proj.inv(xy_x, xy_y, lp_lon, lp_lat);
}
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_DYNAMIC_HPP

View File

@@ -0,0 +1,139 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_STATIC_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_STATIC_HPP
#if defined(_MSC_VER)
// For CRTP, *this is acceptable in constructor -> turn warning off
#pragma warning( disable : 4355 )
#endif // defined(_MSC_VER)
#include <string>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/srs/projections/impl/pj_fwd.hpp>
#include <boost/geometry/srs/projections/impl/pj_inv.hpp>
#include <boost/mpl/assert.hpp>
namespace boost { namespace geometry { namespace projections
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template <typename Prj, typename CSTag, typename SP, typename CT, typename P>
struct static_projection_type
{
BOOST_MPL_ASSERT_MSG((false),
NOT_IMPLEMENTED_FOR_THIS_PROJECTION_OR_CSTAG,
(Prj, CSTag));
};
#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(PROJ, P_SPHERE, P_SPHEROID) \
template <typename SP, typename CT, typename P> \
struct static_projection_type<PROJ, srs_sphere_tag, SP, CT, P> \
{ \
typedef P_SPHERE<CT, P> type; \
}; \
template <typename SP, typename CT, typename P> \
struct static_projection_type<PROJ, srs_spheroid_tag, SP, CT, P> \
{ \
typedef P_SPHEROID<CT, P> type; \
}; \
// Base-template-forward
template <typename Prj, typename CT, typename P>
struct base_t_f
{
public:
inline base_t_f(Prj const& prj, P const& params)
: m_par(params), m_prj(prj)
{}
inline P const& params() const { return m_par; }
inline P& mutable_params() { return m_par; }
template <typename LL, typename XY>
inline bool forward(LL const& lp, XY& xy) const
{
try
{
pj_fwd(m_prj, m_par, lp, xy);
return true;
}
catch(...)
{
return false;
}
}
template <typename XY, typename LL>
inline bool inverse(XY const& , LL& ) const
{
BOOST_MPL_ASSERT_MSG((false),
PROJECTION_IS_NOT_INVERTABLE,
(Prj));
return false;
}
inline std::string name() const
{
return this->m_par.id.name;
}
protected:
P m_par;
const Prj& m_prj;
};
// Base-template-forward/inverse
template <typename Prj, typename CT, typename P>
struct base_t_fi : public base_t_f<Prj, CT, P>
{
public :
inline base_t_fi(Prj const& prj, P const& params)
: base_t_f<Prj, CT, P>(prj, params)
{}
template <typename XY, typename LL>
inline bool inverse(XY const& xy, LL& lp) const
{
try
{
pj_inv(this->m_prj, this->m_par, xy, lp);
return true;
}
catch(...)
{
return false;
}
}
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_BASE_STATIC_HPP

View File

@@ -0,0 +1,268 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_DMS_PARSER_HPP
#define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_DMS_PARSER_HPP
// This file is totally revised from PROJ4 dmstor.c
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/static_assert.hpp>
#include <boost/geometry/core/config.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/srs/projections/str_cast.hpp>
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
template <typename T>
struct dms_result
{
enum axis_selector {axis_lat = 1, axis_lon = 0};
private :
T m_angle;
axis_selector m_axis;
public :
explicit dms_result(T const& v, axis_selector ax)
: m_angle(v)
, m_axis(ax)
{}
inline axis_selector axis() const { return m_axis; }
inline T angle() const { return m_angle; }
template <typename CH, typename TR>
inline friend std::basic_ostream<CH, TR>& operator<<(std::basic_ostream<CH, TR>& os,
const dms_result& d)
{
os << d.m_angle;
return os;
}
};
template <typename T
, bool as_radian = true
, char N = 'N', char E = 'E', char S = 'S', char W = 'W' // translatable
, char MIN = '\'', char SEC = '"' // other char's possible
, char D = 'D', char R = 'R' // degree sign might be small o
>
struct dms_parser
{
// Question from Barend: can we compile-time select that it is case-sensitive/case-insensitive?
// We have to change the switch then -> specializations
// For now: make it (compile-time) case sensitive
static const int diff = 'a' - 'A';
#ifndef __GNUC__
BOOST_STATIC_ASSERT((diff > 0)); // make sure we've the right assumption. GCC does not accept this here.
#endif
static const char n_alter = N <= 'Z' ? N + diff : N - diff;
static const char e_alter = E <= 'Z' ? E + diff : E - diff;
static const char s_alter = S <= 'Z' ? S + diff : S - diff;
static const char w_alter = W <= 'Z' ? W + diff : W - diff;
static const char r_alter = R <= 'Z' ? R + diff : R - diff;
// degree is normally D (proj4) but might be superscript o
// Note d_alter is not correct then, so map it to NULL now, guarded by the while
static const char d_alter =
((D >= 'A' && D <= 'Z') || (D >= 'a' && D <= 'z')) ? (D <= 'Z' ? D + diff : D - diff) : '\0';
struct dms_value
{
T dms[3];
bool has_dms[3];
dms_value()
#ifdef BOOST_GEOMETRY_CXX11_ARRAY_UNIFIED_INITIALIZATION
: dms{0, 0, 0}
, has_dms{false, false, false}
{}
#else
{
std::fill(dms, dms + 3, T(0));
std::fill(has_dms, has_dms + 3, false);
}
#endif
};
template <size_t I>
static inline void assign_dms(dms_value& dms, std::string& value, bool& has_value)
{
dms.dms[I] = geometry::str_cast<T>(value);
dms.has_dms[I] = true;
has_value = false;
value.clear();
}
static inline void process(dms_value& dms, std::string& value, bool& has_value)
{
if (has_value)
{
// Assign last one, sequentially
if (! dms.has_dms[0]) assign_dms<0>(dms, value, has_value);
else if (! dms.has_dms[1]) assign_dms<1>(dms, value, has_value);
else if (! dms.has_dms[2]) assign_dms<2>(dms, value, has_value);
}
}
static inline dms_result<T> apply(std::string const& is)
{
return apply(is.c_str());
}
static inline dms_result<T> apply(const char* is)
{
dms_value dms;
bool has_value = false;
std::string value;
T factor = 1.0; // + denotes N/E values, -1 denotes S/W values
typename dms_result<T>::axis_selector axis = dms_result<T>::axis_lon; // true denotes N/S values
bool in_radian = false; // true denotes values as "0.1R"
while(*is)
{
switch(*is)
{
case '-' :
if (! has_value && ! dms.has_dms[0])
{
factor = -factor;
}
break;
case N :
case n_alter :
axis = dms_result<T>::axis_lat;
break;
case S :
case s_alter :
axis = dms_result<T>::axis_lat;
factor = -factor;
break;
case E :
case e_alter :
axis = dms_result<T>::axis_lon;
break;
case W :
case w_alter :
axis = dms_result<T>::axis_lon;
factor = -factor;
break;
case D :
case d_alter :
if (! dms.has_dms[0] && has_value)
{
assign_dms<0>(dms, value, has_value);
}
break;
case R :
case r_alter :
if (! dms.has_dms[0] && has_value)
{
// specified value is in radian!
in_radian = true;
assign_dms<0>(dms, value, has_value);
}
break;
case MIN:
if (! dms.has_dms[1] && has_value)
{
assign_dms<1>(dms, value, has_value);
}
break;
case SEC :
if (! dms.has_dms[2] && has_value)
{
assign_dms<2>(dms, value, has_value);
}
break;
case ' ' :
case '\t' :
case '\n' :
process(dms, value, has_value);
break;
default :
value += *is;
has_value = true;
break;
}
is++;
}
// Assign last one, if any
process(dms, value, has_value);
T const d2r = math::d2r<T>();
T const r2d = math::r2d<T>();
return dms_result<T>(factor *
(in_radian && as_radian
? dms.dms[0]
: in_radian && ! as_radian
? dms.dms[0] * r2d
: ! in_radian && as_radian
? dms.dms[0] * d2r + dms.dms[1] * d2r / 60.0 + dms.dms[2] * d2r / 3600.0
: dms.dms[0] + dms.dms[1] / 60.0 + dms.dms[2] / 3600.0)
, axis);
}
};
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_DMS_PARSER_HPP

View File

@@ -0,0 +1,86 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_FACTORY_ENTRY_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_FACTORY_ENTRY_HPP
#include <string>
#include <boost/geometry/srs/projections/factory_key.hpp>
#include <boost/geometry/srs/projections/impl/base_dynamic.hpp>
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
// forward declaration needed by some projections
template <typename Params, typename CT, typename Parameters>
class factory;
template <typename Params, typename CT, typename Parameters>
struct factory_entry
{
virtual ~factory_entry() {}
virtual base_v<CT, Parameters>* create_new(Params const& , Parameters const& ) const = 0;
};
// Macros for entries definition
#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_BEGIN(ENTRY) \
template <typename Params, typename T, typename Parameters> \
struct ENTRY : projections::detail::factory_entry<Params, T, Parameters> \
{ \
projections::detail::base_v<T, Parameters>* create_new(Params const& params, \
Parameters const& parameters) const
#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_END };
#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(ENTRY, PROJ) \
BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_BEGIN(ENTRY) \
{ \
return new projections::detail::base_v_f<PROJ<T, Parameters>, T, Parameters>(params, parameters); \
} \
BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_END
#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(ENTRY, PROJ) \
BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_BEGIN(ENTRY) \
{ \
return new projections::detail::base_v_fi<PROJ<T, Parameters>, T, Parameters>(params, parameters); \
} \
BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_END
#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(ENTRY, PROJ_S, PROJ_E) \
BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_BEGIN(ENTRY) \
{ \
if (parameters.es != 0.0) \
return new projections::detail::base_v_fi<PROJ_E<T, Parameters>, T, Parameters>(params, parameters); \
else \
return new projections::detail::base_v_fi<PROJ_S<T, Parameters>, T, Parameters>(params, parameters); \
} \
BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_END
// Macros for factory initialization
#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_BEGIN(FUN_NAME) \
template <typename Params, typename T, typename Parameters> \
inline void FUN_NAME(projections::detail::factory<Params, T, Parameters>& factory)
#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_INIT_ENTRY(PROJ_NAME, ENTRY) \
factory.add_to_factory(projections::detail::factory_key(#PROJ_NAME, \
srs::dpar::proj_##PROJ_NAME), \
new ENTRY<Params, T, Parameters>);
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_FACTORY_ENTRY_HPP

View File

@@ -0,0 +1,40 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_FUNCTION_OVERLOADS_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_FUNCTION_OVERLOADS_HPP
#include <cmath>
namespace boost { namespace geometry { namespace projections
{
// Functions to resolve ambiguity when compiling with coordinates of different types
/*
template <typename T>
inline T atan2(T const& a, T const& b)
{
using std::atan2;
return atan2(a, b);
}
*/
template <typename T>
inline int int_floor(T const& f)
{
using std::floor;
return int(floor(f));
}
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_FUNCTION_OVERLOADS_HPP

View File

@@ -0,0 +1,487 @@
// Boost.Geometry
// This file is manually converted from PROJ4
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// This file was converted to Geometry Library by Adam Wulkiewicz
// Original copyright notice:
/***************************************************************************/
/* RSC IDENTIFIER: GEOCENTRIC
*
* ABSTRACT
*
* This component provides conversions between Geodetic coordinates (latitude,
* longitude in radians and height in meters) and Geocentric coordinates
* (X, Y, Z) in meters.
*
* ERROR HANDLING
*
* This component checks parameters for valid values. If an invalid value
* is found, the error code is combined with the current error code using
* the bitwise or. This combining allows multiple error codes to be
* returned. The possible error codes are:
*
* GEOCENT_NO_ERROR : No errors occurred in function
* GEOCENT_LAT_ERROR : Latitude out of valid range
* (-90 to 90 degrees)
* GEOCENT_LON_ERROR : Longitude out of valid range
* (-180 to 360 degrees)
* GEOCENT_A_ERROR : Semi-major axis lessthan or equal to zero
* GEOCENT_B_ERROR : Semi-minor axis lessthan or equal to zero
* GEOCENT_A_LESS_B_ERROR : Semi-major axis less than semi-minor axis
*
*
* REUSE NOTES
*
* GEOCENTRIC is intended for reuse by any application that performs
* coordinate conversions between geodetic coordinates and geocentric
* coordinates.
*
*
* REFERENCES
*
* An Improved Algorithm for Geocentric to Geodetic Coordinate Conversion,
* Ralph Toms, February 1996 UCRL-JC-123138.
*
* Further information on GEOCENTRIC can be found in the Reuse Manual.
*
* GEOCENTRIC originated from : U.S. Army Topographic Engineering Center
* Geospatial Information Division
* 7701 Telegraph Road
* Alexandria, VA 22310-3864
*
* LICENSES
*
* None apply to this component.
*
* RESTRICTIONS
*
* GEOCENTRIC has no restrictions.
*
* ENVIRONMENT
*
* GEOCENTRIC was tested and certified in the following environments:
*
* 1. Solaris 2.5 with GCC version 2.8.1
* 2. Windows 95 with MS Visual C++ version 6
*
* MODIFICATIONS
*
* Date Description
* ---- -----------
* 25-02-97 Original Code
*
*/
#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_GEOCENT_HPP
#define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_GEOCENT_HPP
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
/***************************************************************************/
/*
* DEFINES
*/
static const long GEOCENT_NO_ERROR = 0x0000;
static const long GEOCENT_LAT_ERROR = 0x0001;
static const long GEOCENT_LON_ERROR = 0x0002;
static const long GEOCENT_A_ERROR = 0x0004;
static const long GEOCENT_B_ERROR = 0x0008;
static const long GEOCENT_A_LESS_B_ERROR = 0x0010;
template <typename T>
struct GeocentricInfo
{
T Geocent_a; /* Semi-major axis of ellipsoid in meters */
T Geocent_b; /* Semi-minor axis of ellipsoid */
T Geocent_a2; /* Square of semi-major axis */
T Geocent_b2; /* Square of semi-minor axis */
T Geocent_e2; /* Eccentricity squared */
T Geocent_ep2; /* 2nd eccentricity squared */
};
template <typename T>
inline T COS_67P5()
{
/*return 0.38268343236508977*/;
return cos(T(67.5) * math::d2r<T>()); /* cosine of 67.5 degrees */
}
template <typename T>
inline T AD_C()
{
return 1.0026000; /* Toms region 1 constant */
}
/***************************************************************************/
/*
* FUNCTIONS
*/
template <typename T>
inline long pj_Set_Geocentric_Parameters (GeocentricInfo<T> & gi, T const& a, T const& b)
{ /* BEGIN Set_Geocentric_Parameters */
/*
* The function Set_Geocentric_Parameters receives the ellipsoid parameters
* as inputs and sets the corresponding state variables.
*
* a : Semi-major axis, in meters. (input)
* b : Semi-minor axis, in meters. (input)
*/
long Error_Code = GEOCENT_NO_ERROR;
if (a <= 0.0)
Error_Code |= GEOCENT_A_ERROR;
if (b <= 0.0)
Error_Code |= GEOCENT_B_ERROR;
if (a < b)
Error_Code |= GEOCENT_A_LESS_B_ERROR;
if (!Error_Code)
{
gi.Geocent_a = a;
gi.Geocent_b = b;
gi.Geocent_a2 = a * a;
gi.Geocent_b2 = b * b;
gi.Geocent_e2 = (gi.Geocent_a2 - gi.Geocent_b2) / gi.Geocent_a2;
gi.Geocent_ep2 = (gi.Geocent_a2 - gi.Geocent_b2) / gi.Geocent_b2;
}
return (Error_Code);
} /* END OF Set_Geocentric_Parameters */
template <typename T>
inline void pj_Get_Geocentric_Parameters (GeocentricInfo<T> const& gi,
T & a,
T & b)
{ /* BEGIN Get_Geocentric_Parameters */
/*
* The function Get_Geocentric_Parameters returns the ellipsoid parameters
* to be used in geocentric coordinate conversions.
*
* a : Semi-major axis, in meters. (output)
* b : Semi-minor axis, in meters. (output)
*/
a = gi.Geocent_a;
b = gi.Geocent_b;
} /* END OF Get_Geocentric_Parameters */
template <typename T>
inline long pj_Convert_Geodetic_To_Geocentric (GeocentricInfo<T> const& gi,
T Longitude, T Latitude, T Height,
T & X, T & Y, T & Z)
{ /* BEGIN Convert_Geodetic_To_Geocentric */
/*
* The function Convert_Geodetic_To_Geocentric converts geodetic coordinates
* (latitude, longitude, and height) to geocentric coordinates (X, Y, Z),
* according to the current ellipsoid parameters.
*
* Latitude : Geodetic latitude in radians (input)
* Longitude : Geodetic longitude in radians (input)
* Height : Geodetic height, in meters (input)
* X : Calculated Geocentric X coordinate, in meters (output)
* Y : Calculated Geocentric Y coordinate, in meters (output)
* Z : Calculated Geocentric Z coordinate, in meters (output)
*
*/
long Error_Code = GEOCENT_NO_ERROR;
T Rn; /* Earth radius at location */
T Sin_Lat; /* sin(Latitude) */
T Sin2_Lat; /* Square of sin(Latitude) */
T Cos_Lat; /* cos(Latitude) */
static const T PI = math::pi<T>();
static const T PI_OVER_2 = math::half_pi<T>();
/*
** Don't blow up if Latitude is just a little out of the value
** range as it may just be a rounding issue. Also removed longitude
** test, it should be wrapped by cos() and sin(). NFW for PROJ.4, Sep/2001.
*/
if( Latitude < -PI_OVER_2 && Latitude > -1.001 * PI_OVER_2 )
Latitude = -PI_OVER_2;
else if( Latitude > PI_OVER_2 && Latitude < 1.001 * PI_OVER_2 )
Latitude = PI_OVER_2;
else if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
{ /* Latitude out of range */
Error_Code |= GEOCENT_LAT_ERROR;
}
if (!Error_Code)
{ /* no errors */
if (Longitude > PI)
Longitude -= (2*PI);
Sin_Lat = sin(Latitude);
Cos_Lat = cos(Latitude);
Sin2_Lat = Sin_Lat * Sin_Lat;
Rn = gi.Geocent_a / (sqrt(1.0e0 - gi.Geocent_e2 * Sin2_Lat));
X = (Rn + Height) * Cos_Lat * cos(Longitude);
Y = (Rn + Height) * Cos_Lat * sin(Longitude);
Z = ((Rn * (1 - gi.Geocent_e2)) + Height) * Sin_Lat;
}
return (Error_Code);
} /* END OF Convert_Geodetic_To_Geocentric */
/*
* The function Convert_Geocentric_To_Geodetic converts geocentric
* coordinates (X, Y, Z) to geodetic coordinates (latitude, longitude,
* and height), according to the current ellipsoid parameters.
*
* X : Geocentric X coordinate, in meters. (input)
* Y : Geocentric Y coordinate, in meters. (input)
* Z : Geocentric Z coordinate, in meters. (input)
* Latitude : Calculated latitude value in radians. (output)
* Longitude : Calculated longitude value in radians. (output)
* Height : Calculated height value, in meters. (output)
*/
#define BOOST_GEOMETRY_PROJECTIONS_USE_ITERATIVE_METHOD
template <typename T>
inline void pj_Convert_Geocentric_To_Geodetic (GeocentricInfo<T> const& gi,
T X, T Y, T Z,
T & Longitude, T & Latitude, T & Height)
{ /* BEGIN Convert_Geocentric_To_Geodetic */
static const T PI_OVER_2 = math::half_pi<T>();
#if !defined(BOOST_GEOMETRY_PROJECTIONS_USE_ITERATIVE_METHOD)
static const T COS_67P5 = detail::COS_67P5<T>();
static const T AD_C = detail::AD_C<T>();
/*
* The method used here is derived from 'An Improved Algorithm for
* Geocentric to Geodetic Coordinate Conversion', by Ralph Toms, Feb 1996
*/
/* Note: Variable names follow the notation used in Toms, Feb 1996 */
T W; /* distance from Z axis */
T W2; /* square of distance from Z axis */
T T0; /* initial estimate of vertical component */
T T1; /* corrected estimate of vertical component */
T S0; /* initial estimate of horizontal component */
T S1; /* corrected estimate of horizontal component */
T Sin_B0; /* sin(B0), B0 is estimate of Bowring aux variable */
T Sin3_B0; /* cube of sin(B0) */
T Cos_B0; /* cos(B0) */
T Sin_p1; /* sin(phi1), phi1 is estimated latitude */
T Cos_p1; /* cos(phi1) */
T Rn; /* Earth radius at location */
T Sum; /* numerator of cos(phi1) */
bool At_Pole; /* indicates location is in polar region */
At_Pole = false;
if (X != 0.0)
{
Longitude = atan2(Y,X);
}
else
{
if (Y > 0)
{
Longitude = PI_OVER_2;
}
else if (Y < 0)
{
Longitude = -PI_OVER_2;
}
else
{
At_Pole = true;
Longitude = 0.0;
if (Z > 0.0)
{ /* north pole */
Latitude = PI_OVER_2;
}
else if (Z < 0.0)
{ /* south pole */
Latitude = -PI_OVER_2;
}
else
{ /* center of earth */
Latitude = PI_OVER_2;
Height = -Geocent_b;
return;
}
}
}
W2 = X*X + Y*Y;
W = sqrt(W2);
T0 = Z * AD_C;
S0 = sqrt(T0 * T0 + W2);
Sin_B0 = T0 / S0;
Cos_B0 = W / S0;
Sin3_B0 = Sin_B0 * Sin_B0 * Sin_B0;
T1 = Z + gi.Geocent_b * gi.Geocent_ep2 * Sin3_B0;
Sum = W - gi.Geocent_a * gi.Geocent_e2 * Cos_B0 * Cos_B0 * Cos_B0;
S1 = sqrt(T1*T1 + Sum * Sum);
Sin_p1 = T1 / S1;
Cos_p1 = Sum / S1;
Rn = gi.Geocent_a / sqrt(1.0 - gi.Geocent_e2 * Sin_p1 * Sin_p1);
if (Cos_p1 >= COS_67P5)
{
Height = W / Cos_p1 - Rn;
}
else if (Cos_p1 <= -COS_67P5)
{
Height = W / -Cos_p1 - Rn;
}
else
{
Height = Z / Sin_p1 + Rn * (gi.Geocent_e2 - 1.0);
}
if (At_Pole == false)
{
Latitude = atan(Sin_p1 / Cos_p1);
}
#else /* defined(BOOST_GEOMETRY_PROJECTIONS_USE_ITERATIVE_METHOD) */
/*
* Reference...
* ============
* Wenzel, H.-G.(1985): Hochauflösende Kugelfunktionsmodelle für
* das Gravitationspotential der Erde. Wiss. Arb. Univ. Hannover
* Nr. 137, p. 130-131.
* Programmed by GGA- Leibniz-Institute of Applied Geophysics
* Stilleweg 2
* D-30655 Hannover
* Federal Republic of Germany
* Internet: www.gga-hannover.de
*
* Hannover, March 1999, April 2004.
* see also: comments in statements
* remarks:
* Mathematically exact and because of symmetry of rotation-ellipsoid,
* each point (X,Y,Z) has at least two solutions (Latitude1,Longitude1,Height1) and
* (Latitude2,Longitude2,Height2). Is point=(0.,0.,Z) (P=0.), so you get even
* four solutions, every two symmetrical to the semi-minor axis.
* Here Height1 and Height2 have at least a difference in order of
* radius of curvature (e.g. (0,0,b)=> (90.,0.,0.) or (-90.,0.,-2b);
* (a+100.)*(sqrt(2.)/2.,sqrt(2.)/2.,0.) => (0.,45.,100.) or
* (0.,225.,-(2a+100.))).
* The algorithm always computes (Latitude,Longitude) with smallest |Height|.
* For normal computations, that means |Height|<10000.m, algorithm normally
* converges after to 2-3 steps!!!
* But if |Height| has the amount of length of ellipsoid's axis
* (e.g. -6300000.m), algorithm needs about 15 steps.
*/
/* local definitions and variables */
/* end-criterium of loop, accuracy of sin(Latitude) */
static const T genau = 1.E-12;
static const T genau2 = (genau*genau);
static const int maxiter = 30;
T P; /* distance between semi-minor axis and location */
T RR; /* distance between center and location */
T CT; /* sin of geocentric latitude */
T ST; /* cos of geocentric latitude */
T RX;
T RK;
T RN; /* Earth radius at location */
T CPHI0; /* cos of start or old geodetic latitude in iterations */
T SPHI0; /* sin of start or old geodetic latitude in iterations */
T CPHI; /* cos of searched geodetic latitude */
T SPHI; /* sin of searched geodetic latitude */
T SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */
int iter; /* # of continuous iteration, max. 30 is always enough (s.a.) */
P = sqrt(X*X+Y*Y);
RR = sqrt(X*X+Y*Y+Z*Z);
/* special cases for latitude and longitude */
if (P/gi.Geocent_a < genau) {
/* special case, if P=0. (X=0., Y=0.) */
Longitude = 0.;
/* if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis
* of ellipsoid (=center of mass), Latitude becomes PI/2 */
if (RR/gi.Geocent_a < genau) {
Latitude = PI_OVER_2;
Height = -gi.Geocent_b;
return ;
}
}
else {
/* ellipsoidal (geodetic) longitude
* interval: -PI < Longitude <= +PI */
Longitude=atan2(Y,X);
}
/* --------------------------------------------------------------
* Following iterative algorithm was developed by
* "Institut für Erdmessung", University of Hannover, July 1988.
* Internet: www.ife.uni-hannover.de
* Iterative computation of CPHI,SPHI and Height.
* Iteration of CPHI and SPHI to 10**-12 radian resp.
* 2*10**-7 arcsec.
* --------------------------------------------------------------
*/
CT = Z/RR;
ST = P/RR;
RX = 1.0/sqrt(1.0-gi.Geocent_e2*(2.0-gi.Geocent_e2)*ST*ST);
CPHI0 = ST*(1.0-gi.Geocent_e2)*RX;
SPHI0 = CT*RX;
iter = 0;
/* loop to find sin(Latitude) resp. Latitude
* until |sin(Latitude(iter)-Latitude(iter-1))| < genau */
do
{
iter++;
RN = gi.Geocent_a/sqrt(1.0-gi.Geocent_e2*SPHI0*SPHI0);
/* ellipsoidal (geodetic) height */
Height = P*CPHI0+Z*SPHI0-RN*(1.0-gi.Geocent_e2*SPHI0*SPHI0);
RK = gi.Geocent_e2*RN/(RN+Height);
RX = 1.0/sqrt(1.0-RK*(2.0-RK)*ST*ST);
CPHI = ST*(1.0-RK)*RX;
SPHI = CT*RX;
SDPHI = SPHI*CPHI0-CPHI*SPHI0;
CPHI0 = CPHI;
SPHI0 = SPHI;
}
while (SDPHI*SDPHI > genau2 && iter < maxiter);
/* ellipsoidal (geodetic) latitude */
Latitude=atan(SPHI/fabs(CPHI));
return;
#endif /* defined(BOOST_GEOMETRY_PROJECTIONS_USE_ITERATIVE_METHOD) */
} /* END OF Convert_Geocentric_To_Geodetic */
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_GEOCENT_HPP

View File

@@ -0,0 +1,433 @@
// Boost.Geometry
// This file is manually converted from PROJ4
// This file was modified by Oracle on 2018, 2019.
// Modifications copyright (c) 2018-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// This file was converted to Geometry Library by Adam Wulkiewicz
// Original copyright notice:
// Author: Frank Warmerdam, warmerdam@pobox.com
// Copyright (c) 2000, Frank Warmerdam
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_HPP
#define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_HPP
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/srs/projections/impl/adjlon.hpp>
#include <boost/geometry/srs/projections/impl/function_overloads.hpp>
#include <boost/geometry/srs/projections/impl/pj_gridlist.hpp>
#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
// Originally implemented in nad_intr.c
template <typename CalcT>
inline void nad_intr(CalcT in_lon, CalcT in_lat,
CalcT & out_lon, CalcT & out_lat,
pj_ctable const& ct)
{
pj_ctable::lp_t frct;
pj_ctable::ilp_t indx;
boost::int32_t in;
indx.lam = int_floor(in_lon /= ct.del.lam);
indx.phi = int_floor(in_lat /= ct.del.phi);
frct.lam = in_lon - indx.lam;
frct.phi = in_lat - indx.phi;
// TODO: implement differently
out_lon = out_lat = HUGE_VAL;
if (indx.lam < 0) {
if (indx.lam == -1 && frct.lam > 0.99999999999) {
++indx.lam;
frct.lam = 0.;
} else
return;
} else if ((in = indx.lam + 1) >= ct.lim.lam) {
if (in == ct.lim.lam && frct.lam < 1e-11) {
--indx.lam;
frct.lam = 1.;
} else
return;
}
if (indx.phi < 0) {
if (indx.phi == -1 && frct.phi > 0.99999999999) {
++indx.phi;
frct.phi = 0.;
} else
return;
} else if ((in = indx.phi + 1) >= ct.lim.phi) {
if (in == ct.lim.phi && frct.phi < 1e-11) {
--indx.phi;
frct.phi = 1.;
} else
return;
}
boost::int32_t index = indx.phi * ct.lim.lam + indx.lam;
pj_ctable::flp_t const& f00 = ct.cvs[index++];
pj_ctable::flp_t const& f10 = ct.cvs[index];
index += ct.lim.lam;
pj_ctable::flp_t const& f11 = ct.cvs[index--];
pj_ctable::flp_t const& f01 = ct.cvs[index];
CalcT m00, m10, m01, m11;
m11 = m10 = frct.lam;
m00 = m01 = 1. - frct.lam;
m11 *= frct.phi;
m01 *= frct.phi;
frct.phi = 1. - frct.phi;
m00 *= frct.phi;
m10 *= frct.phi;
out_lon = m00 * f00.lam + m10 * f10.lam +
m01 * f01.lam + m11 * f11.lam;
out_lat = m00 * f00.phi + m10 * f10.phi +
m01 * f01.phi + m11 * f11.phi;
}
// Originally implemented in nad_cvt.c
template <bool Inverse, typename CalcT>
inline void nad_cvt(CalcT const& in_lon, CalcT const& in_lat,
CalcT & out_lon, CalcT & out_lat,
pj_gi const& gi)
{
static const int max_iterations = 10;
static const CalcT tol = 1e-12;
static const CalcT toltol = tol * tol;
static const CalcT pi = math::pi<CalcT>();
// horizontal grid expected
BOOST_GEOMETRY_ASSERT_MSG(gi.format != pj_gi::gtx,
"Vertical grid cannot be used in horizontal shift.");
pj_ctable const& ct = gi.ct;
// TODO: implement differently
if (in_lon == HUGE_VAL)
{
out_lon = HUGE_VAL;
out_lat = HUGE_VAL;
return;
}
// normalize input to ll origin
pj_ctable::lp_t tb;
tb.lam = in_lon - ct.ll.lam;
tb.phi = in_lat - ct.ll.phi;
tb.lam = adjlon (tb.lam - pi) + pi;
pj_ctable::lp_t t;
nad_intr(tb.lam, tb.phi, t.lam, t.phi, ct);
if (t.lam == HUGE_VAL)
{
out_lon = HUGE_VAL;
out_lat = HUGE_VAL;
return;
}
if (! Inverse)
{
out_lon = in_lon - t.lam;
out_lat = in_lat - t.phi;
return;
}
t.lam = tb.lam + t.lam;
t.phi = tb.phi - t.phi;
int i = max_iterations;
pj_ctable::lp_t del, dif;
do
{
nad_intr(t.lam, t.phi, del.lam, del.phi, ct);
// This case used to return failure, but I have
// changed it to return the first order approximation
// of the inverse shift. This avoids cases where the
// grid shift *into* this grid came from another grid.
// While we aren't returning optimally correct results
// I feel a close result in this case is better than
// no result. NFW
// To demonstrate use -112.5839956 49.4914451 against
// the NTv2 grid shift file from Canada.
if (del.lam == HUGE_VAL)
{
// Inverse grid shift iteration failed, presumably at grid edge. Using first approximation.
break;
}
dif.lam = t.lam - del.lam - tb.lam;
dif.phi = t.phi + del.phi - tb.phi;
t.lam -= dif.lam;
t.phi -= dif.phi;
}
while (--i && (dif.lam*dif.lam + dif.phi*dif.phi > toltol)); // prob. slightly faster than hypot()
if (i==0)
{
// Inverse grid shift iterator failed to converge.
out_lon = HUGE_VAL;
out_lat = HUGE_VAL;
return;
}
out_lon = adjlon (t.lam + ct.ll.lam);
out_lat = t.phi + ct.ll.phi;
}
/************************************************************************/
/* find_grid() */
/* */
/* Determine which grid is the correct given an input coordinate. */
/************************************************************************/
// Originally find_ctable()
// here divided into grid_disjoint(), find_grid() and load_grid()
template <typename T>
inline bool grid_disjoint(T const& lam, T const& phi,
pj_ctable const& ct)
{
double epsilon = (fabs(ct.del.phi)+fabs(ct.del.lam))/10000.0;
return ct.ll.phi - epsilon > phi
|| ct.ll.lam - epsilon > lam
|| (ct.ll.phi + (ct.lim.phi-1) * ct.del.phi + epsilon < phi)
|| (ct.ll.lam + (ct.lim.lam-1) * ct.del.lam + epsilon < lam);
}
template <typename T>
inline pj_gi * find_grid(T const& lam,
T const& phi,
std::vector<pj_gi>::iterator first,
std::vector<pj_gi>::iterator last)
{
pj_gi * gip = NULL;
for( ; first != last ; ++first )
{
// skip tables that don't match our point at all.
if (! grid_disjoint(lam, phi, first->ct))
{
// skip vertical grids
if (first->format != pj_gi::gtx)
{
gip = boost::addressof(*first);
break;
}
}
}
// If we didn't find a child then nothing more to do
if( gip == NULL )
return gip;
// Otherwise use the child, first checking it's children
pj_gi * child = find_grid(lam, phi, first->children.begin(), first->children.end());
if (child != NULL)
gip = child;
return gip;
}
template <typename T>
inline pj_gi * find_grid(T const& lam,
T const& phi,
pj_gridinfo & grids,
std::vector<std::size_t> const& gridindexes)
{
pj_gi * gip = NULL;
// keep trying till we find a table that works
for (std::size_t i = 0 ; i < gridindexes.size() ; ++i)
{
pj_gi & gi = grids[gridindexes[i]];
// skip tables that don't match our point at all.
if (! grid_disjoint(lam, phi, gi.ct))
{
// skip vertical grids
if (gi.format != pj_gi::gtx)
{
gip = boost::addressof(gi);
break;
}
}
}
if (gip == NULL)
return gip;
// If we have child nodes, check to see if any of them apply.
pj_gi * child = find_grid(lam, phi, gip->children.begin(), gip->children.end());
if (child != NULL)
gip = child;
// if we get this far we have found a suitable grid
return gip;
}
template <typename StreamPolicy>
inline bool load_grid(StreamPolicy const& stream_policy, pj_gi_load & gi)
{
// load the grid shift info if we don't have it.
if (gi.ct.cvs.empty())
{
typename StreamPolicy::stream_type is;
stream_policy.open(is, gi.gridname);
if (! pj_gridinfo_load(is, gi))
{
//pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
return false;
}
}
return true;
}
/************************************************************************/
/* pj_apply_gridshift_3() */
/* */
/* This is the real workhorse, given a gridlist. */
/************************************************************************/
template <bool Inverse, typename CalcT, typename StreamPolicy, typename Range>
inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy,
Range & range,
srs::grids & grids,
std::vector<std::size_t> const& gridindexes)
{
typedef typename boost::range_size<Range>::type size_type;
// If the grids are empty the indexes are as well
if (gridindexes.empty())
{
//pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
//return PJD_ERR_FAILED_TO_LOAD_GRID;
return false;
}
size_type point_count = boost::size(range);
for (size_type i = 0 ; i < point_count ; ++i)
{
typename boost::range_reference<Range>::type
point = range::at(range, i);
CalcT in_lon = geometry::get_as_radian<0>(point);
CalcT in_lat = geometry::get_as_radian<1>(point);
pj_gi * gip = find_grid(in_lon, in_lat, grids.gridinfo, gridindexes);
if ( gip != NULL )
{
// load the grid shift info if we don't have it.
if (! gip->ct.cvs.empty() || load_grid(stream_policy, *gip))
{
// TODO: use set_invalid_point() or similar mechanism
CalcT out_lon = HUGE_VAL;
CalcT out_lat = HUGE_VAL;
nad_cvt<Inverse>(in_lon, in_lat, out_lon, out_lat, *gip);
// TODO: check differently
if ( out_lon != HUGE_VAL )
{
geometry::set_from_radian<0>(point, out_lon);
geometry::set_from_radian<1>(point, out_lat);
}
}
}
}
return true;
}
/************************************************************************/
/* pj_apply_gridshift_2() */
/* */
/* This implementation uses the gridlist from a coordinate */
/* system definition. If the gridlist has not yet been */
/* populated in the coordinate system definition we set it up */
/* now. */
/************************************************************************/
template <bool Inverse, typename Par, typename Range, typename ProjGrids>
inline bool pj_apply_gridshift_2(Par const& /*defn*/, Range & range, ProjGrids const& grids)
{
/*if( defn->catalog_name != NULL )
return pj_gc_apply_gridshift( defn, inverse, point_count, point_offset,
x, y, z );*/
/*std::vector<std::size_t> gridindexes;
pj_gridlist_from_nadgrids(pj_get_param_s(defn.params, "nadgrids"),
grids.storage_ptr->stream_policy,
grids.storage_ptr->grids,
gridindexes);*/
BOOST_GEOMETRY_ASSERT(grids.storage_ptr != NULL);
// At this point the grids should be initialized
if (grids.hindexes.empty())
return false;
return pj_apply_gridshift_3
<
Inverse, typename Par::type
>(grids.storage_ptr->stream_policy,
range,
grids.storage_ptr->hgrids,
grids.hindexes);
}
template <bool Inverse, typename Par, typename Range>
inline bool pj_apply_gridshift_2(Par const& , Range & , srs::detail::empty_projection_grids const& )
{
return false;
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_HPP

View File

@@ -0,0 +1,157 @@
// Boost.Geometry
// This file is manually converted from PROJ4
// This file was modified by Oracle on 2018, 2019.
// Modifications copyright (c) 2018-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// This file was converted to Geometry Library by Adam Wulkiewicz
// Original copyright notice:
// Author: Frank Warmerdam, warmerdam@pobox.com
// Copyright (c) 2000, Frank Warmerdam
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_SHARED_HPP
#define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_SHARED_HPP
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp>
#include <boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp>
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
template <bool Inverse, typename CalcT, typename StreamPolicy, typename Range>
inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy,
Range & range,
shared_grids & grids,
std::vector<std::size_t> const& gridindexes)
{
typedef typename boost::range_size<Range>::type size_type;
// If the grids are empty the indexes are as well
if (gridindexes.empty())
{
//pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID);
//return PJD_ERR_FAILED_TO_LOAD_GRID;
return false;
}
size_type point_count = boost::size(range);
// local storage
pj_gi_load local_gi;
for (size_type i = 0 ; i < point_count ; )
{
bool load_needed = false;
CalcT in_lon = 0;
CalcT in_lat = 0;
{
boost::shared_lock<boost::shared_mutex> lock(grids.mutex);
for ( ; i < point_count ; ++i )
{
typename boost::range_reference<Range>::type
point = range::at(range, i);
in_lon = geometry::get_as_radian<0>(point);
in_lat = geometry::get_as_radian<1>(point);
pj_gi * gip = find_grid(in_lon, in_lat, grids.gridinfo, gridindexes);
if (gip == NULL)
{
// do nothing
}
else if (! gip->ct.cvs.empty())
{
// TODO: use set_invalid_point() or similar mechanism
CalcT out_lon = HUGE_VAL;
CalcT out_lat = HUGE_VAL;
nad_cvt<Inverse>(in_lon, in_lat, out_lon, out_lat, *gip);
// TODO: check differently
if (out_lon != HUGE_VAL)
{
geometry::set_from_radian<0>(point, out_lon);
geometry::set_from_radian<1>(point, out_lat);
}
}
else
{
// loading is needed
local_gi = *gip;
load_needed = true;
break;
}
}
}
if (load_needed)
{
if (load_grid(stream_policy, local_gi))
{
boost::unique_lock<boost::shared_mutex> lock(grids.mutex);
// check again in case other thread already loaded the grid.
pj_gi * gip = find_grid(in_lon, in_lat, grids.gridinfo, gridindexes);
if (gip != NULL && gip->ct.cvs.empty())
{
// swap loaded local storage with empty grid
local_gi.swap(*gip);
}
}
else
{
++i;
}
}
}
return true;
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_APPLY_GRIDSHIFT_SHARED_HPP

View File

@@ -0,0 +1,102 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_AUTH_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_AUTH_HPP
#include <cassert>
#include <cmath>
#include <boost/geometry/core/assert.hpp>
namespace boost { namespace geometry { namespace projections {
namespace detail {
template <typename T>
struct apa
{
static const std::size_t size = 3;
T const& operator[](size_t i) const { return data[i]; }
T & operator[](size_t i) { return data[i]; }
private:
T data[3];
};
/* determine latitude from authalic latitude */
template <typename T>
inline detail::apa<T> pj_authset(T const& es)
{
static const T P00 = .33333333333333333333;
static const T P01 = .17222222222222222222;
static const T P02 = .10257936507936507936;
static const T P10 = .06388888888888888888;
static const T P11 = .06640211640211640211;
static const T P20 = .01641501294219154443;
T t = 0;
detail::apa<T> apa;
{
apa[0] = es * P00;
t = es * es;
apa[0] += t * P01;
apa[1] = t * P10;
t *= es;
apa[0] += t * P02;
apa[1] += t * P11;
apa[2] = t * P20;
}
return apa;
}
template <typename T>
inline T pj_authlat(T const& beta, detail::apa<T> const& apa)
{
T const t = beta + beta;
return(beta + apa[0] * sin(t) + apa[1] * sin(t + t) + apa[2] * sin(t + t + t));
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_AUTH_HPP

View File

@@ -0,0 +1,455 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018, 2019.
// Modifications copyright (c) 2017-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUM_SET_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUM_SET_HPP
#include <string>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <boost/geometry/srs/projections/dpar.hpp>
#include <boost/geometry/srs/projections/exception.hpp>
#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/impl/pj_datums.hpp>
#include <boost/geometry/srs/projections/impl/pj_param.hpp>
#include <boost/geometry/srs/projections/proj4.hpp>
#include <boost/geometry/srs/projections/spar.hpp>
namespace boost { namespace geometry { namespace projections {
namespace detail {
/* SEC_TO_RAD = Pi/180/3600 */
template <typename T>
inline T sec_to_rad() { return 4.84813681109535993589914102357e-6; }
/************************************************************************/
/* pj_datum_find_datum() */
/************************************************************************/
template <typename T>
inline const pj_datums_type<T>* pj_datum_find_datum(srs::detail::proj4_parameters const& params)
{
std::string name = pj_get_param_s(params, "datum");
if(! name.empty())
{
/* find the datum definition */
const pj_datums_type<T>* pj_datums = pj_get_datums<T>().first;
const int n = pj_get_datums<T>().second;
int index = -1;
for (int i = 0; i < n && index == -1; i++)
{
if(pj_datums[i].id == name)
{
index = i;
}
}
if (index != -1)
{
return pj_datums + index;
}
else
{
BOOST_THROW_EXCEPTION( projection_exception(error_unknown_ellp_param) );
}
}
return NULL;
}
template <typename T>
inline const pj_datums_type<T>* pj_datum_find_datum(srs::dpar::parameters<T> const& params)
{
typename srs::dpar::parameters<T>::const_iterator
it = pj_param_find(params, srs::dpar::datum);
if (it != params.end())
{
const pj_datums_type<T>* pj_datums = pj_get_datums<T>().first;
const int n = pj_get_datums<T>().second;
int i = it->template get_value<int>();
if (i >= 0 && i < n)
{
return pj_datums + i;
}
else
{
BOOST_THROW_EXCEPTION( projection_exception(error_unknown_ellp_param) );
}
}
return NULL;
}
template
<
typename Params,
typename Param = typename srs::spar::detail::tuples_find_if
<
Params,
srs::spar::detail::is_param_tr<srs::spar::detail::datum_traits>::pred
>::type,
bool IsFound = srs::spar::detail::tuples_is_found<Param>::value
>
struct pj_datum_find_datum_static
{
template <typename T>
static const pj_datums_type<T>* apply(Params const& )
{
const pj_datums_type<T>* pj_datums = pj_get_datums<T>().first;
const int n = pj_get_datums<T>().second;
const int i = srs::spar::detail::datum_traits<Param>::id;
if (i >= 0 && i < n)
{
return pj_datums + i;
}
else
{
// TODO: Implemnt as MPL_ASSERT instead
BOOST_THROW_EXCEPTION( projection_exception(error_unknown_ellp_param) );
}
}
};
template <typename Params, typename Param>
struct pj_datum_find_datum_static<Params, Param, false>
{
template <typename T>
static const pj_datums_type<T>* apply(Params const& )
{
return NULL;
}
};
template <typename T, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline const pj_datums_type<T>* pj_datum_find_datum(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params)
{
return pj_datum_find_datum_static
<
srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>
>::template apply<T>(params);
}
/************************************************************************/
/* pj_datum_find_nadgrids() */
/************************************************************************/
inline bool pj_datum_find_nadgrids(srs::detail::proj4_parameters const& params,
srs::detail::nadgrids & out)
{
std::string snadgrids = pj_get_param_s(params, "nadgrids");
if (! snadgrids.empty())
{
for (std::string::size_type i = 0 ; i < snadgrids.size() ; )
{
std::string::size_type end = snadgrids.find(',', i);
std::string name = snadgrids.substr(i, end - i);
i = end;
if (end != std::string::npos)
++i;
if (! name.empty())
out.push_back(name);
}
}
return ! out.empty();
}
template <typename T>
inline bool pj_datum_find_nadgrids(srs::dpar::parameters<T> const& params,
srs::detail::nadgrids & out)
{
typename srs::dpar::parameters<T>::const_iterator
it = pj_param_find(params, srs::dpar::nadgrids);
if (it != params.end())
{
out = it->template get_value<srs::detail::nadgrids>();
}
return ! out.empty();
}
template
<
typename Params,
int I = srs::spar::detail::tuples_find_index_if
<
Params,
srs::spar::detail::is_param<srs::spar::nadgrids>::pred
>::value,
int N = boost::tuples::length<Params>::value
>
struct pj_datum_find_nadgrids_static
{
static void apply(Params const& params, srs::detail::nadgrids & out)
{
out = boost::tuples::get<I>(params);
}
};
template <typename Params, int N>
struct pj_datum_find_nadgrids_static<Params, N, N>
{
static void apply(Params const& , srs::detail::nadgrids & )
{}
};
template <BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline bool pj_datum_find_nadgrids(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params,
srs::detail::nadgrids & out)
{
pj_datum_find_nadgrids_static
<
srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>
>::apply(params, out);
return ! out.empty();
}
/************************************************************************/
/* pj_datum_find_towgs84() */
/************************************************************************/
template <typename T>
inline bool pj_datum_find_towgs84(srs::detail::proj4_parameters const& params,
srs::detail::towgs84<T> & out)
{
std::string towgs84 = pj_get_param_s(params, "towgs84");
if(! towgs84.empty())
{
std::vector<std::string> parm;
boost::split(parm, towgs84, boost::is_any_of(" ,"));
std::size_t n = (std::min<std::size_t>)(parm.size(), 7);
std::size_t z = n <= 3 ? 3 : 7;
/* parse out the pvalues */
for (std::size_t i = 0 ; i < n; ++i)
{
out.push_back(geometry::str_cast<T>(parm[i]));
}
for (std::size_t i = out.size() ; i < z; ++i)
{
out.push_back(T(0));
}
}
return ! out.empty();
}
template <typename T>
inline bool pj_datum_find_towgs84(srs::dpar::parameters<T> const& params,
srs::detail::towgs84<T> & out)
{
typename srs::dpar::parameters<T>::const_iterator
it = pj_param_find(params, srs::dpar::towgs84);
if (it != params.end())
{
srs::detail::towgs84<T> const&
towgs84 = it->template get_value<srs::detail::towgs84<T> >();
std::size_t n = (std::min<std::size_t>)(towgs84.size(), 7u);
std::size_t z = n <= 3 ? 3 : 7;
for (std::size_t i = 0 ; i < n; ++i)
{
out.push_back(towgs84[i]);
}
for (std::size_t i = out.size() ; i < z; ++i)
{
out.push_back(T(0));
}
}
return ! out.empty();
}
template
<
typename Params,
int I = srs::spar::detail::tuples_find_index_if
<
Params,
srs::spar::detail::is_param_t<srs::spar::towgs84>::pred
>::value,
int N = boost::tuples::length<Params>::value
>
struct pj_datum_find_towgs84_static
{
template <typename T>
static void apply(Params const& params, srs::detail::towgs84<T> & out)
{
typename boost::tuples::element<I, Params>::type const&
towgs84 = boost::tuples::get<I>(params);
std::size_t n = (std::min<std::size_t>)(towgs84.size(), 7u);
std::size_t z = n <= 3 ? 3 : 7;
for (std::size_t i = 0 ; i < n; ++i)
{
out.push_back(towgs84[i]);
}
for (std::size_t i = out.size() ; i < z; ++i)
{
out.push_back(T(0));
}
}
};
template <typename Params, int N>
struct pj_datum_find_towgs84_static<Params, N, N>
{
template <typename T>
static void apply(Params const& , srs::detail::towgs84<T> & )
{}
};
template <typename T, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline bool pj_datum_find_towgs84(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params,
srs::detail::towgs84<T> & out)
{
pj_datum_find_towgs84_static
<
srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>
>::apply(params, out);
return ! out.empty();
}
/************************************************************************/
/* pj_datum_prepare_towgs84() */
/************************************************************************/
template <typename T>
inline bool pj_datum_prepare_towgs84(srs::detail::towgs84<T> & towgs84)
{
if( towgs84.size() == 7
&& (towgs84[3] != 0.0
|| towgs84[4] != 0.0
|| towgs84[5] != 0.0
|| towgs84[6] != 0.0) )
{
static const T sec_to_rad = detail::sec_to_rad<T>();
/* transform from arc seconds to radians */
towgs84[3] *= sec_to_rad;
towgs84[4] *= sec_to_rad;
towgs84[5] *= sec_to_rad;
/* transform from parts per million to scaling factor */
towgs84[6] = (towgs84[6]/1000000.0) + 1;
return true;
}
else
{
return false;
}
}
/************************************************************************/
/* pj_datum_init() */
/************************************************************************/
// This function works differently than the original pj_datum_set().
// It doesn't push parameters defined in datum into params list.
// Instead it tries to use nadgrids and towgs84 and only then
// falls back to nadgrid or towgs84 defiend in datum parameter.
template <typename Params, typename T>
inline void pj_datum_init(Params const& params, parameters<T> & projdef)
{
projdef.datum_type = datum_unknown;
// Check for nadgrids parameter.
if(pj_datum_find_nadgrids(params, projdef.nadgrids))
{
// NOTE: It's different than in the original proj4.
// Nadgrids names are stored in projection definition.
projdef.datum_type = datum_gridshift;
}
// Check for towgs84 parameter.
else if(pj_datum_find_towgs84(params, projdef.datum_params))
{
if (pj_datum_prepare_towgs84(projdef.datum_params))
{
projdef.datum_type = datum_7param;
}
else
{
projdef.datum_type = datum_3param;
}
/* Note that pj_init() will later switch datum_type to
PJD_WGS84 if shifts are all zero, and ellipsoid is WGS84 or GRS80 */
}
// Check for datum parameter.
else
{
const pj_datums_type<T>* datum = pj_datum_find_datum<T>(params);
if (datum != NULL)
{
if (! datum->nadgrids.empty())
{
projdef.nadgrids = datum->nadgrids;
projdef.datum_type = datum_gridshift;
}
else if ( ! datum->towgs84.empty() )
{
projdef.datum_params = datum->towgs84;
if (pj_datum_prepare_towgs84(projdef.datum_params))
{
projdef.datum_type = datum_7param;
}
else
{
projdef.datum_type = datum_3param;
}
}
}
}
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUM_SET_HPP

View File

@@ -0,0 +1,175 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUMS_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUMS_HPP
#include <boost/geometry/srs/projections/par_data.hpp>
#include <boost/geometry/srs/projections/dpar.hpp>
#include <string>
namespace boost { namespace geometry { namespace projections {
namespace detail {
// Originally defined in projects.h
template <typename T>
struct pj_datums_type
{
std::string id; /* datum keyword */
//std::string defn_n; /* e.g. "to_wgs84" */
//std::string defn_v; /* e.g. "0,0,0" */
//std::string ellipse_id; /* ie from ellipse table */
//std::string comments; /* EPSG code, etc */
srs::detail::nadgrids nadgrids;
srs::detail::towgs84<T> towgs84;
srs::dpar::value_ellps ellps;
};
// Originally defined in projects.h
struct pj_prime_meridians_type
{
std::string id; /* prime meridian keyword */
//std::string defn; /* offset from greenwich in DMS format. */
double deg;
};
inline double dms2d(double d, double m, double s, bool east)
{
return (east ? 1 : -1) * (d + m / 60.0 + s / 3600.0);
}
/*
* The ellipse code must match one from pj_ellps.c. The datum id should
* be kept to 12 characters or less if possible. Use the official OGC
* datum name for the comments if available.
*/
template <typename T>
inline std::pair<const pj_datums_type<T>*, int> pj_get_datums()
{
static const pj_datums_type<T> pj_datums[] =
{
{"WGS84", //"towgs84", "0,0,0",
//"WGS84", "",
srs::detail::nadgrids(),
srs::detail::towgs84<T>(0,0,0),
srs::dpar::ellps_wgs84},
{"GGRS87", //"towgs84", "-199.87,74.79,246.62",
//"GRS80", "Greek_Geodetic_Reference_System_1987",
srs::detail::nadgrids(),
srs::detail::towgs84<T>(-199.87,74.79,246.62),
srs::dpar::ellps_grs80},
{"NAD83", //"towgs84", "0,0,0",
//"GRS80", "North_American_Datum_1983",
srs::detail::nadgrids(),
srs::detail::towgs84<T>(0,0,0),
srs::dpar::ellps_grs80},
{"NAD27", //"nadgrids", "@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat",
//"clrk66", "North_American_Datum_1927",
srs::detail::nadgrids("@conus","@alaska","@ntv2_0.gsb","@ntv1_can.dat"),
srs::detail::towgs84<T>(),
srs::dpar::ellps_clrk66},
{"potsdam", //"towgs84", "598.1,73.7,418.2,0.202,0.045,-2.455,6.7",
//"bessel", "Potsdam Rauenberg 1950 DHDN",
srs::detail::nadgrids(),
srs::detail::towgs84<T>(598.1,73.7,418.2,0.202,0.045,-2.455,6.7),
srs::dpar::ellps_bessel},
{"carthage", //"towgs84", "-263.0,6.0,431.0",
//"clrk80ign", "Carthage 1934 Tunisia",
srs::detail::nadgrids(),
srs::detail::towgs84<T>(-263.0,6.0,431.0),
srs::dpar::ellps_clrk80ign},
{"hermannskogel", //"towgs84", "577.326,90.129,463.919,5.137,1.474,5.297,2.4232",
//"bessel", "Hermannskogel",
srs::detail::nadgrids(),
srs::detail::towgs84<T>(577.326,90.129,463.919,5.137,1.474,5.297,2.4232),
srs::dpar::ellps_bessel},
{"ire65", //"towgs84", "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",
//"mod_airy", "Ireland 1965",
srs::detail::nadgrids(),
srs::detail::towgs84<T>(482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15),
srs::dpar::ellps_mod_airy},
{"nzgd49", //"towgs84", "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993",
//"intl", "New Zealand Geodetic Datum 1949",
srs::detail::nadgrids(),
srs::detail::towgs84<T>(59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993),
srs::dpar::ellps_intl},
{"OSGB36", //"towgs84", "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894",
//"airy", "Airy 1830",
srs::detail::nadgrids(),
srs::detail::towgs84<T>(446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894),
srs::dpar::ellps_airy}
};
return std::make_pair(pj_datums, sizeof(pj_datums) / sizeof(pj_datums[0]));
}
static const pj_prime_meridians_type pj_prime_meridians[] =
{
/* id definition */
/* -- ---------- */
{ "greenwich", /*"0dE",*/ 0 },
{ "lisbon", /*"9d07'54.862\"W",*/ dms2d( 9, 7,54.862,false) },
{ "paris", /*"2d20'14.025\"E",*/ dms2d( 2,20,14.025,true) },
{ "bogota", /*"74d04'51.3\"W",*/ dms2d( 74, 4,51.3, false) },
{ "madrid", /*"3d41'16.58\"W",*/ dms2d( 3,41,16.58, false) },
{ "rome", /*"12d27'8.4\"E",*/ dms2d( 12,27, 8.4, true) },
{ "bern", /*"7d26'22.5\"E",*/ dms2d( 7,26,22.5, true) },
{ "jakarta", /*"106d48'27.79\"E",*/ dms2d(106,48,27.79, true) },
{ "ferro", /*"17d40'W",*/ dms2d( 17,40, 0, false) },
{ "brussels", /*"4d22'4.71\"E",*/ dms2d( 4,22,4.71, true) },
{ "stockholm", /*"18d3'29.8\"E",*/ dms2d( 18, 3,29.8, true) },
{ "athens", /*"23d42'58.815\"E",*/ dms2d( 23,42,58.815,true) },
{ "oslo", /*"10d43'22.5\"E",*/ dms2d( 10,43,22.5, true) }
};
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_DATUMS_HPP

View File

@@ -0,0 +1,597 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by
// Barend Gehrels (Geodan, Amsterdam)
// Adam Wulkiewicz
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELL_SET_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELL_SET_HPP
#include <string>
#include <vector>
#include <boost/geometry/formulas/eccentricity_sqr.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/srs/projections/dpar.hpp>
#include <boost/geometry/srs/projections/impl/pj_datum_set.hpp>
#include <boost/geometry/srs/projections/impl/pj_ellps.hpp>
#include <boost/geometry/srs/projections/impl/pj_param.hpp>
#include <boost/geometry/srs/projections/proj4.hpp>
#include <boost/geometry/srs/projections/spar.hpp>
namespace boost { namespace geometry { namespace projections {
namespace detail {
/* set ellipsoid parameters a and es */
template <typename T>
inline T SIXTH() { return .1666666666666666667; } /* 1/6 */
template <typename T>
inline T RA4() { return .04722222222222222222; } /* 17/360 */
template <typename T>
inline T RA6() { return .02215608465608465608; } /* 67/3024 */
template <typename T>
inline T RV4() { return .06944444444444444444; } /* 5/72 */
template <typename T>
inline T RV6() { return .04243827160493827160; } /* 55/1296 */
template <typename T>
inline T pj_ell_b_to_es(T const& a, T const& b)
{
return 1. - (b * b) / (a * a);
}
/************************************************************************/
/* pj_ell_init_ellps() */
/************************************************************************/
// Originally a part of pj_ell_set()
template <typename T>
inline bool pj_ell_init_ellps(srs::detail::proj4_parameters const& params, T &a, T &b)
{
/* check if ellps present and temporarily append its values to pl */
std::string name = pj_get_param_s(params, "ellps");
if (! name.empty())
{
const pj_ellps_type<T>* pj_ellps = pj_get_ellps<T>().first;
const int n = pj_get_ellps<T>().second;
int index = -1;
for (int i = 0; i < n && index == -1; i++)
{
if(pj_ellps[i].id == name)
{
index = i;
}
}
if (index == -1) {
BOOST_THROW_EXCEPTION( projection_exception(error_unknown_ellp_param) );
}
pj_ellps_type<T> const& pj_ellp = pj_ellps[index];
a = pj_ellp.a;
b = pj_ellp.b;
return true;
}
return false;
}
template <typename T>
inline bool pj_ell_init_ellps(srs::dpar::parameters<T> const& params, T &a, T &b)
{
/* check if ellps present and temporarily append its values to pl */
typename srs::dpar::parameters<T>::const_iterator
it = pj_param_find(params, srs::dpar::ellps);
if (it != params.end())
{
if (it->template is_value_set<int>())
{
const pj_ellps_type<T>* pj_ellps = pj_get_ellps<T>().first;
const int n = pj_get_ellps<T>().second;
int i = it->template get_value<int>();
if (i < 0 || i >= n) {
BOOST_THROW_EXCEPTION( projection_exception(error_unknown_ellp_param) );
}
pj_ellps_type<T> const& pj_ellp = pj_ellps[i];
a = pj_ellp.a;
b = pj_ellp.b;
}
else if (it->template is_value_set<T>())
{
a = it->template get_value<T>();
b = a;
}
else if (it->template is_value_set<srs::spheroid<T> >())
{
srs::spheroid<T> const& s = it->template get_value<srs::spheroid<T> >();
a = geometry::get_radius<0>(s);
b = geometry::get_radius<2>(s);
}
else
{
BOOST_THROW_EXCEPTION( projection_exception(error_unknown_ellp_param) );
}
return true;
}
return false;
}
template
<
typename Params,
int I = srs::spar::detail::tuples_find_index_if
<
Params,
srs::spar::detail::is_param_tr<srs::spar::detail::ellps_traits>::pred
>::value,
int N = boost::tuples::length<Params>::value
>
struct pj_ell_init_ellps_static
{
template <typename T>
static bool apply(Params const& params, T &a, T &b)
{
typedef typename boost::tuples::element<I, Params>::type param_type;
typedef srs::spar::detail::ellps_traits<param_type> traits_type;
typedef typename traits_type::template model_type<T>::type model_type;
param_type const& param = boost::tuples::get<I>(params);
model_type const& model = traits_type::template model<T>(param);
a = geometry::get_radius<0>(model);
b = geometry::get_radius<2>(model);
return true;
}
};
template <typename Params, int N>
struct pj_ell_init_ellps_static<Params, N, N>
{
template <typename T>
static bool apply(Params const& , T & , T & )
{
return false;
}
};
template <typename T, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline bool pj_ell_init_ellps(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params,
T &a, T &b)
{
return pj_ell_init_ellps_static
<
srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>
>::apply(params, a, b);
}
/************************************************************************/
/* pj_ell_init() */
/************************************************************************/
/* initialize geographic shape parameters */
// This function works differently than the original pj_ell_set().
// It doesn't push parameters defined in ellps into params list.
// Instead it tries to use size (a, R) and shape (es, e, rf, f, b) parameters
// and then if needed falls back to ellps, then to datum and then to the default WGS84
template <typename Params, typename T>
inline void pj_ell_init(Params const& params, T &a, T &es)
{
/* check for varying forms of ellipsoid input */
a = es = 0.;
/* R takes precedence */
if (pj_param_f<srs::spar::r>(params, "R", srs::dpar::r, a)) {
/* empty */
} else { /* probable elliptical figure */
// Set ellipsoid's size parameter
a = pj_get_param_f<T, srs::spar::a>(params, "a", srs::dpar::a);
bool is_a_set = a != 0.0;
// Set ellipsoid's shape parameter
T b = 0.0;
bool is_ell_set = false;
if (pj_param_f<srs::spar::es>(params, "es", srs::dpar::es, es)) {/* eccentricity squared */
/* empty */
is_ell_set = true;
} else if (pj_param_f<srs::spar::e>(params, "e", srs::dpar::e, es)) { /* eccentricity */
es = es * es;
is_ell_set = true;
} else if (pj_param_f<srs::spar::rf>(params, "rf", srs::dpar::rf, es)) { /* recip flattening */
if (es == 0.0) {
BOOST_THROW_EXCEPTION( projection_exception(error_rev_flattening_is_zero) );
}
es = 1./ es;
es = es * (2. - es);
is_ell_set = true;
} else if (pj_param_f<srs::spar::f>(params, "f", srs::dpar::f, es)) { /* flattening */
es = es * (2. - es);
is_ell_set = true;
} else if (pj_param_f<srs::spar::b>(params, "b", srs::dpar::b, b)) { /* minor axis */
es = pj_ell_b_to_es(a, b);
is_ell_set = true;
} /* else es == 0. and sphere of radius a */
// NOTE: Below when ellps is used to initialize a and es
// b is not set because it only has sense together with a
// but a could have been set separately before, e.g. consider passing:
// a=1 ellps=airy (a=6377563.396 b=6356256.910)
// after setting size parameter a and shape parameter from ellps
// b has to be recalculated
// If ellipsoid's parameters are not set directly
// use ellps parameter
if (! is_a_set || ! is_ell_set) {
T ellps_a = 0, ellps_b = 0;
if (pj_ell_init_ellps(params, ellps_a, ellps_b)) {
if (! is_a_set) {
a = ellps_a;
is_a_set = true;
}
if (! is_ell_set) {
es = pj_ell_b_to_es(ellps_a, ellps_b);
is_ell_set = true;
}
}
}
// If ellipsoid's parameters are not set
// use ellps defined by datum parameter
if (! is_a_set || ! is_ell_set)
{
const pj_datums_type<T>* datum = pj_datum_find_datum<T>(params);
if (datum != NULL)
{
pj_ellps_type<T> const& pj_ellp = pj_get_ellps<T>().first[datum->ellps];
if (! is_a_set) {
a = pj_ellp.a;
is_a_set = true;
}
if (! is_ell_set) {
es = pj_ell_b_to_es(pj_ellp.a, pj_ellp.b);
is_ell_set = true;
}
}
}
// If ellipsoid's parameters are still not set
// use default WGS84
if ((! is_a_set || ! is_ell_set)
&& ! pj_get_param_b<srs::spar::no_defs>(params, "no_defs", srs::dpar::no_defs))
{
pj_ellps_type<T> const& pj_ellp = pj_get_ellps<T>().first[srs::dpar::ellps_wgs84];
if (! is_a_set) {
a = pj_ellp.a;
is_a_set = true;
}
if (! is_ell_set) {
es = pj_ell_b_to_es(pj_ellp.a, pj_ellp.b);
is_ell_set = true;
}
}
if (b == 0.0)
b = a * sqrt(1. - es);
/* following options turn ellipsoid into equivalent sphere */
if (pj_get_param_b<srs::spar::r_au>(params, "R_A", srs::dpar::r_au)) { /* sphere--area of ellipsoid */
a *= 1. - es * (SIXTH<T>() + es * (RA4<T>() + es * RA6<T>()));
es = 0.;
} else if (pj_get_param_b<srs::spar::r_v>(params, "R_V", srs::dpar::r_v)) { /* sphere--vol. of ellipsoid */
a *= 1. - es * (SIXTH<T>() + es * (RV4<T>() + es * RV6<T>()));
es = 0.;
} else if (pj_get_param_b<srs::spar::r_a>(params, "R_a", srs::dpar::r_a)) { /* sphere--arithmetic mean */
a = .5 * (a + b);
es = 0.;
} else if (pj_get_param_b<srs::spar::r_g>(params, "R_g", srs::dpar::r_g)) { /* sphere--geometric mean */
a = sqrt(a * b);
es = 0.;
} else if (pj_get_param_b<srs::spar::r_h>(params, "R_h", srs::dpar::r_h)) { /* sphere--harmonic mean */
a = 2. * a * b / (a + b);
es = 0.;
} else {
T tmp;
bool i = pj_param_r<srs::spar::r_lat_a>(params, "R_lat_a", srs::dpar::r_lat_a, tmp);
if (i || /* sphere--arith. */
pj_param_r<srs::spar::r_lat_g>(params, "R_lat_g", srs::dpar::r_lat_g, tmp)) { /* or geom. mean at latitude */
tmp = sin(tmp);
if (geometry::math::abs(tmp) > geometry::math::half_pi<T>()) {
BOOST_THROW_EXCEPTION( projection_exception(error_ref_rad_larger_than_90) );
}
tmp = 1. - es * tmp * tmp;
a *= i ? .5 * (1. - es + tmp) / ( tmp * sqrt(tmp)) :
sqrt(1. - es) / tmp;
es = 0.;
}
}
}
/* some remaining checks */
if (es < 0.) {
BOOST_THROW_EXCEPTION( projection_exception(error_es_less_than_zero) );
}
if (a <= 0.) {
BOOST_THROW_EXCEPTION( projection_exception(error_major_axis_not_given) );
}
}
template <typename Params>
struct static_srs_tag_check_nonexpanded
{
typedef typename boost::mpl::if_c
<
srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::r>::pred
>::value
|| srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param<srs::spar::r_au>::pred
>::value
|| srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param<srs::spar::r_v>::pred
>::value
|| srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param<srs::spar::r_a>::pred
>::value
|| srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param<srs::spar::r_g>::pred
>::value
|| srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param<srs::spar::r_h>::pred
>::value
|| srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::r_lat_a>::pred
>::value
|| srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::r_lat_g>::pred
>::value,
srs_sphere_tag,
// NOTE: The assumption here is that if the user defines either one of:
// b, es, e, f, rf parameters then he wants to define spheroid, not sphere
typename boost::mpl::if_c
<
srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::b>::pred
>::value
|| srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::es>::pred
>::value
|| srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::e>::pred
>::value
|| srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::rf>::pred
>::value
|| srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::f>::pred
>::value,
srs_spheroid_tag,
void
>::type
>::type type;
};
template <typename Params>
struct static_srs_tag_check_ellps
{
typedef typename geometry::tag
<
typename srs::spar::detail::ellps_traits
<
typename srs::spar::detail::tuples_find_if
<
Params,
srs::spar::detail::is_param_tr<srs::spar::detail::ellps_traits>::pred
>::type
>::template model_type<double>::type // dummy type
>::type type;
};
template <typename Params>
struct static_srs_tag_check_datum
{
typedef typename geometry::tag
<
typename srs::spar::detail::ellps_traits
<
typename srs::spar::detail::datum_traits
<
typename srs::spar::detail::tuples_find_if
<
Params,
srs::spar::detail::is_param_tr<srs::spar::detail::datum_traits>::pred
>::type
>::ellps_type
>::template model_type<double>::type // dummy type
>::type type;
};
template
<
typename Params,
typename NonExpandedTag = typename static_srs_tag_check_nonexpanded
<
Params
>::type,
typename EllpsTag = typename static_srs_tag_check_ellps
<
Params
>::type,
typename DatumTag = typename static_srs_tag_check_datum
<
Params
>::type
>
struct static_srs_tag
{
// User passed one of the non-ellps, non-datum parameters
typedef NonExpandedTag type;
};
template <typename Params, typename EllpsTag, typename DatumTag>
struct static_srs_tag<Params, void, EllpsTag, DatumTag>
{
// User didn't pass neither one of the non-ellps, non-datum parameters
// but passed ellps
typedef EllpsTag type;
};
template <typename Params, typename DatumTag>
struct static_srs_tag<Params, void, void, DatumTag>
{
// User didn't pass neither one of the non-ellps, non-datum parameters
// nor ellps parameter but passed datum parameter
typedef DatumTag type;
};
template <typename Params>
struct static_srs_tag<Params, void, void, void>
{
// User didn't pass any parameter defining model
// so use default or generate error
typedef typename boost::mpl::if_c
<
srs::spar::detail::tuples_exists_if
<
Params, srs::spar::detail::is_param<srs::spar::no_defs>::pred
>::value,
void,
srs_spheroid_tag // WGS84
>::type type;
static const bool is_found = ! boost::is_same<type, void>::value;
BOOST_MPL_ASSERT_MSG((is_found), UNKNOWN_ELLP_PARAM, (Params));
};
template <typename T>
inline void pj_calc_ellipsoid_params(parameters<T> & p, T const& a, T const& es) {
/****************************************************************************************
Calculate a large number of ancillary ellipsoidal parameters, in addition to
the two traditional PROJ defining parameters: Semimajor axis, a, and the
eccentricity squared, es.
Most of these parameters are fairly cheap to compute in comparison to the overall
effort involved in initializing a PJ object. They may, however, take a substantial
part of the time taken in computing an individual point transformation.
So by providing them up front, we can amortize the (already modest) cost over all
transformations carried out over the entire lifetime of a PJ object, rather than
incur that cost for every single transformation.
Most of the parameter calculations here are based on the "angular eccentricity",
i.e. the angle, measured from the semiminor axis, of a line going from the north
pole to one of the foci of the ellipsoid - or in other words: The arc sine of the
eccentricity.
The formulae used are mostly taken from:
Richard H. Rapp: Geometric Geodesy, Part I, (178 pp, 1991).
Columbus, Ohio: Dept. of Geodetic Science
and Surveying, Ohio State University.
****************************************************************************************/
p.a = a;
p.es = es;
/* Compute some ancillary ellipsoidal parameters */
if (p.e==0)
p.e = sqrt(p.es); /* eccentricity */
//p.alpha = asin (p.e); /* angular eccentricity */
/* second eccentricity */
//p.e2 = tan (p.alpha);
//p.e2s = p.e2 * p.e2;
/* third eccentricity */
//p.e3 = (0!=p.alpha)? sin (p.alpha) / sqrt(2 - sin (p.alpha)*sin (p.alpha)): 0;
//p.e3s = p.e3 * p.e3;
/* flattening */
//if (0==p.f)
// p.f = 1 - cos (p.alpha); /* = 1 - sqrt (1 - PIN->es); */
//p.rf = p.f != 0.0 ? 1.0/p.f: HUGE_VAL;
/* second flattening */
//p.f2 = (cos(p.alpha)!=0)? 1/cos (p.alpha) - 1: 0;
//p.rf2 = p.f2 != 0.0 ? 1/p.f2: HUGE_VAL;
/* third flattening */
//p.n = pow (tan (p.alpha/2), 2);
//p.rn = p.n != 0.0 ? 1/p.n: HUGE_VAL;
/* ...and a few more */
//if (0==p.b)
// p.b = (1 - p.f)*p.a;
//p.rb = 1. / p.b;
p.ra = 1. / p.a;
p.one_es = 1. - p.es;
if (p.one_es == 0.) {
BOOST_THROW_EXCEPTION( projection_exception(error_eccentricity_is_one) );
}
p.rone_es = 1./p.one_es;
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELL_SET_HPP

View File

@@ -0,0 +1,130 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELLPS_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELLPS_HPP
#include <string>
namespace boost { namespace geometry { namespace projections {
namespace detail {
// Originally defined in projects.h
template <typename T>
struct pj_ellps_type
{
std::string id; /* ellipse keyword name */
//std::string major; /* a's value */
//std::string ell; /* elliptical parameter value */
//bool is_rf; /* rf or b? */
T a;
T b;
//std::string name; /* comments */
};
inline double b_from_a_rf(double a, double rf)
{
return a * (1.0 - 1.0 / rf);
}
#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF(ID, A, RF, NAME) \
{ID, /*#A, #RF, true,*/ A, b_from_a_rf(A, RF), /*NAME*/}
#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_B(ID, A, B, NAME) \
{ID, /*#A, #B, false,*/ A, B, /*NAME*/}
template <typename T>
inline std::pair<const pj_ellps_type<T>*, int> pj_get_ellps()
{
static const pj_ellps_type<T> pj_ellps[] =
{
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("MERIT", 6378137.0, 298.257, "MERIT 1983"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("SGS85", 6378136.0, 298.257, "Soviet Geodetic System 85"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("GRS80", 6378137.0, 298.257222101, "GRS 1980(IUGG, 1980)"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("IAU76", 6378140.0, 298.257, "IAU 1976"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_B ("airy", 6377563.396, 6356256.910, "Airy 1830"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("APL4.9", 6378137.0, 298.25, "Appl. Physics. 1965"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("NWL9D", 6378145.0, 298.25, "Naval Weapons Lab., 1965"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_B ("mod_airy", 6377340.189, 6356034.446, "Modified Airy"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("andrae", 6377104.43, 300.0, "Andrae 1876 (Den., Iclnd.)"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("aust_SA", 6378160.0, 298.25, "Australian Natl & S. Amer. 1969"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("GRS67", 6378160.0, 298.2471674270, "GRS 67(IUGG 1967)"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("bessel", 6377397.155, 299.1528128, "Bessel 1841"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("bess_nam", 6377483.865, 299.1528128, "Bessel 1841 (Namibia)"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_B ("clrk66", 6378206.4, 6356583.8, "Clarke 1866"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("clrk80", 6378249.145, 293.4663, "Clarke 1880 mod."),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("clrk80ign", 6378249.2, 293.4660212936269, "Clarke 1880 (IGN)."),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("CPM", 6375738.7, 334.29, "Comm. des Poids et Mesures 1799"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("delmbr", 6376428.0, 311.5, "Delambre 1810 (Belgium)"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("engelis", 6378136.05, 298.2566, "Engelis 1985"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("evrst30", 6377276.345, 300.8017, "Everest 1830"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("evrst48", 6377304.063, 300.8017, "Everest 1948"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("evrst56", 6377301.243, 300.8017, "Everest 1956"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("evrst69", 6377295.664, 300.8017, "Everest 1969"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("evrstSS", 6377298.556, 300.8017, "Everest (Sabah & Sarawak)"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("fschr60", 6378166.0, 298.3, "Fischer (Mercury Datum) 1960"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("fschr60m", 6378155.0, 298.3, "Modified Fischer 1960"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("fschr68", 6378150.0, 298.3, "Fischer 1968"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("helmert", 6378200.0, 298.3, "Helmert 1906"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("hough", 6378270.0, 297.0, "Hough"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("intl", 6378388.0, 297.0, "International 1909 (Hayford)"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("krass", 6378245.0, 298.3, "Krassovsky, 1942"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("kaula", 6378163.0, 298.24, "Kaula 1961"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("lerch", 6378139.0, 298.257, "Lerch 1979"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("mprts", 6397300.0, 191.0, "Maupertius 1738"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_B ("new_intl", 6378157.5, 6356772.2, "New International 1967"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_B ("plessis", 6376523.0, 6355863.0, "Plessis 1817 (France)"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_B ("SEasia", 6378155.0, 6356773.3205, "Southeast Asia"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_B ("walbeck", 6376896.0, 6355834.8467, "Walbeck"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("WGS60", 6378165.0, 298.3, "WGS 60"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("WGS66", 6378145.0, 298.25, "WGS 66"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_RF("WGS72", 6378135.0, 298.26, "WGS 72"),
// This has to be consistent with default spheroid and values in pj_datum_transform
// TODO: Define in one place
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_B ("WGS84", 6378137.0, 6356752.3142451793, "WGS 84"),
BOOST_GEOMETRY_PROJECTIONS_DETAIL_PJ_ELLPS_B ("sphere", 6370997.0, 6370997.0, "Normal Sphere (r=6370997)")
};
return std::make_pair(pj_ellps, sizeof(pj_ellps) / sizeof(pj_ellps[0]));
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_ELLPS_HPP

View File

@@ -0,0 +1,101 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_FWD_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_FWD_HPP
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/srs/projections/impl/adjlon.hpp>
#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/math/constants/constants.hpp>
/* general forward projection */
namespace boost { namespace geometry { namespace projections {
namespace detail {
/* forward projection entry */
template <typename Prj, typename LL, typename XY, typename P>
inline void pj_fwd(Prj const& prj, P const& par, LL const& ll, XY& xy)
{
typedef typename P::type calc_t;
static const calc_t EPS = 1.0e-12;
using namespace detail;
calc_t lp_lon = geometry::get_as_radian<0>(ll);
calc_t lp_lat = geometry::get_as_radian<1>(ll);
calc_t const t = geometry::math::abs(lp_lat) - geometry::math::half_pi<calc_t>();
/* check for forward and latitude or longitude overange */
if (t > EPS || geometry::math::abs(lp_lon) > 10.)
{
BOOST_THROW_EXCEPTION( projection_exception(error_lat_or_lon_exceed_limit) );
}
if (geometry::math::abs(t) <= EPS)
{
lp_lat = lp_lat < 0. ? -geometry::math::half_pi<calc_t>() : geometry::math::half_pi<calc_t>();
}
else if (par.geoc)
{
lp_lat = atan(par.rone_es * tan(lp_lat));
}
lp_lon -= par.lam0; /* compute del lp.lam */
if (! par.over)
{
lp_lon = adjlon(lp_lon); /* post_forward del longitude */
}
calc_t x = 0;
calc_t y = 0;
prj.fwd(lp_lon, lp_lat, x, y);
geometry::set<0>(xy, par.fr_meter * (par.a * x + par.x0));
geometry::set<1>(xy, par.fr_meter * (par.a * y + par.y0));
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_FWD_HPP

View File

@@ -0,0 +1,145 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_GAUSS_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_GAUSS_HPP
#include <boost/geometry/srs/projections/constants.hpp>
#include <boost/geometry/srs/projections/exception.hpp>
namespace boost { namespace geometry { namespace projections {
namespace detail {
template <typename T>
struct gauss
{
T C;
T K;
T e;
T ratexp;
};
template <typename T>
inline T srat(T const& esinp, T const& exp)
{
return (math::pow((T(1) - esinp) / (T(1) + esinp), exp));
}
template <typename T>
inline gauss<T> gauss_ini(T const& e, T const& phi0, T& chi, T& rc)
{
static const T fourth_pi = detail::fourth_pi<T>();
using std::asin;
using std::cos;
using std::sin;
using std::sqrt;
using std::tan;
T sphi = 0;
T cphi = 0;
T es = 0;
gauss<T> en;
es = e * e;
en.e = e;
sphi = sin(phi0);
cphi = cos(phi0);
cphi *= cphi;
rc = sqrt(1.0 - es) / (1.0 - es * sphi * sphi);
en.C = sqrt(1.0 + es * cphi * cphi / (1.0 - es));
chi = asin(sphi / en.C);
en.ratexp = 0.5 * en.C * e;
en.K = tan(0.5 * chi + fourth_pi)
/ (math::pow(tan(T(0.5) * phi0 + fourth_pi), en.C) * srat(en.e * sphi, en.ratexp));
return en;
}
template <typename T>
inline void gauss_fwd(gauss<T> const& en, T& lam, T& phi)
{
static const T fourth_pi = detail::fourth_pi<T>();
static const T half_pi = detail::half_pi<T>();
phi = T(2) * atan(en.K * math::pow(tan(T(0.5) * phi + fourth_pi), en.C)
* srat(en.e * sin(phi), en.ratexp) ) - half_pi;
lam *= en.C;
}
template <typename T>
inline void gauss_inv(gauss<T> const& en, T& lam, T& phi)
{
static const int max_iter = 20;
static const T fourth_pi = detail::fourth_pi<T>();
static const T half_pi = detail::half_pi<T>();
static const T del_tol = 1e-14;
lam /= en.C;
const T num = math::pow(tan(T(0.5) * phi + fourth_pi) / en.K, T(1) / en.C);
int i = 0;
for (i = max_iter; i; --i)
{
const T elp_phi = 2.0 * atan(num * srat(en.e * sin(phi), - 0.5 * en.e)) - half_pi;
if (geometry::math::abs(elp_phi - phi) < del_tol)
{
break;
}
phi = elp_phi;
}
/* convergence failed */
if (!i)
{
BOOST_THROW_EXCEPTION( projection_exception(error_non_conv_inv_meri_dist) );
}
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_GAUSS_HPP

View File

@@ -0,0 +1,961 @@
// Boost.Geometry
// This file is manually converted from PROJ4
// This file was modified by Oracle on 2018, 2019.
// Modifications copyright (c) 2018-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// This file was converted to Geometry Library by Adam Wulkiewicz
// Original copyright notice:
// Author: Frank Warmerdam, warmerdam@pobox.com
// Copyright (c) 2000, Frank Warmerdam
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDINFO_HPP
#define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDINFO_HPP
#include <boost/algorithm/string.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/cstdint.hpp>
#include <algorithm>
#include <string>
#include <vector>
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
/************************************************************************/
/* swap_words() */
/* */
/* Convert the byte order of the given word(s) in place. */
/************************************************************************/
inline bool is_lsb()
{
static const int byte_order_test = 1;
static bool result = (1 == ((const unsigned char *) (&byte_order_test))[0]);
return result;
}
inline void swap_words( char *data, int word_size, int word_count )
{
for (int word = 0; word < word_count; word++)
{
for (int i = 0; i < word_size/2; i++)
{
std::swap(data[i], data[word_size-i-1]);
}
data += word_size;
}
}
inline bool cstr_equal(const char * s1, const char * s2, std::size_t n)
{
return std::equal(s1, s1 + n, s2);
}
struct is_trimmable_char
{
inline bool operator()(char ch)
{
return ch == '\n' || ch == ' ';
}
};
// structs originally defined in projects.h
struct pj_ctable
{
struct lp_t { double lam, phi; };
struct flp_t { float lam, phi; };
struct ilp_t { boost::int32_t lam, phi; };
std::string id; // ascii info
lp_t ll; // lower left corner coordinates
lp_t del; // size of cells
ilp_t lim; // limits of conversion matrix
std::vector<flp_t> cvs; // conversion matrix
inline void swap(pj_ctable & r)
{
id.swap(r.id);
std::swap(ll, r.ll);
std::swap(del, r.del);
std::swap(lim, r.lim);
cvs.swap(r.cvs);
}
};
struct pj_gi_load
{
enum format_t { missing = 0, ntv1, ntv2, gtx, ctable, ctable2 };
typedef boost::long_long_type offset_t;
explicit pj_gi_load(std::string const& gname = "",
format_t f = missing,
offset_t off = 0,
bool swap = false)
: gridname(gname)
, format(f)
, grid_offset(off)
, must_swap(swap)
{}
std::string gridname; // identifying name of grid, eg "conus" or ntv2_0.gsb
format_t format; // format of this grid, ie "ctable", "ntv1", "ntv2" or "missing".
offset_t grid_offset; // offset in file, for delayed loading
bool must_swap; // only for NTv2
pj_ctable ct;
inline void swap(pj_gi_load & r)
{
gridname.swap(r.gridname);
std::swap(format, r.format);
std::swap(grid_offset, r.grid_offset);
std::swap(must_swap, r.must_swap);
ct.swap(r.ct);
}
};
struct pj_gi
: pj_gi_load
{
explicit pj_gi(std::string const& gname = "",
pj_gi_load::format_t f = missing,
pj_gi_load::offset_t off = 0,
bool swap = false)
: pj_gi_load(gname, f, off, swap)
{}
std::vector<pj_gi> children;
inline void swap(pj_gi & r)
{
pj_gi_load::swap(r);
children.swap(r.children);
}
};
typedef std::vector<pj_gi> pj_gridinfo;
/************************************************************************/
/* pj_gridinfo_load_ctable() */
/* */
/* Load the data portion of a ctable formatted grid. */
/************************************************************************/
// Originally nad_ctable_load() defined in nad_init.c
template <typename IStream>
bool pj_gridinfo_load_ctable(IStream & is, pj_gi_load & gi)
{
pj_ctable & ct = gi.ct;
// Move the input stream by the size of the proj4 original CTABLE
std::size_t header_size = 80
+ 2 * sizeof(pj_ctable::lp_t)
+ sizeof(pj_ctable::ilp_t)
+ sizeof(pj_ctable::flp_t*);
is.seekg(header_size);
// read all the actual shift values
std::size_t a_size = ct.lim.lam * ct.lim.phi;
ct.cvs.resize(a_size);
std::size_t ch_size = sizeof(pj_ctable::flp_t) * a_size;
is.read(reinterpret_cast<char*>(&ct.cvs[0]), ch_size);
if (is.fail() || std::size_t(is.gcount()) != ch_size)
{
ct.cvs.clear();
//ctable loading failed on fread() - binary incompatible?
return false;
}
return true;
}
/************************************************************************/
/* pj_gridinfo_load_ctable2() */
/* */
/* Load the data portion of a ctable2 formatted grid. */
/************************************************************************/
// Originally nad_ctable2_load() defined in nad_init.c
template <typename IStream>
bool pj_gridinfo_load_ctable2(IStream & is, pj_gi_load & gi)
{
pj_ctable & ct = gi.ct;
is.seekg(160);
// read all the actual shift values
std::size_t a_size = ct.lim.lam * ct.lim.phi;
ct.cvs.resize(a_size);
std::size_t ch_size = sizeof(pj_ctable::flp_t) * a_size;
is.read(reinterpret_cast<char*>(&ct.cvs[0]), ch_size);
if (is.fail() || std::size_t(is.gcount()) != ch_size)
{
//ctable2 loading failed on fread() - binary incompatible?
ct.cvs.clear();
return false;
}
if (! is_lsb())
{
swap_words(reinterpret_cast<char*>(&ct.cvs[0]), 4, (int)a_size * 2);
}
return true;
}
/************************************************************************/
/* pj_gridinfo_load_ntv1() */
/* */
/* NTv1 format. */
/* We process one line at a time. Note that the array storage */
/* direction (e-w) is different in the NTv1 file and what */
/* the CTABLE is supposed to have. The phi/lam are also */
/* reversed, and we have to be aware of byte swapping. */
/************************************************************************/
// originally in pj_gridinfo_load() function
template <typename IStream>
inline bool pj_gridinfo_load_ntv1(IStream & is, pj_gi_load & gi)
{
static const double s2r = math::d2r<double>() / 3600.0;
std::size_t const r_size = gi.ct.lim.lam * 2;
std::size_t const ch_size = sizeof(double) * r_size;
is.seekg(gi.grid_offset);
std::vector<double> row_buf(r_size);
gi.ct.cvs.resize(gi.ct.lim.lam * gi.ct.lim.phi);
for (boost::int32_t row = 0; row < gi.ct.lim.phi; row++ )
{
is.read(reinterpret_cast<char*>(&row_buf[0]), ch_size);
if (is.fail() || std::size_t(is.gcount()) != ch_size)
{
gi.ct.cvs.clear();
return false;
}
if (is_lsb())
swap_words(reinterpret_cast<char*>(&row_buf[0]), 8, (int)r_size);
// convert seconds to radians
for (boost::int32_t i = 0; i < gi.ct.lim.lam; i++ )
{
pj_ctable::flp_t & cvs = gi.ct.cvs[row * gi.ct.lim.lam + (gi.ct.lim.lam - i - 1)];
cvs.phi = (float) (row_buf[i*2] * s2r);
cvs.lam = (float) (row_buf[i*2+1] * s2r);
}
}
return true;
}
/* -------------------------------------------------------------------- */
/* pj_gridinfo_load_ntv2() */
/* */
/* NTv2 format. */
/* We process one line at a time. Note that the array storage */
/* direction (e-w) is different in the NTv2 file and what */
/* the CTABLE is supposed to have. The phi/lam are also */
/* reversed, and we have to be aware of byte swapping. */
/* -------------------------------------------------------------------- */
// originally in pj_gridinfo_load() function
template <typename IStream>
inline bool pj_gridinfo_load_ntv2(IStream & is, pj_gi_load & gi)
{
static const double s2r = math::d2r<double>() / 3600.0;
std::size_t const r_size = gi.ct.lim.lam * 4;
std::size_t const ch_size = sizeof(float) * r_size;
is.seekg(gi.grid_offset);
std::vector<float> row_buf(r_size);
gi.ct.cvs.resize(gi.ct.lim.lam * gi.ct.lim.phi);
for (boost::int32_t row = 0; row < gi.ct.lim.phi; row++ )
{
is.read(reinterpret_cast<char*>(&row_buf[0]), ch_size);
if (is.fail() || std::size_t(is.gcount()) != ch_size)
{
gi.ct.cvs.clear();
return false;
}
if (gi.must_swap)
{
swap_words(reinterpret_cast<char*>(&row_buf[0]), 4, (int)r_size);
}
// convert seconds to radians
for (boost::int32_t i = 0; i < gi.ct.lim.lam; i++ )
{
pj_ctable::flp_t & cvs = gi.ct.cvs[row * gi.ct.lim.lam + (gi.ct.lim.lam - i - 1)];
// skip accuracy values
cvs.phi = (float) (row_buf[i*4] * s2r);
cvs.lam = (float) (row_buf[i*4+1] * s2r);
}
}
return true;
}
/************************************************************************/
/* pj_gridinfo_load_gtx() */
/* */
/* GTX format. */
/************************************************************************/
// originally in pj_gridinfo_load() function
template <typename IStream>
inline bool pj_gridinfo_load_gtx(IStream & is, pj_gi_load & gi)
{
boost::int32_t words = gi.ct.lim.lam * gi.ct.lim.phi;
std::size_t const ch_size = sizeof(float) * words;
is.seekg(gi.grid_offset);
// TODO: Consider changing this unintuitive code
// NOTE: Vertical shift data (one float per point) is stored in a container
// holding horizontal shift data (two floats per point).
gi.ct.cvs.resize((words + 1) / 2);
is.read(reinterpret_cast<char*>(&gi.ct.cvs[0]), ch_size);
if (is.fail() || std::size_t(is.gcount()) != ch_size)
{
gi.ct.cvs.clear();
return false;
}
if (is_lsb())
{
swap_words(reinterpret_cast<char*>(&gi.ct.cvs[0]), 4, words);
}
return true;
}
/************************************************************************/
/* pj_gridinfo_load() */
/* */
/* This function is intended to implement delayed loading of */
/* the data contents of a grid file. The header and related */
/* stuff are loaded by pj_gridinfo_init(). */
/************************************************************************/
template <typename IStream>
inline bool pj_gridinfo_load(IStream & is, pj_gi_load & gi)
{
if (! gi.ct.cvs.empty())
{
return true;
}
if (! is.is_open())
{
return false;
}
// Original platform specific CTable format.
if (gi.format == pj_gi::ctable)
{
return pj_gridinfo_load_ctable(is, gi);
}
// CTable2 format.
else if (gi.format == pj_gi::ctable2)
{
return pj_gridinfo_load_ctable2(is, gi);
}
// NTv1 format.
else if (gi.format == pj_gi::ntv1)
{
return pj_gridinfo_load_ntv1(is, gi);
}
// NTv2 format.
else if (gi.format == pj_gi::ntv2)
{
return pj_gridinfo_load_ntv2(is, gi);
}
// GTX format.
else if (gi.format == pj_gi::gtx)
{
return pj_gridinfo_load_gtx(is, gi);
}
else
{
return false;
}
}
/************************************************************************/
/* pj_gridinfo_parent() */
/* */
/* Seek a parent grid file by name from a grid list */
/************************************************************************/
template <typename It>
inline It pj_gridinfo_parent(It first, It last, std::string const& name)
{
for ( ; first != last ; ++first)
{
if (first->ct.id == name)
return first;
It parent = pj_gridinfo_parent(first->children.begin(), first->children.end(), name);
if( parent != first->children.end() )
return parent;
}
return last;
}
/************************************************************************/
/* pj_gridinfo_init_ntv2() */
/* */
/* Load a ntv2 (.gsb) file. */
/************************************************************************/
template <typename IStream>
inline bool pj_gridinfo_init_ntv2(std::string const& gridname,
IStream & is,
pj_gridinfo & gridinfo)
{
BOOST_STATIC_ASSERT( sizeof(boost::int32_t) == 4 );
BOOST_STATIC_ASSERT( sizeof(double) == 8 );
static const double s2r = math::d2r<double>() / 3600.0;
std::size_t gridinfo_orig_size = gridinfo.size();
// Read the overview header.
char header[11*16];
is.read(header, sizeof(header));
if( is.fail() )
{
return false;
}
bool must_swap = (header[8] == 11)
? !is_lsb()
: is_lsb();
// NOTE: This check is not implemented in proj4
if (! cstr_equal(header + 56, "SECONDS", 7))
{
return false;
}
// Byte swap interesting fields if needed.
if( must_swap )
{
swap_words( header+8, 4, 1 );
swap_words( header+8+16, 4, 1 );
swap_words( header+8+32, 4, 1 );
swap_words( header+8+7*16, 8, 1 );
swap_words( header+8+8*16, 8, 1 );
swap_words( header+8+9*16, 8, 1 );
swap_words( header+8+10*16, 8, 1 );
}
// Get the subfile count out ... all we really use for now.
boost::int32_t num_subfiles;
memcpy( &num_subfiles, header+8+32, 4 );
// Step through the subfiles, creating a PJ_GRIDINFO for each.
for( boost::int32_t subfile = 0; subfile < num_subfiles; subfile++ )
{
// Read header.
is.read(header, sizeof(header));
if( is.fail() )
{
return false;
}
if(! cstr_equal(header, "SUB_NAME", 8))
{
return false;
}
// Byte swap interesting fields if needed.
if( must_swap )
{
swap_words( header+8+16*4, 8, 1 );
swap_words( header+8+16*5, 8, 1 );
swap_words( header+8+16*6, 8, 1 );
swap_words( header+8+16*7, 8, 1 );
swap_words( header+8+16*8, 8, 1 );
swap_words( header+8+16*9, 8, 1 );
swap_words( header+8+16*10, 4, 1 );
}
// Initialize a corresponding "ct" structure.
pj_ctable ct;
pj_ctable::lp_t ur;
ct.id = std::string(header + 8, 8);
ct.ll.lam = - *((double *) (header+7*16+8)); /* W_LONG */
ct.ll.phi = *((double *) (header+4*16+8)); /* S_LAT */
ur.lam = - *((double *) (header+6*16+8)); /* E_LONG */
ur.phi = *((double *) (header+5*16+8)); /* N_LAT */
ct.del.lam = *((double *) (header+9*16+8));
ct.del.phi = *((double *) (header+8*16+8));
ct.lim.lam = (boost::int32_t) (fabs(ur.lam-ct.ll.lam)/ct.del.lam + 0.5) + 1;
ct.lim.phi = (boost::int32_t) (fabs(ur.phi-ct.ll.phi)/ct.del.phi + 0.5) + 1;
ct.ll.lam *= s2r;
ct.ll.phi *= s2r;
ct.del.lam *= s2r;
ct.del.phi *= s2r;
boost::int32_t gs_count;
memcpy( &gs_count, header + 8 + 16*10, 4 );
if( gs_count != ct.lim.lam * ct.lim.phi )
{
return false;
}
//ct.cvs.clear();
// Create a new gridinfo for this if we aren't processing the
// 1st subfile, and initialize our grid info.
// Attach to the correct list or sublist.
// TODO is offset needed?
pj_gi gi(gridname, pj_gi::ntv2, is.tellg(), must_swap);
gi.ct = ct;
if( subfile == 0 )
{
gridinfo.push_back(gi);
}
else if( cstr_equal(header+24, "NONE", 4) )
{
gridinfo.push_back(gi);
}
else
{
pj_gridinfo::iterator git = pj_gridinfo_parent(gridinfo.begin() + gridinfo_orig_size,
gridinfo.end(),
std::string((const char*)header+24, 8));
if( git == gridinfo.end() )
{
gridinfo.push_back(gi);
}
else
{
git->children.push_back(gi);
}
}
// Seek past the data.
is.seekg(gs_count * 16, std::ios::cur);
}
return true;
}
/************************************************************************/
/* pj_gridinfo_init_ntv1() */
/* */
/* Load an NTv1 style Canadian grid shift file. */
/************************************************************************/
template <typename IStream>
inline bool pj_gridinfo_init_ntv1(std::string const& gridname,
IStream & is,
pj_gridinfo & gridinfo)
{
BOOST_STATIC_ASSERT( sizeof(boost::int32_t) == 4 );
BOOST_STATIC_ASSERT( sizeof(double) == 8 );
static const double d2r = math::d2r<double>();
// Read the header.
char header[176];
is.read(header, sizeof(header));
if( is.fail() )
{
return false;
}
// Regularize fields of interest.
if( is_lsb() )
{
swap_words( header+8, 4, 1 );
swap_words( header+24, 8, 1 );
swap_words( header+40, 8, 1 );
swap_words( header+56, 8, 1 );
swap_words( header+72, 8, 1 );
swap_words( header+88, 8, 1 );
swap_words( header+104, 8, 1 );
}
// NTv1 grid shift file has wrong record count, corrupt?
if( *((boost::int32_t *) (header+8)) != 12 )
{
return false;
}
// NOTE: This check is not implemented in proj4
if (! cstr_equal(header + 120, "SECONDS", 7))
{
return false;
}
// Fill in CTABLE structure.
pj_ctable ct;
pj_ctable::lp_t ur;
ct.id = "NTv1 Grid Shift File";
ct.ll.lam = - *((double *) (header+72));
ct.ll.phi = *((double *) (header+24));
ur.lam = - *((double *) (header+56));
ur.phi = *((double *) (header+40));
ct.del.lam = *((double *) (header+104));
ct.del.phi = *((double *) (header+88));
ct.lim.lam = (boost::int32_t) (fabs(ur.lam-ct.ll.lam)/ct.del.lam + 0.5) + 1;
ct.lim.phi = (boost::int32_t) (fabs(ur.phi-ct.ll.phi)/ct.del.phi + 0.5) + 1;
ct.ll.lam *= d2r;
ct.ll.phi *= d2r;
ct.del.lam *= d2r;
ct.del.phi *= d2r;
//ct.cvs.clear();
// is offset needed?
gridinfo.push_back(pj_gi(gridname, pj_gi::ntv1, is.tellg()));
gridinfo.back().ct = ct;
return true;
}
/************************************************************************/
/* pj_gridinfo_init_gtx() */
/* */
/* Load a NOAA .gtx vertical datum shift file. */
/************************************************************************/
template <typename IStream>
inline bool pj_gridinfo_init_gtx(std::string const& gridname,
IStream & is,
pj_gridinfo & gridinfo)
{
BOOST_STATIC_ASSERT( sizeof(boost::int32_t) == 4 );
BOOST_STATIC_ASSERT( sizeof(double) == 8 );
static const double d2r = math::d2r<double>();
// Read the header.
char header[40];
is.read(header, sizeof(header));
if( is.fail() )
{
return false;
}
// Regularize fields of interest and extract.
double xorigin, yorigin, xstep, ystep;
boost::int32_t rows, columns;
if( is_lsb() )
{
swap_words( header+0, 8, 4 );
swap_words( header+32, 4, 2 );
}
memcpy( &yorigin, header+0, 8 );
memcpy( &xorigin, header+8, 8 );
memcpy( &ystep, header+16, 8 );
memcpy( &xstep, header+24, 8 );
memcpy( &rows, header+32, 4 );
memcpy( &columns, header+36, 4 );
// gtx file header has invalid extents, corrupt?
if( xorigin < -360 || xorigin > 360
|| yorigin < -90 || yorigin > 90 )
{
return false;
}
// Fill in CTABLE structure.
pj_ctable ct;
ct.id = "GTX Vertical Grid Shift File";
ct.ll.lam = xorigin;
ct.ll.phi = yorigin;
ct.del.lam = xstep;
ct.del.phi = ystep;
ct.lim.lam = columns;
ct.lim.phi = rows;
// some GTX files come in 0-360 and we shift them back into the
// expected -180 to 180 range if possible. This does not solve
// problems with grids spanning the dateline.
if( ct.ll.lam >= 180.0 )
ct.ll.lam -= 360.0;
if( ct.ll.lam >= 0.0 && ct.ll.lam + ct.del.lam * ct.lim.lam > 180.0 )
{
//"This GTX spans the dateline! This will cause problems." );
}
ct.ll.lam *= d2r;
ct.ll.phi *= d2r;
ct.del.lam *= d2r;
ct.del.phi *= d2r;
//ct.cvs.clear();
// is offset needed?
gridinfo.push_back(pj_gi(gridname, pj_gi::gtx, 40));
gridinfo.back().ct = ct;
return true;
}
/************************************************************************/
/* pj_gridinfo_init_ctable2() */
/* */
/* Read the header portion of a "ctable2" format grid. */
/************************************************************************/
// Originally nad_ctable2_init() defined in nad_init.c
template <typename IStream>
inline bool pj_gridinfo_init_ctable2(std::string const& gridname,
IStream & is,
pj_gridinfo & gridinfo)
{
BOOST_STATIC_ASSERT( sizeof(boost::int32_t) == 4 );
BOOST_STATIC_ASSERT( sizeof(double) == 8 );
char header[160];
is.read(header, sizeof(header));
if( is.fail() )
{
return false;
}
if( !is_lsb() )
{
swap_words( header + 96, 8, 4 );
swap_words( header + 128, 4, 2 );
}
// ctable2 - wrong header!
if (! cstr_equal(header, "CTABLE V2", 9))
{
return false;
}
// read the table header
pj_ctable ct;
ct.id = std::string(header + 16, std::find(header + 16, header + 16 + 80, '\0'));
//memcpy( &ct.ll.lam, header + 96, 8 );
//memcpy( &ct.ll.phi, header + 104, 8 );
//memcpy( &ct.del.lam, header + 112, 8 );
//memcpy( &ct.del.phi, header + 120, 8 );
//memcpy( &ct.lim.lam, header + 128, 4 );
//memcpy( &ct.lim.phi, header + 132, 4 );
memcpy( &ct.ll, header + 96, 40 );
// do some minimal validation to ensure the structure isn't corrupt
if ( (ct.lim.lam < 1) || (ct.lim.lam > 100000)
|| (ct.lim.phi < 1) || (ct.lim.phi > 100000) )
{
return false;
}
// trim white space and newlines off id
boost::trim_right_if(ct.id, is_trimmable_char());
//ct.cvs.clear();
gridinfo.push_back(pj_gi(gridname, pj_gi::ctable2));
gridinfo.back().ct = ct;
return true;
}
/************************************************************************/
/* pj_gridinfo_init_ctable() */
/* */
/* Read the header portion of a "ctable" format grid. */
/************************************************************************/
// Originally nad_ctable_init() defined in nad_init.c
template <typename IStream>
inline bool pj_gridinfo_init_ctable(std::string const& gridname,
IStream & is,
pj_gridinfo & gridinfo)
{
BOOST_STATIC_ASSERT( sizeof(boost::int32_t) == 4 );
BOOST_STATIC_ASSERT( sizeof(double) == 8 );
// 80 + 2*8 + 2*8 + 2*4
char header[120];
// NOTE: in proj4 data is loaded directly into CTABLE
is.read(header, sizeof(header));
if( is.fail() )
{
return false;
}
// NOTE: in proj4 LSB is not checked here
// read the table header
pj_ctable ct;
ct.id = std::string(header, std::find(header, header + 80, '\0'));
memcpy( &ct.ll, header + 80, 40 );
// do some minimal validation to ensure the structure isn't corrupt
if ( (ct.lim.lam < 1) || (ct.lim.lam > 100000)
|| (ct.lim.phi < 1) || (ct.lim.phi > 100000) )
{
return false;
}
// trim white space and newlines off id
boost::trim_right_if(ct.id, is_trimmable_char());
//ct.cvs.clear();
gridinfo.push_back(pj_gi(gridname, pj_gi::ctable));
gridinfo.back().ct = ct;
return true;
}
/************************************************************************/
/* pj_gridinfo_init() */
/* */
/* Open and parse header details from a datum gridshift file */
/* returning a list of PJ_GRIDINFOs for the grids in that */
/* file. This superceeds use of nad_init() for modern */
/* applications. */
/************************************************************************/
template <typename IStream>
inline bool pj_gridinfo_init(std::string const& gridname,
IStream & is,
pj_gridinfo & gridinfo)
{
char header[160];
// Check if the stream is opened.
if (! is.is_open()) {
return false;
}
// Load a header, to determine the file type.
is.read(header, sizeof(header));
if ( is.fail() ) {
return false;
}
is.seekg(0);
// Determine file type.
if ( cstr_equal(header + 0, "HEADER", 6)
&& cstr_equal(header + 96, "W GRID", 6)
&& cstr_equal(header + 144, "TO NAD83 ", 16) )
{
return pj_gridinfo_init_ntv1(gridname, is, gridinfo);
}
else if( cstr_equal(header + 0, "NUM_OREC", 8)
&& cstr_equal(header + 48, "GS_TYPE", 7) )
{
return pj_gridinfo_init_ntv2(gridname, is, gridinfo);
}
else if( boost::algorithm::ends_with(gridname, "gtx")
|| boost::algorithm::ends_with(gridname, "GTX") )
{
return pj_gridinfo_init_gtx(gridname, is, gridinfo);
}
else if( cstr_equal(header + 0, "CTABLE V2", 9) )
{
return pj_gridinfo_init_ctable2(gridname, is, gridinfo);
}
else
{
return pj_gridinfo_init_ctable(gridname, is, gridinfo);
}
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDINFO_HPP

View File

@@ -0,0 +1,174 @@
// Boost.Geometry
// This file is manually converted from PROJ4
// This file was modified by Oracle on 2018.
// Modifications copyright (c) 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// This file was converted to Geometry Library by Adam Wulkiewicz
// Original copyright notice:
// Author: Frank Warmerdam, warmerdam@pobox.com
// Copyright (c) 2000, Frank Warmerdam
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDLIST_HPP
#define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDLIST_HPP
#include <boost/geometry/srs/projections/exception.hpp>
#include <boost/geometry/srs/projections/grids.hpp>
#include <boost/geometry/srs/projections/impl/pj_gridinfo.hpp>
#include <boost/geometry/srs/projections/impl/pj_strerrno.hpp>
#include <boost/geometry/srs/projections/par_data.hpp>
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
/************************************************************************/
/* pj_gridlist_merge_grid() */
/* */
/* Find/load the named gridfile and merge it into the */
/* last_nadgrids_list. */
/************************************************************************/
// Originally one function, here divided into several functions
// with overloads for various types of grids and stream policies
inline bool pj_gridlist_find_all(std::string const& gridname,
pj_gridinfo const& grids,
std::vector<std::size_t> & gridindexes)
{
bool result = false;
for (std::size_t i = 0 ; i < grids.size() ; ++i)
{
if (grids[i].gridname == gridname)
{
result = true;
gridindexes.push_back(i);
}
}
return result;
}
// Fill container with sequentially increasing numbers
inline void pj_gridlist_add_seq_inc(std::vector<std::size_t> & gridindexes,
std::size_t first, std::size_t last)
{
gridindexes.reserve(gridindexes.size() + (last - first));
for ( ; first < last ; ++first)
{
gridindexes.push_back(first);
}
}
// Generic stream policy and standard grids
template <typename StreamPolicy>
inline bool pj_gridlist_merge_gridfile(std::string const& gridname,
StreamPolicy const& stream_policy,
srs::grids & grids,
std::vector<std::size_t> & gridindexes)
{
// Try to find in the existing list of loaded grids. Add all
// matching grids as with NTv2 we can get many grids from one
// file (one shared gridname).
if (pj_gridlist_find_all(gridname, grids.gridinfo, gridindexes))
return true;
std::size_t orig_size = grids.gridinfo.size();
// Try to load the named grid.
typename StreamPolicy::stream_type is;
stream_policy.open(is, gridname);
if (! pj_gridinfo_init(gridname, is, grids.gridinfo))
{
return false;
}
// Add the grid now that it is loaded.
pj_gridlist_add_seq_inc(gridindexes, orig_size, grids.gridinfo.size());
return true;
}
/************************************************************************/
/* pj_gridlist_from_nadgrids() */
/* */
/* This functions loads the list of grids corresponding to a */
/* particular nadgrids string into a list, and returns it. The */
/* list is kept around till a request is made with a different */
/* string in order to cut down on the string parsing cost, and */
/* the cost of building the list of tables each time. */
/************************************************************************/
template <typename StreamPolicy, typename Grids>
inline void pj_gridlist_from_nadgrids(srs::detail::nadgrids const& nadgrids,
StreamPolicy const& stream_policy,
Grids & grids,
std::vector<std::size_t> & gridindexes)
{
// Loop processing names out of nadgrids one at a time.
for (srs::detail::nadgrids::const_iterator it = nadgrids.begin() ;
it != nadgrids.end() ; ++it)
{
bool required = (*it)[0] != '@';
std::string name(it->begin() + (required ? 0 : 1), it->end());
if ( ! pj_gridlist_merge_gridfile(name, stream_policy, grids, gridindexes)
&& required )
{
BOOST_THROW_EXCEPTION( projection_exception(error_failed_to_load_grid) );
}
}
}
template <typename Par, typename GridsStorage>
inline void pj_gridlist_from_nadgrids(Par const& defn, srs::projection_grids<GridsStorage> & grids)
{
BOOST_GEOMETRY_ASSERT(grids.storage_ptr != NULL);
pj_gridlist_from_nadgrids(defn.nadgrids,
grids.storage_ptr->stream_policy,
grids.storage_ptr->hgrids,
grids.hindexes);
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDLIST_HPP

View File

@@ -0,0 +1,122 @@
// Boost.Geometry
// This file is manually converted from PROJ4
// This file was modified by Oracle on 2018, 2019.
// Modifications copyright (c) 2018-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// This file was converted to Geometry Library by Adam Wulkiewicz
// Original copyright notice:
// Author: Frank Warmerdam, warmerdam@pobox.com
// Copyright (c) 2000, Frank Warmerdam
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDLIST_SHARED_HPP
#define BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDLIST_SHARED_HPP
#include <boost/geometry/srs/projections/shared_grids.hpp>
#include <boost/geometry/srs/projections/impl/pj_gridinfo.hpp>
#include <boost/geometry/srs/projections/impl/pj_gridlist.hpp>
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
/************************************************************************/
/* pj_gridlist_merge_grid() */
/* */
/* Find/load the named gridfile and merge it into the */
/* last_nadgrids_list. */
/************************************************************************/
// Generic stream policy and shared grids
template <typename StreamPolicy>
inline bool pj_gridlist_merge_gridfile(std::string const& gridname,
StreamPolicy const& stream_policy,
shared_grids & grids,
std::vector<std::size_t> & gridindexes)
{
// Try to find in the existing list of loaded grids. Add all
// matching grids as with NTv2 we can get many grids from one
// file (one shared gridname).
{
boost::shared_lock<boost::shared_mutex> lock(grids.mutex);
if (pj_gridlist_find_all(gridname, grids.gridinfo, gridindexes))
return true;
}
// Try to load the named grid.
typename StreamPolicy::stream_type is;
stream_policy.open(is, gridname);
pj_gridinfo new_grids;
if (! pj_gridinfo_init(gridname, is, new_grids))
{
return false;
}
// Add the grid now that it is loaded.
std::size_t orig_size = 0;
std::size_t new_size = 0;
{
boost::unique_lock<boost::shared_mutex> lock(grids.mutex);
// Try to find in the existing list of loaded grids again
// in case other thread already added it.
if (pj_gridlist_find_all(gridname, grids.gridinfo, gridindexes))
return true;
orig_size = grids.gridinfo.size();
new_size = orig_size + new_grids.size();
grids.gridinfo.resize(new_size);
for (std::size_t i = 0 ; i < new_grids.size() ; ++ i)
new_grids[i].swap(grids.gridinfo[i + orig_size]);
}
pj_gridlist_add_seq_inc(gridindexes, orig_size, new_size);
return true;
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_IMPL_PJ_GRIDLIST_SHARED_HPP

View File

@@ -0,0 +1,525 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_INIT_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_INIT_HPP
#include <cstdlib>
#include <string>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <boost/mpl/find.hpp>
#include <boost/mpl/if.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/srs/projections/dpar.hpp>
#include <boost/geometry/srs/projections/impl/dms_parser.hpp>
#include <boost/geometry/srs/projections/impl/pj_datum_set.hpp>
#include <boost/geometry/srs/projections/impl/pj_datums.hpp>
#include <boost/geometry/srs/projections/impl/pj_ell_set.hpp>
#include <boost/geometry/srs/projections/impl/pj_param.hpp>
#include <boost/geometry/srs/projections/impl/pj_units.hpp>
#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/proj4.hpp>
#include <boost/geometry/srs/projections/spar.hpp>
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
/************************************************************************/
/* pj_init_proj() */
/************************************************************************/
template <typename T>
inline void pj_init_proj(srs::detail::proj4_parameters const& params,
parameters<T> & par)
{
par.id = pj_get_param_s(params, "proj");
}
template <typename T>
inline void pj_init_proj(srs::dpar::parameters<T> const& params,
parameters<T> & par)
{
typename srs::dpar::parameters<T>::const_iterator it = pj_param_find(params, srs::dpar::proj);
if (it != params.end())
{
par.id = static_cast<srs::dpar::value_proj>(it->template get_value<int>());
}
}
template <typename T, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline void pj_init_proj(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& ,
parameters<T> & par)
{
typedef srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> params_type;
typedef typename srs::spar::detail::tuples_find_if
<
params_type,
srs::spar::detail::is_param_tr<srs::spar::detail::proj_traits>::pred
>::type proj_type;
static const bool is_found = srs::spar::detail::tuples_is_found<proj_type>::value;
BOOST_MPL_ASSERT_MSG((is_found), PROJECTION_NOT_NAMED, (params_type));
par.id = srs::spar::detail::proj_traits<proj_type>::id;
}
/************************************************************************/
/* pj_init_units() */
/************************************************************************/
template <typename T, bool Vertical>
inline void pj_init_units(srs::detail::proj4_parameters const& params,
T & to_meter,
T & fr_meter,
T const& default_to_meter,
T const& default_fr_meter)
{
std::string s;
std::string units = pj_get_param_s(params, Vertical ? "vunits" : "units");
if (! units.empty())
{
static const int n = sizeof(pj_units) / sizeof(pj_units[0]);
int index = -1;
for (int i = 0; i < n && index == -1; i++)
{
if(pj_units[i].id == units)
{
index = i;
}
}
if (index == -1) {
BOOST_THROW_EXCEPTION( projection_exception(error_unknow_unit_id) );
}
s = pj_units[index].to_meter;
}
if (s.empty())
{
s = pj_get_param_s(params, Vertical ? "vto_meter" : "to_meter");
}
// TODO: numerator and denominator could be taken from pj_units
if (! s.empty())
{
std::size_t const pos = s.find('/');
if (pos == std::string::npos)
{
to_meter = geometry::str_cast<T>(s);
}
else
{
T const numerator = geometry::str_cast<T>(s.substr(0, pos));
T const denominator = geometry::str_cast<T>(s.substr(pos + 1));
if (numerator == 0.0 || denominator == 0.0)
{
BOOST_THROW_EXCEPTION( projection_exception(error_unit_factor_less_than_0) );
}
to_meter = numerator / denominator;
}
if (to_meter == 0.0)
{
BOOST_THROW_EXCEPTION( projection_exception(error_unit_factor_less_than_0) );
}
fr_meter = 1. / to_meter;
}
else
{
to_meter = default_to_meter;
fr_meter = default_fr_meter;
}
}
template <typename T, bool Vertical>
inline void pj_init_units(srs::dpar::parameters<T> const& params,
T & to_meter,
T & fr_meter,
T const& default_to_meter,
T const& default_fr_meter)
{
typename srs::dpar::parameters<T>::const_iterator
it = pj_param_find(params, Vertical ? srs::dpar::vunits : srs::dpar::units);
if (it != params.end())
{
static const int n = sizeof(pj_units) / sizeof(pj_units[0]);
const int i = it->template get_value<int>();
if (i >= 0 && i < n)
{
T const numerator = pj_units[i].numerator;
T const denominator = pj_units[i].denominator;
if (numerator == 0.0 || denominator == 0.0)
{
BOOST_THROW_EXCEPTION( projection_exception(error_unit_factor_less_than_0) );
}
to_meter = numerator / denominator;
fr_meter = 1. / to_meter;
}
else
{
BOOST_THROW_EXCEPTION( projection_exception(error_unknow_unit_id) );
}
}
else
{
it = pj_param_find(params, Vertical ? srs::dpar::vto_meter : srs::dpar::to_meter);
if (it != params.end())
{
to_meter = it->template get_value<T>();
fr_meter = 1. / to_meter;
}
else
{
to_meter = default_to_meter;
fr_meter = default_fr_meter;
}
}
}
template
<
typename Params,
bool Vertical,
int UnitsI = srs::spar::detail::tuples_find_index_if
<
Params,
boost::mpl::if_c
<
Vertical,
srs::spar::detail::is_param_t<srs::spar::vunits>,
srs::spar::detail::is_param_tr<srs::spar::detail::units_traits>
>::type::template pred
>::value,
int ToMeterI = srs::spar::detail::tuples_find_index_if
<
Params,
boost::mpl::if_c
<
Vertical,
srs::spar::detail::is_param_t<srs::spar::vto_meter>,
srs::spar::detail::is_param_t<srs::spar::to_meter>
>::type::template pred
>::value,
int N = boost::tuples::length<Params>::value
>
struct pj_init_units_static
: pj_init_units_static<Params, Vertical, UnitsI, N, N>
{};
template <typename Params, bool Vertical, int UnitsI, int N>
struct pj_init_units_static<Params, Vertical, UnitsI, N, N>
{
static const int n = sizeof(pj_units) / sizeof(pj_units[0]);
static const int i = srs::spar::detail::units_traits
<
typename boost::tuples::element<UnitsI, Params>::type
>::id;
static const bool is_valid = i >= 0 && i < n;
BOOST_MPL_ASSERT_MSG((is_valid), UNKNOWN_UNIT_ID, (Params));
template <typename T>
static void apply(Params const& ,
T & to_meter, T & fr_meter,
T const& , T const& )
{
T const numerator = pj_units[i].numerator;
T const denominator = pj_units[i].denominator;
if (numerator == 0.0 || denominator == 0.0)
{
BOOST_THROW_EXCEPTION( projection_exception(error_unit_factor_less_than_0) );
}
to_meter = numerator / denominator;
fr_meter = 1. / to_meter;
}
};
template <typename Params, bool Vertical, int ToMeterI, int N>
struct pj_init_units_static<Params, Vertical, N, ToMeterI, N>
{
template <typename T>
static void apply(Params const& params,
T & to_meter, T & fr_meter,
T const& , T const& )
{
to_meter = boost::tuples::get<ToMeterI>(params).value;
fr_meter = 1. / to_meter;
}
};
template <typename Params, bool Vertical, int N>
struct pj_init_units_static<Params, Vertical, N, N, N>
{
template <typename T>
static void apply(Params const& ,
T & to_meter, T & fr_meter,
T const& default_to_meter, T const& default_fr_meter)
{
to_meter = default_to_meter;
fr_meter = default_fr_meter;
}
};
template <typename T, bool Vertical, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline void pj_init_units(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params,
T & to_meter,
T & fr_meter,
T const& default_to_meter,
T const& default_fr_meter)
{
pj_init_units_static
<
srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>,
Vertical
>::apply(params, to_meter, fr_meter, default_to_meter, default_fr_meter);
}
/************************************************************************/
/* pj_init_pm() */
/************************************************************************/
template <typename T>
inline void pj_init_pm(srs::detail::proj4_parameters const& params, T& val)
{
std::string pm = pj_get_param_s(params, "pm");
if (! pm.empty())
{
int n = sizeof(pj_prime_meridians) / sizeof(pj_prime_meridians[0]);
for (int i = 0; i < n ; i++)
{
if(pj_prime_meridians[i].id == pm)
{
val = pj_prime_meridians[i].deg * math::d2r<T>();
return;
}
}
// TODO: Is this try-catch needed?
// In other cases the bad_str_cast exception is simply thrown
BOOST_TRY
{
val = dms_parser<T, true>::apply(pm).angle();
return;
}
BOOST_CATCH(geometry::bad_str_cast const&)
{
BOOST_THROW_EXCEPTION( projection_exception(error_unknown_prime_meridian) );
}
BOOST_CATCH_END
}
val = 0.0;
}
template <typename T>
inline void pj_init_pm(srs::dpar::parameters<T> const& params, T& val)
{
typename srs::dpar::parameters<T>::const_iterator it = pj_param_find(params, srs::dpar::pm);
if (it != params.end())
{
if (it->template is_value_set<int>())
{
int n = sizeof(pj_prime_meridians) / sizeof(pj_prime_meridians[0]);
int i = it->template get_value<int>();
if (i >= 0 && i < n)
{
val = pj_prime_meridians[i].deg * math::d2r<T>();
return;
}
else
{
BOOST_THROW_EXCEPTION( projection_exception(error_unknown_prime_meridian) );
}
}
else if (it->template is_value_set<T>())
{
val = it->template get_value<T>() * math::d2r<T>();
return;
}
}
val = 0.0;
}
template
<
typename Params,
int I = srs::spar::detail::tuples_find_index_if
<
Params,
srs::spar::detail::is_param_tr<srs::spar::detail::pm_traits>::pred
>::value,
int N = boost::tuples::length<Params>::value
>
struct pj_init_pm_static
{
template <typename T>
static void apply(Params const& params, T & val)
{
typedef typename boost::tuples::element<I, Params>::type param_type;
val = srs::spar::detail::pm_traits<param_type>::value(boost::tuples::get<I>(params));
}
};
template <typename Params, int N>
struct pj_init_pm_static<Params, N, N>
{
template <typename T>
static void apply(Params const& , T & val)
{
val = 0;
}
};
template <typename T, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline void pj_init_pm(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params, T& val)
{
pj_init_pm_static
<
srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>
>::apply(params, val);
}
/************************************************************************/
/* pj_init() */
/* */
/* Main entry point for initialing a PJ projections */
/* definition. */
/************************************************************************/
template <typename T, typename Params>
inline parameters<T> pj_init(Params const& params)
{
parameters<T> pin;
// find projection -> implemented in projection factory
pj_init_proj(params, pin);
// exception thrown in projection<>
// TODO: consider throwing here both projection_unknown_id_exception and
// projection_not_named_exception in order to throw before other exceptions
//if (pin.name.empty())
//{ BOOST_THROW_EXCEPTION( projection_not_named_exception() ); }
// NOTE: proj4 gets defaults from "proj_def.dat".
// In Boost.Geometry this is emulated by manually setting them in
// pj_ell_init and projections aea, lcc and lagrng
/* set datum parameters */
pj_datum_init(params, pin);
/* set ellipsoid/sphere parameters */
pj_ell_init(params, pin.a, pin.es);
pin.a_orig = pin.a;
pin.es_orig = pin.es;
pin.e = sqrt(pin.es);
pin.ra = 1. / pin.a;
pin.one_es = 1. - pin.es;
if (pin.one_es == 0.) {
BOOST_THROW_EXCEPTION( projection_exception(error_eccentricity_is_one) );
}
pin.rone_es = 1./pin.one_es;
/* Now that we have ellipse information check for WGS84 datum */
if( pin.datum_type == datum_3param
&& pin.datum_params[0] == 0.0
&& pin.datum_params[1] == 0.0
&& pin.datum_params[2] == 0.0
&& pin.a == 6378137.0
&& geometry::math::abs(pin.es - 0.006694379990) < 0.000000000050 )/*WGS84/GRS80*/
{
pin.datum_type = datum_wgs84;
}
/* set pin.geoc coordinate system */
pin.geoc = (pin.es && pj_get_param_b<srs::spar::geoc>(params, "geoc", srs::dpar::geoc));
/* over-ranging flag */
pin.over = pj_get_param_b<srs::spar::over>(params, "over", srs::dpar::over);
/* longitude center for wrapping */
pin.is_long_wrap_set = pj_param_r<srs::spar::lon_wrap>(params, "lon_wrap", srs::dpar::lon_wrap, pin.long_wrap_center);
/* central meridian */
pin.lam0 = pj_get_param_r<T, srs::spar::lon_0>(params, "lon_0", srs::dpar::lon_0);
/* central latitude */
pin.phi0 = pj_get_param_r<T, srs::spar::lat_0>(params, "lat_0", srs::dpar::lat_0);
/* false easting and northing */
pin.x0 = pj_get_param_f<T, srs::spar::x_0>(params, "x_0", srs::dpar::x_0);
pin.y0 = pj_get_param_f<T, srs::spar::y_0>(params, "y_0", srs::dpar::y_0);
/* general scaling factor */
if (pj_param_f<srs::spar::k_0>(params, "k_0", srs::dpar::k_0, pin.k0)) {
/* empty */
} else if (pj_param_f<srs::spar::k>(params, "k", srs::dpar::k, pin.k0)) {
/* empty */
} else
pin.k0 = 1.;
if (pin.k0 <= 0.) {
BOOST_THROW_EXCEPTION( projection_exception(error_k_less_than_zero) );
}
/* set units */
pj_init_units<T, false>(params, pin.to_meter, pin.fr_meter, 1., 1.);
pj_init_units<T, true>(params, pin.vto_meter, pin.vfr_meter, pin.to_meter, pin.fr_meter);
/* prime meridian */
pj_init_pm(params, pin.from_greenwich);
return pin;
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_INIT_HPP

View File

@@ -0,0 +1,82 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_INV_HPP
#define BOOST_GEOMETRY_PROJECTIONS_PJ_INV_HPP
#include <boost/geometry/srs/projections/impl/adjlon.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/util/math.hpp>
/* general inverse projection */
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
/* inverse projection entry */
template <typename PRJ, typename LL, typename XY, typename PAR>
inline void pj_inv(PRJ const& prj, PAR const& par, XY const& xy, LL& ll)
{
typedef typename PAR::type calc_t;
static const calc_t EPS = 1.0e-12;
/* can't do as much preliminary checking as with forward */
/* descale and de-offset */
calc_t xy_x = (geometry::get<0>(xy) * par.to_meter - par.x0) * par.ra;
calc_t xy_y = (geometry::get<1>(xy) * par.to_meter - par.y0) * par.ra;
calc_t lon = 0, lat = 0;
prj.inv(xy_x, xy_y, lon, lat); /* inverse project */
lon += par.lam0; /* reduce from del lp.lam */
if (!par.over)
lon = adjlon(lon); /* adjust longitude to CM */
if (par.geoc && geometry::math::abs(geometry::math::abs(lat)-geometry::math::half_pi<calc_t>()) > EPS)
lat = atan(par.one_es * tan(lat));
geometry::set_from_radian<0>(ll, lon);
geometry::set_from_radian<1>(ll, lat);
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif

View File

@@ -0,0 +1,135 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
/* meridional distance for ellipsoid and inverse
** 8th degree - accurate to < 1e-5 meters when used in conjunction
** with typical major axis values.
** Inverse determines phi to EPS (1e-11) radians, about 1e-6 seconds.
*/
#ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_MLFN_HPP
#define BOOST_GEOMETRY_PROJECTIONS_PJ_MLFN_HPP
#include <cstdlib>
#include <boost/geometry/srs/projections/exception.hpp>
#include <boost/geometry/srs/projections/impl/pj_strerrno.hpp>
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry { namespace projections {
namespace detail {
template <typename T>
struct en
{
static const std::size_t size = 5;
T const& operator[](size_t i) const { return data[i]; }
T & operator[](size_t i) { return data[i]; }
private:
T data[5];
};
template <typename T>
inline en<T> pj_enfn(T const& es)
{
static const T C00 = 1.;
static const T C02 = .25;
static const T C04 = .046875;
static const T C06 = .01953125;
static const T C08 = .01068115234375;
static const T C22 = .75;
static const T C44 = .46875;
static const T C46 = .01302083333333333333;
static const T C48 = .00712076822916666666;
static const T C66 = .36458333333333333333;
static const T C68 = .00569661458333333333;
static const T C88 = .3076171875;
T t;
detail::en<T> en;
{
en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08)));
en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08)));
en[2] = (t = es * es) * (C44 - es * (C46 + es * C48));
en[3] = (t *= es) * (C66 - es * C68);
en[4] = t * es * C88;
}
return en;
}
template <typename T>
inline T pj_mlfn(T const& phi, T sphi, T cphi, detail::en<T> const& en)
{
cphi *= sphi;
sphi *= sphi;
return(en[0] * phi - cphi * (en[1] + sphi*(en[2]
+ sphi*(en[3] + sphi*en[4]))));
}
template <typename T>
inline T pj_inv_mlfn(T const& arg, T const& es, detail::en<T> const& en)
{
static const T EPS = 1e-11;
static const int MAX_ITER = 10;
T s, t, phi, k = 1./(1.-es);
int i;
phi = arg;
for (i = MAX_ITER; i ; --i) { /* rarely goes over 2 iterations */
s = sin(phi);
t = 1. - es * s * s;
phi -= t = (pj_mlfn(phi, s, cos(phi), en) - arg) * (t * sqrt(t)) * k;
if (geometry::math::abs(t) < EPS)
return phi;
}
BOOST_THROW_EXCEPTION( projection_exception(error_non_conv_inv_meri_dist) );
return phi;
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif

View File

@@ -0,0 +1,59 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_MSFN_HPP
#define BOOST_GEOMETRY_PROJECTIONS_PJ_MSFN_HPP
namespace boost { namespace geometry { namespace projections {
namespace detail {
/* determine constant small m */
template <typename T>
inline T pj_msfn(T const& sinphi, T const& cosphi, T const& es)
{
return (cosphi / sqrt (1. - es * sinphi * sinphi));
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif

View File

@@ -0,0 +1,653 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_PARAM_HPP
#define BOOST_GEOMETRY_PROJECTIONS_PJ_PARAM_HPP
#include <string>
#include <vector>
#include <boost/geometry/srs/projections/exception.hpp>
#include <boost/geometry/srs/projections/impl/dms_parser.hpp>
#include <boost/geometry/srs/projections/impl/projects.hpp>
#include <boost/geometry/srs/projections/proj4.hpp>
#include <boost/geometry/srs/projections/dpar.hpp>
#include <boost/geometry/srs/projections/spar.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_same.hpp>
#include <iterator>
namespace boost { namespace geometry { namespace projections {
namespace detail {
inline bool pj_param_pred(srs::detail::proj4_parameter const& p, std::string const& name)
{
return p.name == name;
}
template <typename T, typename Id>
inline bool pj_param_pred(srs::dpar::parameter<T> const& p, Id const& id,
typename boost::disable_if_c<boost::is_convertible<Id, std::string>::value>::type * = 0)
{
return p.is_id_equal(id);
}
/* input exists */
template <typename Params, typename Name>
inline typename Params::const_iterator
pj_param_find(Params const& params, Name const& name)
{
typedef typename Params::const_iterator iterator;
for (iterator it = params.begin(); it != params.end(); it++)
{
if (pj_param_pred(*it, name))
{
//it->used = true;
return it;
}
// TODO: needed for pipeline
/*else if (it->name == "step")
{
return pl.end();
}*/
}
return params.end();
}
/*
template
<
typename StaticParams,
typename IsParamPred,
int I = tuples_find_index_if<StaticParams, typename IsParamPred::pred>::value,
int N = boost::tuples::length<StaticParams>::value
>
struct pj_param_find_static
{
typedef boost::tuples::element<I, StaticParams> type;
typedef const type* result_type;
static result_type get(StaticParams const& params)
{
return boost::addressof(boost::get<I>(params));
}
};
template <typename StaticParams, typename IsParamPred, int N>
struct pj_param_find_static<StaticParams, IsParamPred, N>
{
typedef void type;
typedef const type* result_type;
static result_type get(StaticParams const& ) { return NULL; }
};*/
/* input exists */
template <typename Params, typename Name>
inline bool pj_param_exists(Params const& params, Name const& name)
{
return pj_param_find(params, name) != params.end();
}
template <typename Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline bool pj_param_exists(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& )
{
return srs::spar::detail::tuples_is_found
<
typename srs::spar::detail::tuples_find_if
<
srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>,
srs::spar::detail::is_param<Param>::template pred
>::type
>::value;
}
template <template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline bool pj_param_exists(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& )
{
return srs::spar::detail::tuples_is_found
<
typename srs::spar::detail::tuples_find_if
<
srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>,
srs::spar::detail::is_param_t<Param>::template pred
>::type
>::value;
}
template <typename T>
inline void set_value(T & val, srs::detail::proj4_parameter const& p)
{
val = geometry::str_cast<T>(p.value);
}
template <typename T, typename T2>
inline void set_value(T & val, srs::dpar::parameter<T2> const& p)
{
val = p.template get_value<T>();
}
template <typename T>
inline void set_value_r(T & val, srs::detail::proj4_parameter const& p)
{
val = dms_parser<T, true>::apply(p.value.c_str()).angle();
}
template <typename T>
inline void set_value_r(T & val, srs::dpar::parameter<T> const& p)
{
val = p.template get_value<T>() * math::d2r<T>();
}
template <typename Name>
inline void check_name(Name const&)
{
static const bool is_ok = boost::is_convertible<Name, std::string>::value
|| boost::is_same<Name, srs::dpar::name_i>::value
|| boost::is_same<Name, srs::dpar::name_f>::value
|| boost::is_same<Name, srs::dpar::name_r>::value;
BOOST_MPL_ASSERT_MSG((is_ok), INVALID_ARGUMENT, (Name));
}
/* integer input */
template <typename Params, typename Name>
inline bool _pj_param_i(Params const& params, Name const& name, int & par)
{
check_name(name);
typename Params::const_iterator it = pj_param_find(params, name);
if (it != params.end())
{
set_value(par, *it);
return true;
}
return false;
}
/* floating point input */
template <typename T, typename Params, typename Name>
inline bool _pj_param_f(Params const& params, Name const& name, T & par)
{
check_name(name);
typename Params::const_iterator it = pj_param_find(params, name);
if (it != params.end())
{
set_value(par, *it);
return true;
}
return false;
}
/* radians input */
template <typename T, typename Params, typename Name>
inline bool _pj_param_r(Params const& params, Name const& name, T & par)
{
check_name(name);
typename Params::const_iterator it = pj_param_find(params, name);
if (it != params.end())
{
set_value_r(par, *it);
return true;
}
return false;
}
/* bool input */
inline bool _pj_get_param_b(srs::detail::proj4_parameters const& pl, std::string const& name)
{
srs::detail::proj4_parameters::const_iterator it = pj_param_find(pl, name);
if (it != pl.end())
{
switch (it->value[0])
{
case '\0': case 'T': case 't':
return true;
case 'F': case 'f':
return false;
default:
BOOST_THROW_EXCEPTION( projection_exception(error_invalid_boolean_param) );
return false;
}
}
return false;
}
template <typename T>
inline bool _pj_get_param_b(srs::dpar::parameters<T> const& pl, srs::dpar::name_be const& name)
{
bool result = false;
typename srs::dpar::parameters<T>::const_iterator it = pj_param_find(pl, name);
if (it != pl.end())
set_value(result, *it);
return result;
}
/* string input */
inline bool pj_param_s(srs::detail::proj4_parameters const& pl, std::string const& name, std::string & par)
{
srs::detail::proj4_parameters::const_iterator it = pj_param_find(pl, name);
if (it != pl.end())
{
par = it->value;
return true;
}
return false;
}
template
<
typename Params,
template <typename> class IsSamePred,
int I = srs::spar::detail::tuples_find_index_if<Params, IsSamePred>::value,
int N = boost::tuples::length<Params>::value
>
struct _pj_param_x_static
{
static const bool result = true;
template <typename T>
static void apply(Params const& params, T & out)
{
// TODO: int values could be extracted directly from the type
out = boost::tuples::get<I>(params).value;
}
};
template
<
typename Params,
template <typename> class IsSamePred,
int N
>
struct _pj_param_x_static<Params, IsSamePred, N, N>
{
static const bool result = false;
template <typename T>
static void apply(Params const& , T & )
{}
};
template <template <int> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline bool _pj_param_i(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params, int & par)
{
typedef _pj_param_x_static
<
srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>,
srs::spar::detail::is_param_i<Param>::template pred
> impl;
impl::apply(params, par);
return impl::result;
}
template <template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename T>
inline bool _pj_param_f(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params, T & par)
{
typedef _pj_param_x_static
<
srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>,
srs::spar::detail::is_param_t<Param>::template pred
> impl;
impl::apply(params, par);
return impl::result;
}
template <template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename T>
inline bool _pj_param_r(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params, T & par)
{
typedef _pj_param_x_static
<
srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>,
srs::spar::detail::is_param_t<Param>::template pred
> impl;
impl::apply(params, par);
if (impl::result)
par *= math::d2r<T>();
return impl::result;
}
template <typename Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline bool _pj_get_param_b(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& params)
{
return pj_param_exists<Param>(params);
}
//template <typename T, typename Name, typename Value>
//inline bool pj_param_id(srs::dpar::parameters<T> const& pl, Name const& name, Value & par)
//{
// typename srs::dpar::parameters<T>::const_iterator it = pj_param_find(pl, name);
// if (it != pl.end())
// {
// par = static_cast<Value>(it->template get_value<int>());
// return true;
// }
// return false;
//}
// NOTE: In the original code, in pl_ell_set.c there is a function pj_get_param
// which behavior is similar to pj_param but it doesn't set `user` member to TRUE
// while pj_param does in the original code. In Boost.Geometry this member is not used.
template <typename Params, typename Name>
inline int _pj_get_param_i(Params const& pl, Name const& name)
{
int res = 0;
_pj_param_i(pl, name, res);
return res;
}
template <template <int> class Param, typename Params>
inline int _pj_get_param_i(Params const& pl)
{
int res = 0;
_pj_param_i<Param>(pl, res);
return res;
}
template <typename T, typename Params, typename Name>
inline T _pj_get_param_f(Params const& pl, Name const& name)
{
T res = 0;
_pj_param_f(pl, name, res);
return res;
}
template <typename T, template <typename> class Param, typename Params>
inline T _pj_get_param_f(Params const& pl)
{
T res = 0;
_pj_param_f<Param>(pl, res);
return res;
}
template <typename T, typename Params, typename Name>
inline T _pj_get_param_r(Params const& pl, Name const& name)
{
T res = 0;
_pj_param_r(pl, name, res);
return res;
}
template <typename T, template <typename> class Param, typename Params>
inline T _pj_get_param_r(Params const& pl)
{
T res = 0;
_pj_param_r<Param>(pl, res);
return res;
}
inline std::string pj_get_param_s(srs::detail::proj4_parameters const& pl, std::string const& name)
{
std::string res;
pj_param_s(pl, name, res);
return res;
}
// ------------------------------------------------------------------------- //
template <typename Param, typename Name>
inline bool pj_param_exists(srs::detail::proj4_parameters const& pl,
std::string const& sn,
Name const& )
{
return pj_param_exists(pl, sn);
}
template <template <typename> class Param, typename Name>
inline bool pj_param_exists(srs::detail::proj4_parameters const& pl,
std::string const& sn,
Name const& )
{
return pj_param_exists(pl, sn);
}
template <typename Param, typename T, typename Name>
inline bool pj_param_exists(srs::dpar::parameters<T> const& pl,
std::string const& ,
Name const& n)
{
return pj_param_exists(pl, n);
}
template <template <typename> class Param, typename T, typename Name>
inline bool pj_param_exists(srs::dpar::parameters<T> const& pl,
std::string const& ,
Name const& n)
{
return pj_param_exists(pl, n);
}
template <typename Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename Name>
inline bool pj_param_exists(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
std::string const& ,
Name const& )
{
return pj_param_exists<Param>(pl);
}
template <template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename Name>
inline bool pj_param_exists(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
std::string const& ,
Name const& )
{
return pj_param_exists<Param>(pl);
}
template <typename Param>
inline bool pj_get_param_b(srs::detail::proj4_parameters const& pl,
std::string const& sn,
srs::dpar::name_be const& )
{
return _pj_get_param_b(pl, sn);
}
template <typename Param, typename T>
inline bool pj_get_param_b(srs::dpar::parameters<T> const& pl,
std::string const& ,
srs::dpar::name_be const& n)
{
return _pj_get_param_b(pl, n);
}
template <typename Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline bool pj_get_param_b(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
std::string const& ,
srs::dpar::name_be const& )
{
return _pj_get_param_b<Param>(pl);
}
//#define BOOST_GEOMETRY_GET_PARAM_B(PARAMS, NAME) pj_get_param_b(PARAMS, #NAME, srs::dpar::NAME)
template <template <int> class Param>
inline bool pj_param_i(srs::detail::proj4_parameters const& pl,
std::string const& sn,
srs::dpar::name_i const& ,
int & par)
{
return _pj_param_i(pl, sn, par);
}
template <template <int> class Param, typename T>
inline bool pj_param_i(srs::dpar::parameters<T> const& pl,
std::string const& ,
srs::dpar::name_i const& n,
int & par)
{
return _pj_param_i(pl, n, par);
}
template <template <int> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline bool pj_param_i(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
std::string const& ,
srs::dpar::name_i const& ,
int & par)
{
return _pj_param_i<Param>(pl, par);
}
//#define BOOST_GEOMETRY_PARAM_I(PARAMS, NAME, PAR) pj_param_i(PARAMS, #NAME, srs::dpar::NAME, PAR)
template <template <int> class Param>
inline int pj_get_param_i(srs::detail::proj4_parameters const& pl,
std::string const& sn,
srs::dpar::name_i const& )
{
return _pj_get_param_i(pl, sn);
}
template <template <int> class Param, typename T>
inline int pj_get_param_i(srs::dpar::parameters<T> const& pl,
std::string const& ,
srs::dpar::name_i const& n)
{
return _pj_get_param_i(pl, n);
}
template <template <int> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline bool pj_get_param_i(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
std::string const& ,
srs::dpar::name_i const& )
{
return _pj_get_param_i<Param>(pl);
}
//#define BOOST_GEOMETRY_GET_PARAM_I(PARAMS, NAME) pj_get_param_i(PARAMS, #NAME, srs::dpar::NAME)
template <template <typename> class Param, typename T>
inline bool pj_param_f(srs::detail::proj4_parameters const& pl,
std::string const& sn,
srs::dpar::name_f const& ,
T & par)
{
return _pj_param_f(pl, sn, par);
}
template <template <typename> class Param, typename T>
inline bool pj_param_f(srs::dpar::parameters<T> const& pl,
std::string const& ,
srs::dpar::name_f const& n,
T & par)
{
return _pj_param_f(pl, n, par);
}
template <template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename T>
inline bool pj_param_f(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
std::string const& ,
srs::dpar::name_f const& ,
T & par)
{
return _pj_param_f<Param>(pl, par);
}
//#define BOOST_GEOMETRY_PARAM_F(PARAMS, NAME, PAR) pj_param_f(PARAMS, #NAME, srs::dpar::NAME, PAR)
template <typename T, template <typename> class Param>
inline T pj_get_param_f(srs::detail::proj4_parameters const& pl,
std::string const& sn,
srs::dpar::name_f const& )
{
return _pj_get_param_f<T>(pl, sn);
}
template <typename T, template <typename> class Param>
inline T pj_get_param_f(srs::dpar::parameters<T> const& pl,
std::string const& ,
srs::dpar::name_f const& n)
{
return _pj_get_param_f<T>(pl, n);
}
template <typename T, template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline T pj_get_param_f(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
std::string const& ,
srs::dpar::name_f const& )
{
return _pj_get_param_f<T, Param>(pl);
}
//#define BOOST_GEOMETRY_GET_PARAM_F(PARAMS, NAME) pj_get_param_f<T>(PARAMS, #NAME, srs::dpar::NAME)
template <template <typename> class Param, typename T>
inline bool pj_param_r(srs::detail::proj4_parameters const& pl,
std::string const& sn,
srs::dpar::name_r const& ,
T & par)
{
return _pj_param_r(pl, sn, par);
}
template <template <typename> class Param, typename T>
inline bool pj_param_r(srs::dpar::parameters<T> const& pl,
std::string const& ,
srs::dpar::name_r const& n,
T & par)
{
return _pj_param_r(pl, n, par);
}
template <template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename T>
inline bool pj_param_r(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
std::string const& ,
srs::dpar::name_r const& ,
T & par)
{
return _pj_param_r<Param>(pl, par);
}
//#define BOOST_GEOMETRY_PARAM_R(PARAMS, NAME, PAR) pj_param_r(PARAMS, #NAME, srs::dpar::NAME, PAR)
template <typename T, template <typename> class Param>
inline T pj_get_param_r(srs::detail::proj4_parameters const& pl,
std::string const& sn,
srs::dpar::name_r const& )
{
return _pj_get_param_r<T>(pl, sn);
}
template <typename T, template <typename> class Param>
inline T pj_get_param_r(srs::dpar::parameters<T> const& pl,
std::string const& ,
srs::dpar::name_r const& n)
{
return _pj_get_param_r<T>(pl, n);
}
template <typename T, template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline T pj_get_param_r(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& pl,
std::string const& ,
srs::dpar::name_r const& )
{
return _pj_get_param_r<T, Param>(pl);
}
//#define BOOST_GEOMETRY_GET_PARAM_R(PARAMS, NAME) pj_get_param_r<T>(PARAMS, #NAME, srs::dpar::NAME)
} // namespace detail
}}} // namespace boost::geometry::projections
#endif

View File

@@ -0,0 +1,75 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_PHI2_HPP
#define BOOST_GEOMETRY_PROJECTIONS_PHI2_HPP
#include <boost/geometry/srs/projections/exception.hpp>
#include <boost/geometry/srs/projections/impl/pj_strerrno.hpp>
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry { namespace projections {
namespace detail {
template <typename T>
inline T pj_phi2(T const& ts, T const& e)
{
static const T TOL = 1.0e-10;
static const int N_ITER = 15;
T eccnth, Phi, con, dphi;
int i;
eccnth = .5 * e;
Phi = geometry::math::half_pi<T>() - 2. * atan (ts);
i = N_ITER;
do {
con = e * sin (Phi);
dphi = geometry::math::half_pi<T>() - 2. * atan (ts * math::pow((T(1) - con) /
(T(1) + con), eccnth)) - Phi;
Phi += dphi;
} while ( geometry::math::abs(dphi) > TOL && --i);
if (i <= 0)
BOOST_THROW_EXCEPTION( projection_exception(error_non_con_inv_phi2) );
return Phi;
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif

View File

@@ -0,0 +1,95 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_QSFN_HPP
#define BOOST_GEOMETRY_PROJECTIONS_PJ_QSFN_HPP
namespace boost { namespace geometry { namespace projections
{
namespace detail {
/* determine small q */
template <typename T>
inline T pj_qsfn(T const& sinphi, T const& e, T const& one_es)
{
static const T EPSILON = 1.0e-7;
if (e >= EPSILON)
{
T con = e * sinphi;
return (one_es * (sinphi / (1. - con * con) -
(.5 / e) * log ((1. - con) / (1. + con))));
} else
return (sinphi + sinphi);
}
static const int MAX_C = 9;
template <typename T>
struct AUTHALIC
{
T C[MAX_C], CP[MAX_C], CQ[MAX_C];
};
/**
* @brief determine authalic latitude
* @param[in] phi geographic latitude
* @param[in] a initialized structure pointer
* @return authalic latitude
*/
template <typename T>
inline T proj_qsfn(T const& phi, AUTHALIC<T> const& a)
{
T s, s2, sum;
int i = MAX_C;
s = sin(phi);
s2 = s * s;
sum = a.CQ[MAX_C - 1];
while (--i) sum = a.CQ[i] + s2 * sum;
return(s * sum);
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif

View File

@@ -0,0 +1,219 @@
// Boost.Geometry
// This file is manually converted from PROJ4
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// This file was converted to Geometry Library by Adam Wulkiewicz
// Original copyright notice:
// None
/* list of projection system pj_errno values */
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_STRERRNO_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_STRERRNO_HPP
#include <cerrno>
#include <cstring>
#include <sstream>
#include <string>
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
// Originally defined in projects.hpp
/* library errors */
enum error_type
{
error_no_args = -1,
error_no_option_in_init_file = -2,
error_no_colon_in_init_string = -3,
error_proj_not_named = -4,
error_unknown_projection_id = -5,
error_eccentricity_is_one = -6,
error_unknow_unit_id = -7,
error_invalid_boolean_param = -8,
error_unknown_ellp_param = -9,
error_rev_flattening_is_zero = -10,
error_ref_rad_larger_than_90 = -11,
error_es_less_than_zero = -12,
error_major_axis_not_given = -13,
error_lat_or_lon_exceed_limit = -14,
error_invalid_x_or_y = -15,
error_wrong_format_dms_value = -16,
error_non_conv_inv_meri_dist = -17,
error_non_con_inv_phi2 = -18,
error_acos_asin_arg_too_large = -19,
error_tolerance_condition = -20,
error_conic_lat_equal = -21,
error_lat_larger_than_90 = -22,
error_lat1_is_zero = -23,
error_lat_ts_larger_than_90 = -24,
error_control_point_no_dist = -25,
error_no_rotation_proj = -26,
error_w_or_m_zero_or_less = -27,
error_lsat_not_in_range = -28,
error_path_not_in_range = -29,
error_h_less_than_zero = -30,
error_k_less_than_zero = -31,
error_lat_1_or_2_zero_or_90 = -32,
error_lat_0_or_alpha_eq_90 = -33,
error_ellipsoid_use_required = -34,
error_invalid_utm_zone = -35,
error_tcheby_val_out_of_range = -36,
error_failed_to_find_proj = -37,
error_failed_to_load_grid = -38,
error_invalid_m_or_n = -39,
error_n_out_of_range = -40,
error_lat_1_2_unspecified = -41,
error_abs_lat1_eq_abs_lat2 = -42,
error_lat_0_half_pi_from_mean = -43,
error_unparseable_cs_def = -44,
error_geocentric = -45,
error_unknown_prime_meridian = -46,
error_axis = -47,
error_grid_area = -48,
error_invalid_sweep_axis = -49,
error_malformed_pipeline = -50,
error_unit_factor_less_than_0 = -51,
error_invalid_scale = -52,
error_non_convergent = -53,
error_missing_args = -54,
error_lat_0_is_zero = -55,
error_ellipsoidal_unsupported = -56,
error_too_many_inits = -57,
error_invalid_arg = -58
};
static const char *
pj_err_list[] = {
"no arguments in initialization list", /* -1 */
"no options found in 'init' file", /* -2 */
"no colon in init= string", /* -3 */
"projection not named", /* -4 */
"unknown projection id", /* -5 */
"effective eccentricity = 1.", /* -6 */
"unknown unit conversion id", /* -7 */
"invalid boolean param argument", /* -8 */
"unknown elliptical parameter name", /* -9 */
"reciprocal flattening (1/f) = 0", /* -10 */
"|radius reference latitude| > 90", /* -11 */
"squared eccentricity < 0", /* -12 */
"major axis or radius = 0 or not given", /* -13 */
"latitude or longitude exceeded limits", /* -14 */
"invalid x or y", /* -15 */
"improperly formed DMS value", /* -16 */
"non-convergent inverse meridional dist", /* -17 */
"non-convergent inverse phi2", /* -18 */
"acos/asin: |arg| >1.+1e-14", /* -19 */
"tolerance condition error", /* -20 */
"conic lat_1 = -lat_2", /* -21 */
"lat_1 >= 90", /* -22 */
"lat_1 = 0", /* -23 */
"lat_ts >= 90", /* -24 */
"no distance between control points", /* -25 */
"projection not selected to be rotated", /* -26 */
"W <= 0 or M <= 0", /* -27 */
"lsat not in 1-5 range", /* -28 */
"path not in range", /* -29 */
"h <= 0", /* -30 */
"k <= 0", /* -31 */
"lat_0 = 0 or 90 or alpha = 90", /* -32 */
"lat_1=lat_2 or lat_1=0 or lat_2=90", /* -33 */
"elliptical usage required", /* -34 */
"invalid UTM zone number", /* -35 */
"arg(s) out of range for Tcheby eval", /* -36 */
"failed to find projection to be rotated", /* -37 */
"failed to load datum shift file", /* -38 */
"both n & m must be spec'd and > 0", /* -39 */
"n <= 0, n > 1 or not specified", /* -40 */
"lat_1 or lat_2 not specified", /* -41 */
"|lat_1| == |lat_2|", /* -42 */
"lat_0 is pi/2 from mean lat", /* -43 */
"unparseable coordinate system definition", /* -44 */
"geocentric transformation missing z or ellps", /* -45 */
"unknown prime meridian conversion id", /* -46 */
"illegal axis orientation combination", /* -47 */
"point not within available datum shift grids", /* -48 */
"invalid sweep axis, choose x or y", /* -49 */
"malformed pipeline", /* -50 */
"unit conversion factor must be > 0", /* -51 */
"invalid scale", /* -52 */
"non-convergent computation", /* -53 */
"missing required arguments", /* -54 */
"lat_0 = 0", /* -55 */
"ellipsoidal usage unsupported", /* -56 */
"only one +init allowed for non-pipeline operations", /* -57 */
"argument not numerical or out of range", /* -58 */
/* When adding error messages, remember to update ID defines in
projects.h, and transient_error array in pj_transform */
};
inline std::string pj_generic_strerrno(std::string const& msg, int err)
{
std::stringstream ss;
ss << msg << " (" << err << ")";
return ss.str();
}
inline std::string pj_strerrno(int err) {
if (0==err)
{
return "";
}
else if (err > 0)
{
// std::strerror function may be not thread-safe
//return std::strerror(err);
switch(err)
{
#ifdef EINVAL
case EINVAL:
return "Invalid argument";
#endif
#ifdef EDOM
case EDOM:
return "Math argument out of domain of func";
#endif
#ifdef ERANGE
case ERANGE:
return "Math result not representable";
#endif
default:
return pj_generic_strerrno("system error", err);
}
}
else /*if (err < 0)*/
{
size_t adjusted_err = - err - 1;
if (adjusted_err < (sizeof(pj_err_list) / sizeof(char *)))
{
return(pj_err_list[adjusted_err]);
}
else
{
return pj_generic_strerrno("invalid projection system error", err);
}
}
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_STRERRNO_HPP

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,58 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_PJ_TSFN_HPP
#define BOOST_GEOMETRY_PROJECTIONS_PJ_TSFN_HPP
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry { namespace projections {
namespace detail {
/* determine small t */
template <typename T>
inline T pj_tsfn(T const& phi, T sinphi, T const& e)
{
sinphi *= e;
return (tan (.5 * (geometry::math::half_pi<T>() - phi)) /
math::pow((T(1) - sinphi) / (T(1) + sinphi), T(0.5) * e));
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif

View File

@@ -0,0 +1,89 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_UNITS_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_UNITS_HPP
#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry { namespace projections {
namespace detail {
// Originally defined in projects.h
struct pj_units_type
{
std::string id; /* units keyword */
std::string to_meter; /* multiply by value to get meters */
double numerator;
double denominator;
std::string name; /* comments */
};
/* Field 2 that contains the multiplier to convert named units to meters
** may be expressed by either a simple floating point constant or a
** numerator/denomenator values (e.g. 1/1000) */
static const pj_units_type pj_units[] =
{
{ "km", "1000.", 1000.0, 1.0, "Kilometer" },
{ "m", "1.", 1.0, 1.0, "Meter" },
{ "dm", "1/10", 1.0, 10.0, "Decimeter" },
{ "cm", "1/100", 1.0, 100.0, "Centimeter" },
{ "mm", "1/1000", 1.0, 1000.0, "Millimeter" },
{ "kmi", "1852.", 1852.0, 1.0, "International Nautical Mile" },
{ "in", "0.0254", 0.0254, 1.0, "International Inch" },
{ "ft", "0.3048", 0.3048, 1.0, "International Foot" },
{ "yd", "0.9144", 0.9144, 1.0, "International Yard" },
{ "mi", "1609.344", 1609.344, 1.0, "International Statute Mile" },
{ "fath", "1.8288", 1.8288, 1.0, "International Fathom" },
{ "ch", "20.1168", 20.1168, 1.0, "International Chain" },
{ "link", "0.201168", 0.201168, 1.0, "International Link" },
{ "us-in", "1./39.37", 1.0, 39.37, "U.S. Surveyor's Inch" },
{ "us-ft", "0.304800609601219", 0.304800609601219, 1.0, "U.S. Surveyor's Foot" },
{ "us-yd", "0.914401828803658", 0.914401828803658, 1.0, "U.S. Surveyor's Yard" },
{ "us-ch", "20.11684023368047", 20.11684023368047, 1.0, "U.S. Surveyor's Chain" },
{ "us-mi", "1609.347218694437", 1609.347218694437, 1.0, "U.S. Surveyor's Statute Mile" },
{ "ind-yd", "0.91439523", 0.91439523, 1.0, "Indian Yard" },
{ "ind-ft", "0.30479841", 0.30479841, 1.0, "Indian Foot" },
{ "ind-ch", "20.11669506", 20.11669506, 1.0, "Indian Chain" }
};
} // detail
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PJ_UNITS_HPP

View File

@@ -0,0 +1,106 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_ZPOLY1_HPP
#define BOOST_GEOMETRY_PROJECTIONS_ZPOLY1_HPP
#include <boost/geometry/srs/projections/impl/projects.hpp>
namespace boost { namespace geometry { namespace projections { namespace detail {
/* evaluate complex polynomial */
/* note: coefficients are always from C_1 to C_n
** i.e. C_0 == (0., 0)
** n should always be >= 1 though no checks are made
*/
template <typename T>
inline pj_complex<T>
pj_zpoly1(pj_complex<T> z, const pj_complex<T> *C, int n)
{
pj_complex<T> a;
T t;
a = *(C += n);
while (n-- > 0)
{
a.r = (--C)->r + z.r * (t = a.r) - z.i * a.i;
a.i = C->i + z.r * a.i + z.i * t;
}
a.r = z.r * (t = a.r) - z.i * a.i;
a.i = z.r * a.i + z.i * t;
return a;
}
/* evaluate complex polynomial and derivative */
template <typename T>
inline pj_complex<T>
pj_zpolyd1(pj_complex<T> z, const pj_complex<T> *C, int n, pj_complex<T> *der)
{
T t;
bool first = true;
pj_complex<T> a = *(C += n);
pj_complex<T> b = a;
while (n-- > 0)
{
if (first)
{
first = false;
}
else
{
b.r = a.r + z.r * (t = b.r) - z.i * b.i;
b.i = a.i + z.r * b.i + z.i * t;
}
a.r = (--C)->r + z.r * (t = a.r) - z.i * a.i;
a.i = C->i + z.r * a.i + z.i * t;
}
b.r = a.r + z.r * (t = b.r) - z.i * b.i;
b.i = a.i + z.r * b.i + z.i * t;
a.r = z.r * (t = a.r) - z.i * a.i;
a.i = z.r * a.i + z.i * t;
*der = b;
return a;
}
}}}} // namespace boost::geometry::projections::detail
#endif

View File

@@ -0,0 +1,151 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2018.
// Modifications copyright (c) 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_PROJ_MDIST_HPP
#define BOOST_GEOMETRY_PROJECTIONS_PROJ_MDIST_HPP
#include <boost/geometry/srs/projections/exception.hpp>
#include <boost/geometry/srs/projections/impl/pj_strerrno.hpp>
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry { namespace projections
{
namespace detail
{
template <typename T>
struct mdist
{
static const int static_size = 20;
int nb;
T es;
T E;
T b[static_size];
};
template <typename T>
inline bool proj_mdist_ini(T const& es, mdist<T>& b)
{
T numf, numfi, twon1, denf, denfi, ens, t, twon;
T den, El, Es;
T E[mdist<T>::static_size];
int i, j;
/* generate E(e^2) and its terms E[] */
ens = es;
numf = twon1 = denfi = 1.;
denf = 1.;
twon = 4.;
Es = El = E[0] = 1.;
for (i = 1; i < mdist<T>::static_size ; ++i)
{
numf *= (twon1 * twon1);
den = twon * denf * denf * twon1;
t = numf/den;
E[i] = t * ens;
Es -= E[i];
ens *= es;
twon *= 4.;
denf *= ++denfi;
twon1 += 2.;
if (Es == El) /* jump out if no change */
break;
El = Es;
}
b.nb = i - 1;
b.es = es;
b.E = Es;
/* generate b_n coefficients--note: collapse with prefix ratios */
b.b[0] = Es = 1. - Es;
numf = denf = 1.;
numfi = 2.;
denfi = 3.;
for (j = 1; j < i; ++j)
{
Es -= E[j];
numf *= numfi;
denf *= denfi;
b.b[j] = Es * numf / denf;
numfi += 2.;
denfi += 2.;
}
return true;
}
template <typename T>
inline T proj_mdist(T const& phi, T const& sphi, T const& cphi, mdist<T> const& b)
{
T sc, sum, sphi2, D;
int i;
sc = sphi * cphi;
sphi2 = sphi * sphi;
D = phi * b.E - b.es * sc / sqrt(1. - b.es * sphi2);
sum = b.b[i = b.nb];
while (i) sum = b.b[--i] + sphi2 * sum;
return(D + sc * sum);
}
template <typename T>
inline T proj_inv_mdist(T const& dist, mdist<T> const& b)
{
static const T TOL = 1e-14;
T s, t, phi, k;
int i;
k = 1./(1.- b.es);
i = mdist<T>::static_size;
phi = dist;
while ( i-- ) {
s = sin(phi);
t = 1. - b.es * s * s;
phi -= t = (proj_mdist(phi, s, cos(phi), b) - dist) *
(t * sqrt(t)) * k;
if (geometry::math::abs(t) < TOL) /* that is no change */
return phi;
}
/* convergence failed */
BOOST_THROW_EXCEPTION( projection_exception(error_non_conv_inv_meri_dist) );
}
} // namespace detail
}}} // namespace boost::geometry::projections
#endif

View File

@@ -0,0 +1,194 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// This file is manually converted from PROJ4 (projects.h)
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// This file is converted from PROJ4, http://trac.osgeo.org/proj
// PROJ4 is originally written by Gerald Evenden (then of the USGS)
// PROJ4 is maintained by Frank Warmerdam
// PROJ4 is converted to Geometry Library by Barend Gehrels (Geodan, Amsterdam)
// Original copyright notice:
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifndef BOOST_GEOMETRY_PROJECTIONS_IMPL_PROJECTS_HPP
#define BOOST_GEOMETRY_PROJECTIONS_IMPL_PROJECTS_HPP
#include <cstring>
#include <string>
#include <vector>
#include <boost/config.hpp>
#include <boost/geometry/srs/projections/constants.hpp>
#include <boost/geometry/srs/projections/dpar.hpp>
#include <boost/geometry/srs/projections/spar.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_pod.hpp>
namespace boost { namespace geometry { namespace projections
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
/* datum_type values */
enum datum_type
{
datum_unknown = 0,
datum_3param = 1,
datum_7param = 2,
datum_gridshift = 3,
datum_wgs84 = 4 /* WGS84 (or anything considered equivelent) */
};
// Originally defined in proj_internal.h
//enum pj_io_units {
// pj_io_units_whatever = 0, /* Doesn't matter (or depends on pipeline neighbours) */
// pj_io_units_classic = 1, /* Scaled meters (right), projected system */
// pj_io_units_projected = 2, /* Meters, projected system */
// pj_io_units_cartesian = 3, /* Meters, 3D cartesian system */
// pj_io_units_angular = 4 /* Radians */
//};
// Originally defined in proj_internal.h
/* Maximum latitudinal overshoot accepted */
//static const double pj_epsilon_lat = 1e-12;
template <typename T>
struct pj_consts
{
// E L L I P S O I D P A R A M E T E R S
T a; /* semimajor axis (radius if eccentricity==0) */
T ra; /* 1/a */
T e; /* first eccentricity */
T es; /* first eccentricity squared */
T one_es; /* 1 - e^2 */
T rone_es; /* 1/one_es */
T es_orig, a_orig; /* es and a before any +proj related adjustment */
// C O O R D I N A T E H A N D L I N G
int over; /* over-range flag */
int geoc; /* geocentric latitude flag */
int is_latlong; /* proj=latlong ... not really a projection at all */
int is_geocent; /* proj=geocent ... not really a projection at all */
//int need_ellps; /* 0 for operations that are purely cartesian */
//enum pj_io_units left; /* Flags for input/output coordinate types */
//enum pj_io_units right;
// C A R T O G R A P H I C O F F S E T S
T lam0, phi0; /* central longitude, latitude */
T x0, y0/*, z0, t0*/; /* false easting and northing (and height and time) */
// S C A L I N G
T k0; /* general scaling factor */
T to_meter, fr_meter; /* cartesian scaling */
T vto_meter, vfr_meter; /* Vertical scaling. Internal unit [m] */
// D A T U M S A N D H E I G H T S Y S T E M S
detail::datum_type datum_type; /* PJD_UNKNOWN/3PARAM/7PARAM/GRIDSHIFT/WGS84 */
srs::detail::towgs84<T> datum_params; /* Parameters for 3PARAM and 7PARAM */
srs::detail::nadgrids nadgrids; /* Names of horozontal grid files. */
T from_greenwich; /* prime meridian offset (in radians) */
T long_wrap_center; /* 0.0 for -180 to 180, actually in radians*/
bool is_long_wrap_set;
// Initialize all variables
pj_consts()
: a(0), ra(0)
, e(0), es(0), one_es(0), rone_es(0)
, es_orig(0), a_orig(0)
, over(0), geoc(0), is_latlong(0), is_geocent(0)
//, need_ellps(1)
//, left(PJ_IO_UNITS_ANGULAR), right(PJ_IO_UNITS_CLASSIC)
, lam0(0), phi0(0)
, x0(0), y0(0)/*, z0(0), t0(0)*/
, k0(0) , to_meter(0), fr_meter(0), vto_meter(0), vfr_meter(0)
, datum_type(datum_unknown)
, from_greenwich(0), long_wrap_center(0), is_long_wrap_set(false)
{}
};
// PROJ4 complex. Might be replaced with std::complex
template <typename T>
struct pj_complex { T r, i; };
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
/*!
\brief parameters, projection parameters
\details This structure initializes all projections
\ingroup projection
*/
template <typename T>
struct parameters : public detail::pj_consts<T>
{
typedef T type;
struct proj_id
{
proj_id()
: id(srs::dpar::proj_unknown)
{}
proj_id(srs::dpar::value_proj i)
: id(i)
{}
proj_id(std::string const& s)
: id(srs::dpar::proj_unknown)
, name(s)
{}
bool is_unknown() const
{
return id == srs::dpar::proj_unknown && name.empty();
}
// Either one of these is set:
srs::dpar::value_proj id; // id of projection
std::string name; // name of projection
};
proj_id id;
};
}}} // namespace boost::geometry::projections
#endif // BOOST_GEOMETRY_PROJECTIONS_IMPL_PROJECTS_HPP