From b9b0f85560e719278e8d4e9fdc7da998dd5c7857 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Tue, 5 Jun 2018 12:44:36 +0500 Subject: [PATCH 01/62] [util] Add functions to normalize / sum two given values (angles) --- include/boost/geometry/util/math.hpp | 39 +++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/include/boost/geometry/util/math.hpp b/include/boost/geometry/util/math.hpp index e0ab1c899..652ca8507 100644 --- a/include/boost/geometry/util/math.hpp +++ b/include/boost/geometry/util/math.hpp @@ -845,13 +845,50 @@ inline void normalize(T& x, T& y) \brief Normalize a given angle. */ template - inline T normalize_angle(T x) +inline T normalize_angle(T x) { T y = std::fmod(x, T(360)); return y <= -180 ? y + 360 : (y <= 180 ? y : y - 360); } +/*! +\brief The error-free sum of two numbers. +*/ +template +inline T sum_error(T u, T v, T& t) +{ + volatile T s = u + v; + volatile T up = s - v; + volatile T vpp = s - up; + + up -= u; + vpp -= v; + t = -(up + vpp); + + return s; +} + + +/*! +\brief The exact difference of two angles reduced to + (−180°, 180°]. +*/ +template +inline T difference_angle(T x, T y, T& e) +{ + T t, d = normalize_angle(sum_error(std::remainder(-x, T(360)), + std::remainder(y, T(360)), t)); + + // Here y - x = d + t (mod 360), exactly, where d is in (-180,180] and + // abs(t) <= eps (eps = 2^-45 for doubles). The only case where the + // addition of t takes the result outside the range (-180,180] is d = 180 + // and t > 0. The case, d = -180 + eps, t = -eps, can't happen, since + // sum_error would have returned the exact result in such a case (i.e., given t = 0). + return sum_error(d == 180 && t > 0 ? -180 : d, t, e); +} + + /* \brief Evaluate the polynomial in x using Horner's method. */ From 7561d68c086d85ce990e32196dc95874f11ac4c4 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Wed, 6 Jun 2018 09:39:31 +0500 Subject: [PATCH 02/62] [util] Add function for returning NaN (not a number) --- include/boost/geometry/util/math.hpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/include/boost/geometry/util/math.hpp b/include/boost/geometry/util/math.hpp index 652ca8507..f8b3707db 100644 --- a/include/boost/geometry/util/math.hpp +++ b/include/boost/geometry/util/math.hpp @@ -809,6 +809,23 @@ inline void sin_cos_degrees(T const& x, T & sinx, T & cosx) } } +/*! +\brief The NaN (not a number) +*/ +template +inline T NaN() +{ +#if defined(_MSC_VER) + return std::numeric_limits::has_quiet_NaN ? + std::numeric_limits::quiet_NaN() : + (std::numeric_limits::max)(); +#else + return std::numeric_limits::has_quiet_NaN ? + std::numeric_limits::quiet_NaN() : + std::numeric_limits::max(); +#endif +} + /*! \brief Round off a given angle */ @@ -889,7 +906,7 @@ inline T difference_angle(T x, T y, T& e) } -/* +/*! \brief Evaluate the polynomial in x using Horner's method. */ // TODO: adl1995 - Merge these functions with formulas/area_formulas.hpp @@ -909,7 +926,7 @@ inline NT horner_evaluate(NT x, return result; } -/* +/*! \brief Evaluate the polynomial. */ template From 2e064c0f0d1cb0e9fde38643413a76257d11346e Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Wed, 6 Jun 2018 09:42:09 +0500 Subject: [PATCH 03/62] [formulas] Arrange points in canonical form for inverse geodesic problem --- .../geometry/formulas/karney_inverse.hpp | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 include/boost/geometry/formulas/karney_inverse.hpp diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp new file mode 100644 index 000000000..4929f9c0d --- /dev/null +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -0,0 +1,121 @@ +// Boost.Geometry + +// Contributed and/or modified by Adeel Ahmad. + +// 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_FORMULAS_KARNEY_INVERSE_HPP +#define BOOST_GEOMETRY_FORMULAS_KARNEY_INVERSE_HPP + + +#include +#include + +#include +#include + +#include +#include + + +namespace boost { namespace geometry { namespace formula +{ + + +/*! +\brief The solution of the inverse problem of geodesics on latlong coordinates, + after Karney (2011). +\author See +- Charles F.F Karney, Algorithms for geodesics, 2011 +https://arxiv.org/pdf/1109.4448.pdf +*/ +template < + typename CT, + bool EnableDistance, + bool EnableAzimuth, + bool EnableReverseAzimuth = false, + bool EnableReducedLength = false, + bool EnableGeodesicScale = false, + size_t SeriesOrder = 8 +> +class karney_inverse +{ + static const bool CalcQuantities = EnableReducedLength || EnableGeodesicScale; + static const bool CalcAzimuths = EnableAzimuth || EnableReverseAzimuth || CalcQuantities; + static const bool CalcFwdAzimuth = EnableAzimuth || CalcQuantities; + static const bool CalcRevAzimuth = EnableReverseAzimuth || CalcQuantities; + +public: + typedef result_inverse result_type; + + template + static inline result_type apply(T1 const& lo1, + T1 const& la1, + T2 const& lo2, + T2 const& la2, + Spheroid const& spheroid) + { + result_type result; + + CT lat1 = la1; + CT lat2 = la2; + + CT lon1 = lo1; + CT lon2 = lo2; + + CT const c1 = 1; + CT const c2 = 2; + CT const c180 = 180; + CT const c90 = 90; + + // Compute the longitudinal difference. + CT lon12_error; + CT lon12 = math::difference_angle(lon1, lon2, lon12_error); + + int lon12_sign = lon12 >= 0 ? 1 : -1; + + // Make points close to the meridian to lie on it. + lon12 = lon12_sign * math::round_angle(lon12); + lon12_error = math::round_angle((c180 - lon12) - lon12_sign * lon12_error); + + CT lam12 = lon12 * math::d2r(); + CT sin_lam12; + CT cos_lam12; + + lon12 > c90 ? math::sin_cos_degrees(lon12_error, sin_lam12, cos_lam12) + : math::sin_cos_degrees(lon12, sin_lam12, cos_lam12); + + // Make points close to the equator to lie on it. + lat1 = std::abs(lat1) > 90 ? math::NaN() : lat1; + lat2 = std::abs(lat2) > 90 ? math::NaN() : lat2; + + lat1 = math::round_angle(lat1); + lat2 = math::round_angle(lat2); + + // Arrange points in a canonical form, as explained in + // paper Algorithms for geodesics, Eq. (44): + // + // 0 <= lon12 <= 180 + // -90 <= lat1 <= 0 + // lat1 <= lat2 <= -lat1 + int swap_point = std::abs(lat1) < std::abs(lat2) ? -1 : 1; + + if (swap_point < 0) + { + lon12_sign *= -1; + swap(lat1, lat2); + } + + // Enforce lat1 to be <= 0. + int lat_sign = lat1 < 0 ? 1 : -1; + lat1 *= lat_sign; + lat2 *= lat_sign; + } +}; + +}}} // namespace boost::geometry::formula + + +#endif // BOOST_GEOMETRY_FORMULAS_KARNEY_INVERSE_HPP From 276e8e6d7a673a5e9676c4135f23805697a80eee Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Thu, 7 Jun 2018 18:28:22 +0500 Subject: [PATCH 04/62] [formulas] Add function for computing the length at the meridians This method is an integral part of Karney's solution to inverse geodesic problem. It is only invoked for points that lie on the meridian, or are close to it. --- .../geometry/formulas/karney_inverse.hpp | 216 +++++++++++++++++- 1 file changed, 212 insertions(+), 4 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 4929f9c0d..9297034bc 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -49,6 +49,12 @@ class karney_inverse public: typedef result_inverse result_type; + static CT constexpr c0 = 0; + static CT constexpr c1 = 1; + static CT constexpr c2 = 2; + static CT constexpr c3 = 3; + static CT constexpr c180 = 180; + static CT constexpr c90 = 90; template static inline result_type apply(T1 const& lo1, @@ -65,10 +71,16 @@ public: CT lon1 = lo1; CT lon2 = lo2; - CT const c1 = 1; - CT const c2 = 2; - CT const c180 = 180; - CT const c90 = 90; + CT tiny = std::sqrt(std::numeric_limits::min()); + + CT const b = CT(get_radius<2>(spheroid)); + CT const f = formula::flattening(spheroid); + CT const one_minus_f = c1 - f; + CT const two_minus_f = c2 - f; + + CT const n = f / two_minus_f; + CT const e2 = f * two_minus_f; + CT const ep2 = e2 / math::sqr(one_minus_f); // Compute the longitudinal difference. CT lon12_error; @@ -80,6 +92,7 @@ public: lon12 = lon12_sign * math::round_angle(lon12); lon12_error = math::round_angle((c180 - lon12) - lon12_sign * lon12_error); + // Convert to radians. CT lam12 = lon12 * math::d2r(); CT sin_lam12; CT cos_lam12; @@ -112,7 +125,202 @@ public: int lat_sign = lat1 < 0 ? 1 : -1; lat1 *= lat_sign; lat2 *= lat_sign; + + CT sin_beta1, cos_beta1; + math::sin_cos_degrees(lat1, sin_beta1, cos_beta1); + sin_beta1 *= one_minus_f; + + math::normalize(sin_beta1, cos_beta1); + cos_beta1 = std::max(tiny, cos_beta1); + + CT sin_beta2, cos_beta2; + math::sin_cos_degrees(lat2, sin_beta2, cos_beta2); + sin_beta2 *= one_minus_f; + + math::normalize(sin_beta2, cos_beta2); + cos_beta2 = std::max(tiny, cos_beta2); + + // If cos_beta1 < -sin_beta1, then cos_beta2 - cos_beta1 is a + // sensitive measure of the |beta1| - |beta2|. Alternatively, + // (cos_beta1 >= -sin_beta1), abs(sin_beta2) + sin_beta1 is + // a better measure. + // Sometimes these quantities vanish and in that case we + // force beta2 = +/- bet1a exactly. + if (cos_beta1 < -sin_beta1) + { + if (cos_beta1 == cos_beta2) + { + sin_beta2 = sin_beta2 < 0 ? sin_beta1 : + -sin_beta1; + } + } + else + { + if (std::abs(sin_beta2) == -sin_beta1) + { + cos_beta2 = cos_beta1; + } + } + + CT const dn1 = sqrt(c1 + ep2 * math::sqr(sin_beta1)); + CT const dn2 = sqrt(c1 + ep2 * math::sqr(sin_beta2)); + + CT a12, sigma12; + CT m12x, s12x, M21; + + // Index zero element of coeffs_C1 is unused. + CT coeffs_C1[SeriesOrder + 1]; + + bool meridian = lat1 == -90 || sin_lam12 == 0; + + if (meridian) + { + // Endpoints lie on a single full meridian. + + // Point to the target latitude. + CT cos_alpha1 = cos_lam12; + CT sin_alpha1 = sin_lam12; + + // Heading north at the target. + CT cos_alpha2 = 1; + CT sin_alpha2 = 0; + + CT sin_sigma1 = sin_beta1; + CT cos_sigma1 = cos_alpha1 * cos_beta1; + + CT sin_sigma2 = sin_beta2; + CT cos_sigma2 = cos_alpha2 * cos_beta2; + + CT sigma12 = std::atan2(std::max(c0, cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2), + cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2); + + meridian_length(n, ep2, sigma12, sin_sigma1, cos_sigma1, dn1, + sin_sigma2, cos_sigma2, dn2, + cos_beta1, cos_beta2, s12x, + m12x, result.geodesic_scale, M21); + + + if (sigma12 < c1 || m12x >= c0) + { + if (sigma12 < c3 * tiny) + { + sigma12 = m12x = s12x = c0; + } + + m12x *= b; + s12x *= b; + a12 = sigma12 / math::d2r(); + } + else + { + // m12 < 0, i.e., prolate and too close to anti-podal. + meridian = false; + } + } } + + static inline void meridian_length(CT epsilon, CT ep2, CT sigma12, + CT sin_sigma1, CT cos_sigma1, CT dn1, + CT sin_sigma2, CT cos_sigma2, CT dn2, + CT cos_beta1, CT cos_beta2, + CT& s12x, CT& m12x, + CT& M12, CT& M21) + { + CT A12x = 0, J12 = 0; + CT expansion_A1, expansion_A2; + + // Index zero element of coeffs_C1 and coeffs_C2 is unused. + CT coeffs_C1[SeriesOrder + 1]; + CT coeffs_C2[SeriesOrder + 1]; + + if (BOOST_GEOMETRY_CONDITION(EnableDistance) || + BOOST_GEOMETRY_CONDITION(EnableReducedLength) || + BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + { + // Find the coefficients for A1 by computing the + // series expansion using Horner scehme. + expansion_A1 + = series_expansion::evaluate_series_A1(epsilon); + + // Evaluate the coefficients for C1. + series_expansion::evaluate_coeffs_C1(epsilon, coeffs_C1); + + if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || + BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + { + // Find the coefficients for A2 by computing the + // series expansion using Horner scehme. + expansion_A2 + = series_expansion::evaluate_series_A2(epsilon); + + // Evaluate the coefficients for C2. + series_expansion::evaluate_coeffs_C2(epsilon, coeffs_C2); + + A12x = expansion_A1 - expansion_A2; + expansion_A2 += c1; + } + expansion_A1 += c1; + } + + if (BOOST_GEOMETRY_CONDITION(EnableDistance)) + { + CT B1 = series_expansion::sin_cos_series + (sin_sigma2, cos_sigma2, coeffs_C1) + - series_expansion::sin_cos_series + (sin_sigma1, cos_sigma1, coeffs_C1); + + m12x = expansion_A1 * (sigma12 + B1); + + if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || + BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + { + CT B2 = series_expansion::sin_cos_series + (sin_sigma2, cos_sigma2, coeffs_C2) + - series_expansion::sin_cos_series + (sin_sigma1, cos_sigma1, coeffs_C2); + + J12 = A12x * sigma12 + (expansion_A1 * B1 - + expansion_A2 * B2); + } + } + else if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || + BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + { + for (size_t i = 1; i <= SeriesOrder; ++i) + { + coeffs_C2[i] = expansion_A1 * coeffs_C1[i] - + expansion_A2 * coeffs_C2[i]; + } + + J12 = A12x * sigma12 + + (series_expansion::sin_cos_series + (sin_sigma2, + cos_sigma2, + coeffs_C2) + - series_expansion::sin_cos_series + (sin_sigma1, + cos_sigma1, + coeffs_C2)); + } + + if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) + { + m12x = dn2 * (cos_sigma1 * sin_sigma2) - + dn1 * (sin_sigma1 * cos_sigma2) - + cos_sigma1 * cos_sigma2 * J12; + } + + if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + { + CT cos_sigma12 = cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2; + CT t = ep2 * (cos_beta1 - cos_beta2) * + (cos_beta1 + cos_beta2) / (dn1 + dn2); + + M12 = cos_sigma12 + (t * sin_sigma2 - cos_sigma2 * J12) * sin_sigma1 / dn1; + M21 = cos_sigma12 - (t * sin_sigma1 - cos_sigma1 * J12) * sin_sigma2 / dn2; + } + } + }; }}} // namespace boost::geometry::formula From 0344ba5c1a3e596a4558eeb677324bcf7c7d2c30 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Mon, 11 Jun 2018 11:06:18 +0500 Subject: [PATCH 05/62] [formulas] Handle case for equatorial points in inverse problem --- .../geometry/formulas/karney_inverse.hpp | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 9297034bc..59b3cbdef 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -73,6 +73,7 @@ public: CT tiny = std::sqrt(std::numeric_limits::min()); + CT const a = CT(get_radius<0>(spheroid)); CT const b = CT(get_radius<2>(spheroid)); CT const f = formula::flattening(spheroid); CT const one_minus_f = c1 - f; @@ -108,7 +109,7 @@ public: lat2 = math::round_angle(lat2); // Arrange points in a canonical form, as explained in - // paper Algorithms for geodesics, Eq. (44): + // paper, Algorithms for geodesics, Eq. (44): // // 0 <= lon12 <= 180 // -90 <= lat1 <= 0 @@ -141,7 +142,7 @@ public: cos_beta2 = std::max(tiny, cos_beta2); // If cos_beta1 < -sin_beta1, then cos_beta2 - cos_beta1 is a - // sensitive measure of the |beta1| - |beta2|. Alternatively, + // sensitive measure of the |beta1| - |beta2|. Alternatively, // (cos_beta1 >= -sin_beta1), abs(sin_beta2) + sin_beta1 is // a better measure. // Sometimes these quantities vanish and in that case we @@ -173,17 +174,20 @@ public: bool meridian = lat1 == -90 || sin_lam12 == 0; + CT cos_alpha1, sin_alpha1; + CT cos_alpha2, sin_alpha2; + if (meridian) { // Endpoints lie on a single full meridian. // Point to the target latitude. - CT cos_alpha1 = cos_lam12; - CT sin_alpha1 = sin_lam12; + cos_alpha1 = cos_lam12; + sin_alpha1 = sin_lam12; // Heading north at the target. - CT cos_alpha2 = 1; - CT sin_alpha2 = 0; + cos_alpha2 = 1; + sin_alpha2 = 0; CT sin_sigma1 = sin_beta1; CT cos_sigma1 = cos_alpha1 * cos_beta1; @@ -217,6 +221,28 @@ public: meridian = false; } } + + CT omega12, sin_omega12, cos_omega12; + + if (!meridian && sin_beta1 == 0 && + (f <= 0 || lon12_error >= f * c180)) + { + std::cout << "Points lie on the equator." << std::endl; + // Points lie on the equator. + cos_alpha1 = cos_alpha2 = c0; + sin_alpha1 = sin_alpha2 = c1; + + s12x = a * lam12; + sigma12 = omega12 = lam12 / one_minus_f; + m12x = b * sin(sigma12); + + if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + { + result.geodesic_scale = cos(sigma12); + M21 = cos(sigma12); + } + a12 = lon12 / one_minus_f; + } } static inline void meridian_length(CT epsilon, CT ep2, CT sigma12, From 485a2f9a0f6d245ae3b2fb3762e664ced7754ea9 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Mon, 11 Jun 2018 18:44:27 +0500 Subject: [PATCH 06/62] [formulas] Find starting point for inverse problem (short lines) --- .../geometry/formulas/karney_inverse.hpp | 166 ++++++++++++++++-- 1 file changed, 156 insertions(+), 10 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 59b3cbdef..0f3c686ed 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -50,11 +50,17 @@ class karney_inverse public: typedef result_inverse result_type; static CT constexpr c0 = 0; + static CT constexpr c0_001 = 0.001; + static CT constexpr c0_01 = 0.01; + static CT constexpr c0_1 = 0.1; + static CT constexpr c0_5 = 0.5; static CT constexpr c1 = 1; static CT constexpr c2 = 2; static CT constexpr c3 = 3; - static CT constexpr c180 = 180; + static CT constexpr c6 = 6; static CT constexpr c90 = 90; + static CT constexpr c180 = 180; + static CT constexpr c200 = 200; template static inline result_type apply(T1 const& lo1, @@ -71,14 +77,20 @@ public: CT lon1 = lo1; CT lon2 = lo2; - CT tiny = std::sqrt(std::numeric_limits::min()); - CT const a = CT(get_radius<0>(spheroid)); CT const b = CT(get_radius<2>(spheroid)); CT const f = formula::flattening(spheroid); CT const one_minus_f = c1 - f; CT const two_minus_f = c2 - f; + CT const tol0 = std::numeric_limits::epsilon(); + CT const tol1 = c200 * tol0; + CT const tol2 = sqrt(tol0); + CT const etol2 = c0_1 * tol2 / + sqrt(std::max(c0_001, std::abs(f)) * std::min(c1, c1 - f / c2) / c2); + + CT tiny = std::sqrt(std::numeric_limits::min()); + CT const n = f / two_minus_f; CT const e2 = f * two_minus_f; CT const ep2 = e2 / math::sqr(one_minus_f); @@ -198,10 +210,12 @@ public: CT sigma12 = std::atan2(std::max(c0, cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2), cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2); + CT dummy; meridian_length(n, ep2, sigma12, sin_sigma1, cos_sigma1, dn1, sin_sigma2, cos_sigma2, dn2, cos_beta1, cos_beta2, s12x, - m12x, result.geodesic_scale, M21); + m12x, dummy, result.geodesic_scale, + M21, coeffs_C1); if (sigma12 < c1 || m12x >= c0) @@ -227,7 +241,6 @@ public: if (!meridian && sin_beta1 == 0 && (f <= 0 || lon12_error >= f * c180)) { - std::cout << "Points lie on the equator." << std::endl; // Points lie on the equator. cos_alpha1 = cos_alpha2 = c0; sin_alpha1 = sin_alpha2 = c1; @@ -239,24 +252,37 @@ public: if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) { result.geodesic_scale = cos(sigma12); - M21 = cos(sigma12); } a12 = lon12 / one_minus_f; } + + else if (!meridian) + { + // If point1 and point2 belong within a hemisphere bounded by a + // meridian and geodesic is neither meridional nor equatorial. + + // Find the starting point for Newton's method. + CT dnm; + sigma12 = newton_start(sin_beta1, cos_beta1, dn1, + sin_beta2, cos_beta2, dn2, + lam12, sin_lam12, cos_lam12, + sin_alpha1, cos_alpha1, + sin_alpha2, cos_alpha2, + dnm, coeffs_C1, ep2, etol2, n, f); + } } static inline void meridian_length(CT epsilon, CT ep2, CT sigma12, CT sin_sigma1, CT cos_sigma1, CT dn1, CT sin_sigma2, CT cos_sigma2, CT dn2, CT cos_beta1, CT cos_beta2, - CT& s12x, CT& m12x, - CT& M12, CT& M21) + CT& s12x, CT& m12x, CT& m0, + CT& M12, CT& M21, CT coeffs_C1[]) { CT A12x = 0, J12 = 0; CT expansion_A1, expansion_A2; - // Index zero element of coeffs_C1 and coeffs_C2 is unused. - CT coeffs_C1[SeriesOrder + 1]; + // Index zero element of coeffs_C2 is unused. CT coeffs_C2[SeriesOrder + 1]; if (BOOST_GEOMETRY_CONDITION(EnableDistance) || @@ -331,6 +357,8 @@ public: if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) { + m0 = A12x; + m12x = dn2 * (cos_sigma1 * sin_sigma2) - dn1 * (sin_sigma1 * cos_sigma2) - cos_sigma1 * cos_sigma2 * J12; @@ -347,6 +375,124 @@ public: } } + /* + Return a starting point for Newton's method in sin_alpha1 and + cos_alpha1 (function value is -1). If Newton's method + doesn't need to be used, return also sin_alpha2 and + cos_alpha2 and function value is sig12. + */ + static inline CT newton_start(CT sin_beta1, CT cos_beta1, CT dn1, + CT sin_beta2, CT cos_beta2, CT dn2, + CT lam12, CT sin_lam12, CT cos_lam12, + CT& sin_alpha1, CT& cos_alpha1, + CT& sin_alpha2, CT& cos_alpha2, + CT& dnm, CT coeffs_C1[], CT ep2, + CT etol2, CT n, CT f) + { + CT const one_minus_f = c1 - f; + CT sig12 = -c1; + + CT sin_beta12 = sin_beta2 * cos_beta1 - cos_beta2 * sin_beta1; + CT cos_beta12 = cos_beta2 * cos_beta1 + sin_beta2 * sin_beta1; + + CT sin_beta12a = sin_beta2 * cos_beta1 + cos_beta2 * sin_beta1; + + bool shortline = cos_beta12 >= c0 && sin_beta12 < c0_5 && + cos_beta2 * lam12 < c0_5; + + CT sin_omega12, cos_omega12; + + if (shortline) + { + CT sin_beta_m2 = math::sqr(sin_beta1 + sin_beta2); + + sin_beta_m2 /= sin_beta_m2 + math::sqr(cos_beta1 + cos_beta2); + dnm = math::sqrt(c1 + ep2 * sin_beta_m2); + + CT omega12 = lam12 / (one_minus_f * dnm); + + sin_omega12 = sin(omega12); + cos_omega12 = cos(omega12); + } + else + { + sin_omega12 = sin_lam12; + cos_omega12 = cos_lam12; + } + + sin_alpha1 = cos_beta2 * sin_omega12; + // TODO: adl1995 - Resolve inaccuracy with + // cos_alpha1 calculation. + cos_alpha1 = cos_omega12 >= c0 ? + sin_beta12 + cos_beta2 * sin_beta1 * math::sqr(sin_omega12) / (c1 + cos_omega12) : + sin_beta12a - cos_beta2 * sin_beta1 * math::sqr(sin_omega12) / (c1 - cos_omega12); + + CT sin_sigma12 = boost::math::hypot(sin_alpha1, cos_alpha1); + CT cos_sigma12 = sin_beta1 * sin_beta2 + cos_beta1 * cos_beta2 * cos_omega12; + + if (shortline && sin_sigma12 < etol2) + { + sin_alpha2 = cos_beta1 * sin_omega12; + cos_alpha2 = sin_beta12 - cos_beta1 * sin_beta2 * + (cos_omega12 >= c0 ? math::sqr(sin_omega12) / + (c1 + cos_omega12) : c1 - cos_omega12); + } + // Skip astroid calculation if too eccentric. + else if (std::abs(n) > c0_1 || + cos_sigma12 >= c0 || + sin_sigma12 >= c6 * std::abs(n) * math::pi() * + math::sqr(cos_beta1)) + { + // Nothing to do (?). + } + else + { + // Scale lam12 and beta2 to x, y coordinate system where antipodal + // point is at origin and singular point is at y = 0, x = -1. + CT lambda_scale, beta_scale; + + CT y; + volatile CT x; + + CT lam12x = atan2(-sin_lam12, -cos_lam12); + if (f >= 0) + { + CT k2 = math::sqr(sin_beta1) * ep2; + CT epsilon = k2 / (c2 * (c1 * sqrt(c1 + k2)) + k2); + + CT coeffs_A3[SeriesOrder]; + series_expansion::evaluate_coeffs_A3(n, coeffs_A3); + + CT const A3 = math::horner_evaluate(epsilon, coeffs_A3, coeffs_A3 + SeriesOrder); + + lambda_scale = f * cos_beta1 * A3 * math::pi(); + + beta_scale = lambda_scale * cos_beta1; + + x = lam12x / lambda_scale; + y = sin_beta12a / beta_scale; + } + else + { + CT cos_beta12a = cos_beta2 * cos_beta1 - sin_beta2 * sin_beta1; + CT beta12a = atan2(sin_beta12a, cos_beta12a); + + CT m12b, m0, dummy; + meridian_length(n, ep2, math::pi() + beta12a, + sin_beta1, -cos_beta1, dn1, + sin_beta2, cos_beta2, dn2, + cos_beta1, cos_beta2, dummy, + m12b, m0, dummy, dummy, coeffs_C1); + + x = -c1 + m12b / (cos_beta1 * cos_beta2 * m0 * math::pi()); + beta_scale = x < -c0_01 ? sin_beta12a / x : + -f * math::sqr(cos_beta1) * math::pi(); + lambda_scale = beta_scale / cos_beta1; + + y = lam12x / lambda_scale; + } + } + } }; }}} // namespace boost::geometry::formula From 5bb581c932295f0243386cb9504c8b7409bbab2b Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Tue, 12 Jun 2018 15:44:07 +0500 Subject: [PATCH 07/62] [formulas] Flip sign of cos_lam12 This fixes the inaccuracy caused during the calculation of Newton's starting point. --- include/boost/geometry/formulas/karney_inverse.hpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 0f3c686ed..253198a9d 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -91,6 +91,7 @@ public: CT tiny = std::sqrt(std::numeric_limits::min()); + CT const n = f / two_minus_f; CT const e2 = f * two_minus_f; CT const ep2 = e2 / math::sqr(one_minus_f); @@ -110,8 +111,15 @@ public: CT sin_lam12; CT cos_lam12; - lon12 > c90 ? math::sin_cos_degrees(lon12_error, sin_lam12, cos_lam12) - : math::sin_cos_degrees(lon12, sin_lam12, cos_lam12); + if (lon12 > c90) + { + math::sin_cos_degrees(lon12_error, sin_lam12, cos_lam12); + cos_lam12 *= -c1; + } + else + { + math::sin_cos_degrees(lon12, sin_lam12, cos_lam12); + } // Make points close to the equator to lie on it. lat1 = std::abs(lat1) > 90 ? math::NaN() : lat1; @@ -421,8 +429,6 @@ public: } sin_alpha1 = cos_beta2 * sin_omega12; - // TODO: adl1995 - Resolve inaccuracy with - // cos_alpha1 calculation. cos_alpha1 = cos_omega12 >= c0 ? sin_beta12 + cos_beta2 * sin_beta1 * math::sqr(sin_omega12) / (c1 + cos_omega12) : sin_beta12a - cos_beta2 * sin_beta1 * math::sqr(sin_omega12) / (c1 - cos_omega12); From 2bde1c119a3dc04ce3c24261712e894824ff3d05 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Tue, 12 Jun 2018 18:27:29 +0500 Subject: [PATCH 08/62] [formulas] Solve the astroid equation for inverse problem For details, please refer to Eq. (65) in, Geodesics on an ellipsoid of revolution, Charles F.F Karney, https://arxiv.org/abs/1102.1215 --- .../geometry/formulas/karney_inverse.hpp | 112 +++++++++++++++++- 1 file changed, 110 insertions(+), 2 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 253198a9d..2ad45055d 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -57,10 +57,12 @@ public: static CT constexpr c1 = 1; static CT constexpr c2 = 2; static CT constexpr c3 = 3; + static CT constexpr c4 = 4; static CT constexpr c6 = 6; static CT constexpr c90 = 90; static CT constexpr c180 = 180; static CT constexpr c200 = 200; + static CT constexpr c1000 = 1000; template static inline result_type apply(T1 const& lo1, @@ -276,7 +278,9 @@ public: lam12, sin_lam12, cos_lam12, sin_alpha1, cos_alpha1, sin_alpha2, cos_alpha2, - dnm, coeffs_C1, ep2, etol2, n, f); + dnm, coeffs_C1, ep2, + tol1, tol2, etol2, + n, f); } } @@ -395,9 +399,10 @@ public: CT& sin_alpha1, CT& cos_alpha1, CT& sin_alpha2, CT& cos_alpha2, CT& dnm, CT coeffs_C1[], CT ep2, - CT etol2, CT n, CT f) + CT tol1, CT tol2, CT etol2, CT n, CT f) { CT const one_minus_f = c1 - f; + CT const x_thresh = c1000 * tol2; CT sig12 = -c1; CT sin_beta12 = sin_beta2 * cos_beta1 - cos_beta2 * sin_beta1; @@ -497,8 +502,111 @@ public: y = lam12x / lambda_scale; } + + if (y > -tol1 && x > -c1 - x_thresh) + { + // Strip near cut. + if (f >= c0) + { + sin_alpha1 = std::min(c1, -CT(x)); + cos_alpha1 = - std::sqrt(c1 - math::sqr(sin_alpha1)); + } + else + { + cos_alpha1 = std::max(x > -tol1 ? c0 : -c1, CT(x)); + sin_alpha1 = std::sqrt(c1 - math::sqr(cos_alpha1)); + } + } + else + { + // Solve the astroid problem. + CT k = astroid(x, y); + + CT omega12a = lambda_scale * (f >= c0 ? -x * k / + (c1 + k) : -y * (c1 + k) / k); + + CT sin_omega12 = sin(omega12a); + CT cos_omega12 = -cos(omega12a); + + // Update spherical estimate of alpha1 using omgega12 instead of lam12. + sin_alpha1 = cos_beta2 * sin_omega12; + cos_alpha1 = sin_beta12a - cos_beta2 * sin_beta1 * + math::sqr(sin_omega12) / (c1 - cos_omega12); + } } } + + /* + Solve the astroid problem using this equation: + κ4 + 2κ3 + (1 − x2 − y 2 )κ2 − 2y 2 κ − y 2 = 0. + + For details, please refer to Eq. (65) in, + Geodesics on an ellipsoid of revolution, Charles F.F Karney, + https://arxiv.org/abs/1102.1215 + */ + static inline CT astroid(CT x, CT y) + { + CT k; + + CT p = math::sqr(x); + CT q = math::sqr(y); + CT r = (p + q - c1) / c6; + + if (!(q == c0 && r <= c0)) + { + // Avoid possible division by zero when r = 0 by multiplying + // equations for s and t by r^3 and r, respectively. + CT S = p * q / c4; + CT r2 = math::sqr(r); + CT r3 = r * r2; + + // The discriminant of the quadratic equation for T3. This is + // zero on the evolute curve p^(1/3)+q^(1/3) = 1. + CT discriminant = S * (S + c2 * r3); + + CT u = r; + + if (discriminant >= c0) + { + CT T3 = S + r3; + + // Pick the sign on the sqrt to maximize abs(T3). This minimizes + // loss of precision due to cancellation. The result is unchanged + // because of the way the T is used in definition of u. + T3 += T3 < c0 ? -std::sqrt(discriminant) : std::sqrt(discriminant); + + CT T = std::cbrt(T3); + + // T can be zero; but then r2 / T -> 0. + u += T + (T != c0 ? r2 / T : c0); + } + else + { + CT ang = std::atan2(std::sqrt(-discriminant), -(S + r3)); + + // There are three possible cube roots. We choose the root which avoids + // cancellation. Note that discriminant < 0 implies that r < 0. + u += c2 * r * cos(ang / c3); + } + + CT v = std::sqrt(math::sqr(u) + q); + + // Avoid loss of accuracy when u < 0. + CT uv = u < c0 ? q / (v - u) : u + v; + CT w = (uv - q) / (c2 * v); + + // Rearrange expression for k to avoid loss of accuracy due to + // subtraction. Division by 0 not possible because uv > 0, w >= 0. + k = uv / (std::sqrt(uv + math::sqr(w)) + w); + } + else // q == 0 && r <= 0 + { + // y = 0 with |x| <= 1. Handle this case directly. + // For y small, positive root is k = abs(y)/sqrt(1-x^2) + k = c0; + } + return k; + } }; }}} // namespace boost::geometry::formula From 15d5cd628100ef4f605b5b9ae5ee7aa484f33af8 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Tue, 12 Jun 2018 18:32:26 +0500 Subject: [PATCH 09/62] [formulas] Perform normalization on starting guess if it passes the sanity check --- include/boost/geometry/formulas/karney_inverse.hpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 2ad45055d..4e988b32a 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -534,6 +534,19 @@ public: math::sqr(sin_omega12) / (c1 - cos_omega12); } } + + // Apply sanity check on starting guess. Backwards check allows NaN through. + if (!(sin_alpha1 <= c0)) + { + math::normalize(sin_alpha1, cos_alpha1); + } + else + { + sin_alpha1 = c1; + cos_alpha1 = c0; + } + + return sig12; } /* From 06fc06dc7faeb9008721a8b6b5120c47e0eaf312 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Thu, 14 Jun 2018 13:42:44 +0500 Subject: [PATCH 10/62] [formulas] Add function lambda12 to regulate bracketing range in Karney inverse --- .../geometry/formulas/karney_inverse.hpp | 189 +++++++++++++++++- 1 file changed, 180 insertions(+), 9 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 4e988b32a..e4ebb6596 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -59,6 +59,8 @@ public: static CT constexpr c3 = 3; static CT constexpr c4 = 4; static CT constexpr c6 = 6; + static CT constexpr c10 = 10; + static CT constexpr c20 = 20; static CT constexpr c90 = 90; static CT constexpr c180 = 180; static CT constexpr c200 = 200; @@ -274,13 +276,61 @@ public: // Find the starting point for Newton's method. CT dnm; sigma12 = newton_start(sin_beta1, cos_beta1, dn1, - sin_beta2, cos_beta2, dn2, - lam12, sin_lam12, cos_lam12, - sin_alpha1, cos_alpha1, - sin_alpha2, cos_alpha2, - dnm, coeffs_C1, ep2, - tol1, tol2, etol2, - n, f); + sin_beta2, cos_beta2, dn2, + lam12, sin_lam12, cos_lam12, + sin_alpha1, cos_alpha1, + sin_alpha2, cos_alpha2, + dnm, coeffs_C1, ep2, + tol1, tol2, etol2, + n, f); + + if (sigma12 >= c0) + { + // Short lines case (newton_start sets salp2, calp2, dnm) + s12x = sigma12 * b * dnm; + m12x = math::sqr(dnm) * b * sin(sigma12 / dnm); + if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) + { + result.geodesic_scale = cos(sigma12 / dnm); + } + + // Convert to radians. + a12 = sigma12 / math::d2r(); + omega12 = lam12 / (one_minus_f * dnm); + } + else + { + // Apply the Newton's method. + CT sin_sigma1 = c0, cos_sigma1 = c0; + CT sin_sigma2 = c0, cos_sigma2 = c0; + CT eps = c0, diff_omega12 = c0; + + // Bracketing range. + CT sin_alpha1a = tiny, cos_alpha1a = c1; + CT sin_alpha1b = tiny, cos_alpha1b = -c1; + + size_t iteration = 0; + size_t max_iterations = 20 + std::numeric_limits::digits + 10; + + for (bool tripn = false, tripb = false; + iteration < max_iterations; + ++iteration) + { + CT dv; + + CT v = lambda12(sin_beta1, cos_beta1, dn1, + sin_beta2, cos_beta2, dn2, + sin_alpha1, cos_alpha1, + sin_lam12, cos_lam12, + sin_alpha2, cos_alpha2, + sigma12, + sin_sigma1, cos_sigma1, + sin_sigma2, cos_sigma2, + eps, diff_omega12, + iteration < max_iterations, + dv, f, n, ep2, tiny, coeffs_C1); + } + } } } @@ -550,7 +600,7 @@ public: } /* - Solve the astroid problem using this equation: + Solve the astroid problem using the equation: κ4 + 2κ3 + (1 − x2 − y 2 )κ2 − 2y 2 κ − y 2 = 0. For details, please refer to Eq. (65) in, @@ -615,11 +665,132 @@ public: else // q == 0 && r <= 0 { // y = 0 with |x| <= 1. Handle this case directly. - // For y small, positive root is k = abs(y)/sqrt(1-x^2) + // For y small, positive root is k = abs(y)/sqrt(1-x^2). k = c0; } return k; } + + static inline CT lambda12(CT sin_beta1, CT cos_beta1, CT dn1, + CT sin_beta2, CT cos_beta2, CT dn2, + CT sin_alpha1, CT cos_alpha1, + CT sin_lam120, CT cos_lam120, + CT& sin_alpha2, CT& cos_alpha2, + CT& sigma12, + CT& sin_sigma1, CT& cos_sigma1, + CT& sin_sigma2, CT& cos_sigma2, + CT& eps, CT& diff_omega12, + bool diffp, CT& diff_lam12, + CT f, CT n, CT ep2, CT tiny, + CT coeffs_C1[]) + { + CT const one_minus_f = c1 - f; + + if (sin_beta1 == c0 && cos_alpha1 == c0) + { + // Break degeneracy of equatorial line. + cos_alpha1 = -tiny; + } + + CT sin_alpha0 = sin_alpha1 * cos_beta1; + CT cos_alpha0 = boost::math::hypot(cos_alpha1, sin_alpha1 * sin_beta1); + + CT sin_omega1, cos_omega1; + CT sin_omega2, cos_omega2; + CT sin_omega12, cos_omega12; + + CT lam12; + + sin_sigma1 = sin_beta1; + sin_omega1 = sin_alpha0 * sin_beta1; + + cos_sigma1 = cos_omega1 = + cos_alpha1 * cos_beta1; + + math::normalize(sin_sigma1, cos_sigma1); + + // Enforce symmetries in the case abs(beta2) = -beta1. + // Otherwise, this can yield singularities in the Newton iteration. + + // sin(alpha2) * cos(beta2) = sin(alpha0). + sin_alpha2 = cos_beta2 != cos_beta1 ? + sin_alpha0 / cos_beta2 : sin_alpha1; + + cos_alpha2 = cos_beta2 != cos_beta1 || std::abs(sin_beta2) != -sin_beta1 ? + sqrt(math::sqr(cos_alpha1 * cos_beta1) + + (cos_beta1 < -sin_beta1 ? + (cos_beta2 - cos_beta1) * (cos_beta1 + cos_beta2) : + (sin_beta1 - sin_beta2) * (sin_beta1 + sin_beta2))) / cos_beta2 : + std::abs(cos_alpha1); + + sin_sigma2 = sin_beta2; + sin_omega2 = sin_alpha0 * sin_beta2; + + cos_sigma2 = cos_omega2 = + cos_alpha2 * cos_beta2; + + math::normalize(sin_sigma2, cos_sigma2); + + // sig12 = sig2 - sig1, limit to [0, pi]. + sigma12 = atan2(std::max(c0, cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2), + cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2); + + // omg12 = omg2 - omg1, limit to [0, pi]. + sin_omega12 = std::max(c0, cos_omega1 * sin_omega2 - sin_omega1 * cos_omega2); + cos_omega12 = cos_omega1 * cos_omega2 + sin_omega1 * sin_omega2; + + // eta = omg12 - lam120. + CT eta = atan2(sin_omega12 * cos_lam120 - cos_omega12 * sin_lam120, + cos_omega12 * cos_lam120 + sin_omega12 * sin_lam120); + + CT B312; + CT k2 = math::sqr(cos_alpha0) * ep2; + + eps = k2 / (c2 * (c1 + std::sqrt(c1 + k2)) + k2); + + // Compute the size of coefficient array. + size_t const coeffs_C3_size = (SeriesOrder * (SeriesOrder - 1)) / 2; + CT coeffs_C3x[coeffs_C3_size]; + series_expansion::evaluate_coeffs_C3x(n, coeffs_C3x); + + // Evaluate C3 coefficients. + CT coeffs_C3[SeriesOrder]; + series_expansion::evaluate_coeffs_C3(eps, coeffs_C3, coeffs_C3x); + + B312 = series_expansion::sin_cos_series + (sin_sigma2, cos_sigma2, coeffs_C3) - + series_expansion::sin_cos_series + (sin_sigma1, cos_sigma1, coeffs_C3); + + CT coeffs_A3[SeriesOrder]; + series_expansion::evaluate_coeffs_A3(n, coeffs_A3); + + CT const A3 = math::horner_evaluate(eps, coeffs_A3, coeffs_A3 + SeriesOrder); + + diff_omega12 = -f * A3 * sin_alpha0 * (sigma12 + B312); + lam12 = eta + diff_omega12; + + if (diffp) + { + if (cos_alpha2 == c0) + { + diff_lam12 = - c2 * one_minus_f * dn1 / sin_beta1; + } + else + { + CT dummy; + meridian_length(n, eps, sigma12, sin_sigma1, cos_sigma1, dn1, + sin_sigma2, cos_sigma2, dn2, + cos_beta1, cos_beta2, dummy, + diff_lam12, dummy, dummy, + dummy, coeffs_C1); + + diff_lam12 *= one_minus_f / (cos_alpha2 * cos_beta2); + } + } + return lam12; + } + }; }}} // namespace boost::geometry::formula From 2ddad45616ec884589235b07fe81d4043a785f3a Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Tue, 19 Jun 2018 18:08:23 +0500 Subject: [PATCH 11/62] [util] Move difference_angle function to normalize_spheroidal_coordinates.hpp --- .../boost/geometry/formulas/karney_inverse.hpp | 12 +++++++----- include/boost/geometry/util/math.hpp | 18 ------------------ .../util/normalize_spheroidal_coordinates.hpp | 5 +++-- 3 files changed, 10 insertions(+), 25 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index e4ebb6596..6d459abb4 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -155,14 +156,14 @@ public: math::sin_cos_degrees(lat1, sin_beta1, cos_beta1); sin_beta1 *= one_minus_f; - math::normalize(sin_beta1, cos_beta1); + math::normalize_values(sin_beta1, cos_beta1); cos_beta1 = std::max(tiny, cos_beta1); CT sin_beta2, cos_beta2; math::sin_cos_degrees(lat2, sin_beta2, cos_beta2); sin_beta2 *= one_minus_f; - math::normalize(sin_beta2, cos_beta2); + math::normalize_values(sin_beta2, cos_beta2); cos_beta2 = std::max(tiny, cos_beta2); // If cos_beta1 < -sin_beta1, then cos_beta2 - cos_beta1 is a @@ -329,6 +330,7 @@ public: eps, diff_omega12, iteration < max_iterations, dv, f, n, ep2, tiny, coeffs_C1); + } } } @@ -588,7 +590,7 @@ public: // Apply sanity check on starting guess. Backwards check allows NaN through. if (!(sin_alpha1 <= c0)) { - math::normalize(sin_alpha1, cos_alpha1); + math::normalize_values(sin_alpha1, cos_alpha1); } else { @@ -707,7 +709,7 @@ public: cos_sigma1 = cos_omega1 = cos_alpha1 * cos_beta1; - math::normalize(sin_sigma1, cos_sigma1); + math::normalize_values(sin_sigma1, cos_sigma1); // Enforce symmetries in the case abs(beta2) = -beta1. // Otherwise, this can yield singularities in the Newton iteration. @@ -729,7 +731,7 @@ public: cos_sigma2 = cos_omega2 = cos_alpha2 * cos_beta2; - math::normalize(sin_sigma2, cos_sigma2); + math::normalize_values(sin_sigma2, cos_sigma2); // sig12 = sig2 - sig1, limit to [0, pi]. sigma12 = atan2(std::max(c0, cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2), diff --git a/include/boost/geometry/util/math.hpp b/include/boost/geometry/util/math.hpp index 42d910f43..110fbd7fc 100644 --- a/include/boost/geometry/util/math.hpp +++ b/include/boost/geometry/util/math.hpp @@ -866,24 +866,6 @@ inline T sum_error(T u, T v, T& t) return s; } -/*! -\brief The exact difference of two angles reduced to - (−180°, 180°]. -*/ -template -inline T difference_angle(T x, T y, T& e) -{ - T t, d = normalize_angle(sum_error(std::remainder(-x, T(360)), - std::remainder(y, T(360)), t)); - - // Here y - x = d + t (mod 360), exactly, where d is in (-180,180] and - // abs(t) <= eps (eps = 2^-45 for doubles). The only case where the - // addition of t takes the result outside the range (-180,180] is d = 180 - // and t > 0. The case, d = -180 + eps, t = -eps, can't happen, since - // sum_error would have returned the exact result in such a case (i.e., given t = 0). - return sum_error(d == 180 && t > 0 ? -180 : d, t, e); -} - /*! \brief Evaluate the polynomial in x using Horner's method. */ diff --git a/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp b/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp index 71215b3bf..77c8b19d1 100644 --- a/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp +++ b/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp @@ -385,8 +385,9 @@ inline void normalize_angle(CoordinateType& angle) template inline T difference_angle(T x, T y, T& e) { - T t, d = normalize_angle(math::sum_error(std::remainder(-x, T(360)), - std::remainder(y, T(360)), t)); + T t, d = math::sum_error(std::remainder(-x, T(360)), std::remainder(y, T(360)), t); + + normalize_angle(d); // Here y - x = d + t (mod 360), exactly, where d is in (-180,180] and // abs(t) <= eps (eps = 2^-45 for doubles). The only case where the From ead0b188f915bd987eb2c44770e3dcf29e94473c Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Tue, 19 Jun 2018 20:21:05 +0500 Subject: [PATCH 12/62] [formulas] Update bracketing values in Newton's method --- .../geometry/formulas/karney_inverse.hpp | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 6d459abb4..f8e54785b 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -60,7 +60,9 @@ public: static CT constexpr c3 = 3; static CT constexpr c4 = 4; static CT constexpr c6 = 6; + static CT constexpr c8 = 8; static CT constexpr c10 = 10; + static CT constexpr c16 = 16; static CT constexpr c20 = 20; static CT constexpr c90 = 90; static CT constexpr c180 = 180; @@ -331,6 +333,46 @@ public: iteration < max_iterations, dv, f, n, ep2, tiny, coeffs_C1); + // Reversed test to allow escape with NaNs. + if (tripb || !(std::abs(v) >= (tripn ? c8 : c1) * tol0)) + break; + + // Update bracketing values. + if (v > c0 && (iteration > max_iterations || + cos_alpha1 / sin_alpha1 > cos_alpha1b / sin_alpha1b)) + { + sin_alpha1b = sin_alpha1; + cos_alpha1b = cos_alpha1; + } + else if (v < c0 && (iteration > max_iterations || + cos_alpha1 / sin_alpha1 < cos_alpha1a / sin_alpha1a)) + { + sin_alpha1a = sin_alpha1; + cos_alpha1a = cos_alpha1; + } + if (iteration < max_iterations && dv > c0) + { + CT diff_alpha1 = -v / dv; + + CT sin_diff_alpha1 = sin(diff_alpha1); + CT cos_diff_alpha1 = cos(diff_alpha1); + + CT nsin_alpa1 = sin_alpha1 * cos_diff_alpha1 + + cos_alpha1 * sin_diff_alpha1; + + if (nsin_alpa1 > c0 && std::abs(diff_alpha1) < math::pi()) + { + cos_alpha1 = cos_alpha1 * cos_diff_alpha1 - sin_alpha1 * sin_diff_alpha1; + sin_alpha1 = nsin_alpa1; + math::normalize_values(sin_alpha1, cos_alpha1); + + // In some regimes we don't get quadratic convergence because + // slope -> 0. So use convergence conditions based on epsilon + // instead of sqrt(epsilon). + tripn = std::abs(v) <= c16 * tol0; + continue; + } + } } } } From 02577bda556df3cd3e596cc8eb1304ecac032b20 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Wed, 20 Jun 2018 21:31:18 +0500 Subject: [PATCH 13/62] [formulas] Use midpoint of bracket when value lies outside of range --- .../geometry/formulas/karney_inverse.hpp | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index f8e54785b..4573641e5 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -93,6 +93,10 @@ public: CT const tol0 = std::numeric_limits::epsilon(); CT const tol1 = c200 * tol0; CT const tol2 = sqrt(tol0); + + // Check on bisection interval. + CT const tol_bisection = tol0 * tol2; + CT const etol2 = c0_1 * tol2 / sqrt(std::max(c0_001, std::abs(f)) * std::min(c1, c1 - f / c2) / c2); @@ -373,6 +377,22 @@ public: continue; } } + + // Either dv was not positive or updated value was outside legal + // range. Use the midpoint of the bracket as the next estimate. + // This mechanism is not needed for the WGS84 ellipsoid, but it does + // catch problems with more eeccentric ellipsoids. Its efficacy is + // such for the WGS84 test set with the starting guess set to alp1 = + // 90deg: + // the WGS84 test set: mean = 5.21, sd = 3.93, max = 24 + // WGS84 and random input: mean = 4.74, sd = 0.99 + sin_alpha1 = (sin_alpha1a + sin_alpha1b) / c2; + cos_alpha1 = (cos_alpha1a + cos_alpha1b) / c2; + math::normalize_values(sin_alpha1, cos_alpha1); + tripn = false; + tripb = (std::abs(sin_alpha1a - sin_alpha1) + (cos_alpha1a - cos_alpha1) < tol_bisection || + std::abs(sin_alpha1 - sin_alpha1b) + (cos_alpha1 - cos_alpha1b) < tol_bisection); + } } } From 6d0720b5ae1419469577229dbb0d7efb763e9b96 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Wed, 20 Jun 2018 21:32:41 +0500 Subject: [PATCH 14/62] [formulas] Ensure reduced length and geodesic scale are computed in canonical form --- .../geometry/formulas/karney_inverse.hpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 4573641e5..5b6de6989 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -394,6 +394,25 @@ public: std::abs(sin_alpha1 - sin_alpha1b) + (cos_alpha1 - cos_alpha1b) < tol_bisection); } + // Store values in temporary vairables. + // bool enable_reduced_length = EnableReducedLength; + // bool enable_geodesic_scale = EnableGeodesicScale; + + // EnableReducedLength = false; + // EnableGeodesicScale = false; + + CT dummy; + // Ensure that the reduced length and geodesic scale are computed in + // a "canonical" way, with the I2 integral. + meridian_length(n, ep2, sigma12, sin_sigma1, cos_sigma1, dn1, + sin_sigma2, cos_sigma2, dn2, + cos_beta1, cos_beta2, s12x, + m12x, dummy, result.geodesic_scale, + M21, coeffs_C1); + + // Restore values to their previous state. + // EnableReducedLength = enable_reduced_length; + // EnableGeodesicScale = enable_geodesic_scale; } } } From 12bd41fd5db58d0f60d6544dafa981087f077aa5 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Mon, 2 Jul 2018 13:47:58 +0500 Subject: [PATCH 15/62] [formulas] Store values from Karney's inverse method in result_inverse structure The computed values from inverse method include distance, azimuth, reverse_azimuth, reduced_length, and geodesic_scale. --- .../geometry/formulas/karney_inverse.hpp | 88 +++++++++++++------ 1 file changed, 59 insertions(+), 29 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 5b6de6989..517b96683 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -133,8 +133,8 @@ public: } // Make points close to the equator to lie on it. - lat1 = std::abs(lat1) > 90 ? math::NaN() : lat1; - lat2 = std::abs(lat2) > 90 ? math::NaN() : lat2; + lat1 = std::abs(lat1) > c90 ? math::NaN() : lat1; + lat2 = std::abs(lat2) > c90 ? math::NaN() : lat2; lat1 = math::round_angle(lat1); lat2 = math::round_angle(lat2); @@ -217,8 +217,8 @@ public: sin_alpha1 = sin_lam12; // Heading north at the target. - cos_alpha2 = 1; - sin_alpha2 = 0; + cos_alpha2 = c1; + sin_alpha2 = c0; CT sin_sigma1 = sin_beta1; CT cos_sigma1 = cos_alpha1 * cos_beta1; @@ -227,7 +227,7 @@ public: CT cos_sigma2 = cos_alpha2 * cos_beta2; CT sigma12 = std::atan2(std::max(c0, cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2), - cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2); + cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2); CT dummy; meridian_length(n, ep2, sigma12, sin_sigma1, cos_sigma1, dn1, @@ -257,8 +257,8 @@ public: CT omega12, sin_omega12, cos_omega12; - if (!meridian && sin_beta1 == 0 && - (f <= 0 || lon12_error >= f * c180)) + if (!meridian && sin_beta1 == c0 && + (f <= c0 || lon12_error >= f * c180)) { // Points lie on the equator. cos_alpha1 = cos_alpha2 = c0; @@ -324,7 +324,6 @@ public: ++iteration) { CT dv; - CT v = lambda12(sin_beta1, cos_beta1, dn1, sin_beta2, cos_beta2, dn2, sin_alpha1, cos_alpha1, @@ -361,13 +360,13 @@ public: CT sin_diff_alpha1 = sin(diff_alpha1); CT cos_diff_alpha1 = cos(diff_alpha1); - CT nsin_alpa1 = sin_alpha1 * cos_diff_alpha1 + + CT nsin_alpha1 = sin_alpha1 * cos_diff_alpha1 + cos_alpha1 * sin_diff_alpha1; - if (nsin_alpa1 > c0 && std::abs(diff_alpha1) < math::pi()) + if (nsin_alpha1 > c0 && std::abs(diff_alpha1) < math::pi()) { cos_alpha1 = cos_alpha1 * cos_diff_alpha1 - sin_alpha1 * sin_diff_alpha1; - sin_alpha1 = nsin_alpa1; + sin_alpha1 = nsin_alpha1; math::normalize_values(sin_alpha1, cos_alpha1); // In some regimes we don't get quadratic convergence because @@ -394,12 +393,6 @@ public: std::abs(sin_alpha1 - sin_alpha1b) + (cos_alpha1 - cos_alpha1b) < tol_bisection); } - // Store values in temporary vairables. - // bool enable_reduced_length = EnableReducedLength; - // bool enable_geodesic_scale = EnableGeodesicScale; - - // EnableReducedLength = false; - // EnableGeodesicScale = false; CT dummy; // Ensure that the reduced length and geodesic scale are computed in @@ -410,11 +403,49 @@ public: m12x, dummy, result.geodesic_scale, M21, coeffs_C1); - // Restore values to their previous state. - // EnableReducedLength = enable_reduced_length; - // EnableGeodesicScale = enable_geodesic_scale; + m12x *= b; + s12x *= b; + a12 = sigma12 / math::d2r(); } } + + if (swap_point < 0) + { + swap(sin_alpha1, sin_alpha2); + swap(cos_alpha1, cos_alpha2); + swap(result.geodesic_scale, M21); + } + + sin_alpha1 *= swap_point * lon12_sign; + cos_alpha1 *= swap_point * lat_sign; + + sin_alpha2 *= swap_point * lon12_sign; + cos_alpha2 *= swap_point * lat_sign; + + if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) + { + result.reduced_length = m12x; + } + + if (BOOST_GEOMETRY_CONDITION(CalcAzimuths)) + { + if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth)) + { + result.azimuth = atan2(sin_alpha1, cos_alpha1) * math::r2d(); + } + + if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth)) + { + result.reverse_azimuth = atan2(sin_alpha2, cos_alpha2) * math::r2d(); + } + } + + if (BOOST_GEOMETRY_CONDITION(EnableDistance)) + { + result.distance = s12x; + } + + return result; } static inline void meridian_length(CT epsilon, CT ep2, CT sigma12, @@ -436,8 +467,7 @@ public: { // Find the coefficients for A1 by computing the // series expansion using Horner scehme. - expansion_A1 - = series_expansion::evaluate_series_A1(epsilon); + expansion_A1 = series_expansion::evaluate_series_A1(epsilon); // Evaluate the coefficients for C1. series_expansion::evaluate_coeffs_C1(epsilon, coeffs_C1); @@ -447,8 +477,7 @@ public: { // Find the coefficients for A2 by computing the // series expansion using Horner scehme. - expansion_A2 - = series_expansion::evaluate_series_A2(epsilon); + expansion_A2 = series_expansion::evaluate_series_A2(epsilon); // Evaluate the coefficients for C2. series_expansion::evaluate_coeffs_C2(epsilon, coeffs_C2); @@ -466,7 +495,7 @@ public: - series_expansion::sin_cos_series (sin_sigma1, cos_sigma1, coeffs_C1); - m12x = expansion_A1 * (sigma12 + B1); + s12x = expansion_A1 * (sigma12 + B1); if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) @@ -587,7 +616,7 @@ public: sin_sigma12 >= c6 * std::abs(n) * math::pi() * math::sqr(cos_beta1)) { - // Nothing to do (?). + // Nothing to do. } else { @@ -751,6 +780,7 @@ public: // For y small, positive root is k = abs(y)/sqrt(1-x^2). k = c0; } + return k; } @@ -787,8 +817,7 @@ public: sin_sigma1 = sin_beta1; sin_omega1 = sin_alpha0 * sin_beta1; - cos_sigma1 = cos_omega1 = - cos_alpha1 * cos_beta1; + cos_sigma1 = cos_omega1 = cos_alpha1 * cos_beta1; math::normalize_values(sin_sigma1, cos_sigma1); @@ -816,7 +845,7 @@ public: // sig12 = sig2 - sig1, limit to [0, pi]. sigma12 = atan2(std::max(c0, cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2), - cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2); + cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2); // omg12 = omg2 - omg1, limit to [0, pi]. sin_omega12 = std::max(c0, cos_omega1 * sin_omega2 - sin_omega1 * cos_omega2); @@ -871,6 +900,7 @@ public: diff_lam12 *= one_minus_f / (cos_alpha2 * cos_beta2); } } + return lam12; } From 4f0431085902aac5623fbf7db0909162a138a3f7 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Tue, 3 Jul 2018 09:55:06 +0500 Subject: [PATCH 16/62] [formulas][test] Add Karney's inverse method in inverse test cases The compilation is successful with gcc version (7.2.0), but not with version (5.4.1). The accepted tolerance is set to (0.0000001). Currently, all tests are not passing, which indicates an error in the calculation. Additionally, some changes have been made in karney_inverse.hpp --- .../boost/geometry/formulas/karney_inverse.hpp | 18 ++++++++---------- test/formulas/inverse.cpp | 12 +++++++++++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 517b96683..3864fb102 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -98,7 +98,7 @@ public: CT const tol_bisection = tol0 * tol2; CT const etol2 = c0_1 * tol2 / - sqrt(std::max(c0_001, std::abs(f)) * std::min(c1, c1 - f / c2) / c2); + sqrt(std::max(CT(0.001), std::abs(f)) * std::min(CT(1), CT(1) - f / CT(2)) / c2); CT tiny = std::sqrt(std::numeric_limits::min()); @@ -226,8 +226,8 @@ public: CT sin_sigma2 = sin_beta2; CT cos_sigma2 = cos_alpha2 * cos_beta2; - CT sigma12 = std::atan2(std::max(c0, cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2), - cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2); + CT sigma12 = std::atan2(std::max(CT(0), cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2), + cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2); CT dummy; meridian_length(n, ep2, sigma12, sin_sigma1, cos_sigma1, dn1, @@ -670,8 +670,8 @@ public: // Strip near cut. if (f >= c0) { - sin_alpha1 = std::min(c1, -CT(x)); - cos_alpha1 = - std::sqrt(c1 - math::sqr(sin_alpha1)); + sin_alpha1 = std::min(CT(1), -CT(x)); + cos_alpha1 = - std::sqrt(CT(1) - math::sqr(sin_alpha1)); } else { @@ -780,7 +780,6 @@ public: // For y small, positive root is k = abs(y)/sqrt(1-x^2). k = c0; } - return k; } @@ -844,11 +843,11 @@ public: math::normalize_values(sin_sigma2, cos_sigma2); // sig12 = sig2 - sig1, limit to [0, pi]. - sigma12 = atan2(std::max(c0, cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2), - cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2); + sigma12 = atan2(std::max(CT(0), cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2), + cos_sigma1 * cos_sigma2 + sin_sigma1 * sin_sigma2); // omg12 = omg2 - omg1, limit to [0, pi]. - sin_omega12 = std::max(c0, cos_omega1 * sin_omega2 - sin_omega1 * cos_omega2); + sin_omega12 = std::max(CT(0), cos_omega1 * sin_omega2 - sin_omega1 * cos_omega2); cos_omega12 = cos_omega1 * cos_omega2 + sin_omega1 * sin_omega2; // eta = omg12 - lam120. @@ -900,7 +899,6 @@ public: diff_lam12 *= one_minus_f / (cos_alpha2 * cos_beta2); } } - return lam12; } diff --git a/test/formulas/inverse.cpp b/test/formulas/inverse.cpp index 59bb8b692..8e7ad0376 100644 --- a/test/formulas/inverse.cpp +++ b/test/formulas/inverse.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -53,10 +54,15 @@ void test_all(expected_results const& results) double lon2r = results.p2.lon * d2r; double lat2r = results.p2.lat * d2r; + double lon1d = results.p1.lon; + double lat1d = results.p1.lat; + double lon2d = results.p2.lon; + double lat2d = results.p2.lat; + // WGS84 bg::srs::spheroid spheroid(6378137.0, 6356752.3142451793); - bg::formula::result_inverse result_v, result_t, result_a; + bg::formula::result_inverse result_v, result_t, result_a, result_k; typedef bg::formula::vincenty_inverse vi_t; result_v = vi_t::apply(lon1r, lat1r, lon2r, lat2r, spheroid); @@ -75,6 +81,10 @@ void test_all(expected_results const& results) result_a.azimuth *= r2d; result_a.reverse_azimuth *= r2d; check_inverse("andoyer", results, result_a, results.andoyer, results.reference, 0.001); + + typedef bg::formula::karney_inverse ka_t; + result_k = ka_t::apply(lon1d, lat1d, lon2d, lat2d, spheroid); + check_inverse("karney", results, result_k, results.vincenty, results.reference, 0.0000001); } int test_main(int, char*[]) From 535ae96a8682fcc068016db212585e2c5994827a Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Tue, 3 Jul 2018 11:11:41 +0500 Subject: [PATCH 17/62] [test] Add nearly antipodal points dataset for inverse geodesic problem These values are collected from GeodTest which is associated with GeographicLib: https://zenodo.org/record/32156 The conversion to C++ array format is done using this Python script: https://github.com/adl1995/boost-geometry-extra/blob/master/geographiclib-dataset-parse-inverse.py Geodesic scale (M12) is absent from the GeodTest dataset, so it is manually generated using GeographicLib using this C++ script: https://github.com/adl1995/boost-geometry-extra/blob/master/geographicLib-direct-antipodal.cpp --- test/formulas/inverse.cpp | 27 +- test/formulas/inverse_cases_antipodal.hpp | 342 ++++++++++++++++++++++ 2 files changed, 368 insertions(+), 1 deletion(-) create mode 100644 test/formulas/inverse_cases_antipodal.hpp diff --git a/test/formulas/inverse.cpp b/test/formulas/inverse.cpp index 8e7ad0376..07c0fbc99 100644 --- a/test/formulas/inverse.cpp +++ b/test/formulas/inverse.cpp @@ -4,6 +4,7 @@ // Copyright (c) 2016-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle +// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program. // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -14,6 +15,7 @@ #include "test_formula.hpp" #include "inverse_cases.hpp" +#include "inverse_cases_antipodal.hpp" #include #include @@ -22,8 +24,9 @@ #include +template void check_inverse(std::string const& name, - expected_results const& results, + Result const& results, bg::formula::result_inverse const& result, expected_result const& expected, expected_result const& reference, @@ -87,6 +90,23 @@ void test_all(expected_results const& results) check_inverse("karney", results, result_k, results.vincenty, results.reference, 0.0000001); } +void test_karney_antipodal(expected_results_antipodal const& results) +{ + double lon1d = results.p1.lon; + double lat1d = results.p1.lat; + double lon2d = results.p2.lon; + double lat2d = results.p2.lat; + + // WGS84 + bg::srs::spheroid spheroid(6378137.0, 6356752.3142451793); + + bg::formula::result_inverse result; + + typedef bg::formula::karney_inverse ka_t; + result = ka_t::apply(lon1d, lat1d, lon2d, lat2d, spheroid); + check_inverse("karney", results, result, results.karney, results.karney, 0.0000001); +} + int test_main(int, char*[]) { for (size_t i = 0; i < expected_size; ++i) @@ -94,5 +114,10 @@ int test_main(int, char*[]) test_all(expected[i]); } + for (size_t i = 0; i < expected_size_antipodal; ++i) + { + test_karney_antipodal(expected_antipodal[i]); + } + return 0; } diff --git a/test/formulas/inverse_cases_antipodal.hpp b/test/formulas/inverse_cases_antipodal.hpp new file mode 100644 index 000000000..e66046dd5 --- /dev/null +++ b/test/formulas/inverse_cases_antipodal.hpp @@ -0,0 +1,342 @@ +// Boost.Geometry +// Unit Test + +// Copyright (c) 2018 Adeel Ahmad, Islamabad, Pakistan. + +// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program. + +// 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_TEST_INVERSE_CASES_ANTIPODAL_HPP +#define BOOST_GEOMETRY_TEST_INVERSE_CASES_ANTIPODAL_HPP + +#include "inverse_cases.hpp" + +struct expected_results_antipodal +{ + coordinates p1; + coordinates p2; + expected_result karney; +}; + +/* + These values are collected from GeodTest which is associated with GeographicLib: + https://zenodo.org/record/32156 + + The conversion to C++ array format is done using this Python script: + https://github.com/adl1995/boost-geometry-extra/blob/master/geographiclib-dataset-parse-inverse.py + + Geodesic scale (M12) is absent from the GeodTest dataset, so it is manually generated + using GeographicLib using this C++ script: + https://github.com/adl1995/boost-geometry-extra/blob/master/geographicLib-direct-antipodal.cpp +*/ +expected_results_antipodal expected_antipodal[] = +{ + { + { 0, 31.394417440639 }, { 179.615601631202912322, -31.275540610835465807 }, + { 19980218.4055399, 34.266322930672, 145.782701113414306756, 49490.8807994496209, -0.996116451012525883079717914370121434 } + },{ + { 0, 29.788792273749 }, { 178.569451327813675741, -29.558013672069422725 }, + { 19887224.5407334, 74.302205994192, 106.156240654579267308, 97043.7545600593058, -0.998624031147844926081802441331092268 } + },{ + { 0, 46.471843094141 }, { 179.083144618009561276, -46.284166405924629853 }, + { 19944337.8863917, 63.693680310665, 116.699978859005570535, 53139.140576552365, -0.997597309645591900917338534782174975 } + },{ + { 0, 63.016506345929 }, { 179.862869954071637855, -63.02943882703369735 }, + { 20000925.7533636, 153.393656073038, 26.619056019474552953, 12713.9284725111772, -1.00381317792143387457315384381217882 } + },{ + { 0, 19.796231412719 }, { 179.546498474461283862, -19.470586923091672503 }, + { 19956338.1330537, 28.272934411318, 151.789094611690988249, 87191.1749625132931, -0.997015409027664833985227232915349305 } + },{ + { 0, 6.373459459035 }, { 179.240009269347556917, -6.204887833274217382 }, + { 19946581.6983394, 56.859050230583, 123.169200847008284851, 53958.8698005263939, -0.999349049081101004077254401636309922 } + },{ + { 0, 66.380766469414 }, { 179.632633596894388233, -66.27177494016956425 }, + { 19986277.7696849, 38.646950203356, 141.550919825824399405, 22198.215635049214, -0.996949176054954366854587988200364634 } + },{ + { 0, 16.483421185231 }, { 179.731567273052604726, -16.818424446748042212 }, + { 19962737.9842573, 163.431254767325, 16.598399455529231288, 95318.4104529881431, -1.00272210232979741562076014815829694 } + },{ + { 0, 4.215702155486 }, { 179.093771177769992874, -4.051917290690976764 }, + { 19932517.393764, 65.543168480886, 114.482669479963380006, 55205.4553703842317, -0.999655858425056553784315838129259646 } + },{ + { 0, 40.71372085907 }, { 179.404612926861498984, -41.047052242159400671 }, + { 19951133.3595356, 143.672151631634, 36.54002600969304553, 70931.1530155553621, -1.00414169574077272173440178448799998 } + },{ + { 0, 15.465481491654 }, { 179.020726605204181801, -14.622355549425900341 }, + { 19877383.8879911, 36.289185640976, 143.875673907461159912, 156419.0806764376957, -0.997639074397169589580869342171354219 } + },{ + { 0, 17.586197343531 }, { 179.722490735835379144, -17.731394230364437075 }, + { 19982280.4639115, 157.929615091529, 22.089021105298661023, 69727.5357849255557, -1.00280451698301242835498214844847098 } + },{ + { 0, 5.7442768247 }, { 178.85894724576868462, -6.039853564481335581 }, + { 19902873.7431814, 116.146983678305, 63.91482549951374061, 87149.6188944111673, -1.00039332893096744037109147029696032 } + },{ + { 0, 32.002904282111 }, { 179.744925422107715439, -32.297934520693132807 }, + { 19967670.3104795, 163.052160078191, 17.004175883388454943, 78311.3164829640582, -1.00449903445302446414189034840092063 } + },{ + { 0, 55.902716926362 }, { 179.300685189522463007, -55.934320218634018206 }, + { 19970525.337607, 98.927641063414, 81.374264168520557301, 23554.0093185709067, -1.00072788779083454713259015989024192 } + },{ + { 0, 22.69939784398 }, { 179.294173474584020749, -22.654875407651067149 }, + { 19959286.1903172, 74.253870776761, 105.811588890213155275, 22369.7179951557679, -0.998972181419003457669703038845909759 } + },{ + { 0, 41.312328471121 }, { 179.817186837717804928, -40.954523601529804886 }, + { 19962690.5721867, 11.277616109847, 168.784288786443902199, 77252.6121237260201, -0.994825151471527391322524636052548885 } + },{ + { 0, 27.927415327453 }, { 179.636508875679110143, -27.607314264234172721 }, + { 19961296.8828333, 23.166421459647, 156.905194492817275222, 83096.5801709291101, -0.995959692767656723511038308060960844 } + },{ + { 0, 41.567228741451 }, { 179.931812964300204608, -42.103039532074194347 }, + { 19944253.4454809, 176.66609526064, 3.361859685835349219, 96859.08180779197, -1.00513607140487626345759508694754913 } + },{ + { 0, 37.384208978567 }, { 179.225180174670992261, -36.916085670712060029 }, + { 19928705.5911445, 39.072534864532, 141.212743814390850106, 92667.7834060578402, -0.995955516859159284415170532156480476 } + },{ + { 0, 59.011868682852 }, { 179.424923485514312807, -58.82705468054708336 }, + { 19970442.3788306, 44.970301291063, 135.333817989802309531, 38071.1136293083857, -0.996658942892707400140750451100757346 } + },{ + { 0, 35.515406087737 }, { 179.50369572149476218, -35.119747127350258822 }, + { 19948918.9139751, 28.528972431952, 151.622257906284404073, 84564.0387217601751, -0.995562861799169418475230486365035176 } + },{ + { 0, 58.170252463184 }, { 179.254737571455023977, -58.372261836268550805 }, + { 19961407.0813807, 128.021116291844, 52.399129705193347143, 43715.3070711393309, -1.00285273713280753682397516968194395 } + },{ + { 0, 34.012183807959 }, { 179.83713352180447672, -34.29640782899529639 }, + { 19970955.843065, 168.944519134772, 11.093048811826875835, 76493.5814538538151, -1.0047652354558671561335359001532197 } + },{ + { 0, 45.510762948553 }, { 178.981682578823726535, -45.582753595227824235 }, + { 19940248.3450143, 99.886784003837, 80.542330522982505877, 48555.1946627894972, -1.00083807750906350619857221317943186 } + },{ + { 0, 4.19841765451 }, { 179.398024428225540172, -4.198416896099783242 }, + { 19970496.5132933, 89.561550657928, 90.438456568689151881, 14.8790480103109, -0.999994104810285944218151144013972953 } + },{ + { 0, 40.890119148103 }, { 179.6557148951668192, -41.553556264538302258 }, + { 19926563.5817492, 165.437641169967, 14.713597527941311478, 111805.7305227545923, -1.00492294933406567380984597548376769 } + },{ + { 0, 28.096672787686 }, { 178.606868012231657724, -28.472055035513955205 }, + { 19883901.8482359, 115.174366374632, 65.257367020445564176, 107880.4353518862363, -1.00170803073331593502359737613005564 } + },{ + { 0, 6.50572154271 }, { 178.926013840891647541, -6.411745140559297675 }, + { 19917276.4101551, 79.069492719523, 100.985091481519557845, 57073.3242952680707, -0.999736666933808471036115861352300271 } + },{ + { 0, .468835109567 }, { 178.325942223692180692, -.281751687044281805 }, + { 19849380.7342734, 80.234636214474, 99.77243368342786593, 123845.4568822078908, -0.999801437209140719808431185811059549 } + },{ + { 0, 1.682746325049 }, { 179.717131561406935483, -.677647430701204515 }, + { 19890026.0274781, 10.076182752451, 169.927471515299313238, 177917.2104306563981, -0.999538055691262194990542866435134783 } + },{ + { 0, 10.711305126218 }, { 179.874050163405229937, -10.349315378531556046 }, + { 19962987.2134077, 7.528253696796, 172.480576051850009046, 104175.1095378254456, -0.998071853755238880268052525934763253 } + },{ + { 0, 53.374321544652 }, { 179.729445806011012057, -53.196257519024042184 }, + { 19980478.1457438, 23.324715976877, 156.777734080146664812, 41907.8869272231053, -0.995333596277707566279957518418086693 } + },{ + { 0, 39.680221664519 }, { 179.87506206720154785, -39.256187213040660911 }, + { 19956191.7841809, 7.075406493429, 172.967624741991546131, 86943.8110669895148, -0.994801087909667924868983845954062417 } + },{ + { 0, 1.377666714083 }, { 178.994542525209058878, -1.415358715570225495 }, + { 19925401.4931301, 95.29199069739, 84.7178724483824156, 45800.9140624827059, -0.99999803170512457928253979844157584 } + },{ + { 0, 48.751426624188 }, { 179.661697715070846977, -48.688146707479475147 }, + { 19988599.1160495, 40.252328570137, 139.808452951157199824, 26322.3790862461568, -0.995999245724129789181233718409202993 } + },{ + { 0, 59.443039048494 }, { 179.247605418616998285, -59.454371825393424121 }, + { 19969935.9534732, 93.052184108221, 87.331416513795326158, 25342.4691896499534, -1.00020727848897084122370415570912883 } + },{ + { 0, 4.122408476235 }, { 179.749430572914989772, -4.689124208743755363 }, + { 19938291.6332293, 167.73479753304, 12.274635577599782826, 127855.6475863583497, -1.00068600902837667732114823593292385 } + },{ + { 0, 46.422470082432 }, { 178.857408435141563774, -46.390934261324541952 }, + { 19931980.7029341, 86.67365350297, 93.852683224054943377, 56114.680046867064, -0.999607096116300386512421027873642743 } + },{ + { 0, 32.614423729024 }, { 179.460593512880455451, -32.01874745886238612 }, + { 19926887.3785175, 24.943814520557, 155.229917137448282531, 112355.3319340873104, -0.995562150676871926435751447570510209 } + },{ + { 0, 3.242895277973 }, { 179.556428318080663113, -3.001106476068264917 }, + { 19964490.4789049, 30.247458779683, 149.760178923092147784, 80929.0418317066044, -0.999474184270344845337774586369050667 } + },{ + { 0, 6.29069210113 }, { 178.556859259685624933, -6.354208910915346725 }, + { 19877160.8505733, 94.34299459284, 85.750059038253282986, 94127.1566760840083, -0.999976397350904933070125935046235099 } + },{ + { 0, 18.232086569498 }, { 179.658073278238477245, -18.87394850776853555 }, + { 19927978.7462175, 164.41905055334, 15.640779355822506503, 129771.1882449660559, -1.00293460439063886191490837518358603 } + },{ + { 0, 12.049849333181 }, { 179.761046682699610657, -11.201990279782499264 }, + { 19908004.4552909, 9.418096768309, 170.610608272305604585, 157761.5040571466343, -0.997761474497510958414636661473196 } + },{ + { 0, 40.289465276136 }, { 179.644208494155329095, -40.370034926441385999 }, + { 19985674.936106, 143.092606818963, 36.958610382613096419, 36200.8933724688593, -1.00414965876091266672176516294712201 } + },{ + { 0, 2.197784650379 }, { 179.961199531084784854, -1.353440827124394777 }, + { 19910509.7517973, 1.542117609437, 178.458582198505846426, 160403.6285079348996, -0.999488724639301051588802238256903365 } + },{ + { 0, 1.966575272177 }, { 179.699817324905962184, -3.101125282483752618 }, + { 19875595.6267266, 170.112968791865, 9.89572776349855838, 192355.7206665719908, -1.00015463589804554089823795948177576 } + },{ + { 0, 25.078832492684 }, { 178.600804840925824646, -24.897833702325682511 }, + { 19887997.7953866, 77.264585323781, 103.101167809583406892, 92442.9124509225839, -0.998981189838600847075156252685701475 } + },{ + { 0, 31.740361941314 }, { 179.553485210731879874, -31.909206787477701871 }, + { 19972325.3556069, 143.930820896999, 36.145242998351638503, 54883.4113710054145, -1.00379461628115951299378139083273709 } + },{ + { 0, .05479250563 }, { 178.822647462220726609, .836079031223269324 }, + { 19858049.4780499, 41.349430623518, 138.645259065012502544, 169078.442370111714, -0.9997793696948588104689292777038645 } + },{ + { 0, 36.685139871608 }, { 179.366667224014334712, -36.6833040833258687 }, + { 19968965.6773632, 89.167975517493, 90.921025521408327068, 13327.2156799476918, -0.999916537946348604748436628142371774 } + },{ + { 0, 3.451199399671 }, { 179.107509334399258305, -3.459003521120242021 }, + { 19938203.3838544, 91.541212417048, 88.476282464773035164, 32316.1747698810781, -1.00000397484395819880376166111091152 } + },{ + { 0, 27.692898794247 }, { 178.512356615673144314, -27.666009301228316555 }, + { 19883493.6699045, 88.406440883665, 92.036345087713397961, 94128.7880896190836, -0.999736458322951659916100197733612731 } + },{ + { 0, 17.363238291869 }, { 179.567921315455829491, -17.288872648596950413 }, + { 19980749.7638027, 39.697196316589, 140.321938237586060826, 46975.9359427664379, -0.997687691981715030209443284547887743 } + },{ + { 0, 37.006775102539 }, { 179.191103068859169842, -37.156365616364686838 }, + { 19949309.9180043, 116.455543532607, 63.771817992036617793, 45856.1961421018701, -1.00221962858918423044940482213860378 } + },{ + { 0, 45.572883540957 }, { 179.224707765088686272, -45.94675931323086696 }, + { 19940027.8586414, 137.627256708444, 42.723991162977357301, 74208.4359612889496, -1.00380887786447159371050474874209613 } + },{ + { 0, 43.63393981955 }, { 178.878236417027994157, -43.642335115130514773 }, + { 19931045.2914508, 91.203625101465, 89.268780774643462256, 55253.5406349861764, -1.00002974153150514524668324156664312 } + },{ + { 0, 38.4995307019 }, { 179.143856004445269342, -39.042223438550921467 }, + { 19918391.2222193, 141.232864609445, 39.117947060740562295, 102217.2563106863077, -1.00388164115732947401227193040540442 } + },{ + { 0, 27.55015339382 }, { 179.596220103573824099, -27.587412128122249651 }, + { 19986004.7358853, 137.025135713548, 42.992898351962011956, 33938.7346646670654, -1.00316044390281167153489150223322213 } + },{ + { 0, 1.54507498314 }, { 179.567115633151308577, -1.448861185025252004 }, + { 19978593.3191777, 36.816106412092, 143.185763012309022403, 56320.5800276739168, -0.999770499462467210349814195069484413 } + },{ + { 0, 45.217063644222 }, { 179.807382581661125, -45.086424050571516283 }, + { 19987042.0782465, 18.114645812265, 161.928120141429818658, 45544.2915061261936, -0.994974179414854997816064496873877943 } + },{ + { 0, 13.473522450751 }, { 179.726941062277208626, -13.570372758027936877 }, + { 19987364.078382, 156.839609002403, 23.170293747820406391, 65329.9068132034472, -1.00219093189506569530067281448282301 } + },{ + { 0, 6.287741997374 }, { 179.071252372259552052, -6.743450924917895817 }, + { 19912159.8245954, 132.954797451112, 47.100789519677419746, 104772.4027498097375, -1.00071252411103017720961361192166805 } + },{ + { 0, 7.639709001531 }, { 179.616156296978583335, -7.48702643786017917 }, + { 19976374.3699535, 29.731916588299, 150.279582966919438164, 69224.6591757209539, -0.998789792086741234911073661351110786 } + },{ + { 0, 5.893688050348 }, { 179.586212000450856399, -4.888408917114795625 }, + { 19886907.2520668, 14.653438882877, 165.371181401863458848, 177183.5330818593022, -0.998794647031120752522781458537792787 } + },{ + { 0, 61.997076235476 }, { 179.605779116829636081, -62.19593758437129915 }, + { 19976288.2901729, 149.562797049254, 30.65850204223272625, 36696.2853801462176, -1.00373071432437144245852778112748638 } + },{ + { 0, 50.507637741656 }, { 179.893569206021038536, -50.721890799900161112 }, + { 19979542.5263293, 171.564028344478, 8.4746613464253591, 50644.5234828162697, -1.00508881632281776852266830246662721 } + },{ + { 0, 7.484475238477 }, { 178.638400003000590878, -6.926155588124333461 }, + { 19867425.2906303, 57.020570370985, 123.087267812322270238, 132929.2775641349633, -0.999097042677338120775232255255104974 } + },{ + { 0, 56.851165323215 }, { 179.587046628550073045, -56.875248360744638525 }, + { 19988235.9960515, 112.345749045605, 67.744017057185404441, 9971.0934553515518, -1.00182859249871403228837607457535341 } + },{ + { 0, 10.692273150738 }, { 178.709520715733071393, -10.851727623036704339 }, + { 19893210.3050033, 102.824601316946, 77.308514969817191459, 83032.7122948051111, -1.00034345584508432835946223349310458 } + },{ + { 0, 46.694739303788 }, { 179.926838145841924189, -46.948618153686522669 }, + { 19975447.9283188, 174.663684259477, 5.361568174833475454, 59614.5876209460645, -1.00520484875201732144489596976200119 } + },{ + { 0, 15.804386137005 }, { 178.367587635209819128, -15.522042847777054984 }, + { 19855850.8800526, 74.932089158884, 105.357235560913450667, 123350.4326645237628, -0.999091578546475345135036150168161839 } + },{ + { 0, 4.371450175299 }, { 179.780887420199549421, -4.566109732313098407 }, + { 19979071.1035552, 164.163592252794, 15.840695025950408814, 84137.2115482558728, -1.00076323969894742660358133434783667 } + },{ + { 0, 30.894388279688 }, { 179.375426183521944524, -30.871308884744172663 }, + { 19968681.8321577, 77.35154610481, 102.709506078439532936, 14048.0277985734058, -0.998975176336422854284080585784977302 } + },{ + { 0, 9.541166838639 }, { 178.432934555386452839, -10.09982228112793472 }, + { 19848553.7844137, 118.441353539081, 61.736686215549403663, 144831.1911566651614, -1.00060548620110489892454097571317106 } + },{ + { 0, 8.489292700054 }, { 179.906698338023119097, -8.559237750032113623 }, + { 19995477.1669578, 171.963952699866, 8.037517851139094467, 72192.60793572974, -1.00152068486306466965629624610301107 } + },{ + { 0, 19.562401114224 }, { 178.838724116996037606, -20.05038360490599475 }, + { 19893208.1788508, 126.362762598128, 53.875560227496658204, 112181.7524188837615, -1.00185202668802775249901060306001455 } + },{ + { 0, 42.260350252749 }, { 179.807860448877064601, -42.79985897702184353 }, + { 19942715.0054774, 170.703419847646, 9.377654670896439828, 96336.3477142010769, -1.00508642406443549077721399953588843 } + },{ + { 0, 24.511403144656 }, { 178.957598444862223515, -24.616808725039883945 }, + { 19924809.5184876, 102.913211410163, 77.297538210434837096, 55403.453072179318, -1.0008408309188838725134473861544393 } + },{ + { 0, 20.844284170708 }, { 179.069258863637226633, -20.321320573298341477 }, + { 19909084.6340808, 44.172784008084, 136.01627115731728436, 111009.0987238994608, -0.997389183621778974142557672166731209 } + },{ + { 0, 2.426010809098 }, { 178.236397468862000784, -2.513715200833756776 }, + { 19840940.6924189, 94.315194952561, 85.734896842737189557, 130002.6104886615638, -0.999825249844991659209370027383556589 } + },{ + { 0, 6.600682554664 }, { 179.646475458013797028, -7.699164822656561787 }, + { 19878412.28273, 168.167678684515, 11.861035812918738552, 187426.3958525886692, -1.00098284856064978498579876031726599 } + },{ + { 0, 23.372339802326 }, { 179.499422665106094027, -24.239465200482591299 }, + { 19899498.4582543, 161.197647943542, 18.932355367478826536, 151863.2545535951091, -1.00347666868431395492677893344080076 } + },{ + { 0, 16.194668264095 }, { 179.115193814080201851, -17.129419031459576897 }, + { 19874825.6683239, 148.942349959054, 31.225656401221968078, 166033.3161394594622, -1.00222032222233647935638600756647065 } + },{ + { 0, 1.528726471528 }, { 178.791047180477802091, -1.282203000582034597 }, + { 19897803.9939987, 69.212891442493, 110.802928803578167132, 85252.8333849204133, -0.999827144228156883265512533398577943 } + },{ + { 0, 6.297249676078 }, { 178.623258703845895437, -5.709470001196540278 }, + { 19864042.0495193, 56.274639904925, 123.817184177744186806, 137475.1283083659258, -0.999190450178399580671850799262756482 } + },{ + { 0, 17.393540327984 }, { 179.330156510680163326, -17.431100690958209424 }, + { 19962624.6302607, 107.855062015266, 72.181322855288535245, 19320.5501845044839, -1.00091841779689127989172447996679693 } + },{ + { 0, 46.284685151236 }, { 179.852534804091121255, -46.176234945675219984 }, + { 19990422.3478916, 14.758013867151, 165.271681964991897184, 42614.1796365710104, -0.994894592261839960656288894824683666 } + },{ + { 0, 14.924320176299 }, { 179.195663739713760883, -14.125476432252858442 }, + { 19891861.8615337, 31.446544793174, 148.678916887199611191, 149419.6596309045804, -0.997620142585332936313591289945179597 } + },{ + { 0, 23.668824656069 }, { 179.409875478773990359, -24.107855233601412399 }, + { 19938736.4442268, 148.091483667618, 32.02919257641173958, 97771.7687385830819, -1.00323262872000595891108787327539176 } + },{ + { 0, 46.986276695896 }, { 179.92040916864362177, -47.301644191214905832 }, + { 19968596.0414782, 174.796708941456, 5.234240076649939638, 66113.7417494369769, -1.00519095452608087093437916337279603 } + },{ + { 0, 65.946144289524 }, { 179.808282612725835525, -65.871840130833632868 }, + { 19993734.5109736, 25.375428509648, 154.703163938350061652, 18355.2254271672769, -0.996436935914610577569305860379245132 } + },{ + { 0, 10.950298933293 }, { 179.624609619829763098, -10.787771536605316781 }, + { 19975919.5586889, 28.779018914489, 151.238005588662201946, 70291.1998404303581, -0.998272071834115148902810688014142215 } + },{ + { 0, 13.609869340778 }, { 179.035623147420893383, -14.023624108675206222 }, + { 19913213.8514358, 129.616021271129, 50.506400999466711623, 97596.7664002074776, -1.00146664642314031645753402699483559 } + },{ + { 0, 48.701427557433 }, { 179.385565054218238481, -48.735316652259656533 }, + { 19972955.2699173, 102.875149183407, 77.294384444682547869, 18461.7742226227697, -1.00114676855429074464609584538266063 } + },{ + { 0, 31.519172055785 }, { 179.555251675378549409, -31.140142027808697534 }, + { 19952318.3772514, 26.247105619999, 153.865822276646938125, 86354.7117605101002, -0.995739948399825047786748655198607594 } + },{ + { 0, 31.863784754278 }, { 179.722489476483407524, -31.826935359797657785 }, + { 19993324.8682601, 29.572313410211, 150.440607907359037187, 41427.6181613499234, -0.995888009001147267440501309465616941 } + },{ + { 0, 76.434608546092 }, { 179.918287057674124459, -76.48787937532808951 }, + { 19997750.023578, 167.428385412814, 12.621032110142724567, 9619.5267710862108, -1.00233963893091582164629471662919968 } + },{ + { 0, 73.114273316483 }, { 179.576736605988553624, -73.098788070892914568 }, + { 19992866.6147806, 78.154765899661, 102.085693546950923465, 8580.6475692800946, -0.999384143308475469957841141876997426 } + },{ + { 0, 1.125639056292 }, { 178.426819580880619395, -.694775021853292564 }, + { 19852573.5442848, 67.184842289382, 112.831314850896246589, 132932.8743502563937, -0.999732957962833457266071945923613384 } + } +}; + +size_t const expected_size_antipodal = sizeof(expected_antipodal) / sizeof(expected_results_antipodal); + +#endif // BOOST_GEOMETRY_TEST_INVERSE_CASES_ANTIPODAL_HPP From 1a52eaca9c35791984d2d3ba4ed0f5df2c963a23 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Fri, 6 Jul 2018 18:27:49 +0500 Subject: [PATCH 18/62] [formulas] Resolve inaccuracy in starting point for Newton's method --- .../geometry/formulas/karney_inverse.hpp | 46 +++++++++++-------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 3864fb102..691c111cc 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -102,7 +102,6 @@ public: CT tiny = std::sqrt(std::numeric_limits::min()); - CT const n = f / two_minus_f; CT const e2 = f * two_minus_f; CT const ep2 = e2 / math::sqr(one_minus_f); @@ -293,7 +292,7 @@ public: if (sigma12 >= c0) { - // Short lines case (newton_start sets salp2, calp2, dnm) + // Short lines case (newton_start sets sin_alpha2, cos_alpha2, dnm) s12x = sigma12 * b * dnm; m12x = math::sqr(dnm) * b * sin(sigma12 / dnm); if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) @@ -361,7 +360,7 @@ public: CT cos_diff_alpha1 = cos(diff_alpha1); CT nsin_alpha1 = sin_alpha1 * cos_diff_alpha1 + - cos_alpha1 * sin_diff_alpha1; + cos_alpha1 * sin_diff_alpha1; if (nsin_alpha1 > c0 && std::abs(diff_alpha1) < math::pi()) { @@ -565,15 +564,21 @@ public: { CT const one_minus_f = c1 - f; CT const x_thresh = c1000 * tol2; + + // Return a starting point for Newton's method in sin_alpha1 + // and cos_alpha1 (function value is -1). If Newton's method + // doesn't need to be used, return also sin_alpha2 and + // cos_alpha2 and function value is sig12. CT sig12 = -c1; + // bet12 = bet2 - bet1 in [0, pi); beta12a = bet2 + bet1 in (-pi, 0] CT sin_beta12 = sin_beta2 * cos_beta1 - cos_beta2 * sin_beta1; CT cos_beta12 = cos_beta2 * cos_beta1 + sin_beta2 * sin_beta1; CT sin_beta12a = sin_beta2 * cos_beta1 + cos_beta2 * sin_beta1; bool shortline = cos_beta12 >= c0 && sin_beta12 < c0_5 && - cos_beta2 * lam12 < c0_5; + cos_beta2 * lam12 < c0_5; CT sin_omega12, cos_omega12; @@ -609,6 +614,10 @@ public: cos_alpha2 = sin_beta12 - cos_beta1 * sin_beta2 * (cos_omega12 >= c0 ? math::sqr(sin_omega12) / (c1 + cos_omega12) : c1 - cos_omega12); + + math::normalize_values(sin_alpha2, cos_alpha2); + // Set return value. + sig12 = atan2(sin_sigma12, cos_sigma12); } // Skip astroid calculation if too eccentric. else if (std::abs(n) > c0_1 || @@ -616,11 +625,11 @@ public: sin_sigma12 >= c6 * std::abs(n) * math::pi() * math::sqr(cos_beta1)) { - // Nothing to do. + // Nothing to do, zeroth order spherical approximation will do. } else { - // Scale lam12 and beta2 to x, y coordinate system where antipodal + // Scale lam12 and bet2 to x, y coordinate system where antipodal // point is at origin and singular point is at y = 0, x = -1. CT lambda_scale, beta_scale; @@ -628,18 +637,17 @@ public: volatile CT x; CT lam12x = atan2(-sin_lam12, -cos_lam12); - if (f >= 0) + if (f >= c0) { CT k2 = math::sqr(sin_beta1) * ep2; - CT epsilon = k2 / (c2 * (c1 * sqrt(c1 + k2)) + k2); + CT eps = k2 / (c2 * (c1 + sqrt(c1 + k2)) + k2); CT coeffs_A3[SeriesOrder]; series_expansion::evaluate_coeffs_A3(n, coeffs_A3); - CT const A3 = math::horner_evaluate(epsilon, coeffs_A3, coeffs_A3 + SeriesOrder); + CT const A3 = math::horner_evaluate(eps, coeffs_A3, coeffs_A3 + SeriesOrder); lambda_scale = f * cos_beta1 * A3 * math::pi(); - beta_scale = lambda_scale * cos_beta1; x = lam12x / lambda_scale; @@ -671,12 +679,12 @@ public: if (f >= c0) { sin_alpha1 = std::min(CT(1), -CT(x)); - cos_alpha1 = - std::sqrt(CT(1) - math::sqr(sin_alpha1)); + cos_alpha1 = - math::sqrt(c1 - math::sqr(sin_alpha1)); } else { - cos_alpha1 = std::max(x > -tol1 ? c0 : -c1, CT(x)); - sin_alpha1 = std::sqrt(c1 - math::sqr(cos_alpha1)); + cos_alpha1 = std::max(CT(x > -tol1 ? c0 : -c1), CT(x)); + sin_alpha1 = math::sqrt(c1 - math::sqr(cos_alpha1)); } } else @@ -687,8 +695,8 @@ public: CT omega12a = lambda_scale * (f >= c0 ? -x * k / (c1 + k) : -y * (c1 + k) / k); - CT sin_omega12 = sin(omega12a); - CT cos_omega12 = -cos(omega12a); + sin_omega12 = sin(omega12a); + cos_omega12 = -cos(omega12a); // Update spherical estimate of alpha1 using omgega12 instead of lam12. sin_alpha1 = cos_beta2 * sin_omega12; @@ -697,15 +705,15 @@ public: } } - // Apply sanity check on starting guess. Backwards check allows NaN through. + // Sanity check on starting guess. Backwards check allows NaN through. if (!(sin_alpha1 <= c0)) { - math::normalize_values(sin_alpha1, cos_alpha1); + math::normalize_values(sin_alpha1, cos_alpha1); } else { - sin_alpha1 = c1; - cos_alpha1 = c0; + sin_alpha1 = c1; + cos_alpha1 = c0; } return sig12; From 6432dfe96c0141dca0c619dba130c94cd6dc9304 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Tue, 10 Jul 2018 11:36:33 +0500 Subject: [PATCH 19/62] [formulas][util] Reformat code in karney_inverse to use coefficient containers --- .../geometry/formulas/karney_inverse.hpp | 97 +++++++------------ .../util/normalize_spheroidal_coordinates.hpp | 2 +- 2 files changed, 37 insertions(+), 62 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 691c111cc..6b6a3b5b5 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -161,14 +161,14 @@ public: math::sin_cos_degrees(lat1, sin_beta1, cos_beta1); sin_beta1 *= one_minus_f; - math::normalize_values(sin_beta1, cos_beta1); + math::normalize_unit_vector(sin_beta1, cos_beta1); cos_beta1 = std::max(tiny, cos_beta1); CT sin_beta2, cos_beta2; math::sin_cos_degrees(lat2, sin_beta2, cos_beta2); sin_beta2 *= one_minus_f; - math::normalize_values(sin_beta2, cos_beta2); + math::normalize_unit_vector(sin_beta2, cos_beta2); cos_beta2 = std::max(tiny, cos_beta2); // If cos_beta1 < -sin_beta1, then cos_beta2 - cos_beta1 is a @@ -181,8 +181,7 @@ public: { if (cos_beta1 == cos_beta2) { - sin_beta2 = sin_beta2 < 0 ? sin_beta1 : - -sin_beta1; + sin_beta2 = sin_beta2 < 0 ? sin_beta1 : -sin_beta1; } } else @@ -200,7 +199,7 @@ public: CT m12x, s12x, M21; // Index zero element of coeffs_C1 is unused. - CT coeffs_C1[SeriesOrder + 1]; + series_expansion::coeffs_C1 const coeffs_C1(n); bool meridian = lat1 == -90 || sin_lam12 == 0; @@ -292,7 +291,7 @@ public: if (sigma12 >= c0) { - // Short lines case (newton_start sets sin_alpha2, cos_alpha2, dnm) + // Short lines case (newton_start sets sin_alpha2, cos_alpha2, dnm). s12x = sigma12 * b * dnm; m12x = math::sqr(dnm) * b * sin(sigma12 / dnm); if (BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) @@ -366,7 +365,7 @@ public: { cos_alpha1 = cos_alpha1 * cos_diff_alpha1 - sin_alpha1 * sin_diff_alpha1; sin_alpha1 = nsin_alpha1; - math::normalize_values(sin_alpha1, cos_alpha1); + math::normalize_unit_vector(sin_alpha1, cos_alpha1); // In some regimes we don't get quadratic convergence because // slope -> 0. So use convergence conditions based on epsilon @@ -386,7 +385,7 @@ public: // WGS84 and random input: mean = 4.74, sd = 0.99 sin_alpha1 = (sin_alpha1a + sin_alpha1b) / c2; cos_alpha1 = (cos_alpha1a + cos_alpha1b) / c2; - math::normalize_values(sin_alpha1, cos_alpha1); + math::normalize_unit_vector(sin_alpha1, cos_alpha1); tripn = false; tripb = (std::abs(sin_alpha1a - sin_alpha1) + (cos_alpha1a - cos_alpha1) < tol_bisection || std::abs(sin_alpha1 - sin_alpha1b) + (cos_alpha1 - cos_alpha1b) < tol_bisection); @@ -447,18 +446,20 @@ public: return result; } + template static inline void meridian_length(CT epsilon, CT ep2, CT sigma12, CT sin_sigma1, CT cos_sigma1, CT dn1, CT sin_sigma2, CT cos_sigma2, CT dn2, CT cos_beta1, CT cos_beta2, CT& s12x, CT& m12x, CT& m0, - CT& M12, CT& M21, CT coeffs_C1[]) + CT& M12, CT& M21, + CoeffsC1 coeffs_C1) { CT A12x = 0, J12 = 0; CT expansion_A1, expansion_A2; - // Index zero element of coeffs_C2 is unused. - CT coeffs_C2[SeriesOrder + 1]; + // Evaluate the coefficients for C2. + series_expansion::coeffs_C2 coeffs_C2(epsilon); if (BOOST_GEOMETRY_CONDITION(EnableDistance) || BOOST_GEOMETRY_CONDITION(EnableReducedLength) || @@ -466,20 +467,14 @@ public: { // Find the coefficients for A1 by computing the // series expansion using Horner scehme. - expansion_A1 = series_expansion::evaluate_series_A1(epsilon); - - // Evaluate the coefficients for C1. - series_expansion::evaluate_coeffs_C1(epsilon, coeffs_C1); + expansion_A1 = series_expansion::evaluate_A1(epsilon); if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) { // Find the coefficients for A2 by computing the // series expansion using Horner scehme. - expansion_A2 = series_expansion::evaluate_series_A2(epsilon); - - // Evaluate the coefficients for C2. - series_expansion::evaluate_coeffs_C2(epsilon, coeffs_C2); + expansion_A2 = series_expansion::evaluate_A2(epsilon); A12x = expansion_A1 - expansion_A2; expansion_A2 += c1; @@ -489,23 +484,18 @@ public: if (BOOST_GEOMETRY_CONDITION(EnableDistance)) { - CT B1 = series_expansion::sin_cos_series - (sin_sigma2, cos_sigma2, coeffs_C1) - - series_expansion::sin_cos_series - (sin_sigma1, cos_sigma1, coeffs_C1); + CT B1 = series_expansion::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C1) + - series_expansion::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C1); s12x = expansion_A1 * (sigma12 + B1); if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) { - CT B2 = series_expansion::sin_cos_series - (sin_sigma2, cos_sigma2, coeffs_C2) - - series_expansion::sin_cos_series - (sin_sigma1, cos_sigma1, coeffs_C2); + CT B2 = series_expansion::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C2) + - series_expansion::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2); - J12 = A12x * sigma12 + (expansion_A1 * B1 - - expansion_A2 * B2); + J12 = A12x * sigma12 + (expansion_A1 * B1 - expansion_A2 * B2); } } else if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || @@ -518,14 +508,8 @@ public: } J12 = A12x * sigma12 + - (series_expansion::sin_cos_series - (sin_sigma2, - cos_sigma2, - coeffs_C2) - - series_expansion::sin_cos_series - (sin_sigma1, - cos_sigma1, - coeffs_C2)); + (series_expansion::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C2) + - series_expansion::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2)); } if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) @@ -554,12 +538,13 @@ public: doesn't need to be used, return also sin_alpha2 and cos_alpha2 and function value is sig12. */ + template static inline CT newton_start(CT sin_beta1, CT cos_beta1, CT dn1, CT sin_beta2, CT cos_beta2, CT dn2, CT lam12, CT sin_lam12, CT cos_lam12, CT& sin_alpha1, CT& cos_alpha1, CT& sin_alpha2, CT& cos_alpha2, - CT& dnm, CT coeffs_C1[], CT ep2, + CT& dnm, CoeffsC1 coeffs_C1, CT ep2, CT tol1, CT tol2, CT etol2, CT n, CT f) { CT const one_minus_f = c1 - f; @@ -615,7 +600,7 @@ public: (cos_omega12 >= c0 ? math::sqr(sin_omega12) / (c1 + cos_omega12) : c1 - cos_omega12); - math::normalize_values(sin_alpha2, cos_alpha2); + math::normalize_unit_vector(sin_alpha2, cos_alpha2); // Set return value. sig12 = atan2(sin_sigma12, cos_sigma12); } @@ -642,10 +627,9 @@ public: CT k2 = math::sqr(sin_beta1) * ep2; CT eps = k2 / (c2 * (c1 + sqrt(c1 + k2)) + k2); - CT coeffs_A3[SeriesOrder]; - series_expansion::evaluate_coeffs_A3(n, coeffs_A3); + series_expansion::coeffs_A3 const coeffs_A3(n); - CT const A3 = math::horner_evaluate(eps, coeffs_A3, coeffs_A3 + SeriesOrder); + CT const A3 = math::horner_evaluate(eps, coeffs_A3.begin(), coeffs_A3.end()); lambda_scale = f * cos_beta1 * A3 * math::pi(); beta_scale = lambda_scale * cos_beta1; @@ -708,7 +692,7 @@ public: // Sanity check on starting guess. Backwards check allows NaN through. if (!(sin_alpha1 <= c0)) { - math::normalize_values(sin_alpha1, cos_alpha1); + math::normalize_unit_vector(sin_alpha1, cos_alpha1); } else { @@ -791,6 +775,7 @@ public: return k; } + template static inline CT lambda12(CT sin_beta1, CT cos_beta1, CT dn1, CT sin_beta2, CT cos_beta2, CT dn2, CT sin_alpha1, CT cos_alpha1, @@ -802,7 +787,7 @@ public: CT& eps, CT& diff_omega12, bool diffp, CT& diff_lam12, CT f, CT n, CT ep2, CT tiny, - CT coeffs_C1[]) + CoeffsC1 coeffs_C1) { CT const one_minus_f = c1 - f; @@ -826,7 +811,7 @@ public: cos_sigma1 = cos_omega1 = cos_alpha1 * cos_beta1; - math::normalize_values(sin_sigma1, cos_sigma1); + math::normalize_unit_vector(sin_sigma1, cos_sigma1); // Enforce symmetries in the case abs(beta2) = -beta1. // Otherwise, this can yield singularities in the Newton iteration. @@ -848,7 +833,7 @@ public: cos_sigma2 = cos_omega2 = cos_alpha2 * cos_beta2; - math::normalize_values(sin_sigma2, cos_sigma2); + math::normalize_unit_vector(sin_sigma2, cos_sigma2); // sig12 = sig2 - sig1, limit to [0, pi]. sigma12 = atan2(std::max(CT(0), cos_sigma1 * sin_sigma2 - sin_sigma1 * cos_sigma2), @@ -867,24 +852,14 @@ public: eps = k2 / (c2 * (c1 + std::sqrt(c1 + k2)) + k2); - // Compute the size of coefficient array. - size_t const coeffs_C3_size = (SeriesOrder * (SeriesOrder - 1)) / 2; - CT coeffs_C3x[coeffs_C3_size]; - series_expansion::evaluate_coeffs_C3x(n, coeffs_C3x); + series_expansion::coeffs_C3 const coeffs_C3(n, eps); - // Evaluate C3 coefficients. - CT coeffs_C3[SeriesOrder]; - series_expansion::evaluate_coeffs_C3(eps, coeffs_C3, coeffs_C3x); + B312 = series_expansion::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C3) + - series_expansion::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C3); - B312 = series_expansion::sin_cos_series - (sin_sigma2, cos_sigma2, coeffs_C3) - - series_expansion::sin_cos_series - (sin_sigma1, cos_sigma1, coeffs_C3); + series_expansion::coeffs_A3 const coeffs_A3(n); - CT coeffs_A3[SeriesOrder]; - series_expansion::evaluate_coeffs_A3(n, coeffs_A3); - - CT const A3 = math::horner_evaluate(eps, coeffs_A3, coeffs_A3 + SeriesOrder); + CT const A3 = math::horner_evaluate(eps, coeffs_A3.begin(), coeffs_A3.end()); diff_omega12 = -f * A3 * sin_alpha0 * (sigma12 + B312); lam12 = eta + diff_omega12; diff --git a/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp b/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp index 175b96f12..6304484f6 100644 --- a/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp +++ b/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp @@ -387,7 +387,7 @@ inline T difference_angle(T x, T y, T& e) { T t, d = math::sum_error(std::remainder(-x, T(360)), std::remainder(y, T(360)), t); - normalize_angle(d); + normalize_azimuth(d); // Here y - x = d + t (mod 360), exactly, where d is in (-180,180] and // abs(t) <= eps (eps = 2^-45 for doubles). The only case where the From daf03b488898f4aca65379e8982833f9c8cf1ba3 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Tue, 10 Jul 2018 11:52:20 +0500 Subject: [PATCH 20/62] [formulas] Use namespace alias se for series_expansion in karney_inverse --- .../geometry/formulas/karney_inverse.hpp | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 6b6a3b5b5..ae0a368cd 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -24,6 +24,7 @@ namespace boost { namespace geometry { namespace formula { +namespace se = series_expansion; /*! \brief The solution of the inverse problem of geodesics on latlong coordinates, @@ -199,7 +200,7 @@ public: CT m12x, s12x, M21; // Index zero element of coeffs_C1 is unused. - series_expansion::coeffs_C1 const coeffs_C1(n); + se::coeffs_C1 const coeffs_C1(n); bool meridian = lat1 == -90 || sin_lam12 == 0; @@ -459,7 +460,7 @@ public: CT expansion_A1, expansion_A2; // Evaluate the coefficients for C2. - series_expansion::coeffs_C2 coeffs_C2(epsilon); + se::coeffs_C2 coeffs_C2(epsilon); if (BOOST_GEOMETRY_CONDITION(EnableDistance) || BOOST_GEOMETRY_CONDITION(EnableReducedLength) || @@ -467,14 +468,14 @@ public: { // Find the coefficients for A1 by computing the // series expansion using Horner scehme. - expansion_A1 = series_expansion::evaluate_A1(epsilon); + expansion_A1 = se::evaluate_A1(epsilon); if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) { // Find the coefficients for A2 by computing the // series expansion using Horner scehme. - expansion_A2 = series_expansion::evaluate_A2(epsilon); + expansion_A2 = se::evaluate_A2(epsilon); A12x = expansion_A1 - expansion_A2; expansion_A2 += c1; @@ -484,16 +485,16 @@ public: if (BOOST_GEOMETRY_CONDITION(EnableDistance)) { - CT B1 = series_expansion::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C1) - - series_expansion::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C1); + CT B1 = se::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C1) + - se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C1); s12x = expansion_A1 * (sigma12 + B1); if (BOOST_GEOMETRY_CONDITION(EnableReducedLength) || BOOST_GEOMETRY_CONDITION(EnableGeodesicScale)) { - CT B2 = series_expansion::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C2) - - series_expansion::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2); + CT B2 = se::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C2) + - se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2); J12 = A12x * sigma12 + (expansion_A1 * B1 - expansion_A2 * B2); } @@ -508,8 +509,8 @@ public: } J12 = A12x * sigma12 + - (series_expansion::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C2) - - series_expansion::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2)); + (se::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C2) + - se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C2)); } if (BOOST_GEOMETRY_CONDITION(EnableReducedLength)) @@ -627,7 +628,7 @@ public: CT k2 = math::sqr(sin_beta1) * ep2; CT eps = k2 / (c2 * (c1 + sqrt(c1 + k2)) + k2); - series_expansion::coeffs_A3 const coeffs_A3(n); + se::coeffs_A3 const coeffs_A3(n); CT const A3 = math::horner_evaluate(eps, coeffs_A3.begin(), coeffs_A3.end()); @@ -852,12 +853,12 @@ public: eps = k2 / (c2 * (c1 + std::sqrt(c1 + k2)) + k2); - series_expansion::coeffs_C3 const coeffs_C3(n, eps); + se::coeffs_C3 const coeffs_C3(n, eps); - B312 = series_expansion::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C3) - - series_expansion::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C3); + B312 = se::sin_cos_series(sin_sigma2, cos_sigma2, coeffs_C3) + - se::sin_cos_series(sin_sigma1, cos_sigma1, coeffs_C3); - series_expansion::coeffs_A3 const coeffs_A3(n); + se::coeffs_A3 const coeffs_A3(n); CT const A3 = math::horner_evaluate(eps, coeffs_A3.begin(), coeffs_A3.end()); From 55c1691ddc0852613bc37bedc935be308913e3f7 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Fri, 13 Jul 2018 12:08:00 +0500 Subject: [PATCH 21/62] [formulas] Fix incorrect argument to meridian_length() function --- .../geometry/formulas/karney_inverse.hpp | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index ae0a368cd..8c509af47 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -235,7 +235,6 @@ public: m12x, dummy, result.geodesic_scale, M21, coeffs_C1); - if (sigma12 < c1 || m12x >= c0) { if (sigma12 < c3 * tiny) @@ -254,7 +253,7 @@ public: } } - CT omega12, sin_omega12, cos_omega12; + CT omega12; if (!meridian && sin_beta1 == c0 && (f <= c0 || lon12_error >= f * c180)) @@ -273,7 +272,6 @@ public: } a12 = lon12 / one_minus_f; } - else if (!meridian) { // If point1 and point2 belong within a hemisphere bounded by a @@ -352,6 +350,7 @@ public: sin_alpha1a = sin_alpha1; cos_alpha1a = cos_alpha1; } + if (iteration < max_iterations && dv > c0) { CT diff_alpha1 = -v / dv; @@ -390,17 +389,17 @@ public: tripn = false; tripb = (std::abs(sin_alpha1a - sin_alpha1) + (cos_alpha1a - cos_alpha1) < tol_bisection || std::abs(sin_alpha1 - sin_alpha1b) + (cos_alpha1 - cos_alpha1b) < tol_bisection); - } CT dummy; + se::coeffs_C1 const coeffs_C1_eps(eps); // Ensure that the reduced length and geodesic scale are computed in // a "canonical" way, with the I2 integral. - meridian_length(n, ep2, sigma12, sin_sigma1, cos_sigma1, dn1, - sin_sigma2, cos_sigma2, dn2, - cos_beta1, cos_beta2, s12x, - m12x, dummy, result.geodesic_scale, - M21, coeffs_C1); + meridian_length(eps, ep2, sigma12, sin_sigma1, cos_sigma1, dn1, + sin_sigma2, cos_sigma2, dn2, + cos_beta1, cos_beta2, s12x, + m12x, dummy, result.geodesic_scale, + M21, coeffs_C1_eps); m12x *= b; s12x *= b; @@ -874,11 +873,11 @@ public: else { CT dummy; - meridian_length(n, eps, sigma12, sin_sigma1, cos_sigma1, dn1, - sin_sigma2, cos_sigma2, dn2, - cos_beta1, cos_beta2, dummy, - diff_lam12, dummy, dummy, - dummy, coeffs_C1); + meridian_length(eps, ep2, sigma12, sin_sigma1, cos_sigma1, dn1, + sin_sigma2, cos_sigma2, dn2, + cos_beta1, cos_beta2, dummy, + diff_lam12, dummy, dummy, + dummy, coeffs_C1); diff_lam12 *= one_minus_f / (cos_alpha2 * cos_beta2); } From b44e3aed599061be89f8b314446fe02b9345fb2f Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Fri, 13 Jul 2018 12:15:35 +0500 Subject: [PATCH 22/62] [formulas] Remove unused variable a12 in karney_inverse --- include/boost/geometry/formulas/karney_inverse.hpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 8c509af47..28cdae715 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -196,7 +196,7 @@ public: CT const dn1 = sqrt(c1 + ep2 * math::sqr(sin_beta1)); CT const dn2 = sqrt(c1 + ep2 * math::sqr(sin_beta2)); - CT a12, sigma12; + CT sigma12; CT m12x, s12x, M21; // Index zero element of coeffs_C1 is unused. @@ -244,7 +244,6 @@ public: m12x *= b; s12x *= b; - a12 = sigma12 / math::d2r(); } else { @@ -270,7 +269,6 @@ public: { result.geodesic_scale = cos(sigma12); } - a12 = lon12 / one_minus_f; } else if (!meridian) { @@ -299,7 +297,6 @@ public: } // Convert to radians. - a12 = sigma12 / math::d2r(); omega12 = lam12 / (one_minus_f * dnm); } else @@ -403,7 +400,6 @@ public: m12x *= b; s12x *= b; - a12 = sigma12 / math::d2r(); } } From 2ff18246838d2b6a4fe2db549f26581ec3e5cb6b Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Mon, 16 Jul 2018 19:06:20 +0500 Subject: [PATCH 23/62] [formulas][test] Update copyright information --- .../boost/geometry/formulas/karney_inverse.hpp | 17 ++++++++++++++++- test/formulas/inverse.cpp | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 28cdae715..01fea667e 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -1,11 +1,26 @@ // Boost.Geometry -// Contributed and/or modified by Adeel Ahmad. +// Copyright (c) 2018 Adeel Ahmad, Islamabad, Pakistan. + +// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program. // 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 GeographicLib, https://geographiclib.sourceforge.io +// GeographicLib is originally written by Charles Karney. + +// Author: Charles Karney (2008-2017) + +// Last updated version of GeographicLib: 1.49 + +// Original copyright notice: + +// Copyright (c) Charles Karney (2008-2017) and licensed +// under the MIT/X11 License. For more information, see +// https://geographiclib.sourceforge.io + #ifndef BOOST_GEOMETRY_FORMULAS_KARNEY_INVERSE_HPP #define BOOST_GEOMETRY_FORMULAS_KARNEY_INVERSE_HPP diff --git a/test/formulas/inverse.cpp b/test/formulas/inverse.cpp index 07c0fbc99..d9617b5ab 100644 --- a/test/formulas/inverse.cpp +++ b/test/formulas/inverse.cpp @@ -4,7 +4,7 @@ // Copyright (c) 2016-2017 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle -// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program. +// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at From 1bfeba16aa7c7e3db6a753ecf74a299244ab7014 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Fri, 20 Jul 2018 13:52:20 +0500 Subject: [PATCH 24/62] [strategies] Add distance strategy for Karney's inverse formula --- .../strategies/geographic/distance_karney.hpp | 116 ++++++++++++++++++ .../strategies/geographic/parameters.hpp | 47 +++++++ .../boost/geometry/strategies/strategies.hpp | 1 + 3 files changed, 164 insertions(+) create mode 100644 include/boost/geometry/strategies/geographic/distance_karney.hpp diff --git a/include/boost/geometry/strategies/geographic/distance_karney.hpp b/include/boost/geometry/strategies/geographic/distance_karney.hpp new file mode 100644 index 000000000..2391496b3 --- /dev/null +++ b/include/boost/geometry/strategies/geographic/distance_karney.hpp @@ -0,0 +1,116 @@ +// Boost.Geometry + +// Copyright (c) 2018 Adeel Ahmad, Islamabad, Pakistan. + +// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program. + +// 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_STRATEGIES_GEOGRAPHIC_KARNEY_HPP +#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_KARNEY_HPP + + +#include +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace distance +{ + +/*! +\brief The solution of the inverse problem of geodesics on latlong coordinates, + after Karney (2011). +\ingroup distance +\tparam Spheroid The reference spheroid model +\tparam CalculationType \tparam_calculation +\author See +- Charles F.F Karney, Algorithms for geodesics, 2011 +https://arxiv.org/pdf/1109.4448.pdf +*/ +template +< + typename Spheroid = srs::spheroid, + typename CalculationType = void +> +class karney + : public strategy::distance::geographic + < + strategy::karney, Spheroid, CalculationType + > +{ + typedef strategy::distance::geographic + < + strategy::karney, Spheroid, CalculationType + > base_type; + +public: + inline karney() + : base_type() + {} + + explicit inline karney(Spheroid const& spheroid) + : base_type(spheroid) + {} +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +template +struct tag > +{ + typedef strategy_tag_distance_point_point type; +}; + + +template +struct return_type, P1, P2> + : karney::template calculation_type +{}; + + +template +struct comparable_type > +{ + typedef karney type; +}; + + +template +struct get_comparable > +{ + static inline karney apply(karney const& input) + { + return input; + } +}; + +template +struct result_from_distance, P1, P2 > +{ + template + static inline typename return_type, P1, P2>::type + apply(karney const& , T const& value) + { + return value; + } +}; + + +} // namespace services +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::distance + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_KARNEY_HPP diff --git a/include/boost/geometry/strategies/geographic/parameters.hpp b/include/boost/geometry/strategies/geographic/parameters.hpp index 92ebe08f2..7c82902dd 100644 --- a/include/boost/geometry/strategies/geographic/parameters.hpp +++ b/include/boost/geometry/strategies/geographic/parameters.hpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -136,6 +138,46 @@ struct vincenty {}; }; +struct karney +{ + template + < + typename CT, + bool EnableCoordinates = true, + bool EnableReverseAzimuth = false, + bool EnableReducedLength = false, + bool EnableGeodesicScale = false, + size_t SeriesOrder = 8 + > + struct direct + : formula::karney_direct + < + CT, EnableCoordinates, EnableReverseAzimuth, + EnableReducedLength, EnableGeodesicScale, + SeriesOrder + > + {}; + + template + < + typename CT, + bool EnableDistance, + bool EnableAzimuth, + bool EnableReverseAzimuth = false, + bool EnableReducedLength = false, + bool EnableGeodesicScale = false, + size_t SeriesOrder = 8 + > + struct inverse + : formula::karney_inverse + < + CT, EnableDistance, + EnableAzimuth, EnableReverseAzimuth, + EnableReducedLength, EnableGeodesicScale, + SeriesOrder + > + {}; +}; template struct default_order @@ -162,6 +204,11 @@ struct default_order : boost::mpl::integral_c {}; +template<> +struct default_order + : boost::mpl::integral_c +{}; + }}} // namespace boost::geometry::strategy diff --git a/include/boost/geometry/strategies/strategies.hpp b/include/boost/geometry/strategies/strategies.hpp index 7d6cb618c..11019bdbb 100644 --- a/include/boost/geometry/strategies/strategies.hpp +++ b/include/boost/geometry/strategies/strategies.hpp @@ -96,6 +96,7 @@ #include #include #include +#include #include #include //#include From 3b6ad807c3cf2cfaa03560d1907a8d9471150728 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Sun, 17 Mar 2019 11:23:37 +0100 Subject: [PATCH 25/62] [formulas][util] Remove math::round_angle() function and use original value instead --- .../boost/geometry/formulas/karney_direct.hpp | 4 ++-- .../geometry/formulas/karney_inverse.hpp | 11 ++++------ include/boost/geometry/util/math.hpp | 20 ------------------- 3 files changed, 6 insertions(+), 29 deletions(-) diff --git a/include/boost/geometry/formulas/karney_direct.hpp b/include/boost/geometry/formulas/karney_direct.hpp index 1e6add7d4..73a7d4ff6 100644 --- a/include/boost/geometry/formulas/karney_direct.hpp +++ b/include/boost/geometry/formulas/karney_direct.hpp @@ -105,11 +105,11 @@ public: CT const ep2 = e2 / math::sqr(one_minus_f); CT sin_alpha1, cos_alpha1; - math::sin_cos_degrees(math::round_angle(azi12), sin_alpha1, cos_alpha1); + math::sin_cos_degrees(azi12, sin_alpha1, cos_alpha1); // Find the reduced latitude. CT sin_beta1, cos_beta1; - math::sin_cos_degrees(math::round_angle(lat1), sin_beta1, cos_beta1); + math::sin_cos_degrees(lat1, sin_beta1, cos_beta1); sin_beta1 *= one_minus_f; math::normalize_unit_vector(sin_beta1, cos_beta1); diff --git a/include/boost/geometry/formulas/karney_inverse.hpp b/include/boost/geometry/formulas/karney_inverse.hpp index 01fea667e..01dd54232 100644 --- a/include/boost/geometry/formulas/karney_inverse.hpp +++ b/include/boost/geometry/formulas/karney_inverse.hpp @@ -129,8 +129,8 @@ public: int lon12_sign = lon12 >= 0 ? 1 : -1; // Make points close to the meridian to lie on it. - lon12 = lon12_sign * math::round_angle(lon12); - lon12_error = math::round_angle((c180 - lon12) - lon12_sign * lon12_error); + lon12 = lon12_sign * lon12; + lon12_error = (c180 - lon12) - lon12_sign * lon12_error; // Convert to radians. CT lam12 = lon12 * math::d2r(); @@ -148,11 +148,8 @@ public: } // Make points close to the equator to lie on it. - lat1 = std::abs(lat1) > c90 ? math::NaN() : lat1; - lat2 = std::abs(lat2) > c90 ? math::NaN() : lat2; - - lat1 = math::round_angle(lat1); - lat2 = math::round_angle(lat2); + lat1 = std::abs(lat1) > c90 ? c90 : lat1; + lat2 = std::abs(lat2) > c90 ? c90 : lat2; // Arrange points in a canonical form, as explained in // paper, Algorithms for geodesics, Eq. (44): diff --git a/include/boost/geometry/util/math.hpp b/include/boost/geometry/util/math.hpp index 6c6ed7658..3e121240f 100644 --- a/include/boost/geometry/util/math.hpp +++ b/include/boost/geometry/util/math.hpp @@ -829,26 +829,6 @@ inline T NaN() #endif } -/*! -\brief Round off a given angle -*/ -template -inline T round_angle(T x) { - static const T z = 1/T(16); - - if (x == 0) - { - return 0; - } - - T y = math::abs(x); - - // z - (z - y) must not be simplified to y. - y = y < z ? z - (z - y) : y; - - return x < 0 ? -y : y; -} - /*! \brief The error-free sum of two numbers. */ From 05ae463f4e182da467c6a7bd5702a5bddfb3d543 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Sun, 17 Mar 2019 11:30:18 +0100 Subject: [PATCH 26/62] [util] Remove math::NaN() function NaN was previously being used when the angle was greater than 90 deg. Since we now use the maximum angle value [-90, 90] this function is no longer required. --- include/boost/geometry/util/math.hpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/include/boost/geometry/util/math.hpp b/include/boost/geometry/util/math.hpp index 3e121240f..ea0c009c9 100644 --- a/include/boost/geometry/util/math.hpp +++ b/include/boost/geometry/util/math.hpp @@ -812,23 +812,6 @@ inline void sin_cos_degrees(T const& x, } } -/*! -\brief The NaN (not a number) -*/ -template -inline T NaN() -{ -#if defined(_MSC_VER) - return std::numeric_limits::has_quiet_NaN ? - std::numeric_limits::quiet_NaN() : - (std::numeric_limits::max)(); -#else - return std::numeric_limits::has_quiet_NaN ? - std::numeric_limits::quiet_NaN() : - std::numeric_limits::max(); -#endif -} - /*! \brief The error-free sum of two numbers. */ From 9885d3b68a59873affd3f71427d629b9aeb795a8 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Sun, 31 Mar 2019 11:17:17 +0200 Subject: [PATCH 27/62] [test] Add tests involving tiny angles for latitude, longitude, and azimuth --- test/formulas/inverse_cases.hpp | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/test/formulas/inverse_cases.hpp b/test/formulas/inverse_cases.hpp index b3b868d56..81546261c 100644 --- a/test/formulas/inverse_cases.hpp +++ b/test/formulas/inverse_cases.hpp @@ -41,6 +41,48 @@ struct expected_results expected_results expected[] = { { + { 180, 0 },{ 0, 0 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + },{ + { 180, 0 },{ 1e-300, 0 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + },{ + { 180, 0 },{ 1e-200, 0 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + },{ + { 180, 0 },{ 1e-100, 0 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + },{ + { 180, 0 },{ 1e-50, 0 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + },{ + { 180, 0 },{ 1e-20, 0 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + },{ + { 180, 0 },{ 1e-10, 0 }, + { 20003931.45862544700503349304, -9.501793528220011062168943853e-09, -179.9999999904981962117744843, 67125.61229850351810455322266, -1 }, + { 20003931.45862544700503349304, -9.501793528220011062168943853e-09, -179.9999999904981962117744843, 67125.61229850351810455322266, -1 }, + { 20003931.45862544700503349304, -9.501793528220011062168943853e-09, -179.9999999904981962117744843, 67125.61229850351810455322266, -1 }, + { 20003931.45862544700503349304, -9.501793528220011062168943853e-09, -179.9999999904981962117744843, 67125.61229850351810455322266, -1 } + },{ { 0, 0 },{ 2, 0 }, { 222638.98158654713188298047, 90.00000000000000000000, 90.00000000000000000000, 222593.46652303214068524539, 0.99938672191946420487 }, { 222638.98158645280636847019, 90.00000000000000000000, 90.00000000000000000000, 222593.46652303214068524539, 0.99938672191946420487 }, From c5b684f74c9b1bb6d30dd4ed2b4cc501b2d94150 Mon Sep 17 00:00:00 2001 From: Adeel Ahmad Date: Sat, 6 Apr 2019 14:18:15 +0200 Subject: [PATCH 28/62] [tests]: Add test for small angles for Kayney's inverse method --- test/formulas/inverse.cpp | 23 ++++ test/formulas/inverse_cases.hpp | 42 -------- test/formulas/inverse_cases_small_angles.hpp | 106 +++++++++++++++++++ 3 files changed, 129 insertions(+), 42 deletions(-) create mode 100644 test/formulas/inverse_cases_small_angles.hpp diff --git a/test/formulas/inverse.cpp b/test/formulas/inverse.cpp index d9617b5ab..e01d7a48e 100644 --- a/test/formulas/inverse.cpp +++ b/test/formulas/inverse.cpp @@ -16,6 +16,7 @@ #include "test_formula.hpp" #include "inverse_cases.hpp" #include "inverse_cases_antipodal.hpp" +#include "inverse_cases_small_angles.hpp" #include #include @@ -107,6 +108,23 @@ void test_karney_antipodal(expected_results_antipodal const& results) check_inverse("karney", results, result, results.karney, results.karney, 0.0000001); } +void test_karney_small_angles(expected_results_small_angles const& results) +{ + double lon1d = results.p1.lon; + double lat1d = results.p1.lat; + double lon2d = results.p2.lon; + double lat2d = results.p2.lat; + + // WGS84 + bg::srs::spheroid spheroid(6378137.0, 6356752.3142451793); + + bg::formula::result_inverse result; + + typedef bg::formula::karney_inverse ka_t; + result = ka_t::apply(lon1d, lat1d, lon2d, lat2d, spheroid); + check_inverse("karney", results, result, results.karney, results.karney, 0.0000001); +} + int test_main(int, char*[]) { for (size_t i = 0; i < expected_size; ++i) @@ -119,5 +137,10 @@ int test_main(int, char*[]) test_karney_antipodal(expected_antipodal[i]); } + for (size_t i = 0; i < expected_size_small_angles; ++i) + { + test_karney_small_angles(expected_small_angles[i]); + } + return 0; } diff --git a/test/formulas/inverse_cases.hpp b/test/formulas/inverse_cases.hpp index 81546261c..b3b868d56 100644 --- a/test/formulas/inverse_cases.hpp +++ b/test/formulas/inverse_cases.hpp @@ -41,48 +41,6 @@ struct expected_results expected_results expected[] = { { - { 180, 0 },{ 0, 0 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - },{ - { 180, 0 },{ 1e-300, 0 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - },{ - { 180, 0 },{ 1e-200, 0 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - },{ - { 180, 0 },{ 1e-100, 0 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - },{ - { 180, 0 },{ 1e-50, 0 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - },{ - { 180, 0 },{ 1e-20, 0 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, - },{ - { 180, 0 },{ 1e-10, 0 }, - { 20003931.45862544700503349304, -9.501793528220011062168943853e-09, -179.9999999904981962117744843, 67125.61229850351810455322266, -1 }, - { 20003931.45862544700503349304, -9.501793528220011062168943853e-09, -179.9999999904981962117744843, 67125.61229850351810455322266, -1 }, - { 20003931.45862544700503349304, -9.501793528220011062168943853e-09, -179.9999999904981962117744843, 67125.61229850351810455322266, -1 }, - { 20003931.45862544700503349304, -9.501793528220011062168943853e-09, -179.9999999904981962117744843, 67125.61229850351810455322266, -1 } - },{ { 0, 0 },{ 2, 0 }, { 222638.98158654713188298047, 90.00000000000000000000, 90.00000000000000000000, 222593.46652303214068524539, 0.99938672191946420487 }, { 222638.98158645280636847019, 90.00000000000000000000, 90.00000000000000000000, 222593.46652303214068524539, 0.99938672191946420487 }, diff --git a/test/formulas/inverse_cases_small_angles.hpp b/test/formulas/inverse_cases_small_angles.hpp new file mode 100644 index 000000000..6fe9557c7 --- /dev/null +++ b/test/formulas/inverse_cases_small_angles.hpp @@ -0,0 +1,106 @@ +// Boost.Geometry +// Unit Test + +// Copyright (c) 2018 Adeel Ahmad, Islamabad, Pakistan. + +// Contributed and/or modified by Adeel Ahmad, as part of Google Summer of Code 2018 program. + +// 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_TEST_INVERSE_CASES_SMALL_ANGLES_HPP +#define BOOST_GEOMETRY_TEST_INVERSE_CASES_SMALL_ANGLES_HPP + +#include "inverse_cases.hpp" + +struct expected_results_small_angles +{ + coordinates p1; + coordinates p2; + expected_result karney; +}; + +/* + These values are collected from GeodTest which is associated with GeographicLib: + https://zenodo.org/record/32156 + + The conversion to C++ array format is done using this Python script: + https://github.com/adl1995/boost-geometry-extra/blob/master/geographiclib-dataset-parse-inverse.py + + Geodesic scale (M12) is absent from the GeodTest dataset, so it is manually generated + using GeographicLib using this C++ script: + https://github.com/adl1995/boost-geometry-extra/blob/master/geographicLib-direct-small_angles.cpp +*/ +expected_results_small_angles expected_small_angles[] = +{ + { + { 180, 0 },{ 0, 0 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + },{ + { 180, 0 },{ 1e-300, 0 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + },{ + { 180, 0 },{ 1e-200, 0 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + },{ + { 180, 0 },{ 1e-100, 0 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + },{ + { 180, 0 },{ 1e-50, 0 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + },{ + { 180, 0 },{ 1e-20, 0 }, + { 20003931.45862544700503349304, -0.00000000000000000000, 180.00000000000000000000, 67125.61229850351810455322266, -1.00000000000000000000 }, + },{ + { 180, 0 },{ 1e-10, 0 }, + { 20003931.45862544700503349304, -9.501793528220011062168943853e-09, -179.9999999904981962117744843, 67125.61229850351810455322266, -1 }, + },{ + { 0, 1e-100 },{ 170, 1e-200}, + { 18924313.43485650792717933655, 90, 90, 1041298.808552250848151743412, -0.9864919282563420210863114335 }, + },{ + { 0, 1e-300 },{ 170, 1e-50}, + { 18924313.43485650792717933655, 90, 90, 1041298.808552250848151743412, -0.9864919282563420210863114335 }, + },{ + { 0, 1e-300 },{ 170, 1e-10}, + { 18924313.43485650792717933655, 89.99999999939157646622334141, 90.00000000060019544889655663, 1041298.80855225014965981245, -0.9864919282563420210863114335 }, + },{ + { 0, 1e-100 },{ 170, 1e-50}, + { 18924313.43485650792717933655, 90, 90, 1041298.808552250848151743412, -0.9864919282563420210863114335 }, + },{ + { 0, 1e-200 },{ 170, 1e-50}, + { 18924313.43485650792717933655, 90, 90, 1041298.808552250848151743412, -0.9864919282563420210863114335 }, + },{ + { 0, 0.0 },{ 170, 1e-10}, + { 18924313.43485650792717933655, 89.99999999939157646622334141, 90.00000000060019544889655663, 1041298.80855225014965981245, -0.9864919282563420210863114335 }, + },{ + { 0, 1e-20 },{ 170, 1e-100}, + { 18924313.43485650792717933655, 90, 90, 1041298.808552250848151743412, -0.9864919282563420210863114335 }, + },{ + { 0, 1e-100 },{ 170, 0.0}, + { 18924313.43485650792717933655, 90, 90, 1041298.808552250848151743412, -0.9864919282563420210863114335 }, + },{ + { 0, 1e-10 },{ 170, 1e-300}, + { 18924313.43485650792717933655, 89.99999999939980455110344337, 90.00000000060842353377665859, 1041298.80855225014965981245, -0.9864919282563420210863114335 }, + },{ + { 0, 1e-300 },{ 170, 1e-100}, + { 18924313.43485650792717933655, 90, 90, 1041298.808552250848151743412, -0.9864919282563420210863114335 }, + },{ + { 0, 1e-200 },{ 170, 1e-100}, + { 18924313.43485650792717933655, 90, 90, 1041298.808552250848151743412, -0.9864919282563420210863114335 }, + },{ + { 0, 1e-10 },{ 170, 1e-50}, + { 18924313.43485650792717933655, 89.99999999939980455110344337, 90.00000000060842353377665859, 1041298.80855225014965981245, -0.9864919282563420210863114335 }, + },{ + { 0, 0.0 },{ 170, 1e-200}, + { 18924313.43485650792717933655, 90, 90, 1041298.808552250848151743412, -0.9864919282563420210863114335 }, + },{ + { 0, 0.0 },{ 170, 1e-10}, + { 18924313.43485650792717933655, 89.99999999939157646622334141, 90.00000000060019544889655663, 1041298.80855225014965981245, -0.9864919282563420210863114335 }, + } +}; + + +size_t const expected_size_small_angles = sizeof(expected_small_angles) / sizeof(expected_results_small_angles); + +#endif // BOOST_GEOMETRY_TEST_INVERSE_CASES_SMALL_ANGLES_HPP From e3ac1dba9b01d44cefe3abe08126a13d013b60f9 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 21 Aug 2019 18:54:42 +0200 Subject: [PATCH 29/62] [shapefile] Add separate loading of doubles (assume the same endianness as int64_t) and add runtime endianness check. --- .../extensions/gis/io/shapefile/read.hpp | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/include/boost/geometry/extensions/gis/io/shapefile/read.hpp b/include/boost/geometry/extensions/gis/io/shapefile/read.hpp index 684b7c1ef..5d511526b 100644 --- a/include/boost/geometry/extensions/gis/io/shapefile/read.hpp +++ b/include/boost/geometry/extensions/gis/io/shapefile/read.hpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -74,14 +75,55 @@ template inline void read_big(IStream & is, T & v) { is.read(reinterpret_cast(&v), sizeof(T)); - v = boost::endian::big_to_native(v); + boost::endian::big_to_native_inplace(v); } template inline void read_little(IStream & is, T & v) { is.read(reinterpret_cast(&v), sizeof(T)); - v = boost::endian::little_to_native(v); + boost::endian::little_to_native_inplace(v); +} + +inline void double_endianness_check() +{ + BOOST_STATIC_ASSERT(sizeof(double) == 8); + BOOST_STATIC_ASSERT(sizeof(double) * CHAR_BIT == 64); + + double d = 0; + unsigned char* c = reinterpret_cast(&d); + boost::int64_t* i = reinterpret_cast(&d); + + c[0] = 0xd0; + c[1] = 0x61; + c[2] = 0xbe; + c[3] = 0xbc; + c[4] = 0x00; + c[5] = 0xa7; + c[6] = 0x62; + c[7] = 0xc0; + + boost::endian::little_to_native_inplace(*i); + + if (static_cast(d) != -149) + { + BOOST_THROW_EXCEPTION(read_shapefile_exception("Unexpected endianness of double, please contact developers.")); + } +} + +// TODO: It is not clear that this will work on all machines because some of +// them may use mixed endianness (half little-endian, half big-endian) for +// doubles or different endianness than the one used for integers. +// It is also not clear why did the generic version above compile in the +// past. +template +inline void read_little(IStream & is, double & v) +{ + BOOST_STATIC_ASSERT(sizeof(double) * CHAR_BIT == 64); + + is.read(reinterpret_cast(&v), sizeof(double)); + boost::int64_t * proxy = reinterpret_cast(&v); + boost::endian::little_to_native_inplace(*proxy); } template @@ -163,6 +205,8 @@ struct shape_type }; }; +// NOTE: in case this is supported in the future +// floating point numbers smaller than -10^38 represent "no-data" template inline void read_m(IStream & is) { @@ -872,6 +916,8 @@ inline void read_shapefile(IStream &is, RangeOfGeometries & range_of_geometries, geometry::concepts::check(); + detail::shapefile::double_endianness_check(); + dispatch::read_shapefile::apply(is, range_of_geometries, strategy); } @@ -887,6 +933,8 @@ inline void read_shapefile(IStream &is, RangeOfGeometries & range_of_geometries) geometry::concepts::check(); + detail::shapefile::double_endianness_check(); + dispatch::read_shapefile::apply(is, range_of_geometries, strategy_type()); } From 6c1b6a349ec18531316ddb7297217e20f952d527 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 21 Aug 2019 18:56:58 +0200 Subject: [PATCH 30/62] [test][shapefile] Add test checking endianness of double in runtime. --- extensions/test/gis/io/Jamfile.v2 | 6 +++++- extensions/test/gis/io/shapefile/Jamfile.v2 | 20 +++++++++++++++++++ extensions/test/gis/io/shapefile/read.cpp | 22 +++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 extensions/test/gis/io/shapefile/Jamfile.v2 create mode 100644 extensions/test/gis/io/shapefile/read.cpp diff --git a/extensions/test/gis/io/Jamfile.v2 b/extensions/test/gis/io/Jamfile.v2 index 7ca605b7b..a3d508681 100644 --- a/extensions/test/gis/io/Jamfile.v2 +++ b/extensions/test/gis/io/Jamfile.v2 @@ -5,9 +5,13 @@ # Copyright (c) 2009-2012 Mateusz Loskot, London, UK. # Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland. # +# This file was modified by Oracle on 2019. +# Modifications copyright (c) 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) build-project wkb ; - +build-project shapefile ; diff --git a/extensions/test/gis/io/shapefile/Jamfile.v2 b/extensions/test/gis/io/shapefile/Jamfile.v2 new file mode 100644 index 000000000..d58c93f3d --- /dev/null +++ b/extensions/test/gis/io/shapefile/Jamfile.v2 @@ -0,0 +1,20 @@ +# Boost.Geometry (aka GGL, Generic Geometry Library) +# +# Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +# Copyright (c) 2008-2012 Bruno Lalande, Paris, France. +# Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +# Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland. +# +# This file was modified by Oracle on 2019. +# Modifications copyright (c) 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) + +test-suite boost-geometry-extensions-gis-io-shapefile + : + [ run read.cpp ] + ; + diff --git a/extensions/test/gis/io/shapefile/read.cpp b/extensions/test/gis/io/shapefile/read.cpp new file mode 100644 index 000000000..2db075298 --- /dev/null +++ b/extensions/test/gis/io/shapefile/read.cpp @@ -0,0 +1,22 @@ +// Boost.Geometry +// Unit Test + +// Copyright (c) 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) + + +#include + +#include + + +int test_main(int, char*[]) +{ + bg::detail::shapefile::double_endianness_check(); + + return 0; +} From 662ae5c5a171e0939a4c5ab07ecea0442a98847c Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 21 Aug 2019 19:18:26 +0200 Subject: [PATCH 31/62] [srs] Add shared_grids_std using std::shared_mutex and simplify defining new grids implementations. --- .../boost/geometry/srs/projections/grids.hpp | 69 ++------ .../projections/impl/pj_apply_gridshift.hpp | 118 +++++++++++-- .../impl/pj_apply_gridshift_shared.hpp | 157 ------------------ .../srs/projections/impl/pj_gridlist.hpp | 81 +++++++-- .../projections/impl/pj_gridlist_shared.hpp | 122 -------------- .../geometry/srs/projections/shared_grids.hpp | 84 ---------- include/boost/geometry/srs/shared_grids.hpp | 23 ++- .../boost/geometry/srs/shared_grids_boost.hpp | 82 +++++++++ .../boost/geometry/srs/shared_grids_std.hpp | 85 ++++++++++ 9 files changed, 370 insertions(+), 451 deletions(-) delete mode 100644 include/boost/geometry/srs/projections/impl/pj_apply_gridshift_shared.hpp delete mode 100644 include/boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp delete mode 100644 include/boost/geometry/srs/projections/shared_grids.hpp create mode 100644 include/boost/geometry/srs/shared_grids_boost.hpp create mode 100644 include/boost/geometry/srs/shared_grids_std.hpp diff --git a/include/boost/geometry/srs/projections/grids.hpp b/include/boost/geometry/srs/projections/grids.hpp index 611344ccd..315ac4a06 100644 --- a/include/boost/geometry/srs/projections/grids.hpp +++ b/include/boost/geometry/srs/projections/grids.hpp @@ -1,7 +1,7 @@ // Boost.Geometry -// This file was modified by Oracle on 2018. -// Modifications copyright (c) 2018, Oracle and/or its affiliates. +// 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, @@ -20,37 +20,14 @@ namespace boost { namespace geometry { -namespace srs -{ -// Forward declarations for functions declarations below -class grids; - -template -class projection_grids; - -} // namespace srs namespace projections { namespace detail { -// Forward declaratios of grids friends -template -inline bool pj_gridlist_merge_gridfile(std::string const& gridname, - StreamPolicy const& stream_policy, - srs::grids & grids, - std::vector & gridindexes); -template -inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy, - Range & range, - srs::grids & grids, - std::vector const& gridindexes); -// Forward declaratios of projection_grids friends -template -inline void pj_gridlist_from_nadgrids(Par const& defn, - srs::projection_grids & grids); -template -inline bool pj_apply_gridshift_2(Par const& defn, Range & range, Grids const& grids); +struct grids_tag {}; +struct shared_grids_tag {}; + }} // namespace projections::detail @@ -70,22 +47,9 @@ public: return gridinfo.empty(); } -private: - template - friend inline bool projections::detail::pj_gridlist_merge_gridfile( - std::string const& gridname, - StreamPolicy const& stream_policy, - srs::grids & grids, - std::vector & gridindexes); - template - friend inline bool projections::detail::pj_apply_gridshift_3( - StreamPolicy const& stream_policy, - Range & range, - srs::grids & grids, - std::vector const& gridindexes); + typedef projections::detail::grids_tag tag; projections::detail::pj_gridinfo gridinfo; - }; struct ifstream_policy @@ -125,29 +89,20 @@ class projection_grids { public: projection_grids(GridsStorage & storage) - : storage_ptr(boost::addressof(storage)) + : m_storage_ptr(boost::addressof(storage)) {} - std::size_t size() const - { - return hindexes.size(); - } + typedef GridsStorage grids_storage_type; - bool empty() const + GridsStorage & grids_storage() const { - return hindexes.empty(); + return *m_storage_ptr; } private: - template - friend inline void projections::detail::pj_gridlist_from_nadgrids( - Par const& defn, - srs::projection_grids & grids); - template - friend inline bool projections::detail::pj_apply_gridshift_2( - Par const& defn, Range & range, Grids const& grids); + GridsStorage * const m_storage_ptr; - GridsStorage * const storage_ptr; +public: std::vector hindexes; }; diff --git a/include/boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp b/include/boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp index e56fecc8b..e9e4c9e5b 100644 --- a/include/boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp +++ b/include/boost/geometry/srs/projections/impl/pj_apply_gridshift.hpp @@ -329,11 +329,13 @@ inline bool load_grid(StreamPolicy const& stream_policy, pj_gi_load & gi) /* This is the real workhorse, given a gridlist. */ /************************************************************************/ -template +// Generic stream policy and standard grids +template inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy, Range & range, - srs::grids & grids, - std::vector const& gridindexes) + Grids & grids, + std::vector const& gridindexes, + grids_tag) { typedef typename boost::range_size::type size_type; @@ -381,6 +383,103 @@ inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy, return true; } +// Generic stream policy and shared grids +template +inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy, + Range & range, + SharedGrids & grids, + std::vector const& gridindexes, + shared_grids_tag) +{ + typedef typename boost::range_size::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; + + { + typename SharedGrids::read_locked lck_grids(grids); + + for ( ; i < point_count ; ++i ) + { + typename boost::range_reference::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, lck_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(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)) + { + typename SharedGrids::write_locked lck_grids(grids); + + // check again in case other thread already loaded the grid. + pj_gi * gip = find_grid(in_lon, in_lat, lck_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; +} + /************************************************************************/ /* pj_apply_gridshift_2() */ @@ -392,7 +491,7 @@ inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy, /************************************************************************/ template -inline bool pj_apply_gridshift_2(Par const& /*defn*/, Range & range, ProjGrids const& grids) +inline bool pj_apply_gridshift_2(Par const& /*defn*/, Range & range, ProjGrids const& proj_grids) { /*if( defn->catalog_name != NULL ) return pj_gc_apply_gridshift( defn, inverse, point_count, point_offset, @@ -404,19 +503,18 @@ inline bool pj_apply_gridshift_2(Par const& /*defn*/, Range & range, ProjGrids c grids.storage_ptr->grids, gridindexes);*/ - BOOST_GEOMETRY_ASSERT(grids.storage_ptr != NULL); - // At this point the grids should be initialized - if (grids.hindexes.empty()) + if (proj_grids.hindexes.empty()) return false; return pj_apply_gridshift_3 < Inverse, typename Par::type - >(grids.storage_ptr->stream_policy, + >(proj_grids.grids_storage().stream_policy, range, - grids.storage_ptr->hgrids, - grids.hindexes); + proj_grids.grids_storage().hgrids, + proj_grids.hindexes, + typename ProjGrids::grids_storage_type::grids_type::tag()); } template diff --git a/include/boost/geometry/srs/projections/impl/pj_apply_gridshift_shared.hpp b/include/boost/geometry/srs/projections/impl/pj_apply_gridshift_shared.hpp deleted file mode 100644 index c83c1bc51..000000000 --- a/include/boost/geometry/srs/projections/impl/pj_apply_gridshift_shared.hpp +++ /dev/null @@ -1,157 +0,0 @@ -// 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 -#include - -#include -#include - - -namespace boost { namespace geometry { namespace projections -{ - -namespace detail -{ - -template -inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy, - Range & range, - shared_grids & grids, - std::vector const& gridindexes) -{ - typedef typename boost::range_size::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 lock(grids.mutex); - - for ( ; i < point_count ; ++i ) - { - typename boost::range_reference::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(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 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 diff --git a/include/boost/geometry/srs/projections/impl/pj_gridlist.hpp b/include/boost/geometry/srs/projections/impl/pj_gridlist.hpp index deccdd39f..6407142f9 100644 --- a/include/boost/geometry/srs/projections/impl/pj_gridlist.hpp +++ b/include/boost/geometry/srs/projections/impl/pj_gridlist.hpp @@ -1,8 +1,8 @@ // 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. +// 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, @@ -92,11 +92,12 @@ inline void pj_gridlist_add_seq_inc(std::vector & gridindexes, } // Generic stream policy and standard grids -template +template inline bool pj_gridlist_merge_gridfile(std::string const& gridname, StreamPolicy const& stream_policy, - srs::grids & grids, - std::vector & gridindexes) + Grids & grids, + std::vector & gridindexes, + grids_tag) { // Try to find in the existing list of loaded grids. Add all // matching grids as with NTv2 we can get many grids from one @@ -121,6 +122,61 @@ inline bool pj_gridlist_merge_gridfile(std::string const& gridname, return true; } +// Generic stream policy and shared grids +template +inline bool pj_gridlist_merge_gridfile(std::string const& gridname, + StreamPolicy const& stream_policy, + SharedGrids & grids, + std::vector & gridindexes, + shared_grids_tag) +{ + // 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). + { + typename SharedGrids::read_locked lck_grids(grids); + + if (pj_gridlist_find_all(gridname, lck_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; + + { + typename SharedGrids::write_locked lck_grids(grids); + + // Try to find in the existing list of loaded grids again + // in case other thread already added it. + if (pj_gridlist_find_all(gridname, lck_grids.gridinfo, gridindexes)) + return true; + + orig_size = lck_grids.gridinfo.size(); + new_size = orig_size + new_grids.size(); + + lck_grids.gridinfo.resize(new_size); + for (std::size_t i = 0 ; i < new_grids.size() ; ++ i) + new_grids[i].swap(lck_grids.gridinfo[i + orig_size]); + } + + pj_gridlist_add_seq_inc(gridindexes, orig_size, new_size); + + return true; +} + /************************************************************************/ /* pj_gridlist_from_nadgrids() */ @@ -147,7 +203,8 @@ inline void pj_gridlist_from_nadgrids(srs::detail::nadgrids const& nadgrids, std::string name(it->begin() + (required ? 0 : 1), it->end()); - if ( ! pj_gridlist_merge_gridfile(name, stream_policy, grids, gridindexes) + if ( ! pj_gridlist_merge_gridfile(name, stream_policy, grids, gridindexes, + typename Grids::tag()) && required ) { BOOST_THROW_EXCEPTION( projection_exception(error_failed_to_load_grid) ); @@ -155,15 +212,13 @@ inline void pj_gridlist_from_nadgrids(srs::detail::nadgrids const& nadgrids, } } -template -inline void pj_gridlist_from_nadgrids(Par const& defn, srs::projection_grids & grids) +template +inline void pj_gridlist_from_nadgrids(Par const& defn, ProjectionGrids & proj_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); + proj_grids.grids_storage().stream_policy, + proj_grids.grids_storage().hgrids, + proj_grids.hindexes); } diff --git a/include/boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp b/include/boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp deleted file mode 100644 index de8640a01..000000000 --- a/include/boost/geometry/srs/projections/impl/pj_gridlist_shared.hpp +++ /dev/null @@ -1,122 +0,0 @@ -// 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 -#include -#include - - -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 -inline bool pj_gridlist_merge_gridfile(std::string const& gridname, - StreamPolicy const& stream_policy, - shared_grids & grids, - std::vector & 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 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 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 diff --git a/include/boost/geometry/srs/projections/shared_grids.hpp b/include/boost/geometry/srs/projections/shared_grids.hpp deleted file mode 100644 index d4a27e4b1..000000000 --- a/include/boost/geometry/srs/projections/shared_grids.hpp +++ /dev/null @@ -1,84 +0,0 @@ -// Boost.Geometry - -// 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) - -#ifndef BOOST_GEOMETRY_SRS_PROJECTIONS_SHARED_GRIDS_HPP -#define BOOST_GEOMETRY_SRS_PROJECTIONS_SHARED_GRIDS_HPP - - -#include - -#include - -#include - - -namespace boost { namespace geometry -{ - - -namespace projections { namespace detail -{ - -// Forward declaration for functions declarations below -class shared_grids; - -// Forward declaratios of shared_grids friends -template -inline bool pj_gridlist_merge_gridfile(std::string const& gridname, - StreamPolicy const& stream_policy, - shared_grids & grids, - std::vector & gridindexes); -template -inline bool pj_apply_gridshift_3(StreamPolicy const& stream_policy, - Range & range, - shared_grids & grids, - std::vector const& gridindexes); - - -class shared_grids -{ -public: - std::size_t size() const - { - boost::shared_lock lock(mutex); - return gridinfo.size(); - } - - bool empty() const - { - boost::shared_lock lock(mutex); - return gridinfo.empty(); - } - -private: - template - friend inline bool projections::detail::pj_gridlist_merge_gridfile( - std::string const& gridname, - StreamPolicy const& stream_policy, - shared_grids & grids, - std::vector & gridindexes); - template - friend inline bool projections::detail::pj_apply_gridshift_3( - StreamPolicy const& stream_policy, - Range & range, - shared_grids & grids, - std::vector const& gridindexes); - - projections::detail::pj_gridinfo gridinfo; - mutable boost::shared_mutex mutex; -}; - -}} // namespace projections::detail - - -}} // namespace boost::geometry - - -#endif // BOOST_GEOMETRY_SRS_PROJECTIONS_SHARED_GRIDS_HPP diff --git a/include/boost/geometry/srs/shared_grids.hpp b/include/boost/geometry/srs/shared_grids.hpp index bc9528bd2..52b4e9944 100644 --- a/include/boost/geometry/srs/shared_grids.hpp +++ b/include/boost/geometry/srs/shared_grids.hpp @@ -1,7 +1,6 @@ // Boost.Geometry -// This file was modified by Oracle on 2018. -// Modifications copyright (c) 2018, Oracle and/or its affiliates. +// 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, @@ -12,15 +11,23 @@ #define BOOST_GEOMETRY_SRS_SHARED_GRIDS_HPP -#include -#include -#include +#include -namespace boost { namespace geometry { namespace srs + +namespace boost { namespace geometry +{ + +namespace srs { -using geometry::projections::detail::shared_grids; -}}} // namespace boost::geometry::srs +typedef shared_grids_boost shared_grids; + + +} // namespace srs + + +}} // namespace boost::geometry + #endif // BOOST_GEOMETRY_SRS_SHARED_GRIDS_HPP diff --git a/include/boost/geometry/srs/shared_grids_boost.hpp b/include/boost/geometry/srs/shared_grids_boost.hpp new file mode 100644 index 000000000..e55298d73 --- /dev/null +++ b/include/boost/geometry/srs/shared_grids_boost.hpp @@ -0,0 +1,82 @@ +// Boost.Geometry + +// 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) + +#ifndef BOOST_GEOMETRY_SRS_SHARED_GRIDS_BOOST_HPP +#define BOOST_GEOMETRY_SRS_SHARED_GRIDS_BOOST_HPP + + +#include + + +#include + + +namespace boost { namespace geometry +{ + +namespace srs +{ + +class shared_grids_boost +{ +public: + std::size_t size() const + { + boost::shared_lock lock(mutex); + return gridinfo.size(); + } + + bool empty() const + { + boost::shared_lock lock(mutex); + return gridinfo.empty(); + } + + typedef projections::detail::shared_grids_tag tag; + + struct read_locked + { + read_locked(shared_grids_boost & g) + : gridinfo(g.gridinfo) + , lock(g.mutex) + {} + + // should be const& + projections::detail::pj_gridinfo & gridinfo; + + private: + boost::shared_lock lock; + }; + + struct write_locked + { + write_locked(shared_grids_boost & g) + : gridinfo(g.gridinfo) + , lock(g.mutex) + {} + + projections::detail::pj_gridinfo & gridinfo; + + private: + boost::unique_lock lock; + }; + +private: + projections::detail::pj_gridinfo gridinfo; + mutable boost::shared_mutex mutex; +}; + + +} // namespace srs + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_SRS_SHARED_GRIDS_BOOST_HPP diff --git a/include/boost/geometry/srs/shared_grids_std.hpp b/include/boost/geometry/srs/shared_grids_std.hpp new file mode 100644 index 000000000..fec5c603a --- /dev/null +++ b/include/boost/geometry/srs/shared_grids_std.hpp @@ -0,0 +1,85 @@ +// Boost.Geometry + +// 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) + +#ifndef BOOST_GEOMETRY_SRS_SHARED_GRIDS_STD_HPP +#define BOOST_GEOMETRY_SRS_SHARED_GRIDS_STD_HPP + + +#include + + +#include +#include + + +namespace boost { namespace geometry +{ + +namespace srs +{ + +class shared_grids_std +{ + typedef std::shared_mutex mutex_type; + +public: + std::size_t size() const + { + std::shared_lock lock(mutex); + return gridinfo.size(); + } + + bool empty() const + { + std::shared_lock lock(mutex); + return gridinfo.empty(); + } + + typedef projections::detail::shared_grids_tag tag; + + struct read_locked + { + read_locked(shared_grids_std & g) + : gridinfo(g.gridinfo) + , lock(g.mutex) + {} + + // should be const& + projections::detail::pj_gridinfo & gridinfo; + + private: + std::shared_lock lock; + }; + + struct write_locked + { + write_locked(shared_grids_std & g) + : gridinfo(g.gridinfo) + , lock(g.mutex) + {} + + projections::detail::pj_gridinfo & gridinfo; + + private: + std::unique_lock lock; + }; + +private: + projections::detail::pj_gridinfo gridinfo; + mutable mutex_type mutex; +}; + + +} // namespace srs + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_SRS_SHARED_GRIDS_STD_HPP From 72c311ae7a045327171f8c7aabc98e28a06541b2 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 21 Aug 2019 19:19:46 +0200 Subject: [PATCH 32/62] [test][srs] Improve test proj4 wrapper. --- test/srs/proj4.hpp | 76 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 15 deletions(-) diff --git a/test/srs/proj4.hpp b/test/srs/proj4.hpp index 436db1177..e076a7fc6 100644 --- a/test/srs/proj4.hpp +++ b/test/srs/proj4.hpp @@ -21,13 +21,27 @@ struct pj_ptr { - explicit pj_ptr(projPJ ptr) + explicit pj_ptr(projPJ ptr = NULL) : m_ptr(ptr) + {} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + pj_ptr(pj_ptr && other) + : m_ptr(other.m_ptr) { - if (ptr == NULL) - throw std::runtime_error("bleh"); + other.m_ptr = NULL; } + pj_ptr & operator=(pj_ptr && other) + { + if (m_ptr) + pj_free(m_ptr); + m_ptr = other.m_ptr; + other.m_ptr = NULL; + return *this; + } +#endif + projPJ get() const { return m_ptr; @@ -40,6 +54,9 @@ struct pj_ptr } private: + pj_ptr(pj_ptr const&); + pj_ptr & operator=(pj_ptr const&); + projPJ m_ptr; }; @@ -96,18 +113,6 @@ struct pj_transformation , m_to(pj_init_plus(to.c_str())) {} - template - void forward(In const& in, Out & out) const - { - double x = boost::geometry::get_as_radian<0>(in); - double y = boost::geometry::get_as_radian<1>(in); - - pj_transform(m_from.get(), m_to.get(), 1, 0, &x, &y, NULL); - - boost::geometry::set_from_radian<0>(out, x); - boost::geometry::set_from_radian<1>(out, y); - } - void forward(std::vector in_x, std::vector in_y, std::vector & out_x, @@ -135,7 +140,48 @@ struct pj_transformation forward(in_xy[i], out_xy[i]); } + template + void forward(In const& in, Out & out, + typename boost::enable_if_c + < + boost::is_same + < + typename boost::geometry::tag::type, + boost::geometry::point_tag + >::value + >::type* dummy = 0) const + { + transform_point(in, out, m_from, m_to); + } + + template + void inverse(In const& in, Out & out, + typename boost::enable_if_c + < + boost::is_same + < + typename boost::geometry::tag::type, + boost::geometry::point_tag + >::value + >::type* dummy = 0) const + { + transform_point(in, out, m_to, m_from); + } + private: + template + static void transform_point(In const& in, Out & out, + pj_ptr const& from, pj_ptr const& to) + { + double x = boost::geometry::get_as_radian<0>(in); + double y = boost::geometry::get_as_radian<1>(in); + + pj_transform(from.get(), to.get(), 1, 0, &x, &y, NULL); + + boost::geometry::set_from_radian<0>(out, x); + boost::geometry::set_from_radian<1>(out, y); + } + pj_ptr m_from; pj_ptr m_to; }; From e351407d0014d9f42d498126b59c05ccc3e73f62 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 21 Aug 2019 20:38:26 +0200 Subject: [PATCH 33/62] [shapefile] Fix variable name. --- include/boost/geometry/extensions/gis/io/shapefile/read.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/geometry/extensions/gis/io/shapefile/read.hpp b/include/boost/geometry/extensions/gis/io/shapefile/read.hpp index 5d511526b..ef9c5d3df 100644 --- a/include/boost/geometry/extensions/gis/io/shapefile/read.hpp +++ b/include/boost/geometry/extensions/gis/io/shapefile/read.hpp @@ -232,7 +232,7 @@ struct read_and_set_z double z; read_little(is, z); - geometry::set<2>(pt, v); + geometry::set<2>(pt, z); } }; From a88744b59c7b06119284829568e16fc60003ebd0 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 21 Aug 2019 23:28:18 +0200 Subject: [PATCH 34/62] [srs] Conditionally use C++17 untimed std::shared_mutex in shared_grids_std. --- include/boost/geometry/srs/shared_grids_std.hpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/include/boost/geometry/srs/shared_grids_std.hpp b/include/boost/geometry/srs/shared_grids_std.hpp index fec5c603a..f940d9037 100644 --- a/include/boost/geometry/srs/shared_grids_std.hpp +++ b/include/boost/geometry/srs/shared_grids_std.hpp @@ -11,8 +11,13 @@ #define BOOST_GEOMETRY_SRS_SHARED_GRIDS_STD_HPP -#include +#include +#ifdef BOOST_NO_CXX14_HDR_SHARED_MUTEX +#error "C++14 header required." +#endif + +#include #include #include @@ -26,7 +31,16 @@ namespace srs class shared_grids_std { + +// VS 2015 Update 2 +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023918) typedef std::shared_mutex mutex_type; +// Other C++17 +#elif !defined(BOOST_NO_CXX14_HDR_SHARED_MUTEX) && (__cplusplus > 201402L) + typedef std::shared_mutex mutex_type; +#else + typedef std::shared_timed_mutex mutex_type; +#endif public: std::size_t size() const From 8e9e163210729bd20b4bdfd6ca99d683185b3bfd Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 27 Aug 2019 00:00:27 +0200 Subject: [PATCH 35/62] [test][srs] Add proj5 and proj6 API wrappers. --- test/srs/proj4.hpp | 147 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 143 insertions(+), 4 deletions(-) diff --git a/test/srs/proj4.hpp b/test/srs/proj4.hpp index e076a7fc6..d9611dc93 100644 --- a/test/srs/proj4.hpp +++ b/test/srs/proj4.hpp @@ -10,13 +10,25 @@ #ifndef BOOST_GEOMETRY_TEST_SRS_PROJ4_HPP #define BOOST_GEOMETRY_TEST_SRS_PROJ4_HPP -#ifdef TEST_WITH_PROJ4 - #include #include #include +#if defined(TEST_WITH_PROJ6) +#define TEST_WITH_PROJ5 +#endif + +#if defined(TEST_WITH_PROJ5) +#define TEST_WITH_PROJ4 + +#include + +#endif + +#if defined(TEST_WITH_PROJ4) +#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H + #include struct pj_ptr @@ -59,7 +71,7 @@ private: projPJ m_ptr; }; - +/* struct pj_projection { pj_projection(std::string const& prj) @@ -104,7 +116,7 @@ struct pj_projection private: pj_ptr m_ptr; -}; +};*/ struct pj_transformation { @@ -188,4 +200,131 @@ private: #endif // TEST_WITH_PROJ4 +#if defined(TEST_WITH_PROJ5) + +struct proj5_ptr +{ + explicit proj5_ptr(PJ *ptr = NULL) + : m_ptr(ptr) + {} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + proj5_ptr(proj5_ptr && other) + : m_ptr(other.m_ptr) + { + other.m_ptr = NULL; + } + + proj5_ptr & operator=(proj5_ptr && other) + { + if (m_ptr) + proj_destroy(m_ptr); + m_ptr = other.m_ptr; + other.m_ptr = NULL; + return *this; + } +#endif + + PJ *get() const + { + return m_ptr; + } + + ~proj5_ptr() + { + if (m_ptr) + proj_destroy(m_ptr); + } + +private: + proj5_ptr(proj5_ptr const&); + proj5_ptr & operator=(proj5_ptr const&); + + PJ *m_ptr; +}; + +struct proj5_transformation +{ + proj5_transformation(std::string const& to) + : m_proj(proj_create(PJ_DEFAULT_CTX, to.c_str())) + {} + + void forward(std::vector in, + std::vector & out) const + { + proj_trans_array(m_proj.get(), PJ_FWD, in.size(), &in[0]); + out = std::move(in); + } + + template + void forward(In const& in, Out & out, + typename boost::enable_if_c + < + boost::is_same + < + typename boost::geometry::tag::type, + boost::geometry::point_tag + >::value + >::type* dummy = 0) const + { + PJ_COORD c; + c.lp.lam = boost::geometry::get_as_radian<0>(in); + c.lp.phi = boost::geometry::get_as_radian<1>(in); + + c = proj_trans(m_proj.get(), PJ_FWD, c); + + boost::geometry::set_from_radian<0>(out, c.xy.x); + boost::geometry::set_from_radian<1>(out, c.xy.y); + } + +private: + proj5_ptr m_proj; +}; + +#endif // TEST_WITH_PROJ5 + +#if defined(TEST_WITH_PROJ6) + +struct proj6_transformation +{ + proj6_transformation(std::string const& from, std::string const& to) + : m_proj(proj_create_crs_to_crs(PJ_DEFAULT_CTX, from.c_str(), to.c_str(), NULL)) + { + //proj_normalize_for_visualization(0, m_proj.get()); + } + + void forward(std::vector in, + std::vector & out) const + { + proj_trans_array(m_proj.get(), PJ_FWD, in.size(), &in[0]); + out = std::move(in); + } + + template + void forward(In const& in, Out & out, + typename boost::enable_if_c + < + boost::is_same + < + typename boost::geometry::tag::type, + boost::geometry::point_tag + >::value + >::type* dummy = 0) const + { + PJ_COORD c; + c.lp.lam = boost::geometry::get_as_radian<0>(in); + c.lp.phi = boost::geometry::get_as_radian<1>(in); + + c = proj_trans(m_proj.get(), PJ_FWD, c); + + boost::geometry::set_from_radian<0>(out, c.xy.x); + boost::geometry::set_from_radian<1>(out, c.xy.y); + } + +private: + proj5_ptr m_proj; +}; + +#endif // TEST_WITH_PROJ6 + #endif // BOOST_GEOMETRY_TEST_SRS_PROJ4_HPP From 4aecfdf3a916ee72446fcce33d44002ec6843b33 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 1 Sep 2019 18:41:20 +0200 Subject: [PATCH 36/62] [srs] Remove unneeded factory_key type. --- .../geometry/srs/projections/factory.hpp | 53 ++++++++++-- .../geometry/srs/projections/factory_key.hpp | 83 ------------------- .../srs/projections/impl/factory_entry.hpp | 9 +- 3 files changed, 49 insertions(+), 96 deletions(-) delete mode 100644 include/boost/geometry/srs/projections/factory_key.hpp diff --git a/include/boost/geometry/srs/projections/factory.hpp b/include/boost/geometry/srs/projections/factory.hpp index 773d2bbcb..641a6e5dd 100644 --- a/include/boost/geometry/srs/projections/factory.hpp +++ b/include/boost/geometry/srs/projections/factory.hpp @@ -2,8 +2,8 @@ // 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. +// This file was modified by Oracle on 2017, 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, @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -127,6 +126,43 @@ namespace boost { namespace geometry { namespace projections namespace detail { +template +struct factory_key +{ + BOOST_MPL_ASSERT_MSG((false), INVALID_PARAMETERS_TYPE, (Params)); +}; + +template <> +struct factory_key +{ + typedef std::string type; + template + static type const& get(ProjParams const& par) + { + return par.id.name; + } + static const char* get(const char* name, srs::dpar::value_proj id) + { + return name; + } +}; + +template +struct factory_key > +{ + typedef srs::dpar::value_proj type; + template + static type const& get(ProjParams const& par) + { + return par.id.id; + } + static srs::dpar::value_proj get(const char* name, srs::dpar::value_proj id) + { + return id; + } +}; + + template class factory { @@ -138,7 +174,8 @@ private: ProjParams > entry_base; - typedef typename factory_key_util::type key_type; + typedef factory_key key; + typedef typename key::type key_type; typedef boost::shared_ptr entry_ptr; typedef std::map entries_map; @@ -249,17 +286,17 @@ public: detail::wink2_init(*this); } - void add_to_factory(key_type const& key, entry_base* entry) + void add_to_factory(const char* name, srs::dpar::value_proj id, entry_base* entry) { // The pointer has to be owned before std::map::operator[] in case it thrown an exception. entry_ptr ptr(entry); - m_entries[key] = ptr; + m_entries[key::get(name, id)] = ptr; } detail::base_v* create_new(Params const& params, ProjParams const& proj_par) const { - typename factory_key_util::type key = factory_key_util::get(proj_par); - typename entries_map::const_iterator it = m_entries.find(key); + typedef typename entries_map::const_iterator const_iterator; + const_iterator it = m_entries.find(key::get(proj_par)); if (it != m_entries.end()) { return it->second->create_new(params, proj_par); diff --git a/include/boost/geometry/srs/projections/factory_key.hpp b/include/boost/geometry/srs/projections/factory_key.hpp deleted file mode 100644 index 924f92415..000000000 --- a/include/boost/geometry/srs/projections/factory_key.hpp +++ /dev/null @@ -1,83 +0,0 @@ -// Boost.Geometry - -// 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) - -#ifndef BOOST_GEOMETRY_PROJECTIONS_FACTORY_KEY_HPP -#define BOOST_GEOMETRY_PROJECTIONS_FACTORY_KEY_HPP - -#include - -#include -#include - -namespace boost { namespace geometry { namespace projections -{ - -namespace detail -{ - -template -struct factory_key_util -{ - BOOST_MPL_ASSERT_MSG((false), INVALID_PARAMETERS_TYPE, (Params)); -}; - -template <> -struct factory_key_util -{ - typedef std::string type; - template - static type const& get(ProjParams const& par) - { - return par.id.name; - } -}; - -template -struct factory_key_util > -{ - typedef srs::dpar::value_proj type; - template - static type const& get(ProjParams const& par) - { - return par.id.id; - } -}; - -struct factory_key -{ - factory_key(const char* name, srs::dpar::value_proj id) - : m_name(name), m_id(id) - {} - - operator const char*() const - { - return m_name; - } - - operator std::string() const - { - return std::string(m_name); - } - - operator srs::dpar::value_proj() const - { - return m_id; - } - -private: - const char* m_name; - srs::dpar::value_proj m_id; -}; - - -} // namespace detail - -}}} // namespace boost::geometry::projections - -#endif // BOOST_GEOMETRY_PROJECTIONS_FACTORY_KEY_HPP diff --git a/include/boost/geometry/srs/projections/impl/factory_entry.hpp b/include/boost/geometry/srs/projections/impl/factory_entry.hpp index 7a21bbbef..dfa790c7f 100644 --- a/include/boost/geometry/srs/projections/impl/factory_entry.hpp +++ b/include/boost/geometry/srs/projections/impl/factory_entry.hpp @@ -2,8 +2,8 @@ // 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. +// 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, @@ -15,7 +15,6 @@ #include -#include #include namespace boost { namespace geometry { namespace projections @@ -76,8 +75,8 @@ template \ inline void FUN_NAME(projections::detail::factory& 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), \ + factory.add_to_factory(#PROJ_NAME, \ + srs::dpar::proj_##PROJ_NAME, \ new ENTRY); } // namespace detail From f609a959c4f28a02f6de4bc1284cb0a4b96eb2ed Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 5 Sep 2019 17:17:33 +0200 Subject: [PATCH 37/62] [srs] Remove unneeded reference from static proj base. Use property of CRTP instead to get the address of proj. --- .../srs/projections/impl/base_static.hpp | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/include/boost/geometry/srs/projections/impl/base_static.hpp b/include/boost/geometry/srs/projections/impl/base_static.hpp index 9aba3dcb3..66fad5376 100644 --- a/include/boost/geometry/srs/projections/impl/base_static.hpp +++ b/include/boost/geometry/srs/projections/impl/base_static.hpp @@ -2,8 +2,8 @@ // 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. +// 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, @@ -21,6 +21,7 @@ #include +#include #include #include @@ -64,8 +65,10 @@ struct base_t_f public: inline base_t_f(Prj const& prj, P const& params) - : m_par(params), m_prj(prj) - {} + : m_par(params) + { + BOOST_GEOMETRY_ASSERT(&prj == this); + } inline P const& params() const { return m_par; } @@ -76,7 +79,7 @@ public: { try { - pj_fwd(m_prj, m_par, lp, xy); + pj_fwd(this->prj(), this->m_par, lp, xy); return true; } catch(...) @@ -100,9 +103,12 @@ public: } protected: + Prj const& prj() const + { + return static_cast(*this); + } P m_par; - const Prj& m_prj; }; // Base-template-forward/inverse @@ -119,7 +125,7 @@ public : { try { - pj_inv(this->m_prj, this->m_par, xy, lp); + pj_inv(this->prj(), this->m_par, xy, lp); return true; } catch(...) From 1a41b64d7c73d6a46c362a2b5ca4efae986d5d87 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 16 Sep 2019 18:33:41 +0200 Subject: [PATCH 38/62] [srs] Move prj params outside. Replace CRTP with wrappers. This allows to remove some virtual functions from dynamic projection. --- include/boost/geometry/srs/projection.hpp | 2 +- .../geometry/srs/projections/factory.hpp | 6 +- .../srs/projections/impl/base_dynamic.hpp | 135 +++++++------- .../srs/projections/impl/base_static.hpp | 111 +++++++----- .../srs/projections/impl/factory_entry.hpp | 14 +- .../geometry/srs/projections/impl/pj_fwd.hpp | 7 +- .../geometry/srs/projections/impl/pj_inv.hpp | 8 +- .../geometry/srs/projections/proj/aea.hpp | 28 ++- .../geometry/srs/projections/proj/aeqd.hpp | 166 +++++------------- .../geometry/srs/projections/proj/airy.hpp | 19 +- .../geometry/srs/projections/proj/aitoff.hpp | 28 ++- .../geometry/srs/projections/proj/august.hpp | 19 +- .../geometry/srs/projections/proj/bacon.hpp | 33 ++-- .../geometry/srs/projections/proj/bipc.hpp | 21 +-- .../geometry/srs/projections/proj/boggs.hpp | 19 +- .../geometry/srs/projections/proj/bonne.hpp | 40 ++--- .../geometry/srs/projections/proj/cass.hpp | 46 ++--- .../geometry/srs/projections/proj/cc.hpp | 21 +-- .../geometry/srs/projections/proj/cea.hpp | 52 ++---- .../geometry/srs/projections/proj/chamb.hpp | 19 +- .../geometry/srs/projections/proj/collg.hpp | 21 +-- .../geometry/srs/projections/proj/crast.hpp | 21 +-- .../geometry/srs/projections/proj/denoy.hpp | 19 +- .../geometry/srs/projections/proj/eck1.hpp | 21 +-- .../geometry/srs/projections/proj/eck2.hpp | 21 +-- .../geometry/srs/projections/proj/eck3.hpp | 42 ++--- .../geometry/srs/projections/proj/eck4.hpp | 21 +-- .../geometry/srs/projections/proj/eck5.hpp | 21 +-- .../geometry/srs/projections/proj/eqc.hpp | 25 +-- .../geometry/srs/projections/proj/eqdc.hpp | 21 +-- .../geometry/srs/projections/proj/etmerc.hpp | 28 ++- .../geometry/srs/projections/proj/fahey.hpp | 21 +-- .../geometry/srs/projections/proj/fouc_s.hpp | 21 +-- .../geometry/srs/projections/proj/gall.hpp | 21 +-- .../geometry/srs/projections/proj/geocent.hpp | 21 +-- .../geometry/srs/projections/proj/geos.hpp | 32 +--- .../geometry/srs/projections/proj/gins8.hpp | 19 +- .../geometry/srs/projections/proj/gn_sinu.hpp | 63 +++---- .../geometry/srs/projections/proj/gnom.hpp | 23 +-- .../geometry/srs/projections/proj/goode.hpp | 58 +++--- .../geometry/srs/projections/proj/gstmerc.hpp | 33 ++-- .../geometry/srs/projections/proj/hammer.hpp | 21 +-- .../geometry/srs/projections/proj/hatano.hpp | 21 +-- .../geometry/srs/projections/proj/healpix.hpp | 76 +++----- .../geometry/srs/projections/proj/igh.hpp | 40 ++--- .../geometry/srs/projections/proj/imw_p.hpp | 23 +-- .../geometry/srs/projections/proj/isea.hpp | 17 +- .../geometry/srs/projections/proj/krovak.hpp | 29 ++- .../geometry/srs/projections/proj/labrd.hpp | 37 ++-- .../geometry/srs/projections/proj/laea.hpp | 48 ++--- .../geometry/srs/projections/proj/lagrng.hpp | 19 +- .../geometry/srs/projections/proj/larr.hpp | 19 +- .../geometry/srs/projections/proj/lask.hpp | 19 +- .../geometry/srs/projections/proj/latlong.hpp | 35 ++-- .../geometry/srs/projections/proj/lcc.hpp | 35 ++-- .../geometry/srs/projections/proj/lcca.hpp | 31 ++-- .../geometry/srs/projections/proj/loxim.hpp | 21 +-- .../geometry/srs/projections/proj/lsat.hpp | 33 ++-- .../geometry/srs/projections/proj/mbt_fps.hpp | 21 +-- .../geometry/srs/projections/proj/mbtfpp.hpp | 21 +-- .../geometry/srs/projections/proj/mbtfpq.hpp | 21 +-- .../geometry/srs/projections/proj/merc.hpp | 52 ++---- .../geometry/srs/projections/proj/mill.hpp | 21 +-- .../srs/projections/proj/mod_ster.hpp | 61 +++---- .../geometry/srs/projections/proj/moll.hpp | 35 ++-- .../srs/projections/proj/natearth.hpp | 21 +-- .../geometry/srs/projections/proj/nell.hpp | 21 +-- .../geometry/srs/projections/proj/nell_h.hpp | 21 +-- .../geometry/srs/projections/proj/nocol.hpp | 19 +- .../geometry/srs/projections/proj/nsper.hpp | 30 ++-- .../geometry/srs/projections/proj/nzmg.hpp | 25 +-- .../geometry/srs/projections/proj/ob_tran.hpp | 86 +++++---- .../geometry/srs/projections/proj/ocea.hpp | 21 +-- .../geometry/srs/projections/proj/oea.hpp | 21 +-- .../geometry/srs/projections/proj/omerc.hpp | 27 ++- .../geometry/srs/projections/proj/ortho.hpp | 25 +-- .../geometry/srs/projections/proj/poly.hpp | 48 ++--- .../geometry/srs/projections/proj/putp2.hpp | 22 +-- .../geometry/srs/projections/proj/putp3.hpp | 28 ++- .../geometry/srs/projections/proj/putp4p.hpp | 28 ++- .../geometry/srs/projections/proj/putp5.hpp | 28 ++- .../geometry/srs/projections/proj/putp6.hpp | 28 ++- .../geometry/srs/projections/proj/qsc.hpp | 27 ++- .../geometry/srs/projections/proj/robin.hpp | 21 +-- .../geometry/srs/projections/proj/rouss.hpp | 31 ++-- .../geometry/srs/projections/proj/rpoly.hpp | 23 +-- .../geometry/srs/projections/proj/sconics.hpp | 63 +++---- .../geometry/srs/projections/proj/somerc.hpp | 27 ++- .../geometry/srs/projections/proj/stere.hpp | 66 +++---- .../geometry/srs/projections/proj/sterea.hpp | 27 ++- .../geometry/srs/projections/proj/sts.hpp | 42 ++--- .../geometry/srs/projections/proj/tcc.hpp | 19 +- .../geometry/srs/projections/proj/tcea.hpp | 29 ++- .../geometry/srs/projections/proj/tmerc.hpp | 52 ++---- .../geometry/srs/projections/proj/tpeqd.hpp | 21 +-- .../geometry/srs/projections/proj/urm5.hpp | 19 +- .../geometry/srs/projections/proj/urmfps.hpp | 28 ++- .../geometry/srs/projections/proj/vandg.hpp | 21 +-- .../geometry/srs/projections/proj/vandg2.hpp | 24 +-- .../geometry/srs/projections/proj/vandg4.hpp | 19 +- .../geometry/srs/projections/proj/wag2.hpp | 21 +-- .../geometry/srs/projections/proj/wag3.hpp | 21 +-- .../geometry/srs/projections/proj/wag7.hpp | 19 +- .../geometry/srs/projections/proj/wink1.hpp | 21 +-- .../geometry/srs/projections/proj/wink2.hpp | 19 +- 105 files changed, 1221 insertions(+), 2061 deletions(-) diff --git a/include/boost/geometry/srs/projection.hpp b/include/boost/geometry/srs/projection.hpp index c5a5674de..0a7d123e6 100644 --- a/include/boost/geometry/srs/projection.hpp +++ b/include/boost/geometry/srs/projection.hpp @@ -338,7 +338,7 @@ class proj_wrapper typedef typename projections::detail::promote_to_double::type calc_t; typedef projections::parameters parameters_type; - typedef projections::detail::base_v vprj_t; + typedef projections::detail::dynamic_wrapper_b vprj_t; public: template diff --git a/include/boost/geometry/srs/projections/factory.hpp b/include/boost/geometry/srs/projections/factory.hpp index 641a6e5dd..599c4bf4d 100644 --- a/include/boost/geometry/srs/projections/factory.hpp +++ b/include/boost/geometry/srs/projections/factory.hpp @@ -293,7 +293,7 @@ public: m_entries[key::get(name, id)] = ptr; } - detail::base_v* create_new(Params const& params, ProjParams const& proj_par) const + detail::dynamic_wrapper_b* create_new(Params const& params, ProjParams const& proj_par) const { typedef typename entries_map::const_iterator const_iterator; const_iterator it = m_entries.find(key::get(proj_par)); @@ -307,7 +307,7 @@ public: }; template -inline detail::base_v >* +inline detail::dynamic_wrapper_b >* create_new(srs::detail::proj4_parameters const& params, projections::parameters const& parameters) { @@ -316,7 +316,7 @@ inline detail::base_v >* } template -inline detail::base_v >* +inline detail::dynamic_wrapper_b >* create_new(srs::dpar::parameters const& params, projections::parameters const& parameters) { diff --git a/include/boost/geometry/srs/projections/impl/base_dynamic.hpp b/include/boost/geometry/srs/projections/impl/base_dynamic.hpp index 5eeba47ba..05a103ecb 100644 --- a/include/boost/geometry/srs/projections/impl/base_dynamic.hpp +++ b/include/boost/geometry/srs/projections/impl/base_dynamic.hpp @@ -2,8 +2,8 @@ // 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. +// 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, @@ -33,16 +33,28 @@ namespace detail \tparam P parameters type */ template -class base_v +class dynamic_wrapper_b { public : + dynamic_wrapper_b(P const& par) + : m_par(par) + {} + + virtual ~dynamic_wrapper_b() {} + + /// Forward projection using lon / lat and x / y separately + virtual void fwd(P const& par, 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(P const& par, CT const& xy_x, CT const& xy_y, CT& lp_lon, CT& lp_lat) const = 0; + /// Forward projection, from Latitude-Longitude to Cartesian template inline bool forward(LL const& lp, XY& xy) const { try { - pj_fwd(*this, this->params(), lp, xy); + pj_fwd(*this, m_par, lp, xy); return true; } catch (...) @@ -57,7 +69,7 @@ public : { try { - pj_inv(*this, this->params(), xy, lp); + pj_inv(*this, m_par, xy, lp); return true; } catch (projection_not_invertible_exception &) @@ -70,87 +82,74 @@ public : } } - /// 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; + std::string name() const { return m_par.id.name; } /// Returns parameters of projection - virtual P const& params() const = 0; + P const& params() const { return m_par; } /// Returns mutable parameters of projection - virtual P& mutable_params() = 0; - - virtual ~base_v() {} -}; - -// Base-virtual-forward -template -class base_v_f : public base_v -{ -public: - explicit base_v_f(P const& p) - : m_proj(p) - {} - - template - base_v_f(P1 const& p1, P2 const& p2) - : m_proj(p1, p2) - {} - - template - 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(); } + P& mutable_params() { return m_par; } protected: - Prj m_proj; + P m_par; }; -// Base-virtual-forward/inverse +// Forward template -class base_v_fi : public base_v_f +class dynamic_wrapper_f + : public dynamic_wrapper_b + , protected Prj { - typedef base_v_f base_t; + typedef dynamic_wrapper_b base_t; public: - explicit base_v_fi(P const& p) - : base_t(p) + template + dynamic_wrapper_f(Params const& params, P const& par) + : base_t(par) + , Prj(params, this->m_par) // prj can modify parameters {} - template - base_v_fi(P1 const& p1, P2 const& p2) - : base_t(p1, p2) + template + dynamic_wrapper_f(Params const& params, P const& par, P3 const& p3) + : base_t(par) + , Prj(params, this->m_par, p3) // prj can modify parameters {} - template - 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 + virtual void fwd(P const& par, CT const& lp_lon, CT const& lp_lat, CT& xy_x, CT& xy_y) const { - this->m_proj.inv(xy_x, xy_y, lp_lon, lp_lat); + prj().fwd(par, lp_lon, lp_lat, xy_x, xy_y); + } + + virtual void inv(P const& , CT const& , CT const& , CT& , CT& ) const + { + BOOST_THROW_EXCEPTION(projection_not_invertible_exception(this->name())); + } + +protected: + Prj const& prj() const { return *this; } +}; + +// Forward/inverse +template +class dynamic_wrapper_fi : public dynamic_wrapper_f +{ + typedef dynamic_wrapper_f base_t; + +public: + template + dynamic_wrapper_fi(Params const& params, P const& par) + : base_t(params, par) + {} + + template + dynamic_wrapper_fi(Params const& params, P const& par, P3 const& p3) + : base_t(params, par, p3) + {} + + virtual void inv(P const& par, CT const& xy_x, CT const& xy_y, CT& lp_lon, CT& lp_lat) const + { + this->prj().inv(par, xy_x, xy_y, lp_lon, lp_lat); } }; diff --git a/include/boost/geometry/srs/projections/impl/base_static.hpp b/include/boost/geometry/srs/projections/impl/base_static.hpp index 66fad5376..99f7a2383 100644 --- a/include/boost/geometry/srs/projections/impl/base_static.hpp +++ b/include/boost/geometry/srs/projections/impl/base_static.hpp @@ -46,78 +46,105 @@ struct static_projection_type (Prj, CSTag)); }; -#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(PROJ, P_SPHERE, P_SPHEROID) \ +#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(PROJ, P_SPHXXX) \ template \ struct static_projection_type \ { \ - typedef P_SPHERE type; \ + typedef projections::detail::static_wrapper_f, P> type; \ }; \ template \ struct static_projection_type \ { \ - typedef P_SPHEROID type; \ + typedef projections::detail::static_wrapper_f, P> type; \ }; \ -// Base-template-forward -template -struct base_t_f +#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(PROJ, P_SPHXXX) \ +template \ +struct static_projection_type \ +{ \ + typedef projections::detail::static_wrapper_fi, P> type; \ +}; \ +template \ +struct static_projection_type \ +{ \ + typedef projections::detail::static_wrapper_fi, P> type; \ +}; \ + +#define BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(PROJ, P_SPHERE, P_SPHEROID) \ +template \ +struct static_projection_type \ +{ \ + typedef projections::detail::static_wrapper_fi, P> type; \ +}; \ +template \ +struct static_projection_type \ +{ \ + typedef projections::detail::static_wrapper_fi, P> type; \ +}; \ + +template +struct static_wrapper_b +{ + inline explicit static_wrapper_b(P const& par) + : m_par(par) + {} + + std::string name() const { return m_par.id.name; } + + P const& params() const { return m_par; } + + P& mutable_params() { return m_par; } + +protected: + P m_par; +}; + +// Forward +template +struct static_wrapper_f + : public static_wrapper_b

+ , public Prj { public: - - inline base_t_f(Prj const& prj, P const& params) - : m_par(params) - { - BOOST_GEOMETRY_ASSERT(&prj == this); - } - - inline P const& params() const { return m_par; } - - inline P& mutable_params() { return m_par; } + template + inline static_wrapper_f(Params const& params, P const& par) + : static_wrapper_b

(par) + , Prj(params, this->m_par) // prj can modify parameters + {} template inline bool forward(LL const& lp, XY& xy) const { try { - pj_fwd(this->prj(), this->m_par, lp, xy); + pj_fwd(*this, this->m_par, lp, xy); return true; } - catch(...) + catch (...) { return false; } } template - inline bool inverse(XY const& , LL& ) const + inline bool inverse(XY const&, LL&) const { BOOST_MPL_ASSERT_MSG((false), - PROJECTION_IS_NOT_INVERTABLE, - (Prj)); + PROJECTION_IS_NOT_INVERTABLE, + (Prj)); return false; } - - inline std::string name() const - { - return this->m_par.id.name; - } - -protected: - Prj const& prj() const - { - return static_cast(*this); - } - - P m_par; }; -// Base-template-forward/inverse -template -struct base_t_fi : public base_t_f +// Forward/inverse +template +struct static_wrapper_fi + : public static_wrapper_f { -public : - inline base_t_fi(Prj const& prj, P const& params) - : base_t_f(prj, params) +public: + template + inline static_wrapper_fi(Params const& params, P const& par) + : static_wrapper_f(params, par) {} template @@ -125,10 +152,10 @@ public : { try { - pj_inv(this->prj(), this->m_par, xy, lp); + pj_inv(*this, this->m_par, xy, lp); return true; } - catch(...) + catch (...) { return false; } diff --git a/include/boost/geometry/srs/projections/impl/factory_entry.hpp b/include/boost/geometry/srs/projections/impl/factory_entry.hpp index dfa790c7f..a22fe950b 100644 --- a/include/boost/geometry/srs/projections/impl/factory_entry.hpp +++ b/include/boost/geometry/srs/projections/impl/factory_entry.hpp @@ -31,7 +31,7 @@ template struct factory_entry { virtual ~factory_entry() {} - virtual base_v* create_new(Params const& , Parameters const& ) const = 0; + virtual dynamic_wrapper_b* create_new(Params const& , Parameters const& ) const = 0; }; // Macros for entries definition @@ -40,22 +40,22 @@ struct factory_entry template \ struct ENTRY : projections::detail::factory_entry \ { \ - projections::detail::base_v* create_new(Params const& params, \ - Parameters const& parameters) const + projections::detail::dynamic_wrapper_b* 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, T, Parameters>(params, parameters); \ + return new projections::detail::dynamic_wrapper_f, 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, T, Parameters>(params, parameters); \ + return new projections::detail::dynamic_wrapper_fi, T, Parameters>(params, parameters); \ } \ BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_END @@ -63,9 +63,9 @@ BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_END BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_BEGIN(ENTRY) \ { \ if (parameters.es != 0.0) \ - return new projections::detail::base_v_fi, T, Parameters>(params, parameters); \ + return new projections::detail::dynamic_wrapper_fi, T, Parameters>(params, parameters); \ else \ - return new projections::detail::base_v_fi, T, Parameters>(params, parameters); \ + return new projections::detail::dynamic_wrapper_fi, T, Parameters>(params, parameters); \ } \ BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_END diff --git a/include/boost/geometry/srs/projections/impl/pj_fwd.hpp b/include/boost/geometry/srs/projections/impl/pj_fwd.hpp index c1725b0a8..01b7b97a2 100644 --- a/include/boost/geometry/srs/projections/impl/pj_fwd.hpp +++ b/include/boost/geometry/srs/projections/impl/pj_fwd.hpp @@ -3,8 +3,8 @@ // 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. +// 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, @@ -90,7 +90,8 @@ inline void pj_fwd(Prj const& prj, P const& par, LL const& ll, XY& xy) calc_t x = 0; calc_t y = 0; - prj.fwd(lp_lon, lp_lat, x, y); + prj.fwd(par, 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)); } diff --git a/include/boost/geometry/srs/projections/impl/pj_inv.hpp b/include/boost/geometry/srs/projections/impl/pj_inv.hpp index 91cf4c50f..aa65af974 100644 --- a/include/boost/geometry/srs/projections/impl/pj_inv.hpp +++ b/include/boost/geometry/srs/projections/impl/pj_inv.hpp @@ -3,8 +3,8 @@ // 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. +// This file was modified by Oracle on 2017, 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, @@ -65,7 +65,9 @@ inline void pj_inv(PRJ const& prj, PAR const& par, XY const& xy, LL& ll) 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 */ + + prj.inv(par, 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 */ diff --git a/include/boost/geometry/srs/projections/proj/aea.hpp b/include/boost/geometry/srs/projections/proj/aea.hpp index 42c2cc9af..bd0bbd24f 100644 --- a/include/boost/geometry/srs/projections/proj/aea.hpp +++ b/include/boost/geometry/srs/projections/proj/aea.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -115,23 +115,17 @@ namespace projections return( i ? Phi : HUGE_VAL ); } - // template class, using CRTP to implement forward/inverse template struct base_aea_ellipsoid - : public base_t_fi, T, Parameters> { par_aea m_proj_parm; - inline base_aea_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid & spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T rho = this->m_proj_parm.c - (this->m_proj_parm.ellips - ? this->m_proj_parm.n * pj_qsfn(sin(lp_lat), this->m_par.e, this->m_par.one_es) + ? this->m_proj_parm.n * pj_qsfn(sin(lp_lat), par.e, par.one_es) : this->m_proj_parm.n2 * sin(lp_lat)); if (rho < 0.) BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); @@ -142,7 +136,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid & spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); @@ -157,7 +151,7 @@ namespace projections if (this->m_proj_parm.ellips) { lp_lat = (this->m_proj_parm.c - lp_lat * lp_lat) / this->m_proj_parm.n; if (fabs(this->m_proj_parm.ec - fabs(lp_lat)) > tolerance7) { - if ((lp_lat = phi1_(lp_lat, this->m_par.e, this->m_par.one_es)) == HUGE_VAL) + if ((lp_lat = phi1_(lp_lat, par.e, par.one_es)) == HUGE_VAL) BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } else lp_lat = lp_lat < 0. ? -half_pi : half_pi; @@ -282,9 +276,8 @@ namespace projections { template inline aea_ellipsoid(Params const& params, Parameters const& par) - : detail::aea::base_aea_ellipsoid(par) { - detail::aea::setup_aea(params, this->m_par, this->m_proj_parm); + detail::aea::setup_aea(params, par, this->m_proj_parm); } }; @@ -309,9 +302,8 @@ namespace projections { template inline leac_ellipsoid(Params const& params, Parameters const& par) - : detail::aea::base_aea_ellipsoid(par) { - detail::aea::setup_leac(params, this->m_par, this->m_proj_parm); + detail::aea::setup_leac(params, par, this->m_proj_parm); } }; @@ -320,8 +312,8 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_aea, aea_ellipsoid, aea_ellipsoid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_leac, leac_ellipsoid, leac_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_aea, aea_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_leac, leac_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(aea_entry, aea_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/aeqd.hpp b/include/boost/geometry/srs/projections/proj/aeqd.hpp index 73ce9aac4..08459dbaa 100644 --- a/include/boost/geometry/srs/projections/proj/aeqd.hpp +++ b/include/boost/geometry/srs/projections/proj/aeqd.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -329,29 +329,23 @@ namespace projections } } - // template class, using CRTP to implement forward/inverse template struct base_aeqd_e - : public base_t_fi, T, Parameters> { par_aeqd m_proj_parm; - inline base_aeqd_e(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) elliptical // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { - e_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm); + e_forward(lp_lon, lp_lat, xy_x, xy_y, par, this->m_proj_parm); } // INVERSE(e_inverse) elliptical // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { - e_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm); + e_inverse(xy_x, xy_y, lp_lon, lp_lat, par, this->m_proj_parm); } static inline std::string get_name() @@ -361,29 +355,23 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_aeqd_e_guam - : public base_t_fi, T, Parameters> { par_aeqd m_proj_parm; - inline base_aeqd_e_guam(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_guam_fwd) Guam elliptical // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { - e_guam_fwd(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm); + e_guam_fwd(lp_lon, lp_lat, xy_x, xy_y, par, this->m_proj_parm); } // INVERSE(e_guam_inv) Guam elliptical // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { - e_guam_inv(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm); + e_guam_inv(xy_x, xy_y, lp_lon, lp_lat, par, this->m_proj_parm); } static inline std::string get_name() @@ -393,78 +381,23 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse - template - struct base_aeqd_e_static - : public base_t_fi, T, Parameters> - { - par_aeqd m_proj_parm; - - static const bool is_guam = ! boost::is_same - < - typename srs::spar::detail::tuples_find_if - < - BGParameters, - //srs::par4::detail::is_guam - srs::spar::detail::is_param::pred - >::type, - void - >::value; - - inline base_aeqd_e_static(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - - // FORWARD(e_forward or e_guam_fwd) elliptical - // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const - { - if (is_guam) - e_guam_fwd(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm); - else - e_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm); - } - - // INVERSE(e_inverse or e_guam_inv) elliptical - // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const - { - if (is_guam) - e_guam_inv(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm); - else - e_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm); - } - - static inline std::string get_name() - { - return "aeqd_e_static"; - } - - }; - - // template class, using CRTP to implement forward/inverse template struct base_aeqd_s - : public base_t_fi, T, Parameters> { par_aeqd m_proj_parm; - inline base_aeqd_s(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spherical // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { - s_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_par, this->m_proj_parm); + s_forward(lp_lon, lp_lat, xy_x, xy_y, par, this->m_proj_parm); } // INVERSE(s_inverse) spherical // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { - s_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_par, this->m_proj_parm); + s_inverse(xy_x, xy_y, lp_lon, lp_lat, par, this->m_proj_parm); } static inline std::string get_name() @@ -497,10 +430,9 @@ namespace projections struct aeqd_e : public detail::aeqd::base_aeqd_e { template - inline aeqd_e(Params const& params, Parameters const& par) - : detail::aeqd::base_aeqd_e(par) + inline aeqd_e(Params const& params, Parameters & par) { - detail::aeqd::setup_aeqd(params, this->m_par, this->m_proj_parm, false, false); + detail::aeqd::setup_aeqd(params, par, this->m_proj_parm, false, false); } }; @@ -524,38 +456,9 @@ namespace projections struct aeqd_e_guam : public detail::aeqd::base_aeqd_e_guam { template - inline aeqd_e_guam(Params const& params, Parameters const& par) - : detail::aeqd::base_aeqd_e_guam(par) + inline aeqd_e_guam(Params const& params, Parameters & par) { - detail::aeqd::setup_aeqd(params, this->m_par, this->m_proj_parm, false, true); - } - }; - - /*! - \brief Azimuthal Equidistant projection - \ingroup projections - \tparam Geographic latlong point type - \tparam Cartesian xy point type - \tparam Parameters parameter type - \par Projection characteristics - - Azimuthal - - Spheroid - - Ellipsoid - \par Projection parameters - - lat_0: Latitude of origin (degrees) - - guam (boolean) - \par Example - \image html ex_aeqd.gif - */ - template - struct aeqd_e_static : public detail::aeqd::base_aeqd_e_static - { - inline aeqd_e_static(SParams const& params, Parameters const& par) - : detail::aeqd::base_aeqd_e_static(par) - { - detail::aeqd::setup_aeqd(params, this->m_par, this->m_proj_parm, - false, - detail::aeqd::base_aeqd_e_static::is_guam); + detail::aeqd::setup_aeqd(params, par, this->m_proj_parm, false, true); } }; @@ -579,10 +482,9 @@ namespace projections struct aeqd_s : public detail::aeqd::base_aeqd_s { template - inline aeqd_s(Params const& params, Parameters const& par) - : detail::aeqd::base_aeqd_s(par) + inline aeqd_s(Params const& params, Parameters & par) { - detail::aeqd::setup_aeqd(params, this->m_par, this->m_proj_parm, true, false); + detail::aeqd::setup_aeqd(params, par, this->m_proj_parm, true, false); } }; @@ -594,12 +496,30 @@ namespace projections template struct static_projection_type { - typedef aeqd_s type; + typedef static_wrapper_fi, P> type; }; template struct static_projection_type { - typedef aeqd_e_static type; + typedef static_wrapper_fi + < + typename boost::mpl::if_c + < + boost::is_same + < + typename srs::spar::detail::tuples_find_if + < + BGP, + //srs::par4::detail::is_guam + srs::spar::detail::is_param::pred + >::type, + void + >::value, + aeqd_e, + aeqd_e_guam + >::type + , P + > type; }; BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_BEGIN(aeqd_entry) @@ -607,11 +527,11 @@ namespace projections bool const guam = pj_get_param_b(params, "guam", srs::dpar::guam); if (parameters.es && ! guam) - return new base_v_fi, T, Parameters>(params, parameters); + return new dynamic_wrapper_fi, T, Parameters>(params, parameters); else if (parameters.es && guam) - return new base_v_fi, T, Parameters>(params, parameters); + return new dynamic_wrapper_fi, T, Parameters>(params, parameters); else - return new base_v_fi, T, Parameters>(params, parameters); + return new dynamic_wrapper_fi, T, Parameters>(params, parameters); } BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_END diff --git a/include/boost/geometry/srs/projections/proj/airy.hpp b/include/boost/geometry/srs/projections/proj/airy.hpp index fc2ea57de..634be76db 100644 --- a/include/boost/geometry/srs/projections/proj/airy.hpp +++ b/include/boost/geometry/srs/projections/proj/airy.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -81,20 +81,14 @@ namespace projections int no_cut; /* do not cut at hemisphere limit */ }; - // template class, using CRTP to implement forward/inverse template struct base_airy_spheroid - : public base_t_f, T, Parameters> { par_airy m_proj_parm; - inline base_airy_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); @@ -209,10 +203,9 @@ namespace projections struct airy_spheroid : public detail::airy::base_airy_spheroid { template - inline airy_spheroid(Params const& params, Parameters const& par) - : detail::airy::base_airy_spheroid(par) + inline airy_spheroid(Params const& params, Parameters & par) { - detail::airy::setup_airy(params, this->m_par, this->m_proj_parm); + detail::airy::setup_airy(params, par, this->m_proj_parm); } }; @@ -221,7 +214,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_airy, airy_spheroid, airy_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_airy, airy_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(airy_entry, airy_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/aitoff.hpp b/include/boost/geometry/srs/projections/proj/aitoff.hpp index a7ad3b086..f11a46e9d 100644 --- a/include/boost/geometry/srs/projections/proj/aitoff.hpp +++ b/include/boost/geometry/srs/projections/proj/aitoff.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -77,20 +77,14 @@ namespace projections mode_type mode; }; - // template class, using CRTP to implement forward/inverse template struct base_aitoff_spheroid - : public base_t_fi, T, Parameters> { par_aitoff m_proj_parm; - inline base_aitoff_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T c, d; @@ -127,7 +121,7 @@ namespace projections // INVERSE(s_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T pi = detail::pi(); static const T two_pi = detail::two_pi(); @@ -253,10 +247,9 @@ namespace projections struct aitoff_spheroid : public detail::aitoff::base_aitoff_spheroid { template - inline aitoff_spheroid(Params const& , Parameters const& par) - : detail::aitoff::base_aitoff_spheroid(par) + inline aitoff_spheroid(Params const& , Parameters & par) { - detail::aitoff::setup_aitoff(this->m_par, this->m_proj_parm); + detail::aitoff::setup_aitoff(par, this->m_proj_parm); } }; @@ -278,10 +271,9 @@ namespace projections struct wintri_spheroid : public detail::aitoff::base_aitoff_spheroid { template - inline wintri_spheroid(Params const& params, Parameters const& par) - : detail::aitoff::base_aitoff_spheroid(par) + inline wintri_spheroid(Params const& params, Parameters & par) { - detail::aitoff::setup_wintri(params, this->m_par, this->m_proj_parm); + detail::aitoff::setup_wintri(params, par, this->m_proj_parm); } }; @@ -290,8 +282,8 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_aitoff, aitoff_spheroid, aitoff_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_wintri, wintri_spheroid, wintri_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_aitoff, aitoff_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_wintri, wintri_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(aitoff_entry, aitoff_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/august.hpp b/include/boost/geometry/srs/projections/proj/august.hpp index fb55dcb9e..4db65c5a2 100644 --- a/include/boost/geometry/srs/projections/proj/august.hpp +++ b/include/boost/geometry/srs/projections/proj/august.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -56,18 +56,12 @@ namespace projections //static const double M = 1.333333333333333; - // template class, using CRTP to implement forward/inverse template struct base_august_spheroid - : public base_t_f, T, Parameters> { - inline base_august_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T M = 1.333333333333333333333333333333333333; @@ -116,10 +110,9 @@ namespace projections struct august_spheroid : public detail::august::base_august_spheroid { template - inline august_spheroid(Params const& , Parameters const& par) - : detail::august::base_august_spheroid(par) + inline august_spheroid(Params const& , Parameters & par) { - detail::august::setup_august(this->m_par); + detail::august::setup_august(par); } }; @@ -128,7 +121,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_august, august_spheroid, august_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_august, august_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(august_entry, august_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/bacon.hpp b/include/boost/geometry/srs/projections/proj/bacon.hpp index 17b3c36e0..aa8653365 100644 --- a/include/boost/geometry/srs/projections/proj/bacon.hpp +++ b/include/boost/geometry/srs/projections/proj/bacon.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -65,20 +65,14 @@ namespace projections int ortl; }; - // template class, using CRTP to implement forward/inverse template struct base_bacon_spheroid - : public base_t_f, T, Parameters> { par_bacon m_proj_parm; - inline base_bacon_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); static const T half_pi_sqr = detail::half_pi_sqr(); @@ -151,10 +145,9 @@ namespace projections struct apian_spheroid : public detail::bacon::base_bacon_spheroid { template - inline apian_spheroid(Params const& , Parameters const& par) - : detail::bacon::base_bacon_spheroid(par) + inline apian_spheroid(Params const& , Parameters & par) { - detail::bacon::setup_apian(this->m_par, this->m_proj_parm); + detail::bacon::setup_apian(par, this->m_proj_parm); } }; @@ -175,10 +168,9 @@ namespace projections struct ortel_spheroid : public detail::bacon::base_bacon_spheroid { template - inline ortel_spheroid(Params const& , Parameters const& par) - : detail::bacon::base_bacon_spheroid(par) + inline ortel_spheroid(Params const& , Parameters & par) { - detail::bacon::setup_ortel(this->m_par, this->m_proj_parm); + detail::bacon::setup_ortel(par, this->m_proj_parm); } }; @@ -199,10 +191,9 @@ namespace projections struct bacon_spheroid : public detail::bacon::base_bacon_spheroid { template - inline bacon_spheroid(Params const& , Parameters const& par) - : detail::bacon::base_bacon_spheroid(par) + inline bacon_spheroid(Params const& , Parameters & par) { - detail::bacon::setup_bacon(this->m_par, this->m_proj_parm); + detail::bacon::setup_bacon(par, this->m_proj_parm); } }; @@ -211,9 +202,9 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_apian, apian_spheroid, apian_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_bacon, bacon_spheroid, bacon_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_ortel, ortel_spheroid, ortel_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_apian, apian_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_bacon, bacon_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_ortel, ortel_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(apian_entry, apian_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/bipc.hpp b/include/boost/geometry/srs/projections/proj/bipc.hpp index 9d531f87a..97a0f7668 100644 --- a/include/boost/geometry/srs/projections/proj/bipc.hpp +++ b/include/boost/geometry/srs/projections/proj/bipc.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -84,20 +84,14 @@ namespace projections int noskew; }; - // template class, using CRTP to implement forward/inverse template struct base_bipc_spheroid - : public base_t_fi, T, Parameters> { par_bipc m_proj_parm; - inline base_bipc_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); static const T pi = detail::pi(); @@ -171,7 +165,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { T t, r, rp, rl, al, z, fAz, Az, s, c, Av; int neg, i; @@ -251,10 +245,9 @@ namespace projections struct bipc_spheroid : public detail::bipc::base_bipc_spheroid { template - inline bipc_spheroid(Params const& params, Parameters const& par) - : detail::bipc::base_bipc_spheroid(par) + inline bipc_spheroid(Params const& params, Parameters & par) { - detail::bipc::setup_bipc(params, this->m_par, this->m_proj_parm); + detail::bipc::setup_bipc(params, par, this->m_proj_parm); } }; @@ -263,7 +256,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_bipc, bipc_spheroid, bipc_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_bipc, bipc_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(bipc_entry, bipc_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/boggs.hpp b/include/boost/geometry/srs/projections/proj/boggs.hpp index a9bf51716..a7d12509e 100644 --- a/include/boost/geometry/srs/projections/proj/boggs.hpp +++ b/include/boost/geometry/srs/projections/proj/boggs.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -62,18 +62,12 @@ namespace projections static const double FXC2 = 1.11072; static const double FYC = 0.49931; - // template class, using CRTP to implement forward/inverse template struct base_boggs_spheroid - : public base_t_f, T, Parameters> { - inline base_boggs_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); static const T pi = detail::pi(); @@ -132,10 +126,9 @@ namespace projections struct boggs_spheroid : public detail::boggs::base_boggs_spheroid { template - inline boggs_spheroid(Params const& , Parameters const& par) - : detail::boggs::base_boggs_spheroid(par) + inline boggs_spheroid(Params const& , Parameters & par) { - detail::boggs::setup_boggs(this->m_par); + detail::boggs::setup_boggs(par); } }; @@ -144,7 +137,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_boggs, boggs_spheroid, boggs_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_boggs, boggs_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(boggs_entry, boggs_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/bonne.hpp b/include/boost/geometry/srs/projections/proj/bonne.hpp index 70bdc87fd..dcbf0e001 100644 --- a/include/boost/geometry/srs/projections/proj/bonne.hpp +++ b/include/boost/geometry/srs/projections/proj/bonne.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -72,43 +72,37 @@ namespace projections detail::en en; }; - // template class, using CRTP to implement forward/inverse template struct base_bonne_ellipsoid - : public base_t_fi, T, Parameters> { par_bonne m_proj_parm; - inline base_bonne_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T rh, E, c; rh = this->m_proj_parm.am1 + this->m_proj_parm.m1 - pj_mlfn(lp_lat, E = sin(lp_lat), c = cos(lp_lat), this->m_proj_parm.en); - E = c * lp_lon / (rh * sqrt(1. - this->m_par.es * E * E)); + E = c * lp_lon / (rh * sqrt(1. - par.es * E * E)); xy_x = rh * sin(E); xy_y = this->m_proj_parm.am1 - rh * cos(E); } // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); T s, rh; rh = boost::math::hypot(xy_x, xy_y = this->m_proj_parm.am1 - xy_y); - lp_lat = pj_inv_mlfn(this->m_proj_parm.am1 + this->m_proj_parm.m1 - rh, this->m_par.es, this->m_proj_parm.en); + lp_lat = pj_inv_mlfn(this->m_proj_parm.am1 + this->m_proj_parm.m1 - rh, par.es, this->m_proj_parm.en); if ((s = fabs(lp_lat)) < half_pi) { s = sin(lp_lat); lp_lon = rh * atan2(xy_x, xy_y) * - sqrt(1. - this->m_par.es * s * s) / cos(lp_lat); + sqrt(1. - par.es * s * s) / cos(lp_lat); } else if (fabs(s - half_pi) <= epsilon10) lp_lon = 0.; else @@ -122,20 +116,14 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_bonne_spheroid - : public base_t_fi, T, Parameters> { par_bonne m_proj_parm; - inline base_bonne_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T E, rh; @@ -149,7 +137,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); @@ -175,7 +163,7 @@ namespace projections // Bonne (Werner lat_1=90) template - inline void setup_bonne(Params const& params, Parameters& par, par_bonne& proj_parm) + inline void setup_bonne(Params const& params, Parameters const& par, par_bonne& proj_parm) { static const T half_pi = detail::half_pi(); @@ -221,9 +209,8 @@ namespace projections { template inline bonne_ellipsoid(Params const& params, Parameters const& par) - : detail::bonne::base_bonne_ellipsoid(par) { - detail::bonne::setup_bonne(params, this->m_par, this->m_proj_parm); + detail::bonne::setup_bonne(params, par, this->m_proj_parm); } }; @@ -247,9 +234,8 @@ namespace projections { template inline bonne_spheroid(Params const& params, Parameters const& par) - : detail::bonne::base_bonne_spheroid(par) { - detail::bonne::setup_bonne(params, this->m_par, this->m_proj_parm); + detail::bonne::setup_bonne(params, par, this->m_proj_parm); } }; @@ -258,7 +244,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_bonne, bonne_spheroid, bonne_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_bonne, bonne_spheroid, bonne_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(bonne_entry, bonne_spheroid, bonne_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/cass.hpp b/include/boost/geometry/srs/projections/proj/cass.hpp index 4f68cd01b..f87ed312d 100644 --- a/include/boost/geometry/srs/projections/proj/cass.hpp +++ b/include/boost/geometry/srs/projections/proj/cass.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -81,20 +81,14 @@ namespace projections detail::en en; }; - // template class, using CRTP to implement forward/inverse template struct base_cass_ellipsoid - : public base_t_fi, T, Parameters> { par_cass m_proj_parm; - inline base_cass_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T C1 = cass::C1(); static const T C2 = cass::C2(); @@ -103,11 +97,11 @@ namespace projections T n = sin(lp_lat); T c = cos(lp_lat); xy_y = pj_mlfn(lp_lat, n, c, this->m_proj_parm.en); - n = 1./sqrt(1. - this->m_par.es * n * n); + n = 1./sqrt(1. - par.es * n * n); T tn = tan(lp_lat); T t = tn * tn; T a1 = lp_lon * c; - c *= this->m_par.es * c / (1 - this->m_par.es); + c *= par.es * c / (1 - par.es); T a2 = a1 * a1; xy_x = n * a1 * (1. - a2 * t * (C1 - (8. - t + 8. * c) * a2 * C2)); @@ -117,7 +111,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T C3 = cass::C3(); static const T C4 = cass::C4(); @@ -125,12 +119,12 @@ namespace projections T ph1; - ph1 = pj_inv_mlfn(this->m_proj_parm.m0 + xy_y, this->m_par.es, this->m_proj_parm.en); + ph1 = pj_inv_mlfn(this->m_proj_parm.m0 + xy_y, par.es, this->m_proj_parm.en); T tn = tan(ph1); T t = tn * tn; T n = sin(ph1); - T r = 1. / (1. - this->m_par.es * n * n); + T r = 1. / (1. - par.es * n * n); n = sqrt(r); - r *= (1. - this->m_par.es) * n; + r *= (1. - par.es) * n; T dd = xy_x / n; T d2 = dd * dd; lp_lat = ph1 - (n * tn / r) * d2 * @@ -146,30 +140,24 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_cass_spheroid - : public base_t_fi, T, Parameters> { par_cass m_proj_parm; - inline base_cass_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { xy_x = asin(cos(lp_lat) * sin(lp_lon)); - xy_y = atan2(tan(lp_lat) , cos(lp_lon)) - this->m_par.phi0; + xy_y = atan2(tan(lp_lat) , cos(lp_lon)) - par.phi0; } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { - T dd = xy_y + this->m_par.phi0; + T dd = xy_y + par.phi0; lp_lat = asin(sin(dd) * cos(xy_x)); lp_lon = atan2(tan(xy_x), cos(dd)); } @@ -213,9 +201,8 @@ namespace projections { template inline cass_ellipsoid(Params const& , Parameters const& par) - : detail::cass::base_cass_ellipsoid(par) { - detail::cass::setup_cass(this->m_par, this->m_proj_parm); + detail::cass::setup_cass(par, this->m_proj_parm); } }; @@ -237,9 +224,8 @@ namespace projections { template inline cass_spheroid(Params const& , Parameters const& par) - : detail::cass::base_cass_spheroid(par) { - detail::cass::setup_cass(this->m_par, this->m_proj_parm); + detail::cass::setup_cass(par, this->m_proj_parm); } }; @@ -248,7 +234,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_cass, cass_spheroid, cass_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_cass, cass_spheroid, cass_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(cass_entry, cass_spheroid, cass_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/cc.hpp b/include/boost/geometry/srs/projections/proj/cc.hpp index fbc97c7bd..0684efc6b 100644 --- a/include/boost/geometry/srs/projections/proj/cc.hpp +++ b/include/boost/geometry/srs/projections/proj/cc.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -58,18 +58,12 @@ namespace projections static const double epsilon10 = 1.e-10; - // template class, using CRTP to implement forward/inverse template struct base_cc_spheroid - : public base_t_fi, T, Parameters> { - inline base_cc_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); @@ -82,7 +76,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = atan(xy_y); lp_lon = xy_x; @@ -121,10 +115,9 @@ namespace projections struct cc_spheroid : public detail::cc::base_cc_spheroid { template - inline cc_spheroid(Params const& , Parameters const& par) - : detail::cc::base_cc_spheroid(par) + inline cc_spheroid(Params const& , Parameters & par) { - detail::cc::setup_cc(this->m_par); + detail::cc::setup_cc(par); } }; @@ -133,7 +126,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_cc, cc_spheroid, cc_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_cc, cc_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(cc_entry, cc_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/cea.hpp b/include/boost/geometry/srs/projections/proj/cea.hpp index 14d7ea9a3..53f253aeb 100644 --- a/include/boost/geometry/srs/projections/proj/cea.hpp +++ b/include/boost/geometry/srs/projections/proj/cea.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -68,31 +68,25 @@ namespace projections detail::apa apa; }; - // template class, using CRTP to implement forward/inverse template struct base_cea_ellipsoid - : public base_t_fi, T, Parameters> { par_cea m_proj_parm; - inline base_cea_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { - xy_x = this->m_par.k0 * lp_lon; - xy_y = .5 * pj_qsfn(sin(lp_lat), this->m_par.e, this->m_par.one_es) / this->m_par.k0; + xy_x = par.k0 * lp_lon; + xy_y = .5 * pj_qsfn(sin(lp_lat), par.e, par.one_es) / par.k0; } // INVERSE(e_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { - lp_lat = pj_authlat(asin( 2. * xy_y * this->m_par.k0 / this->m_proj_parm.qp), this->m_proj_parm.apa); - lp_lon = xy_x / this->m_par.k0; + lp_lat = pj_authlat(asin( 2. * xy_y * par.k0 / this->m_proj_parm.qp), this->m_proj_parm.apa); + lp_lon = xy_x / par.k0; } static inline std::string get_name() @@ -102,39 +96,33 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_cea_spheroid - : public base_t_fi, T, Parameters> { par_cea m_proj_parm; - inline base_cea_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { - xy_x = this->m_par.k0 * lp_lon; - xy_y = sin(lp_lat) / this->m_par.k0; + xy_x = par.k0 * lp_lon; + xy_y = sin(lp_lat) / par.k0; } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); T t; - if ((t = fabs(xy_y *= this->m_par.k0)) - epsilon <= 1.) { + if ((t = fabs(xy_y *= par.k0)) - epsilon <= 1.) { if (t >= 1.) lp_lat = xy_y < 0. ? -half_pi : half_pi; else lp_lat = asin(xy_y); - lp_lon = xy_x / this->m_par.k0; + lp_lon = xy_x / par.k0; } else BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } @@ -190,10 +178,9 @@ namespace projections struct cea_ellipsoid : public detail::cea::base_cea_ellipsoid { template - inline cea_ellipsoid(Params const& params, Parameters const& par) - : detail::cea::base_cea_ellipsoid(par) + inline cea_ellipsoid(Params const& params, Parameters & par) { - detail::cea::setup_cea(params, this->m_par, this->m_proj_parm); + detail::cea::setup_cea(params, par, this->m_proj_parm); } }; @@ -216,10 +203,9 @@ namespace projections struct cea_spheroid : public detail::cea::base_cea_spheroid { template - inline cea_spheroid(Params const& params, Parameters const& par) - : detail::cea::base_cea_spheroid(par) + inline cea_spheroid(Params const& params, Parameters & par) { - detail::cea::setup_cea(params, this->m_par, this->m_proj_parm); + detail::cea::setup_cea(params, par, this->m_proj_parm); } }; @@ -228,7 +214,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_cea, cea_spheroid, cea_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_cea, cea_spheroid, cea_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(cea_entry, cea_spheroid, cea_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/chamb.hpp b/include/boost/geometry/srs/projections/proj/chamb.hpp index 0200a565c..d0e33fde1 100644 --- a/include/boost/geometry/srs/projections/proj/chamb.hpp +++ b/include/boost/geometry/srs/projections/proj/chamb.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -112,20 +112,14 @@ namespace projections return aacos(.5 * (b * b + c * c - a * a) / (b * c)); } - // template class, using CRTP to implement forward/inverse template struct base_chamb_spheroid - : public base_t_f, T, Parameters> { par_chamb m_proj_parm; - inline base_chamb_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T third = detail::third(); @@ -263,10 +257,9 @@ namespace projections struct chamb_spheroid : public detail::chamb::base_chamb_spheroid { template - inline chamb_spheroid(Params const& params, Parameters const& par) - : detail::chamb::base_chamb_spheroid(par) + inline chamb_spheroid(Params const& params, Parameters & par) { - detail::chamb::setup_chamb(params, this->m_par, this->m_proj_parm); + detail::chamb::setup_chamb(params, par, this->m_proj_parm); } }; @@ -275,7 +268,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_chamb, chamb_spheroid, chamb_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_chamb, chamb_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(chamb_entry, chamb_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/collg.hpp b/include/boost/geometry/srs/projections/proj/collg.hpp index 8cddbf803..06d08a92a 100644 --- a/include/boost/geometry/srs/projections/proj/collg.hpp +++ b/include/boost/geometry/srs/projections/proj/collg.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -60,18 +60,12 @@ namespace projections static const double FYC = 1.77245385090551602729; static const double one_plus_eps = 1.0000001; - // template class, using CRTP to implement forward/inverse template struct base_collg_spheroid - : public base_t_fi, T, Parameters> { - inline base_collg_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { if ((xy_y = 1. - sin(lp_lat)) <= 0.) xy_y = 0.; @@ -83,7 +77,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static T const half_pi = detail::half_pi(); @@ -135,10 +129,9 @@ namespace projections struct collg_spheroid : public detail::collg::base_collg_spheroid { template - inline collg_spheroid(Params const& , Parameters const& par) - : detail::collg::base_collg_spheroid(par) + inline collg_spheroid(Params const& , Parameters & par) { - detail::collg::setup_collg(this->m_par); + detail::collg::setup_collg(par); } }; @@ -147,7 +140,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_collg, collg_spheroid, collg_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_collg, collg_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(collg_entry, collg_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/crast.hpp b/include/boost/geometry/srs/projections/proj/crast.hpp index fa6fb98a7..ee8887ba9 100644 --- a/include/boost/geometry/srs/projections/proj/crast.hpp +++ b/include/boost/geometry/srs/projections/proj/crast.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -60,18 +60,12 @@ namespace projections static const double RYM = 0.32573500793527994772; //static const double third = 0.333333333333333333; - // template class, using CRTP to implement forward/inverse template struct base_crast_spheroid - : public base_t_fi, T, Parameters> { - inline base_crast_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { static const T third = detail::third(); @@ -82,7 +76,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T third = detail::third(); @@ -123,10 +117,9 @@ namespace projections struct crast_spheroid : public detail::crast::base_crast_spheroid { template - inline crast_spheroid(Params const& , Parameters const& par) - : detail::crast::base_crast_spheroid(par) + inline crast_spheroid(Params const& , Parameters & par) { - detail::crast::setup_crast(this->m_par); + detail::crast::setup_crast(par); } }; @@ -135,7 +128,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_crast, crast_spheroid, crast_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_crast, crast_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(crast_entry, crast_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/denoy.hpp b/include/boost/geometry/srs/projections/proj/denoy.hpp index 0f344751d..cb5ca2931 100644 --- a/include/boost/geometry/srs/projections/proj/denoy.hpp +++ b/include/boost/geometry/srs/projections/proj/denoy.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -65,18 +65,12 @@ namespace projections template inline T C3() { return 0.0016666666666666666666666666666; } - // template class, using CRTP to implement forward/inverse template struct base_denoy_spheroid - : public base_t_f, T, Parameters> { - inline base_denoy_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T C1 = denoy::C1(); static const T C3 = denoy::C3(); @@ -122,10 +116,9 @@ namespace projections struct denoy_spheroid : public detail::denoy::base_denoy_spheroid { template - inline denoy_spheroid(Params const& , Parameters const& par) - : detail::denoy::base_denoy_spheroid(par) + inline denoy_spheroid(Params const& , Parameters & par) { - detail::denoy::setup_denoy(this->m_par); + detail::denoy::setup_denoy(par); } }; @@ -134,7 +127,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_denoy, denoy_spheroid, denoy_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_denoy, denoy_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(denoy_entry, denoy_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/eck1.hpp b/include/boost/geometry/srs/projections/proj/eck1.hpp index a551c0421..4320176f9 100644 --- a/include/boost/geometry/srs/projections/proj/eck1.hpp +++ b/include/boost/geometry/srs/projections/proj/eck1.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -57,18 +57,12 @@ namespace projections static const double FC = .92131773192356127802; static const double RP = .31830988618379067154; - // template class, using CRTP to implement forward/inverse template struct base_eck1_spheroid - : public base_t_fi, T, Parameters> { - inline base_eck1_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { xy_x = FC * lp_lon * (1. - RP * fabs(lp_lat)); xy_y = FC * lp_lat; @@ -76,7 +70,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = xy_y / FC; lp_lon = xy_x / (FC * (1. - RP * fabs(lp_lat))); @@ -115,10 +109,9 @@ namespace projections struct eck1_spheroid : public detail::eck1::base_eck1_spheroid { template - inline eck1_spheroid(Params const& , Parameters const& par) - : detail::eck1::base_eck1_spheroid(par) + inline eck1_spheroid(Params const& , Parameters & par) { - detail::eck1::setup_eck1(this->m_par); + detail::eck1::setup_eck1(par); } }; @@ -127,7 +120,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_eck1, eck1_spheroid, eck1_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_eck1, eck1_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(eck1_entry, eck1_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/eck2.hpp b/include/boost/geometry/srs/projections/proj/eck2.hpp index c9f8f8d41..b09979668 100644 --- a/include/boost/geometry/srs/projections/proj/eck2.hpp +++ b/include/boost/geometry/srs/projections/proj/eck2.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -61,18 +61,12 @@ namespace projections //static const double C13 = 0.33333333333333333333; static const double one_plus_eps = 1.0000001; - // template class, using CRTP to implement forward/inverse template struct base_eck2_spheroid - : public base_t_fi, T, Parameters> { - inline base_eck2_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { xy_x = FXC * lp_lon * (xy_y = sqrt(4. - 3. * sin(fabs(lp_lat)))); xy_y = FYC * (2. - xy_y); @@ -81,7 +75,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); static const T C13 = detail::third(); @@ -132,10 +126,9 @@ namespace projections struct eck2_spheroid : public detail::eck2::base_eck2_spheroid { template - inline eck2_spheroid(Params const& , Parameters const& par) - : detail::eck2::base_eck2_spheroid(par) + inline eck2_spheroid(Params const& , Parameters & par) { - detail::eck2::setup_eck2(this->m_par); + detail::eck2::setup_eck2(par); } }; @@ -144,7 +137,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_eck2, eck2_spheroid, eck2_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_eck2, eck2_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(eck2_entry, eck2_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/eck3.hpp b/include/boost/geometry/srs/projections/proj/eck3.hpp index 65ff88429..85d13ed2d 100644 --- a/include/boost/geometry/srs/projections/proj/eck3.hpp +++ b/include/boost/geometry/srs/projections/proj/eck3.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -63,20 +63,14 @@ namespace projections T C_x, C_y, A, B; }; - // template class, using CRTP to implement forward/inverse template struct base_eck3_spheroid - : public base_t_fi, T, Parameters> { par_eck3 m_proj_parm; - inline base_eck3_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { xy_y = this->m_proj_parm.C_y * lp_lat; xy_x = this->m_proj_parm.C_x * lp_lon * (this->m_proj_parm.A + asqrt(1. - this->m_proj_parm.B * lp_lat * lp_lat)); @@ -84,7 +78,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { T denominator; lp_lat = xy_y / this->m_proj_parm.C_y; @@ -179,10 +173,9 @@ namespace projections struct eck3_spheroid : public detail::eck3::base_eck3_spheroid { template - inline eck3_spheroid(Params const& , Parameters const& par) - : detail::eck3::base_eck3_spheroid(par) + inline eck3_spheroid(Params const& , Parameters & par) { - detail::eck3::setup_eck3(this->m_par, this->m_proj_parm); + detail::eck3::setup_eck3(par, this->m_proj_parm); } }; @@ -202,10 +195,9 @@ namespace projections struct putp1_spheroid : public detail::eck3::base_eck3_spheroid { template - inline putp1_spheroid(Params const& , Parameters const& par) - : detail::eck3::base_eck3_spheroid(par) + inline putp1_spheroid(Params const& , Parameters & par) { - detail::eck3::setup_putp1(this->m_par, this->m_proj_parm); + detail::eck3::setup_putp1(par, this->m_proj_parm); } }; @@ -225,10 +217,9 @@ namespace projections struct wag6_spheroid : public detail::eck3::base_eck3_spheroid { template - inline wag6_spheroid(Params const& , Parameters const& par) - : detail::eck3::base_eck3_spheroid(par) + inline wag6_spheroid(Params const& , Parameters & par) { - detail::eck3::setup_wag6(this->m_par, this->m_proj_parm); + detail::eck3::setup_wag6(par, this->m_proj_parm); } }; @@ -248,10 +239,9 @@ namespace projections struct kav7_spheroid : public detail::eck3::base_eck3_spheroid { template - inline kav7_spheroid(Params const& , Parameters const& par) - : detail::eck3::base_eck3_spheroid(par) + inline kav7_spheroid(Params const& , Parameters & par) { - detail::eck3::setup_kav7(this->m_par, this->m_proj_parm); + detail::eck3::setup_kav7(par, this->m_proj_parm); } }; @@ -260,10 +250,10 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_eck3, eck3_spheroid, eck3_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_putp1, putp1_spheroid, putp1_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_wag6, wag6_spheroid, wag6_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_kav7, kav7_spheroid, kav7_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_eck3, eck3_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_putp1, putp1_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_wag6, wag6_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_kav7, kav7_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(eck3_entry, eck3_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/eck4.hpp b/include/boost/geometry/srs/projections/proj/eck4.hpp index 0a8a2bcd9..bdc4311e9 100644 --- a/include/boost/geometry/srs/projections/proj/eck4.hpp +++ b/include/boost/geometry/srs/projections/proj/eck4.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -63,18 +63,12 @@ namespace projections static const double epsilon = 1e-7; static const int n_iter = 6; - // template class, using CRTP to implement forward/inverse template struct base_eck4_spheroid - : public base_t_fi, T, Parameters> { - inline base_eck4_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { T p, V, s, c; int i; @@ -101,7 +95,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { T c; @@ -143,10 +137,9 @@ namespace projections struct eck4_spheroid : public detail::eck4::base_eck4_spheroid { template - inline eck4_spheroid(Params const& , Parameters const& par) - : detail::eck4::base_eck4_spheroid(par) + inline eck4_spheroid(Params const& , Parameters & par) { - detail::eck4::setup_eck4(this->m_par); + detail::eck4::setup_eck4(par); } }; @@ -155,7 +148,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_eck4, eck4_spheroid, eck4_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_eck4, eck4_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(eck4_entry, eck4_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/eck5.hpp b/include/boost/geometry/srs/projections/proj/eck5.hpp index 23901b71a..ae658ea61 100644 --- a/include/boost/geometry/srs/projections/proj/eck5.hpp +++ b/include/boost/geometry/srs/projections/proj/eck5.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -59,18 +59,12 @@ namespace projections static const double YF = 0.88202554344910296438; static const double RYF = 1.13375401361911319568; - // template class, using CRTP to implement forward/inverse template struct base_eck5_spheroid - : public base_t_fi, T, Parameters> { - inline base_eck5_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { xy_x = XF * (1. + cos(lp_lat)) * lp_lon; xy_y = YF * lp_lat; @@ -78,7 +72,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { lp_lon = RXF * xy_x / (1. + cos( lp_lat = RYF * xy_y)); } @@ -116,10 +110,9 @@ namespace projections struct eck5_spheroid : public detail::eck5::base_eck5_spheroid { template - inline eck5_spheroid(Params const& , Parameters const& par) - : detail::eck5::base_eck5_spheroid(par) + inline eck5_spheroid(Params const& , Parameters & par) { - detail::eck5::setup_eck5(this->m_par); + detail::eck5::setup_eck5(par); } }; @@ -128,7 +121,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_eck5, eck5_spheroid, eck5_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_eck5, eck5_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(eck5_entry, eck5_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/eqc.hpp b/include/boost/geometry/srs/projections/proj/eqc.hpp index 5a19f39ec..93a90dca3 100644 --- a/include/boost/geometry/srs/projections/proj/eqc.hpp +++ b/include/boost/geometry/srs/projections/proj/eqc.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -60,31 +60,25 @@ namespace projections T rc; }; - // template class, using CRTP to implement forward/inverse template struct base_eqc_spheroid - : public base_t_fi, T, Parameters> { par_eqc m_proj_parm; - inline base_eqc_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { xy_x = this->m_proj_parm.rc * lp_lon; - xy_y = lp_lat - this->m_par.phi0; + xy_y = lp_lat - par.phi0; } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { lp_lon = xy_x / this->m_proj_parm.rc; - lp_lat = xy_y + this->m_par.phi0; + lp_lat = xy_y + par.phi0; } static inline std::string get_name() @@ -126,10 +120,9 @@ namespace projections struct eqc_spheroid : public detail::eqc::base_eqc_spheroid { template - inline eqc_spheroid(Params const& params, Parameters const& par) - : detail::eqc::base_eqc_spheroid(par) + inline eqc_spheroid(Params const& params, Parameters & par) { - detail::eqc::setup_eqc(params, this->m_par, this->m_proj_parm); + detail::eqc::setup_eqc(params, par, this->m_proj_parm); } }; @@ -138,7 +131,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_eqc, eqc_spheroid, eqc_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_eqc, eqc_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(eqc_entry, eqc_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/eqdc.hpp b/include/boost/geometry/srs/projections/proj/eqdc.hpp index 986e258e2..2919c5d7f 100644 --- a/include/boost/geometry/srs/projections/proj/eqdc.hpp +++ b/include/boost/geometry/srs/projections/proj/eqdc.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -75,20 +75,14 @@ namespace projections bool ellips; }; - // template class, using CRTP to implement forward/inverse template struct base_eqdc_ellipsoid - : public base_t_fi, T, Parameters> { par_eqdc m_proj_parm; - inline base_eqdc_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) sphere & ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T rho = 0.0; @@ -100,7 +94,7 @@ namespace projections // INVERSE(e_inverse) sphere & ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { static T const half_pi = detail::half_pi(); @@ -114,7 +108,7 @@ namespace projections } lp_lat = this->m_proj_parm.c - rho; if (this->m_proj_parm.ellips) - lp_lat = pj_inv_mlfn(lp_lat, this->m_par.es, this->m_proj_parm.en); + lp_lat = pj_inv_mlfn(lp_lat, par.es, this->m_proj_parm.en); lp_lon = atan2(xy_x, xy_y) / this->m_proj_parm.n; } else { lp_lon = 0.; @@ -193,9 +187,8 @@ namespace projections { template inline eqdc_ellipsoid(Params const& params, Parameters const& par) - : detail::eqdc::base_eqdc_ellipsoid(par) { - detail::eqdc::setup_eqdc(params, this->m_par, this->m_proj_parm); + detail::eqdc::setup_eqdc(params, par, this->m_proj_parm); } }; @@ -204,7 +197,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_eqdc, eqdc_ellipsoid, eqdc_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_eqdc, eqdc_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(eqdc_entry, eqdc_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/etmerc.hpp b/include/boost/geometry/srs/projections/proj/etmerc.hpp index 86e2a506f..946ad2813 100644 --- a/include/boost/geometry/srs/projections/proj/etmerc.hpp +++ b/include/boost/geometry/srs/projections/proj/etmerc.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -163,20 +163,14 @@ namespace projections return(sin(arg_r)*hr); } - // template class, using CRTP to implement forward/inverse template struct base_etmerc_ellipsoid - : public base_t_fi, T, Parameters> { par_etmerc m_proj_parm; - inline base_etmerc_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T sin_Cn, cos_Cn, cos_Ce, sin_Ce, dCn, dCe; T Cn = lp_lat, Ce = lp_lon; @@ -205,7 +199,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { T sin_Cn, cos_Cn, cos_Ce, sin_Ce, dCn, dCe; T Cn = xy_y, Ce = xy_x; @@ -391,10 +385,9 @@ namespace projections struct etmerc_ellipsoid : public detail::etmerc::base_etmerc_ellipsoid { template - inline etmerc_ellipsoid(Params const& , Parameters const& par) - : detail::etmerc::base_etmerc_ellipsoid(par) + inline etmerc_ellipsoid(Params const& , Parameters & par) { - detail::etmerc::setup_etmerc(this->m_par, this->m_proj_parm); + detail::etmerc::setup_etmerc(par, this->m_proj_parm); } }; @@ -417,10 +410,9 @@ namespace projections struct utm_ellipsoid : public detail::etmerc::base_etmerc_ellipsoid { template - inline utm_ellipsoid(Params const& params, Parameters const& par) - : detail::etmerc::base_etmerc_ellipsoid(par) + inline utm_ellipsoid(Params const& params, Parameters & par) { - detail::etmerc::setup_utm(params, this->m_par, this->m_proj_parm); + detail::etmerc::setup_utm(params, par, this->m_proj_parm); } }; @@ -429,8 +421,8 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_etmerc, etmerc_ellipsoid, etmerc_ellipsoid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_utm, utm_ellipsoid, utm_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_etmerc, etmerc_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_utm, utm_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(etmerc_entry, etmerc_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/fahey.hpp b/include/boost/geometry/srs/projections/proj/fahey.hpp index 85cc05c93..e143436f9 100644 --- a/include/boost/geometry/srs/projections/proj/fahey.hpp +++ b/include/boost/geometry/srs/projections/proj/fahey.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -57,18 +57,12 @@ namespace projections static const double tolerance = 1e-6; - // template class, using CRTP to implement forward/inverse template struct base_fahey_spheroid - : public base_t_fi, T, Parameters> { - inline base_fahey_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { xy_x = tan(0.5 * lp_lat); xy_y = 1.819152 * xy_x; @@ -77,7 +71,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const { xy_y /= 1.819152; lp_lat = 2. * atan(xy_y); @@ -118,10 +112,9 @@ namespace projections struct fahey_spheroid : public detail::fahey::base_fahey_spheroid { template - inline fahey_spheroid(Params const& , Parameters const& par) - : detail::fahey::base_fahey_spheroid(par) + inline fahey_spheroid(Params const& , Parameters & par) { - detail::fahey::setup_fahey(this->m_par); + detail::fahey::setup_fahey(par); } }; @@ -130,7 +123,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_fahey, fahey_spheroid, fahey_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_fahey, fahey_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(fahey_entry, fahey_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/fouc_s.hpp b/include/boost/geometry/srs/projections/proj/fouc_s.hpp index f6a8c5ed4..ec1cd3483 100644 --- a/include/boost/geometry/srs/projections/proj/fouc_s.hpp +++ b/include/boost/geometry/srs/projections/proj/fouc_s.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -67,20 +67,14 @@ namespace projections T n, n1; }; - // template class, using CRTP to implement forward/inverse template struct base_fouc_s_spheroid - : public base_t_fi, T, Parameters> { par_fouc_s m_proj_parm; - inline base_fouc_s_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T t; @@ -91,7 +85,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static T const half_pi = detail::half_pi(); @@ -154,10 +148,9 @@ namespace projections struct fouc_s_spheroid : public detail::fouc_s::base_fouc_s_spheroid { template - inline fouc_s_spheroid(Params const& params, Parameters const& par) - : detail::fouc_s::base_fouc_s_spheroid(par) + inline fouc_s_spheroid(Params const& params, Parameters & par) { - detail::fouc_s::setup_fouc_s(params, this->m_par, this->m_proj_parm); + detail::fouc_s::setup_fouc_s(params, par, this->m_proj_parm); } }; @@ -166,7 +159,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_fouc_s, fouc_s_spheroid, fouc_s_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_fouc_s, fouc_s_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(fouc_s_entry, fouc_s_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/gall.hpp b/include/boost/geometry/srs/projections/proj/gall.hpp index 5d2779945..61967ce81 100644 --- a/include/boost/geometry/srs/projections/proj/gall.hpp +++ b/include/boost/geometry/srs/projections/proj/gall.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -59,18 +59,12 @@ namespace projections static const double RYF = 0.58578643762690495119; static const double RXF = 1.41421356237309504880; - // template class, using CRTP to implement forward/inverse template struct base_gall_spheroid - : public base_t_fi, T, Parameters> { - inline base_gall_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { xy_x = XF * lp_lon; xy_y = YF * tan(.5 * lp_lat); @@ -78,7 +72,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { lp_lon = RXF * xy_x; lp_lat = 2. * atan(xy_y * RYF); @@ -117,10 +111,9 @@ namespace projections struct gall_spheroid : public detail::gall::base_gall_spheroid { template - inline gall_spheroid(Params const& , Parameters const& par) - : detail::gall::base_gall_spheroid(par) + inline gall_spheroid(Params const& , Parameters & par) { - detail::gall::setup_gall(this->m_par); + detail::gall::setup_gall(par); } }; @@ -129,7 +122,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_gall, gall_spheroid, gall_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_gall, gall_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(gall_entry, gall_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/geocent.hpp b/include/boost/geometry/srs/projections/proj/geocent.hpp index 094feca58..541073672 100644 --- a/include/boost/geometry/srs/projections/proj/geocent.hpp +++ b/include/boost/geometry/srs/projections/proj/geocent.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -60,18 +60,12 @@ namespace projections namespace detail { namespace geocent { - // template class, using CRTP to implement forward/inverse template struct base_geocent_other - : public base_t_fi, T, Parameters> { - inline base_geocent_other(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(forward) // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { xy_x = lp_lon; xy_y = lp_lat; @@ -79,7 +73,7 @@ namespace projections // INVERSE(inverse) // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = xy_y; lp_lon = xy_x; @@ -117,10 +111,9 @@ namespace projections struct geocent_other : public detail::geocent::base_geocent_other { template - inline geocent_other(Params const& , Parameters const& par) - : detail::geocent::base_geocent_other(par) + inline geocent_other(Params const& , Parameters & par) { - detail::geocent::setup_geocent(this->m_par); + detail::geocent::setup_geocent(par); } }; @@ -129,7 +122,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_geocent, geocent_other, geocent_other) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_geocent, geocent_other) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(geocent_entry, geocent_other) diff --git a/include/boost/geometry/srs/projections/proj/geos.hpp b/include/boost/geometry/srs/projections/proj/geos.hpp index f9f290124..e27786ee1 100644 --- a/include/boost/geometry/srs/projections/proj/geos.hpp +++ b/include/boost/geometry/srs/projections/proj/geos.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -75,20 +75,14 @@ namespace projections bool flip_axis; }; - // template class, using CRTP to implement forward/inverse template struct base_geos_ellipsoid - : public base_t_fi, T, Parameters> { par_geos m_proj_parm; - inline base_geos_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { T r, Vx, Vy, Vz, tmp; @@ -121,7 +115,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { T Vx, Vy, Vz, a, b, det, k; @@ -163,20 +157,14 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_geos_spheroid - : public base_t_fi, T, Parameters> { par_geos m_proj_parm; - inline base_geos_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T Vx, Vy, Vz, tmp; @@ -206,7 +194,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { T Vx, Vy, Vz, a, b, det, k; @@ -325,9 +313,8 @@ namespace projections { template inline geos_ellipsoid(Params const& params, Parameters const& par) - : detail::geos::base_geos_ellipsoid(par) { - detail::geos::setup_geos(params, this->m_par, this->m_proj_parm); + detail::geos::setup_geos(params, par, this->m_proj_parm); } }; @@ -352,9 +339,8 @@ namespace projections { template inline geos_spheroid(Params const& params, Parameters const& par) - : detail::geos::base_geos_spheroid(par) { - detail::geos::setup_geos(params, this->m_par, this->m_proj_parm); + detail::geos::setup_geos(params, par, this->m_proj_parm); } }; @@ -363,7 +349,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_geos, geos_spheroid, geos_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_geos, geos_spheroid, geos_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(geos_entry, geos_spheroid, geos_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/gins8.hpp b/include/boost/geometry/srs/projections/proj/gins8.hpp index 2e9088a2a..b1bb4a74c 100644 --- a/include/boost/geometry/srs/projections/proj/gins8.hpp +++ b/include/boost/geometry/srs/projections/proj/gins8.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -61,18 +61,12 @@ namespace projections template inline T C12() { return 0.083333333333333333333333333333333333; } - // template class, using CRTP to implement forward/inverse template struct base_gins8_spheroid - : public base_t_f, T, Parameters> { - inline base_gins8_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T C12 = gins8::C12(); @@ -118,10 +112,9 @@ namespace projections struct gins8_spheroid : public detail::gins8::base_gins8_spheroid { template - inline gins8_spheroid(Params const& , Parameters const& par) - : detail::gins8::base_gins8_spheroid(par) + inline gins8_spheroid(Params const& , Parameters & par) { - detail::gins8::setup_gins8(this->m_par); + detail::gins8::setup_gins8(par); } }; @@ -130,7 +123,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_gins8, gins8_spheroid, gins8_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_gins8, gins8_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(gins8_entry, gins8_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/gn_sinu.hpp b/include/boost/geometry/srs/projections/proj/gn_sinu.hpp index 2ef7df509..ea7a8f95c 100644 --- a/include/boost/geometry/srs/projections/proj/gn_sinu.hpp +++ b/include/boost/geometry/srs/projections/proj/gn_sinu.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -72,38 +72,32 @@ namespace projections /* Ellipsoidal Sinusoidal only */ - // template class, using CRTP to implement forward/inverse template struct base_gn_sinu_ellipsoid - : public base_t_fi, T, Parameters> { par_gn_sinu m_proj_parm; - inline base_gn_sinu_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T s, c; xy_y = pj_mlfn(lp_lat, s = sin(lp_lat), c = cos(lp_lat), this->m_proj_parm.en); - xy_x = lp_lon * c / sqrt(1. - this->m_par.es * s * s); + xy_x = lp_lon * c / sqrt(1. - par.es * s * s); } // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); T s; - if ((s = fabs(lp_lat = pj_inv_mlfn(xy_y, this->m_par.es, this->m_proj_parm.en))) < half_pi) { + if ((s = fabs(lp_lat = pj_inv_mlfn(xy_y, par.es, this->m_proj_parm.en))) < half_pi) { s = sin(lp_lat); - lp_lon = xy_x * sqrt(1. - this->m_par.es * s * s) / cos(lp_lat); + lp_lon = xy_x * sqrt(1. - par.es * s * s) / cos(lp_lat); } else if ((s - epsilon10) < half_pi) lp_lon = 0.; else @@ -118,20 +112,14 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_gn_sinu_spheroid - : public base_t_fi, T, Parameters> { par_gn_sinu m_proj_parm; - inline base_gn_sinu_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { if (this->m_proj_parm.m == 0.0) lp_lat = this->m_proj_parm.n != 1. ? aasin(this->m_proj_parm.n * sin(lp_lat)): lp_lat; @@ -156,7 +144,7 @@ namespace projections // INVERSE(s_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const { xy_y /= this->m_proj_parm.C_y; lp_lat = (this->m_proj_parm.m != 0.0) ? aasin((this->m_proj_parm.m * xy_y + sin(xy_y)) / this->m_proj_parm.n) : @@ -249,10 +237,9 @@ namespace projections struct gn_sinu_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid { template - inline gn_sinu_spheroid(Params const& params, Parameters const& par) - : detail::gn_sinu::base_gn_sinu_spheroid(par) + inline gn_sinu_spheroid(Params const& params, Parameters & par) { - detail::gn_sinu::setup_gn_sinu(params, this->m_par, this->m_proj_parm); + detail::gn_sinu::setup_gn_sinu(params, par, this->m_proj_parm); } }; @@ -273,10 +260,9 @@ namespace projections struct sinu_ellipsoid : public detail::gn_sinu::base_gn_sinu_ellipsoid { template - inline sinu_ellipsoid(Params const& , Parameters const& par) - : detail::gn_sinu::base_gn_sinu_ellipsoid(par) + inline sinu_ellipsoid(Params const& , Parameters & par) { - detail::gn_sinu::setup_sinu(this->m_par, this->m_proj_parm); + detail::gn_sinu::setup_sinu(par, this->m_proj_parm); } }; @@ -297,10 +283,9 @@ namespace projections struct sinu_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid { template - inline sinu_spheroid(Params const& , Parameters const& par) - : detail::gn_sinu::base_gn_sinu_spheroid(par) + inline sinu_spheroid(Params const& , Parameters & par) { - detail::gn_sinu::setup_sinu(this->m_par, this->m_proj_parm); + detail::gn_sinu::setup_sinu(par, this->m_proj_parm); } }; @@ -320,10 +305,9 @@ namespace projections struct eck6_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid { template - inline eck6_spheroid(Params const& , Parameters const& par) - : detail::gn_sinu::base_gn_sinu_spheroid(par) + inline eck6_spheroid(Params const& , Parameters & par) { - detail::gn_sinu::setup_eck6(this->m_par, this->m_proj_parm); + detail::gn_sinu::setup_eck6(par, this->m_proj_parm); } }; @@ -343,10 +327,9 @@ namespace projections struct mbtfps_spheroid : public detail::gn_sinu::base_gn_sinu_spheroid { template - inline mbtfps_spheroid(Params const& , Parameters const& par) - : detail::gn_sinu::base_gn_sinu_spheroid(par) + inline mbtfps_spheroid(Params const& , Parameters & par) { - detail::gn_sinu::setup_mbtfps(this->m_par, this->m_proj_parm); + detail::gn_sinu::setup_mbtfps(par, this->m_proj_parm); } }; @@ -355,10 +338,10 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_gn_sinu, gn_sinu_spheroid, gn_sinu_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_sinu, sinu_spheroid, sinu_ellipsoid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_eck6, eck6_spheroid, eck6_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_mbtfps, mbtfps_spheroid, mbtfps_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_gn_sinu, gn_sinu_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_sinu, sinu_spheroid, sinu_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_eck6, eck6_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_mbtfps, mbtfps_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(gn_sinu_entry, gn_sinu_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/gnom.hpp b/include/boost/geometry/srs/projections/proj/gnom.hpp index 6c9ca3a02..bde8e1906 100644 --- a/include/boost/geometry/srs/projections/proj/gnom.hpp +++ b/include/boost/geometry/srs/projections/proj/gnom.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -74,20 +74,14 @@ namespace projections mode_type mode; }; - // template class, using CRTP to implement forward/inverse template struct base_gnom_spheroid - : public base_t_fi, T, Parameters> { par_gnom m_proj_parm; - inline base_gnom_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T coslam, cosphi, sinphi; @@ -133,7 +127,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); @@ -144,7 +138,7 @@ namespace projections cosz = sqrt(1. - sinz * sinz); if (fabs(rh) <= epsilon10) { - lp_lat = this->m_par.phi0; + lp_lat = par.phi0; lp_lon = 0.; } else { switch (this->m_proj_parm.mode) { @@ -223,10 +217,9 @@ namespace projections struct gnom_spheroid : public detail::gnom::base_gnom_spheroid { template - inline gnom_spheroid(Params const& , Parameters const& par) - : detail::gnom::base_gnom_spheroid(par) + inline gnom_spheroid(Params const& , Parameters & par) { - detail::gnom::setup_gnom(this->m_par, this->m_proj_parm); + detail::gnom::setup_gnom(par, this->m_proj_parm); } }; @@ -235,7 +228,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_gnom, gnom_spheroid, gnom_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_gnom, gnom_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(gnom_entry, gnom_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/goode.hpp b/include/boost/geometry/srs/projections/proj/goode.hpp index b9cc03460..386fff1f7 100644 --- a/include/boost/geometry/srs/projections/proj/goode.hpp +++ b/include/boost/geometry/srs/projections/proj/goode.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -59,46 +59,53 @@ namespace projections static const double Y_COR = 0.05280; static const double PHI_LIM = .71093078197902358062; - // TODO: consider storing references to Parameters instead of copies template struct par_goode { sinu_spheroid sinu; moll_spheroid moll; + // NOTE: It is ok to share parameters between projections because + // the only member that is modified in the constructors of + // spherical sinu and moll projections is es = 0 which is set + // below in setup_goode() anyway. + // Moreover in these projections parameters are not used + // in fwd() nor inv(). + template - par_goode(Params const& params, Par const& par) - : sinu(params, par), moll(params, par) + par_goode(Params const& params, Par & par) + : sinu(params, par) + , moll(params, par) {} }; template inline void s_forward(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y, - par_goode const& proj_par) + Par const& par, par_goode const& proj_par) { if (fabs(lp_lat) <= PHI_LIM) - proj_par.sinu.fwd(lp_lon, lp_lat, xy_x, xy_y); + proj_par.sinu.fwd(par, lp_lon, lp_lat, xy_x, xy_y); else { - proj_par.moll.fwd(lp_lon, lp_lat, xy_x, xy_y); + proj_par.moll.fwd(par, lp_lon, lp_lat, xy_x, xy_y); xy_y -= lp_lat >= 0.0 ? Y_COR : -Y_COR; } } template inline void s_inverse(T const& xy_x, T xy_y, T& lp_lon, T& lp_lat, - par_goode const& proj_par) + Par const& par, par_goode const& proj_par) { if (fabs(xy_y) <= PHI_LIM) - proj_par.sinu.inv(xy_x, xy_y, lp_lon, lp_lat); + proj_par.sinu.inv(par, xy_x, xy_y, lp_lon, lp_lat); else { xy_y += xy_y >= 0.0 ? Y_COR : -Y_COR; - proj_par.moll.inv(xy_x, xy_y, lp_lon, lp_lat); + proj_par.moll.inv(par, xy_x, xy_y, lp_lon, lp_lat); } } // Goode Homolosine template - inline void setup_goode(Par& par) + inline Par& setup_goode(Par& par) { par.es = 0.; @@ -108,6 +115,8 @@ namespace projections //proj_par.sinu.m_par.es = 0.; //detail::gn_sinu::setup_sinu(proj_par.sinu.m_par, proj_par.sinu.m_proj_parm); + + return par; } }} // namespace detail::goode @@ -126,42 +135,33 @@ namespace projections \image html ex_goode.gif */ template - struct goode_spheroid : public detail::base_t_fi, T, Parameters> + struct goode_spheroid { detail::goode::par_goode m_proj_parm; template - inline goode_spheroid(Params const& params, Parameters const& par) - : detail::base_t_fi, T, Parameters>(*this, par) - , m_proj_parm(params, setup(this->m_par)) + inline goode_spheroid(Params const& params, Parameters & par) + : m_proj_parm(params, detail::goode::setup_goode(par)) {} // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { - detail::goode::s_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm); + detail::goode::s_forward(lp_lon, lp_lat, xy_x, xy_y, par, this->m_proj_parm); } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { - detail::goode::s_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm); + detail::goode::s_inverse(xy_x, xy_y, lp_lon, lp_lat, par, this->m_proj_parm); } static inline std::string get_name() { return "goode_spheroid"; } - - private: - static Parameters& setup(Parameters& par) - { - detail::goode::setup_goode(par); - return par; - } - }; #ifndef DOXYGEN_NO_DETAIL @@ -169,7 +169,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_goode, goode_spheroid, goode_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_goode, goode_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(goode_entry, goode_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/gstmerc.hpp b/include/boost/geometry/srs/projections/proj/gstmerc.hpp index b53cb9d73..a39db181a 100644 --- a/include/boost/geometry/srs/projections/proj/gstmerc.hpp +++ b/include/boost/geometry/srs/projections/proj/gstmerc.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -67,42 +67,36 @@ namespace projections T YS; }; - // template class, using CRTP to implement forward/inverse template struct base_gstmerc_spheroid - : public base_t_fi, T, Parameters> { par_gstmerc m_proj_parm; - inline base_gstmerc_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T L, Ls, sinLs1, Ls1; L= this->m_proj_parm.n1*lp_lon; - Ls= this->m_proj_parm.c+this->m_proj_parm.n1*log(pj_tsfn(-1.0*lp_lat,-1.0*sin(lp_lat),this->m_par.e)); + Ls= this->m_proj_parm.c+this->m_proj_parm.n1*log(pj_tsfn(-1.0*lp_lat,-1.0*sin(lp_lat), par.e)); sinLs1= sin(L)/cosh(Ls); Ls1= log(pj_tsfn(-1.0*asin(sinLs1),0.0,0.0)); - xy_x= (this->m_proj_parm.XS + this->m_proj_parm.n2*Ls1)*this->m_par.ra; - xy_y= (this->m_proj_parm.YS + this->m_proj_parm.n2*atan(sinh(Ls)/cos(L)))*this->m_par.ra; + xy_x= (this->m_proj_parm.XS + this->m_proj_parm.n2*Ls1) * par.ra; + xy_y= (this->m_proj_parm.YS + this->m_proj_parm.n2*atan(sinh(Ls)/cos(L))) * par.ra; } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { T L, LC, sinC; - L= atan(sinh((xy_x*this->m_par.a - this->m_proj_parm.XS)/this->m_proj_parm.n2)/cos((xy_y*this->m_par.a - this->m_proj_parm.YS)/this->m_proj_parm.n2)); - sinC= sin((xy_y*this->m_par.a - this->m_proj_parm.YS)/this->m_proj_parm.n2)/cosh((xy_x*this->m_par.a - this->m_proj_parm.XS)/this->m_proj_parm.n2); + L= atan(sinh((xy_x * par.a - this->m_proj_parm.XS)/this->m_proj_parm.n2)/cos((xy_y * par.a - this->m_proj_parm.YS)/this->m_proj_parm.n2)); + sinC= sin((xy_y * par.a - this->m_proj_parm.YS)/this->m_proj_parm.n2)/cosh((xy_x * par.a - this->m_proj_parm.XS)/this->m_proj_parm.n2); LC= log(pj_tsfn(-1.0*asin(sinC),0.0,0.0)); lp_lon= L/this->m_proj_parm.n1; - lp_lat= -1.0*pj_phi2(exp((LC-this->m_proj_parm.c)/this->m_proj_parm.n1),this->m_par.e); + lp_lat= -1.0*pj_phi2(exp((LC-this->m_proj_parm.c)/this->m_proj_parm.n1), par.e); } static inline std::string get_name() @@ -114,7 +108,7 @@ namespace projections // Gauss-Schreiber Transverse Mercator (aka Gauss-Laborde Reunion) template - inline void setup_gstmerc(Parameters& par, par_gstmerc& proj_parm) + inline void setup_gstmerc(Parameters const& par, par_gstmerc& proj_parm) { proj_parm.lamc= par.lam0; proj_parm.n1= sqrt(T(1)+par.es*math::pow(cos(par.phi0),4)/(T(1)-par.es)); @@ -151,9 +145,8 @@ namespace projections { template inline gstmerc_spheroid(Params const& , Parameters const& par) - : detail::gstmerc::base_gstmerc_spheroid(par) { - detail::gstmerc::setup_gstmerc(this->m_par, this->m_proj_parm); + detail::gstmerc::setup_gstmerc(par, this->m_proj_parm); } }; @@ -162,7 +155,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_gstmerc, gstmerc_spheroid, gstmerc_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_gstmerc, gstmerc_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(gstmerc_entry, gstmerc_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/hammer.hpp b/include/boost/geometry/srs/projections/proj/hammer.hpp index f9e1ae4e7..de2afa55e 100644 --- a/include/boost/geometry/srs/projections/proj/hammer.hpp +++ b/include/boost/geometry/srs/projections/proj/hammer.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -63,20 +63,14 @@ namespace projections T m, rm; }; - // template class, using CRTP to implement forward/inverse template struct base_hammer_spheroid - : public base_t_fi, T, Parameters> { par_hammer m_proj_parm; - inline base_hammer_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T cosphi, d; @@ -87,7 +81,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { T z; @@ -155,10 +149,9 @@ namespace projections struct hammer_spheroid : public detail::hammer::base_hammer_spheroid { template - inline hammer_spheroid(Params const& params, Parameters const& par) - : detail::hammer::base_hammer_spheroid(par) + inline hammer_spheroid(Params const& params, Parameters & par) { - detail::hammer::setup_hammer(params, this->m_par, this->m_proj_parm); + detail::hammer::setup_hammer(params, par, this->m_proj_parm); } }; @@ -167,7 +160,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_hammer, hammer_spheroid, hammer_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_hammer, hammer_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(hammer_entry, hammer_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/hatano.hpp b/include/boost/geometry/srs/projections/proj/hatano.hpp index f3ae7d07d..4d444f87e 100644 --- a/include/boost/geometry/srs/projections/proj/hatano.hpp +++ b/include/boost/geometry/srs/projections/proj/hatano.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -70,18 +70,12 @@ namespace projections static const double FXC = 0.85; static const double RXC = 1.17647058823529411764; - // template class, using CRTP to implement forward/inverse template struct base_hatano_spheroid - : public base_t_fi, T, Parameters> { - inline base_hatano_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { T th1, c; int i; @@ -97,7 +91,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static T const half_pi = detail::half_pi(); @@ -161,10 +155,9 @@ namespace projections struct hatano_spheroid : public detail::hatano::base_hatano_spheroid { template - inline hatano_spheroid(Params const& , Parameters const& par) - : detail::hatano::base_hatano_spheroid(par) + inline hatano_spheroid(Params const& , Parameters & par) { - detail::hatano::setup_hatano(this->m_par); + detail::hatano::setup_hatano(par); } }; @@ -173,7 +166,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_hatano, hatano_spheroid, hatano_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_hatano, hatano_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(hatano_entry, hatano_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/healpix.hpp b/include/boost/geometry/srs/projections/proj/healpix.hpp index 2084ae82f..bb5bb6e69 100644 --- a/include/boost/geometry/srs/projections/proj/healpix.hpp +++ b/include/boost/geometry/srs/projections/proj/healpix.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -546,28 +546,22 @@ namespace projections xy_y = vector[1]; } - // template class, using CRTP to implement forward/inverse template struct base_healpix_ellipsoid - : public base_t_fi, T, Parameters> { par_healpix m_proj_parm; - inline base_healpix_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_healpix_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { - lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 0); + lp_lat = auth_lat(par, m_proj_parm, lp_lat, 0); return healpix_sphere(lp_lon, lp_lat, xy_x, xy_y); } // INVERSE(e_healpix_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { /* Check whether (x, y) lies in the HEALPix image. */ if (in_image(xy_x, xy_y, 0, 0, 0) == 0) { @@ -576,7 +570,7 @@ namespace projections BOOST_THROW_EXCEPTION( projection_exception(error_invalid_x_or_y) ); } healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat); - lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 1); + lp_lat = auth_lat(par, m_proj_parm, lp_lat, 1); } static inline std::string get_name() @@ -586,27 +580,21 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_healpix_spheroid - : public base_t_fi, T, Parameters> { par_healpix m_proj_parm; - inline base_healpix_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_healpix_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { return healpix_sphere(lp_lon, lp_lat, xy_x, xy_y); } // INVERSE(s_healpix_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { /* Check whether (x, y) lies in the HEALPix image */ if (in_image(xy_x, xy_y, 0, 0, 0) == 0) { @@ -624,29 +612,23 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_rhealpix_ellipsoid - : public base_t_fi, T, Parameters> { par_healpix m_proj_parm; - inline base_rhealpix_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_rhealpix_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { - lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 0); + lp_lat = auth_lat(par, m_proj_parm, lp_lat, 0); healpix_sphere(lp_lon, lp_lat, xy_x, xy_y); combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 0); } // INVERSE(e_rhealpix_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { /* Check whether (x, y) lies in the rHEALPix image. */ if (in_image(xy_x, xy_y, 1, this->m_proj_parm.north_square, this->m_proj_parm.south_square) == 0) { @@ -656,7 +638,7 @@ namespace projections } combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 1); healpix_sphere_inverse(xy_x, xy_y, lp_lon, lp_lat); - lp_lat = auth_lat(this->params(), m_proj_parm, lp_lat, 1); + lp_lat = auth_lat(par, m_proj_parm, lp_lat, 1); } static inline std::string get_name() @@ -666,20 +648,14 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_rhealpix_spheroid - : public base_t_fi, T, Parameters> { par_healpix m_proj_parm; - inline base_rhealpix_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_rhealpix_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { healpix_sphere(lp_lon, lp_lat, xy_x, xy_y); combine_caps(xy_x, xy_y, this->m_proj_parm.north_square, this->m_proj_parm.south_square, 0); @@ -687,7 +663,7 @@ namespace projections // INVERSE(s_rhealpix_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { /* Check whether (x, y) lies in the rHEALPix image. */ if (in_image(xy_x, xy_y, 1, this->m_proj_parm.north_square, this->m_proj_parm.south_square) == 0) { @@ -762,10 +738,9 @@ namespace projections struct healpix_ellipsoid : public detail::healpix::base_healpix_ellipsoid { template - inline healpix_ellipsoid(Params const& , Parameters const& par) - : detail::healpix::base_healpix_ellipsoid(par) + inline healpix_ellipsoid(Params const& , Parameters & par) { - detail::healpix::setup_healpix(this->m_par, this->m_proj_parm); + detail::healpix::setup_healpix(par, this->m_proj_parm); } }; @@ -785,10 +760,9 @@ namespace projections struct healpix_spheroid : public detail::healpix::base_healpix_spheroid { template - inline healpix_spheroid(Params const& , Parameters const& par) - : detail::healpix::base_healpix_spheroid(par) + inline healpix_spheroid(Params const& , Parameters & par) { - detail::healpix::setup_healpix(this->m_par, this->m_proj_parm); + detail::healpix::setup_healpix(par, this->m_proj_parm); } }; @@ -811,10 +785,9 @@ namespace projections struct rhealpix_ellipsoid : public detail::healpix::base_rhealpix_ellipsoid { template - inline rhealpix_ellipsoid(Params const& params, Parameters const& par) - : detail::healpix::base_rhealpix_ellipsoid(par) + inline rhealpix_ellipsoid(Params const& params, Parameters & par) { - detail::healpix::setup_rhealpix(params, this->m_par, this->m_proj_parm); + detail::healpix::setup_rhealpix(params, par, this->m_proj_parm); } }; @@ -837,10 +810,9 @@ namespace projections struct rhealpix_spheroid : public detail::healpix::base_rhealpix_spheroid { template - inline rhealpix_spheroid(Params const& params, Parameters const& par) - : detail::healpix::base_rhealpix_spheroid(par) + inline rhealpix_spheroid(Params const& params, Parameters & par) { - detail::healpix::setup_rhealpix(params, this->m_par, this->m_proj_parm); + detail::healpix::setup_rhealpix(params, par, this->m_proj_parm); } }; @@ -849,8 +821,8 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_healpix, healpix_spheroid, healpix_ellipsoid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_rhealpix, rhealpix_spheroid, rhealpix_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_healpix, healpix_spheroid, healpix_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_rhealpix, rhealpix_spheroid, rhealpix_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(healpix_entry, healpix_spheroid, healpix_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/igh.hpp b/include/boost/geometry/srs/projections/proj/igh.hpp index 6403d7412..fc2f3f305 100644 --- a/include/boost/geometry/srs/projections/proj/igh.hpp +++ b/include/boost/geometry/srs/projections/proj/igh.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -59,11 +59,14 @@ namespace projections namespace detail { namespace igh { // TODO: consider replacing dynamically created projections - // with member objects + // with member objects + // NOTE: dynamic_wrapper_b holds copy of Parameters + // TODO: use only one copy of Parameters + // it is doable if zone-specific x0, y0 and lam0 are stored in par_igh template struct par_igh { - boost::shared_ptr > pj[12]; + boost::shared_ptr > pj[12]; T dy0; }; @@ -114,21 +117,17 @@ namespace projections proj_parm.pj[n-1]->mutable_params().lam0 = lon_0; } - // template class, using CRTP to implement forward/inverse template struct base_igh_spheroid - : public base_t_fi, T, Parameters> { par_igh m_proj_parm; - inline base_igh_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { + // Parameters ignored because m_proj_parm holds their own copies + static const T d4044118 = igh::d4044118(); static const T d20 = igh::d20(); static const T d40 = igh::d40(); @@ -156,15 +155,17 @@ namespace projections } lp_lon -= this->m_proj_parm.pj[z-1]->params().lam0; - this->m_proj_parm.pj[z-1]->fwd(lp_lon, lp_lat, xy_x, xy_y); + this->m_proj_parm.pj[z-1]->fwd(this->m_proj_parm.pj[z-1]->params(), lp_lon, lp_lat, xy_x, xy_y); xy_x += this->m_proj_parm.pj[z-1]->params().x0; xy_y += this->m_proj_parm.pj[z-1]->params().y0; } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { + // Parameters ignored because m_proj_parm holds their own copies + static const T d4044118 = igh::d4044118(); static const T d10 = igh::d10(); static const T d20 = igh::d20(); @@ -207,7 +208,7 @@ namespace projections xy_x -= this->m_proj_parm.pj[z-1]->params().x0; xy_y -= this->m_proj_parm.pj[z-1]->params().y0; - this->m_proj_parm.pj[z-1]->inv(xy_x, xy_y, lp_lon, lp_lat); + this->m_proj_parm.pj[z-1]->inv(this->m_proj_parm.pj[z-1]->params(), xy_x, xy_y, lp_lon, lp_lat); lp_lon += this->m_proj_parm.pj[z-1]->params().lam0; switch (z) { @@ -301,8 +302,8 @@ namespace projections do_setup(1, params, par, proj_parm, -d100, d0, -d100); // y0 ? - proj_parm.pj[0]->fwd(lp_lam, lp_phi, xy1_x, xy1_y); // zone 1 - proj_parm.pj[2]->fwd(lp_lam, lp_phi, xy3_x, xy3_y); // zone 3 + proj_parm.pj[0]->fwd(proj_parm.pj[0]->params(), lp_lam, lp_phi, xy1_x, xy1_y); // zone 1 + proj_parm.pj[2]->fwd(proj_parm.pj[2]->params(), lp_lam, lp_phi, xy3_x, xy3_y); // zone 3 // y0 + xy1_y = xy3_y for lt = 40d44'11.8" proj_parm.dy0 = xy3_y - xy1_y; @@ -338,10 +339,9 @@ namespace projections struct igh_spheroid : public detail::igh::base_igh_spheroid { template - inline igh_spheroid(Params const& params, Parameters const& par) - : detail::igh::base_igh_spheroid(par) + inline igh_spheroid(Params const& params, Parameters & par) { - detail::igh::setup_igh(params, this->m_par, this->m_proj_parm); + detail::igh::setup_igh(params, par, this->m_proj_parm); } }; @@ -350,7 +350,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_igh, igh_spheroid, igh_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_igh, igh_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(igh_entry, igh_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/imw_p.hpp b/include/boost/geometry/srs/projections/proj/imw_p.hpp index d86c3c8f7..2e018646d 100644 --- a/include/boost/geometry/srs/projections/proj/imw_p.hpp +++ b/include/boost/geometry/srs/projections/proj/imw_p.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -162,29 +162,23 @@ namespace projections *x = *R * sin(F); } - // template class, using CRTP to implement forward/inverse template struct base_imw_p_ellipsoid - : public base_t_fi, T, Parameters> { par_imw_p m_proj_parm; - inline base_imw_p_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T yc = 0; - point_xy xy = loc_for(lp_lon, lp_lat, this->m_par, m_proj_parm, &yc); + point_xy xy = loc_for(lp_lon, lp_lat, par, m_proj_parm, &yc); xy_x = xy.x; xy_y = xy.y; } // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { point_xy t; T yc = 0.0; @@ -194,7 +188,7 @@ namespace projections lp_lat = this->m_proj_parm.phi_2; lp_lon = xy_x / cos(lp_lat); do { - t = loc_for(lp_lon, lp_lat, this->m_par, m_proj_parm, &yc); + t = loc_for(lp_lon, lp_lat, par, m_proj_parm, &yc); lp_lat = ((lp_lat - this->m_proj_parm.phi_1) * (xy_y - yc) / (t.y - yc)) + this->m_proj_parm.phi_1; lp_lon = lp_lon * xy_x / t.x; i++; @@ -290,9 +284,8 @@ namespace projections { template inline imw_p_ellipsoid(Params const& params, Parameters const& par) - : detail::imw_p::base_imw_p_ellipsoid(par) { - detail::imw_p::setup_imw_p(params, this->m_par, this->m_proj_parm); + detail::imw_p::setup_imw_p(params, par, this->m_proj_parm); } }; @@ -301,7 +294,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_imw_p, imw_p_ellipsoid, imw_p_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_imw_p, imw_p_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(imw_p_entry, imw_p_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/isea.hpp b/include/boost/geometry/srs/projections/proj/isea.hpp index d8a48041d..b04f65e4f 100644 --- a/include/boost/geometry/srs/projections/proj/isea.hpp +++ b/include/boost/geometry/srs/projections/proj/isea.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -1114,20 +1114,14 @@ namespace projections isea_dgg dgg; }; - // template class, using CRTP to implement forward/inverse template struct base_isea_spheroid - : public base_t_f, T, Parameters> { par_isea m_proj_parm; - inline base_isea_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { isea_pt out; isea_geo in; @@ -1294,8 +1288,7 @@ namespace projections struct isea_spheroid : public detail::isea::base_isea_spheroid { template - inline isea_spheroid(Params const& params, Parameters const& par) - : detail::isea::base_isea_spheroid(par) + inline isea_spheroid(Params const& params, Parameters const& ) { detail::isea::setup_isea(params, this->m_proj_parm); } @@ -1306,7 +1299,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_isea, isea_spheroid, isea_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_isea, isea_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(isea_entry, isea_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/krovak.hpp b/include/boost/geometry/srs/projections/proj/krovak.hpp index 75771b49e..d1761f637 100644 --- a/include/boost/geometry/srs/projections/proj/krovak.hpp +++ b/include/boost/geometry/srs/projections/proj/krovak.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -101,24 +101,18 @@ namespace projections **/ - // template class, using CRTP to implement forward/inverse template struct base_krovak_ellipsoid - : public base_t_fi, T, Parameters> { par_krovak m_proj_parm; - inline base_krovak_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T gfi, u, deltav, s, d, eps, rho; - gfi = math::pow( (T(1) + this->m_par.e * sin(lp_lat)) / (T(1) - this->m_par.e * sin(lp_lat)), this->m_proj_parm.alpha * this->m_par.e / T(2)); + gfi = math::pow( (T(1) + par.e * sin(lp_lat)) / (T(1) - par.e * sin(lp_lat)), this->m_proj_parm.alpha * par.e / T(2)); u = 2. * (atan(this->m_proj_parm.k * math::pow( tan(lp_lat / T(2) + S45), this->m_proj_parm.alpha) / gfi)-S45); deltav = -lp_lon * this->m_proj_parm.alpha; @@ -138,7 +132,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { T u, deltav, s, d, eps, rho, fi1, xy0; int i; @@ -160,7 +154,7 @@ namespace projections u = asin(cos(this->m_proj_parm.ad) * sin(s) - sin(this->m_proj_parm.ad) * cos(s) * cos(d)); deltav = asin(cos(s) * sin(d) / cos(u)); - lp_lon = this->m_par.lam0 - deltav / this->m_proj_parm.alpha; + lp_lon = par.lam0 - deltav / this->m_proj_parm.alpha; /* ITERATION FOR lp_lat */ fi1 = u; @@ -168,7 +162,7 @@ namespace projections for (i = max_iter; i ; --i) { lp_lat = T(2) * ( atan( math::pow( this->m_proj_parm.k, T(-1) / this->m_proj_parm.alpha) * math::pow( tan(u / T(2) + S45) , T(1) / this->m_proj_parm.alpha) * - math::pow( (T(1) + this->m_par.e * sin(fi1)) / (T(1) - this->m_par.e * sin(fi1)) , this->m_par.e / T(2)) + math::pow( (T(1) + par.e * sin(fi1)) / (T(1) - par.e * sin(fi1)) , par.e / T(2)) ) - S45); if (fabs(fi1 - lp_lat) < epsilon) @@ -178,7 +172,7 @@ namespace projections if( i == 0 ) BOOST_THROW_EXCEPTION( projection_exception(error_non_convergent) ); - lp_lon -= this->m_par.lam0; + lp_lon -= par.lam0; } static inline std::string get_name() @@ -252,10 +246,9 @@ namespace projections struct krovak_ellipsoid : public detail::krovak::base_krovak_ellipsoid { template - inline krovak_ellipsoid(Params const& params, Parameters const& par) - : detail::krovak::base_krovak_ellipsoid(par) + inline krovak_ellipsoid(Params const& params, Parameters & par) { - detail::krovak::setup_krovak(params, this->m_par, this->m_proj_parm); + detail::krovak::setup_krovak(params, par, this->m_proj_parm); } }; @@ -264,7 +257,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_krovak, krovak_ellipsoid, krovak_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_krovak, krovak_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(krovak_entry, krovak_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/labrd.hpp b/include/boost/geometry/srs/projections/proj/labrd.hpp index 1b86fe74e..b6626b932 100644 --- a/include/boost/geometry/srs/projections/proj/labrd.hpp +++ b/include/boost/geometry/srs/projections/proj/labrd.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -63,20 +63,14 @@ namespace projections int rot; }; - // template class, using CRTP to implement forward/inverse template struct base_labrd_ellipsoid - : public base_t_fi, T, Parameters> { par_labrd m_proj_parm; - inline base_labrd_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T fourth_pi = detail::fourth_pi(); @@ -84,8 +78,8 @@ namespace projections T I1, I2, I3, I4, I5, I6, x2, y2, t; V1 = this->m_proj_parm.A * log( tan(fourth_pi + .5 * lp_lat) ); - t = this->m_par.e * sin(lp_lat); - V2 = .5 * this->m_par.e * this->m_proj_parm.A * log ((1. + t)/(1. - t)); + t = par.e * sin(lp_lat); + V2 = .5 * par.e * this->m_proj_parm.A * log ((1. + t)/(1. - t)); ps = 2. * (atan(exp(V1 - V2 + this->m_proj_parm.C)) - fourth_pi); I1 = ps - this->m_proj_parm.p0s; cosps = cos(ps); cosps2 = cosps * cosps; @@ -110,7 +104,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid & spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { static const T fourth_pi = detail::fourth_pi(); @@ -130,25 +124,25 @@ namespace projections xy_x += - this->m_proj_parm.Ca * V1 - this->m_proj_parm.Cb * V2 + this->m_proj_parm.Cc * V3 + this->m_proj_parm.Cd * V4; xy_y += this->m_proj_parm.Cb * V1 - this->m_proj_parm.Ca * V2 - this->m_proj_parm.Cd * V3 + this->m_proj_parm.Cc * V4; ps = this->m_proj_parm.p0s + xy_y / this->m_proj_parm.kRg; - pe = ps + this->m_par.phi0 - this->m_proj_parm.p0s; + pe = ps + par.phi0 - this->m_proj_parm.p0s; for ( i = 20; i; --i) { V1 = this->m_proj_parm.A * log(tan(fourth_pi + .5 * pe)); - tpe = this->m_par.e * sin(pe); - V2 = .5 * this->m_par.e * this->m_proj_parm.A * log((1. + tpe)/(1. - tpe)); + tpe = par.e * sin(pe); + V2 = .5 * par.e * this->m_proj_parm.A * log((1. + tpe)/(1. - tpe)); t = ps - 2. * (atan(exp(V1 - V2 + this->m_proj_parm.C)) - fourth_pi); pe += t; if (fabs(t) < epsilon) break; } - t = this->m_par.e * sin(pe); + t = par.e * sin(pe); t = 1. - t * t; - Re = this->m_par.one_es / ( t * sqrt(t) ); + Re = par.one_es / ( t * sqrt(t) ); t = tan(ps); t2 = t * t; s = this->m_proj_parm.kRg * this->m_proj_parm.kRg; - d = Re * this->m_par.k0 * this->m_proj_parm.kRg; + d = Re * par.k0 * this->m_proj_parm.kRg; I7 = t / (2. * d); I8 = t * (5. + 3. * t2) / (24. * d * s); d = cos(ps) * this->m_proj_parm.kRg * this->m_proj_parm.A; @@ -170,7 +164,7 @@ namespace projections // Laborde template - inline void setup_labrd(Params const& params, Parameters& par, par_labrd& proj_parm) + inline void setup_labrd(Params const& params, Parameters const& par, par_labrd& proj_parm) { static const T fourth_pi = detail::fourth_pi(); @@ -220,9 +214,8 @@ namespace projections { template inline labrd_ellipsoid(Params const& params, Parameters const& par) - : detail::labrd::base_labrd_ellipsoid(par) { - detail::labrd::setup_labrd(params, this->m_par, this->m_proj_parm); + detail::labrd::setup_labrd(params, par, this->m_proj_parm); } }; @@ -231,7 +224,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_labrd, labrd_ellipsoid, labrd_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_labrd, labrd_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(labrd_entry, labrd_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/laea.hpp b/include/boost/geometry/srs/projections/proj/laea.hpp index 9c4560a94..c6775ed3e 100644 --- a/include/boost/geometry/srs/projections/proj/laea.hpp +++ b/include/boost/geometry/srs/projections/proj/laea.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -83,20 +83,14 @@ namespace projections mode_type mode; }; - // template class, using CRTP to implement forward/inverse template struct base_laea_ellipsoid - : public base_t_fi, T, Parameters> { par_laea m_proj_parm; - inline base_laea_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); @@ -105,7 +99,7 @@ namespace projections coslam = cos(lp_lon); sinlam = sin(lp_lon); sinphi = sin(lp_lat); - q = pj_qsfn(sinphi, this->m_par.e, this->m_par.one_es); + q = pj_qsfn(sinphi, par.e, par.one_es); if (this->m_proj_parm.mode == obliq || this->m_proj_parm.mode == equit) { sinb = q / this->m_proj_parm.qp; @@ -158,7 +152,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { T cCe, sCe, q, rho, ab=0.0; @@ -170,7 +164,7 @@ namespace projections rho = boost::math::hypot(xy_x, xy_y); if (rho < epsilon10) { lp_lon = 0.; - lp_lat = this->m_par.phi0; + lp_lat = par.phi0; return; } sCe = 2. * asin(.5 * rho / this->m_proj_parm.rq); @@ -192,7 +186,7 @@ namespace projections q = (xy_x * xy_x + xy_y * xy_y); if (q == 0.0) { lp_lon = 0.; - lp_lat = this->m_par.phi0; + lp_lat = par.phi0; return; } ab = 1. - q / this->m_proj_parm.qp; @@ -211,20 +205,14 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_laea_spheroid - : public base_t_fi, T, Parameters> { par_laea m_proj_parm; - inline base_laea_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T fourth_pi = detail::fourth_pi(); @@ -252,7 +240,7 @@ namespace projections coslam = -coslam; BOOST_FALLTHROUGH; case s_pole: - if (fabs(lp_lat + this->m_par.phi0) < epsilon10) { + if (fabs(lp_lat + par.phi0) < epsilon10) { BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } xy_y = fourth_pi - lp_lat * .5; @@ -265,7 +253,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); @@ -287,7 +275,7 @@ namespace projections xy_y = cosz * rh; break; case obliq: - lp_lat = fabs(rh) <= epsilon10 ? this->m_par.phi0 : + lp_lat = fabs(rh) <= epsilon10 ? par.phi0 : asin(cosz * this->m_proj_parm.sinb1 + xy_y * sinz * this->m_proj_parm.cosb1 / rh); xy_x *= sinz * this->m_proj_parm.cosb1; xy_y = (cosz - sin(lp_lat) * this->m_proj_parm.sinb1) * rh; @@ -329,7 +317,7 @@ namespace projections if (par.es != 0.0) { double sinphi; - par.e = sqrt(par.es); + par.e = sqrt(par.es); // TODO : Isn't it already set? proj_parm.qp = pj_qsfn(1., par.e, par.one_es); proj_parm.mmf = .5 / (1. - par.es); proj_parm.apa = pj_authset(par.es); @@ -382,10 +370,9 @@ namespace projections struct laea_ellipsoid : public detail::laea::base_laea_ellipsoid { template - inline laea_ellipsoid(Params const& , Parameters const& par) - : detail::laea::base_laea_ellipsoid(par) + inline laea_ellipsoid(Params const& , Parameters & par) { - detail::laea::setup_laea(this->m_par, this->m_proj_parm); + detail::laea::setup_laea(par, this->m_proj_parm); } }; @@ -406,10 +393,9 @@ namespace projections struct laea_spheroid : public detail::laea::base_laea_spheroid { template - inline laea_spheroid(Params const& , Parameters const& par) - : detail::laea::base_laea_spheroid(par) + inline laea_spheroid(Params const& , Parameters & par) { - detail::laea::setup_laea(this->m_par, this->m_proj_parm); + detail::laea::setup_laea(par, this->m_proj_parm); } }; @@ -418,7 +404,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_laea, laea_spheroid, laea_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_laea, laea_spheroid, laea_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(laea_entry, laea_spheroid, laea_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/lagrng.hpp b/include/boost/geometry/srs/projections/proj/lagrng.hpp index 6df445962..439b57471 100644 --- a/include/boost/geometry/srs/projections/proj/lagrng.hpp +++ b/include/boost/geometry/srs/projections/proj/lagrng.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -67,20 +67,14 @@ namespace projections T hrw; }; - // template class, using CRTP to implement forward/inverse template struct base_lagrng_spheroid - : public base_t_f, T, Parameters> { par_lagrng m_proj_parm; - inline base_lagrng_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T lp_lon, T lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); @@ -161,10 +155,9 @@ namespace projections struct lagrng_spheroid : public detail::lagrng::base_lagrng_spheroid { template - inline lagrng_spheroid(Params const& params, Parameters const& par) - : detail::lagrng::base_lagrng_spheroid(par) + inline lagrng_spheroid(Params const& params, Parameters & par) { - detail::lagrng::setup_lagrng(params, this->m_par, this->m_proj_parm); + detail::lagrng::setup_lagrng(params, par, this->m_proj_parm); } }; @@ -173,7 +166,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_lagrng, lagrng_spheroid, lagrng_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_lagrng, lagrng_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(lagrng_entry, lagrng_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/larr.hpp b/include/boost/geometry/srs/projections/proj/larr.hpp index 82025019b..a584aa337 100644 --- a/include/boost/geometry/srs/projections/proj/larr.hpp +++ b/include/boost/geometry/srs/projections/proj/larr.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -54,18 +54,12 @@ namespace projections namespace detail { namespace larr { - // template class, using CRTP to implement forward/inverse template struct base_larr_spheroid - : public base_t_f, T, Parameters> { - inline base_larr_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T sixth = detail::sixth(); @@ -107,10 +101,9 @@ namespace projections struct larr_spheroid : public detail::larr::base_larr_spheroid { template - inline larr_spheroid(Params const& , Parameters const& par) - : detail::larr::base_larr_spheroid(par) + inline larr_spheroid(Params const& , Parameters & par) { - detail::larr::setup_larr(this->m_par); + detail::larr::setup_larr(par); } }; @@ -119,7 +112,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_larr, larr_spheroid, larr_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_larr, larr_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(larr_entry, larr_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/lask.hpp b/include/boost/geometry/srs/projections/proj/lask.hpp index ef9c5e38b..158402de0 100644 --- a/include/boost/geometry/srs/projections/proj/lask.hpp +++ b/include/boost/geometry/srs/projections/proj/lask.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -65,18 +65,12 @@ namespace projections static const double b23 = -0.0285500; static const double b05 = -0.0491032; - // template class, using CRTP to implement forward/inverse template struct base_lask_spheroid - : public base_t_f, T, Parameters> { - inline base_lask_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T l2, p2; @@ -121,10 +115,9 @@ namespace projections struct lask_spheroid : public detail::lask::base_lask_spheroid { template - inline lask_spheroid(Params const& , Parameters const& par) - : detail::lask::base_lask_spheroid(par) + inline lask_spheroid(Params const& , Parameters & par) { - detail::lask::setup_lask(this->m_par); + detail::lask::setup_lask(par); } }; @@ -133,7 +126,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_lask, lask_spheroid, lask_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_lask, lask_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(lask_entry, lask_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/latlong.hpp b/include/boost/geometry/srs/projections/proj/latlong.hpp index a6e8dcdfd..111075ef2 100644 --- a/include/boost/geometry/srs/projections/proj/latlong.hpp +++ b/include/boost/geometry/srs/projections/proj/latlong.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -63,33 +63,27 @@ namespace projections /* very loosely based upon DMA code by Bradford W. Drew */ - // template class, using CRTP to implement forward/inverse template struct base_latlong_other - : public base_t_fi, T, Parameters> { - inline base_latlong_other(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(forward) // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { // TODO: in the original code a is not used // different mechanism is probably used instead - xy_x = lp_lon / this->m_par.a; - xy_y = lp_lat / this->m_par.a; + xy_x = lp_lon / par.a; + xy_y = lp_lat / par.a; } // INVERSE(inverse) // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { // TODO: in the original code a is not used // different mechanism is probably used instead - lp_lat = xy_y * this->m_par.a; - lp_lon = xy_x * this->m_par.a; + lp_lat = xy_y * par.a; + lp_lon = xy_x * par.a; } static inline std::string get_name() @@ -124,10 +118,9 @@ namespace projections struct latlong_other : public detail::latlong::base_latlong_other { template - inline latlong_other(Params const& , Parameters const& par) - : detail::latlong::base_latlong_other(par) + inline latlong_other(Params const& , Parameters & par) { - detail::latlong::setup_latlong(this->m_par); + detail::latlong::setup_latlong(par); } }; @@ -136,10 +129,10 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_lonlat, latlong_other, latlong_other) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_latlon, latlong_other, latlong_other) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_latlong, latlong_other, latlong_other) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_longlat, latlong_other, latlong_other) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_lonlat, latlong_other) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_latlon, latlong_other) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_latlong, latlong_other) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_longlat, latlong_other) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(latlong_entry, latlong_other) diff --git a/include/boost/geometry/srs/projections/proj/lcc.hpp b/include/boost/geometry/srs/projections/proj/lcc.hpp index ebd9c3bb6..bea2798ed 100644 --- a/include/boost/geometry/srs/projections/proj/lcc.hpp +++ b/include/boost/geometry/srs/projections/proj/lcc.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -74,20 +74,14 @@ namespace projections int ellips; }; - // template class, using CRTP to implement forward/inverse template struct base_lcc_ellipsoid - : public base_t_fi, T, Parameters> { par_lcc m_proj_parm; - inline base_lcc_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid & spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T fourth_pi = detail::fourth_pi(); static const T half_pi = detail::half_pi(); @@ -101,24 +95,24 @@ namespace projections rho = 0.; } else { rho = this->m_proj_parm.c * (this->m_proj_parm.ellips - ? math::pow(pj_tsfn(lp_lat, sin(lp_lat), this->m_par.e), this->m_proj_parm.n) + ? math::pow(pj_tsfn(lp_lat, sin(lp_lat), par.e), this->m_proj_parm.n) : math::pow(tan(fourth_pi + T(0.5) * lp_lat), -this->m_proj_parm.n)); } lp_lon *= this->m_proj_parm.n; - xy_x = this->m_par.k0 * (rho * sin( lp_lon) ); - xy_y = this->m_par.k0 * (this->m_proj_parm.rho0 - rho * cos(lp_lon) ); + xy_x = par.k0 * (rho * sin( lp_lon) ); + xy_y = par.k0 * (this->m_proj_parm.rho0 - rho * cos(lp_lon) ); } // INVERSE(e_inverse) ellipsoid & spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); T rho; - xy_x /= this->m_par.k0; - xy_y /= this->m_par.k0; + xy_x /= par.k0; + xy_y /= par.k0; xy_y = this->m_proj_parm.rho0 - xy_y; rho = boost::math::hypot(xy_x, xy_y); @@ -129,7 +123,7 @@ namespace projections xy_y = -xy_y; } if (this->m_proj_parm.ellips) { - lp_lat = pj_phi2(math::pow(rho / this->m_proj_parm.c, T(1)/this->m_proj_parm.n), this->m_par.e); + lp_lat = pj_phi2(math::pow(rho / this->m_proj_parm.c, T(1)/this->m_proj_parm.n), par.e); if (lp_lat == HUGE_VAL) { BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } @@ -193,7 +187,7 @@ namespace projections if( (proj_parm.ellips = (par.es != 0.)) ) { double ml1, m1; - par.e = sqrt(par.es); + par.e = sqrt(par.es); // TODO: Isn't it already set? m1 = pj_msfn(sinphi, cosphi, par.es); ml1 = pj_tsfn(proj_parm.phi1, sinphi, par.e); if (secant) { /* secant cone */ @@ -239,10 +233,9 @@ namespace projections struct lcc_ellipsoid : public detail::lcc::base_lcc_ellipsoid { template - inline lcc_ellipsoid(Params const& params, Parameters const& par) - : detail::lcc::base_lcc_ellipsoid(par) + inline lcc_ellipsoid(Params const& params, Parameters & par) { - detail::lcc::setup_lcc(params, this->m_par, this->m_proj_parm); + detail::lcc::setup_lcc(params, par, this->m_proj_parm); } }; @@ -251,7 +244,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_lcc, lcc_ellipsoid, lcc_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_lcc, lcc_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(lcc_entry, lcc_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/lcca.hpp b/include/boost/geometry/srs/projections/proj/lcca.hpp index 090b7f4c2..e36ece867 100644 --- a/include/boost/geometry/srs/projections/proj/lcca.hpp +++ b/include/boost/geometry/srs/projections/proj/lcca.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -125,39 +125,33 @@ namespace projections return(1. + 3.* S * S * C); } - // template class, using CRTP to implement forward/inverse template struct base_lcca_ellipsoid - : public base_t_fi, T, Parameters> { par_lcca m_proj_parm; - inline base_lcca_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T S, r, dr; S = pj_mlfn(lp_lat, sin(lp_lat), cos(lp_lat), this->m_proj_parm.en) - this->m_proj_parm.M0; dr = fS(S, this->m_proj_parm.C); r = this->m_proj_parm.r0 - dr; - xy_x = this->m_par.k0 * (r * sin( lp_lon *= this->m_proj_parm.l ) ); - xy_y = this->m_par.k0 * (this->m_proj_parm.r0 - r * cos(lp_lon) ); + xy_x = par.k0 * (r * sin( lp_lon *= this->m_proj_parm.l ) ); + xy_y = par.k0 * (this->m_proj_parm.r0 - r * cos(lp_lon) ); } // INVERSE(e_inverse) ellipsoid & spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { T theta, dr, S, dif; int i; - xy_x /= this->m_par.k0; - xy_y /= this->m_par.k0; + xy_x /= par.k0; + xy_y /= par.k0; theta = atan2(xy_x , this->m_proj_parm.r0 - xy_y); dr = xy_y - xy_x * tan(0.5 * theta); lp_lon = theta / this->m_proj_parm.l; @@ -169,7 +163,7 @@ namespace projections if (!i) { BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } - lp_lat = pj_inv_mlfn(S + this->m_proj_parm.M0, this->m_par.es, this->m_proj_parm.en); + lp_lat = pj_inv_mlfn(S + this->m_proj_parm.M0, par.es, this->m_proj_parm.en); } static inline std::string get_name() @@ -181,7 +175,7 @@ namespace projections // Lambert Conformal Conic Alternative template - inline void setup_lcca(Parameters& par, par_lcca& proj_parm) + inline void setup_lcca(Parameters const& par, par_lcca& proj_parm) { T s2p0, N0, R0, tan0; @@ -224,9 +218,8 @@ namespace projections { template inline lcca_ellipsoid(Params const& , Parameters const& par) - : detail::lcca::base_lcca_ellipsoid(par) { - detail::lcca::setup_lcca(this->m_par, this->m_proj_parm); + detail::lcca::setup_lcca(par, this->m_proj_parm); } }; @@ -235,7 +228,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_lcca, lcca_ellipsoid, lcca_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_lcca, lcca_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(lcca_entry, lcca_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/loxim.hpp b/include/boost/geometry/srs/projections/proj/loxim.hpp index 927cab157..d39bf8928 100644 --- a/include/boost/geometry/srs/projections/proj/loxim.hpp +++ b/include/boost/geometry/srs/projections/proj/loxim.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -66,20 +66,14 @@ namespace projections T tanphi1; }; - // template class, using CRTP to implement forward/inverse template struct base_loxim_spheroid - : public base_t_fi, T, Parameters> { par_loxim m_proj_parm; - inline base_loxim_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T fourth_pi = detail::fourth_pi(); static const T half_pi = detail::half_pi(); @@ -98,7 +92,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const&, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T fourth_pi = detail::fourth_pi(); static const T half_pi = detail::half_pi(); @@ -159,10 +153,9 @@ namespace projections struct loxim_spheroid : public detail::loxim::base_loxim_spheroid { template - inline loxim_spheroid(Params const& params, Parameters const& par) - : detail::loxim::base_loxim_spheroid(par) + inline loxim_spheroid(Params const& params, Parameters & par) { - detail::loxim::setup_loxim(params, this->m_par, this->m_proj_parm); + detail::loxim::setup_loxim(params, par, this->m_proj_parm); } }; @@ -171,7 +164,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_loxim, loxim_spheroid, loxim_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_loxim, loxim_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(loxim_entry, loxim_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/lsat.hpp b/include/boost/geometry/srs/projections/proj/lsat.hpp index 3a20d96cb..dd6b3ae62 100644 --- a/include/boost/geometry/srs/projections/proj/lsat.hpp +++ b/include/boost/geometry/srs/projections/proj/lsat.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -93,20 +93,14 @@ namespace projections proj_parm.c3 += fc * cos(lam * 3.); } - // template class, using CRTP to implement forward/inverse template struct base_lsat_ellipsoid - : public base_t_fi, T, Parameters> { par_lsat m_proj_parm; - inline base_lsat_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { static const T fourth_pi = detail::fourth_pi(); static const T half_pi = detail::half_pi(); @@ -143,7 +137,7 @@ namespace projections c = cos(lamt); if (fabs(c) < tolerance) lamt -= tolerance; - xlam = (this->m_par.one_es * tanphi * this->m_proj_parm.sa + sin(lamt) * this->m_proj_parm.ca) / c; + xlam = (par.one_es * tanphi * this->m_proj_parm.sa + sin(lamt) * this->m_proj_parm.ca) / c; lamdp = atan(xlam) + fac; if (fabs(fabs(sav) - fabs(lamdp)) < tolerance) break; @@ -158,8 +152,8 @@ namespace projections } if (l) { sp = sin(lp_lat); - phidp = aasin((this->m_par.one_es * this->m_proj_parm.ca * sp - this->m_proj_parm.sa * cos(lp_lat) * - sin(lamt)) / sqrt(1. - this->m_par.es * sp * sp)); + phidp = aasin((par.one_es * this->m_proj_parm.ca * sp - this->m_proj_parm.sa * cos(lp_lat) * + sin(lamt)) / sqrt(1. - par.es * sp * sp)); tanph = log(tan(fourth_pi + .5 * phidp)); sd = sin(lamdp); sdsq = sd * sd; @@ -175,7 +169,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T fourth_pi = detail::fourth_pi(); static const T half_pi = detail::half_pi(); @@ -205,7 +199,7 @@ namespace projections lamdp -= tolerance; spp = sin(phidp); sppsq = spp * spp; - lamt = atan(((1. - sppsq * this->m_par.rone_es) * tan(lamdp) * + lamt = atan(((1. - sppsq * par.rone_es) * tan(lamdp) * this->m_proj_parm.ca - spp * this->m_proj_parm.sa * sqrt((1. + this->m_proj_parm.q * dd) * ( 1. - sppsq) - sppsq * this->m_proj_parm.u) / cos(lamdp)) / (1. - sppsq * (1. + this->m_proj_parm.u))); @@ -214,10 +208,10 @@ namespace projections lamt -= half_pi * (1. - scl) * sl; lp_lon = lamt - this->m_proj_parm.p22 * lamdp; if (fabs(this->m_proj_parm.sa) < tolerance) - lp_lat = aasin(spp / sqrt(this->m_par.one_es * this->m_par.one_es + this->m_par.es * sppsq)); + lp_lat = aasin(spp / sqrt(par.one_es * par.one_es + par.es * sppsq)); else lp_lat = atan((tan(lamdp) * cos(lamt) - this->m_proj_parm.ca * sin(lamt)) / - (this->m_par.one_es * this->m_proj_parm.sa)); + (par.one_es * this->m_proj_parm.sa)); } static inline std::string get_name() @@ -307,10 +301,9 @@ namespace projections struct lsat_ellipsoid : public detail::lsat::base_lsat_ellipsoid { template - inline lsat_ellipsoid(Params const& params, Parameters const& par) - : detail::lsat::base_lsat_ellipsoid(par) + inline lsat_ellipsoid(Params const& params, Parameters & par) { - detail::lsat::setup_lsat(params, this->m_par, this->m_proj_parm); + detail::lsat::setup_lsat(params, par, this->m_proj_parm); } }; @@ -319,7 +312,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_lsat, lsat_ellipsoid, lsat_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_lsat, lsat_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(lsat_entry, lsat_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/mbt_fps.hpp b/include/boost/geometry/srs/projections/proj/mbt_fps.hpp index 25b59887e..282799f84 100644 --- a/include/boost/geometry/srs/projections/proj/mbt_fps.hpp +++ b/include/boost/geometry/srs/projections/proj/mbt_fps.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -67,18 +67,12 @@ namespace projections template inline T C1_2() { return detail::third(); } - // template class, using CRTP to implement forward/inverse template struct base_mbt_fps_spheroid - : public base_t_fi, T, Parameters> { - inline base_mbt_fps_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { static const T C1_2 = mbt_fps::C1_2(); @@ -100,7 +94,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const&, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { T t; @@ -142,10 +136,9 @@ namespace projections struct mbt_fps_spheroid : public detail::mbt_fps::base_mbt_fps_spheroid { template - inline mbt_fps_spheroid(Params const& , Parameters const& par) - : detail::mbt_fps::base_mbt_fps_spheroid(par) + inline mbt_fps_spheroid(Params const& , Parameters & par) { - detail::mbt_fps::setup_mbt_fps(this->m_par); + detail::mbt_fps::setup_mbt_fps(par); } }; @@ -154,7 +147,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_mbt_fps, mbt_fps_spheroid, mbt_fps_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_mbt_fps, mbt_fps_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(mbt_fps_entry, mbt_fps_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/mbtfpp.hpp b/include/boost/geometry/srs/projections/proj/mbtfpp.hpp index 87e4d2ffa..7b587b7da 100644 --- a/include/boost/geometry/srs/projections/proj/mbtfpp.hpp +++ b/include/boost/geometry/srs/projections/proj/mbtfpp.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -63,18 +63,12 @@ namespace projections //static const double C13 = .33333333333333333333; static const double one_plus_eps = 1.0000001; - // template class, using CRTP to implement forward/inverse template struct base_mbtfpp_spheroid - : public base_t_fi, T, Parameters> { - inline base_mbtfpp_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { static const T C23 = detail::two_thirds(); static const T C13 = detail::third(); @@ -86,7 +80,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); static const T C23 = detail::two_thirds(); @@ -145,10 +139,9 @@ namespace projections struct mbtfpp_spheroid : public detail::mbtfpp::base_mbtfpp_spheroid { template - inline mbtfpp_spheroid(Params const& , Parameters const& par) - : detail::mbtfpp::base_mbtfpp_spheroid(par) + inline mbtfpp_spheroid(Params const& , Parameters & par) { - detail::mbtfpp::setup_mbtfpp(this->m_par); + detail::mbtfpp::setup_mbtfpp(par); } }; @@ -157,7 +150,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_mbtfpp, mbtfpp_spheroid, mbtfpp_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_mbtfpp, mbtfpp_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(mbtfpp_entry, mbtfpp_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/mbtfpq.hpp b/include/boost/geometry/srs/projections/proj/mbtfpq.hpp index d806a8b98..6bd850a5e 100644 --- a/include/boost/geometry/srs/projections/proj/mbtfpq.hpp +++ b/include/boost/geometry/srs/projections/proj/mbtfpq.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -66,18 +66,12 @@ namespace projections static const double FXC = 0.31245971410378249250; static const double RXC = 3.20041258076506210122; - // template class, using CRTP to implement forward/inverse template struct base_mbtfpq_spheroid - : public base_t_fi, T, Parameters> { - inline base_mbtfpq_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { T th1, c; int i; @@ -94,7 +88,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T pi = detail::pi(); static const T half_pi = detail::half_pi(); @@ -156,10 +150,9 @@ namespace projections struct mbtfpq_spheroid : public detail::mbtfpq::base_mbtfpq_spheroid { template - inline mbtfpq_spheroid(Params const& , Parameters const& par) - : detail::mbtfpq::base_mbtfpq_spheroid(par) + inline mbtfpq_spheroid(Params const& , Parameters & par) { - detail::mbtfpq::setup_mbtfpq(this->m_par); + detail::mbtfpq::setup_mbtfpq(par); } }; @@ -168,7 +161,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_mbtfpq, mbtfpq_spheroid, mbtfpq_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_mbtfpq, mbtfpq_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(mbtfpq_entry, mbtfpq_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/merc.hpp b/include/boost/geometry/srs/projections/proj/merc.hpp index 5ec1e1f84..398339a69 100644 --- a/include/boost/geometry/srs/projections/proj/merc.hpp +++ b/include/boost/geometry/srs/projections/proj/merc.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -62,36 +62,30 @@ namespace projections static const double epsilon10 = 1.e-10; - // template class, using CRTP to implement forward/inverse template struct base_merc_ellipsoid - : public base_t_fi, T, Parameters> { - inline base_merc_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); if (fabs(fabs(lp_lat) - half_pi) <= epsilon10) { BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } - xy_x = this->m_par.k0 * lp_lon; - xy_y = - this->m_par.k0 * log(pj_tsfn(lp_lat, sin(lp_lat), this->m_par.e)); + xy_x = par.k0 * lp_lon; + xy_y = - par.k0 * log(pj_tsfn(lp_lat, sin(lp_lat), par.e)); } // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { - if ((lp_lat = pj_phi2(exp(- xy_y / this->m_par.k0), this->m_par.e)) == HUGE_VAL) { + if ((lp_lat = pj_phi2(exp(- xy_y / par.k0), par.e)) == HUGE_VAL) { BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } - lp_lon = xy_x / this->m_par.k0; + lp_lon = xy_x / par.k0; } static inline std::string get_name() @@ -101,18 +95,12 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_merc_spheroid - : public base_t_fi, T, Parameters> { - inline base_merc_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); static const T fourth_pi = detail::fourth_pi(); @@ -120,18 +108,18 @@ namespace projections if (fabs(fabs(lp_lat) - half_pi) <= epsilon10) { BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } - xy_x = this->m_par.k0 * lp_lon; - xy_y = this->m_par.k0 * log(tan(fourth_pi + .5 * lp_lat)); + xy_x = par.k0 * lp_lon; + xy_y = par.k0 * log(tan(fourth_pi + .5 * lp_lat)); } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); - lp_lat = half_pi - 2. * atan(exp(-xy_y / this->m_par.k0)); - lp_lon = xy_x / this->m_par.k0; + lp_lat = half_pi - 2. * atan(exp(-xy_y / par.k0)); + lp_lon = xy_x / par.k0; } static inline std::string get_name() @@ -187,10 +175,9 @@ namespace projections struct merc_ellipsoid : public detail::merc::base_merc_ellipsoid { template - inline merc_ellipsoid(Params const& params, Parameters const& par) - : detail::merc::base_merc_ellipsoid(par) + inline merc_ellipsoid(Params const& params, Parameters & par) { - detail::merc::setup_merc(params, this->m_par); + detail::merc::setup_merc(params, par); } }; @@ -213,10 +200,9 @@ namespace projections struct merc_spheroid : public detail::merc::base_merc_spheroid { template - inline merc_spheroid(Params const& params, Parameters const& par) - : detail::merc::base_merc_spheroid(par) + inline merc_spheroid(Params const& params, Parameters & par) { - detail::merc::setup_merc(params, this->m_par); + detail::merc::setup_merc(params, par); } }; @@ -225,7 +211,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_merc, merc_spheroid, merc_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_merc, merc_spheroid, merc_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(merc_entry, merc_spheroid, merc_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/mill.hpp b/include/boost/geometry/srs/projections/proj/mill.hpp index 6fa47eb0d..375f056fb 100644 --- a/include/boost/geometry/srs/projections/proj/mill.hpp +++ b/include/boost/geometry/srs/projections/proj/mill.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -53,18 +53,12 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace mill { - // template class, using CRTP to implement forward/inverse template struct base_mill_spheroid - : public base_t_fi, T, Parameters> { - inline base_mill_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T fourth_pi = detail::fourth_pi(); @@ -74,7 +68,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T fourth_pi = detail::fourth_pi(); @@ -115,10 +109,9 @@ namespace projections struct mill_spheroid : public detail::mill::base_mill_spheroid { template - inline mill_spheroid(Params const& , Parameters const& par) - : detail::mill::base_mill_spheroid(par) + inline mill_spheroid(Params const& , Parameters & par) { - detail::mill::setup_mill(this->m_par); + detail::mill::setup_mill(par); } }; @@ -127,7 +120,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_mill, mill_spheroid, mill_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_mill, mill_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(mill_entry, mill_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/mod_ster.hpp b/include/boost/geometry/srs/projections/proj/mod_ster.hpp index ade151dc8..605045270 100644 --- a/include/boost/geometry/srs/projections/proj/mod_ster.hpp +++ b/include/boost/geometry/srs/projections/proj/mod_ster.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -71,20 +71,14 @@ namespace projections /* based upon Snyder and Linck, USGS-NMD */ - // template class, using CRTP to implement forward/inverse template struct base_mod_ster_ellipsoid - : public base_t_fi, T, Parameters> { par_mod_ster m_proj_parm; - inline base_mod_ster_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); @@ -93,9 +87,9 @@ namespace projections sinlon = sin(lp_lon); coslon = cos(lp_lon); - esphi = this->m_par.e * sin(lp_lat); + esphi = par.e * sin(lp_lat); chi = 2. * atan(tan((half_pi + lp_lat) * .5) * - math::pow((T(1) - esphi) / (T(1) + esphi), this->m_par.e * T(0.5))) - half_pi; + math::pow((T(1) - esphi) / (T(1) + esphi), par.e * T(0.5))) - half_pi; schi = sin(chi); cchi = cos(chi); s = 2. / (1. + this->m_proj_parm.schio * schi + this->m_proj_parm.cchio * cchi * coslon); @@ -108,7 +102,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); @@ -135,21 +129,21 @@ namespace projections z = 2. * atan(.5 * rh); sinz = sin(z); cosz = cos(z); - lp_lon = this->m_par.lam0; + lp_lon = par.lam0; if (fabs(rh) <= epsilon) { /* if we end up here input coordinates were (0,0). * pj_inv() adds P->lam0 to lp.lam, this way we are * sure to get the correct offset */ lp_lon = 0.0; - lp_lat = this->m_par.phi0; + lp_lat = par.phi0; return; } chi = aasin(cosz * this->m_proj_parm.schio + p.i * sinz * this->m_proj_parm.cchio / rh); phi = chi; for (nn = 20; nn ;--nn) { - esphi = this->m_par.e * sin(phi); + esphi = par.e * sin(phi); dphi = 2. * atan(tan((half_pi + chi) * .5) * - math::pow((T(1) + esphi) / (T(1) - esphi), this->m_par.e * T(0.5))) - half_pi - phi; + math::pow((T(1) + esphi) / (T(1) - esphi), par.e * T(0.5))) - half_pi - phi; phi += dphi; if (fabs(dphi) <= epsilon) break; @@ -357,10 +351,9 @@ namespace projections struct mil_os_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid { template - inline mil_os_ellipsoid(Params const& , Parameters const& par) - : detail::mod_ster::base_mod_ster_ellipsoid(par) + inline mil_os_ellipsoid(Params const& , Parameters & par) { - detail::mod_ster::setup_mil_os(this->m_par, this->m_proj_parm); + detail::mod_ster::setup_mil_os(par, this->m_proj_parm); } }; @@ -379,10 +372,9 @@ namespace projections struct lee_os_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid { template - inline lee_os_ellipsoid(Params const& , Parameters const& par) - : detail::mod_ster::base_mod_ster_ellipsoid(par) + inline lee_os_ellipsoid(Params const& , Parameters & par) { - detail::mod_ster::setup_lee_os(this->m_par, this->m_proj_parm); + detail::mod_ster::setup_lee_os(par, this->m_proj_parm); } }; @@ -401,10 +393,9 @@ namespace projections struct gs48_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid { template - inline gs48_ellipsoid(Params const& , Parameters const& par) - : detail::mod_ster::base_mod_ster_ellipsoid(par) + inline gs48_ellipsoid(Params const& , Parameters & par) { - detail::mod_ster::setup_gs48(this->m_par, this->m_proj_parm); + detail::mod_ster::setup_gs48(par, this->m_proj_parm); } }; @@ -423,10 +414,9 @@ namespace projections struct alsk_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid { template - inline alsk_ellipsoid(Params const& , Parameters const& par) - : detail::mod_ster::base_mod_ster_ellipsoid(par) + inline alsk_ellipsoid(Params const& , Parameters & par) { - detail::mod_ster::setup_alsk(this->m_par, this->m_proj_parm); + detail::mod_ster::setup_alsk(par, this->m_proj_parm); } }; @@ -445,10 +435,9 @@ namespace projections struct gs50_ellipsoid : public detail::mod_ster::base_mod_ster_ellipsoid { template - inline gs50_ellipsoid(Params const& , Parameters const& par) - : detail::mod_ster::base_mod_ster_ellipsoid(par) + inline gs50_ellipsoid(Params const& , Parameters & par) { - detail::mod_ster::setup_gs50(this->m_par, this->m_proj_parm); + detail::mod_ster::setup_gs50(par, this->m_proj_parm); } }; @@ -457,11 +446,11 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_mil_os, mil_os_ellipsoid, mil_os_ellipsoid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_lee_os, lee_os_ellipsoid, lee_os_ellipsoid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_gs48, gs48_ellipsoid, gs48_ellipsoid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_alsk, alsk_ellipsoid, alsk_ellipsoid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_gs50, gs50_ellipsoid, gs50_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_mil_os, mil_os_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_lee_os, lee_os_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_gs48, gs48_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_alsk, alsk_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_gs50, gs50_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(mil_os_entry, mil_os_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/moll.hpp b/include/boost/geometry/srs/projections/proj/moll.hpp index b62175a86..e00bb2c76 100644 --- a/include/boost/geometry/srs/projections/proj/moll.hpp +++ b/include/boost/geometry/srs/projections/proj/moll.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -66,20 +66,14 @@ namespace projections T C_x, C_y, C_p; }; - // template class, using CRTP to implement forward/inverse template struct base_moll_spheroid - : public base_t_fi, T, Parameters> { par_moll m_proj_parm; - inline base_moll_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); @@ -103,7 +97,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T pi = detail::pi(); @@ -182,10 +176,9 @@ namespace projections struct moll_spheroid : public detail::moll::base_moll_spheroid { template - inline moll_spheroid(Params const& , Parameters const& par) - : detail::moll::base_moll_spheroid(par) + inline moll_spheroid(Params const& , Parameters & par) { - detail::moll::setup_moll(this->m_par, this->m_proj_parm); + detail::moll::setup_moll(par, this->m_proj_parm); } }; @@ -205,10 +198,9 @@ namespace projections struct wag4_spheroid : public detail::moll::base_moll_spheroid { template - inline wag4_spheroid(Params const& , Parameters const& par) - : detail::moll::base_moll_spheroid(par) + inline wag4_spheroid(Params const& , Parameters & par) { - detail::moll::setup_wag4(this->m_par, this->m_proj_parm); + detail::moll::setup_wag4(par, this->m_proj_parm); } }; @@ -228,10 +220,9 @@ namespace projections struct wag5_spheroid : public detail::moll::base_moll_spheroid { template - inline wag5_spheroid(Params const& , Parameters const& par) - : detail::moll::base_moll_spheroid(par) + inline wag5_spheroid(Params const& , Parameters & par) { - detail::moll::setup_wag5(this->m_par, this->m_proj_parm); + detail::moll::setup_wag5(par, this->m_proj_parm); } }; @@ -240,9 +231,9 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_moll, moll_spheroid, moll_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_wag4, wag4_spheroid, wag4_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_wag5, wag5_spheroid, wag5_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_moll, moll_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_wag4, wag4_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_wag5, wag5_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(moll_entry, moll_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/natearth.hpp b/include/boost/geometry/srs/projections/proj/natearth.hpp index 6c9935b0e..fb736a842 100644 --- a/include/boost/geometry/srs/projections/proj/natearth.hpp +++ b/include/boost/geometry/srs/projections/proj/natearth.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -90,18 +90,12 @@ namespace projections /* Not sure at all of the appropriate number for max_iter... */ static const int max_iter = 100; - // template class, using CRTP to implement forward/inverse template struct base_natearth_spheroid - : public base_t_fi, T, Parameters> { - inline base_natearth_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T phi2, phi4; @@ -113,7 +107,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const { static const T max_y = natearth::max_y(); @@ -181,10 +175,9 @@ namespace projections struct natearth_spheroid : public detail::natearth::base_natearth_spheroid { template - inline natearth_spheroid(Params const& , Parameters const& par) - : detail::natearth::base_natearth_spheroid(par) + inline natearth_spheroid(Params const& , Parameters & par) { - detail::natearth::setup_natearth(this->m_par); + detail::natearth::setup_natearth(par); } }; @@ -193,7 +186,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_natearth, natearth_spheroid, natearth_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_natearth, natearth_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(natearth_entry, natearth_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/nell.hpp b/include/boost/geometry/srs/projections/proj/nell.hpp index c8a10f7be..3f9ee74d9 100644 --- a/include/boost/geometry/srs/projections/proj/nell.hpp +++ b/include/boost/geometry/srs/projections/proj/nell.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -58,18 +58,12 @@ namespace projections static const int max_iter = 10; static const double loop_tol = 1e-7; - // template class, using CRTP to implement forward/inverse template struct base_nell_spheroid - : public base_t_fi, T, Parameters> { - inline base_nell_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { T k, V; int i; @@ -89,7 +83,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { lp_lon = 2. * xy_x / (1. + cos(xy_y)); lp_lat = aasin(0.5 * (xy_y + sin(xy_y))); @@ -128,10 +122,9 @@ namespace projections struct nell_spheroid : public detail::nell::base_nell_spheroid { template - inline nell_spheroid(Params const& , Parameters const& par) - : detail::nell::base_nell_spheroid(par) + inline nell_spheroid(Params const& , Parameters & par) { - detail::nell::setup_nell(this->m_par); + detail::nell::setup_nell(par); } }; @@ -140,7 +133,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_nell, nell_spheroid, nell_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_nell, nell_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(nell_entry, nell_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/nell_h.hpp b/include/boost/geometry/srs/projections/proj/nell_h.hpp index 2e0e05738..95240d7ef 100644 --- a/include/boost/geometry/srs/projections/proj/nell_h.hpp +++ b/include/boost/geometry/srs/projections/proj/nell_h.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -59,18 +59,12 @@ namespace projections static const int n_iter = 9; static const double epsilon = 1e-7; - // template class, using CRTP to implement forward/inverse template struct base_nell_h_spheroid - : public base_t_fi, T, Parameters> { - inline base_nell_h_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { xy_x = 0.5 * lp_lon * (1. + cos(lp_lat)); xy_y = 2.0 * (lp_lat - tan(0.5 *lp_lat)); @@ -78,7 +72,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); @@ -132,10 +126,9 @@ namespace projections struct nell_h_spheroid : public detail::nell_h::base_nell_h_spheroid { template - inline nell_h_spheroid(Params const& , Parameters const& par) - : detail::nell_h::base_nell_h_spheroid(par) + inline nell_h_spheroid(Params const& , Parameters & par) { - detail::nell_h::setup_nell_h(this->m_par); + detail::nell_h::setup_nell_h(par); } }; @@ -144,7 +137,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_nell_h, nell_h_spheroid, nell_h_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_nell_h, nell_h_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(nell_h_entry, nell_h_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/nocol.hpp b/include/boost/geometry/srs/projections/proj/nocol.hpp index 924ec86ef..45ccbf4f6 100644 --- a/include/boost/geometry/srs/projections/proj/nocol.hpp +++ b/include/boost/geometry/srs/projections/proj/nocol.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -58,18 +58,12 @@ namespace projections static const double epsilon = 1e-10; - // template class, using CRTP to implement forward/inverse template struct base_nocol_spheroid - : public base_t_f, T, Parameters> { - inline base_nocol_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); @@ -138,10 +132,9 @@ namespace projections struct nicol_spheroid : public detail::nocol::base_nocol_spheroid { template - inline nicol_spheroid(Params const& , Parameters const& par) - : detail::nocol::base_nocol_spheroid(par) + inline nicol_spheroid(Params const& , Parameters & par) { - detail::nocol::setup_nicol(this->m_par); + detail::nocol::setup_nicol(par); } }; @@ -150,7 +143,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_nicol, nicol_spheroid, nicol_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_nicol, nicol_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(nicol_entry, nicol_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/nsper.hpp b/include/boost/geometry/srs/projections/proj/nsper.hpp index 6366e100d..442110767 100644 --- a/include/boost/geometry/srs/projections/proj/nsper.hpp +++ b/include/boost/geometry/srs/projections/proj/nsper.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -88,20 +88,14 @@ namespace projections int tilt; }; - // template class, using CRTP to implement forward/inverse template struct base_nsper_spheroid - : public base_t_fi, T, Parameters> { par_nsper m_proj_parm; - inline base_nsper_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T coslam, cosphi, sinphi; @@ -154,7 +148,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { T rh, cosz, sinz; @@ -175,7 +169,7 @@ namespace projections cosz = sqrt(1. - sinz * sinz); if (fabs(rh) <= epsilon10) { lp_lon = 0.; - lp_lat = this->m_par.phi0; + lp_lat = par.phi0; } else { switch (this->m_proj_parm.mode) { case obliq: @@ -275,10 +269,9 @@ namespace projections struct nsper_spheroid : public detail::nsper::base_nsper_spheroid { template - inline nsper_spheroid(Params const& params, Parameters const& par) - : detail::nsper::base_nsper_spheroid(par) + inline nsper_spheroid(Params const& params, Parameters & par) { - detail::nsper::setup_nsper(params, this->m_par, this->m_proj_parm); + detail::nsper::setup_nsper(params, par, this->m_proj_parm); } }; @@ -302,10 +295,9 @@ namespace projections struct tpers_spheroid : public detail::nsper::base_nsper_spheroid { template - inline tpers_spheroid(Params const& params, Parameters const& par) - : detail::nsper::base_nsper_spheroid(par) + inline tpers_spheroid(Params const& params, Parameters & par) { - detail::nsper::setup_tpers(params, this->m_par, this->m_proj_parm); + detail::nsper::setup_tpers(params, par, this->m_proj_parm); } }; @@ -314,8 +306,8 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_nsper, nsper_spheroid, nsper_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_tpers, tpers_spheroid, tpers_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_nsper, nsper_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_tpers, tpers_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(nsper_entry, nsper_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/nzmg.hpp b/include/boost/geometry/srs/projections/proj/nzmg.hpp index 858685f74..4c0d83284 100644 --- a/include/boost/geometry/srs/projections/proj/nzmg.hpp +++ b/include/boost/geometry/srs/projections/proj/nzmg.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -102,18 +102,12 @@ namespace projections return result; } - // template class, using CRTP to implement forward/inverse template struct base_nzmg_ellipsoid - : public base_t_fi, T, Parameters> { - inline base_nzmg_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { static const T rad_to_sec5 = nzmg::rad_to_sec5(); @@ -121,7 +115,7 @@ namespace projections const T * C; int i; - lp_lat = (lp_lat - this->m_par.phi0) * rad_to_sec5; + lp_lat = (lp_lat - par.phi0) * rad_to_sec5; for (p.r = *(C = tpsi() + (i = Ntpsi)); i ; --i) p.r = *--C + lp_lat * p.r; p.r *= lp_lat; @@ -133,7 +127,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T sec5_to_rad = nzmg::sec5_to_rad(); @@ -158,7 +152,7 @@ namespace projections lp_lon = p.i; for (lp_lat = *(C = tphi() + (i = Ntphi)); i ; --i) lp_lat = *--C + p.r * lp_lat; - lp_lat = this->m_par.phi0 + p.r * lp_lat * sec5_to_rad; + lp_lat = par.phi0 + p.r * lp_lat * sec5_to_rad; } else lp_lon = lp_lat = HUGE_VAL; } @@ -204,10 +198,9 @@ namespace projections struct nzmg_ellipsoid : public detail::nzmg::base_nzmg_ellipsoid { template - inline nzmg_ellipsoid(Params const& , Parameters const& par) - : detail::nzmg::base_nzmg_ellipsoid(par) + inline nzmg_ellipsoid(Params const& , Parameters & par) { - detail::nzmg::setup_nzmg(this->m_par); + detail::nzmg::setup_nzmg(par); } }; @@ -216,7 +209,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_nzmg, nzmg_ellipsoid, nzmg_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_nzmg, nzmg_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(nzmg_entry, nzmg_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/ob_tran.hpp b/include/boost/geometry/srs/projections/proj/ob_tran.hpp index 99a7b82b1..f46938f01 100644 --- a/include/boost/geometry/srs/projections/proj/ob_tran.hpp +++ b/include/boost/geometry/srs/projections/proj/ob_tran.hpp @@ -60,12 +60,12 @@ namespace projections // fwd declaration needed below template - inline detail::base_v >* + inline detail::dynamic_wrapper_b >* create_new(srs::detail::proj4_parameters const& params, projections::parameters const& parameters); template - inline detail::base_v >* + inline detail::dynamic_wrapper_b >* create_new(srs::dpar::parameters const& params, projections::parameters const& parameters); @@ -163,6 +163,11 @@ namespace projections return pj; } + // TODO: It's possible that the original Parameters could be used + // instead of a copy in link. + // But it's not possible with the current implementation of + // dynamic_wrapper_b always storing params + template struct par_ob_tran { @@ -176,15 +181,15 @@ namespace projections inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { - link->fwd(lp_lon, lp_lat, xy_x, xy_y); + link->fwd(link->params(), lp_lon, lp_lat, xy_x, xy_y); } inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { - link->inv(xy_x, xy_y, lp_lon, lp_lat); + link->inv(link->params(), xy_x, xy_y, lp_lon, lp_lat); } - boost::shared_ptr > link; + boost::shared_ptr > link; T lamp; T cphip, sphip; }; @@ -219,12 +224,12 @@ namespace projections inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { - link.fwd(lp_lon, lp_lat, xy_x, xy_y); + link.fwd(link.params(), lp_lon, lp_lat, xy_x, xy_y); } inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { - link.inv(xy_x, xy_y, lp_lon, lp_lat); + link.inv(link.params(), xy_x, xy_y, lp_lon, lp_lat); } projection_type link; @@ -352,33 +357,28 @@ namespace projections return phip; } - // template class, using CRTP to implement forward/inverse template struct base_ob_tran_oblique - : public base_t_fi, T, Parameters> { par_ob_tran m_proj_parm; - inline base_ob_tran_oblique(Parameters const& par, - par_ob_tran const& proj_parm) - : base_t_fi - < - base_ob_tran_oblique, T, Parameters - >(*this, par) - , m_proj_parm(proj_parm) + inline base_ob_tran_oblique(par_ob_tran const& proj_parm) + : m_proj_parm(proj_parm) {} // FORWARD(o_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { + // NOTE: Parameters ignored, m_proj_parm.link has a copy o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm); } // INVERSE(o_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { + // NOTE: Parameters ignored, m_proj_parm.link has a copy o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm); } @@ -389,33 +389,28 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_ob_tran_transverse - : public base_t_fi, T, Parameters> { par_ob_tran m_proj_parm; - inline base_ob_tran_transverse(Parameters const& par, - par_ob_tran const& proj_parm) - : base_t_fi - < - base_ob_tran_transverse, T, Parameters - >(*this, par) - , m_proj_parm(proj_parm) + inline base_ob_tran_transverse(par_ob_tran const& proj_parm) + : m_proj_parm(proj_parm) {} // FORWARD(t_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { + // NOTE: Parameters ignored, m_proj_parm.link has a copy t_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm); } // INVERSE(t_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { + // NOTE: Parameters ignored, m_proj_parm.link has a copy t_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm); } @@ -426,23 +421,21 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_ob_tran_static - : public base_t_fi, T, Parameters> { par_ob_tran_static m_proj_parm; bool m_is_oblique; inline base_ob_tran_static(StaticParameters const& params, Parameters const& par) - : base_t_fi, T, Parameters>(*this, par) - , m_proj_parm(params, par) + : m_proj_parm(params, par) {} // FORWARD(o_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { + // NOTE: Parameters ignored, m_proj_parm.link has a copy if (m_is_oblique) { o_forward(lp_lon, lp_lat, xy_x, xy_y, this->m_proj_parm); } else { @@ -452,8 +445,9 @@ namespace projections // INVERSE(o_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { + // NOTE: Parameters ignored, m_proj_parm.link has a copy if (m_is_oblique) { o_inverse(xy_x, xy_y, lp_lon, lp_lat, this->m_proj_parm); } else { @@ -499,9 +493,10 @@ namespace projections template struct ob_tran_oblique : public detail::ob_tran::base_ob_tran_oblique { - inline ob_tran_oblique(Parameters const& par, + template + inline ob_tran_oblique(Params const& , Parameters const& , detail::ob_tran::par_ob_tran const& proj_parm) - : detail::ob_tran::base_ob_tran_oblique(par, proj_parm) + : detail::ob_tran::base_ob_tran_oblique(proj_parm) { // already done //detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm); @@ -535,10 +530,11 @@ namespace projections */ template struct ob_tran_transverse : public detail::ob_tran::base_ob_tran_transverse - { - inline ob_tran_transverse(Parameters const& par, + { + template + inline ob_tran_transverse(Params const& , Parameters const& , detail::ob_tran::par_ob_tran const& proj_parm) - : detail::ob_tran::base_ob_tran_transverse(par, proj_parm) + : detail::ob_tran::base_ob_tran_transverse(proj_parm) { // already done //detail::ob_tran::setup_ob_tran(this->m_par, this->m_proj_parm); @@ -576,7 +572,7 @@ namespace projections inline ob_tran_static(StaticParameters const& params, Parameters const& par) : detail::ob_tran::base_ob_tran_static(params, par) { - T phip = detail::ob_tran::setup_ob_tran(params, this->m_par, this->m_proj_parm); + T phip = detail::ob_tran::setup_ob_tran(params, par, this->m_proj_parm); this->m_is_oblique = fabs(phip) > detail::ob_tran::tolerance; } }; @@ -589,12 +585,12 @@ namespace projections template struct static_projection_type { - typedef ob_tran_static type; + typedef static_wrapper_fi, P> type; }; template struct static_projection_type { - typedef ob_tran_static type; + typedef static_wrapper_fi, P> type; }; // Factory entry(s) @@ -605,9 +601,9 @@ namespace projections T phip = detail::ob_tran::setup_ob_tran(params, parameters_copy, proj_parm); if (fabs(phip) > detail::ob_tran::tolerance) - return new base_v_fi, T, Parameters>(parameters_copy, proj_parm); + return new dynamic_wrapper_fi, T, Parameters>(params, parameters_copy, proj_parm); else - return new base_v_fi, T, Parameters>(parameters_copy, proj_parm); + return new dynamic_wrapper_fi, T, Parameters>(params, parameters_copy, proj_parm); } BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_END diff --git a/include/boost/geometry/srs/projections/proj/ocea.hpp b/include/boost/geometry/srs/projections/proj/ocea.hpp index c7f531745..d9dc57a2f 100644 --- a/include/boost/geometry/srs/projections/proj/ocea.hpp +++ b/include/boost/geometry/srs/projections/proj/ocea.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -67,20 +67,14 @@ namespace projections T cosgam; }; - // template class, using CRTP to implement forward/inverse template struct base_ocea_spheroid - : public base_t_fi, T, Parameters> { par_ocea m_proj_parm; - inline base_ocea_spheroid(const Parameters& par) - : base_t_fi, - T, Parameters>(*this, par) {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T pi = detail::pi(); @@ -97,7 +91,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { T t, s; @@ -189,10 +183,9 @@ namespace projections struct ocea_spheroid : public detail::ocea::base_ocea_spheroid { template - inline ocea_spheroid(Params const& params, Parameters const& par) - : detail::ocea::base_ocea_spheroid(par) + inline ocea_spheroid(Params const& params, Parameters & par) { - detail::ocea::setup_ocea(params, this->m_par, this->m_proj_parm); + detail::ocea::setup_ocea(params, par, this->m_proj_parm); } }; @@ -201,7 +194,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_ocea, ocea_spheroid, ocea_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_ocea, ocea_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(ocea_entry, ocea_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/oea.hpp b/include/boost/geometry/srs/projections/proj/oea.hpp index 10399ec1a..c92a2f46c 100644 --- a/include/boost/geometry/srs/projections/proj/oea.hpp +++ b/include/boost/geometry/srs/projections/proj/oea.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -66,20 +66,14 @@ namespace projections T cp0, sp0; }; - // template class, using CRTP to implement forward/inverse template struct base_oea_spheroid - : public base_t_fi, T, Parameters> { par_oea m_proj_parm; - inline base_oea_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T Az, M, N, cp, sp, cl, shz; @@ -96,7 +90,7 @@ namespace projections // INVERSE(s_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { T N, M, xp, yp, z, Az, cz, sz, cAz; @@ -164,10 +158,9 @@ namespace projections struct oea_spheroid : public detail::oea::base_oea_spheroid { template - inline oea_spheroid(Params const& params, Parameters const& par) - : detail::oea::base_oea_spheroid(par) + inline oea_spheroid(Params const& params, Parameters & par) { - detail::oea::setup_oea(params, this->m_par, this->m_proj_parm); + detail::oea::setup_oea(params, par, this->m_proj_parm); } }; @@ -176,7 +169,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_oea, oea_spheroid, oea_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_oea, oea_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(oea_entry, oea_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/omerc.hpp b/include/boost/geometry/srs/projections/proj/omerc.hpp index 0bec0cacc..7122eaabd 100644 --- a/include/boost/geometry/srs/projections/proj/omerc.hpp +++ b/include/boost/geometry/srs/projections/proj/omerc.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -71,27 +71,21 @@ namespace projections static const double tolerance = 1.e-7; static const double epsilon = 1.e-10; - // template class, using CRTP to implement forward/inverse template struct base_omerc_ellipsoid - : public base_t_fi, T, Parameters> { par_omerc m_proj_parm; - inline base_omerc_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); T s, t, U, V, W, temp, u, v; if (fabs(fabs(lp_lat) - half_pi) > epsilon) { - W = this->m_proj_parm.E / math::pow(pj_tsfn(lp_lat, sin(lp_lat), this->m_par.e), this->m_proj_parm.B); + W = this->m_proj_parm.E / math::pow(pj_tsfn(lp_lat, sin(lp_lat), par.e), this->m_proj_parm.B); temp = 1. / W; s = .5 * (W - temp); t = .5 * (W + temp); @@ -123,7 +117,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); @@ -146,7 +140,7 @@ namespace projections lp_lat = Up < 0. ? -half_pi : half_pi; } else { lp_lat = this->m_proj_parm.E / sqrt((1. + Up) / (1. - Up)); - if ((lp_lat = pj_phi2(math::pow(lp_lat, T(1) / this->m_proj_parm.B), this->m_par.e)) == HUGE_VAL) { + if ((lp_lat = pj_phi2(math::pow(lp_lat, T(1) / this->m_proj_parm.B), par.e)) == HUGE_VAL) { BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } lp_lon = - this->m_proj_parm.rB * atan2((Sp * this->m_proj_parm.cosgam - @@ -163,7 +157,7 @@ namespace projections // Oblique Mercator template - inline void setup_omerc(Params const& params, Parameters& par, par_omerc& proj_parm) + inline void setup_omerc(Params const& params, Parameters & par, par_omerc& proj_parm) { static const T fourth_pi = detail::fourth_pi(); static const T half_pi = detail::half_pi(); @@ -301,10 +295,9 @@ namespace projections struct omerc_ellipsoid : public detail::omerc::base_omerc_ellipsoid { template - inline omerc_ellipsoid(Params const& params, Parameters const& par) - : detail::omerc::base_omerc_ellipsoid(par) + inline omerc_ellipsoid(Params const& params, Parameters & par) { - detail::omerc::setup_omerc(params, this->m_par, this->m_proj_parm); + detail::omerc::setup_omerc(params, par, this->m_proj_parm); } }; @@ -313,7 +306,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_omerc, omerc_ellipsoid, omerc_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_omerc, omerc_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(omerc_entry, omerc_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/ortho.hpp b/include/boost/geometry/srs/projections/proj/ortho.hpp index 319655448..1f8fb88ca 100644 --- a/include/boost/geometry/srs/projections/proj/ortho.hpp +++ b/include/boost/geometry/srs/projections/proj/ortho.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -75,20 +75,14 @@ namespace projections static const double epsilon10 = 1.e-10; - // template class, using CRTP to implement forward/inverse template struct base_ortho_spheroid - : public base_t_fi, T, Parameters> { par_ortho m_proj_parm; - inline base_ortho_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); @@ -114,7 +108,7 @@ namespace projections coslam = - coslam; BOOST_FALLTHROUGH; case s_pole: - if (fabs(lp_lat - this->m_par.phi0) - epsilon10 > half_pi) { + if (fabs(lp_lat - par.phi0) - epsilon10 > half_pi) { BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } xy_y = cosphi * coslam; @@ -125,7 +119,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); @@ -139,7 +133,7 @@ namespace projections } cosc = sqrt(1. - sinc * sinc); /* in this range OK */ if (fabs(rh) <= epsilon10) { - lp_lat = this->m_par.phi0; + lp_lat = par.phi0; lp_lon = 0.0; } else { switch (this->m_proj_parm.mode) { @@ -213,10 +207,9 @@ namespace projections struct ortho_spheroid : public detail::ortho::base_ortho_spheroid { template - inline ortho_spheroid(Params const& , Parameters const& par) - : detail::ortho::base_ortho_spheroid(par) + inline ortho_spheroid(Params const& , Parameters & par) { - detail::ortho::setup_ortho(this->m_par, this->m_proj_parm); + detail::ortho::setup_ortho(par, this->m_proj_parm); } }; @@ -225,7 +218,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_ortho, ortho_spheroid, ortho_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_ortho, ortho_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(ortho_entry, ortho_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/poly.hpp b/include/boost/geometry/srs/projections/proj/poly.hpp index d0fab653f..f16caad6f 100644 --- a/include/boost/geometry/srs/projections/proj/poly.hpp +++ b/include/boost/geometry/srs/projections/proj/poly.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -69,20 +69,14 @@ namespace projections detail::en en; }; - // template class, using CRTP to implement forward/inverse template struct base_poly_ellipsoid - : public base_t_fi, T, Parameters> { par_poly m_proj_parm; - inline base_poly_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T ms, sp, cp; @@ -91,7 +85,7 @@ namespace projections xy_y = -this->m_proj_parm.ml0; } else { sp = sin(lp_lat); - ms = fabs(cp = cos(lp_lat)) > tolerance ? pj_msfn(sp, cp, this->m_par.es) / sp : 0.; + ms = fabs(cp = cos(lp_lat)) > tolerance ? pj_msfn(sp, cp, par.es) / sp : 0.; xy_x = ms * sin(lp_lon *= sp); xy_y = (pj_mlfn(lp_lat, sp, cp, this->m_proj_parm.en) - this->m_proj_parm.ml0) + ms * (1. - cos(lp_lon)); } @@ -99,7 +93,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const { xy_y += this->m_proj_parm.ml0; if (fabs(xy_y) <= tolerance) { @@ -116,13 +110,13 @@ namespace projections if (fabs(cp) < i_tolerance) { BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } - c = sp * (mlp = sqrt(1. - this->m_par.es * sp * sp)) / cp; + c = sp * (mlp = sqrt(1. - par.es * sp * sp)) / cp; ml = pj_mlfn(lp_lat, sp, cp, this->m_proj_parm.en); mlb = ml * ml + r; - mlp = this->m_par.one_es / (mlp * mlp * mlp); + mlp = par.one_es / (mlp * mlp * mlp); lp_lat += ( dPhi = ( ml + ml + c * mlb - 2. * xy_y * (c * ml + 1.) ) / ( - this->m_par.es * s2ph * (mlb - 2. * xy_y * ml) / c + + par.es * s2ph * (mlb - 2. * xy_y * ml) / c + 2.* (xy_y - ml) * (c * mlp - 1. / s2ph) - mlp - mlp )); if (fabs(dPhi) <= i_tolerance) break; @@ -131,7 +125,7 @@ namespace projections BOOST_THROW_EXCEPTION( projection_exception(error_tolerance_condition) ); } c = sin(lp_lat); - lp_lon = asin(xy_x * tan(lp_lat) * sqrt(1. - this->m_par.es * c * c)) / sin(lp_lat); + lp_lon = asin(xy_x * tan(lp_lat) * sqrt(1. - par.es * c * c)) / sin(lp_lat); } } @@ -142,20 +136,14 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_poly_spheroid - : public base_t_fi, T, Parameters> { par_poly m_proj_parm; - inline base_poly_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T cot, E; @@ -165,18 +153,18 @@ namespace projections } else { cot = 1. / tan(lp_lat); xy_x = sin(E = lp_lon * sin(lp_lat)) * cot; - xy_y = lp_lat - this->m_par.phi0 + cot * (1. - cos(E)); + xy_y = lp_lat - par.phi0 + cot * (1. - cos(E)); } } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const { T B, dphi, tp; int i; - if (fabs(xy_y = this->m_par.phi0 + xy_y) <= tolerance) { + if (fabs(xy_y = par.phi0 + xy_y) <= tolerance) { lp_lon = xy_x; lp_lat = 0.; } else { @@ -205,7 +193,7 @@ namespace projections // Polyconic (American) template - inline void setup_poly(Parameters& par, par_poly& proj_parm) + inline void setup_poly(Parameters const& par, par_poly& proj_parm) { if (par.es != 0.0) { proj_parm.en = pj_enfn(par.es); @@ -236,9 +224,8 @@ namespace projections { template inline poly_ellipsoid(Params const& , Parameters const& par) - : detail::poly::base_poly_ellipsoid(par) { - detail::poly::setup_poly(this->m_par, this->m_proj_parm); + detail::poly::setup_poly(par, this->m_proj_parm); } }; @@ -260,9 +247,8 @@ namespace projections { template inline poly_spheroid(Params const& , Parameters const& par) - : detail::poly::base_poly_spheroid(par) { - detail::poly::setup_poly(this->m_par, this->m_proj_parm); + detail::poly::setup_poly(par, this->m_proj_parm); } }; @@ -271,7 +257,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_poly, poly_spheroid, poly_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_poly, poly_spheroid, poly_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(poly_entry, poly_spheroid, poly_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/putp2.hpp b/include/boost/geometry/srs/projections/proj/putp2.hpp index 104a74702..c99cfd8a2 100644 --- a/include/boost/geometry/srs/projections/proj/putp2.hpp +++ b/include/boost/geometry/srs/projections/proj/putp2.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -62,19 +62,12 @@ namespace projections static const int n_iter = 10; //static const double third_pi = 1.0471975511965977; - // template class, using CRTP to implement forward/inverse template struct base_putp2_spheroid - : public base_t_fi, T, Parameters> { - - inline base_putp2_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { static const T third_pi = detail::third_pi(); @@ -100,7 +93,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { T c; @@ -142,10 +135,9 @@ namespace projections struct putp2_spheroid : public detail::putp2::base_putp2_spheroid { template - inline putp2_spheroid(Params const& , Parameters const& par) - : detail::putp2::base_putp2_spheroid(par) + inline putp2_spheroid(Params const& , Parameters & par) { - detail::putp2::setup_putp2(this->m_par); + detail::putp2::setup_putp2(par); } }; @@ -154,7 +146,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_putp2, putp2_spheroid, putp2_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_putp2, putp2_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(putp2_entry, putp2_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/putp3.hpp b/include/boost/geometry/srs/projections/proj/putp3.hpp index 3f6fceb0f..b7ee61350 100644 --- a/include/boost/geometry/srs/projections/proj/putp3.hpp +++ b/include/boost/geometry/srs/projections/proj/putp3.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -63,20 +63,14 @@ namespace projections T A; }; - // template class, using CRTP to implement forward/inverse template struct base_putp3_spheroid - : public base_t_fi, T, Parameters> { par_putp3 m_proj_parm; - inline base_putp3_spheroid(const Parameters& par) - : base_t_fi, - T, Parameters>(*this, par) {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { xy_x = C * lp_lon * (1. - this->m_proj_parm.A * lp_lat * lp_lat); xy_y = C * lp_lat; @@ -84,7 +78,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = xy_y / C; lp_lon = xy_x / (C * (1. - this->m_proj_parm.A * lp_lat * lp_lat)); @@ -135,10 +129,9 @@ namespace projections struct putp3_spheroid : public detail::putp3::base_putp3_spheroid { template - inline putp3_spheroid(Params const& , Parameters const& par) - : detail::putp3::base_putp3_spheroid(par) + inline putp3_spheroid(Params const& , Parameters & par) { - detail::putp3::setup_putp3(this->m_par, this->m_proj_parm); + detail::putp3::setup_putp3(par, this->m_proj_parm); } }; @@ -158,10 +151,9 @@ namespace projections struct putp3p_spheroid : public detail::putp3::base_putp3_spheroid { template - inline putp3p_spheroid(Params const& , Parameters const& par) - : detail::putp3::base_putp3_spheroid(par) + inline putp3p_spheroid(Params const& , Parameters & par) { - detail::putp3::setup_putp3p(this->m_par, this->m_proj_parm); + detail::putp3::setup_putp3p(par, this->m_proj_parm); } }; @@ -170,8 +162,8 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_putp3, putp3_spheroid, putp3_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_putp3p, putp3p_spheroid, putp3p_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_putp3, putp3_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_putp3p, putp3p_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(putp3_entry, putp3_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/putp4p.hpp b/include/boost/geometry/srs/projections/proj/putp4p.hpp index bf408b8d9..f510557ca 100644 --- a/include/boost/geometry/srs/projections/proj/putp4p.hpp +++ b/include/boost/geometry/srs/projections/proj/putp4p.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -60,20 +60,14 @@ namespace projections T C_x, C_y; }; - // template class, using CRTP to implement forward/inverse template struct base_putp4p_spheroid - : public base_t_fi, T, Parameters> { par_putp4p m_proj_parm; - inline base_putp4p_spheroid(const Parameters& par) - : base_t_fi, - T, Parameters>(*this, par) {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { static T const third = detail::third(); @@ -85,7 +79,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = aasin(xy_y / this->m_proj_parm.C_y); lp_lon = xy_x * cos(lp_lat) / this->m_proj_parm.C_x; @@ -141,10 +135,9 @@ namespace projections struct putp4p_spheroid : public detail::putp4p::base_putp4p_spheroid { template - inline putp4p_spheroid(Params const& , Parameters const& par) - : detail::putp4p::base_putp4p_spheroid(par) + inline putp4p_spheroid(Params const& , Parameters & par) { - detail::putp4p::setup_putp4p(this->m_par, this->m_proj_parm); + detail::putp4p::setup_putp4p(par, this->m_proj_parm); } }; @@ -164,10 +157,9 @@ namespace projections struct weren_spheroid : public detail::putp4p::base_putp4p_spheroid { template - inline weren_spheroid(Params const& , Parameters const& par) - : detail::putp4p::base_putp4p_spheroid(par) + inline weren_spheroid(Params const& , Parameters & par) { - detail::putp4p::setup_weren(this->m_par, this->m_proj_parm); + detail::putp4p::setup_weren(par, this->m_proj_parm); } }; @@ -176,8 +168,8 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_putp4p, putp4p_spheroid, putp4p_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_weren, weren_spheroid, weren_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_putp4p, putp4p_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_weren, weren_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(putp4p_entry, putp4p_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/putp5.hpp b/include/boost/geometry/srs/projections/proj/putp5.hpp index bdddd8553..6601b9dc9 100644 --- a/include/boost/geometry/srs/projections/proj/putp5.hpp +++ b/include/boost/geometry/srs/projections/proj/putp5.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -63,20 +63,14 @@ namespace projections T A, B; }; - // template class, using CRTP to implement forward/inverse template struct base_putp5_spheroid - : public base_t_fi, T, Parameters> { par_putp5 m_proj_parm; - inline base_putp5_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { xy_x = C * lp_lon * (this->m_proj_parm.A - this->m_proj_parm.B * sqrt(1. + D * lp_lat * lp_lat)); xy_y = C * lp_lat; @@ -84,7 +78,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = xy_y / C; lp_lon = xy_x / (C * (this->m_proj_parm.A - this->m_proj_parm.B * sqrt(1. + D * lp_lat * lp_lat))); @@ -137,10 +131,9 @@ namespace projections struct putp5_spheroid : public detail::putp5::base_putp5_spheroid { template - inline putp5_spheroid(Params const& , Parameters const& par) - : detail::putp5::base_putp5_spheroid(par) + inline putp5_spheroid(Params const& , Parameters & par) { - detail::putp5::setup_putp5(this->m_par, this->m_proj_parm); + detail::putp5::setup_putp5(par, this->m_proj_parm); } }; @@ -160,10 +153,9 @@ namespace projections struct putp5p_spheroid : public detail::putp5::base_putp5_spheroid { template - inline putp5p_spheroid(Params const& , Parameters const& par) - : detail::putp5::base_putp5_spheroid(par) + inline putp5p_spheroid(Params const& , Parameters & par) { - detail::putp5::setup_putp5p(this->m_par, this->m_proj_parm); + detail::putp5::setup_putp5p(par, this->m_proj_parm); } }; @@ -172,8 +164,8 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_putp5, putp5_spheroid, putp5_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_putp5p, putp5p_spheroid, putp5p_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_putp5, putp5_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_putp5p, putp5p_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(putp5_entry, putp5_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/putp6.hpp b/include/boost/geometry/srs/projections/proj/putp6.hpp index 97d69e45e..cf3025247 100644 --- a/include/boost/geometry/srs/projections/proj/putp6.hpp +++ b/include/boost/geometry/srs/projections/proj/putp6.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -65,20 +65,14 @@ namespace projections T C_x, C_y, A, B, D; }; - // template class, using CRTP to implement forward/inverse template struct base_putp6_spheroid - : public base_t_fi, T, Parameters> { par_putp6 m_proj_parm; - inline base_putp6_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { T p, r, V; int i; @@ -100,7 +94,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { T r; @@ -163,10 +157,9 @@ namespace projections struct putp6_spheroid : public detail::putp6::base_putp6_spheroid { template - inline putp6_spheroid(Params const& , Parameters const& par) - : detail::putp6::base_putp6_spheroid(par) + inline putp6_spheroid(Params const& , Parameters & par) { - detail::putp6::setup_putp6(this->m_par, this->m_proj_parm); + detail::putp6::setup_putp6(par, this->m_proj_parm); } }; @@ -186,10 +179,9 @@ namespace projections struct putp6p_spheroid : public detail::putp6::base_putp6_spheroid { template - inline putp6p_spheroid(Params const& , Parameters const& par) - : detail::putp6::base_putp6_spheroid(par) + inline putp6p_spheroid(Params const& , Parameters & par) { - detail::putp6::setup_putp6p(this->m_par, this->m_proj_parm); + detail::putp6::setup_putp6p(par, this->m_proj_parm); } }; @@ -198,8 +190,8 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_putp6, putp6_spheroid, putp6_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_putp6p, putp6p_spheroid, putp6p_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_putp6, putp6_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_putp6p, putp6p_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(putp6_entry, putp6_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/qsc.hpp b/include/boost/geometry/srs/projections/proj/qsc.hpp index e4a1ff953..825777143 100644 --- a/include/boost/geometry/srs/projections/proj/qsc.hpp +++ b/include/boost/geometry/srs/projections/proj/qsc.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -174,20 +174,14 @@ namespace projections /* Forward projection, ellipsoid */ - // template class, using CRTP to implement forward/inverse template struct base_qsc_ellipsoid - : public base_t_fi, T, Parameters> { par_qsc m_proj_parm; - inline base_qsc_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T fourth_pi = detail::fourth_pi(); static const T half_pi = detail::half_pi(); @@ -201,7 +195,7 @@ namespace projections /* Convert the geodetic latitude to a geocentric latitude. * This corresponds to the shift from the ellipsoid to the sphere * described in [LK12]. */ - if (this->m_par.es != 0.0) { + if (par.es != 0.0) { lat = atan(this->m_proj_parm.one_minus_f_squared * tan(lp_lat)); } else { lat = lp_lat; @@ -308,7 +302,7 @@ namespace projections // INVERSE(e_inverse) // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); static const T pi = detail::pi(); @@ -436,13 +430,13 @@ namespace projections /* Apply the shift from the sphere to the ellipsoid as described * in [LK12]. */ - if (this->m_par.es != 0.0) { + if (par.es != 0.0) { int invert_sign; T tanphi, xa; invert_sign = (lp_lat < 0.0 ? 1 : 0); tanphi = tan(lp_lat); xa = this->m_proj_parm.b / sqrt(tanphi * tanphi + this->m_proj_parm.one_minus_f_squared); - lp_lat = atan(sqrt(this->m_par.a * this->m_par.a - xa * xa) / (this->m_proj_parm.one_minus_f * xa)); + lp_lat = atan(sqrt(par.a * par.a - xa * xa) / (this->m_proj_parm.one_minus_f * xa)); if (invert_sign) { lp_lat = -lp_lat; } @@ -458,7 +452,7 @@ namespace projections // Quadrilateralized Spherical Cube template - inline void setup_qsc(Parameters& par, par_qsc& proj_parm) + inline void setup_qsc(Parameters const& par, par_qsc& proj_parm) { static const T fourth_pi = detail::fourth_pi(); static const T half_pi = detail::half_pi(); @@ -505,9 +499,8 @@ namespace projections { template inline qsc_ellipsoid(Params const& , Parameters const& par) - : detail::qsc::base_qsc_ellipsoid(par) { - detail::qsc::setup_qsc(this->m_par, this->m_proj_parm); + detail::qsc::setup_qsc(par, this->m_proj_parm); } }; @@ -516,7 +509,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_qsc, qsc_ellipsoid, qsc_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_qsc, qsc_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(qsc_entry, qsc_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/robin.hpp b/include/boost/geometry/srs/projections/proj/robin.hpp index bf8a704ea..8de13e09f 100644 --- a/include/boost/geometry/srs/projections/proj/robin.hpp +++ b/include/boost/geometry/srs/projections/proj/robin.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -135,15 +135,9 @@ namespace projections return result; } - // template class, using CRTP to implement forward/inverse template struct base_robin_spheroid - : public base_t_fi, T, Parameters> { - inline base_robin_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - inline T v(coefs const& c, T const& z) const { return (c.c0 + z * (c.c1 + z * (c.c2 + z * c.c3))); } inline T dv(coefs const& c, T const& z) const @@ -151,7 +145,7 @@ namespace projections // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { int i; T dphi; @@ -169,7 +163,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); const coefs * coefs_x = robin::coefs_x(); @@ -251,10 +245,9 @@ namespace projections struct robin_spheroid : public detail::robin::base_robin_spheroid { template - inline robin_spheroid(Params const& , Parameters const& par) - : detail::robin::base_robin_spheroid(par) + inline robin_spheroid(Params const& , Parameters & par) { - detail::robin::setup_robin(this->m_par); + detail::robin::setup_robin(par); } }; @@ -263,7 +256,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_robin, robin_spheroid, robin_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_robin, robin_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(robin_entry, robin_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/rouss.hpp b/include/boost/geometry/srs/projections/proj/rouss.hpp index 01693c5a7..227dc194a 100644 --- a/include/boost/geometry/srs/projections/proj/rouss.hpp +++ b/include/boost/geometry/srs/projections/proj/rouss.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -67,20 +67,14 @@ namespace projections mdist en; }; - // template class, using CRTP to implement forward/inverse template struct base_rouss_ellipsoid - : public base_t_fi, T, Parameters> { par_rouss m_proj_parm; - inline base_rouss_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T s, al, cp, sp, al2, s2; @@ -88,20 +82,20 @@ namespace projections sp = sin(lp_lat); s = proj_mdist(lp_lat, sp, cp, this->m_proj_parm.en) - this->m_proj_parm.s0; s2 = s * s; - al = lp_lon * cp / sqrt(1. - this->m_par.es * sp * sp); + al = lp_lon * cp / sqrt(1. - par.es * sp * sp); al2 = al * al; - xy_x = this->m_par.k0 * al*(1.+s2*(this->m_proj_parm.A1+s2*this->m_proj_parm.A4)-al2*(this->m_proj_parm.A2+s*this->m_proj_parm.A3+s2*this->m_proj_parm.A5 + xy_x = par.k0 * al*(1.+s2*(this->m_proj_parm.A1+s2*this->m_proj_parm.A4)-al2*(this->m_proj_parm.A2+s*this->m_proj_parm.A3+s2*this->m_proj_parm.A5 +al2*this->m_proj_parm.A6)); - xy_y = this->m_par.k0 * (al2*(this->m_proj_parm.B1+al2*this->m_proj_parm.B4)+ + xy_y = par.k0 * (al2*(this->m_proj_parm.B1+al2*this->m_proj_parm.B4)+ s*(1.+al2*(this->m_proj_parm.B3-al2*this->m_proj_parm.B6)+s2*(this->m_proj_parm.B2+s2*this->m_proj_parm.B8)+ s*al2*(this->m_proj_parm.B5+s*this->m_proj_parm.B7))); } // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { - T s, al, x = xy_x / this->m_par.k0, y = xy_y / this->m_par.k0, x2, y2; + T s, al, x = xy_x / par.k0, y = xy_y / par.k0, x2, y2; x2 = x * x; y2 = y * y; @@ -112,7 +106,7 @@ namespace projections x2*(this->m_proj_parm.D4+y*(this->m_proj_parm.D6+y*this->m_proj_parm.D10)-x2*this->m_proj_parm.D9)); lp_lat=proj_inv_mdist(s, this->m_proj_parm.en); s = sin(lp_lat); - lp_lon=al * sqrt(1. - this->m_par.es * s * s)/cos(lp_lat); + lp_lon=al * sqrt(1. - par.es * s * s)/cos(lp_lat); } static inline std::string get_name() @@ -124,7 +118,7 @@ namespace projections // Roussilhe Stereographic template - inline void setup_rouss(Parameters& par, par_rouss& proj_parm) + inline void setup_rouss(Parameters const& par, par_rouss& proj_parm) { T N0, es2, t, t2, R_R0_2, R_R0_4; @@ -192,9 +186,8 @@ namespace projections { template inline rouss_ellipsoid(Params const& , Parameters const& par) - : detail::rouss::base_rouss_ellipsoid(par) { - detail::rouss::setup_rouss(this->m_par, this->m_proj_parm); + detail::rouss::setup_rouss(par, this->m_proj_parm); } }; @@ -203,7 +196,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_rouss, rouss_ellipsoid, rouss_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_rouss, rouss_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(rouss_entry, rouss_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/rpoly.hpp b/include/boost/geometry/srs/projections/proj/rpoly.hpp index fc59a0397..f0edd7b64 100644 --- a/include/boost/geometry/srs/projections/proj/rpoly.hpp +++ b/include/boost/geometry/srs/projections/proj/rpoly.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -66,20 +66,14 @@ namespace projections int mode; }; - // template class, using CRTP to implement forward/inverse template struct base_rpoly_spheroid - : public base_t_f, T, Parameters> { par_rpoly m_proj_parm; - inline base_rpoly_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T fa; @@ -89,11 +83,11 @@ namespace projections fa = 0.5 * lp_lon; if (fabs(lp_lat) < epsilon) { xy_x = fa + fa; - xy_y = - this->m_par.phi0; + xy_y = - par.phi0; } else { xy_y = 1. / tan(lp_lat); xy_x = sin(fa = 2. * atan(fa * sin(lp_lat))) * xy_y; - xy_y = lp_lat - this->m_par.phi0 + (1. - cos(fa)) * xy_y; + xy_y = lp_lat - par.phi0 + (1. - cos(fa)) * xy_y; } } @@ -139,10 +133,9 @@ namespace projections struct rpoly_spheroid : public detail::rpoly::base_rpoly_spheroid { template - inline rpoly_spheroid(Params const& params, Parameters const& par) - : detail::rpoly::base_rpoly_spheroid(par) + inline rpoly_spheroid(Params const& params, Parameters & par) { - detail::rpoly::setup_rpoly(params, this->m_par, this->m_proj_parm); + detail::rpoly::setup_rpoly(params, par, this->m_proj_parm); } }; @@ -151,7 +144,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_rpoly, rpoly_spheroid, rpoly_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_rpoly, rpoly_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(rpoly_entry, rpoly_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/sconics.hpp b/include/boost/geometry/srs/projections/proj/sconics.hpp index 44d606cab..465928cbd 100644 --- a/include/boost/geometry/srs/projections/proj/sconics.hpp +++ b/include/boost/geometry/srs/projections/proj/sconics.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -102,20 +102,14 @@ namespace projections return err; } - // template class, using CRTP to implement forward/inverse template struct base_sconics_spheroid - : public base_t_fi, T, Parameters> { par_sconics m_proj_parm; - inline base_sconics_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T rho; @@ -136,7 +130,7 @@ namespace projections // INVERSE(s_inverse) ellipsoid & spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { T rho; @@ -300,10 +294,9 @@ namespace projections struct tissot_spheroid : public detail::sconics::base_sconics_spheroid { template - inline tissot_spheroid(Params const& params, const Parameters& par) - : detail::sconics::base_sconics_spheroid(par) + inline tissot_spheroid(Params const& params, Parameters& par) { - detail::sconics::setup_tissot(params, this->m_par, this->m_proj_parm); + detail::sconics::setup_tissot(params, par, this->m_proj_parm); } }; @@ -326,10 +319,9 @@ namespace projections struct murd1_spheroid : public detail::sconics::base_sconics_spheroid { template - inline murd1_spheroid(Params const& params, const Parameters& par) - : detail::sconics::base_sconics_spheroid(par) + inline murd1_spheroid(Params const& params, Parameters& par) { - detail::sconics::setup_murd1(params, this->m_par, this->m_proj_parm); + detail::sconics::setup_murd1(params, par, this->m_proj_parm); } }; @@ -352,10 +344,9 @@ namespace projections struct murd2_spheroid : public detail::sconics::base_sconics_spheroid { template - inline murd2_spheroid(Params const& params, const Parameters& par) - : detail::sconics::base_sconics_spheroid(par) + inline murd2_spheroid(Params const& params, Parameters& par) { - detail::sconics::setup_murd2(params, this->m_par, this->m_proj_parm); + detail::sconics::setup_murd2(params, par, this->m_proj_parm); } }; @@ -378,10 +369,9 @@ namespace projections struct murd3_spheroid : public detail::sconics::base_sconics_spheroid { template - inline murd3_spheroid(Params const& params, const Parameters& par) - : detail::sconics::base_sconics_spheroid(par) + inline murd3_spheroid(Params const& params, Parameters& par) { - detail::sconics::setup_murd3(params, this->m_par, this->m_proj_parm); + detail::sconics::setup_murd3(params, par, this->m_proj_parm); } }; @@ -404,10 +394,9 @@ namespace projections struct euler_spheroid : public detail::sconics::base_sconics_spheroid { template - inline euler_spheroid(Params const& params, const Parameters& par) - : detail::sconics::base_sconics_spheroid(par) + inline euler_spheroid(Params const& params, Parameters& par) { - detail::sconics::setup_euler(params, this->m_par, this->m_proj_parm); + detail::sconics::setup_euler(params, par, this->m_proj_parm); } }; @@ -430,10 +419,9 @@ namespace projections struct pconic_spheroid : public detail::sconics::base_sconics_spheroid { template - inline pconic_spheroid(Params const& params, const Parameters& par) - : detail::sconics::base_sconics_spheroid(par) + inline pconic_spheroid(Params const& params, Parameters& par) { - detail::sconics::setup_pconic(params, this->m_par, this->m_proj_parm); + detail::sconics::setup_pconic(params, par, this->m_proj_parm); } }; @@ -456,10 +444,9 @@ namespace projections struct vitk1_spheroid : public detail::sconics::base_sconics_spheroid { template - inline vitk1_spheroid(Params const& params, const Parameters& par) - : detail::sconics::base_sconics_spheroid(par) + inline vitk1_spheroid(Params const& params, Parameters& par) { - detail::sconics::setup_vitk1(params, this->m_par, this->m_proj_parm); + detail::sconics::setup_vitk1(params, par, this->m_proj_parm); } }; @@ -468,13 +455,13 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_euler, euler_spheroid, euler_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_murd1, murd1_spheroid, murd1_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_murd2, murd2_spheroid, murd2_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_murd3, murd3_spheroid, murd3_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_pconic, pconic_spheroid, pconic_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_tissot, tissot_spheroid, tissot_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_vitk1, vitk1_spheroid, vitk1_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_euler, euler_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_murd1, murd1_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_murd2, murd2_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_murd3, murd3_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_pconic, pconic_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_tissot, tissot_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_vitk1, vitk1_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(euler_entry, euler_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/somerc.hpp b/include/boost/geometry/srs/projections/proj/somerc.hpp index e27ac3018..6c189726c 100644 --- a/include/boost/geometry/srs/projections/proj/somerc.hpp +++ b/include/boost/geometry/srs/projections/proj/somerc.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -65,27 +65,21 @@ namespace projections T K, c, hlf_e, kR, cosp0, sinp0; }; - // template class, using CRTP to implement forward/inverse template struct base_somerc_ellipsoid - : public base_t_fi, T, Parameters> { par_somerc m_proj_parm; - inline base_somerc_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T fourth_pi = detail::fourth_pi(); static const T half_pi = detail::half_pi(); T phip, lamp, phipp, lampp, sp, cp; - sp = this->m_par.e * sin(lp_lat); + sp = par.e * sin(lp_lat); phip = 2.* atan( exp( this->m_proj_parm.c * ( log(tan(fourth_pi + 0.5 * lp_lat)) - this->m_proj_parm.hlf_e * log((1. + sp)/(1. - sp))) + this->m_proj_parm.K)) - half_pi; @@ -99,7 +93,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid & spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T fourth_pi = detail::fourth_pi(); @@ -113,10 +107,10 @@ namespace projections lamp = aasin(cp * sin(lampp) / cos(phip)); con = (this->m_proj_parm.K - log(tan(fourth_pi + 0.5 * phip)))/this->m_proj_parm.c; for (i = n_iter; i ; --i) { - esp = this->m_par.e * sin(phip); + esp = par.e * sin(phip); delp = (con + log(tan(fourth_pi + 0.5 * phip)) - this->m_proj_parm.hlf_e * log((1. + esp)/(1. - esp)) ) * - (1. - esp * esp) * cos(phip) * this->m_par.rone_es; + (1. - esp * esp) * cos(phip) * par.rone_es; phip -= delp; if (fabs(delp) < epsilon) break; @@ -138,7 +132,7 @@ namespace projections // Swiss. Obl. Mercator template - inline void setup_somerc(Parameters& par, par_somerc& proj_parm) + inline void setup_somerc(Parameters const& par, par_somerc& proj_parm) { static const T fourth_pi = detail::fourth_pi(); @@ -178,9 +172,8 @@ namespace projections { template inline somerc_ellipsoid(Params const& , Parameters const& par) - : detail::somerc::base_somerc_ellipsoid(par) { - detail::somerc::setup_somerc(this->m_par, this->m_proj_parm); + detail::somerc::setup_somerc(par, this->m_proj_parm); } }; @@ -189,7 +182,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_somerc, somerc_ellipsoid, somerc_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_somerc, somerc_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(somerc_entry, somerc_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/stere.hpp b/include/boost/geometry/srs/projections/proj/stere.hpp index 7c2de3fcc..21b308bb2 100644 --- a/include/boost/geometry/srs/projections/proj/stere.hpp +++ b/include/boost/geometry/srs/projections/proj/stere.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -91,20 +91,14 @@ namespace projections math::pow((T(1) - sinphi) / (T(1) + sinphi), T(0.5) * eccen)); } - // template class, using CRTP to implement forward/inverse template struct base_stere_ellipsoid - : public base_t_fi, T, Parameters> { par_stere m_proj_parm; - inline base_stere_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); @@ -114,7 +108,7 @@ namespace projections sinlam = sin(lp_lon); sinphi = sin(lp_lat); if (this->m_proj_parm.mode == obliq || this->m_proj_parm.mode == equit) { - sinX = sin(X = 2. * atan(ssfn_(lp_lat, sinphi, this->m_par.e)) - half_pi); + sinX = sin(X = 2. * atan(ssfn_(lp_lat, sinphi, par.e)) - half_pi); cosX = cos(X); } switch (this->m_proj_parm.mode) { @@ -143,7 +137,7 @@ namespace projections sinphi = -sinphi; BOOST_FALLTHROUGH; case n_pole: - xy_x = this->m_proj_parm.akm1 * pj_tsfn(lp_lat, sinphi, this->m_par.e); + xy_x = this->m_proj_parm.akm1 * pj_tsfn(lp_lat, sinphi, par.e); xy_y = - xy_x * coslam; break; } @@ -153,7 +147,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); @@ -175,7 +169,7 @@ namespace projections xy_x *= sinphi; xy_y = rho * this->m_proj_parm.cosX1 * cosphi - xy_y * this->m_proj_parm.sinX1* sinphi; halfpi = half_pi; - halfe = .5 * this->m_par.e; + halfe = .5 * par.e; break; case n_pole: xy_y = -xy_y; @@ -183,11 +177,11 @@ namespace projections case s_pole: phi_l = half_pi - 2. * atan(tp = - rho / this->m_proj_parm.akm1); halfpi = -half_pi; - halfe = -.5 * this->m_par.e; + halfe = -.5 * par.e; break; } for (i = n_iter; i--; phi_l = lp_lat) { - sinphi = this->m_par.e * sin(phi_l); + sinphi = par.e * sin(phi_l); lp_lat = T(2) * atan(tp * math::pow((T(1)+sinphi)/(T(1)-sinphi), halfe)) - halfpi; if (fabs(phi_l - lp_lat) < conv_tolerance) { if (this->m_proj_parm.mode == s_pole) @@ -206,20 +200,14 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_stere_spheroid - : public base_t_fi, T, Parameters> { par_stere m_proj_parm; - inline base_stere_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { static const T fourth_pi = detail::fourth_pi(); static const T half_pi = detail::half_pi(); @@ -260,7 +248,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const { T c, rh, sinc, cosc; @@ -279,7 +267,7 @@ namespace projections break; case obliq: if (fabs(rh) <= epsilon10) - lp_lat = this->m_par.phi0; + lp_lat = par.phi0; else lp_lat = asin(cosc * this->m_proj_parm.sinX1 + xy_y * sinc * this->m_proj_parm.cosX1 / rh); if ((c = cosc - this->m_proj_parm.sinX1 * sin(lp_lat)) != 0. || xy_x != 0.) @@ -290,7 +278,7 @@ namespace projections BOOST_FALLTHROUGH; case s_pole: if (fabs(rh) <= epsilon10) - lp_lat = this->m_par.phi0; + lp_lat = par.phi0; else lp_lat = asin(this->m_proj_parm.mode == s_pole ? - cosc : cosc); lp_lon = (xy_x == 0. && xy_y == 0.) ? 0. : atan2(xy_x, xy_y); @@ -306,7 +294,7 @@ namespace projections }; template - inline void setup(Parameters& par, par_stere& proj_parm) /* general initialization */ + inline void setup(Parameters const& par, par_stere& proj_parm) /* general initialization */ { static const T fourth_pi = detail::fourth_pi(); static const T half_pi = detail::half_pi(); @@ -367,7 +355,7 @@ namespace projections // Stereographic template - inline void setup_stere(Params const& params, Parameters& par, par_stere& proj_parm) + inline void setup_stere(Params const& params, Parameters const& par, par_stere& proj_parm) { static const T half_pi = detail::half_pi(); @@ -419,10 +407,9 @@ namespace projections struct stere_ellipsoid : public detail::stere::base_stere_ellipsoid { template - inline stere_ellipsoid(Params const& params, const Parameters& par) - : detail::stere::base_stere_ellipsoid(par) + inline stere_ellipsoid(Params const& params, Parameters const& par) { - detail::stere::setup_stere(params, this->m_par, this->m_proj_parm); + detail::stere::setup_stere(params, par, this->m_proj_parm); } }; @@ -445,10 +432,9 @@ namespace projections struct stere_spheroid : public detail::stere::base_stere_spheroid { template - inline stere_spheroid(Params const& params, const Parameters& par) - : detail::stere::base_stere_spheroid(par) + inline stere_spheroid(Params const& params, Parameters const& par) { - detail::stere::setup_stere(params, this->m_par, this->m_proj_parm); + detail::stere::setup_stere(params, par, this->m_proj_parm); } }; @@ -471,10 +457,9 @@ namespace projections struct ups_ellipsoid : public detail::stere::base_stere_ellipsoid { template - inline ups_ellipsoid(Params const& params, const Parameters& par) - : detail::stere::base_stere_ellipsoid(par) + inline ups_ellipsoid(Params const& params, Parameters & par) { - detail::stere::setup_ups(params, this->m_par, this->m_proj_parm); + detail::stere::setup_ups(params, par, this->m_proj_parm); } }; @@ -497,10 +482,9 @@ namespace projections struct ups_spheroid : public detail::stere::base_stere_spheroid { template - inline ups_spheroid(Params const& params, const Parameters& par) - : detail::stere::base_stere_spheroid(par) + inline ups_spheroid(Params const& params, Parameters & par) { - detail::stere::setup_ups(params, this->m_par, this->m_proj_parm); + detail::stere::setup_ups(params, par, this->m_proj_parm); } }; @@ -509,8 +493,8 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_stere, stere_spheroid, stere_ellipsoid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_ups, ups_spheroid, ups_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_stere, stere_spheroid, stere_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_ups, ups_spheroid, ups_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(stere_entry, stere_spheroid, stere_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/sterea.hpp b/include/boost/geometry/srs/projections/proj/sterea.hpp index 514fb03a3..c1e6134bd 100644 --- a/include/boost/geometry/srs/projections/proj/sterea.hpp +++ b/include/boost/geometry/srs/projections/proj/sterea.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -69,20 +69,14 @@ namespace projections gauss en; }; - // template class, using CRTP to implement forward/inverse template struct base_sterea_ellipsoid - : public base_t_fi, T, Parameters> { par_sterea m_proj_parm; - inline base_sterea_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T lp_lon, T lp_lat, T& xy_x, T& xy_y) const { T cosc, sinc, cosl_, k; @@ -90,19 +84,19 @@ namespace projections sinc = sin(lp_lat); cosc = cos(lp_lat); cosl_ = cos(lp_lon); - k = this->m_par.k0 * this->m_proj_parm.R2 / (1. + this->m_proj_parm.sinc0 * sinc + this->m_proj_parm.cosc0 * cosc * cosl_); + k = par.k0 * this->m_proj_parm.R2 / (1. + this->m_proj_parm.sinc0 * sinc + this->m_proj_parm.cosc0 * cosc * cosl_); xy_x = k * cosc * sin(lp_lon); xy_y = k * (this->m_proj_parm.cosc0 * sinc - this->m_proj_parm.sinc0 * cosc * cosl_); } // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { T rho, c, sinc, cosc; - xy_x /= this->m_par.k0; - xy_y /= this->m_par.k0; + xy_x /= par.k0; + xy_y /= par.k0; if((rho = boost::math::hypot(xy_x, xy_y)) != 0.0) { c = 2. * atan2(rho, this->m_proj_parm.R2); sinc = sin(c); @@ -126,7 +120,7 @@ namespace projections // Oblique Stereographic Alternative template - inline void setup_sterea(Parameters& par, par_sterea& proj_parm) + inline void setup_sterea(Parameters const& par, par_sterea& proj_parm) { T R; @@ -157,9 +151,8 @@ namespace projections { template inline sterea_ellipsoid(Params const& , Parameters const& par) - : detail::sterea::base_sterea_ellipsoid(par) { - detail::sterea::setup_sterea(this->m_par, this->m_proj_parm); + detail::sterea::setup_sterea(par, this->m_proj_parm); } }; @@ -168,7 +161,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_sterea, sterea_ellipsoid, sterea_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_sterea, sterea_ellipsoid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(sterea_entry, sterea_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/sts.hpp b/include/boost/geometry/srs/projections/proj/sts.hpp index cdb73fbcc..deca4d001 100644 --- a/include/boost/geometry/srs/projections/proj/sts.hpp +++ b/include/boost/geometry/srs/projections/proj/sts.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -61,20 +61,14 @@ namespace projections bool tan_mode; }; - // template class, using CRTP to implement forward/inverse template struct base_sts_spheroid - : public base_t_fi, T, Parameters> { par_sts m_proj_parm; - inline base_sts_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { T c; @@ -93,7 +87,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const { T c; @@ -172,10 +166,9 @@ namespace projections struct kav5_spheroid : public detail::sts::base_sts_spheroid { template - inline kav5_spheroid(Params const& , Parameters const& par) - : detail::sts::base_sts_spheroid(par) + inline kav5_spheroid(Params const& , Parameters & par) { - detail::sts::setup_kav5(this->m_par, this->m_proj_parm); + detail::sts::setup_kav5(par, this->m_proj_parm); } }; @@ -195,10 +188,9 @@ namespace projections struct qua_aut_spheroid : public detail::sts::base_sts_spheroid { template - inline qua_aut_spheroid(Params const& , Parameters const& par) - : detail::sts::base_sts_spheroid(par) + inline qua_aut_spheroid(Params const& , Parameters & par) { - detail::sts::setup_qua_aut(this->m_par, this->m_proj_parm); + detail::sts::setup_qua_aut(par, this->m_proj_parm); } }; @@ -218,10 +210,9 @@ namespace projections struct mbt_s_spheroid : public detail::sts::base_sts_spheroid { template - inline mbt_s_spheroid(Params const& , Parameters const& par) - : detail::sts::base_sts_spheroid(par) + inline mbt_s_spheroid(Params const& , Parameters & par) { - detail::sts::setup_mbt_s(this->m_par, this->m_proj_parm); + detail::sts::setup_mbt_s(par, this->m_proj_parm); } }; @@ -241,10 +232,9 @@ namespace projections struct fouc_spheroid : public detail::sts::base_sts_spheroid { template - inline fouc_spheroid(Params const& , Parameters const& par) - : detail::sts::base_sts_spheroid(par) + inline fouc_spheroid(Params const& , Parameters & par) { - detail::sts::setup_fouc(this->m_par, this->m_proj_parm); + detail::sts::setup_fouc(par, this->m_proj_parm); } }; @@ -253,10 +243,10 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_kav5, kav5_spheroid, kav5_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_qua_aut, qua_aut_spheroid, qua_aut_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_mbt_s, mbt_s_spheroid, mbt_s_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_fouc, fouc_spheroid, fouc_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_kav5, kav5_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_qua_aut, qua_aut_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_mbt_s, mbt_s_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_fouc, fouc_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(kav5_entry, kav5_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/tcc.hpp b/include/boost/geometry/srs/projections/proj/tcc.hpp index 84c092bdf..8380d94b0 100644 --- a/include/boost/geometry/srs/projections/proj/tcc.hpp +++ b/include/boost/geometry/srs/projections/proj/tcc.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -56,18 +56,12 @@ namespace projections static const double epsilon10 = 1.e-10; - // template class, using CRTP to implement forward/inverse template struct base_tcc_spheroid - : public base_t_f, T, Parameters> { - inline base_tcc_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T b, bt; @@ -113,10 +107,9 @@ namespace projections struct tcc_spheroid : public detail::tcc::base_tcc_spheroid { template - inline tcc_spheroid(Params const& , Parameters const& par) - : detail::tcc::base_tcc_spheroid(par) + inline tcc_spheroid(Params const& , Parameters & par) { - detail::tcc::setup_tcc(this->m_par); + detail::tcc::setup_tcc(par); } }; @@ -125,7 +118,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_tcc, tcc_spheroid, tcc_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_tcc, tcc_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(tcc_entry, tcc_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/tcea.hpp b/include/boost/geometry/srs/projections/proj/tcea.hpp index 44a04f326..f442e010b 100644 --- a/include/boost/geometry/srs/projections/proj/tcea.hpp +++ b/include/boost/geometry/srs/projections/proj/tcea.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -53,31 +53,25 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace tcea { - // template class, using CRTP to implement forward/inverse template struct base_tcea_spheroid - : public base_t_fi, T, Parameters> { - inline base_tcea_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { - xy_x = cos(lp_lat) * sin(lp_lon) / this->m_par.k0; - xy_y = this->m_par.k0 * (atan2(tan(lp_lat), cos(lp_lon)) - this->m_par.phi0); + xy_x = cos(lp_lat) * sin(lp_lon) / par.k0; + xy_y = par.k0 * (atan2(tan(lp_lat), cos(lp_lon)) - par.phi0); } // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T xy_x, T xy_y, T& lp_lon, T& lp_lat) const { T t; - xy_y = xy_y / this->m_par.k0 + this->m_par.phi0; - xy_x *= this->m_par.k0; + xy_y = xy_y / par.k0 + par.phi0; + xy_x *= par.k0; t = sqrt(1. - xy_x * xy_x); lp_lat = asin(t * sin(xy_y)); lp_lon = atan2(xy_x, t * cos(xy_y)); @@ -116,10 +110,9 @@ namespace projections struct tcea_spheroid : public detail::tcea::base_tcea_spheroid { template - inline tcea_spheroid(Params const& , Parameters const& par) - : detail::tcea::base_tcea_spheroid(par) + inline tcea_spheroid(Params const& , Parameters & par) { - detail::tcea::setup_tcea(this->m_par); + detail::tcea::setup_tcea(par); } }; @@ -128,7 +121,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_tcea, tcea_spheroid, tcea_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_tcea, tcea_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(tcea_entry, tcea_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/tmerc.hpp b/include/boost/geometry/srs/projections/proj/tmerc.hpp index b8dc51cba..7c8ca6464 100644 --- a/include/boost/geometry/srs/projections/proj/tmerc.hpp +++ b/include/boost/geometry/srs/projections/proj/tmerc.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -86,20 +86,14 @@ namespace projections detail::en en; }; - // template class, using CRTP to implement forward/inverse template struct base_tmerc_ellipsoid - : public base_t_fi, T, Parameters> { par_tmerc m_proj_parm; - inline base_tmerc_ellipsoid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(e_forward) ellipse // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); static const T FC1 = tmerc::FC1(); @@ -134,14 +128,14 @@ namespace projections t *= t; al = cosphi * lp_lon; als = al * al; - al /= sqrt(1. - this->m_par.es * sinphi * sinphi); + al /= sqrt(1. - par.es * sinphi * sinphi); n = this->m_proj_parm.esp * cosphi * cosphi; - xy_x = this->m_par.k0 * al * (FC1 + + xy_x = par.k0 * al * (FC1 + FC3 * als * (1. - t + n + FC5 * als * (5. + t * (t - 18.) + n * (14. - 58. * t) + FC7 * als * (61. + t * ( t * (179. - t) - 479. ) ) ))); - xy_y = this->m_par.k0 * (pj_mlfn(lp_lat, sinphi, cosphi, this->m_proj_parm.en) - this->m_proj_parm.ml0 + + xy_y = par.k0 * (pj_mlfn(lp_lat, sinphi, cosphi, this->m_proj_parm.en) - this->m_proj_parm.ml0 + sinphi * al * lp_lon * FC2 * ( 1. + FC4 * als * (5. - t + n * (9. + 4. * n) + FC6 * als * (61. + t * (t - 58.) + n * (270. - 330 * t) @@ -151,7 +145,7 @@ namespace projections // INVERSE(e_inverse) ellipsoid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); static const T FC1 = tmerc::FC1(); @@ -165,7 +159,7 @@ namespace projections T n, con, cosphi, d, ds, sinphi, t; - lp_lat = pj_inv_mlfn(this->m_proj_parm.ml0 + xy_y / this->m_par.k0, this->m_par.es, this->m_proj_parm.en); + lp_lat = pj_inv_mlfn(this->m_proj_parm.ml0 + xy_y / par.k0, par.es, this->m_proj_parm.en); if (fabs(lp_lat) >= half_pi) { lp_lat = xy_y < 0. ? -half_pi : half_pi; lp_lon = 0.; @@ -174,11 +168,11 @@ namespace projections cosphi = cos(lp_lat); t = fabs(cosphi) > 1e-10 ? sinphi/cosphi : 0.; n = this->m_proj_parm.esp * cosphi * cosphi; - d = xy_x * sqrt(con = 1. - this->m_par.es * sinphi * sinphi) / this->m_par.k0; + d = xy_x * sqrt(con = 1. - par.es * sinphi * sinphi) / par.k0; con *= t; t *= t; ds = d * d; - lp_lat -= (con * ds / (1.-this->m_par.es)) * FC2 * (1. - + lp_lat -= (con * ds / (1.-par.es)) * FC2 * (1. - ds * FC4 * (5. + t * (3. - 9. * n) + n * (1. - 4 * n) - ds * FC6 * (61. + t * (90. - 252. * n + 45. * t) + 46. * n @@ -199,20 +193,14 @@ namespace projections }; - // template class, using CRTP to implement forward/inverse template struct base_tmerc_spheroid - : public base_t_fi, T, Parameters> { par_tmerc m_proj_parm; - inline base_tmerc_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& par, T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); @@ -251,22 +239,22 @@ namespace projections if (lp_lat < 0.) xy_y = -xy_y; - xy_y = this->m_proj_parm.esp * (xy_y - this->m_par.phi0); + xy_y = this->m_proj_parm.esp * (xy_y - par.phi0); } // INVERSE(s_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& par, T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { T h, g; h = exp(xy_x / this->m_proj_parm.esp); g = .5 * (h - 1. / h); - h = cos(this->m_par.phi0 + xy_y / this->m_proj_parm.esp); + h = cos(par.phi0 + xy_y / this->m_proj_parm.esp); lp_lat = asin(sqrt((1. - h * h) / (1. + g * g))); /* Make sure that phi is on the correct hemisphere when false northing is used */ - if (xy_y < 0. && -lp_lat+this->m_par.phi0 < 0.0) lp_lat = -lp_lat; + if (xy_y < 0. && -lp_lat+par.phi0 < 0.0) lp_lat = -lp_lat; lp_lon = (g != 0.0 || h != 0.0) ? atan2(g, h) : 0.; } @@ -279,7 +267,7 @@ namespace projections }; template - inline void setup(Parameters& par, par_tmerc& proj_parm) + inline void setup(Parameters const& par, par_tmerc& proj_parm) { if (par.es != 0.0) { proj_parm.en = pj_enfn(par.es); @@ -312,9 +300,8 @@ namespace projections { template inline tmerc_ellipsoid(Params const&, Parameters const& par) - : detail::tmerc::base_tmerc_ellipsoid(par) { - detail::tmerc::setup(this->m_par, this->m_proj_parm); + detail::tmerc::setup(par, this->m_proj_parm); } }; @@ -336,9 +323,8 @@ namespace projections { template inline tmerc_spheroid(Params const&, Parameters const& par) - : detail::tmerc::base_tmerc_spheroid(par) { - detail::tmerc::setup(this->m_par, this->m_proj_parm); + detail::tmerc::setup(par, this->m_proj_parm); } }; @@ -347,7 +333,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_tmerc, tmerc_spheroid, tmerc_ellipsoid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI2(srs::spar::proj_tmerc, tmerc_spheroid, tmerc_ellipsoid) // Factory entry(s) - dynamic projection BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI2(tmerc_entry, tmerc_spheroid, tmerc_ellipsoid) diff --git a/include/boost/geometry/srs/projections/proj/tpeqd.hpp b/include/boost/geometry/srs/projections/proj/tpeqd.hpp index 06f9cc0a0..4c059313e 100644 --- a/include/boost/geometry/srs/projections/proj/tpeqd.hpp +++ b/include/boost/geometry/srs/projections/proj/tpeqd.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -65,20 +65,14 @@ namespace projections T hz0, thz0, rhshz0, ca, sa, lp, lamc; }; - // template class, using CRTP to implement forward/inverse template struct base_tpeqd_spheroid - : public base_t_fi, T, Parameters> { par_tpeqd m_proj_parm; - inline base_tpeqd_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T t, z1, z2, dl1, dl2, sp, cp; @@ -98,7 +92,7 @@ namespace projections // INVERSE(s_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { T cz1, cz2, s, d, cp, sp; @@ -190,10 +184,9 @@ namespace projections struct tpeqd_spheroid : public detail::tpeqd::base_tpeqd_spheroid { template - inline tpeqd_spheroid(Params const& params, Parameters const& par) - : detail::tpeqd::base_tpeqd_spheroid(par) + inline tpeqd_spheroid(Params const& params, Parameters & par) { - detail::tpeqd::setup_tpeqd(params, this->m_par, this->m_proj_parm); + detail::tpeqd::setup_tpeqd(params, par, this->m_proj_parm); } }; @@ -202,7 +195,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_tpeqd, tpeqd_spheroid, tpeqd_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_tpeqd, tpeqd_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(tpeqd_entry, tpeqd_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/urm5.hpp b/include/boost/geometry/srs/projections/proj/urm5.hpp index b1682332a..b9914382e 100644 --- a/include/boost/geometry/srs/projections/proj/urm5.hpp +++ b/include/boost/geometry/srs/projections/proj/urm5.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -61,20 +61,14 @@ namespace projections T m, rmn, q3, n; }; - // template class, using CRTP to implement forward/inverse template struct base_urm5_spheroid - : public base_t_f, T, Parameters> { par_urm5 m_proj_parm; - inline base_urm5_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const&, T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { T t; @@ -136,10 +130,9 @@ namespace projections struct urm5_spheroid : public detail::urm5::base_urm5_spheroid { template - inline urm5_spheroid(Params const& params, Parameters const& par) - : detail::urm5::base_urm5_spheroid(par) + inline urm5_spheroid(Params const& params, Parameters & par) { - detail::urm5::setup_urm5(params, this->m_par, this->m_proj_parm); + detail::urm5::setup_urm5(params, par, this->m_proj_parm); } }; @@ -148,7 +141,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_urm5, urm5_spheroid, urm5_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_urm5, urm5_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(urm5_entry, urm5_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/urmfps.hpp b/include/boost/geometry/srs/projections/proj/urmfps.hpp index 8f608619a..a065b651f 100644 --- a/include/boost/geometry/srs/projections/proj/urmfps.hpp +++ b/include/boost/geometry/srs/projections/proj/urmfps.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -65,20 +65,14 @@ namespace projections T n, C_y; }; - // template class, using CRTP to implement forward/inverse template struct base_urmfps_spheroid - : public base_t_fi, T, Parameters> { par_urmfps m_proj_parm; - inline base_urmfps_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { lp_lat = aasin(this->m_proj_parm.n * sin(lp_lat)); xy_x = C_x * lp_lon * cos(lp_lat); @@ -87,7 +81,7 @@ namespace projections // INVERSE(s_inverse) sphere // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T xy_y, T& lp_lon, T& lp_lat) const { xy_y /= this->m_proj_parm.C_y; lp_lat = aasin(sin(xy_y) / this->m_proj_parm.n); @@ -151,10 +145,9 @@ namespace projections struct urmfps_spheroid : public detail::urmfps::base_urmfps_spheroid { template - inline urmfps_spheroid(Params const& params, Parameters const& par) - : detail::urmfps::base_urmfps_spheroid(par) + inline urmfps_spheroid(Params const& params, Parameters & par) { - detail::urmfps::setup_urmfps(params, this->m_par, this->m_proj_parm); + detail::urmfps::setup_urmfps(params, par, this->m_proj_parm); } }; @@ -174,10 +167,9 @@ namespace projections struct wag1_spheroid : public detail::urmfps::base_urmfps_spheroid { template - inline wag1_spheroid(Params const& , Parameters const& par) - : detail::urmfps::base_urmfps_spheroid(par) + inline wag1_spheroid(Params const& , Parameters & par) { - detail::urmfps::setup_wag1(this->m_par, this->m_proj_parm); + detail::urmfps::setup_wag1(par, this->m_proj_parm); } }; @@ -186,8 +178,8 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_urmfps, urmfps_spheroid, urmfps_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_wag1, wag1_spheroid, wag1_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_urmfps, urmfps_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_wag1, wag1_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(urmfps_entry, urmfps_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/vandg.hpp b/include/boost/geometry/srs/projections/proj/vandg.hpp index 08ca85a08..c34c500ab 100644 --- a/include/boost/geometry/srs/projections/proj/vandg.hpp +++ b/include/boost/geometry/srs/projections/proj/vandg.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017, 2018, Oracle and/or its affiliates. +// 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, @@ -67,18 +67,12 @@ namespace projections template inline T HPISQ() { return 4.9348022005446793094172454999381; } - // template class, using CRTP to implement forward/inverse template struct base_vandg_spheroid - : public base_t_fi, T, Parameters> { - inline base_vandg_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); static const T pi = detail::pi(); @@ -123,7 +117,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T half_pi = detail::half_pi(); static const T pi = detail::pi(); @@ -201,10 +195,9 @@ namespace projections struct vandg_spheroid : public detail::vandg::base_vandg_spheroid { template - inline vandg_spheroid(Params const& , Parameters const& par) - : detail::vandg::base_vandg_spheroid(par) + inline vandg_spheroid(Params const& , Parameters & par) { - detail::vandg::setup_vandg(this->m_par); + detail::vandg::setup_vandg(par); } }; @@ -213,7 +206,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_vandg, vandg_spheroid, vandg_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_vandg, vandg_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(vandg_entry, vandg_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/vandg2.hpp b/include/boost/geometry/srs/projections/proj/vandg2.hpp index dc9b45cde..3d5a7d5ce 100644 --- a/include/boost/geometry/srs/projections/proj/vandg2.hpp +++ b/include/boost/geometry/srs/projections/proj/vandg2.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -63,20 +63,14 @@ namespace projections bool vdg3; }; - // template class, using CRTP to implement forward/inverse template struct base_vandg2_spheroid - : public base_t_f, T, Parameters> { par_vandg2 m_proj_parm; - inline base_vandg2_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T pi = detail::pi(); static const T two_div_pi = detail::two_div_pi(); @@ -149,8 +143,7 @@ namespace projections struct vandg2_spheroid : public detail::vandg2::base_vandg2_spheroid { template - inline vandg2_spheroid(Params const& , Parameters const& par) - : detail::vandg2::base_vandg2_spheroid(par) + inline vandg2_spheroid(Params const& , Parameters const& ) { detail::vandg2::setup_vandg2(this->m_proj_parm); } @@ -173,10 +166,9 @@ namespace projections struct vandg3_spheroid : public detail::vandg2::base_vandg2_spheroid { template - inline vandg3_spheroid(Params const& , Parameters const& par) - : detail::vandg2::base_vandg2_spheroid(par) + inline vandg3_spheroid(Params const& , Parameters & par) { - detail::vandg2::setup_vandg3(this->m_par, this->m_proj_parm); + detail::vandg2::setup_vandg3(par, this->m_proj_parm); } }; @@ -185,8 +177,8 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_vandg2, vandg2_spheroid, vandg2_spheroid) - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_vandg3, vandg3_spheroid, vandg3_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_vandg2, vandg2_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_vandg3, vandg3_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(vandg2_entry, vandg2_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/vandg4.hpp b/include/boost/geometry/srs/projections/proj/vandg4.hpp index 4dce98a78..92cd6302b 100644 --- a/include/boost/geometry/srs/projections/proj/vandg4.hpp +++ b/include/boost/geometry/srs/projections/proj/vandg4.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -58,18 +58,12 @@ namespace projections static const double tolerance = 1e-10; - // template class, using CRTP to implement forward/inverse template struct base_vandg4_spheroid - : public base_t_f, T, Parameters> { - inline base_vandg4_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T half_pi = detail::half_pi(); static const T two_div_pi = detail::two_div_pi(); @@ -141,10 +135,9 @@ namespace projections struct vandg4_spheroid : public detail::vandg4::base_vandg4_spheroid { template - inline vandg4_spheroid(Params const& , Parameters const& par) - : detail::vandg4::base_vandg4_spheroid(par) + inline vandg4_spheroid(Params const& , Parameters & par) { - detail::vandg4::setup_vandg4(this->m_par); + detail::vandg4::setup_vandg4(par); } }; @@ -153,7 +146,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_vandg4, vandg4_spheroid, vandg4_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_vandg4, vandg4_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(vandg4_entry, vandg4_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/wag2.hpp b/include/boost/geometry/srs/projections/proj/wag2.hpp index 3c3c5ac12..78e7b0318 100644 --- a/include/boost/geometry/srs/projections/proj/wag2.hpp +++ b/include/boost/geometry/srs/projections/proj/wag2.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -60,18 +60,12 @@ namespace projections static const double C_p1 = 0.88022; static const double C_p2 = 0.88550; - // template class, using CRTP to implement forward/inverse template struct base_wag2_spheroid - : public base_t_fi, T, Parameters> { - inline base_wag2_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { lp_lat = aasin(C_p1 * sin(C_p2 * lp_lat)); xy_x = C_x * lp_lon * cos(lp_lat); @@ -80,7 +74,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = xy_y / C_y; lp_lon = xy_x / (C_x * cos(lp_lat)); @@ -120,10 +114,9 @@ namespace projections struct wag2_spheroid : public detail::wag2::base_wag2_spheroid { template - inline wag2_spheroid(Params const& , Parameters const& par) - : detail::wag2::base_wag2_spheroid(par) + inline wag2_spheroid(Params const& , Parameters & par) { - detail::wag2::setup_wag2(this->m_par); + detail::wag2::setup_wag2(par); } }; @@ -132,7 +125,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_wag2, wag2_spheroid, wag2_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_wag2, wag2_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(wag2_entry, wag2_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/wag3.hpp b/include/boost/geometry/srs/projections/proj/wag3.hpp index c69eca7b7..2c65eb591 100644 --- a/include/boost/geometry/srs/projections/proj/wag3.hpp +++ b/include/boost/geometry/srs/projections/proj/wag3.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -60,20 +60,14 @@ namespace projections T C_x; }; - // template class, using CRTP to implement forward/inverse template struct base_wag3_spheroid - : public base_t_fi, T, Parameters> { par_wag3 m_proj_parm; - inline base_wag3_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { static const T two_thirds = detail::two_thirds(); @@ -83,7 +77,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { static const T two_thirds = detail::two_thirds(); @@ -128,10 +122,9 @@ namespace projections struct wag3_spheroid : public detail::wag3::base_wag3_spheroid { template - inline wag3_spheroid(Params const& params, Parameters const& par) - : detail::wag3::base_wag3_spheroid(par) + inline wag3_spheroid(Params const& params, Parameters & par) { - detail::wag3::setup_wag3(params, this->m_par, this->m_proj_parm); + detail::wag3::setup_wag3(params, par, this->m_proj_parm); } }; @@ -140,7 +133,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_wag3, wag3_spheroid, wag3_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_wag3, wag3_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(wag3_entry, wag3_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/wag7.hpp b/include/boost/geometry/srs/projections/proj/wag7.hpp index 9e2f3a58b..f2fafb58a 100644 --- a/include/boost/geometry/srs/projections/proj/wag7.hpp +++ b/include/boost/geometry/srs/projections/proj/wag7.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -54,18 +54,12 @@ namespace projections namespace detail { namespace wag7 { - // template class, using CRTP to implement forward/inverse template struct base_wag7_spheroid - : public base_t_f, T, Parameters> { - inline base_wag7_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) - {} - // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { T theta, ct, D; @@ -109,10 +103,9 @@ namespace projections struct wag7_spheroid : public detail::wag7::base_wag7_spheroid { template - inline wag7_spheroid(Params const& , Parameters const& par) - : detail::wag7::base_wag7_spheroid(par) + inline wag7_spheroid(Params const& , Parameters & par) { - detail::wag7::setup_wag7(this->m_par); + detail::wag7::setup_wag7(par); } }; @@ -121,7 +114,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_wag7, wag7_spheroid, wag7_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_wag7, wag7_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(wag7_entry, wag7_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/wink1.hpp b/include/boost/geometry/srs/projections/proj/wink1.hpp index d05f9458f..c3c399848 100644 --- a/include/boost/geometry/srs/projections/proj/wink1.hpp +++ b/include/boost/geometry/srs/projections/proj/wink1.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -61,20 +61,14 @@ namespace projections T cosphi1; }; - // template class, using CRTP to implement forward/inverse template struct base_wink1_spheroid - : public base_t_fi, T, Parameters> { - par_wink1 m_proj_parm; - inline base_wink1_spheroid(const Parameters& par) - : base_t_fi, T, Parameters>(*this, par) {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T const& lp_lat, T& xy_x, T& xy_y) const { xy_x = .5 * lp_lon * (this->m_proj_parm.cosphi1 + cos(lp_lat)); xy_y = lp_lat; @@ -82,7 +76,7 @@ namespace projections // INVERSE(s_inverse) spheroid // Project coordinates from cartesian (x, y) to geographic (lon, lat) - inline void inv(T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const + inline void inv(Parameters const& , T const& xy_x, T const& xy_y, T& lp_lon, T& lp_lat) const { lp_lat = xy_y; lp_lon = 2. * xy_x / (this->m_proj_parm.cosphi1 + cos(lp_lat)); @@ -124,10 +118,9 @@ namespace projections struct wink1_spheroid : public detail::wink1::base_wink1_spheroid { template - inline wink1_spheroid(Params const& params, Parameters const& par) - : detail::wink1::base_wink1_spheroid(par) + inline wink1_spheroid(Params const& params, Parameters & par) { - detail::wink1::setup_wink1(params, this->m_par, this->m_proj_parm); + detail::wink1::setup_wink1(params, par, this->m_proj_parm); } }; @@ -136,7 +129,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_wink1, wink1_spheroid, wink1_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_FI(srs::spar::proj_wink1, wink1_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_FI(wink1_entry, wink1_spheroid) diff --git a/include/boost/geometry/srs/projections/proj/wink2.hpp b/include/boost/geometry/srs/projections/proj/wink2.hpp index 71bc147ab..a8d2bdb57 100644 --- a/include/boost/geometry/srs/projections/proj/wink2.hpp +++ b/include/boost/geometry/srs/projections/proj/wink2.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2008-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates. +// 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, @@ -66,20 +66,14 @@ namespace projections T cosphi1; }; - // template class, using CRTP to implement forward/inverse template struct base_wink2_spheroid - : public base_t_f, T, Parameters> { - par_wink2 m_proj_parm; - inline base_wink2_spheroid(const Parameters& par) - : base_t_f, T, Parameters>(*this, par) {} - // FORWARD(s_forward) spheroid // Project coordinates from geographic (lon, lat) to cartesian (x, y) - inline void fwd(T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const + inline void fwd(Parameters const& , T const& lp_lon, T lp_lat, T& xy_x, T& xy_y) const { static const T pi = detail::pi(); static const T half_pi = detail::half_pi(); @@ -143,10 +137,9 @@ namespace projections struct wink2_spheroid : public detail::wink2::base_wink2_spheroid { template - inline wink2_spheroid(Params const& params, Parameters const& par) - : detail::wink2::base_wink2_spheroid(par) + inline wink2_spheroid(Params const& params, Parameters & par) { - detail::wink2::setup_wink2(params, this->m_par, this->m_proj_parm); + detail::wink2::setup_wink2(params, par, this->m_proj_parm); } }; @@ -155,7 +148,7 @@ namespace projections { // Static projection - BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION(srs::spar::proj_wink2, wink2_spheroid, wink2_spheroid) + BOOST_GEOMETRY_PROJECTIONS_DETAIL_STATIC_PROJECTION_F(srs::spar::proj_wink2, wink2_spheroid) // Factory entry(s) BOOST_GEOMETRY_PROJECTIONS_DETAIL_FACTORY_ENTRY_F(wink2_entry, wink2_spheroid) From fdbc9086d7e2f99cc76cffac325e62ea203cfb50 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 16 Sep 2019 18:34:32 +0200 Subject: [PATCH 39/62] [test][srs] Update low level projections test WRT recent changes. --- test/srs/projections_static.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/srs/projections_static.cpp b/test/srs/projections_static.cpp index 98004fff0..86e243951 100644 --- a/test/srs/projections_static.cpp +++ b/test/srs/projections_static.cpp @@ -35,7 +35,11 @@ void test_forward(GeoPoint const& geo_point1, GeoPoint const& geo_point2, typedef typename bg::coordinate_type::type coordinate_type; typedef bg::model::d2::point_xy cartesian_point_type; typedef bg::projections::parameters parameters_type; - typedef Projection projection_type; + typedef bg::projections::detail::static_wrapper_f + < + Projection, + parameters_type + > projection_type; try { From 338e7c3247f904d5671ec40a72f7697bd992fe6d Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 16 Sep 2019 23:14:55 +0200 Subject: [PATCH 40/62] [srs] Decrease memory used by gn_sinu and igh projections by modifying parameters. --- .../geometry/srs/projections/proj/gn_sinu.hpp | 38 +++-- .../geometry/srs/projections/proj/goode.hpp | 3 + .../geometry/srs/projections/proj/igh.hpp | 161 +++++++++++------- 3 files changed, 124 insertions(+), 78 deletions(-) diff --git a/include/boost/geometry/srs/projections/proj/gn_sinu.hpp b/include/boost/geometry/srs/projections/proj/gn_sinu.hpp index ea7a8f95c..7e6903f9b 100644 --- a/include/boost/geometry/srs/projections/proj/gn_sinu.hpp +++ b/include/boost/geometry/srs/projections/proj/gn_sinu.hpp @@ -64,10 +64,15 @@ namespace projections static const double loop_tol = 1e-7; template - struct par_gn_sinu + struct par_gn_sinu_e { detail::en en; - T m, n, C_x, C_y; + }; + + template + struct par_gn_sinu_s + { + T m, n, C_x, C_y; }; /* Ellipsoidal Sinusoidal only */ @@ -75,7 +80,7 @@ namespace projections template struct base_gn_sinu_ellipsoid { - par_gn_sinu m_proj_parm; + par_gn_sinu_e m_proj_parm; // FORWARD(e_forward) ellipsoid // Project coordinates from geographic (lon, lat) to cartesian (x, y) @@ -115,7 +120,7 @@ namespace projections template struct base_gn_sinu_spheroid { - par_gn_sinu m_proj_parm; + par_gn_sinu_s m_proj_parm; // FORWARD(s_forward) sphere // Project coordinates from geographic (lon, lat) to cartesian (x, y) @@ -160,7 +165,7 @@ namespace projections }; template - inline void setup(Parameters& par, par_gn_sinu& proj_parm) + inline void setup(Parameters& par, par_gn_sinu_s& proj_parm) { par.es = 0; @@ -170,7 +175,7 @@ namespace projections // General Sinusoidal Series template - inline void setup_gn_sinu(Params const& params, Parameters& par, par_gn_sinu& proj_parm) + inline void setup_gn_sinu(Params const& params, Parameters& par, par_gn_sinu_s& proj_parm) { if (pj_param_f(params, "n", srs::dpar::n, proj_parm.n) && pj_param_f(params, "m", srs::dpar::m, proj_parm.m)) { @@ -184,22 +189,23 @@ namespace projections // Sinusoidal (Sanson-Flamsteed) template - inline void setup_sinu(Parameters& par, par_gn_sinu& proj_parm) + inline void setup_sinu(Parameters const& par, par_gn_sinu_e& proj_parm) { proj_parm.en = pj_enfn(par.es); + } - if (par.es != 0.0) { - /* empty */ - } else { - proj_parm.n = 1.; - proj_parm.m = 0.; - setup(par, proj_parm); - } + // Sinusoidal (Sanson-Flamsteed) + template + inline void setup_sinu(Parameters& par, par_gn_sinu_s& proj_parm) + { + proj_parm.n = 1.; + proj_parm.m = 0.; + setup(par, proj_parm); } // Eckert VI template - inline void setup_eck6(Parameters& par, par_gn_sinu& proj_parm) + inline void setup_eck6(Parameters& par, par_gn_sinu_s& proj_parm) { proj_parm.m = 1.; proj_parm.n = 2.570796326794896619231321691; @@ -208,7 +214,7 @@ namespace projections // McBryde-Thomas Flat-Polar Sinusoidal template - inline void setup_mbtfps(Parameters& par, par_gn_sinu& proj_parm) + inline void setup_mbtfps(Parameters& par, par_gn_sinu_s& proj_parm) { proj_parm.m = 0.5; proj_parm.n = 1.785398163397448309615660845; diff --git a/include/boost/geometry/srs/projections/proj/goode.hpp b/include/boost/geometry/srs/projections/proj/goode.hpp index 386fff1f7..f8dd87c37 100644 --- a/include/boost/geometry/srs/projections/proj/goode.hpp +++ b/include/boost/geometry/srs/projections/proj/goode.hpp @@ -59,6 +59,9 @@ namespace projections static const double Y_COR = 0.05280; static const double PHI_LIM = .71093078197902358062; + // TODO: It would be possible to further decrease the size of par_goode + // because spherical sinu and moll has constant parameters. + template struct par_goode { diff --git a/include/boost/geometry/srs/projections/proj/igh.hpp b/include/boost/geometry/srs/projections/proj/igh.hpp index fc2f3f305..385ac3031 100644 --- a/include/boost/geometry/srs/projections/proj/igh.hpp +++ b/include/boost/geometry/srs/projections/proj/igh.hpp @@ -40,9 +40,6 @@ #ifndef BOOST_GEOMETRY_PROJECTIONS_IGH_HPP #define BOOST_GEOMETRY_PROJECTIONS_IGH_HPP -#include -#include - #include #include #include @@ -50,6 +47,10 @@ #include #include +#include + +#include + namespace boost { namespace geometry { @@ -58,16 +59,69 @@ namespace projections #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace igh { - // TODO: consider replacing dynamically created projections - // with member objects - // NOTE: dynamic_wrapper_b holds copy of Parameters - // TODO: use only one copy of Parameters - // it is doable if zone-specific x0, y0 and lam0 are stored in par_igh + template + struct par_igh_zone + { + T x0; + T y0; + T lam0; + }; + + // NOTE: x0, y0, lam0 are not used in moll nor sinu projections + // so it is a waste of memory to keep 12 copies of projections + // with parameters as in the original Proj4. + + // TODO: It would be possible to further decrease the size of par_igh + // because spherical sinu and moll has constant parameters. + // TODO: Furthermore there is no need to store par_igh_zone parameters + // since they are constant for zones. In both fwd() and inv() there are + // parts of code dependent on specific zones (if statements) anyway + // so these parameters could be hardcoded there instead of stored. + template struct par_igh { - boost::shared_ptr > pj[12]; + moll_spheroid moll; + sinu_spheroid sinu; + par_igh_zone zones[12]; T dy0; + + // NOTE: The constructors of moll and sinu projections sets + // par.es = 0 + + template + inline par_igh(Params const& params, Parameters & par) + : moll(params, par) + , sinu(params, par) + {} + + inline void fwd(int zone, Parameters const& par, T const& lp_lon, T const& lp_lat, T & xy_x, T & xy_y) const + { + if (zone <= 2 || zone >= 9) // 1, 2, 9, 10, 11, 12 + moll.fwd(par, lp_lon, lp_lat, xy_x, xy_y); + else // 3, 4, 5, 6, 7, 8 + sinu.fwd(par, lp_lon, lp_lat, xy_x, xy_y); + } + + inline void inv(int zone, Parameters const& par, T const& xy_x, T const& xy_y, T & lp_lon, T & lp_lat) const + { + if (zone <= 2 || zone >= 9) // 1, 2, 9, 10, 11, 12 + moll.inv(par, xy_x, xy_y, lp_lon, lp_lat); + else // 3, 4, 5, 6, 7, 8 + sinu.inv(par, xy_x, xy_y, lp_lon, lp_lat); + } + + inline void set_zone(int zone, T const& x_0, T const& y_0, T const& lon_0) + { + zones[zone - 1].x0 = x_0; + zones[zone - 1].y0 = y_0; + zones[zone - 1].lam0 = lon_0; + } + + inline par_igh_zone const& get_zone(int zone) const + { + return zones[zone - 1]; + } }; /* 40d 44' 11.8" [degrees] */ @@ -101,33 +155,20 @@ namespace projections static const double epsilon = 1.e-10; // allow a little 'slack' on zone edge positions - // Converted from #define SETUP(n, proj, x_0, y_0, lon_0) - template