From 5d22d137b1be282bdc14c1d12ab8f669f58d41a6 Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Mon, 26 Oct 2020 12:44:18 -0400 Subject: Update Mercator projection Introduction ------------ The existing formulation for the Mercator projection is "satisfactory"; it is reasonably accurate. However for a core projection like Mercator, I think we should strive for full double precision accuracy. This commit uses cleaner, more accurate, and faster methods for computing the forward and inverse projections. These use the formulation in terms of hyperbolic functions that are manifestly odd in latitude psi = asinh(tan(phi)) - e * atanh(e * sin(phi)) (phi = latitude; psi = isometric latitude = Mercator y coordinate). Contrast this with the existing formulation psi = log(tan(pi/4 - phi/2)) - e/2 * log((1 + e * sin(phi)) / (1 - e * sin(phi))) where psi(-phi) isn't exactly equal to -psi(phi) and psi(0) isn't guaranteed to be 0. Implementation -------------- There's no particular issue implementing the forward projection, just apply the formulas above. The inverse projection is tricky because there's no closed form solution for the inverse. The existing code for the inverse uses an iterative method from Snyder. This is the usual hokey function iteration, and, as usual, the convergence rate is linear (error reduced by a constant factor on each iteration). This is OK (just) for low accuracy work. But nowadays, something with quadratic convergence (e.g., Newton's method, number of correct digits doubles on each iteration) is preferred (and used here). More on this later. The solution for phi(psi) I use is described in my TM paper and I lifted the specific formulation from GeographicLib's Math::tauf, which uses the same underlying machinery for all conformal projections. It solves for tan(phi) in terms of sinh(psi) which as a near identity mapping is ideal for Newton's method. For comparison I also look at the approach adopted by Poder + Engsager in their TM paper and implemented in etmerc. This uses trigonometric series (accurate to n^6) to convert phi <-> chi. psi is then given by psi = asinh(tan(chi)) Accuracy -------- I tested just the routines for transforming phi <-> psi from merc.cpp and measured the errors (converted to true nm = nanometers) for the forward and inverse mapping. I also included in my analysis the method used by etmerc. This uses a trigonometric series to convert phi <-> chi = atan(sinh(psi)), the conformal latitude. forward inverse max rms max rms old merc 3.60 0.85 2189.47 264.81 etmerc 1.82 0.38 1.42 0.37 new merc 1.83 0.30 2.12 0.31 1 nm is pretty much the absolute limit for accuracy in double precision (1 nm = 10e6 m / 2^53, approximately), and 5 nm is probably the limit on what you should routinely expect. So the old merc inverse is considerably less accurate that it could be. The old merc forward is OK on accuracy -- except that if does not preserve the parity of the projection. The accuracy of etmerc is fine (the truncation error of the 6th order series is small compared with the round-off error). However, situation reverses as the flattening is increased. E.g., at f = 1/150, the max error for the inverse projection is 8 nm. etmerc is OK for terrestrial applications, but couldn't be used for Mars. Timing ------ Here's what I get with g++ -O3 on various Linux machines with recent versions of g++. As always, you should take these with a grain of salt. You might expect the relative timings to vary by 20% or so when switching between compilers/machines. Times per call in ns = nanoseconds. forward inverse old merc 121 360 etmerc 4e-6 1.4 new merc 20 346 The new merc method is 6 times faster at the forward projection and modestly faster at the inverse projection (despite being more accurate). The latter result is because it only take 2 iterations of Newton's method to get full accuracy compared with an average of 5 iterations for the old method to get only um accuracy. A shocking aspect of these timings is how fast etmerc is. Another is that forward etmerc is streaks faster that inverse etmerc (it made be doubt my timing code). Evidently, asinh(tan(chi)) is a lot faster to compute than atan(sinh(psi)). The hesitation about adopting etmerc then comes down to: * the likelihood that Mercator may be used for non-terrestrial bodies; * the question of whether the timing benefits for the etmerc method would be noticeable in a realistic application; * need to duplicate the machinery for evaluating the coefficients for the series and for Clenshaw summation in the current code layout. Ripple effects ============== The Mercator routines used the the Snyder method, pj_tsfn and pj_phi2, are used in other projections. These relate phi to t = exp(-psi) (a rather bizarre choice in my book). I've retrofitted these to use the more accurate methods. These do the "right thing" for phi in [-pi/2, pi/2] , t in [0, inf], and e in [0, 1). NANs are properly handled. Of course, phi = pi/2 in double precision is actually less than pi/2, so cos(pi/2) > 0. So no special handling is needed for pi/2. Even if angles were handled in such a way that 90deg were exactly represented, these routines would still "work", with, e.g., tan(pi/2) -> inf. (A caution: with long doubles = a 64-bit fraction, we have cos(pi/2) < 0; and now we would need to be careful.) As a consequence, there no need for error handling in pj_tsfn; the HUGE_VAL return has gone and, of course, HUGE_VAL is a perfectly legal input to tsfn's inverse, phi2, which would return -pi/2. This "error handling" was only needed for e = 1, a case which is filtered out upstream. I will note that bad argument handling is much more natural using NAN instead of HUGE_VAL. See issue #2376 I've renamed the error condition for non-convergence of the inverse projection from "non-convergent inverse phi2" to "non-convergent sinh(psi) to tan(phi)". Now that pj_tsfn and pj_phi2 now return "better" results, there were some malfunctions in the projections that called them, specifically gstmerc, lcc, and tobmerc. * gstmerc invoked pj_tsfn(phi, sinphi, e) with a value of sinphi that wasn't equal to sin(phi). Disaster followed. I fixed this. I also replaced numerous occurrences of "-1.0 * x" by "-x". (Defining a function with arguments phi and sinphi is asking for trouble.) * lcc incorrectly thinks that the projection isn't defined for standard latitude = +/- 90d. This happens to be false (it reduces to polar stereographic in this limit). The check was whether tsfn(phi) = 0 (which only tested for the north pole not the south pole). However since tsfn(pi/2) now (correctly) returns a nonzero result, this test fails. I now just test for |phi| = pi/2. This is clearer and catches both poles (I'm assuming that the current implementation will probably fail in these cases). * tobmerc similarly thinks that phi close to +/- pi/2 can't be transformed even though psi(pi/2) is only 38. I'm disincline to fight this. However I did tighten up the failure condition (strict equality of |phi| == pi/2). OTHER STUFF =========== Testing ------- builtins.gei: I tightened up the tests for merc (and while I was about it etmerc and tmerc) to reflect full double precision accuracy. My test values are generated with MPFR enabled code and so should be accurate to all digits given. For the record, for GRS80 I use f = 1/298.2572221008827112431628366 in these calculations. pj_phi2_test: many of the tests were bogus testing irrelevant input parameters, like negative values of exp(-psi), and freezing in the arbitrary behavior of phi2. I've reworked most for the tests to be semi-useful. @schwehr can you review. Documentation ------------- I've updated merc.rst to outline the calculation of the inverse projection. phi2.cpp includes detailed notes about applying Newton's method to find tan(phi) in terms of sinh(psi). Future work ----------- lcc needs some tender loving care. It can easily (and should) be modified to allow stdlat = +/- 90 (reduces to polar stereographic), stdlat = 0 and stdlat_1 + stdlat_2 = 0 (reduces to Mercator). A little more elbow grease will allow the treatment of stdlat_1 close to stdlat_2 using divided differences. (See my implementation of the LambertConformalConic class in GeographicLib.) All the places where pj_tsfn and pj_phi2 are called need to be reworked to cut out the use of Snyder's t = exp(-psi() variable and instead use sinh(psi). Maybe include the machinery for series conversions between all auxiliary latitudes as "support functions". Then etmerc could use this (as could mlfn for computing meridional distance). merc could offer the etmerc style projection via chi as an option when the flattening is sufficiently small. --- src/phi2.cpp | 175 ++++++++++++++++++++++++++++++-------------- src/proj_internal.h | 3 +- src/projections/gstmerc.cpp | 18 ++--- src/projections/lcc.cpp | 10 +-- src/projections/merc.cpp | 26 +------ src/projections/tobmerc.cpp | 19 ++--- src/strerrno.cpp | 2 +- src/tsfn.cpp | 29 +++++--- 8 files changed, 168 insertions(+), 114 deletions(-) (limited to 'src') diff --git a/src/phi2.cpp b/src/phi2.cpp index b81456b0..eb6d5c82 100644 --- a/src/phi2.cpp +++ b/src/phi2.cpp @@ -1,6 +1,7 @@ /* Determine latitude angle phi-2. */ #include +#include #include "proj.h" #include "proj_internal.h" @@ -8,61 +9,125 @@ static const double TOL = 1.0e-10; static const int N_ITER = 15; +double pj_sinhpsi2tanphi(projCtx ctx, const double taup, const double e) { + /**************************************************************************** + * Convert tau' = sinh(psi) = tan(chi) to tau = tan(phi). The code is taken + * from GeographicLib::Math::tauf(taup, e). + * + * Here + * phi = geographic latitude (radians) + * psi is the isometric latitude + * psi = asinh(tan(phi)) - e * atanh(e * sin(phi)) + * = asinh(tan(chi)) + * chi is the conformal latitude + * + * The representation of latitudes via their tangents, tan(phi) and tan(chi), + * maintains full *relative* accuracy close to latitude = 0 and +/- pi/2. + * This is sometimes important, e.g., to compute the scale of the transverse + * Mercator projection which involves cos(phi)/cos(chi) tan(phi) + * + * From Karney (2011), Eq. 7, + * + * tau' = sinh(psi) = sinh(asinh(tan(phi)) - e * atanh(e * sin(phi))) + * = tan(phi) * cosh(e * atanh(e * sin(phi))) - + * sec(phi) * sinh(e * atanh(e * sin(phi))) + * = tau * sqrt(1 + sigma^2) - sqrt(1 + tau^2) * sigma + * where + * sigma = sinh(e * atanh( e * tau / sqrt(1 + tau^2) )) + * + * For e small, + * + * tau' = (1 - e^2) * tau + * + * The relation tau'(tau) can therefore by reliably inverted by Newton's + * method with + * + * tau = tau' / (1 - e^2) + * + * as an initial guess. Newton's method requires dtau'/dtau. Noting that + * + * dsigma/dtau = e^2 * sqrt(1 + sigma^2) / + * (sqrt(1 + tau^2) * (1 + (1 - e^2) * tau^2)) + * d(sqrt(1 + tau^2))/dtau = tau / sqrt(1 + tau^2) + * + * we have + * + * dtau'/dtau = (1 - e^2) * sqrt(1 + tau'^2) * sqrt(1 + tau^2) / + * (1 + (1 - e^2) * tau^2) + * + * This works fine unless tau^2 and tau'^2 overflows. This may be partially + * cured by writing, e.g., sqrt(1 + tau^2) as hypot(1, tau). However, nan + * will still be generated with tau' = inf, since (inf - inf) will appear in + * the Newton iteration. + * + * If we note that for sufficiently large |tau|, i.e., |tau| >= 2/sqrt(eps), + * sqrt(1 + tau^2) = |tau| and + * + * tau' = exp(- e * atanh(e)) * tau + * + * So + * + * tau = exp(e * atanh(e)) * tau' + * + * can be returned unless |tau| >= 2/sqrt(eps); this then avoids overflow + * problems for large tau' and returns the correct result for tau' = +/-inf + * and nan. + * + * Newton's method usually take 2 iterations to converge to double precision + * accuracy (for WGS84 flattening). However only 1 iteration is needed for + * |chi| < 3.35 deg. In addition, only 1 iteration is needed for |chi| > + * 89.18 deg (tau' > 70), if tau = exp(e * atanh(e)) * tau' is used as the + * starting guess. + ****************************************************************************/ + + constexpr int numit = 5; + // min iterations = 1, max iterations = 2; mean = 1.954 + constexpr double tol = sqrt(std::numeric_limits::epsilon()) / 10; + constexpr double tmax = 2 / sqrt(std::numeric_limits::epsilon()); + double + e2m = 1 - e * e, + tau = fabs(taup) > 70 ? taup * exp(e * atanh(e)) : taup / e2m, + stol = tol * std::max(1.0, fabs(taup)); + if (!(fabs(tau) < tmax)) return tau; // handles +/-inf and nan and e = 1 + // if (e2m < 0) return std::numeric_limits::quiet_NaN(); + int i = numit; + for (; i; --i) { + double tau1 = sqrt(1 + tau * tau), + sig = sinh( e * atanh(e * tau / tau1) ), + taupa = sqrt(1 + sig * sig) * tau - sig * tau1, + dtau = (taup - taupa) * (1 + e2m * tau * tau) / + ( e2m * sqrt(1 + tau * tau) * sqrt(1 + taupa * taupa) ); + tau += dtau; + if (!(fabs(dtau) >= stol)) + break; + } + if (i == 0) + pj_ctx_set_errno(ctx, PJD_ERR_NON_CONV_SINHPSI2TANPHI); + return tau; +} + /*****************************************************************************/ double pj_phi2(projCtx ctx, const double ts0, const double e) { -/****************************************************************************** -Determine latitude angle phi-2. -Inputs: - ts = exp(-psi) where psi is the isometric latitude (dimensionless) - e = eccentricity of the ellipsoid (dimensionless) -Output: - phi = geographic latitude (radians) -Here isometric latitude is defined by - psi = log( tan(pi/4 + phi/2) * - ( (1 - e*sin(phi)) / (1 + e*sin(phi)) )^(e/2) ) - = asinh(tan(phi)) - e * atanh(e * sin(phi)) -This routine inverts this relation using the iterative scheme given -by Snyder (1987), Eqs. (7-9) - (7-11) -*******************************************************************************/ - const double eccnth = .5 * e; - double ts = ts0; -#ifdef no_longer_used_original_convergence_on_exact_dphi - double Phi = M_HALFPI - 2. * atan(ts); -#endif - int i = N_ITER; - - for(;;) { - /* - * sin(Phi) = sin(PI/2 - 2* atan(ts)) - * = cos(2*atan(ts)) - * = 2*cos^2(atan(ts)) - 1 - * = 2 / (1 + ts^2) - 1 - * = (1 - ts^2) / (1 + ts^2) - */ - const double sinPhi = (1 - ts * ts) / (1 + ts * ts); - const double con = e * sinPhi; - double old_ts = ts; - ts = ts0 * pow((1. - con) / (1. + con), eccnth); -#ifdef no_longer_used_original_convergence_on_exact_dphi - /* The convergence criterion is nominally on exact dphi */ - const double newPhi = M_HALFPI - 2. * atan(ts); - const double dphi = newPhi - Phi; - Phi = newPhi; -#else - /* If we don't immediately update Phi from this, we can - * change the conversion criterion to save us computing atan() at each step. - * Particularly we can observe that: - * |atan(ts) - atan(old_ts)| <= |ts - old_ts| - * So if |ts - old_ts| matches our convergence criterion, we're good. - */ - const double dphi = 2 * (ts - old_ts); -#endif - if (fabs(dphi) > TOL && --i) { - continue; - } - break; - } - if (i <= 0) - pj_ctx_set_errno(ctx, PJD_ERR_NON_CON_INV_PHI2); - return M_HALFPI - 2. * atan(ts); + /**************************************************************************** + * Determine latitude angle phi-2. + * Inputs: + * ts = exp(-psi) where psi is the isometric latitude (dimensionless) + * e = eccentricity of the ellipsoid (dimensionless) + * Output: + * phi = geographic latitude (radians) + * Here isometric latitude is defined by + * psi = log( tan(pi/4 + phi/2) * + * ( (1 - e*sin(phi)) / (1 + e*sin(phi)) )^(e/2) ) + * = asinh(tan(phi)) - e * atanh(e * sin(phi)) + * + * OLD: This routine inverts this relation using the iterative scheme given + * by Snyder (1987), Eqs. (7-9) - (7-11). + * + * NEW: This routine writes converts t = exp(-psi) to + * + * tau' = sinh(psi) = (1/t - t)/2 + * + * returns atan(sinpsi2tanphi(tau')) + ***************************************************************************/ + return atan(pj_sinhpsi2tanphi(ctx, (1/ts0 - ts0) / 2, e)); } diff --git a/src/proj_internal.h b/src/proj_internal.h index 79b1da10..203765a3 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -626,7 +626,7 @@ struct FACTORS { #define PJD_ERR_INVALID_X_OR_Y -15 #define PJD_ERR_WRONG_FORMAT_DMS_VALUE -16 #define PJD_ERR_NON_CONV_INV_MERI_DIST -17 -#define PJD_ERR_NON_CON_INV_PHI2 -18 +#define PJD_ERR_NON_CONV_SINHPSI2TANPHI -18 #define PJD_ERR_ACOS_ASIN_ARG_TOO_LARGE -19 #define PJD_ERR_TOLERANCE_CONDITION -20 #define PJD_ERR_CONIC_LAT_EQUAL -21 @@ -846,6 +846,7 @@ double pj_qsfn(double, double, double); double pj_tsfn(double, double, double); double pj_msfn(double, double, double); double PROJ_DLL pj_phi2(projCtx_t *, const double, const double); +double pj_sinhpsi2tanphi(projCtx_t *, const double, const double); double pj_qsfn_(double, PJ *); double *pj_authset(double); double pj_authlat(double, double *); diff --git a/src/projections/gstmerc.cpp b/src/projections/gstmerc.cpp index 808d9ef7..50814bb5 100644 --- a/src/projections/gstmerc.cpp +++ b/src/projections/gstmerc.cpp @@ -28,9 +28,9 @@ static PJ_XY gstmerc_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forw double L, Ls, sinLs1, Ls1; L = Q->n1*lp.lam; - Ls = Q->c + Q->n1 * log(pj_tsfn(-1.0 * lp.phi, -1.0 * sin(lp.phi), P->e)); + Ls = Q->c + Q->n1 * log(pj_tsfn(-lp.phi, -sin(lp.phi), P->e)); sinLs1 = sin(L) / cosh(Ls); - Ls1 = log(pj_tsfn(-1.0 * asin(sinLs1), 0.0, 0.0)); + Ls1 = log(pj_tsfn(-asin(sinLs1), -sinLs1, 0.0)); xy.x = (Q->XS + Q->n2*Ls1) * P->ra; xy.y = (Q->YS + Q->n2*atan(sinh(Ls) / cos(L))) * P->ra; @@ -45,9 +45,9 @@ static PJ_LP gstmerc_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inve L = atan(sinh((xy.x * P->a - Q->XS) / Q->n2) / cos((xy.y * P->a - Q->YS) / Q->n2)); sinC = sin((xy.y * P->a - Q->YS) / Q->n2) / cosh((xy.x * P->a - Q->XS) / Q->n2); - LC = log(pj_tsfn(-1.0 * asin(sinC), 0.0, 0.0)); + LC = log(pj_tsfn(-asin(sinC), -sinC, 0.0)); lp.lam = L / Q->n1; - lp.phi = -1.0 * pj_phi2(P->ctx, exp((LC - Q->c) / Q->n1), P->e); + lp.phi = -pj_phi2(P->ctx, exp((LC - Q->c) / Q->n1), P->e); return lp; } @@ -60,13 +60,13 @@ PJ *PROJECTION(gstmerc) { P->opaque = Q; Q->lamc = P->lam0; - Q->n1 = sqrt(1.0 + P->es * pow(cos(P->phi0), 4.0) / (1.0 - P->es)); + Q->n1 = sqrt(1 + P->es * pow(cos(P->phi0), 4.0) / (1 - P->es)); Q->phic = asin(sin(P->phi0) / Q->n1); - Q->c = log(pj_tsfn(-1.0 * Q->phic, 0.0, 0.0)) - - Q->n1 * log(pj_tsfn(-1.0 * P->phi0, -1.0 * sin(P->phi0), P->e)); - Q->n2 = P->k0 * P->a * sqrt(1.0 - P->es) / (1.0 - P->es * sin(P->phi0) * sin(P->phi0)); + Q->c = log(pj_tsfn(-Q->phic, -sin(P->phi0) / Q->n1, 0.0)) + - Q->n1 * log(pj_tsfn(-P->phi0, -sin(P->phi0), P->e)); + Q->n2 = P->k0 * P->a * sqrt(1 - P->es) / (1 - P->es * sin(P->phi0) * sin(P->phi0)); Q->XS = 0; - Q->YS = -1.0 * Q->n2 * Q->phic; + Q->YS = -Q->n2 * Q->phic; P->inv = gstmerc_s_inverse; P->fwd = gstmerc_s_forward; diff --git a/src/projections/lcc.cpp b/src/projections/lcc.cpp index 91ffc511..b83b8072 100644 --- a/src/projections/lcc.cpp +++ b/src/projections/lcc.cpp @@ -106,10 +106,10 @@ PJ *PROJECTION(lcc) { double ml1, m1; m1 = pj_msfn(sinphi, cosphi, P->es); - ml1 = pj_tsfn(Q->phi1, sinphi, P->e); - if( ml1 == 0 ) { + if( abs(Q->phi1) == M_HALFPI ) { return pj_default_destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90); } + ml1 = pj_tsfn(Q->phi1, sinphi, P->e); if (secant) { /* secant cone */ sinphi = sin(Q->phi2); Q->n = log(m1 / pj_msfn(sinphi, cos(Q->phi2), P->es)); @@ -117,10 +117,10 @@ PJ *PROJECTION(lcc) { // Not quite, but es is very close to 1... return pj_default_destructor(P, PJD_ERR_INVALID_ECCENTRICITY); } - const double ml2 = pj_tsfn(Q->phi2, sinphi, P->e); - if( ml2 == 0 ) { - return pj_default_destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90); + if( abs(Q->phi2) == M_HALFPI ) { + return pj_default_destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90); } + const double ml2 = pj_tsfn(Q->phi2, sinphi, P->e); const double denom = log(ml1 / ml2); if( denom == 0 ) { // Not quite, but es is very close to 1... diff --git a/src/projections/merc.cpp b/src/projections/merc.cpp index a77d7517..472cb43f 100644 --- a/src/projections/merc.cpp +++ b/src/projections/merc.cpp @@ -10,45 +10,25 @@ PROJ_HEAD(merc, "Mercator") "\n\tCyl, Sph&Ell\n\tlat_ts="; PROJ_HEAD(webmerc, "Web Mercator / Pseudo Mercator") "\n\tCyl, Ell\n\t"; -#define EPS10 1.e-10 -static double logtanpfpim1(double x) { /* log(tan(x/2 + M_FORTPI)) */ - if (fabs(x) <= DBL_EPSILON) { - /* tan(M_FORTPI + .5 * x) can be approximated by 1.0 + x */ - return log1p(x); - } - return log(tan(M_FORTPI + .5 * x)); -} - static PJ_XY merc_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; - if (fabs(fabs(lp.phi) - M_HALFPI) <= EPS10) { - proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); - return xy; - } xy.x = P->k0 * lp.lam; - xy.y = - P->k0 * log(pj_tsfn(lp.phi, sin(lp.phi), P->e)); + xy.y = P->k0 * (asinh(tan(lp.phi)) - P->e * atanh(P->e * sin(lp.phi))); return xy; } static PJ_XY merc_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0,0.0}; - if (fabs(fabs(lp.phi) - M_HALFPI) <= EPS10) { - proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); - return xy; -} xy.x = P->k0 * lp.lam; - xy.y = P->k0 * logtanpfpim1(lp.phi); + xy.y = P->k0 * asinh(tan(lp.phi)); return xy; } static PJ_LP merc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse */ PJ_LP lp = {0.0,0.0}; - if ((lp.phi = pj_phi2(P->ctx, exp(- xy.y / P->k0), P->e)) == HUGE_VAL) { - proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); - return lp; -} + lp.phi = atan(pj_sinhpsi2tanphi(P->ctx, sinh(xy.y / P->k0), P->e)); lp.lam = xy.x / P->k0; return lp; } diff --git a/src/projections/tobmerc.cpp b/src/projections/tobmerc.cpp index a1616036..f05a9b6b 100644 --- a/src/projections/tobmerc.cpp +++ b/src/projections/tobmerc.cpp @@ -9,27 +9,24 @@ PROJ_HEAD(tobmerc, "Tobler-Mercator") "\n\tCyl, Sph"; -#define EPS10 1.e-10 -static double logtanpfpim1(double x) { /* log(tan(x/2 + M_FORTPI)) */ - if (fabs(x) <= DBL_EPSILON) { - /* tan(M_FORTPI + .5 * x) can be approximated by 1.0 + x */ - return log1p(x); - } - return log(tan(M_FORTPI + .5 * x)); -} - static PJ_XY tobmerc_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward */ PJ_XY xy = {0.0, 0.0}; double cosphi; - if (fabs(fabs(lp.phi) - M_HALFPI) <= EPS10) { + if (fabs(lp.phi) >= M_HALFPI) { + // builtins.gie tests "Test expected failure at the poles:". However + // given that M_HALFPI is strictly less than pi/2 in double precision, + // it's not clear why shouldn't just return a large result for xy.y (and + // it's not even that large, merely 38.025...). Even if the logic was + // such that phi was strictly equal to pi/2, allowing xy.y = inf would be + // a reasonable result. proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); return xy; } cosphi = cos(lp.phi); xy.x = P->k0 * lp.lam * cosphi * cosphi; - xy.y = P->k0 * logtanpfpim1(lp.phi); + xy.y = P->k0 * asinh(tan(lp.phi)); return xy; } diff --git a/src/strerrno.cpp b/src/strerrno.cpp index 5ae0d7e1..1c8673d0 100644 --- a/src/strerrno.cpp +++ b/src/strerrno.cpp @@ -27,7 +27,7 @@ pj_err_list[] = { "invalid x or y", /* -15 */ "improperly formed DMS value", /* -16 */ "non-convergent inverse meridional dist", /* -17 */ - "non-convergent inverse phi2", /* -18 */ + "non-convergent sinh(psi) to tan(phi)", /* -18 */ "acos/asin: |arg| >1.+1e-14", /* -19 */ "tolerance condition error", /* -20 */ "conic lat_1 = -lat_2", /* -21 */ diff --git a/src/tsfn.cpp b/src/tsfn.cpp index 32da09f2..fe8f29ed 100644 --- a/src/tsfn.cpp +++ b/src/tsfn.cpp @@ -4,14 +4,25 @@ #include "proj_internal.h" double pj_tsfn(double phi, double sinphi, double e) { - double denominator; - sinphi *= e; + /**************************************************************************** + * Determine function ts(phi) defined in Snyder (1987), Eq. (7-10) + * Inputs: + * phi = geographic latitude (radians) + * e = eccentricity of the ellipsoid (dimensionless) + * Output: + * ts = exp(-psi) where psi is the isometric latitude (dimensionless) + * Here isometric latitude is defined by + * psi = log( tan(pi/4 + phi/2) * + * ( (1 - e*sin(phi)) / (1 + e*sin(phi)) )^(e/2) ) + * = asinh(tan(phi)) - e * atanh(e * sin(phi)) + ***************************************************************************/ - /* avoid zero division, fail gracefully */ - denominator = 1.0 + sinphi; - if (denominator == 0.0) - return HUGE_VAL; - - return (tan (.5 * (M_HALFPI - phi)) / - pow((1. - sinphi) / (denominator), .5 * e)); + double cosphi = cos(phi); + // exp(-asinh(tan(phi))) = 1 / (tan(phi) + sec(phi)) + // = cos(phi) / (1 + sin(phi)) good for phi > 0 + // = (1 - sin(phi)) / cos(phi) good for phi < 0 + return exp(e * atanh(e * sinphi)) * + ( sinphi > 0 ? + cosphi / (1 + sinphi) : + (1 - sinphi) / cosphi ); } -- cgit v1.2.3 From b3a20c5b9c6efbeb0d6f528aad1d4e6bb4332bfa Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Mon, 26 Oct 2020 13:58:42 -0400 Subject: Try to fix compiler complaints for max and constexpr sqrt --- src/apps/gie.cpp | 2 +- src/phi2.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/apps/gie.cpp b/src/apps/gie.cpp index 8940afde..2fe854fa 100644 --- a/src/apps/gie.cpp +++ b/src/apps/gie.cpp @@ -1124,7 +1124,7 @@ static const struct errno_vs_err_const lookup[] = { {"pjd_err_invalid_x_or_y" , -15}, {"pjd_err_wrong_format_dms_value" , -16}, {"pjd_err_non_conv_inv_meri_dist" , -17}, - {"pjd_err_non_con_inv_phi2" , -18}, + {"pjd_err_non_conv_sinhpsi2tanphi" , -18}, {"pjd_err_acos_asin_arg_too_large" , -19}, {"pjd_err_tolerance_condition" , -20}, {"pjd_err_conic_lat_equal" , -21}, diff --git a/src/phi2.cpp b/src/phi2.cpp index eb6d5c82..6e810240 100644 --- a/src/phi2.cpp +++ b/src/phi2.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "proj.h" #include "proj_internal.h" @@ -82,8 +83,8 @@ double pj_sinhpsi2tanphi(projCtx ctx, const double taup, const double e) { constexpr int numit = 5; // min iterations = 1, max iterations = 2; mean = 1.954 - constexpr double tol = sqrt(std::numeric_limits::epsilon()) / 10; - constexpr double tmax = 2 / sqrt(std::numeric_limits::epsilon()); + static const double tol = sqrt(std::numeric_limits::epsilon()) / 10; + static const double tmax = 2 / sqrt(std::numeric_limits::epsilon()); double e2m = 1 - e * e, tau = fabs(taup) > 70 ? taup * exp(e * atanh(e)) : taup / e2m, -- cgit v1.2.3 From 1b484f853061e8577d95205f27e1ebbdbf80ec47 Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Mon, 26 Oct 2020 14:05:06 -0400 Subject: Address comments by @schwehr --- src/tsfn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tsfn.cpp b/src/tsfn.cpp index fe8f29ed..a0960a66 100644 --- a/src/tsfn.cpp +++ b/src/tsfn.cpp @@ -21,7 +21,7 @@ double pj_tsfn(double phi, double sinphi, double e) { // exp(-asinh(tan(phi))) = 1 / (tan(phi) + sec(phi)) // = cos(phi) / (1 + sin(phi)) good for phi > 0 // = (1 - sin(phi)) / cos(phi) good for phi < 0 - return exp(e * atanh(e * sinphi)) * + return exp(e * atanh(e * sinphi)) * ( sinphi > 0 ? cosphi / (1 + sinphi) : (1 - sinphi) / cosphi ); -- cgit v1.2.3 From 6c2363e88f8eb86e1331b3dc5f05897436ad9c43 Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Mon, 26 Oct 2020 14:57:52 -0400 Subject: phi2.cpp: remove unused static consts + minor code tweak --- src/phi2.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/src/phi2.cpp b/src/phi2.cpp index 6e810240..c60ca055 100644 --- a/src/phi2.cpp +++ b/src/phi2.cpp @@ -7,9 +7,6 @@ #include "proj.h" #include "proj_internal.h" -static const double TOL = 1.0e-10; -static const int N_ITER = 15; - double pj_sinhpsi2tanphi(projCtx ctx, const double taup, const double e) { /**************************************************************************** * Convert tau' = sinh(psi) = tan(chi) to tau = tan(phi). The code is taken @@ -97,7 +94,7 @@ double pj_sinhpsi2tanphi(projCtx ctx, const double taup, const double e) { sig = sinh( e * atanh(e * tau / tau1) ), taupa = sqrt(1 + sig * sig) * tau - sig * tau1, dtau = (taup - taupa) * (1 + e2m * tau * tau) / - ( e2m * sqrt(1 + tau * tau) * sqrt(1 + taupa * taupa) ); + ( e2m * tau1 * sqrt(1 + taupa * taupa) ); tau += dtau; if (!(fabs(dtau) >= stol)) break; -- cgit v1.2.3 From 1081e496a0fc7e45c6eb4703b0fc402bf2a9e945 Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Mon, 26 Oct 2020 16:06:19 -0400 Subject: lcc.cpp: fix abs -> fabs Also some corrected information... Timing UPDATED -------------- Sorry the previous timing data was wrong. Here are corrected values.. Here's what I get with g++ -O3 on two Linux machines with recent versions of g++. As always, you should take these with a grain of salt. Times per call in ns = nanoseconds. Fedora 31 Ubuntu 18 g++-9.3.1 g++-7.5.0 fwd inv fwd inv old merc 207 461 217 522 new merc 228 457 168 410 etmerc 212 196 174 147 The new forward method is the 10% slower (resp 20% faster) on Fedora 31 (resp Ubuntu 18). The new inverse method is the same speed (resp 20% faster) on Fedora 31 (resp Ubuntu 18). Roughly speaking the speed comparison is a wash. Maybe we should pay attention more to the Fedora 31 results since these are with a newer version of the compiler. I would still make the argument that a 20% time penalty (which in a full PROJ pipeline would probably be no more than a 5% penalty) would be a worthwhile price to pay for a more robust implementation of the projection. --- src/projections/lcc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/projections/lcc.cpp b/src/projections/lcc.cpp index b83b8072..46378ce4 100644 --- a/src/projections/lcc.cpp +++ b/src/projections/lcc.cpp @@ -106,7 +106,7 @@ PJ *PROJECTION(lcc) { double ml1, m1; m1 = pj_msfn(sinphi, cosphi, P->es); - if( abs(Q->phi1) == M_HALFPI ) { + if( fabs(Q->phi1) == M_HALFPI ) { return pj_default_destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90); } ml1 = pj_tsfn(Q->phi1, sinphi, P->e); @@ -117,7 +117,7 @@ PJ *PROJECTION(lcc) { // Not quite, but es is very close to 1... return pj_default_destructor(P, PJD_ERR_INVALID_ECCENTRICITY); } - if( abs(Q->phi2) == M_HALFPI ) { + if( fabs(Q->phi2) == M_HALFPI ) { return pj_default_destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90); } const double ml2 = pj_tsfn(Q->phi2, sinphi, P->e); -- cgit v1.2.3 From ee35d15db597801a86314dc8a47da7de10c9d8f2 Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Mon, 26 Oct 2020 17:50:51 -0400 Subject: phi2.cpp: Slight cosmetic changes to sinpsi2tanphi. --- src/phi2.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/phi2.cpp b/src/phi2.cpp index c60ca055..7bbb5679 100644 --- a/src/phi2.cpp +++ b/src/phi2.cpp @@ -80,23 +80,29 @@ double pj_sinhpsi2tanphi(projCtx ctx, const double taup, const double e) { constexpr int numit = 5; // min iterations = 1, max iterations = 2; mean = 1.954 - static const double tol = sqrt(std::numeric_limits::epsilon()) / 10; - static const double tmax = 2 / sqrt(std::numeric_limits::epsilon()); - double + static const double + rooteps = sqrt(std::numeric_limits::epsilon()), + tol = rooteps / 10, // the convergence criterion for Newton's method + tmax = 2 / rooteps; // the large arg limit is exact for tau > tmax + const double e2m = 1 - e * e, - tau = fabs(taup) > 70 ? taup * exp(e * atanh(e)) : taup / e2m, stol = tol * std::max(1.0, fabs(taup)); - if (!(fabs(tau) < tmax)) return tau; // handles +/-inf and nan and e = 1 + // The initial guess. 70 corresponds to chi = 89.18 deg (see above) + double tau = fabs(taup) > 70 ? taup * exp(e * atanh(e)) : taup / e2m; + if (!(fabs(tau) < tmax)) // handles +/-inf and nan and e = 1 + return tau; + // If we need to deal with e > 1, then we could include: // if (e2m < 0) return std::numeric_limits::quiet_NaN(); int i = numit; for (; i; --i) { - double tau1 = sqrt(1 + tau * tau), + double + tau1 = sqrt(1 + tau * tau), sig = sinh( e * atanh(e * tau / tau1) ), taupa = sqrt(1 + sig * sig) * tau - sig * tau1, - dtau = (taup - taupa) * (1 + e2m * tau * tau) / - ( e2m * tau1 * sqrt(1 + taupa * taupa) ); + dtau = ( (taup - taupa) * (1 + e2m * (tau * tau)) / + (e2m * tau1 * sqrt(1 + taupa * taupa)) ); tau += dtau; - if (!(fabs(dtau) >= stol)) + if (!(fabs(dtau) >= stol)) // backwards test to allow nans to succeed. break; } if (i == 0) -- cgit v1.2.3 From 75a8436b2491dbc1eebb196ea42b961fd011a52e Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Mon, 26 Oct 2020 18:29:19 -0400 Subject: Use sincos optimization in merc_e_forward. Revised timing data... Times per call in ns = nanoseconds. Fedora 31 Ubuntu 18 g++-9.3.1 g++-7.5.0 fwd inv fwd inv old merc 207 461 217 522 new merc 159 457 137 410 etmerc 212 196 174 147 The new forward method is now 25% faster (resp 35% faster) on Fedora 31 (resp Ubuntu 18). The new inverse method is the same speed (resp 20% faster) on Fedora 31 (resp Ubuntu 18). The accuracy is hardly affected: rms error increases from 0.30 nm to 0.33 nm, max error increases from 1.83 nm to 1.84 nm (a barely noticeable degradation). --- src/projections/merc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/merc.cpp b/src/projections/merc.cpp index 472cb43f..e5da3967 100644 --- a/src/projections/merc.cpp +++ b/src/projections/merc.cpp @@ -13,7 +13,8 @@ PROJ_HEAD(webmerc, "Web Mercator / Pseudo Mercator") "\n\tCyl, Ell\n\t"; static PJ_XY merc_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; xy.x = P->k0 * lp.lam; - xy.y = P->k0 * (asinh(tan(lp.phi)) - P->e * atanh(P->e * sin(lp.phi))); + double sphi = sin(lp.phi), cphi = cos(lp.phi); + xy.y = P->k0 * (asinh(sphi/cphi) - P->e * atanh(P->e * sphi)); return xy; } -- cgit v1.2.3 From 6bd7c777f8e789f8ea34a6aa68104ab44a31beee Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Mon, 26 Oct 2020 19:03:26 -0400 Subject: Fix/add some comments. --- src/phi2.cpp | 2 +- src/projections/merc.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/phi2.cpp b/src/phi2.cpp index 7bbb5679..b9b37765 100644 --- a/src/phi2.cpp +++ b/src/phi2.cpp @@ -127,7 +127,7 @@ double pj_phi2(projCtx ctx, const double ts0, const double e) { * OLD: This routine inverts this relation using the iterative scheme given * by Snyder (1987), Eqs. (7-9) - (7-11). * - * NEW: This routine writes converts t = exp(-psi) to + * NEW: This routine converts t = exp(-psi) to * * tau' = sinh(psi) = (1/t - t)/2 * diff --git a/src/projections/merc.cpp b/src/projections/merc.cpp index e5da3967..39685478 100644 --- a/src/projections/merc.cpp +++ b/src/projections/merc.cpp @@ -13,6 +13,8 @@ PROJ_HEAD(webmerc, "Web Mercator / Pseudo Mercator") "\n\tCyl, Ell\n\t"; static PJ_XY merc_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward */ PJ_XY xy = {0.0,0.0}; xy.x = P->k0 * lp.lam; + // Instead of calling tan and sin, call sin and cos which the compiler + // optimizes to a single call to sincos. double sphi = sin(lp.phi), cphi = cos(lp.phi); xy.y = P->k0 * (asinh(sphi/cphi) - P->e * atanh(P->e * sphi)); return xy; -- cgit v1.2.3 From 94e36270ca393bd7b107bf690f09fd8ec1cd046b Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Tue, 27 Oct 2020 10:02:27 -0400 Subject: Use nm units in builtins.gie. Remove backward looking comments in code. --- src/phi2.cpp | 10 +++++----- src/tsfn.cpp | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/phi2.cpp b/src/phi2.cpp index b9b37765..0fdca47c 100644 --- a/src/phi2.cpp +++ b/src/phi2.cpp @@ -116,6 +116,7 @@ double pj_phi2(projCtx ctx, const double ts0, const double e) { * Determine latitude angle phi-2. * Inputs: * ts = exp(-psi) where psi is the isometric latitude (dimensionless) + * this variable is defined in Snyder (1987), Eq. (7-10) * e = eccentricity of the ellipsoid (dimensionless) * Output: * phi = geographic latitude (radians) @@ -123,13 +124,12 @@ double pj_phi2(projCtx ctx, const double ts0, const double e) { * psi = log( tan(pi/4 + phi/2) * * ( (1 - e*sin(phi)) / (1 + e*sin(phi)) )^(e/2) ) * = asinh(tan(phi)) - e * atanh(e * sin(phi)) + * = asinh(tan(chi)) + * chi = conformal latitude * - * OLD: This routine inverts this relation using the iterative scheme given - * by Snyder (1987), Eqs. (7-9) - (7-11). + * This routine converts t = exp(-psi) to * - * NEW: This routine converts t = exp(-psi) to - * - * tau' = sinh(psi) = (1/t - t)/2 + * tau' = tan(chi) = sinh(psi) = (1/t - t)/2 * * returns atan(sinpsi2tanphi(tau')) ***************************************************************************/ diff --git a/src/tsfn.cpp b/src/tsfn.cpp index a0960a66..8ed258d6 100644 --- a/src/tsfn.cpp +++ b/src/tsfn.cpp @@ -11,10 +11,13 @@ double pj_tsfn(double phi, double sinphi, double e) { * e = eccentricity of the ellipsoid (dimensionless) * Output: * ts = exp(-psi) where psi is the isometric latitude (dimensionless) + * = 1 / (tan(chi) + sec(chi)) * Here isometric latitude is defined by * psi = log( tan(pi/4 + phi/2) * * ( (1 - e*sin(phi)) / (1 + e*sin(phi)) )^(e/2) ) * = asinh(tan(phi)) - e * atanh(e * sin(phi)) + * = asinh(tan(chi)) + * chi = conformal latitude ***************************************************************************/ double cosphi = cos(phi); -- cgit v1.2.3 From 692fc26b6d494aeaa85658314bc020a5cd6da7a1 Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Tue, 27 Oct 2020 16:44:43 -0400 Subject: merc.cpp + phi2.cpp: Avoid declaring multiple variables in 1 statement. --- src/phi2.cpp | 23 ++++++++++------------- src/projections/merc.cpp | 3 ++- 2 files changed, 12 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/phi2.cpp b/src/phi2.cpp index 0fdca47c..1c48d67f 100644 --- a/src/phi2.cpp +++ b/src/phi2.cpp @@ -80,13 +80,11 @@ double pj_sinhpsi2tanphi(projCtx ctx, const double taup, const double e) { constexpr int numit = 5; // min iterations = 1, max iterations = 2; mean = 1.954 - static const double - rooteps = sqrt(std::numeric_limits::epsilon()), - tol = rooteps / 10, // the convergence criterion for Newton's method - tmax = 2 / rooteps; // the large arg limit is exact for tau > tmax - const double - e2m = 1 - e * e, - stol = tol * std::max(1.0, fabs(taup)); + static const double rooteps = sqrt(std::numeric_limits::epsilon()); + static const double tol = rooteps / 10; // the criterion for Newton's method + static const double tmax = 2 / rooteps; // threshold for large arg limit exact + const double e2m = 1 - e * e; + const double stol = tol * std::max(1.0, fabs(taup)); // The initial guess. 70 corresponds to chi = 89.18 deg (see above) double tau = fabs(taup) > 70 ? taup * exp(e * atanh(e)) : taup / e2m; if (!(fabs(tau) < tmax)) // handles +/-inf and nan and e = 1 @@ -95,12 +93,11 @@ double pj_sinhpsi2tanphi(projCtx ctx, const double taup, const double e) { // if (e2m < 0) return std::numeric_limits::quiet_NaN(); int i = numit; for (; i; --i) { - double - tau1 = sqrt(1 + tau * tau), - sig = sinh( e * atanh(e * tau / tau1) ), - taupa = sqrt(1 + sig * sig) * tau - sig * tau1, - dtau = ( (taup - taupa) * (1 + e2m * (tau * tau)) / - (e2m * tau1 * sqrt(1 + taupa * taupa)) ); + double tau1 = sqrt(1 + tau * tau); + double sig = sinh( e * atanh(e * tau / tau1) ); + double taupa = sqrt(1 + sig * sig) * tau - sig * tau1; + double dtau = ( (taup - taupa) * (1 + e2m * (tau * tau)) / + (e2m * tau1 * sqrt(1 + taupa * taupa)) ); tau += dtau; if (!(fabs(dtau) >= stol)) // backwards test to allow nans to succeed. break; diff --git a/src/projections/merc.cpp b/src/projections/merc.cpp index 39685478..3a0ed7b4 100644 --- a/src/projections/merc.cpp +++ b/src/projections/merc.cpp @@ -15,7 +15,8 @@ static PJ_XY merc_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forward xy.x = P->k0 * lp.lam; // Instead of calling tan and sin, call sin and cos which the compiler // optimizes to a single call to sincos. - double sphi = sin(lp.phi), cphi = cos(lp.phi); + double sphi = sin(lp.phi); + double cphi = cos(lp.phi); xy.y = P->k0 * (asinh(sphi/cphi) - P->e * atanh(P->e * sphi)); return xy; } -- cgit v1.2.3 From c08da1a6604f9cb422bb71e34b6006ede6146642 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 31 Oct 2020 10:52:44 +0100 Subject: proj_create_ellipsoidal_2D/3D_cs(): doc improvement --- src/iso19111/c_api.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 7582f37f..f4f6e6a2 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -4438,8 +4438,9 @@ PJ *proj_create_cartesian_2D_cs(PJ_CONTEXT *ctx, PJ_CARTESIAN_CS_2D_TYPE type, * * @param ctx PROJ context, or NULL for default context * @param type Coordinate system type. - * @param unit_name Unit name. - * @param unit_conv_factor Unit conversion factor to SI. + * @param unit_name Name of the angular units. Or NULL for Degree + * @param unit_conv_factor Conversion factor from the angular unit to radian. + * Or 0 for Degree if unit_name == NULL. Otherwise should be not NULL * * @return Object that must be unreferenced with * proj_destroy(), or NULL in case of error. @@ -4478,13 +4479,17 @@ PJ *proj_create_ellipsoidal_2D_cs(PJ_CONTEXT *ctx, * * @param ctx PROJ context, or NULL for default context * @param type Coordinate system type. - * @param horizontal_angular_unit_name Horizontal angular unit name. - * @param horizontal_angular_unit_conv_factor Horizontal angular unit conversion - * factor to SI. - * @param vertical_linear_unit_name Vertical linear unit name. + * @param horizontal_angular_unit_name Name of the angular units. Or NULL for + * Degree. + * @param horizontal_angular_unit_conv_factor Conversion factor from the angular + * unit to radian. Or 0 for Degree if horizontal_angular_unit_name == NULL. + * Otherwise should be not NULL + * @param vertical_linear_unit_name Vertical linear unit name. Or NULL for + * Metre. * @param vertical_linear_unit_conv_factor Vertical linear unit conversion - * factor to SI. - * + * factor to metre. Or 0 for Metre if vertical_linear_unit_name == NULL. + * Otherwise should be not NULL + * @return Object that must be unreferenced with * proj_destroy(), or NULL in case of error. * @since 6.3 -- cgit v1.2.3 From baed8dae4980698873500dec16b158638df71318 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 31 Oct 2020 13:59:25 +0100 Subject: Make sure that remarks is preserved when substituting (EPSG) grid name by PROJ one --- src/iso19111/coordinateoperation.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index be15b3e0..599e04bd 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -8836,11 +8836,16 @@ createSimilarPropertiesTransformation(TransformationNNPtr obj) { // The domain(s) are unchanged addDomains(map, obj.get()); - std::string forwardName = obj->nameStr(); + const std::string &forwardName = obj->nameStr(); if (!forwardName.empty()) { map.set(common::IdentifiedObject::NAME_KEY, forwardName); } + const std::string &remarks = obj->remarks(); + if (!remarks.empty()) { + map.set(common::IdentifiedObject::REMARKS_KEY, remarks); + } + addModifiedIdentifier(map, obj.get(), false, true); return map; -- cgit v1.2.3 From 67718853e1248656cc35caa5a605ac102ec7e985 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 31 Oct 2020 15:47:52 +0100 Subject: Fill remarks for PROJ-based operation mixing horizontal and vertical transformations --- src/iso19111/coordinateoperation.cpp | 63 ++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 599e04bd..e9d73f52 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -12620,6 +12620,55 @@ createGeodToGeodPROJBased(const crs::CRSNNPtr &geodSrc, // --------------------------------------------------------------------------- +static std::string +getRemarks(const std::vector &ops) { + std::string remarks; + for (const auto &op : ops) { + const auto &opRemarks = op->remarks(); + if (!opRemarks.empty()) { + if (!remarks.empty()) { + remarks += '\n'; + } + + std::string opName(op->nameStr()); + if (starts_with(opName, INVERSE_OF)) { + opName = opName.substr(INVERSE_OF.size()); + } + + remarks += "For "; + remarks += opName; + + const auto &ids = op->identifiers(); + if (!ids.empty()) { + std::string authority(*ids.front()->codeSpace()); + if (starts_with(authority, "INVERSE(") && + authority.back() == ')') { + authority = authority.substr(strlen("INVERSE("), + authority.size() - 1 - + strlen("INVERSE(")); + } + if (starts_with(authority, "DERIVED_FROM(") && + authority.back() == ')') { + authority = authority.substr(strlen("DERIVED_FROM("), + authority.size() - 1 - + strlen("DERIVED_FROM(")); + } + + remarks += " ("; + remarks += authority; + remarks += ':'; + remarks += ids.front()->code(); + remarks += ')'; + } + remarks += ": "; + remarks += opRemarks; + } + } + return remarks; +} + +// --------------------------------------------------------------------------- + static CoordinateOperationNNPtr createHorizVerticalPROJBased( const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS, const operation::CoordinateOperationNNPtr &horizTransform, @@ -12645,6 +12694,10 @@ static CoordinateOperationNNPtr createHorizVerticalPROJBased( properties.set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY, NN_NO_CHECK(extent)); } + const auto &remarks = verticalTransform->remarks(); + if (!remarks.empty()) { + properties.set(common::IdentifiedObject::REMARKS_KEY, remarks); + } return createPROJBased( properties, exportable, sourceCRS, targetCRS, nullptr, verticalTransform->coordinateOperationAccuracies(), @@ -12669,6 +12722,11 @@ static CoordinateOperationNNPtr createHorizVerticalPROJBased( NN_NO_CHECK(extent)); } + const auto remarks = getRemarks(ops); + if (!remarks.empty()) { + properties.set(common::IdentifiedObject::REMARKS_KEY, remarks); + } + std::vector accuracies; const double accuracy = getAccuracy(ops); if (accuracy >= 0.0) { @@ -12729,6 +12787,11 @@ static CoordinateOperationNNPtr createHorizVerticalHorizPROJBased( NN_NO_CHECK(extent)); } + const auto remarks = getRemarks(ops); + if (!remarks.empty()) { + properties.set(common::IdentifiedObject::REMARKS_KEY, remarks); + } + std::vector accuracies; const double accuracy = getAccuracy(ops); if (accuracy >= 0.0) { -- cgit v1.2.3 From 6e7124c8b16dcc00e4a3f4336d1535f9655f1aa3 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 31 Oct 2020 15:53:15 +0100 Subject: Doxygen: improve doc of functions related to Datum/DatumEnsemble --- src/iso19111/c_api.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 7582f37f..f463dc2a 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -2049,6 +2049,8 @@ PJ *proj_get_ellipsoid(PJ_CONTEXT *ctx, const PJ *obj) { // --------------------------------------------------------------------------- /** \brief Get the horizontal datum from a CRS + * + * This function may return a Datum or DatumEnsemble object. * * The returned object must be unreferenced with proj_destroy() after * use. @@ -7986,6 +7988,9 @@ double proj_coordoperation_get_accuracy(PJ_CONTEXT *ctx, // --------------------------------------------------------------------------- /** \brief Returns the datum of a SingleCRS. + * + * If that function returns NULL, @see proj_crs_get_datum_ensemble() to + * potentially get a DatumEnsemble instead. * * The returned object must be unreferenced with proj_destroy() after * use. @@ -8017,6 +8022,9 @@ PJ *proj_crs_get_datum(PJ_CONTEXT *ctx, const PJ *crs) { // --------------------------------------------------------------------------- /** \brief Returns the datum ensemble of a SingleCRS. + * + * If that function returns NULL, @see proj_crs_get_datum() to + * potentially get a Datum instead. * * The returned object must be unreferenced with proj_destroy() after * use. -- cgit v1.2.3 From 82695cce869e1bcf2eb2a8ff078b679b6a21c663 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 8 Oct 2020 17:08:27 +0200 Subject: When reading from database, possibly return Geographic/GeodeticCRS with a DatumEnsemble, typically for WGS 84 and ETRS89 ('breaking change') --- src/iso19111/factory.cpp | 158 ++++++++++++++++++++++++++++++++++------------- src/iso19111/io.cpp | 4 ++ 2 files changed, 118 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 5d02aeea..cce80b8a 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -192,6 +192,13 @@ struct DatabaseContext::Private { void cache(const std::string &code, const datum::GeodeticReferenceFrameNNPtr &datum); + datum::DatumEnsemblePtr + // cppcheck-suppress functionStatic + getDatumEnsembleFromCache(const std::string &code); + // cppcheck-suppress functionStatic + void cache(const std::string &code, + const datum::DatumEnsembleNNPtr &datumEnsemble); + datum::EllipsoidPtr // cppcheck-suppress functionStatic getEllipsoidFromCache(const std::string &code); @@ -258,6 +265,7 @@ struct DatabaseContext::Private { LRUCacheOfObjects cacheCRS_{CACHE_SIZE}; LRUCacheOfObjects cacheEllipsoid_{CACHE_SIZE}; LRUCacheOfObjects cacheGeodeticDatum_{CACHE_SIZE}; + LRUCacheOfObjects cacheDatumEnsemble_{CACHE_SIZE}; LRUCacheOfObjects cachePrimeMeridian_{CACHE_SIZE}; LRUCacheOfObjects cacheCS_{CACHE_SIZE}; LRUCacheOfObjects cacheExtent_{CACHE_SIZE}; @@ -417,6 +425,22 @@ void DatabaseContext::Private::cache( // --------------------------------------------------------------------------- +datum::DatumEnsemblePtr +DatabaseContext::Private::getDatumEnsembleFromCache(const std::string &code) { + util::BaseObjectPtr obj; + getFromCache(cacheDatumEnsemble_, code, obj); + return std::static_pointer_cast(obj); +} + +// --------------------------------------------------------------------------- + +void DatabaseContext::Private::cache( + const std::string &code, const datum::DatumEnsembleNNPtr &datumEnsemble) { + insertIntoCache(cacheDatumEnsemble_, code, datumEnsemble.as_nullable()); +} + +// --------------------------------------------------------------------------- + datum::EllipsoidPtr DatabaseContext::Private::getEllipsoidFromCache(const std::string &code) { util::BaseObjectPtr obj; @@ -1064,18 +1088,6 @@ std::string DatabaseContext::getOldProjGridName(const std::string &gridName) { // --------------------------------------------------------------------------- -// FIXME: as we don't support datum ensemble yet, add it from name -static std::string removeEnsembleSuffix(const std::string &name) { - if (name == "World Geodetic System 1984 ensemble") { - return "World Geodetic System 1984"; - } else if (name == "European Terrestrial Reference System 1989 ensemble") { - return "European Terrestrial Reference System 1989"; - } - return name; -} - -// --------------------------------------------------------------------------- - /** \brief Gets the alias name from an official name. * * @param officialName Official name. Mandatory @@ -2012,18 +2024,38 @@ AuthorityFactory::createEllipsoid(const std::string &code) const { datum::GeodeticReferenceFrameNNPtr AuthorityFactory::createGeodeticDatum(const std::string &code) const { + + datum::GeodeticReferenceFramePtr datum; + datum::DatumEnsemblePtr datumEnsemble; + constexpr bool turnEnsembleAsDatum = true; + createGeodeticDatumOrEnsemble(code, datum, datumEnsemble, + turnEnsembleAsDatum); + return NN_NO_CHECK(datum); +} + +// --------------------------------------------------------------------------- + +void AuthorityFactory::createGeodeticDatumOrEnsemble( + const std::string &code, datum::GeodeticReferenceFramePtr &outDatum, + datum::DatumEnsemblePtr &outDatumEnsemble, bool turnEnsembleAsDatum) const { const auto cacheKey(d->authority() + code); { - auto datum = d->context()->d->getGeodeticDatumFromCache(cacheKey); - if (datum) { - return NN_NO_CHECK(datum); + outDatumEnsemble = d->context()->d->getDatumEnsembleFromCache(cacheKey); + if (outDatumEnsemble) { + if (!turnEnsembleAsDatum) + return; + outDatumEnsemble = nullptr; + } + outDatum = d->context()->d->getGeodeticDatumFromCache(cacheKey); + if (outDatum) { + return; } } auto res = d->runWithCodeParam("SELECT name, ellipsoid_auth_name, ellipsoid_code, " "prime_meridian_auth_name, prime_meridian_code, " "publication_date, frame_reference_epoch, " - "deprecated FROM geodetic_datum " + "ensemble_accuracy, deprecated FROM geodetic_datum " "WHERE " "auth_name = ? AND code = ?", code); @@ -2040,29 +2072,63 @@ AuthorityFactory::createGeodeticDatum(const std::string &code) const { const auto &prime_meridian_code = row[4]; const auto &publication_date = row[5]; const auto &frame_reference_epoch = row[6]; - const bool deprecated = row[7] == "1"; - auto ellipsoid = d->createFactory(ellipsoid_auth_name) - ->createEllipsoid(ellipsoid_code); - auto pm = d->createFactory(prime_meridian_auth_name) - ->createPrimeMeridian(prime_meridian_code); - auto props = d->createPropertiesSearchUsages( - "geodetic_datum", code, removeEnsembleSuffix(name), deprecated); - auto anchor = util::optional(); - if (!publication_date.empty()) { - props.set("PUBLICATION_DATE", publication_date); + const auto &ensemble_accuracy = row[7]; + const bool deprecated = row[8] == "1"; + + std::string massagedName = name; + if (turnEnsembleAsDatum) { + if (name == "World Geodetic System 1984 ensemble") { + massagedName = "World Geodetic System 1984"; + } else if (name == + "European Terrestrial Reference System 1989 ensemble") { + massagedName = "European Terrestrial Reference System 1989"; + } + } + auto props = d->createPropertiesSearchUsages("geodetic_datum", code, + massagedName, deprecated); + + if (!turnEnsembleAsDatum && !ensemble_accuracy.empty()) { + auto resMembers = + d->run("SELECT member_auth_name, member_code FROM " + "geodetic_datum_ensemble_member WHERE " + "ensemble_auth_name = ? AND ensemble_code = ? " + "ORDER BY sequence", + {d->authority(), code}); + + std::vector members; + for (const auto &memberRow : resMembers) { + members.push_back( + d->createFactory(memberRow[0])->createDatum(memberRow[1])); + } + auto datumEnsemble = datum::DatumEnsemble::create( + props, std::move(members), + metadata::PositionalAccuracy::create(ensemble_accuracy)); + d->context()->d->cache(cacheKey, datumEnsemble); + outDatumEnsemble = datumEnsemble.as_nullable(); + } else { + auto ellipsoid = d->createFactory(ellipsoid_auth_name) + ->createEllipsoid(ellipsoid_code); + auto pm = d->createFactory(prime_meridian_auth_name) + ->createPrimeMeridian(prime_meridian_code); + + auto anchor = util::optional(); + if (!publication_date.empty()) { + props.set("PUBLICATION_DATE", publication_date); + } + auto datum = frame_reference_epoch.empty() + ? datum::GeodeticReferenceFrame::create( + props, ellipsoid, anchor, pm) + : util::nn_static_pointer_cast< + datum::GeodeticReferenceFrame>( + datum::DynamicGeodeticReferenceFrame::create( + props, ellipsoid, anchor, pm, + common::Measure( + c_locale_stod(frame_reference_epoch), + common::UnitOfMeasure::YEAR), + util::optional())); + d->context()->d->cache(cacheKey, datum); + outDatum = datum.as_nullable(); } - auto datum = - frame_reference_epoch.empty() - ? datum::GeodeticReferenceFrame::create(props, ellipsoid, - anchor, pm) - : util::nn_static_pointer_cast( - datum::DynamicGeodeticReferenceFrame::create( - props, ellipsoid, anchor, pm, - common::Measure(c_locale_stod(frame_reference_epoch), - common::UnitOfMeasure::YEAR), - util::optional())); - d->context()->d->cache(cacheKey, datum); - return datum; } catch (const std::exception &ex) { throw buildFactoryException("geodetic reference frame", code, ex); } @@ -2472,20 +2538,24 @@ AuthorityFactory::createGeodeticCRS(const std::string &code, auto cs = d->createFactory(cs_auth_name)->createCoordinateSystem(cs_code); - auto datum = - d->createFactory(datum_auth_name)->createGeodeticDatum(datum_code); + datum::GeodeticReferenceFramePtr datum; + datum::DatumEnsemblePtr datumEnsemble; + constexpr bool turnEnsembleAsDatum = false; + d->createFactory(datum_auth_name) + ->createGeodeticDatumOrEnsemble(datum_code, datum, datumEnsemble, + turnEnsembleAsDatum); auto ellipsoidalCS = util::nn_dynamic_pointer_cast(cs); if ((type == GEOG_2D || type == GEOG_3D) && ellipsoidalCS) { auto crsRet = crs::GeographicCRS::create( - props, datum, NN_NO_CHECK(ellipsoidalCS)); + props, datum, datumEnsemble, NN_NO_CHECK(ellipsoidalCS)); d->context()->d->cache(cacheKey, crsRet); return crsRet; } auto geocentricCS = util::nn_dynamic_pointer_cast(cs); if (type == GEOCENTRIC && geocentricCS) { - auto crsRet = crs::GeodeticCRS::create(props, datum, + auto crsRet = crs::GeodeticCRS::create(props, datum, datumEnsemble, NN_NO_CHECK(geocentricCS)); d->context()->d->cache(cacheKey, crsRet); return crsRet; @@ -5617,7 +5687,7 @@ std::string AuthorityFactory::getOfficialNameFromAlias( if (res.empty()) { // shouldn't happen normally return std::string(); } - return removeEnsembleSuffix(res.front()[0]); + return res.front()[0]; } } return std::string(); @@ -5667,7 +5737,7 @@ std::string AuthorityFactory::getOfficialNameFromAlias( outTableName = row[1]; outAuthName = row[2]; outCode = row[3]; - return removeEnsembleSuffix(row[0]); + return row[0]; } } diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index f4ec7740..fde697ad 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -2110,6 +2110,10 @@ GeodeticReferenceFrameNNPtr WKTParser::Private::buildGeodeticReferenceFrame( name = "World Geodetic System 1984"; authNameFromAlias = Identifier::EPSG; codeFromAlias = "6326"; + } else if (name == "D_ETRS_1989") { + name = "European Terrestrial Reference System 1989"; + authNameFromAlias = Identifier::EPSG; + codeFromAlias = "6258"; } else { tableNameForAlias = "geodetic_datum"; } -- cgit v1.2.3 From c2b0dcc468b4e722e46fe10fca93fe70a95fcb8e Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 8 Oct 2020 18:41:57 +0200 Subject: When reading from database, possibly return VerticalCRS with a DatumEnsemble Only occurence for now is EPSG:9451 'BI height' using the 'British Isles height ensemble' --- src/iso19111/factory.cpp | 84 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index cce80b8a..301b88be 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -2146,9 +2146,23 @@ void AuthorityFactory::createGeodeticDatumOrEnsemble( datum::VerticalReferenceFrameNNPtr AuthorityFactory::createVerticalDatum(const std::string &code) const { + datum::VerticalReferenceFramePtr datum; + datum::DatumEnsemblePtr datumEnsemble; + constexpr bool turnEnsembleAsDatum = true; + createVerticalDatumOrEnsemble(code, datum, datumEnsemble, + turnEnsembleAsDatum); + return NN_NO_CHECK(datum); +} + +// --------------------------------------------------------------------------- + +void AuthorityFactory::createVerticalDatumOrEnsemble( + const std::string &code, datum::VerticalReferenceFramePtr &outDatum, + datum::DatumEnsemblePtr &outDatumEnsemble, bool turnEnsembleAsDatum) const { auto res = d->runWithCodeParam("SELECT name, publication_date, " - "frame_reference_epoch, deprecated FROM " + "frame_reference_epoch, ensemble_accuracy, " + "deprecated FROM " "vertical_datum WHERE auth_name = ? AND code = ?", code); if (res.empty()) { @@ -2160,24 +2174,49 @@ AuthorityFactory::createVerticalDatum(const std::string &code) const { const auto &name = row[0]; const auto &publication_date = row[1]; const auto &frame_reference_epoch = row[2]; - const bool deprecated = row[3] == "1"; + const auto &ensemble_accuracy = row[3]; + const bool deprecated = row[4] == "1"; auto props = d->createPropertiesSearchUsages("vertical_datum", code, name, deprecated); - if (!publication_date.empty()) { - props.set("PUBLICATION_DATE", publication_date); - } - if (d->authority() == "ESRI" && starts_with(code, "from_geogdatum_")) { - props.set("VERT_DATUM_TYPE", "2002"); - } - auto anchor = util::optional(); - if (frame_reference_epoch.empty()) { - return datum::VerticalReferenceFrame::create(props, anchor); + if (!turnEnsembleAsDatum && !ensemble_accuracy.empty()) { + auto resMembers = + d->run("SELECT member_auth_name, member_code FROM " + "vertical_datum_ensemble_member WHERE " + "ensemble_auth_name = ? AND ensemble_code = ? " + "ORDER BY sequence", + {d->authority(), code}); + + std::vector members; + for (const auto &memberRow : resMembers) { + members.push_back( + d->createFactory(memberRow[0])->createDatum(memberRow[1])); + } + auto datumEnsemble = datum::DatumEnsemble::create( + props, std::move(members), + metadata::PositionalAccuracy::create(ensemble_accuracy)); + outDatumEnsemble = datumEnsemble.as_nullable(); } else { - return datum::DynamicVerticalReferenceFrame::create( - props, anchor, util::optional(), - common::Measure(c_locale_stod(frame_reference_epoch), - common::UnitOfMeasure::YEAR), - util::optional()); + if (!publication_date.empty()) { + props.set("PUBLICATION_DATE", publication_date); + } + if (d->authority() == "ESRI" && + starts_with(code, "from_geogdatum_")) { + props.set("VERT_DATUM_TYPE", "2002"); + } + auto anchor = util::optional(); + if (frame_reference_epoch.empty()) { + outDatum = datum::VerticalReferenceFrame::create(props, anchor) + .as_nullable(); + } else { + outDatum = + datum::DynamicVerticalReferenceFrame::create( + props, anchor, + util::optional(), + common::Measure(c_locale_stod(frame_reference_epoch), + common::UnitOfMeasure::YEAR), + util::optional()) + .as_nullable(); + } } } catch (const std::exception &ex) { throw buildFactoryException("vertical reference frame", code, ex); @@ -2609,16 +2648,19 @@ AuthorityFactory::createVerticalCRS(const std::string &code) const { const bool deprecated = row[5] == "1"; auto cs = d->createFactory(cs_auth_name)->createCoordinateSystem(cs_code); - auto datum = - d->createFactory(datum_auth_name)->createVerticalDatum(datum_code); - + datum::VerticalReferenceFramePtr datum; + datum::DatumEnsemblePtr datumEnsemble; + constexpr bool turnEnsembleAsDatum = false; + d->createFactory(datum_auth_name) + ->createVerticalDatumOrEnsemble(datum_code, datum, datumEnsemble, + turnEnsembleAsDatum); auto props = d->createPropertiesSearchUsages("vertical_crs", code, name, deprecated); auto verticalCS = util::nn_dynamic_pointer_cast(cs); if (verticalCS) { - auto crsRet = - crs::VerticalCRS::create(props, datum, NN_NO_CHECK(verticalCS)); + auto crsRet = crs::VerticalCRS::create(props, datum, datumEnsemble, + NN_NO_CHECK(verticalCS)); d->context()->d->cache(cacheKey, crsRet); return crsRet; } -- cgit v1.2.3 From 1e5acb00a0c0fc2533b9bce2e5803da10ed1d8d6 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 8 Oct 2020 20:59:19 +0200 Subject: projinfo / createObjectsFromName(): support returning a datum ensemble --- src/apps/projinfo.cpp | 18 +++++++++++------ src/iso19111/c_api.cpp | 2 +- src/iso19111/datum.cpp | 8 ++++++++ src/iso19111/factory.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++- src/iso19111/io.cpp | 5 +++++ 5 files changed, 76 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 37b76346..6ee5925a 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -79,7 +79,8 @@ struct OutputOptions { static void usage() { std::cerr - << "usage: projinfo [-o formats] [-k crs|operation|datum|ellipsoid] " + << "usage: projinfo [-o formats] " + "[-k crs|operation|datum|ensemble|ellipsoid] " "[--summary] [-q]" << std::endl << " ([--area name_or_code] | " @@ -184,11 +185,11 @@ static BaseObjectNNPtr buildObject( auto urn = "urn:ogc:def:coordinateOperation:" + tokens[0] + "::" + tokens[1]; obj = createFromUserInput(urn, dbContext).as_nullable(); - } else if (kind == "ellipsoid" && tokens.size() == 2) { - auto urn = "urn:ogc:def:ellipsoid:" + tokens[0] + "::" + tokens[1]; - obj = createFromUserInput(urn, dbContext).as_nullable(); - } else if (kind == "datum" && tokens.size() == 2) { - auto urn = "urn:ogc:def:datum:" + tokens[0] + "::" + tokens[1]; + } else if ((kind == "ellipsoid" || kind == "datum" || + kind == "ensemble") && + tokens.size() == 2) { + auto urn = + "urn:ogc:def:" + kind + ":" + tokens[0] + "::" + tokens[1]; obj = createFromUserInput(urn, dbContext).as_nullable(); } else { // Convenience to be able to use C escaped strings... @@ -222,6 +223,9 @@ static BaseObjectNNPtr buildObject( AuthorityFactory::ObjectType::ELLIPSOID); else if (kind == "datum") allowedTypes.push_back(AuthorityFactory::ObjectType::DATUM); + else if (kind == "ensemble") + allowedTypes.push_back( + AuthorityFactory::ObjectType::DATUM_ENSEMBLE); constexpr size_t limitResultCount = 10; auto factory = AuthorityFactory::create(NN_NO_CHECK(dbContext), std::string()); @@ -929,6 +933,8 @@ int main(int argc, char **argv) { objectKind = "ellipsoid"; } else if (ci_equal(kind, "datum")) { objectKind = "datum"; + } else if (ci_equal(kind, "ensemble")) { + objectKind = "ensemble"; } else { std::cerr << "Unrecognized value for option -k: " << kind << std::endl; diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 90a414c6..4fb73d31 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -916,7 +916,7 @@ convertPJObjectTypeToObjectType(PJ_TYPE type, bool &valid) { break; case PJ_TYPE_DATUM_ENSEMBLE: - cppType = AuthorityFactory::ObjectType::DATUM; + cppType = AuthorityFactory::ObjectType::DATUM_ENSEMBLE; break; case PJ_TYPE_TEMPORAL_DATUM: diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 5bc8074c..e29f6319 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -1731,6 +1731,14 @@ void DatumEnsemble::_exportToWKT( formatter->startNode(io::WKTConstants::ENSEMBLEACCURACY, false); formatter->add(positionalAccuracy()->value()); formatter->endNode(); + + // In theory, we should do the following, but currently the WKT grammar + // doesn't allow this + // ObjectUsage::baseExportToWKT(formatter); + if (formatter->outputId()) { + formatID(formatter); + } + formatter->endNode(); } //! @endcond diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 301b88be..0ccfefc1 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -5452,6 +5452,11 @@ AuthorityFactory::getAuthorityCodes(const ObjectType &type, case ObjectType::CONCATENATED_OPERATION: sql = "SELECT code FROM concatenated_operation WHERE "; break; + case ObjectType::DATUM_ENSEMBLE: + sql = "SELECT code FROM object_view WHERE table_name IN " + "('geodetic_datum', 'vertical_datum') AND " + "type = 'ensemble' AND "; + break; } sql += "auth_name = ?"; @@ -5961,12 +5966,28 @@ AuthorityFactory::createObjectsFromNameEx( res.emplace_back( TableType("concatenated_operation", std::string())); break; + case ObjectType::DATUM_ENSEMBLE: + res.emplace_back(TableType("geodetic_datum", "ensemble")); + res.emplace_back(TableType("vertical_datum", "ensemble")); + break; } } } return res; }; + bool datumEnsembleAllowed = false; + if (allowedObjectTypes.empty()) { + datumEnsembleAllowed = true; + } else { + for (const auto type : allowedObjectTypes) { + if (type == ObjectType::DATUM_ENSEMBLE) { + datumEnsembleAllowed = true; + break; + } + } + } + const auto listTableNameType = getTableAndTypeConstraints(); bool first = true; ListOfParams params; @@ -5984,6 +6005,8 @@ AuthorityFactory::createObjectsFromNameEx( if (!tableNameTypePair.second.empty()) { if (tableNameTypePair.second == "frame_reference_epoch") { sql += "AND frame_reference_epoch IS NOT NULL "; + } else if (tableNameTypePair.second == "ensemble") { + sql += "AND ensemble_accuracy IS NOT NULL "; } else { sql += "AND type = '"; sql += tableNameTypePair.second; @@ -6018,6 +6041,8 @@ AuthorityFactory::createObjectsFromNameEx( if (!tableNameTypePair.second.empty()) { if (tableNameTypePair.second == "frame_reference_epoch") { sql += "AND ov.frame_reference_epoch IS NOT NULL "; + } else if (tableNameTypePair.second == "ensemble") { + sql += "AND ov.ensemble_accuracy IS NOT NULL "; } else { sql += "AND ov.type = '"; sql += tableNameTypePair.second; @@ -6165,7 +6190,7 @@ AuthorityFactory::createObjectsFromNameEx( break; } auto factory = d->createFactory(auth_name); - auto getObject = [&factory]( + auto getObject = [&factory, datumEnsembleAllowed]( const std::string &l_table_name, const std::string &l_code) -> common::IdentifiedObjectNNPtr { if (l_table_name == "prime_meridian") { @@ -6173,8 +6198,32 @@ AuthorityFactory::createObjectsFromNameEx( } else if (l_table_name == "ellipsoid") { return factory->createEllipsoid(l_code); } else if (l_table_name == "geodetic_datum") { + if (datumEnsembleAllowed) { + datum::GeodeticReferenceFramePtr datum; + datum::DatumEnsemblePtr datumEnsemble; + constexpr bool turnEnsembleAsDatum = false; + factory->createGeodeticDatumOrEnsemble( + l_code, datum, datumEnsemble, turnEnsembleAsDatum); + if (datum) { + return NN_NO_CHECK(datum); + } + assert(datumEnsemble); + return NN_NO_CHECK(datumEnsemble); + } return factory->createGeodeticDatum(l_code); } else if (l_table_name == "vertical_datum") { + if (datumEnsembleAllowed) { + datum::VerticalReferenceFramePtr datum; + datum::DatumEnsemblePtr datumEnsemble; + constexpr bool turnEnsembleAsDatum = false; + factory->createVerticalDatumOrEnsemble( + l_code, datum, datumEnsemble, turnEnsembleAsDatum); + if (datum) { + return NN_NO_CHECK(datum); + } + assert(datumEnsemble); + return NN_NO_CHECK(datumEnsemble); + } return factory->createVerticalDatum(l_code); } else if (l_table_name == "geodetic_crs") { return factory->createGeodeticCRS(l_code); diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index fde697ad..b2e5822b 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -6267,6 +6267,9 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text, if (type == "datum") { return factory->createDatum(code); } + if (type == "ensemble") { + return factory->createDatumEnsemble(code); + } if (type == "ellipsoid") { return factory->createEllipsoid(code); } @@ -6384,6 +6387,8 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text, ELLIPSOID, AuthorityFactory::ObjectType:: DATUM, + AuthorityFactory::ObjectType:: + DATUM_ENSEMBLE, AuthorityFactory::ObjectType:: COORDINATE_OPERATION}, goOn); -- cgit v1.2.3 From 119888b041258267768d632b89395e7074323326 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 10 Oct 2020 15:35:29 +0200 Subject: proj.h: add PJ_CATEGORY_DATUM_ENSEMBLE for proj_create_from_database() --- src/iso19111/c_api.cpp | 3 +++ src/proj.h | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 4fb73d31..cbbdcaa8 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -675,6 +675,9 @@ PJ *proj_create_from_database(PJ_CONTEXT *ctx, const char *auth_name, codeStr, usePROJAlternativeGridNames != 0) .as_nullable(); break; + case PJ_CATEGORY_DATUM_ENSEMBLE: + obj = factory->createDatumEnsemble(codeStr).as_nullable(); + break; } return pj_obj_create(ctx, NN_NO_CHECK(obj)); } catch (const std::exception &e) { diff --git a/src/proj.h b/src/proj.h index e77a5984..4185ddbf 100644 --- a/src/proj.h +++ b/src/proj.h @@ -694,7 +694,8 @@ typedef enum PJ_CATEGORY_PRIME_MERIDIAN, PJ_CATEGORY_DATUM, PJ_CATEGORY_CRS, - PJ_CATEGORY_COORDINATE_OPERATION + PJ_CATEGORY_COORDINATE_OPERATION, + PJ_CATEGORY_DATUM_ENSEMBLE } PJ_CATEGORY; /** \brief Object type. */ -- cgit v1.2.3 From dd829c94fffba3a0b725504d5c7b42384b2e6ee7 Mon Sep 17 00:00:00 2001 From: Olli Raisa Date: Mon, 2 Nov 2020 09:25:48 +0200 Subject: cmake build: set CURL_ENABLED definition on projinfo build (#2404) Fixes projinfo operation, when --remote-data command line option is parsed. --- src/bin_projinfo.cmake | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/bin_projinfo.cmake b/src/bin_projinfo.cmake index 16c9e9d0..8610a3a7 100644 --- a/src/bin_projinfo.cmake +++ b/src/bin_projinfo.cmake @@ -15,3 +15,7 @@ install(TARGETS binprojinfo if(MSVC AND BUILD_SHARED_LIBS) target_compile_definitions(binprojinfo PRIVATE PROJ_MSVC_DLL_IMPORT=1) endif() + +if(CURL_ENABLED) + target_compile_definitions(binprojinfo PRIVATE -DCURL_ENABLED) +endif() -- cgit v1.2.3 From 848ee7b6a8bf56a9d967f104ba2ef2ad92dc48d5 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 4 Nov 2020 15:24:44 +0100 Subject: createBoundCRSToWGS84IfPossible(): make it return same result with a CRS built from EPSG code or WKT1 Related to https://github.com/OSGeo/gdal/issues/3144 --- src/iso19111/coordinateoperation.cpp | 296 ++++++++++++++++++----------------- src/iso19111/crs.cpp | 6 +- 2 files changed, 156 insertions(+), 146 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index e9d73f52..4cf1ae89 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -15545,149 +15545,6 @@ void CoordinateOperationFactory::Private::createOperationsBoundToCompound( // --------------------------------------------------------------------------- -static crs::CRSNNPtr -getResolvedCRS(const crs::CRSNNPtr &crs, - const CoordinateOperationContextNNPtr &context, - metadata::ExtentPtr &extentOut) { - const auto &authFactory = context->getAuthorityFactory(); - const auto &ids = crs->identifiers(); - const auto &name = crs->nameStr(); - - bool approxExtent; - extentOut = getExtentPossiblySynthetized(crs, approxExtent); - - // We try to "identify" the provided CRS with the ones of the database, - // but in a more restricted way that what identify() does. - // If we get a match from id in priority, and from name as a fallback, and - // that they are equivalent to the input CRS, then use the identified CRS. - // Even if they aren't equivalent, we update extentOut with the one of the - // identified CRS if our input one is absent/not reliable. - - const auto tryToIdentifyByName = [&crs, &name, &authFactory, approxExtent, - &extentOut]( - io::AuthorityFactory::ObjectType objectType) { - if (name != "unknown" && name != "unnamed") { - auto matches = authFactory->createObjectsFromName( - name, {objectType}, false, 2); - if (matches.size() == 1) { - const auto match = - util::nn_static_pointer_cast(matches.front()); - if (approxExtent || !extentOut) { - extentOut = getExtent(match); - } - if (match->isEquivalentTo( - crs.get(), util::IComparable::Criterion::EQUIVALENT)) { - return match; - } - } - } - return crs; - }; - - auto geogCRS = dynamic_cast(crs.get()); - if (geogCRS && authFactory) { - if (!ids.empty()) { - const auto tmpAuthFactory = io::AuthorityFactory::create( - authFactory->databaseContext(), *ids.front()->codeSpace()); - try { - auto resolvedCrs( - tmpAuthFactory->createGeographicCRS(ids.front()->code())); - if (approxExtent || !extentOut) { - extentOut = getExtent(resolvedCrs); - } - if (resolvedCrs->isEquivalentTo( - crs.get(), util::IComparable::Criterion::EQUIVALENT)) { - return util::nn_static_pointer_cast(resolvedCrs); - } - } catch (const std::exception &) { - } - } else { - return tryToIdentifyByName( - geogCRS->coordinateSystem()->axisList().size() == 2 - ? io::AuthorityFactory::ObjectType::GEOGRAPHIC_2D_CRS - : io::AuthorityFactory::ObjectType::GEOGRAPHIC_3D_CRS); - } - } - - auto projectedCrs = dynamic_cast(crs.get()); - if (projectedCrs && authFactory) { - if (!ids.empty()) { - const auto tmpAuthFactory = io::AuthorityFactory::create( - authFactory->databaseContext(), *ids.front()->codeSpace()); - try { - auto resolvedCrs( - tmpAuthFactory->createProjectedCRS(ids.front()->code())); - if (approxExtent || !extentOut) { - extentOut = getExtent(resolvedCrs); - } - if (resolvedCrs->isEquivalentTo( - crs.get(), util::IComparable::Criterion::EQUIVALENT)) { - return util::nn_static_pointer_cast(resolvedCrs); - } - } catch (const std::exception &) { - } - } else { - return tryToIdentifyByName( - io::AuthorityFactory::ObjectType::PROJECTED_CRS); - } - } - - auto compoundCrs = dynamic_cast(crs.get()); - if (compoundCrs && authFactory) { - if (!ids.empty()) { - const auto tmpAuthFactory = io::AuthorityFactory::create( - authFactory->databaseContext(), *ids.front()->codeSpace()); - try { - auto resolvedCrs( - tmpAuthFactory->createCompoundCRS(ids.front()->code())); - if (approxExtent || !extentOut) { - extentOut = getExtent(resolvedCrs); - } - if (resolvedCrs->isEquivalentTo( - crs.get(), util::IComparable::Criterion::EQUIVALENT)) { - return util::nn_static_pointer_cast(resolvedCrs); - } - } catch (const std::exception &) { - } - } else { - auto outCrs = tryToIdentifyByName( - io::AuthorityFactory::ObjectType::COMPOUND_CRS); - const auto &components = compoundCrs->componentReferenceSystems(); - if (outCrs.get() != crs.get()) { - bool hasGeoid = false; - if (components.size() == 2) { - auto vertCRS = - dynamic_cast(components[1].get()); - if (vertCRS && !vertCRS->geoidModel().empty()) { - hasGeoid = true; - } - } - if (!hasGeoid) { - return outCrs; - } - } - if (approxExtent || !extentOut) { - // If we still did not get a reliable extent, then try to - // resolve the components of the compoundCRS, and take the - // intersection of their extent. - extentOut = metadata::ExtentPtr(); - for (const auto &component : components) { - metadata::ExtentPtr componentExtent; - getResolvedCRS(component, context, componentExtent); - if (extentOut && componentExtent) - extentOut = extentOut->intersection( - NN_NO_CHECK(componentExtent)); - else if (componentExtent) - extentOut = componentExtent; - } - } - } - } - return crs; -} - -// --------------------------------------------------------------------------- - /** \brief Find a list of CoordinateOperation from sourceCRS to targetCRS. * * The operations are sorted with the most relevant ones first: by @@ -15723,13 +15580,14 @@ CoordinateOperationFactory::createOperations( const auto &targetBoundCRS = targetCRS->canonicalBoundCRS(); auto l_sourceCRS = srcBoundCRS ? NN_NO_CHECK(srcBoundCRS) : sourceCRS; auto l_targetCRS = targetBoundCRS ? NN_NO_CHECK(targetBoundCRS) : targetCRS; + const auto &authFactory = context->getAuthorityFactory(); metadata::ExtentPtr sourceCRSExtent; auto l_resolvedSourceCRS = - getResolvedCRS(l_sourceCRS, context, sourceCRSExtent); + crs::CRS::getResolvedCRS(l_sourceCRS, authFactory, sourceCRSExtent); metadata::ExtentPtr targetCRSExtent; auto l_resolvedTargetCRS = - getResolvedCRS(l_targetCRS, context, targetCRSExtent); + crs::CRS::getResolvedCRS(l_targetCRS, authFactory, targetCRSExtent); Private::Context contextPrivate(sourceCRSExtent, targetCRSExtent, context); if (context->getSourceAndTargetCRSExtentUse() == @@ -16054,4 +15912,152 @@ PROJBasedOperation::gridsNeeded(const io::DatabaseContextPtr &databaseContext, // --------------------------------------------------------------------------- } // namespace operation + +namespace crs { +// --------------------------------------------------------------------------- + +//! @cond Doxygen_Suppress + +crs::CRSNNPtr CRS::getResolvedCRS(const crs::CRSNNPtr &crs, + const io::AuthorityFactoryPtr &authFactory, + metadata::ExtentPtr &extentOut) { + const auto &ids = crs->identifiers(); + const auto &name = crs->nameStr(); + + bool approxExtent; + extentOut = getExtentPossiblySynthetized(crs, approxExtent); + + // We try to "identify" the provided CRS with the ones of the database, + // but in a more restricted way that what identify() does. + // If we get a match from id in priority, and from name as a fallback, and + // that they are equivalent to the input CRS, then use the identified CRS. + // Even if they aren't equivalent, we update extentOut with the one of the + // identified CRS if our input one is absent/not reliable. + + const auto tryToIdentifyByName = [&crs, &name, &authFactory, approxExtent, + &extentOut]( + io::AuthorityFactory::ObjectType objectType) { + if (name != "unknown" && name != "unnamed") { + auto matches = authFactory->createObjectsFromName( + name, {objectType}, false, 2); + if (matches.size() == 1) { + const auto match = + util::nn_static_pointer_cast(matches.front()); + if (approxExtent || !extentOut) { + extentOut = getExtent(match); + } + if (match->isEquivalentTo( + crs.get(), util::IComparable::Criterion::EQUIVALENT)) { + return match; + } + } + } + return crs; + }; + + auto geogCRS = dynamic_cast(crs.get()); + if (geogCRS && authFactory) { + if (!ids.empty()) { + const auto tmpAuthFactory = io::AuthorityFactory::create( + authFactory->databaseContext(), *ids.front()->codeSpace()); + try { + auto resolvedCrs( + tmpAuthFactory->createGeographicCRS(ids.front()->code())); + if (approxExtent || !extentOut) { + extentOut = getExtent(resolvedCrs); + } + if (resolvedCrs->isEquivalentTo( + crs.get(), util::IComparable::Criterion::EQUIVALENT)) { + return util::nn_static_pointer_cast(resolvedCrs); + } + } catch (const std::exception &) { + } + } else { + return tryToIdentifyByName( + geogCRS->coordinateSystem()->axisList().size() == 2 + ? io::AuthorityFactory::ObjectType::GEOGRAPHIC_2D_CRS + : io::AuthorityFactory::ObjectType::GEOGRAPHIC_3D_CRS); + } + } + + auto projectedCrs = dynamic_cast(crs.get()); + if (projectedCrs && authFactory) { + if (!ids.empty()) { + const auto tmpAuthFactory = io::AuthorityFactory::create( + authFactory->databaseContext(), *ids.front()->codeSpace()); + try { + auto resolvedCrs( + tmpAuthFactory->createProjectedCRS(ids.front()->code())); + if (approxExtent || !extentOut) { + extentOut = getExtent(resolvedCrs); + } + if (resolvedCrs->isEquivalentTo( + crs.get(), util::IComparable::Criterion::EQUIVALENT)) { + return util::nn_static_pointer_cast(resolvedCrs); + } + } catch (const std::exception &) { + } + } else { + return tryToIdentifyByName( + io::AuthorityFactory::ObjectType::PROJECTED_CRS); + } + } + + auto compoundCrs = dynamic_cast(crs.get()); + if (compoundCrs && authFactory) { + if (!ids.empty()) { + const auto tmpAuthFactory = io::AuthorityFactory::create( + authFactory->databaseContext(), *ids.front()->codeSpace()); + try { + auto resolvedCrs( + tmpAuthFactory->createCompoundCRS(ids.front()->code())); + if (approxExtent || !extentOut) { + extentOut = getExtent(resolvedCrs); + } + if (resolvedCrs->isEquivalentTo( + crs.get(), util::IComparable::Criterion::EQUIVALENT)) { + return util::nn_static_pointer_cast(resolvedCrs); + } + } catch (const std::exception &) { + } + } else { + auto outCrs = tryToIdentifyByName( + io::AuthorityFactory::ObjectType::COMPOUND_CRS); + const auto &components = compoundCrs->componentReferenceSystems(); + if (outCrs.get() != crs.get()) { + bool hasGeoid = false; + if (components.size() == 2) { + auto vertCRS = + dynamic_cast(components[1].get()); + if (vertCRS && !vertCRS->geoidModel().empty()) { + hasGeoid = true; + } + } + if (!hasGeoid) { + return outCrs; + } + } + if (approxExtent || !extentOut) { + // If we still did not get a reliable extent, then try to + // resolve the components of the compoundCRS, and take the + // intersection of their extent. + extentOut = metadata::ExtentPtr(); + for (const auto &component : components) { + metadata::ExtentPtr componentExtent; + getResolvedCRS(component, authFactory, componentExtent); + if (extentOut && componentExtent) + extentOut = extentOut->intersection( + NN_NO_CHECK(componentExtent)); + else if (componentExtent) + extentOut = componentExtent; + } + } + } + } + return crs; +} + +//! @endcond + +} // namespace crs NS_PROJ_END diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index edc8a71f..84b98984 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -533,8 +533,12 @@ CRSNNPtr CRS::createBoundCRSToWGS84IfPossible( auto authFactory = io::AuthorityFactory::create( NN_NO_CHECK(dbContext), authority == "any" ? std::string() : authority); + metadata::ExtentPtr extentResolved(extent); + if (!extent) { + getResolvedCRS(thisAsCRS, authFactory, extentResolved); + } auto ctxt = operation::CoordinateOperationContext::create( - authFactory, extent, 0.0); + authFactory, extentResolved, 0.0); ctxt->setAllowUseIntermediateCRS(allowIntermediateCRSUse); // ctxt->setSpatialCriterion( // operation::CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION); -- cgit v1.2.3 From af342bf74cd154b653a0f9d931d4ca17001650b9 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Tue, 10 Nov 2020 14:08:30 +0100 Subject: Allow cct to instantiate operations via object codes or names (#2419) Running cct like cct EPSG:8366 or cct "ITRF2014 to ETRF2014 (1)" is now possible. --- src/apps/cct.cpp | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/apps/cct.cpp b/src/apps/cct.cpp index f7413872..4de3cf8e 100644 --- a/src/apps/cct.cpp +++ b/src/apps/cct.cpp @@ -77,6 +77,7 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-25/2017-10-26 #include #include #include +#include #include "proj.h" #include "proj_internal.h" @@ -193,9 +194,8 @@ static void print(PJ_LOG_LEVEL log_level, const char *fmt, ...) { free( msg_buf ); } - int main(int argc, char **argv) { - PJ *P; + PJ *P = nullptr; PJ_COORD point; PJ_PROJ_INFO info; OPTARGS *o; @@ -292,8 +292,36 @@ int main(int argc, char **argv) { } /* Setup transformation */ - P = proj_create_argv (nullptr, o->pargc, o->pargv); - if ((nullptr==P) || (0==o->pargc)) { + if (o-> pargc == 0 && o->fargc > 0) { + /* Assume we got a auth:code combination */ + std::string input(o->fargv[0]); + auto n = input.find(":"); + if (n > 0) { + std::string auth = input.substr(0,n); + std::string code = input.substr(n+1, input.length()); + P = proj_create_from_database( + nullptr, auth.c_str(), code.c_str(), PJ_CATEGORY_COORDINATE_OPERATION, 0, nullptr + ); + } + if( P == nullptr ) { + /* if we didn't get a auth:code combo we try to see if the input matches */ + /* anything else */ + P = proj_create(nullptr, o->fargv[0]); + } + + /* If instantiating operation without +-options optargpm thinks the input is */ + /* a file, hence we move all o->fargv entries one place closer to the start */ + /* of the array. This effectively overwrites the input and only leaves a list */ + /* of files in o->fargv. */ + o->fargc = o->fargc-1; + for (int j=0; j < o->fargc; j++) { + o->fargv[j] = o->fargv[j+1]; + } + } else { + P = proj_create_argv (nullptr, o->pargc, o->pargv); + } + + if (nullptr==P) { print (PJ_LOG_ERROR, "%s: Bad transformation arguments - (%s)\n '%s -h' for help", o->progname, pj_strerrno (proj_errno(P)), o->progname); free (o); -- cgit v1.2.3 From 6be4e25c66e805218c851d67157e4d1ddc0a761e Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 10 Nov 2020 14:40:17 +0100 Subject: cct: allow @filename syntax Similarly as for projinfo, allow "cct @filename" to mean read filename and use its content as if it was provided inline. Useful for WKT or PROJJSON And a tiny improvements, when the object definition contains ':', only try proj_create_from_database() if the left part (authority name) matches a known authority, to avoid a warning. --- src/apps/cct.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/apps/cct.cpp b/src/apps/cct.cpp index 4de3cf8e..c482efc2 100644 --- a/src/apps/cct.cpp +++ b/src/apps/cct.cpp @@ -77,6 +77,8 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-25/2017-10-26 #include #include #include + +#include // std::ifstream #include #include "proj.h" @@ -293,20 +295,55 @@ int main(int argc, char **argv) { /* Setup transformation */ if (o-> pargc == 0 && o->fargc > 0) { - /* Assume we got a auth:code combination */ std::string input(o->fargv[0]); + + if (!input.empty() && input[0] == '@') { + std::ifstream fs; + auto filename = input.substr(1); + fs.open(filename, std::fstream::in | std::fstream::binary); + if (!fs.is_open()) { + std::cerr << "cannot open " << filename << std::endl; + std::exit(1); + } + input.clear(); + while (!fs.eof()) { + char buffer[256]; + fs.read(buffer, sizeof(buffer)); + input.append(buffer, static_cast(fs.gcount())); + if (input.size() > 100 * 1000) { + fs.close(); + std::cerr << "too big file " << filename << std::endl; + std::exit(1); + } + } + fs.close(); + } + + /* Assume we got a auth:code combination */ auto n = input.find(":"); if (n > 0) { std::string auth = input.substr(0,n); std::string code = input.substr(n+1, input.length()); - P = proj_create_from_database( - nullptr, auth.c_str(), code.c_str(), PJ_CATEGORY_COORDINATE_OPERATION, 0, nullptr - ); + // Check that the authority matches one of the known ones + auto authorityList = proj_get_authorities_from_database(nullptr); + if( authorityList ) + { + for( auto iter = authorityList; *iter; iter++ ) + { + if( *iter == auth ) { + P = proj_create_from_database( + nullptr, auth.c_str(), code.c_str(), + PJ_CATEGORY_COORDINATE_OPERATION, 0, nullptr); + break; + } + } + proj_string_list_destroy(authorityList); + } } if( P == nullptr ) { /* if we didn't get a auth:code combo we try to see if the input matches */ /* anything else */ - P = proj_create(nullptr, o->fargv[0]); + P = proj_create(nullptr, input.c_str()); } /* If instantiating operation without +-options optargpm thinks the input is */ -- cgit v1.2.3 From b38d0143a65fff72635b95a61ed6c4c41802889e Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 11 Nov 2020 23:56:58 +0100 Subject: Polar stereographic at pole: make it return (0,0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Due to the improved accuracy of pj_tsfn(), it no longer returns 0 when phi=90° due to the conversion in radians. Some GDAL tests are very sensitive to the pole transforming to (0,0) exactly, so add a special case for that. master only --- src/projections/stere.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/projections/stere.cpp b/src/projections/stere.cpp index abc4aa13..3fff722d 100644 --- a/src/projections/stere.cpp +++ b/src/projections/stere.cpp @@ -86,7 +86,10 @@ static PJ_XY stere_e_forward (PJ_LP lp, PJ *P) { /* Ellipsoidal, forwar sinphi = -sinphi; /*-fallthrough*/ case N_POLE: - xy.x = Q->akm1 * pj_tsfn (lp.phi, sinphi, P->e); + if( fabs(lp.phi - M_HALFPI) < 1e-15 ) + xy.x = 0; + else + xy.x = Q->akm1 * pj_tsfn (lp.phi, sinphi, P->e); xy.y = - xy.x * coslam; break; } -- cgit v1.2.3 From 63f9f4e09ab26f1a52751cec15f394e88660b8bf Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 16 Nov 2020 13:57:09 +0100 Subject: WKT2 parsing: several fixes related to map projection parameter units - WKT2 grammar: accept PARAMETER[name,value,id] without unit - Recognize "Ellipsoid scaling factor" as a parameter with a scaling unit, and defaults to Unity when not specified - WKT2 parsing: implement the requirement of 18-010r7.html#80, that is when a map projection parameter has no explicit unit, use metre/degree/unity as the default unit (contrary to WKT1 parsing rules where they are deduced from the GeogCRS angular unit and coordinate system) --- src/iso19111/io.cpp | 15 +- src/wkt2_generated_parser.c | 1932 ++++++++++++++++++++++--------------------- src/wkt2_grammar.y | 1 + 3 files changed, 987 insertions(+), 961 deletions(-) (limited to 'src') diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index b2e5822b..623ad6f9 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -2944,7 +2944,8 @@ UnitOfMeasure WKTParser::Private::guessUnitForParameter( const UnitOfMeasure &defaultAngularUnit) { UnitOfMeasure unit; // scale must be first because of 'Scale factor on pseudo standard parallel' - if (ci_find(paramName, "scale") != std::string::npos) { + if (ci_find(paramName, "scale") != std::string::npos || + ci_find(paramName, "scaling factor") != std::string::npos) { unit = UnitOfMeasure::SCALE_UNITY; } else if (ci_find(paramName, "latitude") != std::string::npos || ci_find(paramName, "longitude") != std::string::npos || @@ -3876,8 +3877,16 @@ WKTParser::Private::buildProjectedCRS(const WKTNodeNNPtr &node) { return createPseudoMercator(props, NN_NO_CHECK(cartesianCS)); } - auto linearUnit = buildUnitInSubNode(node, UnitOfMeasure::Type::LINEAR); - auto angularUnit = baseGeodCRS->coordinateSystem()->axisList()[0]->unit(); + // For WKT2, if there is no explicit parameter unit, use metre for linear + // units and degree for angular units + auto linearUnit = + !isNull(conversionNode) + ? UnitOfMeasure::METRE + : buildUnitInSubNode(node, UnitOfMeasure::Type::LINEAR); + auto angularUnit = + !isNull(conversionNode) + ? UnitOfMeasure::DEGREE + : baseGeodCRS->coordinateSystem()->axisList()[0]->unit(); auto conversion = !isNull(conversionNode) diff --git a/src/wkt2_generated_parser.c b/src/wkt2_generated_parser.c index feb2cc6b..f7bb5798 100644 --- a/src/wkt2_generated_parser.c +++ b/src/wkt2_generated_parser.c @@ -542,16 +542,16 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 106 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 3132 +#define YYLAST 3219 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 164 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 353 /* YYNRULES -- Number of rules. */ -#define YYNRULES 694 +#define YYNRULES 695 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 1427 +#define YYNSTATES 1429 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ @@ -658,30 +658,30 @@ static const yytype_uint16 yyrline[] = 997, 1003, 1003, 1007, 1007, 1008, 1008, 1010, 1015, 1016, 1017, 1018, 1019, 1021, 1027, 1032, 1038, 1040, 1042, 1044, 1048, 1054, 1055, 1056, 1058, 1060, 1062, 1066, 1066, 1068, - 1070, 1075, 1076, 1078, 1080, 1082, 1084, 1088, 1088, 1090, - 1096, 1103, 1103, 1106, 1113, 1114, 1115, 1116, 1117, 1119, - 1123, 1125, 1127, 1127, 1131, 1136, 1136, 1136, 1140, 1145, - 1145, 1147, 1151, 1151, 1155, 1160, 1162, 1166, 1166, 1170, - 1175, 1177, 1181, 1182, 1183, 1184, 1185, 1187, 1187, 1189, - 1192, 1194, 1194, 1196, 1198, 1200, 1204, 1210, 1211, 1212, - 1213, 1215, 1217, 1221, 1226, 1228, 1231, 1236, 1240, 1246, - 1246, 1246, 1246, 1246, 1246, 1250, 1255, 1257, 1262, 1262, - 1263, 1265, 1265, 1267, 1274, 1274, 1276, 1283, 1283, 1285, - 1292, 1299, 1304, 1305, 1306, 1308, 1314, 1319, 1327, 1333, - 1335, 1337, 1343, 1345, 1345, 1346, 1346, 1350, 1356, 1356, - 1358, 1363, 1369, 1374, 1380, 1385, 1390, 1396, 1401, 1406, - 1412, 1417, 1422, 1428, 1428, 1429, 1429, 1430, 1430, 1431, - 1431, 1432, 1432, 1433, 1433, 1436, 1436, 1438, 1439, 1440, - 1442, 1444, 1448, 1451, 1451, 1454, 1455, 1456, 1458, 1462, - 1463, 1465, 1467, 1467, 1468, 1468, 1469, 1469, 1469, 1470, - 1471, 1471, 1472, 1472, 1473, 1473, 1475, 1475, 1476, 1476, - 1477, 1478, 1478, 1482, 1486, 1487, 1490, 1495, 1496, 1497, - 1498, 1499, 1500, 1501, 1503, 1505, 1507, 1510, 1512, 1514, - 1516, 1518, 1520, 1522, 1524, 1526, 1528, 1533, 1537, 1538, - 1541, 1546, 1547, 1548, 1549, 1550, 1552, 1557, 1562, 1563, - 1566, 1572, 1572, 1572, 1572, 1574, 1575, 1576, 1577, 1579, - 1581, 1586, 1592, 1594, 1599, 1600, 1603, 1609, 1609, 1611, - 1612, 1613, 1614, 1616, 1618 + 1070, 1075, 1076, 1077, 1079, 1081, 1083, 1085, 1089, 1089, + 1091, 1097, 1104, 1104, 1107, 1114, 1115, 1116, 1117, 1118, + 1120, 1124, 1126, 1128, 1128, 1132, 1137, 1137, 1137, 1141, + 1146, 1146, 1148, 1152, 1152, 1156, 1161, 1163, 1167, 1167, + 1171, 1176, 1178, 1182, 1183, 1184, 1185, 1186, 1188, 1188, + 1190, 1193, 1195, 1195, 1197, 1199, 1201, 1205, 1211, 1212, + 1213, 1214, 1216, 1218, 1222, 1227, 1229, 1232, 1237, 1241, + 1247, 1247, 1247, 1247, 1247, 1247, 1251, 1256, 1258, 1263, + 1263, 1264, 1266, 1266, 1268, 1275, 1275, 1277, 1284, 1284, + 1286, 1293, 1300, 1305, 1306, 1307, 1309, 1315, 1320, 1328, + 1334, 1336, 1338, 1344, 1346, 1346, 1347, 1347, 1351, 1357, + 1357, 1359, 1364, 1370, 1375, 1381, 1386, 1391, 1397, 1402, + 1407, 1413, 1418, 1423, 1429, 1429, 1430, 1430, 1431, 1431, + 1432, 1432, 1433, 1433, 1434, 1434, 1437, 1437, 1439, 1440, + 1441, 1443, 1445, 1449, 1452, 1452, 1455, 1456, 1457, 1459, + 1463, 1464, 1466, 1468, 1468, 1469, 1469, 1470, 1470, 1470, + 1471, 1472, 1472, 1473, 1473, 1474, 1474, 1476, 1476, 1477, + 1477, 1478, 1479, 1479, 1483, 1487, 1488, 1491, 1496, 1497, + 1498, 1499, 1500, 1501, 1502, 1504, 1506, 1508, 1511, 1513, + 1515, 1517, 1519, 1521, 1523, 1525, 1527, 1529, 1534, 1538, + 1539, 1542, 1547, 1548, 1549, 1550, 1551, 1553, 1558, 1563, + 1564, 1567, 1573, 1573, 1573, 1573, 1575, 1576, 1577, 1578, + 1580, 1582, 1587, 1593, 1595, 1600, 1601, 1604, 1610, 1610, + 1612, 1613, 1614, 1615, 1617, 1619 }; #endif @@ -933,7 +933,7 @@ static const yytype_uint16 yytoknum[] = #define yypact_value_is_default(Yystate) \ (!!((Yystate) == (-1232))) -#define YYTABLE_NINF -633 +#define YYTABLE_NINF -634 #define yytable_value_is_error(Yytable_value) \ 0 @@ -942,149 +942,149 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - 2573, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, + 1574, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, - -1232, -1232, -1232, -1232, -1232, -1232, -1232, 114, -1232, -1232, - -1232, 231, -1232, -1232, -1232, 231, -1232, -1232, -1232, -1232, - -1232, -1232, 231, 231, -1232, 231, -1232, -75, 231, -1232, - 231, -1232, 231, -1232, -1232, -1232, 231, -1232, 231, -1232, - 231, -1232, 231, -1232, 231, -1232, 231, -1232, 231, -1232, - 231, -1232, -1232, -1232, -1232, -1232, -1232, -1232, 231, -1232, - -1232, -1232, -1232, -1232, -1232, 231, -1232, 231, -1232, 231, - -1232, 231, -1232, 231, -1232, 231, -1232, -1232, -1232, 33, - 33, 33, 33, 33, -1232, 81, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 879, - 33, 33, 33, 117, -1232, -1232, -75, -1232, -75, -1232, - -75, -75, -1232, -75, -1232, -1232, -1232, 231, -1232, -75, - -75, -1232, -75, -75, -75, -75, -75, -75, -75, -75, - -75, -1232, -75, -1232, -75, -1232, -1232, -1232, -1232, 28, - -1232, -1232, -1232, -1232, -1232, 97, 168, 186, -1232, -1232, - -1232, -1232, 284, -1232, -75, -1232, -75, -75, -75, -1232, - -75, 231, 1038, 176, 66, 66, 713, 33, 287, 179, - 157, 766, 290, 284, 244, 284, 413, 284, 105, 286, - 284, 297, 1406, -1232, -1232, -1232, 428, 101, -1232, -1232, - 101, -1232, -1232, 101, -1232, -1232, 331, 879, -1232, -1232, - -1232, -1232, -1232, -1232, -1232, 728, -1232, -1232, -1232, -1232, - 265, 278, 293, 713, -1232, -75, -1232, -75, 231, -1232, - -1232, -1232, -1232, 231, -75, 231, -75, -1232, 231, 231, - -75, -75, -1232, -1232, -1232, -1232, -75, -75, -75, -75, - -1232, -75, -1232, -75, -75, -75, -1232, -1232, -1232, -1232, - 231, 231, -1232, -1232, -75, 231, -1232, -1232, 231, -75, - -75, -1232, -75, -1232, -1232, 231, -1232, -75, -75, 231, - -1232, -1232, -75, -75, 231, -1232, -1232, -75, -75, 231, - -1232, -1232, -75, -75, 231, -1232, -1232, -75, -75, 231, - -75, 231, -1232, -1232, -75, 231, -1232, -75, -1232, -1232, - -1232, -1232, 231, -1232, -75, 231, -75, -75, -75, -75, - -75, -1232, -75, 231, 284, -1232, 476, 728, -1232, -1232, - 387, 284, 283, 284, 284, 33, 33, 59, 404, 258, - 33, 33, 441, 441, 59, 258, 441, 441, 713, 476, - 284, 452, 33, 33, 349, 284, 33, 33, 88, 477, - 441, 33, 479, -1232, 479, 33, 477, 441, 33, 477, - 441, 33, 477, 441, 33, -1232, -1232, 682, 74, -1232, - 33, 441, 33, 1406, 728, 117, -1232, 33, 331, 117, - -1232, 487, 117, -1232, 331, 469, 879, -1232, 728, -1232, - -1232, -1232, -1232, -1232, -1232, -1232, -1232, -75, -75, 231, - -1232, 231, -1232, -1232, -75, -75, 231, -75, -1232, -1232, - -1232, -75, -75, -75, -1232, -75, 231, -1232, -1232, -1232, - -1232, -1232, -1232, 231, 284, -75, -1232, -75, -75, -1232, - -75, 231, -75, -75, 284, -75, -75, -1232, -75, -75, - 713, 284, -1232, -75, -75, -75, -1232, -75, -75, 231, - -1232, -1232, -75, -75, -75, 231, 284, -75, -75, -75, - -75, -1232, 284, 284, -75, -75, 284, -75, -75, 284, - -75, -75, -1232, -1232, 116, -1232, 284, -75, -1232, 284, - -75, -75, -75, 293, 284, -1232, 284, -75, -1232, -75, - 231, -75, -1232, -75, 231, 284, -1232, 488, 511, 33, - 33, -1232, -1232, 479, -1232, 1192, 486, 479, 284, 176, - 258, 614, 284, 728, 1482, -1232, 477, 56, 56, 477, - 33, 477, 258, -1232, 477, 477, 148, 284, 345, -1232, - -1232, -1232, 477, 56, 56, -1232, -1232, 33, 284, 176, - 477, 1503, -1232, 477, 277, -1232, -1232, -1232, -1232, 477, - -1, -1232, 477, -2, -1232, 477, 22, -1232, -1232, 728, - -1232, -1232, 728, -1232, -1232, -1232, 477, 179, 1669, 284, - 728, -1232, -1232, 487, 1210, 284, 33, 523, 1412, 284, - 33, -1232, -75, -1232, -1232, 284, -1232, 284, -1232, -75, - -1232, 284, -75, -1232, -75, -1232, -75, 284, -1232, -1232, - -1232, 231, -1232, 293, 284, -1232, -1232, -1232, -1232, -1232, - -1232, -1232, -1232, -1232, -75, -1232, -1232, -1232, -1232, -75, - -75, -75, -1232, -75, -75, -75, -75, 284, -1232, -75, - 284, 284, 284, 284, -1232, -1232, -75, -75, 231, -1232, - -1232, -1232, -75, 231, 284, -75, -75, -75, -75, -1232, - -75, -1232, -75, 284, -75, 284, -75, -75, 284, -75, - 284, -75, 284, -75, 159, 401, -1232, 767, 284, -1232, - -1232, -1232, -1232, -75, -1232, -1232, -1232, -1232, -1232, -1232, - -1232, -1232, -1232, -1232, -1232, -75, 231, -75, 231, -1232, - -75, 231, -75, 231, -75, 231, -75, 231, -75, -1232, - 231, -75, -1232, -1232, -75, -1232, -1232, -1232, 231, -75, - -75, 231, -75, 231, -1232, -1232, -75, -1232, 231, -1232, - -1232, -75, 511, -1232, -1232, -1232, -1232, -1232, -1232, 257, - -1232, 33, 728, -1232, 586, 586, 586, 586, 59, 196, - 284, 59, 284, -1232, 487, -1232, -1232, -1232, -1232, -1232, - -1232, 33, -1232, 33, -1232, 59, 141, 284, 59, 284, - 476, 631, -1232, 586, -1232, 88, 284, -1232, 284, -1232, - 284, -1232, 284, -1232, 728, -1232, -1232, 728, 728, -1232, - 415, -1232, -1232, -1232, -1232, 452, 145, 548, 528, -1232, - 33, 547, -1232, 33, 322, -1232, 1192, 325, -1232, 1192, - 267, -1232, 682, -1232, 439, -1232, 980, 284, 33, -1232, - -1232, 33, -1232, 1192, 479, 284, 282, 42, -1232, -1232, - -1232, -75, -1232, -75, -1232, -1232, -1232, -1232, -75, -75, - -75, -75, -75, -75, -75, -1232, -75, -1232, -75, -1232, - -75, -75, -75, -75, -1232, -75, -75, -1232, -75, -1232, - -1232, -75, -75, -75, -75, -1232, -1232, -1232, -1232, -1232, - 433, 415, -1232, 767, 728, -1232, -75, -1232, -75, -1232, - -75, -1232, -75, -1232, -1232, 284, -75, -75, -75, -1232, - 284, -75, -75, -1232, -75, -75, -1232, -75, -1232, -1232, - -75, -1232, 284, -1232, -1232, -75, -75, -75, 231, -75, - -1232, -75, -75, 284, -1232, -1232, -1232, -1232, -1232, -1232, - 284, -75, -75, 284, 284, 284, 284, 284, 284, -1232, - -1232, 284, 259, 284, 713, 713, 284, -1232, 345, -1232, - -1232, 284, 456, 284, 284, 284, -1232, -1232, 728, -1232, - -1232, -1232, 284, -1232, 212, -1232, -1232, 322, -1232, 325, - -1232, -1232, -1232, 325, -1232, -1232, 1192, -1232, 1192, 682, - -1232, -1232, -1232, 1052, -1232, 879, -1232, 476, 33, -1232, - -75, 167, 487, -1232, -1232, -75, -75, -75, -75, -1232, - -1232, -75, -75, -75, -1232, -1232, -75, -75, -1232, -75, - -1232, -1232, -1232, -1232, -1232, -1232, 231, -75, -1232, -75, - -1232, -1232, -1232, 1008, -1232, 284, -75, -75, -75, -1232, - -75, -75, -75, -75, -1232, -75, -1232, -75, -1232, -1232, - 284, -75, 284, -75, -1232, -75, 523, 231, -1232, -75, - -1232, 595, 595, 595, 595, -1232, -1232, -1232, 284, 284, - -1232, 33, -1232, 595, 1080, -1232, -1232, 315, 622, 553, - 325, -1232, -1232, -1232, -1232, 1192, 376, 284, -1232, -1232, - -1232, 775, 284, 231, 33, 1141, 284, -1232, -75, 231, - -75, 231, -75, -75, 231, -1232, -1232, -75, -75, 525, - 1080, -1232, -75, -75, -1232, -75, -1232, -1232, -75, -1232, - -75, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -75, - -1232, 231, -1232, 282, -75, -1232, -75, -75, -1232, 696, - -1232, 33, 688, -1232, 33, -1232, 974, -1232, 33, 713, - 1086, -1232, -1232, 622, 553, 553, -1232, 1192, 284, 33, - 284, 476, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, - -1232, -1232, -1232, -1232, -1232, 231, -1232, 231, -75, -1232, - -75, -1232, -75, -75, -75, -1232, -75, -75, -75, -1232, - -1232, -75, -75, 231, -75, -1232, -1232, -1232, -1232, 284, - -1232, -75, -75, -75, 33, 33, 1412, 2101, -1232, -1232, - 2559, -1232, 2630, 284, 478, -1232, -1232, 33, 553, -1232, - 713, 284, 1469, 284, 284, -75, -75, -1232, -1232, -1232, + -1232, -1232, -1232, -1232, -1232, -1232, -1232, 62, -1232, -1232, + -1232, 98, -1232, -1232, -1232, 98, -1232, -1232, -1232, -1232, + -1232, -1232, 98, 98, -1232, 98, -1232, -87, 98, -1232, + 98, -1232, 98, -1232, -1232, -1232, 98, -1232, 98, -1232, + 98, -1232, 98, -1232, 98, -1232, 98, -1232, 98, -1232, + 98, -1232, -1232, -1232, -1232, -1232, -1232, -1232, 98, -1232, + -1232, -1232, -1232, -1232, -1232, 98, -1232, 98, -1232, 98, + -1232, 98, -1232, 98, -1232, 98, -1232, -1232, -1232, -24, + -24, -24, -24, -24, -1232, 83, -24, -24, -24, -24, + -24, -24, -24, -24, -24, -24, -24, -24, -24, 810, + -24, -24, -24, 113, -1232, -1232, -87, -1232, -87, -1232, + -87, -87, -1232, -87, -1232, -1232, -1232, 98, -1232, -87, + -87, -1232, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -1232, -87, -1232, -87, -1232, -1232, -1232, -1232, 26, + -1232, -1232, -1232, -1232, -1232, 37, 52, 179, -1232, -1232, + -1232, -1232, 360, -1232, -87, -1232, -87, -87, -87, -1232, + -87, 98, 1048, 212, 59, 59, 761, -24, 256, 138, + 156, 467, 304, 360, 203, 360, 322, 360, 217, 314, + 360, 275, 1439, -1232, -1232, -1232, 483, 69, -1232, -1232, + 69, -1232, -1232, 69, -1232, -1232, 335, 810, -1232, -1232, + -1232, -1232, -1232, -1232, -1232, 462, -1232, -1232, -1232, -1232, + 252, 265, 287, 761, -1232, -87, -1232, -87, 98, -1232, + -1232, -1232, -1232, 98, -87, 98, -87, -1232, 98, 98, + -87, -87, -1232, -1232, -1232, -1232, -87, -87, -87, -87, + -1232, -87, -1232, -87, -87, -87, -1232, -1232, -1232, -1232, + 98, 98, -1232, -1232, -87, 98, -1232, -1232, 98, -87, + -87, -1232, -87, -1232, -1232, 98, -1232, -87, -87, 98, + -1232, -1232, -87, -87, 98, -1232, -1232, -87, -87, 98, + -1232, -1232, -87, -87, 98, -1232, -1232, -87, -87, 98, + -87, 98, -1232, -1232, -87, 98, -1232, -87, -1232, -1232, + -1232, -1232, 98, -1232, -87, 98, -87, -87, -87, -87, + -87, -1232, -87, 98, 360, -1232, 416, 462, -1232, -1232, + 558, 360, 75, 360, 360, -24, -24, 78, 390, 102, + -24, -24, 413, 413, 78, 102, 413, 413, 761, 416, + 360, 466, -24, -24, 364, 360, -24, -24, 89, 477, + 413, -24, 488, -1232, 488, -24, 477, 413, -24, 477, + 413, -24, 477, 413, -24, -1232, -1232, 387, 104, -1232, + -24, 413, -24, 1439, 462, 113, -1232, -24, 335, 113, + -1232, 499, 113, -1232, 335, 461, 810, -1232, 462, -1232, + -1232, -1232, -1232, -1232, -1232, -1232, -1232, -87, -87, 98, + -1232, 98, -1232, -1232, -87, -87, 98, -87, -1232, -1232, + -1232, -87, -87, -87, -1232, -87, 98, -1232, -1232, -1232, + -1232, -1232, -1232, 98, 360, -87, -1232, -87, -87, -1232, + -87, 98, -87, -87, 360, -87, -87, -1232, -87, -87, + 761, 360, -1232, -87, -87, -87, -1232, -87, -87, 98, + -1232, -1232, -87, -87, -87, 98, 360, -87, -87, -87, + -87, -1232, 360, 360, -87, -87, 360, -87, -87, 360, + -87, -87, -1232, -1232, 159, -1232, 360, -87, -1232, 360, + -87, -87, -87, 287, 360, -1232, 360, -87, -1232, -87, + 98, -87, -1232, -87, 98, 360, -1232, 481, 486, -24, + -24, -1232, -1232, 488, -1232, 823, 479, 488, 360, 212, + 102, 517, 360, 462, 1699, -1232, 477, 112, 112, 477, + -24, 477, 102, -1232, 477, 477, 329, 360, 306, -1232, + -1232, -1232, 477, 112, 112, -1232, -1232, -24, 360, 212, + 477, 940, -1232, 477, 243, -1232, -1232, -1232, -1232, 477, + 108, -1232, 477, 192, -1232, 477, 25, -1232, -1232, 462, + -1232, -1232, 462, -1232, -1232, -1232, 477, 138, 1409, 360, + 462, -1232, -1232, 499, 1212, 360, -24, 498, 1047, 360, + -24, -1232, -87, -1232, -1232, 360, -1232, 360, -1232, -87, + -1232, 360, -87, -1232, -87, -1232, -87, 360, -1232, -1232, + -1232, 98, -1232, 287, 360, -1232, -1232, -1232, -1232, -1232, + -1232, -1232, -1232, -1232, -87, -1232, -1232, -1232, -1232, -87, + -87, -87, -1232, -87, -87, -87, -87, 360, -1232, -87, + 360, 360, 360, 360, -1232, -1232, -87, -87, 98, -1232, + -1232, -1232, -87, 98, 360, -87, -87, -87, -87, -1232, + -87, -1232, -87, 360, -87, 360, -87, -87, 360, -87, + 360, -87, 360, -87, 205, 427, -1232, 497, 360, -1232, + -1232, -1232, -1232, -87, -1232, -1232, -1232, -1232, -1232, -1232, + -1232, -1232, -1232, -1232, -1232, -87, 98, -87, 98, -1232, + -87, 98, -87, 98, -87, 98, -87, 98, -87, -1232, + 98, -87, -1232, -1232, -87, -1232, -1232, -1232, 98, -87, + -87, 98, -87, 98, -1232, -1232, -87, -1232, 98, -1232, + -1232, -87, 486, -1232, -1232, -1232, -1232, -1232, -1232, 117, + -1232, -24, 462, -1232, 398, 398, 398, 398, 78, 100, + 360, 78, 360, -1232, 499, -1232, -1232, -1232, -1232, -1232, + -1232, -24, -1232, -24, -1232, 78, 58, 360, 78, 360, + 416, 518, -1232, 398, -1232, 89, 360, -1232, 360, -1232, + 360, -1232, 360, -1232, 462, -1232, -1232, 462, 462, -1232, + 430, -1232, -1232, -1232, -1232, 466, 176, 566, 530, -1232, + -24, 547, -1232, -24, 425, -1232, 823, 281, -1232, 823, + 333, -1232, 387, -1232, 469, -1232, 1134, 360, -24, -1232, + -1232, -24, -1232, 823, 488, 360, 267, 47, -1232, -1232, + -1232, -87, -1232, -87, -1232, -1232, -1232, -1232, -87, -87, + -87, -87, -87, -87, -87, -1232, -87, -1232, -87, -1232, + -87, -87, -87, -87, -1232, -87, -87, -1232, -87, -1232, + -1232, -87, -87, -87, -87, -1232, -1232, -1232, -1232, -1232, + 465, 430, -1232, 497, 462, -1232, -87, -1232, -87, -1232, + -87, -1232, -87, -1232, -1232, 360, -87, -87, -87, -1232, + 360, -87, -87, -1232, -87, -87, -1232, -87, -1232, -1232, + -87, -1232, 360, -1232, -1232, -87, -87, -87, 98, -87, + -1232, -87, -87, 360, -1232, -1232, -1232, -1232, -1232, -1232, + 360, -87, -87, 360, 360, 360, 360, 360, 360, -1232, + -1232, 360, 103, 360, 761, 761, 360, -1232, 306, -1232, + -1232, 360, 746, 360, 360, 360, -1232, -1232, 462, -1232, + -1232, -1232, 360, -1232, 338, -1232, -1232, 425, -1232, 281, + -1232, -1232, -1232, 281, -1232, -1232, 823, -1232, 823, 387, + -1232, -1232, -1232, 1054, -1232, 810, -1232, 416, -24, -1232, + -87, 168, 499, -1232, -1232, -87, -87, -87, -87, -1232, + -1232, -87, -87, -87, -1232, -1232, -87, -87, -1232, -87, + -1232, -1232, -1232, -1232, -1232, -87, -1232, 98, -87, -1232, + -87, -1232, -1232, -1232, 681, -1232, 360, -87, -87, -87, + -1232, -87, -87, -87, -87, -1232, -87, -1232, -87, -1232, + -1232, 360, -87, 360, -87, -1232, -87, 498, 98, -1232, + -87, -1232, 623, 623, 623, 623, -1232, -1232, -1232, 360, + 360, -1232, -1232, -24, -1232, 623, 811, -1232, -1232, 199, + 535, 579, 281, -1232, -1232, -1232, -1232, 823, 372, 360, + -1232, -1232, -1232, 297, 360, 98, -24, 1415, 360, -1232, + -87, 98, -87, 98, -87, -87, 98, -1232, -1232, -87, + -87, 370, 811, -1232, -87, -87, -1232, -87, -1232, -1232, + -87, -1232, -87, -1232, -1232, -1232, -1232, -1232, -1232, -1232, + -1232, -87, -1232, 98, -1232, 267, -87, -1232, -87, -87, + -1232, 1348, -1232, -24, 1001, -1232, -24, -1232, 711, -1232, + -24, 761, 1104, -1232, -1232, 535, 579, 579, -1232, 823, + 360, -24, 360, 416, -1232, -1232, -1232, -1232, -1232, -1232, + -1232, -1232, -1232, -1232, -1232, -1232, -1232, 98, -1232, 98, + -87, -1232, -87, -1232, -87, -87, -87, -1232, -87, -87, + -87, -1232, -1232, -87, -87, 98, -87, -1232, -1232, -1232, + -1232, 360, -1232, -87, -87, -87, -24, -24, 1047, 2503, + -1232, -1232, 2115, -1232, 2716, 360, 1527, -1232, -1232, -24, + 579, -1232, 761, 360, 1340, 360, 360, -87, -87, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -1232, - -1232, -1232, -1232, -1232, -75, -75, -75, -75, -75, 284, - -1232, -75, -75, -75, -75, -75, 284, -1232, -75, -1232, - -75, -1232, -75, -1232, -75, -1232, -1232, -75, 231, -1232, - -1232, 713, 284, 55, 284, 563, 563, 723, 723, -1232, - 741, 457, 563, 593, 593, -1232, 530, -1232, 284, -1232, - -1232, 282, -75, -1232, -1232, -75, -75, -1232, -75, 231, - -1232, -1232, -75, -75, -1232, -75, 231, -75, -1232, -1232, - -75, -75, -1232, -75, 231, -75, -1232, -75, -75, -1232, - -75, -75, -1232, -75, -75, -1232, -75, -1232, -75, -75, - -1232, -75, -1232, -75, -1232, 284, 284, -1232, -1232, 92, - -1232, 728, -1232, -1232, 741, -1232, 1192, 763, -1232, -1232, - -1232, 741, -1232, 1192, 763, -1232, -1232, -1232, 763, -1232, - -1232, 530, -1232, -1232, -1232, 530, -1232, -1232, -1232, -1232, - -75, -1232, -75, 284, -75, -75, -75, -75, -75, -75, - 284, -75, -75, -75, -75, -1232, -1232, -1232, -1232, 763, - -1232, 577, -1232, -1232, 763, -1232, -1232, -1232, -1232, -1232, - -1232, -75, 284, -75, -1232, -1232, -1232 + -1232, -1232, -1232, -1232, -1232, -1232, -87, -87, -87, -87, + -87, 360, -1232, -87, -87, -87, -87, -87, 360, -1232, + -87, -1232, -87, -1232, -87, -1232, -87, -1232, -1232, -87, + 98, -1232, -1232, 761, 360, 272, 360, 679, 679, 710, + 710, -1232, 870, 412, 679, 494, 494, -1232, 336, -1232, + 360, -1232, -1232, 267, -87, -1232, -1232, -87, -87, -1232, + -87, 98, -1232, -1232, -87, -87, -1232, -87, 98, -87, + -1232, -1232, -87, -87, -1232, -87, 98, -87, -1232, -87, + -87, -1232, -87, -87, -1232, -87, -87, -1232, -87, -1232, + -87, -87, -1232, -87, -1232, -87, -1232, 360, 360, -1232, + -1232, 74, -1232, 462, -1232, -1232, 870, -1232, 823, 475, + -1232, -1232, -1232, 870, -1232, 823, 475, -1232, -1232, -1232, + 475, -1232, -1232, 336, -1232, -1232, -1232, 336, -1232, -1232, + -1232, -1232, -87, -1232, -87, 360, -87, -87, -87, -87, + -87, -87, 360, -87, -87, -87, -87, -1232, -1232, -1232, + -1232, 475, -1232, 438, -1232, -1232, 475, -1232, -1232, -1232, + -1232, -1232, -1232, -87, 360, -87, -1232, -1232, -1232 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -1092,190 +1092,190 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 0, 419, 406, 395, 405, 161, 431, 454, 397, 482, - 485, 600, 644, 679, 682, 507, 500, 356, 559, 492, - 489, 497, 495, 611, 666, 396, 421, 432, 398, 420, - 483, 487, 486, 508, 493, 490, 498, 0, 4, 5, - 2, 0, 13, 346, 347, 0, 583, 385, 383, 384, - 386, 387, 0, 0, 3, 0, 12, 416, 0, 585, - 0, 11, 0, 587, 467, 468, 0, 14, 0, 589, - 0, 15, 0, 591, 0, 16, 0, 593, 0, 17, - 0, 584, 540, 538, 539, 541, 542, 586, 0, 588, - 590, 592, 594, 19, 18, 0, 7, 0, 8, 0, + 0, 419, 406, 395, 405, 161, 431, 454, 397, 483, + 486, 601, 645, 680, 683, 508, 501, 356, 560, 493, + 490, 498, 496, 612, 667, 396, 421, 432, 398, 420, + 484, 488, 487, 509, 494, 491, 499, 0, 4, 5, + 2, 0, 13, 346, 347, 0, 584, 385, 383, 384, + 386, 387, 0, 0, 3, 0, 12, 416, 0, 586, + 0, 11, 0, 588, 468, 469, 0, 14, 0, 590, + 0, 15, 0, 592, 0, 16, 0, 594, 0, 17, + 0, 585, 541, 539, 540, 542, 543, 587, 0, 589, + 591, 593, 595, 19, 18, 0, 7, 0, 8, 0, 9, 0, 10, 0, 6, 0, 1, 73, 74, 0, 0, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 162, 0, 357, 0, 394, 0, 0, 407, 0, 411, 412, 417, 0, 422, 0, 0, 455, 0, 0, 423, 0, 423, 0, 423, 0, - 502, 560, 0, 601, 0, 612, 626, 613, 627, 614, - 615, 629, 616, 617, 618, 619, 620, 621, 622, 623, - 624, 625, 0, 609, 0, 645, 0, 0, 0, 650, + 503, 561, 0, 602, 0, 613, 627, 614, 628, 615, + 616, 630, 617, 618, 619, 620, 621, 622, 623, 624, + 625, 626, 0, 610, 0, 646, 0, 0, 0, 651, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 75, 76, 608, 0, 0, 633, 635, - 0, 657, 659, 0, 667, 669, 0, 0, 40, 20, + 0, 0, 0, 75, 76, 609, 0, 0, 634, 636, + 0, 658, 660, 0, 668, 670, 0, 0, 40, 20, 37, 38, 39, 41, 42, 0, 163, 21, 22, 26, 0, 25, 35, 0, 164, 154, 361, 0, 0, 446, 447, 369, 400, 0, 0, 0, 0, 399, 0, 0, - 0, 0, 544, 547, 545, 548, 0, 0, 0, 0, + 0, 0, 545, 548, 546, 549, 0, 0, 0, 0, 408, 0, 413, 0, 423, 0, 433, 434, 435, 436, - 0, 0, 458, 457, 451, 0, 572, 472, 0, 0, - 0, 471, 0, 568, 569, 0, 428, 190, 424, 0, - 484, 575, 0, 0, 0, 491, 578, 0, 0, 0, - 496, 581, 0, 0, 0, 514, 510, 190, 190, 0, - 190, 0, 501, 562, 0, 0, 595, 0, 596, 603, - 604, 610, 0, 647, 0, 0, 0, 0, 0, 0, - 0, 652, 0, 0, 0, 34, 27, 0, 33, 23, + 0, 0, 458, 457, 451, 0, 573, 473, 0, 0, + 0, 472, 0, 569, 570, 0, 428, 190, 424, 0, + 485, 576, 0, 0, 0, 492, 579, 0, 0, 0, + 497, 582, 0, 0, 0, 515, 511, 190, 190, 0, + 190, 0, 502, 563, 0, 0, 596, 0, 597, 604, + 605, 611, 0, 648, 0, 0, 0, 0, 0, 0, + 0, 653, 0, 0, 0, 34, 27, 0, 33, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 425, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 506, 505, 0, 0, 503, - 0, 0, 0, 0, 0, 0, 634, 0, 0, 0, - 658, 0, 0, 668, 0, 0, 0, 649, 0, 29, + 0, 0, 0, 0, 0, 507, 506, 0, 0, 504, + 0, 0, 0, 0, 0, 0, 635, 0, 0, 0, + 659, 0, 0, 669, 0, 0, 0, 650, 0, 29, 31, 28, 36, 168, 171, 165, 166, 155, 158, 0, 160, 0, 153, 365, 0, 351, 0, 0, 348, 353, 362, 359, 0, 0, 371, 375, 0, 223, 393, 204, - 205, 206, 207, 0, 0, 0, 448, 0, 0, 521, + 205, 206, 207, 0, 0, 0, 448, 0, 0, 522, 0, 0, 0, 0, 0, 0, 0, 409, 402, 190, - 0, 0, 418, 0, 0, 0, 463, 190, 451, 0, + 0, 0, 418, 0, 0, 0, 464, 190, 451, 0, 450, 459, 190, 0, 0, 0, 0, 0, 0, 190, 190, 429, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 50, 511, 48, 512, 0, 190, 515, 0, - 0, 0, 597, 605, 0, 648, 0, 0, 524, 661, - 0, 0, 693, 80, 0, 0, 32, 0, 0, 0, + 0, 0, 50, 512, 48, 513, 0, 190, 516, 0, + 0, 0, 598, 606, 0, 649, 0, 0, 525, 662, + 0, 0, 694, 80, 0, 0, 32, 0, 0, 0, 0, 350, 355, 0, 354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 388, 0, 0, 0, 0, 0, 0, 0, 390, 0, 0, 0, 0, 0, 415, 24, 410, 0, 0, 0, 452, 453, 0, 0, 0, - 0, 0, 469, 0, 0, 191, 426, 427, 488, 0, - 0, 494, 0, 0, 499, 0, 0, 44, 58, 0, - 45, 49, 0, 509, 504, 513, 0, 0, 0, 0, - 606, 602, 646, 0, 0, 0, 0, 0, 0, 0, - 0, 651, 156, 159, 169, 0, 172, 0, 367, 351, + 0, 0, 470, 0, 0, 191, 426, 427, 489, 0, + 0, 495, 0, 0, 500, 0, 0, 44, 58, 0, + 45, 49, 0, 510, 505, 514, 0, 0, 0, 0, + 607, 603, 647, 0, 0, 0, 0, 0, 0, 0, + 0, 652, 156, 159, 169, 0, 172, 0, 367, 351, 366, 0, 351, 363, 359, 358, 0, 0, 380, 381, 376, 0, 368, 372, 0, 224, 225, 226, 227, 228, 229, 230, 231, 232, 0, 233, 234, 235, 236, 0, - 0, 0, 392, 0, 552, 0, 552, 0, 522, 0, + 0, 0, 392, 0, 553, 0, 553, 0, 523, 0, 0, 0, 0, 0, 199, 198, 190, 190, 0, 401, - 197, 196, 190, 0, 0, 0, 438, 0, 438, 464, + 197, 196, 190, 0, 0, 0, 438, 0, 438, 465, 0, 456, 0, 0, 0, 0, 0, 190, 0, 190, - 0, 190, 0, 190, 48, 0, 59, 0, 0, 563, - 564, 565, 566, 0, 174, 100, 133, 136, 144, 148, - 98, 599, 82, 88, 89, 93, 0, 85, 0, 92, + 0, 190, 0, 190, 48, 0, 59, 0, 0, 564, + 565, 566, 567, 0, 174, 100, 133, 136, 144, 148, + 98, 600, 82, 88, 89, 93, 0, 85, 0, 92, 85, 0, 85, 0, 85, 0, 85, 0, 85, 84, - 0, 597, 582, 607, 637, 536, 656, 665, 0, 661, - 661, 0, 80, 0, 660, 525, 378, 680, 0, 81, - 681, 0, 0, 167, 170, 352, 364, 349, 360, 0, + 0, 598, 583, 608, 638, 537, 657, 666, 0, 662, + 662, 0, 80, 0, 661, 526, 378, 681, 0, 81, + 682, 0, 0, 167, 170, 352, 364, 349, 360, 0, 389, 0, 373, 370, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 543, 0, 546, 391, 549, 550, 404, + 0, 0, 0, 544, 0, 547, 391, 550, 551, 404, 403, 0, 414, 0, 430, 0, 0, 0, 0, 0, - 27, 0, 470, 0, 567, 0, 0, 573, 0, 576, - 0, 579, 0, 46, 0, 43, 68, 0, 0, 53, - 71, 55, 66, 67, 558, 0, 0, 0, 0, 91, + 27, 0, 471, 0, 568, 0, 0, 574, 0, 577, + 0, 580, 0, 46, 0, 43, 68, 0, 0, 53, + 71, 55, 66, 67, 559, 0, 0, 0, 0, 91, 0, 0, 117, 0, 0, 118, 0, 0, 119, 0, - 0, 120, 0, 83, 0, 598, 0, 0, 0, 662, - 663, 0, 664, 0, 0, 0, 0, 0, 683, 685, + 0, 120, 0, 83, 0, 599, 0, 0, 0, 663, + 664, 0, 665, 0, 0, 0, 0, 0, 684, 686, 157, 0, 382, 378, 374, 237, 238, 239, 190, 190, - 190, 190, 552, 190, 190, 551, 552, 556, 517, 202, + 190, 190, 553, 190, 190, 552, 553, 557, 518, 202, 0, 0, 438, 190, 449, 190, 190, 437, 438, 444, - 465, 461, 0, 190, 190, 570, 574, 577, 580, 52, + 466, 461, 0, 190, 190, 571, 575, 578, 581, 52, 48, 71, 60, 0, 0, 70, 190, 96, 85, 94, 0, 90, 85, 87, 101, 0, 85, 85, 85, 134, 0, 85, 85, 137, 0, 85, 145, 0, 149, 150, - 0, 79, 0, 654, 643, 637, 637, 80, 0, 80, - 636, 0, 0, 0, 379, 523, 673, 674, 671, 672, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 554, - 553, 0, 0, 0, 0, 0, 0, 442, 0, 439, + 0, 79, 0, 655, 644, 638, 638, 80, 0, 80, + 637, 0, 0, 0, 379, 524, 674, 675, 672, 673, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 555, + 554, 0, 0, 0, 0, 0, 0, 442, 0, 439, 441, 0, 0, 0, 0, 0, 47, 69, 0, 54, 57, 72, 0, 95, 0, 86, 99, 0, 121, 0, 122, 123, 132, 0, 124, 125, 0, 126, 0, 0, - 173, 638, 639, 0, 640, 0, 642, 27, 0, 655, - 0, 0, 0, 684, 377, 0, 0, 0, 0, 555, - 557, 190, 517, 517, 516, 203, 190, 190, 443, 190, - 445, 188, 186, 185, 187, 466, 0, 190, 460, 0, - 571, 64, 56, 0, 561, 0, 102, 103, 104, 105, - 85, 85, 85, 85, 138, 0, 146, 142, 151, 152, - 0, 80, 0, 0, 537, 378, 0, 0, 688, 689, - 687, 0, 0, 0, 0, 520, 518, 519, 0, 0, - 440, 0, 462, 0, 0, 63, 97, 0, 0, 0, - 0, 127, 128, 129, 130, 0, 0, 0, 147, 641, - 653, 0, 0, 0, 0, 0, 0, 243, 214, 0, - 209, 0, 80, 220, 0, 192, 189, 0, 474, 65, - 0, 61, 106, 107, 108, 109, 110, 111, 85, 139, - 0, 143, 141, 534, 529, 530, 531, 532, 533, 378, - 527, 0, 535, 0, 0, 692, 689, 689, 686, 0, - 213, 0, 0, 208, 0, 218, 0, 219, 0, 0, - 0, 473, 62, 0, 0, 0, 131, 0, 0, 0, - 0, 27, 691, 690, 183, 180, 179, 182, 200, 181, - 201, 217, 345, 175, 177, 0, 176, 0, 215, 244, - 0, 212, 209, 80, 0, 222, 220, 0, 190, 480, - 478, 80, 80, 0, 112, 113, 114, 115, 140, 0, - 526, 194, 675, 190, 0, 0, 0, 0, 211, 210, - 0, 221, 0, 0, 0, 475, 477, 0, 0, 135, - 0, 0, 0, 0, 0, 0, 194, 216, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 297, 246, 248, 250, 252, 0, - 245, 270, 277, 279, 281, 283, 0, 276, 293, 184, - 80, 481, 378, 116, 190, 528, 678, 80, 0, 670, - 694, 0, 0, 0, 0, 0, 0, 0, 0, 240, - 0, 0, 0, 0, 0, 242, 0, 476, 0, 195, - 677, 0, 190, 193, 344, 190, 190, 298, 190, 0, - 241, 340, 190, 190, 247, 190, 0, 190, 249, 342, - 190, 190, 251, 190, 0, 190, 253, 190, 190, 271, - 190, 190, 278, 190, 190, 280, 190, 282, 190, 190, - 284, 190, 294, 190, 479, 0, 0, 299, 302, 0, - 300, 0, 254, 261, 0, 258, 0, 0, 260, 262, - 269, 0, 266, 0, 0, 268, 272, 275, 0, 273, - 285, 0, 287, 288, 289, 0, 291, 292, 295, 296, - 675, 178, 190, 0, 190, 190, 0, 190, 190, 190, - 0, 190, 190, 190, 190, 676, 301, 343, 257, 0, - 255, 0, 259, 265, 0, 263, 341, 267, 274, 286, - 290, 190, 0, 190, 256, 339, 264 + 173, 639, 640, 0, 641, 0, 643, 27, 0, 656, + 0, 0, 0, 685, 377, 0, 0, 0, 0, 556, + 558, 190, 518, 518, 517, 203, 190, 190, 443, 190, + 445, 188, 186, 185, 187, 190, 467, 0, 190, 460, + 0, 572, 64, 56, 0, 562, 0, 102, 103, 104, + 105, 85, 85, 85, 85, 138, 0, 146, 142, 151, + 152, 0, 80, 0, 0, 538, 378, 0, 0, 689, + 690, 688, 0, 0, 0, 0, 521, 519, 520, 0, + 0, 440, 462, 0, 463, 0, 0, 63, 97, 0, + 0, 0, 0, 127, 128, 129, 130, 0, 0, 0, + 147, 642, 654, 0, 0, 0, 0, 0, 0, 243, + 214, 0, 209, 0, 80, 220, 0, 192, 189, 0, + 475, 65, 0, 61, 106, 107, 108, 109, 110, 111, + 85, 139, 0, 143, 141, 535, 530, 531, 532, 533, + 534, 378, 528, 0, 536, 0, 0, 693, 690, 690, + 687, 0, 213, 0, 0, 208, 0, 218, 0, 219, + 0, 0, 0, 474, 62, 0, 0, 0, 131, 0, + 0, 0, 0, 27, 692, 691, 183, 180, 179, 182, + 200, 181, 201, 217, 345, 175, 177, 0, 176, 0, + 215, 244, 0, 212, 209, 80, 0, 222, 220, 0, + 190, 481, 479, 80, 80, 0, 112, 113, 114, 115, + 140, 0, 527, 194, 676, 190, 0, 0, 0, 0, + 211, 210, 0, 221, 0, 0, 0, 476, 478, 0, + 0, 135, 0, 0, 0, 0, 0, 0, 194, 216, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 297, 246, 248, 250, + 252, 0, 245, 270, 277, 279, 281, 283, 0, 276, + 293, 184, 80, 482, 378, 116, 190, 529, 679, 80, + 0, 671, 695, 0, 0, 0, 0, 0, 0, 0, + 0, 240, 0, 0, 0, 0, 0, 242, 0, 477, + 0, 195, 678, 0, 190, 193, 344, 190, 190, 298, + 190, 0, 241, 340, 190, 190, 247, 190, 0, 190, + 249, 342, 190, 190, 251, 190, 0, 190, 253, 190, + 190, 271, 190, 190, 278, 190, 190, 280, 190, 282, + 190, 190, 284, 190, 294, 190, 480, 0, 0, 299, + 302, 0, 300, 0, 254, 261, 0, 258, 0, 0, + 260, 262, 269, 0, 266, 0, 0, 268, 272, 275, + 0, 273, 285, 0, 287, 288, 289, 0, 291, 292, + 295, 296, 676, 178, 190, 0, 190, 190, 0, 190, + 190, 190, 0, 190, 190, 190, 190, 677, 301, 343, + 257, 0, 255, 0, 259, 265, 0, 263, 341, 267, + 274, 286, 290, 190, 0, 190, 256, 339, 264 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -1232, -1232, -1232, -222, -226, -189, -1232, 247, -195, 289, - -1232, -1232, -1232, -1232, -1232, -1232, -196, -342, -662, -56, - -783, -637, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -569, - -252, -1232, -1232, -1232, -849, -1232, -1232, -247, 1222, 1220, - -57, 1263, -1232, -708, -589, -607, -1232, -1232, -169, -1232, - -1232, -168, -1232, -1232, -1232, -167, -321, -1232, -1232, -791, - -1232, -1232, -1232, -1232, -1232, -788, -1232, -1232, -1232, -1232, - -655, -1232, -1232, -1232, 108, -1232, -1232, -1232, -1232, -1232, - 130, -1232, -1232, -503, -1232, -1232, -489, -1232, -1232, -1222, - -1232, -1232, -1232, -1232, -552, 1709, -427, -1231, -565, -1232, - -1232, -1232, -746, -909, -36, -1232, -516, -1232, -1232, -1232, - -1232, -518, -334, 99, -1232, -1232, -315, -1007, -385, -466, - -1008, -980, -1232, -942, -614, -1232, -1232, -1232, -1232, -600, - -1232, -1232, -1232, -1232, -606, -611, -1232, -583, -1232, -776, - -1232, -761, -1232, 711, -412, -190, 514, -417, 29, -245, - -310, 107, -1232, -1232, -1232, 193, -1232, -110, -1232, -77, - -1232, -1232, -1232, -1232, -1232, -1232, -835, -1232, -1232, -1232, - -1232, 635, 637, 638, 640, -283, 531, -1232, -1232, -91, - 41, -1232, -1232, -1232, -1232, -1232, -107, -1232, -1232, -1232, - -1232, 10, -1232, 502, -104, -1232, -1232, -1232, 642, -1232, - -1232, -1232, -620, -1232, -1232, -1232, 580, 584, 510, -174, - 2, 312, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -367, - -798, -966, -1232, -1232, 662, 671, -1232, 232, -1232, -411, - -1232, -1232, -1232, -182, -1232, 675, -1232, -178, -1232, 677, - -1232, -186, -1232, 679, -1232, -187, -1232, -1232, 414, -1232, - -1232, -1232, -1232, -1232, 969, -289, -1232, -1232, -379, -1232, - -1232, -785, -1232, -1232, -1232, -775, -1232, -1232, 687, -1232, - -1232, 625, -1232, 628, -1232, -1232, 230, -618, 234, 241, - 242, 699, -1232, -1232, -1232, -1232, -1232, 717, -1232, -1232, - -1232, -1232, 718, -1232, -1232, 719, -1232, -1232, 727, -1232, - -1232, 738, -188, -344, 109, -1232, -1232, -1232, -1232, -1232, - -1232, -1232, -1232, -1232, -1232, 842, -1232, 539, -179, -1232, - -119, -209, -1232, -1232, -86, -1232, 115, -1232, -1232, -1232, - -808, -1232, -1232, -1232, 549, 16, 887, -1232, -1232, 551, - -1083, -502, -1232, -988, 892, -1232, -1232, -1232, -49, -1232, - -375, -1232, -200 + -1232, -1232, -1232, -221, -226, -189, -1232, 266, -194, 293, + -1232, -1232, -1232, -1232, -1232, -1232, -196, -341, -654, -53, + -782, -642, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -563, + -250, -1232, -1232, -1232, -847, -1232, -1232, -237, 1251, 1249, + -57, 1948, -1232, -665, -567, -574, -1232, -1232, -157, -1232, + -1232, -156, -1232, -1232, -1232, -154, -306, -1232, -1232, -791, + -1232, -1232, -1232, -1232, -1232, -783, -1232, -1232, -1232, -1232, + -657, -1232, -1232, -1232, 110, -1232, -1232, -1232, -1232, -1232, + 143, -1232, -1232, -505, -1232, -1232, -473, -1232, -1232, -1231, + -1232, -1232, -1232, -1232, -557, 1794, -410, -1201, -544, -1232, + -1232, -1232, -748, -930, -37, -1232, -497, -1232, -1232, -1232, + -1232, -500, -334, 124, -1232, -1232, -290, -1018, -364, -446, + -1004, -578, -1232, -852, -597, -1232, -1232, -1232, -1232, -602, + -1232, -1232, -1232, -1232, -729, -588, -1232, -701, -1232, -556, + -1232, -724, -1232, 716, -416, -148, 519, -419, 36, -102, + -326, 101, -1232, -1232, -1232, 188, -1232, -117, -1232, -67, + -1232, -1232, -1232, -1232, -1232, -1232, -836, -1232, -1232, -1232, + -1232, 600, 604, 605, 607, -280, 663, -1232, -1232, -91, + 42, -1232, -1232, -1232, -1232, -1232, -107, -1232, -1232, -1232, + -1232, 10, -1232, 506, -105, -1232, -1232, -1232, 609, -1232, + -1232, -1232, -644, -1232, -1232, -1232, 546, 552, 527, -204, + 4, 277, -1232, -1232, -1232, -1232, -1232, -1232, -1232, -367, + -794, -938, -1232, -1232, 627, 633, -1232, 197, -1232, -448, + -1232, -1232, -1232, -192, -1232, 640, -1232, -185, -1232, 641, + -1232, -186, -1232, 644, -1232, -187, -1232, -1232, 378, -1232, + -1232, -1232, -1232, -1232, 540, -406, -1232, -1232, -384, -1232, + -1232, -781, -1232, -1232, -1232, -796, -1232, -1232, 648, -1232, + -1232, 588, -1232, 590, -1232, -1232, 190, -624, 193, 194, + 195, 660, -1232, -1232, -1232, -1232, -1232, 671, -1232, -1232, + -1232, -1232, 672, -1232, -1232, 673, -1232, -1232, 674, -1232, + -1232, 675, -179, -349, 76, -1232, -1232, -1232, -1232, -1232, + -1232, -1232, -1232, -1232, -1232, 806, -1232, 478, -253, -1232, + -119, -209, -1232, -1232, -109, -1232, 81, -1232, -1232, -1232, + -814, -1232, -1232, -1232, 489, -64, 816, -1232, -1232, 484, + -1087, -552, -1232, -1001, 842, -1232, -1232, -1232, -96, -1232, + -458, -1232, -249 }; /* YYDEFGOTO[NTERM-NUM]. */ @@ -1284,18 +1284,18 @@ static const yytype_int16 yydefgoto[] = -1, 37, 38, 39, 235, 620, 237, 880, 238, 470, 239, 240, 419, 420, 241, 348, 242, 243, 894, 589, 503, 590, 504, 695, 890, 591, 809, 969, 592, 810, - 893, 1032, 1033, 1110, 811, 812, 813, 895, 109, 215, + 893, 1033, 1034, 1112, 811, 812, 813, 895, 109, 215, 382, 456, 922, 609, 749, 819, 712, 713, 714, 715, - 716, 717, 718, 905, 1035, 719, 720, 721, 910, 722, - 723, 914, 1045, 1120, 1199, 724, 1087, 725, 917, 1047, - 726, 727, 920, 1050, 489, 351, 41, 136, 245, 427, - 428, 429, 615, 430, 431, 617, 729, 730, 1172, 1173, - 1174, 1175, 1025, 1026, 874, 383, 667, 1176, 1221, 673, - 668, 1177, 870, 1016, 448, 449, 1143, 450, 1140, 451, - 452, 1147, 453, 649, 650, 651, 858, 1100, 1098, 1103, - 1101, 1180, 1269, 1324, 1332, 1270, 1339, 1276, 1342, 1347, - 1277, 1352, 1294, 1317, 1264, 1325, 1326, 1333, 1334, 1327, - 1319, 1178, 42, 252, 353, 534, 44, 354, 253, 138, + 716, 717, 718, 905, 1036, 719, 720, 721, 910, 722, + 723, 914, 1046, 1122, 1201, 724, 1089, 725, 917, 1048, + 726, 727, 920, 1051, 489, 351, 41, 136, 245, 427, + 428, 429, 615, 430, 431, 617, 729, 730, 1174, 1175, + 1176, 1177, 1026, 1027, 874, 383, 667, 1178, 1223, 673, + 668, 1179, 870, 1016, 448, 449, 1145, 450, 1142, 451, + 452, 1149, 453, 649, 650, 651, 858, 1102, 1100, 1105, + 1103, 1182, 1271, 1326, 1334, 1272, 1341, 1278, 1344, 1349, + 1279, 1354, 1296, 1319, 1266, 1327, 1328, 1335, 1336, 1329, + 1321, 1180, 42, 252, 353, 534, 44, 354, 253, 138, 247, 538, 248, 441, 624, 435, 436, 621, 619, 254, 255, 445, 446, 634, 542, 630, 845, 631, 853, 46, 47, 48, 49, 50, 51, 454, 140, 52, 53, 256, @@ -1303,11 +1303,11 @@ static const yytype_int16 yydefgoto[] = 56, 257, 58, 149, 203, 298, 299, 492, 59, 60, 275, 276, 787, 277, 278, 279, 258, 259, 457, 876, 936, 375, 62, 152, 284, 285, 482, 478, 963, 738, - 680, 881, 1027, 63, 64, 65, 290, 486, 1151, 1192, - 1193, 1282, 66, 67, 68, 69, 70, 71, 72, 73, + 680, 881, 1028, 63, 64, 65, 290, 486, 1153, 1194, + 1195, 1284, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 210, 80, 318, 319, 506, 320, 321, 509, 937, 953, 461, 659, 941, 520, - 746, 739, 1129, 1130, 1131, 740, 741, 1055, 81, 82, + 746, 739, 1131, 1132, 1133, 740, 741, 1056, 81, 82, 83, 260, 84, 261, 85, 86, 262, 770, 263, 264, 265, 87, 88, 162, 324, 325, 703, 89, 292, 293, 294, 295, 90, 303, 304, 91, 308, 309, 92, 313, @@ -1315,8 +1315,8 @@ static const yytype_int16 yydefgoto[] = 96, 182, 97, 183, 184, 938, 218, 219, 837, 99, 186, 334, 335, 516, 336, 191, 342, 343, 927, 928, 742, 743, 100, 221, 222, 605, 939, 102, 224, 225, - 940, 1223, 103, 748, 328, 105, 523, 848, 849, 1059, - 1096, 524, 1060 + 940, 1225, 103, 748, 328, 105, 523, 848, 849, 1060, + 1098, 524, 1061 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -1324,638 +1324,654 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 115, 270, 61, 236, 421, 344, 672, 479, 146, 711, - 57, 337, 187, 188, 339, 737, 347, 532, 943, 291, - 307, 312, 531, 697, 326, 613, 302, 421, 929, 45, - 906, 1053, 519, 907, 842, 808, 911, 871, 772, 345, - 931, 54, 434, 932, 970, 485, 1017, 190, 349, 918, - 1160, 925, 205, 1099, 207, 1099, 1104, 803, 789, 512, - 1, 926, 1316, 1, 19, 21, 1108, 518, 1093, 1168, - 1, 15, 5, 1323, 1323, 1331, 1331, 1314, 1338, 192, - 1323, 193, 464, 194, 195, 249, 196, 144, 114, 34, - 36, 5, 198, 199, 250, 200, 201, 202, 204, 202, - 206, 202, 208, 209, 267, 211, 1168, 212, 40, 5, - 33, 442, 251, 822, 106, 825, 17, 828, 266, 831, - 333, 833, 251, 10, 289, 316, 17, 216, 1392, 217, - 220, 223, 483, 226, 338, 1182, 26, 340, 1104, 26, - 29, 189, 1394, 29, 1170, 1397, 26, 144, 670, 1398, - 29, 422, 1401, 671, 15, 664, 1402, 189, 5, 665, - 282, 425, 5, 145, 1184, 5, 908, 1012, 1187, 912, - 370, 704, 915, 467, 31, 32, 476, 1013, 311, 333, - 134, 1170, 283, 1037, 1075, 1051, 1038, 1421, 350, 1040, - 352, -628, 1423, 33, 525, 1203, 484, 357, 249, 359, - 710, 502, 144, 362, 363, 735, 1048, 250, 513, 364, - 365, 366, 367, 5, 368, 326, 369, 202, 371, 994, - 1092, 996, 526, 145, 734, 1111, 1058, 374, 1355, 626, - 288, 968, 378, 379, 1288, 380, 485, 246, 891, 274, - 1188, 384, 706, 707, 948, 386, 387, 924, 951, 850, - 389, 390, 956, 966, 731, 392, 393, 627, 961, 682, - -630, 1152, 2, 398, 144, 708, 709, 401, 476, 661, - 403, 587, 4, 588, 447, 560, 5, 405, 145, 408, - 409, 411, 412, 414, 5, 415, 1112, 600, 2, 1113, - 1115, 973, 2, 704, 1158, 975, 1134, 735, 4, 978, - 980, 981, 4, 5, 984, 985, 7, 5, 987, 19, - 297, 1284, 10, 296, -51, 301, 588, 317, 246, 1039, - 1136, 12, 1041, 338, 1042, 1107, 340, 899, 1043, 903, - 459, -631, 903, 251, 34, 903, 315, 316, 903, 5, - 145, 903, 5, 1089, 246, 433, 707, 633, 704, -632, - 493, 704, 670, 496, 1328, 807, 499, 671, 476, 24, - 1345, 323, 5, 31, 32, 1194, 5, 443, 708, 709, - 527, 528, 341, 473, 463, 708, 709, 352, 533, 709, - 536, 1183, 1312, 664, 537, 539, 540, 665, 541, 1191, - 107, 108, 687, 694, 1145, 868, 696, 691, 546, 693, - 547, 548, 689, 549, 733, 551, 552, 762, 554, 555, - 326, 556, 558, 1201, 1287, 346, 562, 563, 564, 423, - 424, 374, 1114, 1116, 1117, 1118, 569, 570, -30, 755, - 573, 574, 757, 1081, 1082, 1083, 1084, 579, 580, 531, - 582, 583, 229, 585, 586, 213, 214, 1308, 421, 851, - 859, 860, 861, 596, 597, 598, 654, 656, 1225, 1226, - 603, 444, 604, 1021, 607, 532, 608, 1022, 1023, 1024, - 653, 655, 676, 678, 5, 1209, 7, 1321, 883, 1314, - 21, 882, 477, 1215, 1216, 306, 675, 677, 903, 459, - 903, 751, 490, 447, 903, 5, 5, 686, 1195, 1196, - 1197, 696, 329, 330, 704, 36, 1135, 705, 706, 707, - 652, 1156, 518, 657, 1189, 660, 522, 1318, 662, 663, - 423, 1335, 1335, 517, 1340, 1344, 674, 1349, 1349, 521, - 1353, 708, 709, 710, 134, 228, 229, 685, 230, 231, - 232, 233, 234, 688, 424, 5, 690, 5, 433, 692, - 1171, 807, 1314, 1181, 704, 752, 587, 1185, 706, 707, - 698, 1190, 533, 1283, 5, 533, 854, 537, 747, 759, - 1164, 805, 1307, 704, 1165, 1166, 1167, 705, 707, 1310, - 5, 708, 709, 1321, 670, 1314, 921, 764, 1395, 671, - 588, 903, 765, 766, 767, 1399, 768, 769, 771, 769, - 708, 709, 774, 1097, 1271, 1403, 1278, 709, 889, 1404, - 5, 696, 892, 884, 1329, 1314, 469, 1227, 785, 786, - 788, 786, 154, 790, 156, 791, 158, 793, 160, 795, - 233, 234, 1169, 1286, 1057, 418, 502, 913, 942, 804, - 916, 618, 971, 141, 967, 623, 815, 897, 150, 900, - 153, 901, 155, 1036, 157, 421, 159, 612, 816, 1121, - 818, 1292, 864, 821, 666, 824, 1208, 827, 1211, 830, - 684, 830, 628, 629, 598, 708, 709, 836, 1102, 875, - 1186, -59, 604, 604, 1336, 608, -59, -59, -59, 844, - 1343, 807, 246, 433, 847, 1164, 1097, 696, 892, 1165, - 1166, 1167, 1168, 1164, 1350, 5, 728, 1165, 1166, 1167, - 1168, 43, 728, 5, 704, 287, 728, 705, 706, 707, - 1348, 1348, 704, 1066, 1067, 705, 706, 707, 1057, 622, - 1164, 758, 807, 933, 1165, 1166, 1167, 855, 856, 857, - 5, 708, 709, 710, 1329, 1314, 991, 992, 1164, 708, - 709, 710, 1165, 1166, 1167, 839, 840, 1169, 5, 1015, - 1015, 1162, 1163, 1314, 165, 1169, 166, 167, 807, 168, - 1164, 169, 1031, 1052, 1165, 1166, 1167, 1170, 862, 280, - 5, 866, 1123, 281, 1019, 1170, 1124, 1125, 1126, 1127, - 566, 170, 1169, 502, 759, 872, 844, 1044, 878, 1046, - 171, 10, 683, 1280, 172, 769, 173, 1074, 174, 769, - 1169, 952, 507, 954, 955, 786, 175, 896, 958, 421, - 268, 786, 251, 269, 962, 791, 17, 699, 176, 134, - 228, 700, 1169, 230, 231, 232, 286, 696, 701, 702, - 835, 830, 98, 974, 1128, 830, 177, 178, 179, 977, - 979, 830, 31, 32, 983, 830, 180, 986, 830, 1422, - 988, 228, 229, 989, 230, 231, 232, 181, 836, 836, - 993, 458, 608, 406, 997, 998, 228, 863, 1109, 230, - 231, 232, 474, 475, 1001, 1002, 410, 101, 1405, 3, - 413, 488, 104, 1003, 873, 1137, 1119, 6, 495, 0, - 0, 498, 0, 0, 501, 0, 8, 0, 0, 0, - 0, 0, 511, 9, 696, 228, 11, 0, 230, 231, - 232, 233, 234, 805, 898, 806, 902, 0, 0, 902, - 0, 16, 902, 0, 0, 902, 0, 0, 902, 0, - 0, 0, 18, 1056, 728, 20, 0, 22, 1061, 1062, - 1063, 1064, 934, 0, 1015, 952, 952, 0, 25, 0, - 27, 0, 28, 0, 30, 0, 0, 0, 1198, 0, - 35, 0, 1073, 0, 0, 0, 0, 0, 0, 1077, - 1078, 1079, 1097, 1080, 830, 830, 830, 0, 1085, 476, - 1086, 5, 0, 0, 608, 0, 1091, 5, 844, 0, - 704, 0, 1095, 705, 706, 707, 704, 0, 0, 705, - 706, 707, 0, 0, 0, 0, 0, 0, 735, 0, - 0, 0, 923, 736, 0, 1015, 0, 708, 709, 710, - 0, 0, 0, 708, 709, 710, 0, 0, 0, 0, - 0, 1139, 0, 1142, 0, 608, 1146, 0, 0, 0, - 1149, 1150, 0, 0, 0, 1153, 1154, 0, 1155, 0, - 1011, 830, 0, 1157, 0, 0, 0, 0, 0, 5, - 0, 0, 844, 0, 0, 0, 0, 1161, 704, 1095, - 1095, 705, 706, 707, 0, 902, 0, 902, 0, 0, - 0, 902, 0, 1164, 0, 736, 1015, 1165, 1166, 1167, - 1168, 728, 0, 5, 0, 708, 709, 710, 0, 0, - 0, 0, 704, 0, 0, 705, 706, 707, 0, 0, - 0, 1206, 1189, 1207, 0, 1142, 608, 1210, 0, 1146, - 1212, 0, 0, 0, 1214, 608, 0, 1218, 0, 708, - 709, 710, 0, 0, 1220, 1222, 0, 0, 0, 0, - 476, 0, 0, 0, 0, 1169, 228, 229, 5, 230, - 231, 232, 233, 234, 0, 1393, 806, 704, 1291, 1220, - 705, 706, 707, 0, 0, 1170, 0, 1396, 0, 735, - 0, 0, 0, 0, 1400, 134, 228, 229, 902, 230, - 231, 232, 233, 234, 708, 709, 710, 0, 0, 0, - 0, 0, 0, 728, 0, 0, 0, 1293, 1295, 1296, - 1297, 1298, 0, 0, 1300, 1301, 1302, 1303, 1304, 476, - 0, 1306, 0, 608, 0, 844, 0, 5, 228, 0, - 608, 230, 231, 232, 233, 234, 704, 0, 806, 705, - 706, 707, 0, 0, 0, 0, 0, 728, 735, 0, - 728, 0, 0, 736, 728, 0, 0, 0, 728, 0, - 0, 1359, 0, 708, 709, 710, 0, 110, 1364, 0, - 1367, 0, 0, 0, 111, 112, 1371, 113, 1374, 0, - 116, 0, 117, 1378, 118, 0, 1381, 0, 119, 0, - 120, 1385, 121, 0, 122, 0, 123, 0, 124, 0, - 125, 0, 126, 0, 0, 0, 0, 0, 0, 0, - 127, 0, 0, 0, 728, 0, 0, 128, 0, 129, - 0, 130, 728, 131, 0, 132, 0, 133, 0, 0, - 728, 460, 462, 1222, 0, 465, 466, 0, 1409, 1411, - 228, 229, 1414, 230, 231, 232, 233, 234, 0, 487, - 0, 0, 0, 0, 0, 0, 494, 0, 0, 497, - 0, 0, 500, 0, 0, 0, 0, 0, 0, 197, - 510, 0, 135, 137, 139, 139, 142, 0, 0, 148, - 139, 151, 139, 148, 139, 148, 139, 148, 139, 148, - 161, 163, 0, 185, 185, 185, 0, 0, 0, 0, - 0, 1315, 0, 1322, 1322, 1330, 1330, 0, 1337, 1341, - 1322, 1346, 1346, 227, 1351, 0, 3, 0, 0, 0, - 0, 0, 0, 300, 6, 305, 0, 310, 0, 5, - 322, 0, 0, 8, 0, 0, 0, 0, 704, 0, - 9, 705, 706, 707, 0, 0, 0, 0, 0, 0, - 0, 0, 14, 0, 0, 244, 0, 0, 16, 0, - 272, 0, 0, 0, 0, 708, 709, 710, 0, 18, - 355, 0, 20, 0, 22, 356, 0, 358, 0, 0, - 360, 361, 0, 0, 0, 25, 5, 27, 0, 28, - 0, 30, 0, 0, 0, 704, 0, 35, 705, 706, - 707, 0, 372, 373, 0, 0, 0, 376, 0, 0, - 377, 0, 736, 0, 747, 0, 0, 381, 0, 0, - 0, 385, 708, 709, 710, 0, 388, 0, 0, 0, - 0, 391, 0, 0, 0, 0, 394, 0, 0, 0, - 0, 397, 0, 400, 0, 0, 0, 402, 0, 0, - 0, 0, 0, 0, 404, 0, 0, 407, 0, 0, - 0, 0, 0, 0, 417, 416, 0, 0, 0, 0, - 0, 432, 0, 438, 439, 635, 636, 637, 638, 639, - 640, 641, 642, 643, 644, 645, 646, 647, 648, 0, - 472, 0, 0, 0, 0, 480, 635, 636, 637, 638, - 639, 640, 641, 642, 643, 0, 0, 0, 0, 0, - 0, 0, 0, 426, 0, 0, 0, 0, 440, 137, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 481, - 137, 0, 0, 0, 0, 0, 0, 0, 491, 0, - 0, 529, 0, 530, 0, 0, 0, 0, 535, 0, - 505, 0, 0, 508, 0, 0, 0, 0, 543, 0, - 515, 0, 0, 0, 545, 544, 0, 0, 0, 3, - 0, 0, 0, 550, 553, 0, 5, 6, 0, 0, - 0, 561, 0, 0, 0, 704, 8, 0, 705, 706, - 707, 567, 0, 9, 0, 0, 572, 571, 0, 0, - 0, 0, 577, 578, 0, 14, 581, 0, 0, 584, - 0, 16, 708, 709, 710, 0, 593, 0, 0, 595, - 0, 0, 18, 0, 601, 20, 602, 22, 0, 0, - 0, 0, 606, 0, 0, 611, 610, 0, 25, 0, - 27, 0, 28, 0, 30, 0, 0, 0, 625, 0, - 35, 0, 632, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 669, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 681, 0, - 0, 0, 614, 616, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 658, 0, 0, 0, 0, 0, 732, - 0, 0, 0, 0, 0, 744, 0, 0, 0, 750, - 679, 0, 0, 0, 0, 753, 0, 754, 0, 0, - 0, 756, 0, 0, 0, 0, 0, 760, 0, 0, - 0, 0, 0, 761, 763, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 745, - 0, 0, 0, 185, 0, 0, 0, 773, 0, 0, - 775, 776, 777, 778, 0, 0, 0, 0, 0, 0, - 781, 0, 0, 0, 784, 783, 0, 0, 0, 0, - 0, 0, 0, 792, 0, 794, 0, 0, 797, 0, - 799, 0, 801, 0, 0, 0, 0, 0, 814, 0, + 115, 672, 270, 236, 61, 421, 344, 479, 146, 291, + 57, 337, 187, 188, 339, 532, 347, 943, 531, 302, + 307, 312, 929, 613, 190, 1017, 434, 519, 421, 697, + 906, 711, 772, 326, 789, 871, 45, 737, 907, 345, + 926, 911, 54, 808, 931, 485, 970, 932, 1162, 349, + 918, 205, 803, 207, 512, 925, 1095, 1110, 1101, 1054, + 1101, 1106, 106, 1, 144, 670, 1325, 1325, 1333, 1333, + 671, 1340, 518, 1325, 15, 5, 114, 842, 249, 192, + 2, 193, 1, 194, 195, 464, 196, 250, 1170, 144, + 4, 5, 198, 199, 1318, 200, 201, 202, 204, 202, + 206, 202, 208, 209, 267, 211, 144, 212, 144, 189, + 40, 338, 476, 33, 340, 251, 1, 5, 447, 17, + 5, 5, 2, 134, 10, 333, 1184, 216, 266, 217, + 220, 223, 4, 226, 289, 1396, 246, 433, 1399, 26, + 145, 735, 1400, 29, 1106, 1403, 822, 333, 825, 1404, + 828, 422, 831, 189, 833, 316, 1013, 249, 26, 282, + 1394, 425, 29, 1172, 908, 145, 250, 912, 251, 370, + 915, 1012, 17, 19, 467, 31, 32, 476, 246, 1052, + 1423, 283, 145, 1038, 145, 1425, 484, 1077, 350, -629, + 352, 1039, 26, 5, 1041, 525, 29, 357, 34, 359, + -631, 502, 704, 362, 363, 1059, 735, 1049, 513, 364, + 365, 366, 367, 626, 368, -632, 369, 202, 371, 734, + 1094, 1190, 526, 1290, 326, 1205, 1357, 374, 956, 1113, + 707, 710, 378, 379, 961, 380, 485, 288, 948, 968, + 274, 384, 951, 682, 891, 386, 387, 850, 966, 731, + 389, 390, 708, 709, 442, 392, 393, 107, 108, 21, + 627, 2, 994, 398, 996, 1154, 15, 401, 19, 924, + 403, 4, 661, 246, 301, 483, 560, 405, 10, 408, + 409, 411, 412, 414, 36, 415, 1170, 600, 1114, 5, + 311, 7, 1286, 34, 1316, 1160, 1115, 1117, 5, 251, + 338, 1138, 1136, 340, 1125, 33, 12, 704, 1126, 1127, + 1128, 1129, 297, 670, 587, 459, 588, 1040, 671, 317, + 1042, 5, 1043, 5, 973, 1109, 1044, 296, 975, 31, + 32, 5, 978, 980, 981, 709, 664, 984, 985, 323, + 665, 987, -633, 899, 24, 903, 5, 633, 903, 493, + 5, 903, 496, 5, 903, 499, 807, 903, 1316, 704, + -51, 1172, 588, 1314, 315, 316, 1130, 443, 706, 707, + 527, 528, 1196, 476, 463, 473, 341, 352, 533, 664, + 536, 5, 687, 665, 537, 539, 540, 1091, 541, 21, + 868, 708, 709, 694, 306, 689, 696, 691, 546, 693, + 547, 548, 346, 549, 733, 551, 552, 762, 554, 555, + 1289, 556, 558, 1203, 36, -30, 562, 563, 564, 326, + 1185, 374, 1116, 1118, 1119, 1120, 569, 570, 1193, 5, + 573, 574, 1323, 851, 1316, 531, 229, 579, 580, 1147, + 582, 583, 5, 585, 586, 670, 1330, 444, 1310, 421, + 671, 704, 1347, 596, 597, 598, 654, 656, 1227, 1228, + 603, 459, 604, 532, 607, 882, 608, 1083, 1084, 1085, + 1086, 755, 676, 678, 757, 859, 860, 861, 708, 709, + 653, 655, 1166, 1273, 477, 1280, 1167, 1168, 1169, 517, + 7, 751, 5, 447, 490, 521, 675, 677, 1197, 1198, + 1199, 696, 10, 883, 903, 5, 903, 686, 522, 652, + 903, 5, 657, 423, 660, 1331, 1316, 662, 663, 424, + 1211, 213, 214, 251, 518, 674, -59, 17, 1217, 1218, + 1137, -59, -59, -59, 134, 228, 685, 286, 230, 231, + 232, 433, 688, 747, 1171, 690, 1158, 5, 692, 855, + 856, 857, 807, 31, 32, 752, 704, 329, 330, 698, + 706, 707, 533, 1285, 5, 533, 854, 537, 1186, 759, + 233, 234, 1189, 704, 1173, 628, 629, 1183, 707, 246, + 433, 1187, 587, 708, 709, 1192, 805, 764, 708, 709, + 423, 424, 765, 766, 767, 705, 768, 769, 771, 769, + 708, 709, 774, 884, 1350, 1350, 1067, 1068, 889, 903, + 228, 696, 892, 230, 231, 232, 921, 1309, 785, 786, + 788, 786, 588, 790, 1312, 791, 154, 793, 156, 795, + 158, 1099, 160, 709, 1058, 469, 502, 913, 942, 418, + 916, 1229, 804, 618, 971, 228, 815, 623, 230, 231, + 232, 233, 234, 805, 967, 806, 421, 1288, 816, 897, + 818, 900, 864, 821, 901, 824, 666, 827, 1037, 830, + 612, 830, 991, 992, 598, 839, 840, 836, 1123, 875, + 1164, 1165, 604, 604, 1294, 608, 1166, 1210, 1213, 844, + 1167, 1168, 1169, 807, 847, 684, 5, 696, 892, 1323, + 1104, 1316, 1188, 1338, 1352, 134, 228, 229, 728, 230, + 231, 232, 233, 234, 728, 1345, 43, 1166, 728, 1099, + 287, 1167, 1168, 1169, 622, 758, 933, 5, 5, 165, + 1058, 1331, 1316, 166, 167, 807, 168, 704, 169, 1320, + 705, 706, 707, 1337, 1337, 280, 1342, 1346, 1171, 1351, + 1351, 281, 1355, 1021, 1019, 566, 170, 1022, 1023, 1024, + 1015, 1015, 171, 5, 708, 709, 710, 683, 1282, 172, + 173, 807, 1032, 174, 1053, 141, 507, 175, 862, 1171, + 150, 866, 153, 268, 155, 269, 157, 699, 159, 176, + 700, 701, 702, 502, 759, 872, 844, 1045, 878, 1047, + 177, 178, 179, 180, 181, 769, 98, 835, 1076, 769, + 1397, 952, 406, 954, 955, 786, 101, 1401, 958, 896, + 3, 786, 421, 413, 962, 791, 410, 1405, 6, 228, + 229, 1406, 230, 231, 232, 233, 234, 8, 696, 806, + 1407, 830, 104, 974, 9, 830, 1003, 11, 1139, 977, + 979, 830, 0, 0, 983, 830, 1424, 986, 830, 0, + 988, 0, 16, 989, 0, 0, 0, 0, 836, 836, + 993, 0, 608, 18, 997, 998, 20, 1166, 22, 863, + 1111, 1167, 1168, 1169, 1001, 1002, 0, 5, 458, 25, + 0, 27, 1316, 28, 0, 30, 873, 0, 1121, 474, + 475, 35, 460, 462, 0, 0, 465, 466, 488, 228, + 229, 0, 230, 231, 232, 495, 696, 0, 498, 0, + 487, 501, 0, 0, 0, 0, 898, 494, 902, 511, + 497, 902, 0, 500, 902, 0, 0, 902, 0, 1171, + 902, 510, 0, 1057, 0, 0, 728, 0, 1062, 1063, + 1064, 1065, 0, 0, 934, 952, 952, 1015, 0, 228, + 0, 0, 230, 231, 232, 233, 234, 0, 0, 806, + 1200, 228, 229, 1075, 230, 231, 232, 233, 234, 0, + 1079, 1080, 1081, 0, 1082, 830, 830, 830, 0, 1087, + 0, 1088, 0, 0, 0, 608, 0, 1093, 0, 844, + 0, 0, 0, 1097, 0, 0, 0, 0, 1166, 1099, + 0, 0, 1167, 1168, 1169, 1170, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 0, 0, 704, 1015, 0, + 705, 706, 707, 635, 636, 637, 638, 639, 640, 641, + 642, 643, 0, 1141, 0, 1144, 0, 608, 1148, 0, + 0, 0, 1151, 1152, 708, 709, 710, 1155, 1156, 0, + 1157, 0, 1011, 830, 5, 1159, 0, 0, 0, 0, + 1171, 5, 1025, 704, 844, 0, 705, 706, 707, 1163, + 704, 1097, 1097, 705, 706, 707, 0, 902, 0, 902, + 1172, 0, 0, 902, 0, 0, 0, 736, 0, 1015, + 708, 709, 710, 728, 0, 0, 0, 708, 709, 710, + 0, 1166, 0, 0, 0, 1167, 1168, 1169, 1170, 0, + 0, 5, 0, 1208, 0, 1209, 0, 1144, 608, 1212, + 704, 1148, 1214, 705, 706, 707, 1216, 608, 0, 1220, + 1191, 0, 0, 476, 0, 0, 1222, 1224, 0, 0, + 0, 5, 0, 0, 0, 0, 0, 708, 709, 710, + 704, 0, 0, 705, 706, 707, 0, 1395, 0, 0, + 1293, 1222, 735, 1171, 0, 0, 923, 736, 0, 1398, + 0, 0, 0, 0, 0, 0, 1402, 708, 709, 710, + 0, 0, 902, 1172, 0, 134, 228, 229, 0, 230, + 231, 232, 233, 234, 0, 0, 0, 728, 0, 1295, + 1297, 1298, 1299, 1300, 0, 0, 1302, 1303, 1304, 1305, + 1306, 476, 0, 1308, 0, 608, 0, 844, 0, 5, + 0, 0, 608, 0, 0, 0, 0, 0, 704, 0, + 0, 705, 706, 707, 0, 0, 0, 0, 0, 0, + 735, 728, 0, 0, 728, 736, 0, 0, 728, 0, + 0, 0, 728, 1361, 0, 708, 709, 710, 0, 0, + 1366, 0, 1369, 0, 0, 0, 0, 0, 1373, 0, + 1376, 0, 0, 0, 0, 1380, 0, 0, 1383, 0, + 0, 0, 0, 1387, 0, 0, 110, 0, 0, 0, + 0, 0, 0, 111, 112, 0, 113, 0, 0, 116, + 0, 117, 0, 118, 0, 0, 0, 119, 728, 120, + 0, 121, 0, 122, 0, 123, 728, 124, 0, 125, + 0, 126, 0, 0, 728, 1224, 0, 0, 0, 127, + 1411, 1413, 0, 0, 1416, 0, 128, 0, 129, 0, + 130, 0, 131, 0, 132, 1166, 133, 5, 0, 1167, + 1168, 1169, 1170, 0, 0, 5, 704, 0, 0, 705, + 706, 707, 0, 0, 704, 0, 0, 705, 706, 707, + 0, 0, 0, 736, 0, 747, 0, 0, 0, 0, + 0, 0, 0, 708, 709, 710, 0, 0, 197, 0, + 0, 708, 709, 710, 0, 1317, 0, 1324, 1324, 1332, + 1332, 0, 1339, 1343, 1324, 1348, 1348, 1171, 1353, 3, + 0, 0, 0, 0, 476, 0, 5, 6, 0, 0, + 0, 0, 5, 0, 0, 704, 8, 1172, 705, 706, + 707, 704, 227, 9, 705, 706, 707, 0, 0, 3, + 0, 0, 300, 735, 305, 14, 310, 6, 0, 322, + 0, 16, 708, 709, 710, 0, 8, 0, 708, 709, + 710, 0, 18, 9, 0, 20, 0, 22, 0, 0, + 0, 0, 0, 0, 0, 14, 0, 0, 25, 0, + 27, 16, 28, 0, 30, 0, 0, 0, 0, 355, + 35, 0, 18, 0, 356, 20, 358, 22, 0, 360, + 361, 0, 0, 0, 0, 0, 0, 0, 25, 0, + 27, 0, 28, 0, 30, 0, 0, 0, 0, 0, + 35, 372, 373, 0, 0, 0, 376, 0, 0, 377, + 0, 0, 0, 0, 5, 0, 381, 0, 0, 0, + 385, 0, 0, 704, 0, 388, 705, 706, 707, 0, + 391, 0, 0, 1191, 0, 394, 0, 0, 0, 0, + 397, 0, 400, 0, 0, 0, 402, 0, 1, 2, + 708, 709, 710, 404, 3, 0, 407, 0, 0, 4, + 0, 5, 6, 417, 416, 0, 0, 0, 7, 0, + 432, 8, 438, 439, 0, 0, 0, 0, 9, 10, + 0, 11, 0, 12, 0, 0, 0, 0, 13, 472, + 14, 0, 0, 15, 480, 0, 16, 0, 0, 0, + 0, 0, 0, 0, 17, 0, 0, 18, 0, 19, + 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, + 23, 24, 0, 25, 26, 27, 0, 28, 29, 30, + 31, 32, 33, 0, 34, 35, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 817, 0, - 820, 0, 0, 823, 0, 826, 0, 829, 0, 832, - 0, 0, 834, 0, 0, 0, 0, 0, 0, 0, - 838, 0, 0, 841, 0, 843, 0, 0, 0, 0, - 846, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 529, 0, 530, 0, 0, 0, 0, 535, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 543, 0, 0, + 0, 0, 0, 545, 544, 0, 0, 0, 0, 0, + 0, 0, 550, 553, 0, 0, 0, 0, 0, 0, + 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 567, 0, 0, 0, 0, 572, 571, 0, 0, 0, + 0, 577, 578, 0, 0, 581, 0, 0, 584, 0, + 0, 0, 0, 0, 0, 593, 0, 0, 595, 0, + 0, 0, 0, 601, 0, 602, 0, 0, 0, 0, + 0, 606, 0, 0, 611, 610, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 625, 0, 0, + 0, 632, 635, 636, 637, 638, 639, 640, 641, 642, + 643, 644, 645, 646, 647, 648, 669, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 865, 0, 867, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 877, 0, 879, - 0, 0, 0, 0, 0, 0, 885, 0, 886, 0, - 887, 0, 888, 0, 852, 0, 395, 396, 0, 399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 869, 0, 869, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 930, 0, 0, - 0, 0, 0, 0, 0, 935, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 732, 0, + 0, 0, 0, 0, 744, 0, 0, 0, 750, 0, + 0, 0, 0, 0, 753, 0, 754, 0, 0, 0, + 756, 0, 0, 0, 0, 0, 760, 0, 0, 0, + 0, 0, 761, 763, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 904, 0, 0, 909, 0, 0, 0, - 0, 0, 0, 0, 0, 919, 0, 0, 0, 0, - 0, 679, 0, 0, 679, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 773, 0, 0, 775, + 776, 777, 778, 0, 0, 0, 0, 0, 0, 781, + 0, 0, 0, 784, 783, 0, 0, 0, 0, 0, + 0, 0, 792, 0, 794, 0, 0, 797, 0, 799, + 0, 801, 0, 0, 0, 0, 0, 814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 976, 0, 0, 0, 0, - 982, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 990, 0, 0, 0, 0, 0, 0, 0, - 995, 0, 0, 999, 0, 0, 0, 0, 0, 0, - 1000, 0, 0, 1004, 1005, 1006, 1007, 1008, 1009, 0, - 0, 1010, 0, 1014, 0, 0, 1018, 0, 559, 0, - 0, 1020, 0, 1028, 1029, 1030, 565, 0, 0, 0, - 0, 568, 1034, 0, 0, 0, 0, 0, 575, 576, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1228, - 1229, 1230, 1231, 1232, 1233, 1234, 594, 1235, 1236, 1237, - 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, - 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, - 1258, 0, 0, 1259, 1260, 1261, 1262, 1263, 1071, 0, - 0, 0, 1049, 0, 0, 1076, 0, 0, 0, 0, - 0, 1054, 0, 0, 0, 0, 0, 0, 0, 0, - 1088, 0, 1090, 0, 0, 0, 0, 0, 0, 1094, - 0, 0, 0, 0, 0, 0, 0, 0, 1105, 1106, + 0, 0, 0, 0, 0, 0, 0, 817, 0, 820, + 0, 0, 823, 0, 826, 0, 829, 0, 832, 0, + 0, 834, 0, 0, 0, 0, 0, 0, 0, 838, + 0, 0, 841, 0, 843, 0, 0, 0, 0, 846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1122, 0, 0, - 0, 0, 1132, 0, 0, 1133, 1138, 0, 0, 0, - 0, 1141, 0, 1144, 0, 0, 1148, 0, 0, 0, - 0, 0, 0, 0, 869, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 865, + 0, 867, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 877, 0, 879, 0, + 0, 0, 0, 0, 0, 885, 0, 886, 0, 887, + 0, 888, 0, 0, 0, 0, 0, 135, 137, 139, + 139, 142, 0, 0, 148, 139, 151, 139, 148, 139, + 148, 139, 148, 139, 148, 161, 163, 0, 185, 185, + 185, 0, 0, 0, 0, 0, 930, 0, 0, 0, + 0, 0, 0, 0, 935, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1159, 0, 0, 0, 679, 0, 0, + 0, 395, 396, 0, 399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 779, 780, 0, 1200, 0, - 1202, 782, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 796, 1204, 798, 1205, - 800, 0, 802, 0, 1179, 0, 0, 1179, 0, 0, - 0, 1179, 0, 0, 0, 1217, 0, 0, 0, 1219, - 0, 0, 869, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1279, 0, 0, 0, 0, 0, 0, - 0, 1285, 0, 1289, 1290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 869, 869, 0, + 244, 0, 0, 0, 0, 272, 0, 0, 0, 0, + 0, 0, 0, 0, 976, 0, 0, 0, 0, 982, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1281, 0, 0, 0, 0, 0, 0, 0, 0, 1299, - 0, 0, 0, 0, 0, 0, 1305, 0, 0, 0, + 0, 990, 0, 0, 0, 0, 0, 0, 0, 995, + 0, 0, 999, 0, 0, 0, 0, 0, 0, 1000, + 0, 0, 1004, 1005, 1006, 1007, 1008, 1009, 0, 0, + 1010, 0, 1014, 0, 0, 1018, 0, 0, 0, 0, + 1020, 0, 1029, 1030, 1031, 0, 0, 0, 0, 0, + 0, 1035, 1267, 1230, 1231, 1232, 1233, 1234, 1235, 1236, + 1268, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, + 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, + 1256, 1257, 1258, 1259, 1260, 1269, 1270, 1261, 1262, 1263, + 1264, 1265, 0, 559, 0, 0, 0, 0, 0, 0, + 0, 565, 0, 0, 0, 0, 568, 0, 1073, 0, + 0, 0, 0, 575, 576, 1078, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 426, 0, + 1090, 594, 1092, 440, 137, 0, 0, 0, 0, 1096, + 0, 0, 0, 0, 0, 0, 0, 0, 1107, 1108, + 0, 0, 0, 0, 481, 137, 0, 0, 0, 0, + 0, 0, 0, 491, 0, 0, 0, 0, 1124, 0, + 0, 0, 0, 1134, 0, 505, 1135, 1140, 508, 0, + 0, 0, 1143, 0, 1146, 515, 0, 1150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1311, 0, 1313, 0, 1320, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1361, 0, 0, 0, 0, 0, 0, 1366, 0, - 0, 0, 0, 0, 0, 0, 1373, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 944, 945, 946, - 947, 0, 949, 950, 0, 1390, 1391, 1, 2, 0, - 0, 0, 957, 3, 959, 960, 0, 0, 4, 0, - 5, 6, 964, 965, 0, 0, 0, 7, 0, 0, - 8, 0, 0, 0, 0, 972, 0, 9, 10, 0, - 11, 0, 12, 1407, 0, 0, 0, 13, 0, 14, - 1416, 0, 15, 0, 0, 16, 0, 0, 0, 0, - 0, 0, 0, 17, 0, 0, 18, 0, 19, 20, - 21, 22, 1425, 0, 0, 0, 0, 0, 0, 23, - 24, 0, 25, 26, 27, 0, 28, 29, 30, 31, - 32, 33, 0, 34, 35, 36, 1265, 1228, 1229, 1230, - 1231, 1232, 1233, 1234, 1266, 1235, 1236, 1237, 1238, 1239, - 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, - 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1267, - 1268, 1259, 1260, 1261, 1262, 1263, 0, 0, 0, 0, + 0, 0, 0, 0, 1161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1065, 0, 0, 0, 0, 1068, 1069, 0, 1070, 0, - 0, 0, 0, 0, 0, 0, 1072, 1272, 1228, 1229, - 1230, 1231, 1232, 1233, 1234, 1273, 1235, 1236, 1237, 1238, - 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, - 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, - 1274, 1275, 1259, 1260, 1261, 1262, 1263, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1202, + 0, 1204, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1206, 0, + 1207, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1219, 0, 0, 0, + 1221, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 779, 780, 0, 0, 1281, 0, 782, 0, 0, 0, + 0, 0, 1287, 0, 1291, 1292, 0, 614, 616, 0, + 0, 796, 0, 798, 0, 800, 0, 802, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 658, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 679, 0, 0, 0, 0, + 1301, 0, 0, 0, 0, 0, 0, 1307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1313, 0, 1315, 0, 1322, 0, 0, 0, 0, + 0, 0, 0, 0, 745, 0, 0, 0, 185, 1356, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1363, 0, 0, 0, 0, 0, 0, 1368, + 0, 0, 0, 0, 0, 0, 0, 1375, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1392, 1393, 0, 0, + 0, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 0, 1237, + 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, + 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, + 1258, 1259, 1260, 0, 1409, 1261, 1262, 1263, 1264, 1265, + 0, 1418, 944, 945, 946, 947, 0, 949, 950, 0, + 0, 0, 0, 0, 0, 0, 0, 957, 0, 959, + 960, 0, 0, 1427, 0, 0, 0, 964, 965, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 972, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 852, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 869, + 0, 869, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 904, 0, + 0, 909, 0, 0, 0, 0, 0, 0, 0, 0, + 919, 0, 0, 0, 0, 0, 679, 0, 0, 679, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1066, 0, 0, 0, 0, + 1069, 1070, 0, 1071, 0, 0, 0, 0, 0, 1072, + 0, 0, 1074, 1274, 1230, 1231, 1232, 1233, 1234, 1235, + 1236, 1275, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, + 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, + 1255, 1256, 1257, 1258, 1259, 1260, 1276, 1277, 1261, 1262, + 1263, 1264, 1265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1050, 0, 0, + 0, 0, 0, 0, 0, 0, 1055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1215, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 869, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1356, 0, 0, 1357, 1358, 0, 1360, 0, 0, - 0, 1362, 1363, 0, 1365, 0, 1368, 0, 0, 1369, - 1370, 0, 1372, 0, 1375, 0, 1376, 1377, 0, 1379, - 1380, 0, 1382, 1383, 0, 1384, 0, 1386, 1387, 0, - 1388, 0, 1389, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 679, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1406, 0, 1408, 1410, 0, 1412, 1413, 1415, 0, - 1417, 1418, 1419, 1420, 0, 0, 0, 0, 0, 0, + 1311, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1181, 0, 0, 1181, 0, 0, 0, 1181, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1358, 869, + 0, 1359, 1360, 0, 1362, 0, 0, 0, 1364, 1365, + 0, 1367, 0, 1370, 0, 0, 1371, 1372, 0, 1374, + 0, 1377, 0, 1378, 1379, 0, 1381, 1382, 0, 1384, + 1385, 0, 1386, 0, 1388, 1389, 0, 1390, 0, 1391, + 0, 0, 0, 0, 869, 869, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1283, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1424, 0, 1426 + 0, 0, 0, 0, 0, 0, 0, 0, 1408, 0, + 1410, 1412, 0, 1414, 1415, 1417, 0, 1419, 1420, 1421, + 1422, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1426, 0, 1428 }; static const yytype_int16 yycheck[] = { - 57, 196, 0, 192, 346, 227, 558, 374, 115, 598, - 0, 220, 131, 132, 223, 604, 242, 434, 853, 201, - 206, 208, 434, 592, 212, 528, 204, 369, 836, 0, - 821, 997, 411, 821, 742, 697, 824, 783, 656, 235, - 838, 0, 352, 841, 893, 379, 955, 133, 243, 832, - 1133, 836, 156, 1061, 158, 1063, 1064, 694, 678, 403, - 4, 836, 1293, 4, 65, 67, 1073, 25, 1056, 14, - 4, 49, 17, 1295, 1296, 1297, 1298, 22, 1300, 136, - 1302, 138, 365, 140, 141, 19, 143, 6, 163, 90, - 92, 17, 149, 150, 28, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 195, 162, 14, 164, 0, 17, - 88, 356, 56, 720, 0, 722, 60, 724, 195, 726, - 78, 728, 56, 35, 201, 51, 60, 184, 1359, 186, - 187, 188, 377, 190, 220, 1142, 80, 223, 1146, 80, - 84, 40, 1364, 84, 89, 1367, 80, 6, 7, 1371, - 84, 347, 1374, 12, 49, 7, 1378, 40, 17, 11, - 3, 350, 17, 82, 1144, 17, 821, 952, 1148, 824, - 274, 26, 827, 368, 86, 87, 9, 952, 73, 78, - 147, 89, 25, 974, 1033, 993, 974, 1409, 245, 977, - 247, 163, 1414, 88, 416, 1161, 378, 254, 19, 256, - 55, 397, 6, 260, 261, 38, 989, 28, 404, 266, - 267, 268, 269, 17, 271, 403, 273, 274, 275, 927, - 1055, 929, 418, 82, 603, 1074, 1001, 284, 1311, 539, - 201, 893, 289, 290, 1222, 292, 570, 61, 807, 198, - 1149, 298, 30, 31, 862, 302, 303, 836, 866, 752, - 307, 308, 872, 890, 598, 312, 313, 540, 878, 569, - 163, 1110, 5, 320, 6, 53, 54, 324, 9, 552, - 327, 155, 15, 157, 16, 470, 17, 334, 82, 336, - 337, 338, 339, 340, 17, 342, 1077, 513, 5, 1077, - 1078, 898, 5, 26, 1129, 902, 1094, 38, 15, 906, - 907, 908, 15, 17, 911, 912, 24, 17, 915, 65, - 202, 1220, 35, 23, 155, 71, 157, 209, 61, 974, - 1095, 39, 977, 409, 979, 1071, 412, 816, 983, 818, - 48, 163, 821, 56, 90, 824, 50, 51, 827, 17, - 82, 830, 17, 1051, 61, 62, 31, 543, 26, 163, - 386, 26, 7, 389, 1296, 697, 392, 12, 9, 77, - 1302, 64, 17, 86, 87, 1153, 17, 357, 53, 54, - 427, 428, 41, 371, 364, 53, 54, 434, 435, 54, - 437, 1142, 1291, 7, 441, 442, 443, 11, 445, 1150, - 159, 160, 574, 589, 1102, 774, 592, 583, 455, 586, - 457, 458, 580, 460, 600, 462, 463, 633, 465, 466, - 598, 468, 469, 1159, 1222, 150, 473, 474, 475, 32, - 33, 478, 1077, 1078, 1079, 1080, 483, 484, 150, 619, - 487, 488, 622, 1040, 1041, 1042, 1043, 494, 495, 851, - 497, 498, 149, 500, 501, 161, 162, 1282, 790, 759, - 765, 766, 767, 510, 511, 512, 547, 548, 1204, 1205, - 517, 57, 519, 7, 521, 882, 523, 11, 12, 13, - 547, 548, 563, 564, 17, 1183, 24, 20, 793, 22, - 67, 791, 374, 1191, 1192, 72, 563, 564, 977, 48, - 979, 610, 384, 16, 983, 17, 17, 574, 1153, 1154, - 1155, 697, 74, 75, 26, 92, 1095, 29, 30, 31, - 546, 1118, 25, 549, 36, 551, 47, 1293, 554, 555, - 32, 1297, 1298, 408, 1300, 1301, 562, 1303, 1304, 414, - 1306, 53, 54, 55, 147, 148, 149, 573, 151, 152, - 153, 154, 155, 579, 33, 17, 582, 17, 62, 585, - 1139, 893, 22, 1142, 26, 612, 155, 1146, 30, 31, - 596, 1150, 619, 1218, 17, 622, 762, 624, 45, 626, - 7, 156, 1280, 26, 11, 12, 13, 29, 31, 1287, - 17, 53, 54, 20, 7, 22, 147, 644, 1364, 12, - 157, 1080, 649, 650, 651, 1371, 653, 654, 655, 656, - 53, 54, 659, 8, 1210, 1381, 1212, 54, 804, 1385, - 17, 807, 808, 795, 21, 22, 369, 1206, 675, 676, - 677, 678, 120, 680, 122, 682, 124, 684, 126, 686, - 154, 155, 69, 1222, 1001, 346, 832, 826, 847, 695, - 829, 533, 894, 112, 891, 537, 703, 816, 117, 817, - 119, 818, 121, 974, 123, 997, 125, 527, 715, 1086, - 717, 1226, 769, 720, 556, 722, 1182, 724, 1186, 726, - 571, 728, 58, 59, 731, 53, 54, 734, 1063, 786, - 1146, 156, 739, 740, 1298, 742, 161, 162, 163, 746, - 1301, 1033, 61, 62, 751, 7, 8, 893, 894, 11, - 12, 13, 14, 7, 1304, 17, 598, 11, 12, 13, - 14, 0, 604, 17, 26, 201, 608, 29, 30, 31, - 1303, 1304, 26, 1012, 1013, 29, 30, 31, 1095, 536, - 7, 624, 1074, 843, 11, 12, 13, 151, 152, 153, - 17, 53, 54, 55, 21, 22, 925, 926, 7, 53, - 54, 55, 11, 12, 13, 739, 740, 69, 17, 954, - 955, 1136, 1137, 22, 129, 69, 129, 129, 1110, 129, - 7, 129, 968, 995, 11, 12, 13, 89, 768, 199, - 17, 771, 7, 199, 958, 89, 11, 12, 13, 14, - 478, 129, 69, 989, 851, 785, 853, 986, 788, 988, - 129, 35, 570, 1214, 129, 862, 129, 1033, 129, 866, - 69, 868, 398, 870, 871, 872, 129, 815, 875, 1161, - 195, 878, 56, 195, 881, 882, 60, 597, 129, 147, - 148, 597, 69, 151, 152, 153, 70, 1033, 597, 597, - 731, 898, 0, 900, 69, 902, 129, 129, 129, 906, - 907, 908, 86, 87, 911, 912, 129, 914, 915, 1411, - 917, 148, 149, 920, 151, 152, 153, 129, 925, 926, - 927, 361, 929, 334, 931, 932, 148, 769, 1074, 151, - 152, 153, 372, 373, 941, 942, 337, 0, 1390, 10, - 339, 381, 0, 942, 786, 1095, 1085, 18, 388, -1, - -1, 391, -1, -1, 394, -1, 27, -1, -1, -1, - -1, -1, 402, 34, 1110, 148, 37, -1, 151, 152, - 153, 154, 155, 156, 816, 158, 818, -1, -1, 821, - -1, 52, 824, -1, -1, 827, -1, -1, 830, -1, - -1, -1, 63, 1000, 836, 66, -1, 68, 1005, 1006, - 1007, 1008, 844, -1, 1149, 1012, 1013, -1, 79, -1, - 81, -1, 83, -1, 85, -1, -1, -1, 1157, -1, - 91, -1, 1029, -1, -1, -1, -1, -1, -1, 1036, - 1037, 1038, 8, 1040, 1041, 1042, 1043, -1, 1045, 9, - 1047, 17, -1, -1, 1051, -1, 1053, 17, 1055, -1, - 26, -1, 1059, 29, 30, 31, 26, -1, -1, 29, - 30, 31, -1, -1, -1, -1, -1, -1, 38, -1, - -1, -1, 42, 43, -1, 1220, -1, 53, 54, 55, - -1, -1, -1, 53, 54, 55, -1, -1, -1, -1, - -1, 1098, -1, 1100, -1, 1102, 1103, -1, -1, -1, - 1107, 1108, -1, -1, -1, 1112, 1113, -1, 1115, -1, - 952, 1118, -1, 1120, -1, -1, -1, -1, -1, 17, - -1, -1, 1129, -1, -1, -1, -1, 1134, 26, 1136, - 1137, 29, 30, 31, -1, 977, -1, 979, -1, -1, - -1, 983, -1, 7, -1, 43, 1291, 11, 12, 13, - 14, 993, -1, 17, -1, 53, 54, 55, -1, -1, - -1, -1, 26, -1, -1, 29, 30, 31, -1, -1, - -1, 1178, 36, 1180, -1, 1182, 1183, 1184, -1, 1186, - 1187, -1, -1, -1, 1191, 1192, -1, 1194, -1, 53, - 54, 55, -1, -1, 1201, 1202, -1, -1, -1, -1, - 9, -1, -1, -1, -1, 69, 148, 149, 17, 151, - 152, 153, 154, 155, -1, 1361, 158, 26, 1225, 1226, - 29, 30, 31, -1, -1, 89, -1, 1366, -1, 38, - -1, -1, -1, -1, 1373, 147, 148, 149, 1080, 151, - 152, 153, 154, 155, 53, 54, 55, -1, -1, -1, - -1, -1, -1, 1095, -1, -1, -1, 1264, 1265, 1266, - 1267, 1268, -1, -1, 1271, 1272, 1273, 1274, 1275, 9, - -1, 1278, -1, 1280, -1, 1282, -1, 17, 148, -1, - 1287, 151, 152, 153, 154, 155, 26, -1, 158, 29, - 30, 31, -1, -1, -1, -1, -1, 1139, 38, -1, - 1142, -1, -1, 43, 1146, -1, -1, -1, 1150, -1, - -1, 1318, -1, 53, 54, 55, -1, 45, 1325, -1, - 1327, -1, -1, -1, 52, 53, 1333, 55, 1335, -1, - 58, -1, 60, 1340, 62, -1, 1343, -1, 66, -1, - 68, 1348, 70, -1, 72, -1, 74, -1, 76, -1, - 78, -1, 80, -1, -1, -1, -1, -1, -1, -1, - 88, -1, -1, -1, 1206, -1, -1, 95, -1, 97, - -1, 99, 1214, 101, -1, 103, -1, 105, -1, -1, - 1222, 362, 363, 1390, -1, 366, 367, -1, 1395, 1396, - 148, 149, 1399, 151, 152, 153, 154, 155, -1, 380, - -1, -1, -1, -1, -1, -1, 387, -1, -1, 390, - -1, -1, 393, -1, -1, -1, -1, -1, -1, 147, - 401, -1, 109, 110, 111, 112, 113, -1, -1, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, -1, 130, 131, 132, -1, -1, -1, -1, - -1, 1293, -1, 1295, 1296, 1297, 1298, -1, 1300, 1301, - 1302, 1303, 1304, 191, 1306, -1, 10, -1, -1, -1, - -1, -1, -1, 203, 18, 205, -1, 207, -1, 17, - 210, -1, -1, 27, -1, -1, -1, -1, 26, -1, - 34, 29, 30, 31, -1, -1, -1, -1, -1, -1, - -1, -1, 46, -1, -1, 192, -1, -1, 52, -1, - 197, -1, -1, -1, -1, 53, 54, 55, -1, 63, - 248, -1, 66, -1, 68, 253, -1, 255, -1, -1, - 258, 259, -1, -1, -1, 79, 17, 81, -1, 83, - -1, 85, -1, -1, -1, 26, -1, 91, 29, 30, - 31, -1, 280, 281, -1, -1, -1, 285, -1, -1, - 288, -1, 43, -1, 45, -1, -1, 295, -1, -1, - -1, 299, 53, 54, 55, -1, 304, -1, -1, -1, - -1, 309, -1, -1, -1, -1, 314, -1, -1, -1, - -1, 319, -1, 321, -1, -1, -1, 325, -1, -1, - -1, -1, -1, -1, 332, -1, -1, 335, -1, -1, - -1, -1, -1, -1, 344, 343, -1, -1, -1, -1, - -1, 351, -1, 353, 354, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, -1, - 370, -1, -1, -1, -1, 375, 93, 94, 95, 96, - 97, 98, 99, 100, 101, -1, -1, -1, -1, -1, - -1, -1, -1, 350, -1, -1, -1, -1, 355, 356, + 57, 558, 196, 192, 0, 346, 227, 374, 115, 201, + 0, 220, 131, 132, 223, 434, 242, 853, 434, 204, + 206, 208, 836, 528, 133, 955, 352, 411, 369, 592, + 821, 598, 656, 212, 678, 783, 0, 604, 821, 235, + 836, 824, 0, 697, 838, 379, 893, 841, 1135, 243, + 832, 156, 694, 158, 403, 836, 1057, 1075, 1062, 997, + 1064, 1065, 0, 4, 6, 7, 1297, 1298, 1299, 1300, + 12, 1302, 25, 1304, 49, 17, 163, 742, 19, 136, + 5, 138, 4, 140, 141, 365, 143, 28, 14, 6, + 15, 17, 149, 150, 1295, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 195, 162, 6, 164, 6, 40, + 0, 220, 9, 88, 223, 56, 4, 17, 16, 60, + 17, 17, 5, 147, 35, 78, 1144, 184, 195, 186, + 187, 188, 15, 190, 201, 1366, 61, 62, 1369, 80, + 82, 38, 1373, 84, 1148, 1376, 720, 78, 722, 1380, + 724, 347, 726, 40, 728, 51, 952, 19, 80, 3, + 1361, 350, 84, 89, 821, 82, 28, 824, 56, 274, + 827, 952, 60, 65, 368, 86, 87, 9, 61, 993, + 1411, 25, 82, 974, 82, 1416, 378, 1034, 245, 163, + 247, 974, 80, 17, 977, 416, 84, 254, 90, 256, + 163, 397, 26, 260, 261, 1001, 38, 989, 404, 266, + 267, 268, 269, 539, 271, 163, 273, 274, 275, 603, + 1056, 1151, 418, 1224, 403, 1163, 1313, 284, 872, 1076, + 31, 55, 289, 290, 878, 292, 570, 201, 862, 893, + 198, 298, 866, 569, 807, 302, 303, 752, 890, 598, + 307, 308, 53, 54, 356, 312, 313, 159, 160, 67, + 540, 5, 927, 320, 929, 1112, 49, 324, 65, 836, + 327, 15, 552, 61, 71, 377, 470, 334, 35, 336, + 337, 338, 339, 340, 92, 342, 14, 513, 1079, 17, + 73, 24, 1222, 90, 22, 1131, 1079, 1080, 17, 56, + 409, 1097, 1096, 412, 7, 88, 39, 26, 11, 12, + 13, 14, 202, 7, 155, 48, 157, 974, 12, 209, + 977, 17, 979, 17, 898, 1073, 983, 23, 902, 86, + 87, 17, 906, 907, 908, 54, 7, 911, 912, 64, + 11, 915, 163, 816, 77, 818, 17, 543, 821, 386, + 17, 824, 389, 17, 827, 392, 697, 830, 22, 26, + 155, 89, 157, 1293, 50, 51, 69, 357, 30, 31, + 427, 428, 1155, 9, 364, 371, 41, 434, 435, 7, + 437, 17, 574, 11, 441, 442, 443, 1052, 445, 67, + 774, 53, 54, 589, 72, 580, 592, 583, 455, 586, + 457, 458, 150, 460, 600, 462, 463, 633, 465, 466, + 1224, 468, 469, 1161, 92, 150, 473, 474, 475, 598, + 1144, 478, 1079, 1080, 1081, 1082, 483, 484, 1152, 17, + 487, 488, 20, 759, 22, 851, 149, 494, 495, 1104, + 497, 498, 17, 500, 501, 7, 1298, 57, 1284, 790, + 12, 26, 1304, 510, 511, 512, 547, 548, 1206, 1207, + 517, 48, 519, 882, 521, 791, 523, 1041, 1042, 1043, + 1044, 619, 563, 564, 622, 765, 766, 767, 53, 54, + 547, 548, 7, 1212, 374, 1214, 11, 12, 13, 408, + 24, 610, 17, 16, 384, 414, 563, 564, 1155, 1156, + 1157, 697, 35, 793, 977, 17, 979, 574, 47, 546, + 983, 17, 549, 32, 551, 21, 22, 554, 555, 33, + 1185, 161, 162, 56, 25, 562, 156, 60, 1193, 1194, + 1097, 161, 162, 163, 147, 148, 573, 70, 151, 152, + 153, 62, 579, 45, 69, 582, 1120, 17, 585, 151, + 152, 153, 893, 86, 87, 612, 26, 74, 75, 596, + 30, 31, 619, 1220, 17, 622, 762, 624, 1146, 626, + 154, 155, 1150, 26, 1141, 58, 59, 1144, 31, 61, + 62, 1148, 155, 53, 54, 1152, 156, 644, 53, 54, + 32, 33, 649, 650, 651, 29, 653, 654, 655, 656, + 53, 54, 659, 795, 1305, 1306, 1012, 1013, 804, 1082, + 148, 807, 808, 151, 152, 153, 147, 1282, 675, 676, + 677, 678, 157, 680, 1289, 682, 120, 684, 122, 686, + 124, 8, 126, 54, 1001, 369, 832, 826, 847, 346, + 829, 1208, 695, 533, 894, 148, 703, 537, 151, 152, + 153, 154, 155, 156, 891, 158, 997, 1224, 715, 816, + 717, 817, 769, 720, 818, 722, 556, 724, 974, 726, + 527, 728, 925, 926, 731, 739, 740, 734, 1088, 786, + 1138, 1139, 739, 740, 1228, 742, 7, 1184, 1188, 746, + 11, 12, 13, 1034, 751, 571, 17, 893, 894, 20, + 1064, 22, 1148, 1300, 1306, 147, 148, 149, 598, 151, + 152, 153, 154, 155, 604, 1303, 0, 7, 608, 8, + 201, 11, 12, 13, 536, 624, 843, 17, 17, 129, + 1097, 21, 22, 129, 129, 1076, 129, 26, 129, 1295, + 29, 30, 31, 1299, 1300, 199, 1302, 1303, 69, 1305, + 1306, 199, 1308, 7, 958, 478, 129, 11, 12, 13, + 954, 955, 129, 17, 53, 54, 55, 570, 1216, 129, + 129, 1112, 968, 129, 995, 112, 398, 129, 768, 69, + 117, 771, 119, 195, 121, 195, 123, 597, 125, 129, + 597, 597, 597, 989, 851, 785, 853, 986, 788, 988, + 129, 129, 129, 129, 129, 862, 0, 731, 1034, 866, + 1366, 868, 334, 870, 871, 872, 0, 1373, 875, 815, + 10, 878, 1163, 339, 881, 882, 337, 1383, 18, 148, + 149, 1387, 151, 152, 153, 154, 155, 27, 1034, 158, + 1392, 898, 0, 900, 34, 902, 942, 37, 1097, 906, + 907, 908, -1, -1, 911, 912, 1413, 914, 915, -1, + 917, -1, 52, 920, -1, -1, -1, -1, 925, 926, + 927, -1, 929, 63, 931, 932, 66, 7, 68, 769, + 1076, 11, 12, 13, 941, 942, -1, 17, 361, 79, + -1, 81, 22, 83, -1, 85, 786, -1, 1087, 372, + 373, 91, 362, 363, -1, -1, 366, 367, 381, 148, + 149, -1, 151, 152, 153, 388, 1112, -1, 391, -1, + 380, 394, -1, -1, -1, -1, 816, 387, 818, 402, + 390, 821, -1, 393, 824, -1, -1, 827, -1, 69, + 830, 401, -1, 1000, -1, -1, 836, -1, 1005, 1006, + 1007, 1008, -1, -1, 844, 1012, 1013, 1151, -1, 148, + -1, -1, 151, 152, 153, 154, 155, -1, -1, 158, + 1159, 148, 149, 1030, 151, 152, 153, 154, 155, -1, + 1037, 1038, 1039, -1, 1041, 1042, 1043, 1044, -1, 1046, + -1, 1048, -1, -1, -1, 1052, -1, 1054, -1, 1056, + -1, -1, -1, 1060, -1, -1, -1, -1, 7, 8, + -1, -1, 11, 12, 13, 14, -1, -1, 17, -1, + -1, -1, -1, -1, -1, -1, -1, 26, 1222, -1, + 29, 30, 31, 93, 94, 95, 96, 97, 98, 99, + 100, 101, -1, 1100, -1, 1102, -1, 1104, 1105, -1, + -1, -1, 1109, 1110, 53, 54, 55, 1114, 1115, -1, + 1117, -1, 952, 1120, 17, 1122, -1, -1, -1, -1, + 69, 17, 962, 26, 1131, -1, 29, 30, 31, 1136, + 26, 1138, 1139, 29, 30, 31, -1, 977, -1, 979, + 89, -1, -1, 983, -1, -1, -1, 43, -1, 1293, + 53, 54, 55, 993, -1, -1, -1, 53, 54, 55, + -1, 7, -1, -1, -1, 11, 12, 13, 14, -1, + -1, 17, -1, 1180, -1, 1182, -1, 1184, 1185, 1186, + 26, 1188, 1189, 29, 30, 31, 1193, 1194, -1, 1196, + 36, -1, -1, 9, -1, -1, 1203, 1204, -1, -1, + -1, 17, -1, -1, -1, -1, -1, 53, 54, 55, + 26, -1, -1, 29, 30, 31, -1, 1363, -1, -1, + 1227, 1228, 38, 69, -1, -1, 42, 43, -1, 1368, + -1, -1, -1, -1, -1, -1, 1375, 53, 54, 55, + -1, -1, 1082, 89, -1, 147, 148, 149, -1, 151, + 152, 153, 154, 155, -1, -1, -1, 1097, -1, 1266, + 1267, 1268, 1269, 1270, -1, -1, 1273, 1274, 1275, 1276, + 1277, 9, -1, 1280, -1, 1282, -1, 1284, -1, 17, + -1, -1, 1289, -1, -1, -1, -1, -1, 26, -1, + -1, 29, 30, 31, -1, -1, -1, -1, -1, -1, + 38, 1141, -1, -1, 1144, 43, -1, -1, 1148, -1, + -1, -1, 1152, 1320, -1, 53, 54, 55, -1, -1, + 1327, -1, 1329, -1, -1, -1, -1, -1, 1335, -1, + 1337, -1, -1, -1, -1, 1342, -1, -1, 1345, -1, + -1, -1, -1, 1350, -1, -1, 45, -1, -1, -1, + -1, -1, -1, 52, 53, -1, 55, -1, -1, 58, + -1, 60, -1, 62, -1, -1, -1, 66, 1208, 68, + -1, 70, -1, 72, -1, 74, 1216, 76, -1, 78, + -1, 80, -1, -1, 1224, 1392, -1, -1, -1, 88, + 1397, 1398, -1, -1, 1401, -1, 95, -1, 97, -1, + 99, -1, 101, -1, 103, 7, 105, 17, -1, 11, + 12, 13, 14, -1, -1, 17, 26, -1, -1, 29, + 30, 31, -1, -1, 26, -1, -1, 29, 30, 31, + -1, -1, -1, 43, -1, 45, -1, -1, -1, -1, + -1, -1, -1, 53, 54, 55, -1, -1, 147, -1, + -1, 53, 54, 55, -1, 1295, -1, 1297, 1298, 1299, + 1300, -1, 1302, 1303, 1304, 1305, 1306, 69, 1308, 10, + -1, -1, -1, -1, 9, -1, 17, 18, -1, -1, + -1, -1, 17, -1, -1, 26, 27, 89, 29, 30, + 31, 26, 191, 34, 29, 30, 31, -1, -1, 10, + -1, -1, 203, 38, 205, 46, 207, 18, -1, 210, + -1, 52, 53, 54, 55, -1, 27, -1, 53, 54, + 55, -1, 63, 34, -1, 66, -1, 68, -1, -1, + -1, -1, -1, -1, -1, 46, -1, -1, 79, -1, + 81, 52, 83, -1, 85, -1, -1, -1, -1, 248, + 91, -1, 63, -1, 253, 66, 255, 68, -1, 258, + 259, -1, -1, -1, -1, -1, -1, -1, 79, -1, + 81, -1, 83, -1, 85, -1, -1, -1, -1, -1, + 91, 280, 281, -1, -1, -1, 285, -1, -1, 288, + -1, -1, -1, -1, 17, -1, 295, -1, -1, -1, + 299, -1, -1, 26, -1, 304, 29, 30, 31, -1, + 309, -1, -1, 36, -1, 314, -1, -1, -1, -1, + 319, -1, 321, -1, -1, -1, 325, -1, 4, 5, + 53, 54, 55, 332, 10, -1, 335, -1, -1, 15, + -1, 17, 18, 344, 343, -1, -1, -1, 24, -1, + 351, 27, 353, 354, -1, -1, -1, -1, 34, 35, + -1, 37, -1, 39, -1, -1, -1, -1, 44, 370, + 46, -1, -1, 49, 375, -1, 52, -1, -1, -1, + -1, -1, -1, -1, 60, -1, -1, 63, -1, 65, + 66, 67, 68, -1, -1, -1, -1, -1, -1, -1, + 76, 77, -1, 79, 80, 81, -1, 83, 84, 85, + 86, 87, 88, -1, 90, 91, 92, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 376, - 377, -1, -1, -1, -1, -1, -1, -1, 385, -1, - -1, 429, -1, 431, -1, -1, -1, -1, 436, -1, - 397, -1, -1, 400, -1, -1, -1, -1, 446, -1, - 407, -1, -1, -1, 454, 453, -1, -1, -1, 10, - -1, -1, -1, 461, 464, -1, 17, 18, -1, -1, - -1, 471, -1, -1, -1, 26, 27, -1, 29, 30, - 31, 479, -1, 34, -1, -1, 486, 485, -1, -1, - -1, -1, 492, 493, -1, 46, 496, -1, -1, 499, - -1, 52, 53, 54, 55, -1, 506, -1, -1, 509, - -1, -1, 63, -1, 514, 66, 516, 68, -1, -1, - -1, -1, 520, -1, -1, 525, 524, -1, 79, -1, - 81, -1, 83, -1, 85, -1, -1, -1, 538, -1, - 91, -1, 542, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 557, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 568, -1, - -1, -1, 529, 530, -1, -1, -1, -1, -1, -1, + 429, -1, 431, -1, -1, -1, -1, 436, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 446, -1, -1, + -1, -1, -1, 454, 453, -1, -1, -1, -1, -1, + -1, -1, 461, 464, -1, -1, -1, -1, -1, -1, + 471, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 479, -1, -1, -1, -1, 486, 485, -1, -1, -1, + -1, 492, 493, -1, -1, 496, -1, -1, 499, -1, + -1, -1, -1, -1, -1, 506, -1, -1, 509, -1, + -1, -1, -1, 514, -1, 516, -1, -1, -1, -1, + -1, 520, -1, -1, 525, 524, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 538, -1, -1, + -1, 542, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 557, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 568, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 550, -1, -1, -1, -1, -1, 599, - -1, -1, -1, -1, -1, 605, -1, -1, -1, 609, - 567, -1, -1, -1, -1, 615, -1, 617, -1, -1, - -1, 621, -1, -1, -1, -1, -1, 627, -1, -1, - -1, -1, -1, 631, 634, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 606, - -1, -1, -1, 610, -1, -1, -1, 657, -1, -1, - 660, 661, 662, 663, -1, -1, -1, -1, -1, -1, - 668, -1, -1, -1, 674, 673, -1, -1, -1, -1, - -1, -1, -1, 683, -1, 685, -1, -1, 688, -1, - 690, -1, 692, -1, -1, -1, -1, -1, 698, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 716, -1, - 718, -1, -1, 721, -1, 723, -1, 725, -1, 727, - -1, -1, 730, -1, -1, -1, -1, -1, -1, -1, - 738, -1, -1, 741, -1, 743, -1, -1, -1, -1, - 748, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 599, -1, + -1, -1, -1, -1, 605, -1, -1, -1, 609, -1, + -1, -1, -1, -1, 615, -1, 617, -1, -1, -1, + 621, -1, -1, -1, -1, -1, 627, -1, -1, -1, + -1, -1, 631, 634, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 770, -1, 772, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 787, -1, 789, - -1, -1, -1, -1, -1, -1, 796, -1, 798, -1, - 800, -1, 802, -1, 761, -1, 317, 318, -1, 320, + -1, -1, -1, -1, -1, -1, 657, -1, -1, 660, + 661, 662, 663, -1, -1, -1, -1, -1, -1, 668, + -1, -1, -1, 674, 673, -1, -1, -1, -1, -1, + -1, -1, 683, -1, 685, -1, -1, 688, -1, 690, + -1, 692, -1, -1, -1, -1, -1, 698, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 781, -1, 783, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 837, -1, -1, - -1, -1, -1, -1, -1, 845, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 716, -1, 718, + -1, -1, 721, -1, 723, -1, 725, -1, 727, -1, + -1, 730, -1, -1, -1, -1, -1, -1, -1, 738, + -1, -1, 741, -1, 743, -1, -1, -1, -1, 748, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 820, -1, -1, 823, -1, -1, -1, - -1, -1, -1, -1, -1, 832, -1, -1, -1, -1, - -1, 838, -1, -1, 841, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 770, + -1, 772, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 787, -1, 789, -1, + -1, -1, -1, -1, -1, 796, -1, 798, -1, 800, + -1, 802, -1, -1, -1, -1, -1, 109, 110, 111, + 112, 113, -1, -1, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, -1, 130, 131, + 132, -1, -1, -1, -1, -1, 837, -1, -1, -1, + -1, -1, -1, -1, 845, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 905, -1, -1, -1, -1, - 910, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 922, -1, -1, -1, -1, -1, -1, -1, - 928, -1, -1, 933, -1, -1, -1, -1, -1, -1, - 940, -1, -1, 943, 944, 945, 946, 947, 948, -1, - -1, 951, -1, 953, -1, -1, 956, -1, 469, -1, - -1, 961, -1, 963, 964, 965, 477, -1, -1, -1, - -1, 482, 972, -1, -1, -1, -1, -1, 489, 490, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 108, - 109, 110, 111, 112, 113, 114, 507, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, -1, -1, 142, 143, 144, 145, 146, 1026, -1, - -1, -1, 989, -1, -1, 1035, -1, -1, -1, -1, - -1, 998, -1, -1, -1, -1, -1, -1, -1, -1, - 1050, -1, 1052, -1, -1, -1, -1, -1, -1, 1057, - -1, -1, -1, -1, -1, -1, -1, -1, 1068, 1069, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1087, -1, -1, - -1, -1, 1092, -1, -1, 1093, 1096, -1, -1, -1, - -1, 1099, -1, 1101, -1, -1, 1104, -1, -1, -1, - -1, -1, -1, -1, 1071, -1, -1, -1, -1, -1, + -1, 317, 318, -1, 320, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1131, -1, -1, -1, 1094, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 666, 667, -1, 1158, -1, - 1160, 672, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 687, 1175, 689, 1177, - 691, -1, 693, -1, 1141, -1, -1, 1144, -1, -1, - -1, 1148, -1, -1, -1, 1193, -1, -1, -1, 1199, - -1, -1, 1159, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1213, -1, -1, -1, -1, -1, -1, - -1, 1221, -1, 1223, 1224, -1, -1, -1, -1, -1, + 192, -1, -1, -1, -1, 197, -1, -1, -1, -1, + -1, -1, -1, -1, 905, -1, -1, -1, -1, 910, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1204, 1205, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1217, -1, -1, -1, -1, -1, -1, -1, -1, 1269, - -1, -1, -1, -1, -1, -1, 1276, -1, -1, -1, + -1, 922, -1, -1, -1, -1, -1, -1, -1, 928, + -1, -1, 933, -1, -1, -1, -1, -1, -1, 940, + -1, -1, 943, 944, 945, 946, 947, 948, -1, -1, + 951, -1, 953, -1, -1, 956, -1, -1, -1, -1, + 961, -1, 963, 964, 965, -1, -1, -1, -1, -1, + -1, 972, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, -1, 469, -1, -1, -1, -1, -1, -1, + -1, 477, -1, -1, -1, -1, 482, -1, 1027, -1, + -1, -1, -1, 489, 490, 1036, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 350, -1, + 1051, 507, 1053, 355, 356, -1, -1, -1, -1, 1058, + -1, -1, -1, -1, -1, -1, -1, -1, 1069, 1070, + -1, -1, -1, -1, 376, 377, -1, -1, -1, -1, + -1, -1, -1, 385, -1, -1, -1, -1, 1089, -1, + -1, -1, -1, 1094, -1, 397, 1095, 1098, 400, -1, + -1, -1, 1101, -1, 1103, 407, -1, 1106, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1288, -1, 1292, -1, 1294, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 1308, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1319, -1, -1, -1, -1, -1, -1, 1326, -1, - -1, -1, -1, -1, -1, -1, 1334, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 858, 859, 860, - 861, -1, 863, 864, -1, 1355, 1356, 4, 5, -1, - -1, -1, 873, 10, 875, 876, -1, -1, 15, -1, - 17, 18, 883, 884, -1, -1, -1, 24, -1, -1, - 27, -1, -1, -1, -1, 896, -1, 34, 35, -1, - 37, -1, 39, 1393, -1, -1, -1, 44, -1, 46, - 1400, -1, 49, -1, -1, 52, -1, -1, -1, -1, - -1, -1, -1, 60, -1, -1, 63, -1, 65, 66, - 67, 68, 1422, -1, -1, -1, -1, -1, -1, 76, - 77, -1, 79, 80, 81, -1, 83, 84, 85, 86, - 87, 88, -1, 90, 91, 92, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, -1, -1, -1, -1, + -1, -1, -1, -1, 1133, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1011, -1, -1, -1, -1, 1016, 1017, -1, 1019, -1, - -1, -1, -1, -1, -1, -1, 1027, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 1160, + -1, 1162, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 1177, -1, + 1179, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 1195, -1, -1, -1, + 1201, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 666, 667, -1, -1, 1215, -1, 672, -1, -1, -1, + -1, -1, 1223, -1, 1225, 1226, -1, 529, 530, -1, + -1, 687, -1, 689, -1, 691, -1, 693, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 550, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 567, -1, -1, -1, -1, + 1271, -1, -1, -1, -1, -1, -1, 1278, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1290, -1, 1294, -1, 1296, -1, -1, -1, -1, + -1, -1, -1, -1, 606, -1, -1, -1, 610, 1310, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 1321, -1, -1, -1, -1, -1, -1, 1328, + -1, -1, -1, -1, -1, -1, -1, 1336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 1357, 1358, -1, -1, + -1, 108, 109, 110, 111, 112, 113, 114, -1, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, -1, 1395, 142, 143, 144, 145, 146, + -1, 1402, 858, 859, 860, 861, -1, 863, 864, -1, + -1, -1, -1, -1, -1, -1, -1, 873, -1, 875, + 876, -1, -1, 1424, -1, -1, -1, 883, 884, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 896, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 761, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 781, + -1, 783, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 820, -1, + -1, 823, -1, -1, -1, -1, -1, -1, -1, -1, + 832, -1, -1, -1, -1, -1, 838, -1, -1, 841, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 1011, -1, -1, -1, -1, + 1016, 1017, -1, 1019, -1, -1, -1, -1, -1, 1025, + -1, -1, 1028, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1188, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1203, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 989, -1, -1, + -1, -1, -1, -1, -1, -1, 998, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 1190, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 1205, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1284, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1073, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1312, -1, -1, 1315, 1316, -1, 1318, -1, -1, - -1, 1322, 1323, -1, 1325, -1, 1327, -1, -1, 1330, - 1331, -1, 1333, -1, 1335, -1, 1337, 1338, -1, 1340, - 1341, -1, 1343, 1344, -1, 1346, -1, 1348, 1349, -1, - 1351, -1, 1353, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 1096, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1392, -1, 1394, 1395, -1, 1397, 1398, 1399, -1, - 1401, 1402, 1403, 1404, -1, -1, -1, -1, -1, -1, + 1286, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1143, -1, -1, 1146, -1, -1, -1, 1150, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 1314, 1161, + -1, 1317, 1318, -1, 1320, -1, -1, -1, 1324, 1325, + -1, 1327, -1, 1329, -1, -1, 1332, 1333, -1, 1335, + -1, 1337, -1, 1339, 1340, -1, 1342, 1343, -1, 1345, + 1346, -1, 1348, -1, 1350, 1351, -1, 1353, -1, 1355, + -1, -1, -1, -1, 1206, 1207, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 1219, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1421, -1, 1423 + -1, -1, -1, -1, -1, -1, -1, -1, 1394, -1, + 1396, 1397, -1, 1399, 1400, 1401, -1, 1403, 1404, 1405, + 1406, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 1423, -1, 1425 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -2064,47 +2080,47 @@ static const yytype_uint16 yystos[] = 203, 482, 482, 204, 207, 202, 207, 204, 204, 203, 203, 204, 204, 512, 203, 203, 203, 203, 203, 203, 203, 238, 425, 429, 203, 172, 267, 267, 203, 373, - 203, 7, 11, 12, 13, 256, 257, 386, 203, 203, - 203, 180, 195, 196, 203, 218, 220, 223, 229, 234, - 229, 234, 234, 234, 169, 226, 169, 233, 184, 205, - 237, 494, 167, 385, 205, 431, 204, 383, 429, 513, - 516, 204, 204, 204, 204, 259, 419, 419, 259, 259, - 259, 202, 259, 204, 168, 198, 203, 204, 204, 204, - 204, 209, 209, 209, 209, 204, 204, 230, 203, 207, - 203, 204, 330, 507, 202, 204, 514, 8, 282, 284, - 281, 284, 282, 283, 284, 203, 203, 266, 281, 180, - 197, 198, 223, 229, 234, 229, 234, 234, 234, 169, - 227, 260, 203, 7, 11, 12, 13, 14, 69, 426, - 427, 428, 203, 202, 384, 208, 429, 516, 203, 204, - 272, 202, 204, 270, 202, 207, 204, 275, 202, 204, - 204, 392, 198, 204, 204, 204, 209, 204, 330, 202, - 504, 204, 514, 514, 7, 11, 12, 13, 14, 69, - 89, 208, 252, 253, 254, 255, 261, 265, 305, 205, - 285, 208, 281, 305, 285, 208, 283, 285, 267, 36, - 208, 305, 393, 394, 229, 234, 234, 234, 169, 228, - 203, 266, 203, 385, 202, 202, 204, 204, 270, 207, - 204, 275, 204, 259, 204, 207, 207, 202, 204, 203, - 204, 262, 204, 505, 259, 266, 266, 208, 108, 109, - 110, 111, 112, 113, 114, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 142, - 143, 144, 145, 146, 298, 107, 115, 140, 141, 286, - 289, 298, 107, 115, 140, 141, 291, 294, 298, 203, - 393, 205, 395, 234, 267, 203, 208, 494, 507, 203, - 203, 204, 262, 204, 296, 204, 204, 204, 204, 203, - 204, 204, 204, 204, 204, 203, 204, 207, 330, 259, - 207, 202, 267, 203, 22, 238, 261, 297, 303, 304, - 203, 20, 238, 253, 287, 299, 300, 303, 287, 21, - 238, 253, 288, 301, 302, 303, 288, 238, 253, 290, - 303, 238, 292, 299, 303, 287, 238, 293, 301, 303, - 293, 238, 295, 303, 203, 504, 259, 259, 259, 204, - 259, 202, 259, 259, 204, 259, 202, 204, 259, 259, - 259, 204, 259, 202, 204, 259, 259, 259, 204, 259, - 259, 204, 259, 259, 259, 204, 259, 259, 259, 259, - 203, 203, 261, 180, 253, 303, 169, 253, 253, 303, - 169, 253, 253, 303, 303, 505, 259, 203, 259, 204, - 259, 204, 259, 259, 204, 259, 203, 259, 259, 259, - 259, 253, 258, 253, 259, 203, 259 + 203, 7, 11, 12, 13, 238, 256, 257, 386, 203, + 203, 203, 180, 195, 196, 203, 218, 220, 223, 229, + 234, 229, 234, 234, 234, 169, 226, 169, 233, 184, + 205, 237, 494, 167, 385, 205, 431, 204, 383, 429, + 513, 516, 204, 204, 204, 204, 259, 419, 419, 259, + 259, 259, 259, 202, 259, 204, 168, 198, 203, 204, + 204, 204, 204, 209, 209, 209, 209, 204, 204, 230, + 203, 207, 203, 204, 330, 507, 202, 204, 514, 8, + 282, 284, 281, 284, 282, 283, 284, 203, 203, 266, + 281, 180, 197, 198, 223, 229, 234, 229, 234, 234, + 234, 169, 227, 260, 203, 7, 11, 12, 13, 14, + 69, 426, 427, 428, 203, 202, 384, 208, 429, 516, + 203, 204, 272, 202, 204, 270, 202, 207, 204, 275, + 202, 204, 204, 392, 198, 204, 204, 204, 209, 204, + 330, 202, 504, 204, 514, 514, 7, 11, 12, 13, + 14, 69, 89, 208, 252, 253, 254, 255, 261, 265, + 305, 205, 285, 208, 281, 305, 285, 208, 283, 285, + 267, 36, 208, 305, 393, 394, 229, 234, 234, 234, + 169, 228, 203, 266, 203, 385, 202, 202, 204, 204, + 270, 207, 204, 275, 204, 259, 204, 207, 207, 202, + 204, 203, 204, 262, 204, 505, 259, 266, 266, 208, + 108, 109, 110, 111, 112, 113, 114, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 142, 143, 144, 145, 146, 298, 107, 115, 140, + 141, 286, 289, 298, 107, 115, 140, 141, 291, 294, + 298, 203, 393, 205, 395, 234, 267, 203, 208, 494, + 507, 203, 203, 204, 262, 204, 296, 204, 204, 204, + 204, 203, 204, 204, 204, 204, 204, 203, 204, 207, + 330, 259, 207, 202, 267, 203, 22, 238, 261, 297, + 303, 304, 203, 20, 238, 253, 287, 299, 300, 303, + 287, 21, 238, 253, 288, 301, 302, 303, 288, 238, + 253, 290, 303, 238, 292, 299, 303, 287, 238, 293, + 301, 303, 293, 238, 295, 303, 203, 504, 259, 259, + 259, 204, 259, 202, 259, 259, 204, 259, 202, 204, + 259, 259, 259, 204, 259, 202, 204, 259, 259, 259, + 204, 259, 259, 204, 259, 259, 259, 204, 259, 259, + 259, 259, 203, 203, 261, 180, 253, 303, 169, 253, + 253, 303, 169, 253, 253, 303, 303, 505, 259, 203, + 259, 204, 259, 204, 259, 259, 204, 259, 203, 259, + 259, 259, 259, 253, 258, 253, 259, 203, 259 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ @@ -2156,30 +2172,30 @@ static const yytype_uint16 yyr1[] = 362, 363, 363, 364, 364, 364, 364, 365, 366, 366, 366, 366, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 375, 375, 376, 377, 378, 379, 379, 380, - 381, 382, 382, 383, 384, 385, 386, 387, 387, 388, - 389, 390, 390, 391, 392, 392, 392, 392, 392, 393, - 394, 395, 396, 396, 397, 398, 398, 398, 399, 400, - 400, 401, 402, 402, 403, 404, 405, 406, 406, 407, - 408, 409, 410, 410, 410, 410, 410, 411, 411, 412, - 413, 414, 414, 415, 416, 417, 418, 419, 419, 419, - 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, - 428, 428, 428, 428, 428, 429, 430, 431, 432, 432, - 432, 433, 433, 434, 435, 435, 436, 437, 437, 438, - 439, 440, 441, 441, 441, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 450, 450, 450, 451, 452, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 466, 466, 466, 466, 466, 466, - 466, 466, 466, 466, 466, 467, 467, 468, 468, 468, - 469, 470, 471, 472, 472, 473, 473, 473, 474, 475, - 475, 476, 477, 477, 477, 477, 477, 477, 477, 477, - 477, 477, 477, 477, 477, 477, 478, 478, 478, 478, - 478, 478, 478, 479, 480, 480, 481, 482, 482, 482, - 482, 482, 482, 482, 483, 484, 485, 486, 487, 488, - 489, 490, 491, 492, 493, 494, 495, 496, 497, 497, - 498, 499, 499, 499, 499, 499, 500, 501, 502, 502, - 503, 504, 504, 504, 504, 505, 505, 505, 505, 506, - 507, 508, 509, 510, 511, 511, 512, 513, 513, 514, - 514, 514, 514, 515, 516 + 381, 382, 382, 382, 383, 384, 385, 386, 387, 387, + 388, 389, 390, 390, 391, 392, 392, 392, 392, 392, + 393, 394, 395, 396, 396, 397, 398, 398, 398, 399, + 400, 400, 401, 402, 402, 403, 404, 405, 406, 406, + 407, 408, 409, 410, 410, 410, 410, 410, 411, 411, + 412, 413, 414, 414, 415, 416, 417, 418, 419, 419, + 419, 419, 420, 421, 422, 423, 424, 425, 426, 427, + 428, 428, 428, 428, 428, 428, 429, 430, 431, 432, + 432, 432, 433, 433, 434, 435, 435, 436, 437, 437, + 438, 439, 440, 441, 441, 441, 442, 443, 444, 445, + 446, 447, 448, 449, 450, 450, 450, 450, 451, 452, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 466, 466, 466, 466, 466, + 466, 466, 466, 466, 466, 466, 467, 467, 468, 468, + 468, 469, 470, 471, 472, 472, 473, 473, 473, 474, + 475, 475, 476, 477, 477, 477, 477, 477, 477, 477, + 477, 477, 477, 477, 477, 477, 477, 478, 478, 478, + 478, 478, 478, 478, 479, 480, 480, 481, 482, 482, + 482, 482, 482, 482, 482, 483, 484, 485, 486, 487, + 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, + 497, 498, 499, 499, 499, 499, 499, 500, 501, 502, + 502, 503, 504, 504, 504, 504, 505, 505, 505, 505, + 506, 507, 508, 509, 510, 511, 511, 512, 513, 513, + 514, 514, 514, 514, 515, 516 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -2231,30 +2247,30 @@ static const yytype_uint8 yyr2[] = 10, 1, 1, 1, 1, 1, 1, 7, 0, 3, 5, 3, 3, 9, 7, 9, 1, 1, 1, 1, 7, 0, 3, 3, 1, 1, 5, 1, 1, 1, - 7, 0, 3, 1, 1, 1, 1, 1, 1, 8, - 10, 1, 1, 10, 0, 3, 5, 3, 2, 5, - 1, 1, 1, 1, 5, 1, 1, 1, 8, 1, - 1, 5, 1, 1, 8, 1, 5, 1, 1, 8, - 1, 5, 0, 3, 5, 3, 3, 1, 1, 4, - 1, 1, 1, 4, 1, 1, 7, 0, 3, 3, - 3, 1, 1, 5, 1, 1, 9, 1, 5, 1, - 1, 1, 1, 1, 1, 7, 1, 1, 1, 1, - 1, 1, 1, 10, 1, 1, 10, 1, 1, 10, - 10, 7, 0, 3, 3, 9, 7, 9, 10, 1, - 1, 9, 1, 1, 1, 1, 1, 10, 1, 1, - 7, 9, 1, 10, 7, 1, 10, 7, 1, 10, - 7, 1, 9, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, 3, 2, - 1, 1, 4, 1, 1, 1, 2, 3, 4, 1, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 7, 0, 3, 3, 1, 1, 1, 1, 1, 1, + 8, 10, 1, 1, 10, 0, 3, 5, 3, 2, + 5, 1, 1, 1, 1, 5, 1, 1, 1, 8, + 1, 1, 5, 1, 1, 8, 1, 5, 1, 1, + 8, 1, 5, 0, 3, 5, 3, 3, 1, 1, + 4, 1, 1, 1, 4, 1, 1, 7, 0, 3, + 3, 3, 1, 1, 5, 1, 1, 9, 1, 5, + 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, + 1, 1, 1, 1, 10, 1, 1, 10, 1, 1, + 10, 10, 7, 0, 3, 3, 9, 7, 9, 10, + 1, 1, 9, 1, 1, 1, 1, 1, 10, 1, + 1, 7, 9, 1, 10, 7, 1, 10, 7, 1, + 10, 7, 1, 9, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 3, + 2, 1, 1, 4, 1, 1, 1, 2, 3, 4, + 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 4, 3, 1, 8, 0, 3, 3, - 3, 5, 3, 2, 1, 1, 4, 1, 1, 4, - 1, 4, 1, 4, 1, 4, 1, 4, 3, 1, - 6, 0, 3, 3, 3, 2, 1, 4, 3, 1, - 16, 1, 1, 1, 1, 0, 6, 3, 2, 1, - 1, 9, 1, 4, 3, 1, 6, 1, 1, 0, - 3, 3, 2, 1, 7 + 1, 1, 1, 1, 4, 3, 1, 8, 0, 3, + 3, 3, 5, 3, 2, 1, 1, 4, 1, 1, + 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, + 1, 6, 0, 3, 3, 3, 2, 1, 4, 3, + 1, 16, 1, 1, 1, 1, 0, 6, 3, 2, + 1, 1, 9, 1, 4, 3, 1, 6, 1, 1, + 0, 3, 3, 2, 1, 7 }; diff --git a/src/wkt2_grammar.y b/src/wkt2_grammar.y index 4f30b5b2..fc2e8bf0 100644 --- a/src/wkt2_grammar.y +++ b/src/wkt2_grammar.y @@ -1073,6 +1073,7 @@ map_projection_parameter: parameter_keyword left_delimiter parameter_name right_delimiter opt_separator_param_unit_identifier_list: + | wkt_separator identifier opt_separator_identifier_list | wkt_separator map_projection_parameter_unit opt_separator_identifier_list parameter_keyword: T_PARAMETER -- cgit v1.2.3 From c560b7957664c32e2465e8425abaccc5a6b2607d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 17 Nov 2020 12:39:48 +0100 Subject: cs2cs, cct, proj and geod: fflush(stdout) after each line to emit each result as soon as it is produced This is needed when working with pipes, when stdout is not an interactive terminal, and thus the behaviour is to have it buffered as a regular file, whereas with an interactive terminal, each newline character causes an implicit flush. --- src/apps/cct.cpp | 2 ++ src/apps/cs2cs.cpp | 1 + src/apps/geod.cpp | 1 + src/apps/proj.cpp | 3 +++ 4 files changed, 7 insertions(+) (limited to 'src') diff --git a/src/apps/cct.cpp b/src/apps/cct.cpp index c482efc2..fa75267a 100644 --- a/src/apps/cct.cpp +++ b/src/apps/cct.cpp @@ -470,6 +470,8 @@ int main(int argc, char **argv) { decimals_distances, point.xyzt.z, point.xyzt.t, comment_delimiter, comment ); + if( fout == stdout ) + fflush(stdout); } proj_destroy(P); diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp index 58c164c9..1a33d444 100644 --- a/src/apps/cs2cs.cpp +++ b/src/apps/cs2cs.cpp @@ -217,6 +217,7 @@ static void process(FILE *fid) printf("%s", s); else printf("\n"); + fflush(stdout); } } diff --git a/src/apps/geod.cpp b/src/apps/geod.cpp index 919430ca..35a8e826 100644 --- a/src/apps/geod.cpp +++ b/src/apps/geod.cpp @@ -124,6 +124,7 @@ process(FILE *fid) { (void)fputs(rtodms(pline, al21, 0, 0), stdout); } (void)fputs(s, stdout); + fflush(stdout); } } diff --git a/src/apps/proj.cpp b/src/apps/proj.cpp index 0bf98b3a..c9bd8950 100644 --- a/src/apps/proj.cpp +++ b/src/apps/proj.cpp @@ -171,6 +171,7 @@ static void process(FILE *fid) { (void)fputs("\t<* * * * * *>", stdout); } (void)fputs(bin_in ? "\n" : s, stdout); + fflush(stdout); } } @@ -286,6 +287,8 @@ static void vprocess(FILE *fid) { (void)fputs(proj_rtodms(pline, facs.meridian_convergence, 0, 0), stdout); (void)printf(" [ %.8f ]\n", facs.meridian_convergence * RAD_TO_DEG); (void)printf("Max-min (Tissot axis a-b) scale error: %.5f %.5f\n\n", facs.tissot_semimajor, facs.tissot_semiminor); + + fflush(stdout); } } -- cgit v1.2.3 From 2cbf659bfcdffe12a4e7e397553c886566b2e949 Mon Sep 17 00:00:00 2001 From: "J.H. van de Water" Date: Thu, 19 Nov 2020 10:52:29 +0100 Subject: Replace line feed in input line by null character As result of a modification in logging (adding a line feed), many changes had to be made in different places of cct.cpp. However, one missed the line feed in input to cct. As result of missing this, the output from cct showed a superfluous empty line after each output line, but only if the corresponding input line ended with comment. Replacing the LF in the "comment" string (present if the input line ended with comment) by a null character ('\0') solves this issue. Modification in logging? https://github.com/OSGeo/PROJ/commit/37da5e243191c04607597f6b8a77acfa017a5c99 ( cct: revise end-of-line handling in logging, and always output debug ) See also: https://github.com/OSGeo/PROJ/issues/1677 ( cct outputs excessive whitespace comments are included in input data ) --- src/apps/cct.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/apps/cct.cpp b/src/apps/cct.cpp index fa75267a..b0e15e62 100644 --- a/src/apps/cct.cpp +++ b/src/apps/cct.cpp @@ -450,6 +450,11 @@ int main(int argc, char **argv) { colmax = MAX(colmax, columns_xyzt[i]); comment = column(buf, colmax+1); } + /* remove the line feed from comment, as logger() above, invoked + by print() below (output), will add one */ + size_t len = strlen(comment); + if (len >= 1) + comment[len - 1] = '\0'; comment_delimiter = (comment && *comment) ? whitespace : blank_comment; /* Time to print the result */ -- cgit v1.2.3 From 9419b42ade1f1d35a61c05f0f7ce9aab2eeff3c7 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Sun, 1 Nov 2020 13:34:32 +0100 Subject: Remove proj_api.h Removes proj_api.h from the public API. The contents of the header file has been moved to proj_internal.h verbatim and any references to proj_api.h has been changed to proj_internal.h. The documentation of proj_api.h has been removed. The only exception to this is the API migration guides which still mention the old API. Fixes #837 --- src/Makefile.am | 2 +- src/apps/emess.cpp | 2 +- src/iso19111/datum.cpp | 1 - src/iso19111/factory.cpp | 1 - src/iso19111/io.cpp | 1 - src/lib_proj.cmake | 1 - src/mutex.cpp | 5 - src/proj.h | 4 - src/proj_api.h | 227 ------------------------------------------ src/proj_internal.h | 163 ++++++++++++++++++++++++++++-- src/projections/calcofi.cpp | 1 - src/tests/multistresstest.cpp | 2 +- src/tests/test228.cpp | 2 +- 13 files changed, 161 insertions(+), 251 deletions(-) delete mode 100644 src/proj_api.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 5b36c8bd..62bff403 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,7 @@ AM_CPPFLAGS = -DPROJ_LIB=\"$(pkgdatadir)\" \ -DMUTEX_@MUTEX_SETTING@ -I$(top_srcdir)/include @SQLITE3_CFLAGS@ @TIFF_CFLAGS@ @TIFF_ENABLED_FLAGS@ @CURL_CFLAGS@ @CURL_ENABLED_FLAGS@ AM_CXXFLAGS = @CXX_WFLAGS@ @FLTO_FLAG@ -include_HEADERS = proj.h proj_experimental.h proj_constants.h proj_api.h geodesic.h \ +include_HEADERS = proj.h proj_experimental.h proj_constants.h geodesic.h \ proj_symbol_rename.h EXTRA_DIST = bin_cct.cmake bin_gie.cmake bin_cs2cs.cmake \ diff --git a/src/apps/emess.cpp b/src/apps/emess.cpp index 53018ba8..138cbf01 100644 --- a/src/apps/emess.cpp +++ b/src/apps/emess.cpp @@ -19,7 +19,7 @@ #include #include -#include "proj_api.h" +#include "proj_internal.h" #include "proj_config.h" #define EMESS_ROUTINE #include "emess.h" diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index e29f6319..28dbc462 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -43,7 +43,6 @@ // clang-format off #include "proj.h" #include "proj_internal.h" -#include "proj_api.h" // clang-format on #include "proj_json_streaming_writer.hpp" diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 0ccfefc1..03fd5267 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -65,7 +65,6 @@ // clang-format off #include "proj.h" #include "proj_internal.h" -#include "proj_api.h" // clang-format on #include diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 623ad6f9..8c815f36 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -70,7 +70,6 @@ // clang-format off #include "proj.h" #include "proj_internal.h" -#include "proj_api.h" // clang-format on using namespace NS_PROJ::common; diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 67bc1f4e..95417004 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -275,7 +275,6 @@ set(SRC_LIBPROJ_CORE ) set(HEADERS_LIBPROJ - proj_api.h proj.h proj_experimental.h proj_constants.h diff --git a/src/mutex.cpp b/src/mutex.cpp index da415e55..2cc4d0a1 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -34,11 +34,6 @@ #ifndef _WIN32 #include "proj_config.h" #include "proj_internal.h" -#else -#ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -#endif -#include "proj_api.h" #endif /* on win32 we always use win32 mutexes, even if pthreads are available */ diff --git a/src/proj.h b/src/proj.h index 4185ddbf..0597db26 100644 --- a/src/proj.h +++ b/src/proj.h @@ -119,10 +119,6 @@ #include /* For size_t */ -#ifdef PROJ_API_H -#error proj.h must be included before proj_api.h -#endif - #ifdef PROJ_RENAME_SYMBOLS #include "proj_symbol_rename.h" #endif diff --git a/src/proj_api.h b/src/proj_api.h deleted file mode 100644 index a26088ca..00000000 --- a/src/proj_api.h +++ /dev/null @@ -1,227 +0,0 @@ -/****************************************************************************** - * Project: PROJ.4 - * Purpose: Public (application) include file for PROJ.4 API, and constants. - * Author: Frank Warmerdam, - * - ****************************************************************************** - * Copyright (c) 2001, 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. - *****************************************************************************/ - -/* - * This version number should be updated with every release! - * - * This file is expected to be removed from the PROJ distribution - * when a few minor-version releases has been made. - * - */ - -#ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -#error 'To use the proj_api.h you must define the macro ACCEPT_USE_OF_DEPRECATED_PROJ_API_H' -#endif - -#ifndef PJ_VERSION -#define PJ_VERSION 800 -#endif - -#ifdef PROJ_RENAME_SYMBOLS -#include "proj_symbol_rename.h" -#endif - - -/* If we're not asked for PJ_VERSION only, give them everything */ -#ifndef PROJ_API_INCLUDED_FOR_PJ_VERSION_ONLY -/* General projections header file */ -#ifndef PROJ_API_H -#define PROJ_API_H - -/* standard inclusions */ -#include -#include -#include - -#ifndef PROJ_DLL -#ifdef PROJ_MSVC_DLL_EXPORT -#define PROJ_DLL __declspec(dllexport) -#elif defined(PROJ_MSVC_DLL_IMPORT) -#define PROJ_DLL __declspec(dllimport) -#elif defined(__GNUC__) -#define PROJ_DLL __attribute__ ((visibility("default"))) -#else -#define PROJ_DLL -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -/* pj_init() and similar functions can be used with a non-C locale */ -/* Can be detected too at runtime if the symbol pj_atof exists */ -#define PJ_LOCALE_SAFE 1 - -#define RAD_TO_DEG 57.295779513082321 -#define DEG_TO_RAD .017453292519943296 - - -#if defined(PROJ_H) -#define PROJ_API_H_NOT_INVOKED_AS_PRIMARY_API -#endif - - - -extern char const PROJ_DLL pj_release[]; /* global release id string */ -PROJ_DLL extern int pj_errno; /* global error return code */ - -#ifndef PROJ_INTERNAL_H -/* replaced by enum proj_log_level in proj_internal.h */ -#define PJ_LOG_NONE 0 -#define PJ_LOG_ERROR 1 -#define PJ_LOG_DEBUG_MAJOR 2 -#define PJ_LOG_DEBUG_MINOR 3 -#endif - -#ifdef PROJ_API_H_NOT_INVOKED_AS_PRIMARY_API - /* These make the function declarations below conform with classic proj */ - typedef PJ *projPJ; /* projPJ is a pointer to PJ */ - typedef struct projCtx_t *projCtx; /* projCtx is a pointer to projCtx_t */ -# define projXY PJ_XY -# define projLP PJ_LP -# define projXYZ PJ_XYZ -# define projLPZ PJ_LPZ - -#else - /* i.e. proj_api invoked as primary API */ - typedef struct { double u, v; } projUV; - typedef struct { double u, v, w; } projUVW; - typedef void *projPJ; - #define projXY projUV - #define projLP projUV - #define projXYZ projUVW - #define projLPZ projUVW - typedef void *projCtx; -#endif - - -/* If included *after* proj.h finishes, we have alternative names */ -/* file reading api, like stdio */ -typedef int *PAFile; -typedef struct projFileAPI_t { - PAFile (*FOpen)(projCtx ctx, const char *filename, const char *access); - size_t (*FRead)(void *buffer, size_t size, size_t nmemb, PAFile file); - int (*FSeek)(PAFile file, long offset, int whence); - long (*FTell)(PAFile file); - void (*FClose)(PAFile); -} projFileAPI; - - - -/* procedure prototypes */ - -projCtx PROJ_DLL pj_get_default_ctx(void); -projCtx PROJ_DLL pj_get_ctx( projPJ ); - -projXY PROJ_DLL pj_fwd(projLP, projPJ); -projLP PROJ_DLL pj_inv(projXY, projPJ); - -projXYZ PROJ_DLL pj_fwd3d(projLPZ, projPJ); -projLPZ PROJ_DLL pj_inv3d(projXYZ, projPJ); - - -int PROJ_DLL pj_transform( projPJ src, projPJ dst, long point_count, int point_offset, - double *x, double *y, double *z ); -int PROJ_DLL pj_datum_transform( projPJ src, projPJ dst, long point_count, int point_offset, - double *x, double *y, double *z ); -int PROJ_DLL pj_geocentric_to_geodetic( double a, double es, - long point_count, int point_offset, - double *x, double *y, double *z ); -int PROJ_DLL pj_geodetic_to_geocentric( double a, double es, - long point_count, int point_offset, - double *x, double *y, double *z ); -int PROJ_DLL pj_compare_datums( projPJ srcdefn, projPJ dstdefn ); -int PROJ_DLL pj_apply_gridshift( projCtx, const char *, int, - long point_count, int point_offset, - double *x, double *y, double *z ); -void PROJ_DLL pj_deallocate_grids(void); -void PROJ_DLL pj_clear_initcache(void); -int PROJ_DLL pj_is_latlong(projPJ); -int PROJ_DLL pj_is_geocent(projPJ); -void PROJ_DLL pj_get_spheroid_defn(projPJ defn, double *major_axis, double *eccentricity_squared); -void PROJ_DLL pj_pr_list(projPJ); -void PROJ_DLL pj_free(projPJ); -void PROJ_DLL pj_set_finder( const char *(*)(const char *) ); -void PROJ_DLL pj_set_searchpath ( int count, const char **path ); -projPJ PROJ_DLL pj_init(int, char **); -projPJ PROJ_DLL pj_init_plus(const char *); -projPJ PROJ_DLL pj_init_ctx( projCtx, int, char ** ); -projPJ PROJ_DLL pj_init_plus_ctx( projCtx, const char * ); -char PROJ_DLL *pj_get_def(projPJ, int); -projPJ PROJ_DLL pj_latlong_from_proj( projPJ ); -int PROJ_DLL pj_has_inverse(projPJ); - - -void PROJ_DLL *pj_malloc(size_t); -void PROJ_DLL pj_dalloc(void *); -void PROJ_DLL *pj_calloc (size_t n, size_t size); -void PROJ_DLL *pj_dealloc (void *ptr); -char PROJ_DLL *pj_strdup(const char *str); -char PROJ_DLL *pj_strerrno(int); -int PROJ_DLL *pj_get_errno_ref(void); -const char PROJ_DLL *pj_get_release(void); -void PROJ_DLL pj_acquire_lock(void); -void PROJ_DLL pj_release_lock(void); -void PROJ_DLL pj_cleanup_lock(void); - -void PROJ_DLL pj_set_ctx( projPJ, projCtx ); -projCtx PROJ_DLL pj_ctx_alloc(void); -void PROJ_DLL pj_ctx_free( projCtx ); -int PROJ_DLL pj_ctx_get_errno( projCtx ); -void PROJ_DLL pj_ctx_set_errno( projCtx, int ); -void PROJ_DLL pj_ctx_set_debug( projCtx, int ); -void PROJ_DLL pj_ctx_set_logger( projCtx, void (*)(void *, int, const char *) ); -void PROJ_DLL pj_ctx_set_app_data( projCtx, void * ); -void PROJ_DLL *pj_ctx_get_app_data( projCtx ); -void PROJ_DLL pj_ctx_set_fileapi( projCtx, projFileAPI *); -projFileAPI PROJ_DLL *pj_ctx_get_fileapi( projCtx ); - -void PROJ_DLL pj_log( projCtx ctx, int level, const char *fmt, ... ); -void PROJ_DLL pj_stderr_logger( void *, int, const char * ); - -/* file api */ -projFileAPI PROJ_DLL *pj_get_default_fileapi(void); - -PAFile PROJ_DLL pj_ctx_fopen(projCtx ctx, const char *filename, const char *access); -size_t PROJ_DLL pj_ctx_fread(projCtx ctx, void *buffer, size_t size, size_t nmemb, PAFile file); -int PROJ_DLL pj_ctx_fseek(projCtx ctx, PAFile file, long offset, int whence); -long PROJ_DLL pj_ctx_ftell(projCtx ctx, PAFile file); -void PROJ_DLL pj_ctx_fclose(projCtx ctx, PAFile file); -char PROJ_DLL *pj_ctx_fgets(projCtx ctx, char *line, int size, PAFile file); - -PAFile PROJ_DLL pj_open_lib(projCtx, const char *, const char *); -int PROJ_DLL pj_find_file(projCtx ctx, const char *short_filename, - char* out_full_filename, size_t out_full_filename_size); - -#ifdef __cplusplus -} -#endif - -#endif /* ndef PROJ_API_H */ -#endif /* ndef PROJ_API_INCLUDED_FOR_PJ_VERSION_ONLY */ diff --git a/src/proj_internal.h b/src/proj_internal.h index 203765a3..5a075088 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -66,10 +66,6 @@ #include "proj.h" -#ifdef PROJ_API_H -#error proj_internal.h must be included before proj_api.h -#endif - #ifdef PROJ_RENAME_SYMBOLS #include "proj_symbol_rename.h" #endif @@ -910,7 +906,162 @@ void pj_clear_vgridshift_knowngrids_cache(); PJ_LP pj_generic_inverse_2d(PJ_XY xy, PJ *P, PJ_LP lpInitial); -/* classic public API */ -#include "proj_api.h" + + + +/*****************************************************************************/ +/* */ +/* proj_api.h */ +/* */ +/* The rest of this header file includes what used to be "proj_api.h" */ +/* */ +/*****************************************************************************/ + +/* pj_init() and similar functions can be used with a non-C locale */ +/* Can be detected too at runtime if the symbol pj_atof exists */ +#define PJ_LOCALE_SAFE 1 + +#define RAD_TO_DEG 57.295779513082321 +#define DEG_TO_RAD .017453292519943296 + + +#if defined(PROJ_H) +#define PROJ_API_H_NOT_INVOKED_AS_PRIMARY_API +#endif + + + +extern char const PROJ_DLL pj_release[]; /* global release id string */ +PROJ_DLL extern int pj_errno; /* global error return code */ + +#ifndef PROJ_INTERNAL_H +/* replaced by enum proj_log_level in proj_internal.h */ +#define PJ_LOG_NONE 0 +#define PJ_LOG_ERROR 1 +#define PJ_LOG_DEBUG_MAJOR 2 +#define PJ_LOG_DEBUG_MINOR 3 +#endif + +#ifdef PROJ_API_H_NOT_INVOKED_AS_PRIMARY_API + /* These make the function declarations below conform with classic proj */ + typedef PJ *projPJ; /* projPJ is a pointer to PJ */ + typedef struct projCtx_t *projCtx; /* projCtx is a pointer to projCtx_t */ +# define projXY PJ_XY +# define projLP PJ_LP +# define projXYZ PJ_XYZ +# define projLPZ PJ_LPZ + +#else + /* i.e. proj_api invoked as primary API */ + typedef struct { double u, v; } projUV; + typedef struct { double u, v, w; } projUVW; + typedef void *projPJ; + #define projXY projUV + #define projLP projUV + #define projXYZ projUVW + #define projLPZ projUVW + typedef void *projCtx; +#endif + + +/* If included *after* proj.h finishes, we have alternative names */ +/* file reading api, like stdio */ +typedef int *PAFile; +typedef struct projFileAPI_t { + PAFile (*FOpen)(projCtx ctx, const char *filename, const char *access); + size_t (*FRead)(void *buffer, size_t size, size_t nmemb, PAFile file); + int (*FSeek)(PAFile file, long offset, int whence); + long (*FTell)(PAFile file); + void (*FClose)(PAFile); +} projFileAPI; + + + +/* procedure prototypes */ + +projCtx PROJ_DLL pj_get_default_ctx(void); +projCtx PROJ_DLL pj_get_ctx( projPJ ); + +projXY PROJ_DLL pj_fwd(projLP, projPJ); +projLP PROJ_DLL pj_inv(projXY, projPJ); + +projXYZ PROJ_DLL pj_fwd3d(projLPZ, projPJ); +projLPZ PROJ_DLL pj_inv3d(projXYZ, projPJ); + + +int PROJ_DLL pj_transform( projPJ src, projPJ dst, long point_count, int point_offset, + double *x, double *y, double *z ); +int PROJ_DLL pj_datum_transform( projPJ src, projPJ dst, long point_count, int point_offset, + double *x, double *y, double *z ); +int PROJ_DLL pj_geocentric_to_geodetic( double a, double es, + long point_count, int point_offset, + double *x, double *y, double *z ); +int PROJ_DLL pj_geodetic_to_geocentric( double a, double es, + long point_count, int point_offset, + double *x, double *y, double *z ); +int PROJ_DLL pj_compare_datums( projPJ srcdefn, projPJ dstdefn ); +int PROJ_DLL pj_apply_gridshift( projCtx, const char *, int, + long point_count, int point_offset, + double *x, double *y, double *z ); +void PROJ_DLL pj_deallocate_grids(void); +void PROJ_DLL pj_clear_initcache(void); +int PROJ_DLL pj_is_latlong(projPJ); +int PROJ_DLL pj_is_geocent(projPJ); +void PROJ_DLL pj_get_spheroid_defn(projPJ defn, double *major_axis, double *eccentricity_squared); +void PROJ_DLL pj_pr_list(projPJ); +void PROJ_DLL pj_free(projPJ); +void PROJ_DLL pj_set_finder( const char *(*)(const char *) ); +void PROJ_DLL pj_set_searchpath ( int count, const char **path ); +projPJ PROJ_DLL pj_init(int, char **); +projPJ PROJ_DLL pj_init_plus(const char *); +projPJ PROJ_DLL pj_init_ctx( projCtx, int, char ** ); +projPJ PROJ_DLL pj_init_plus_ctx( projCtx, const char * ); +char PROJ_DLL *pj_get_def(projPJ, int); +projPJ PROJ_DLL pj_latlong_from_proj( projPJ ); +int PROJ_DLL pj_has_inverse(projPJ); + + +void PROJ_DLL *pj_malloc(size_t); +void PROJ_DLL pj_dalloc(void *); +void PROJ_DLL *pj_calloc (size_t n, size_t size); +void PROJ_DLL *pj_dealloc (void *ptr); +char PROJ_DLL *pj_strdup(const char *str); +char PROJ_DLL *pj_strerrno(int); +int PROJ_DLL *pj_get_errno_ref(void); +const char PROJ_DLL *pj_get_release(void); +void PROJ_DLL pj_acquire_lock(void); +void PROJ_DLL pj_release_lock(void); +void PROJ_DLL pj_cleanup_lock(void); + +void PROJ_DLL pj_set_ctx( projPJ, projCtx ); +projCtx PROJ_DLL pj_ctx_alloc(void); +void PROJ_DLL pj_ctx_free( projCtx ); +int PROJ_DLL pj_ctx_get_errno( projCtx ); +void PROJ_DLL pj_ctx_set_errno( projCtx, int ); +void PROJ_DLL pj_ctx_set_debug( projCtx, int ); +void PROJ_DLL pj_ctx_set_logger( projCtx, void (*)(void *, int, const char *) ); +void PROJ_DLL pj_ctx_set_app_data( projCtx, void * ); +void PROJ_DLL *pj_ctx_get_app_data( projCtx ); +void PROJ_DLL pj_ctx_set_fileapi( projCtx, projFileAPI *); +projFileAPI PROJ_DLL *pj_ctx_get_fileapi( projCtx ); + +void PROJ_DLL pj_log( projCtx ctx, int level, const char *fmt, ... ); +void PROJ_DLL pj_stderr_logger( void *, int, const char * ); + +/* file api */ +projFileAPI PROJ_DLL *pj_get_default_fileapi(void); + +PAFile PROJ_DLL pj_ctx_fopen(projCtx ctx, const char *filename, const char *access); +size_t PROJ_DLL pj_ctx_fread(projCtx ctx, void *buffer, size_t size, size_t nmemb, PAFile file); +int PROJ_DLL pj_ctx_fseek(projCtx ctx, PAFile file, long offset, int whence); +long PROJ_DLL pj_ctx_ftell(projCtx ctx, PAFile file); +void PROJ_DLL pj_ctx_fclose(projCtx ctx, PAFile file); +char PROJ_DLL *pj_ctx_fgets(projCtx ctx, char *line, int size, PAFile file); + +PAFile PROJ_DLL pj_open_lib(projCtx, const char *, const char *); +int PROJ_DLL pj_find_file(projCtx ctx, const char *short_filename, + char* out_full_filename, size_t out_full_filename_size); + + #endif /* ndef PROJ_INTERNAL_H */ diff --git a/src/projections/calcofi.cpp b/src/projections/calcofi.cpp index 57c12dde..d1e96de8 100644 --- a/src/projections/calcofi.cpp +++ b/src/projections/calcofi.cpp @@ -4,7 +4,6 @@ #include "proj.h" #include "proj_internal.h" -#include "proj_api.h" PROJ_HEAD(calcofi, "Cal Coop Ocean Fish Invest Lines/Stations") "\n\tCyl, Sph&Ell"; diff --git a/src/tests/multistresstest.cpp b/src/tests/multistresstest.cpp index 33d2d738..6af35979 100644 --- a/src/tests/multistresstest.cpp +++ b/src/tests/multistresstest.cpp @@ -34,7 +34,7 @@ #define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H #endif -#include "proj_api.h" +#include "proj_internal.h" #ifdef _WIN32 #include diff --git a/src/tests/test228.cpp b/src/tests/test228.cpp index 8ae17c87..b27ebf2f 100644 --- a/src/tests/test228.cpp +++ b/src/tests/test228.cpp @@ -30,7 +30,7 @@ #define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H #endif -#include "proj_api.h" +#include "proj_internal.h" #include /* for printf declaration */ -- cgit v1.2.3 From 9e50c8c0e207191c4c7bb6883f7ad485df04fc2c Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Sun, 1 Nov 2020 14:56:17 +0100 Subject: Remove ACCEPT_USE_OF_DEPRECATED_PROJ_API_H macro --- src/apps/emess.cpp | 4 ---- src/proj_internal.h | 4 ---- src/tests/multistresstest.cpp | 4 ---- src/tests/test228.cpp | 4 ---- 4 files changed, 16 deletions(-) (limited to 'src') diff --git a/src/apps/emess.cpp b/src/apps/emess.cpp index 138cbf01..5a50cd25 100644 --- a/src/apps/emess.cpp +++ b/src/apps/emess.cpp @@ -9,10 +9,6 @@ # endif #endif -#ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -#endif - #include #include #include diff --git a/src/proj_internal.h b/src/proj_internal.h index 5a075088..e0cc5170 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -33,10 +33,6 @@ #error "proj_internal.h can only be included from a C++ file" #endif -#ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -#endif - #ifdef _MSC_VER # ifndef _CRT_SECURE_NO_DEPRECATE # define _CRT_SECURE_NO_DEPRECATE diff --git a/src/tests/multistresstest.cpp b/src/tests/multistresstest.cpp index 6af35979..51720fbd 100644 --- a/src/tests/multistresstest.cpp +++ b/src/tests/multistresstest.cpp @@ -30,10 +30,6 @@ #include #include -#ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -#endif - #include "proj_internal.h" #ifdef _WIN32 diff --git a/src/tests/test228.cpp b/src/tests/test228.cpp index b27ebf2f..bffb8e79 100644 --- a/src/tests/test228.cpp +++ b/src/tests/test228.cpp @@ -26,10 +26,6 @@ * DEALINGS IN THE SOFTWARE. ****************************************************************************/ -#ifndef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -#define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H -#endif - #include "proj_internal.h" #include /* for printf declaration */ -- cgit v1.2.3 From eb82aa83f2530e5e4df420ab64476b947bdc7f5d Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Sat, 14 Nov 2020 11:04:02 +0100 Subject: Raise error when ACCEPT_USE_OF_DEPRECATED_PROJ_API_H is defined --- src/proj.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/proj.h b/src/proj.h index 0597db26..e2c47a17 100644 --- a/src/proj.h +++ b/src/proj.h @@ -119,6 +119,10 @@ #include /* For size_t */ +#ifdef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H + #error "The proj_api.h header has been removed from PROJ with version 8.0.0" +#endif + #ifdef PROJ_RENAME_SYMBOLS #include "proj_symbol_rename.h" #endif -- cgit v1.2.3 From e2dd223c5601b387cd622b88583e857b03e9fade Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Sat, 14 Nov 2020 11:28:36 +0100 Subject: Remove src/transform.cpp and related tests --- src/Makefile.am | 2 +- src/lib_proj.cmake | 1 - src/malloc.cpp | 1 - src/proj_internal.h | 12 - src/transform.cpp | 1850 --------------------------------------------------- 5 files changed, 1 insertion(+), 1865 deletions(-) delete mode 100644 src/transform.cpp (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 62bff403..edfd05ef 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -220,7 +220,7 @@ libproj_la_SOURCES = \ generic_inverse.cpp \ quadtree.hpp \ \ - datums.cpp datum_set.cpp transform.cpp \ + datums.cpp datum_set.cpp \ utils.cpp \ mutex.cpp initcache.cpp geodesic.c \ strtod.cpp \ diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 95417004..b0f9a6ba 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -246,7 +246,6 @@ set(SRC_LIBPROJ_CORE rtodms.cpp strerrno.cpp strtod.cpp - transform.cpp tsfn.cpp units.cpp utils.cpp diff --git a/src/malloc.cpp b/src/malloc.cpp index c8de6630..eb64023f 100644 --- a/src/malloc.cpp +++ b/src/malloc.cpp @@ -262,7 +262,6 @@ PJ *pj_default_destructor (PJ *P, int errlev) { /* Destructor */ void proj_cleanup() { /*****************************************************************************/ pj_clear_initcache(); - pj_deallocate_grids(); FileManager::clearMemoryCache(); pj_clear_hgridshift_knowngrids_cache(); pj_clear_vgridshift_knowngrids_cache(); diff --git a/src/proj_internal.h b/src/proj_internal.h index e0cc5170..062f240b 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -985,21 +985,9 @@ projXYZ PROJ_DLL pj_fwd3d(projLPZ, projPJ); projLPZ PROJ_DLL pj_inv3d(projXYZ, projPJ); -int PROJ_DLL pj_transform( projPJ src, projPJ dst, long point_count, int point_offset, - double *x, double *y, double *z ); -int PROJ_DLL pj_datum_transform( projPJ src, projPJ dst, long point_count, int point_offset, - double *x, double *y, double *z ); -int PROJ_DLL pj_geocentric_to_geodetic( double a, double es, - long point_count, int point_offset, - double *x, double *y, double *z ); -int PROJ_DLL pj_geodetic_to_geocentric( double a, double es, - long point_count, int point_offset, - double *x, double *y, double *z ); -int PROJ_DLL pj_compare_datums( projPJ srcdefn, projPJ dstdefn ); int PROJ_DLL pj_apply_gridshift( projCtx, const char *, int, long point_count, int point_offset, double *x, double *y, double *z ); -void PROJ_DLL pj_deallocate_grids(void); void PROJ_DLL pj_clear_initcache(void); int PROJ_DLL pj_is_latlong(projPJ); int PROJ_DLL pj_is_geocent(projPJ); diff --git a/src/transform.cpp b/src/transform.cpp deleted file mode 100644 index cff89232..00000000 --- a/src/transform.cpp +++ /dev/null @@ -1,1850 +0,0 @@ -/****************************************************************************** - * Project: PROJ.4 - * Purpose: Perform overall coordinate system to coordinate system - * transformations (pj_transform() function) including reprojection - * and datum shifting. - * 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. - *****************************************************************************/ - -#include -#include -#include - -#include "proj.h" -#include "proj_internal.h" -#include "grids.hpp" - -using namespace NS_PROJ; - - -/////////////////////////////////////////////////////////////////////////////// -/// From older geocent.h -/////////////////////////////////////////////////////////////////////////////// - - -/***************************************************************************/ -/* RSC IDENTIFIER: GEOCENTRIC - * - * ABSTRACT - * - * This component provides conversions between Geodetic coordinates (latitude, - * longitude in radians and height in meters) and Geocentric coordinates - * (X, Y, Z) in meters. - * - * ERROR HANDLING - * - * This component checks parameters for valid values. If an invalid value - * is found, the error code is combined with the current error code using - * the bitwise or. This combining allows multiple error codes to be - * returned. The possible error codes are: - * - * GEOCENT_NO_ERROR : No errors occurred in function - * GEOCENT_LAT_ERROR : Latitude out of valid range - * (-90 to 90 degrees) - * GEOCENT_LON_ERROR : Longitude out of valid range - * (-180 to 360 degrees) - * GEOCENT_A_ERROR : Semi-major axis less than or equal to zero - * GEOCENT_B_ERROR : Semi-minor axis less than or equal to zero - * GEOCENT_A_LESS_B_ERROR : Semi-major axis less than semi-minor axis - * - * - * REUSE NOTES - * - * GEOCENTRIC is intended for reuse by any application that performs - * coordinate conversions between geodetic coordinates and geocentric - * coordinates. - * - * - * REFERENCES - * - * An Improved Algorithm for Geocentric to Geodetic Coordinate Conversion, - * Ralph Toms, February 1996 UCRL-JC-123138. - * - * Further information on GEOCENTRIC can be found in the Reuse Manual. - * - * GEOCENTRIC originated from : U.S. Army Topographic Engineering Center - * Geospatial Information Division - * 7701 Telegraph Road - * Alexandria, VA 22310-3864 - * - * LICENSES - * - * None apply to this component. - * - * RESTRICTIONS - * - * GEOCENTRIC has no restrictions. - * - * ENVIRONMENT - * - * GEOCENTRIC was tested and certified in the following environments: - * - * 1. Solaris 2.5 with GCC version 2.8.1 - * 2. Windows 95 with MS Visual C++ version 6 - * - * MODIFICATIONS - * - * Date Description - * ---- ----------- - * - * - */ - - -/***************************************************************************/ -/* - * DEFINES - */ -#define GEOCENT_NO_ERROR 0x0000 -#define GEOCENT_LAT_ERROR 0x0001 -#define GEOCENT_LON_ERROR 0x0002 -#define GEOCENT_A_ERROR 0x0004 -#define GEOCENT_B_ERROR 0x0008 -#define GEOCENT_A_LESS_B_ERROR 0x0010 - - -/***************************************************************************/ -/* - * FUNCTION PROTOTYPES - */ - -/* ensure proper linkage to c++ programs */ -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct -{ - double Geocent_a; /* Semi-major axis of ellipsoid in meters */ - double Geocent_b; /* Semi-minor axis of ellipsoid */ - double Geocent_a2; /* Square of semi-major axis */ - double Geocent_b2; /* Square of semi-minor axis */ - double Geocent_e2; /* Eccentricity squared */ - double Geocent_ep2; /* 2nd eccentricity squared */ -} GeocentricInfo; - -void pj_Init_Geocentric( GeocentricInfo *gi ); -long pj_Set_Geocentric_Parameters( GeocentricInfo *gi, - double a, - double b); - -/* - * The function Set_Geocentric_Parameters receives the ellipsoid parameters - * as inputs and sets the corresponding state variables. - * - * a : Semi-major axis, in meters. (input) - * b : Semi-minor axis, in meters. (input) - */ - - -void pj_Get_Geocentric_Parameters ( GeocentricInfo *gi, - double *a, - double *b); - -/* - * The function Get_Geocentric_Parameters returns the ellipsoid parameters - * to be used in geocentric coordinate conversions. - * - * a : Semi-major axis, in meters. (output) - * b : Semi-minor axis, in meters. (output) - */ - - -long pj_Convert_Geodetic_To_Geocentric ( GeocentricInfo *gi, - double Latitude, - double Longitude, - double Height, - double *X, - double *Y, - double *Z); -/* - * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates - * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z), - * according to the current ellipsoid parameters. - * - * Latitude : Geodetic latitude in radians (input) - * Longitude : Geodetic longitude in radians (input) - * Height : Geodetic height, in meters (input) - * X : Calculated Geocentric X coordinate, in meters. (output) - * Y : Calculated Geocentric Y coordinate, in meters. (output) - * Z : Calculated Geocentric Z coordinate, in meters. (output) - * - */ - - -void pj_Convert_Geocentric_To_Geodetic (GeocentricInfo *gi, - double X, - double Y, - double Z, - double *Latitude, - double *Longitude, - double *Height); -/* - * The function Convert_Geocentric_To_Geodetic converts geocentric - * coordinates (X, Y, Z) to geodetic coordinates (latitude, longitude, - * and height), according to the current ellipsoid parameters. - * - * X : Geocentric X coordinate, in meters. (input) - * Y : Geocentric Y coordinate, in meters. (input) - * Z : Geocentric Z coordinate, in meters. (input) - * Latitude : Calculated latitude value in radians. (output) - * Longitude : Calculated longitude value in radians. (output) - * Height : Calculated height value, in meters. (output) - */ - - -#ifdef __cplusplus -} -#endif - - -/////////////////////////////////////////////////////////////////////////////// -/// From older geocent.cpp -/////////////////////////////////////////////////////////////////////////////// - - -/***************************************************************************/ -/* RSC IDENTIFIER: GEOCENTRIC - * - * ABSTRACT - * - * This component provides conversions between Geodetic coordinates (latitude, - * longitude in radians and height in meters) and Geocentric coordinates - * (X, Y, Z) in meters. - * - * ERROR HANDLING - * - * This component checks parameters for valid values. If an invalid value - * is found, the error code is combined with the current error code using - * the bitwise or. This combining allows multiple error codes to be - * returned. The possible error codes are: - * - * GEOCENT_NO_ERROR : No errors occurred in function - * GEOCENT_LAT_ERROR : Latitude out of valid range - * (-90 to 90 degrees) - * GEOCENT_LON_ERROR : Longitude out of valid range - * (-180 to 360 degrees) - * GEOCENT_A_ERROR : Semi-major axis lessthan or equal to zero - * GEOCENT_B_ERROR : Semi-minor axis lessthan or equal to zero - * GEOCENT_A_LESS_B_ERROR : Semi-major axis less than semi-minor axis - * - * - * REUSE NOTES - * - * GEOCENTRIC is intended for reuse by any application that performs - * coordinate conversions between geodetic coordinates and geocentric - * coordinates. - * - * - * REFERENCES - * - * An Improved Algorithm for Geocentric to Geodetic Coordinate Conversion, - * Ralph Toms, February 1996 UCRL-JC-123138. - * - * Further information on GEOCENTRIC can be found in the Reuse Manual. - * - * GEOCENTRIC originated from : U.S. Army Topographic Engineering Center - * Geospatial Information Division - * 7701 Telegraph Road - * Alexandria, VA 22310-3864 - * - * LICENSES - * - * None apply to this component. - * - * RESTRICTIONS - * - * GEOCENTRIC has no restrictions. - * - * ENVIRONMENT - * - * GEOCENTRIC was tested and certified in the following environments: - * - * 1. Solaris 2.5 with GCC version 2.8.1 - * 2. Windows 95 with MS Visual C++ version 6 - * - * MODIFICATIONS - * - * Date Description - * ---- ----------- - * 25-02-97 Original Code - * - */ - - -/***************************************************************************/ -/* - * INCLUDES - */ -#include -//#include "geocent.h" -/* - * math.h - is needed for calls to sin, cos, tan and sqrt. - * geocent.h - is needed for Error codes and prototype error checking. - */ - - -/***************************************************************************/ -/* - * DEFINES - */ -#define PI 3.14159265358979323e0 -#define PI_OVER_2 (PI / 2.0e0) -#define FALSE 0 -#define TRUE 1 -#define COS_67P5 0.38268343236508977 /* cosine of 67.5 degrees */ -#define AD_C 1.0026000 /* Toms region 1 constant */ - - -/***************************************************************************/ -/* - * FUNCTIONS - */ - - -long pj_Set_Geocentric_Parameters (GeocentricInfo *gi, double a, double b) - -{ /* BEGIN Set_Geocentric_Parameters */ -/* - * The function Set_Geocentric_Parameters receives the ellipsoid parameters - * as inputs and sets the corresponding state variables. - * - * a : Semi-major axis, in meters. (input) - * b : Semi-minor axis, in meters. (input) - */ - long Error_Code = GEOCENT_NO_ERROR; - - if (a <= 0.0) - Error_Code |= GEOCENT_A_ERROR; - if (b <= 0.0) - Error_Code |= GEOCENT_B_ERROR; - if (a < b) - Error_Code |= GEOCENT_A_LESS_B_ERROR; - if (!Error_Code) - { - gi->Geocent_a = a; - gi->Geocent_b = b; - gi->Geocent_a2 = a * a; - gi->Geocent_b2 = b * b; - gi->Geocent_e2 = (gi->Geocent_a2 - gi->Geocent_b2) / gi->Geocent_a2; - gi->Geocent_ep2 = (gi->Geocent_a2 - gi->Geocent_b2) / gi->Geocent_b2; - } - return (Error_Code); -} /* END OF Set_Geocentric_Parameters */ - - -void pj_Get_Geocentric_Parameters (GeocentricInfo *gi, - double *a, - double *b) -{ /* BEGIN Get_Geocentric_Parameters */ -/* - * The function Get_Geocentric_Parameters returns the ellipsoid parameters - * to be used in geocentric coordinate conversions. - * - * a : Semi-major axis, in meters. (output) - * b : Semi-minor axis, in meters. (output) - */ - - *a = gi->Geocent_a; - *b = gi->Geocent_b; -} /* END OF Get_Geocentric_Parameters */ - - -long pj_Convert_Geodetic_To_Geocentric (GeocentricInfo *gi, - double Latitude, - double Longitude, - double Height, - double *X, - double *Y, - double *Z) -{ /* BEGIN Convert_Geodetic_To_Geocentric */ -/* - * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates - * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z), - * according to the current ellipsoid parameters. - * - * Latitude : Geodetic latitude in radians (input) - * Longitude : Geodetic longitude in radians (input) - * Height : Geodetic height, in meters (input) - * X : Calculated Geocentric X coordinate, in meters (output) - * Y : Calculated Geocentric Y coordinate, in meters (output) - * Z : Calculated Geocentric Z coordinate, in meters (output) - * - */ - long Error_Code = GEOCENT_NO_ERROR; - double Rn; /* Earth radius at location */ - double Sin_Lat; /* sin(Latitude) */ - double Sin2_Lat; /* Square of sin(Latitude) */ - double Cos_Lat; /* cos(Latitude) */ - - /* - ** Don't blow up if Latitude is just a little out of the value - ** range as it may just be a rounding issue. Also removed longitude - ** test, it should be wrapped by cos() and sin(). NFW for PROJ.4, Sep/2001. - */ - if( Latitude < -PI_OVER_2 && Latitude > -1.001 * PI_OVER_2 ) - Latitude = -PI_OVER_2; - else if( Latitude > PI_OVER_2 && Latitude < 1.001 * PI_OVER_2 ) - Latitude = PI_OVER_2; - else if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2)) - { /* Latitude out of range */ - Error_Code |= GEOCENT_LAT_ERROR; - } - - if (!Error_Code) - { /* no errors */ - if (Longitude > PI) - Longitude -= (2*PI); - Sin_Lat = sin(Latitude); - Cos_Lat = cos(Latitude); - Sin2_Lat = Sin_Lat * Sin_Lat; - Rn = gi->Geocent_a / (sqrt(1.0e0 - gi->Geocent_e2 * Sin2_Lat)); - *X = (Rn + Height) * Cos_Lat * cos(Longitude); - *Y = (Rn + Height) * Cos_Lat * sin(Longitude); - *Z = ((Rn * (1 - gi->Geocent_e2)) + Height) * Sin_Lat; - - } - return (Error_Code); -} /* END OF Convert_Geodetic_To_Geocentric */ - -/* - * The function Convert_Geocentric_To_Geodetic converts geocentric - * coordinates (X, Y, Z) to geodetic coordinates (latitude, longitude, - * and height), according to the current ellipsoid parameters. - * - * X : Geocentric X coordinate, in meters. (input) - * Y : Geocentric Y coordinate, in meters. (input) - * Z : Geocentric Z coordinate, in meters. (input) - * Latitude : Calculated latitude value in radians. (output) - * Longitude : Calculated longitude value in radians. (output) - * Height : Calculated height value, in meters. (output) - */ - -#define USE_ITERATIVE_METHOD - -void pj_Convert_Geocentric_To_Geodetic (GeocentricInfo *gi, - double X, - double Y, - double Z, - double *Latitude, - double *Longitude, - double *Height) -{ /* BEGIN Convert_Geocentric_To_Geodetic */ -#if !defined(USE_ITERATIVE_METHOD) -/* - * The method used here is derived from 'An Improved Algorithm for - * Geocentric to Geodetic Coordinate Conversion', by Ralph Toms, Feb 1996 - */ - -/* Note: Variable names follow the notation used in Toms, Feb 1996 */ - - double W; /* distance from Z axis */ - double W2; /* square of distance from Z axis */ - double T0; /* initial estimate of vertical component */ - double T1; /* corrected estimate of vertical component */ - double S0; /* initial estimate of horizontal component */ - double S1; /* corrected estimate of horizontal component */ - double Sin_B0; /* sin(B0), B0 is estimate of Bowring aux variable */ - double Sin3_B0; /* cube of sin(B0) */ - double Cos_B0; /* cos(B0) */ - double Sin_p1; /* sin(phi1), phi1 is estimated latitude */ - double Cos_p1; /* cos(phi1) */ - double Rn; /* Earth radius at location */ - double Sum; /* numerator of cos(phi1) */ - int At_Pole; /* indicates location is in polar region */ - - At_Pole = FALSE; - if (X != 0.0) - { - *Longitude = atan2(Y,X); - } - else - { - if (Y > 0) - { - *Longitude = PI_OVER_2; - } - else if (Y < 0) - { - *Longitude = -PI_OVER_2; - } - else - { - At_Pole = TRUE; - *Longitude = 0.0; - if (Z > 0.0) - { /* north pole */ - *Latitude = PI_OVER_2; - } - else if (Z < 0.0) - { /* south pole */ - *Latitude = -PI_OVER_2; - } - else - { /* center of earth */ - *Latitude = PI_OVER_2; - *Height = -Geocent_b; - return; - } - } - } - W2 = X*X + Y*Y; - W = sqrt(W2); - T0 = Z * AD_C; - S0 = sqrt(T0 * T0 + W2); - Sin_B0 = T0 / S0; - Cos_B0 = W / S0; - Sin3_B0 = Sin_B0 * Sin_B0 * Sin_B0; - T1 = Z + gi->Geocent_b * gi->Geocent_ep2 * Sin3_B0; - Sum = W - gi->Geocent_a * gi->Geocent_e2 * Cos_B0 * Cos_B0 * Cos_B0; - S1 = sqrt(T1*T1 + Sum * Sum); - Sin_p1 = T1 / S1; - Cos_p1 = Sum / S1; - Rn = gi->Geocent_a / sqrt(1.0 - gi->Geocent_e2 * Sin_p1 * Sin_p1); - if (Cos_p1 >= COS_67P5) - { - *Height = W / Cos_p1 - Rn; - } - else if (Cos_p1 <= -COS_67P5) - { - *Height = W / -Cos_p1 - Rn; - } - else - { - *Height = Z / Sin_p1 + Rn * (gi->Geocent_e2 - 1.0); - } - if (At_Pole == FALSE) - { - *Latitude = atan(Sin_p1 / Cos_p1); - } -#else /* defined(USE_ITERATIVE_METHOD) */ -/* -* Reference... -* ============ -* Wenzel, H.-G.(1985): Hochauflösende Kugelfunktionsmodelle für -* das Gravitationspotential der Erde. Wiss. Arb. Univ. Hannover -* Nr. 137, p. 130-131. - -* Programmed by GGA- Leibniz-Institute of Applied Geophysics -* Stilleweg 2 -* D-30655 Hannover -* Federal Republic of Germany -* Internet: www.gga-hannover.de -* -* Hannover, March 1999, April 2004. -* see also: comments in statements -* remarks: -* Mathematically exact and because of symmetry of rotation-ellipsoid, -* each point (X,Y,Z) has at least two solutions (Latitude1,Longitude1,Height1) and -* (Latitude2,Longitude2,Height2). Is point=(0.,0.,Z) (P=0.), so you get even -* four solutions, every two symmetrical to the semi-minor axis. -* Here Height1 and Height2 have at least a difference in order of -* radius of curvature (e.g. (0,0,b)=> (90.,0.,0.) or (-90.,0.,-2b); -* (a+100.)*(sqrt(2.)/2.,sqrt(2.)/2.,0.) => (0.,45.,100.) or -* (0.,225.,-(2a+100.))). -* The algorithm always computes (Latitude,Longitude) with smallest |Height|. -* For normal computations, that means |Height|<10000.m, algorithm normally -* converges after to 2-3 steps!!! -* But if |Height| has the amount of length of ellipsoid's axis -* (e.g. -6300000.m), algorithm needs about 15 steps. -*/ - -/* local definitions and variables */ -/* end-criterium of loop, accuracy of sin(Latitude) */ -#define genau 1.E-12 -#define genau2 (genau*genau) -#define maxiter 30 - - double P; /* distance between semi-minor axis and location */ - double RR; /* distance between center and location */ - double CT; /* sin of geocentric latitude */ - double ST; /* cos of geocentric latitude */ - double RX; - double RK; - double RN; /* Earth radius at location */ - double CPHI0; /* cos of start or old geodetic latitude in iterations */ - double SPHI0; /* sin of start or old geodetic latitude in iterations */ - double CPHI; /* cos of searched geodetic latitude */ - double SPHI; /* sin of searched geodetic latitude */ - double SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */ - int iter; /* # of continuous iteration, max. 30 is always enough (s.a.) */ - - P = sqrt(X*X+Y*Y); - RR = sqrt(X*X+Y*Y+Z*Z); - -/* special cases for latitude and longitude */ - if (P/gi->Geocent_a < genau) { - -/* special case, if P=0. (X=0., Y=0.) */ - *Longitude = 0.; - -/* if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis - * of ellipsoid (=center of mass), Latitude becomes PI/2 */ - if (RR/gi->Geocent_a < genau) { - *Latitude = PI_OVER_2; - *Height = -gi->Geocent_b; - return ; - - } - } - else { -/* ellipsoidal (geodetic) longitude - * interval: -PI < Longitude <= +PI */ - *Longitude=atan2(Y,X); - } - -/* -------------------------------------------------------------- - * Following iterative algorithm was developed by - * "Institut für Erdmessung", University of Hannover, July 1988. - * Internet: www.ife.uni-hannover.de - * Iterative computation of CPHI,SPHI and Height. - * Iteration of CPHI and SPHI to 10**-12 radian resp. - * 2*10**-7 arcsec. - * -------------------------------------------------------------- - */ - CT = Z/RR; - ST = P/RR; - { - const double denominator = 1.0-gi->Geocent_e2*(2.0-gi->Geocent_e2)*ST*ST; - if( denominator == 0 ) - { - *Latitude = HUGE_VAL; - *Longitude = HUGE_VAL; - *Height = HUGE_VAL; - return; - } - RX = 1.0/sqrt(denominator); - } - CPHI0 = ST*(1.0-gi->Geocent_e2)*RX; - SPHI0 = CT*RX; - iter = 0; - -/* loop to find sin(Latitude) resp. Latitude - * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */ - do - { - iter++; - RN = gi->Geocent_a/sqrt(1.0-gi->Geocent_e2*SPHI0*SPHI0); - -/* ellipsoidal (geodetic) height */ - *Height = P*CPHI0+Z*SPHI0-RN*(1.0-gi->Geocent_e2*SPHI0*SPHI0); - - /* avoid zero division */ - if (RN+*Height==0.0) { - *Latitude = 0.0; - return; - } - RK = gi->Geocent_e2*RN/(RN+*Height); - { - const double denominator = 1.0-RK*(2.0-RK)*ST*ST; - if( denominator == 0 ) - { - *Latitude = HUGE_VAL; - *Longitude = HUGE_VAL; - *Height = HUGE_VAL; - return; - } - RX = 1.0/sqrt(denominator); - } - CPHI = ST*(1.0-RK)*RX; - SPHI = CT*RX; - SDPHI = SPHI*CPHI0-CPHI*SPHI0; - CPHI0 = CPHI; - SPHI0 = SPHI; - } - while (SDPHI*SDPHI > genau2 && iter < maxiter); - -/* ellipsoidal (geodetic) latitude */ - *Latitude=atan2(SPHI, fabs(CPHI)); - -#endif /* defined(USE_ITERATIVE_METHOD) */ -} /* END OF Convert_Geocentric_To_Geodetic */ - - -/////////////////////////////////////////////////////////////////////////////// -/// Main of transform.cpp -/////////////////////////////////////////////////////////////////////////////// - - -static int adjust_axis( projCtx ctx, const char *axis, int denormalize_flag, - long point_count, int point_offset, - double *x, double *y, double *z ); - -#ifndef SRS_WGS84_SEMIMAJOR -#define SRS_WGS84_SEMIMAJOR 6378137.0 -#endif - -#ifndef SRS_WGS84_ESQUARED -#define SRS_WGS84_ESQUARED 0.0066943799901413165 -#endif - -#define Dx_BF (defn->datum_params[0]) -#define Dy_BF (defn->datum_params[1]) -#define Dz_BF (defn->datum_params[2]) -#define Rx_BF (defn->datum_params[3]) -#define Ry_BF (defn->datum_params[4]) -#define Rz_BF (defn->datum_params[5]) -#define M_BF (defn->datum_params[6]) - -/* -** This table is intended to indicate for any given error code -** whether that error will occur for all locations (ie. -** it is a problem with the coordinate system as a whole) in which case the -** value would be 0, or if the problem is with the point being transformed -** in which case the value is 1. -** -** At some point we might want to move this array in with the error message -** list or something, but while experimenting with it this should be fine. -** -** -** NOTE (2017-10-01): Non-transient errors really should have resulted in a -** PJ==0 during initialization, and hence should be handled at the level -** before calling pj_transform. The only obvious example of the contrary -** appears to be the PJD_ERR_GRID_AREA case, which may also be taken to -** mean "no grids available" -** -** -*/ - -static const int transient_error[70] = { - /* 0 1 2 3 4 5 6 7 8 9 */ - /* 0 to 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 10 to 19 */ 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, - /* 20 to 29 */ 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, - /* 30 to 39 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 40 to 49 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - /* 50 to 59 */ 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, - /* 60 to 69 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}; - - -/* -------------------------------------------------------------------- */ -/* Read transient_error[] in a safe way. */ -/* -------------------------------------------------------------------- */ -static int get_transient_error_value(int pos_index) -{ - const int array_size = - (int)(sizeof(transient_error) / sizeof(transient_error[0])); - if( pos_index < 0 || pos_index >= array_size ) { - return 0; - } - return transient_error[pos_index]; -} - - -/* -------------------------------------------------------------------- */ -/* Transform unusual input coordinate axis orientation to */ -/* standard form if needed. */ -/* -------------------------------------------------------------------- */ -static int adjust_axes (PJ *P, PJ_DIRECTION dir, long n, int dist, double *x, double *y, double *z) { - /* Nothing to do? */ - if (0==strcmp(P->axis,"enu")) - return 0; - - return adjust_axis( P->ctx, P->axis, - dir==PJ_FWD ? 1: 0, n, dist, x, y, z ); -} - - - -/* ----------------------------------------------------------------------- */ -/* Transform geographic (lat/long) source coordinates to */ -/* cartesian ("geocentric"), if needed */ -/* ----------------------------------------------------------------------- */ -static int geographic_to_cartesian (PJ *P, PJ_DIRECTION dir, long n, int dist, double *x, double *y, double *z) { - int res; - long i; - double fac = P->to_meter; - - /* Nothing to do? */ - if (!P->is_geocent) - return 0; - - if ( z == nullptr ) { - pj_ctx_set_errno( pj_get_ctx(P), PJD_ERR_GEOCENTRIC); - return PJD_ERR_GEOCENTRIC; - } - - if (PJ_FWD==dir) { - fac = P->fr_meter; - res = pj_geodetic_to_geocentric( P->a_orig, P->es_orig, n, dist, x, y, z ); - if (res) - return res; - } - - if (fac != 1.0) { - for( i = 0; i < n; i++ ) { - if( x[dist*i] != HUGE_VAL ) { - x[dist*i] *= fac; - y[dist*i] *= fac; - z[dist*i] *= fac; - } - } - } - - if (PJ_FWD==dir) - return 0; - return pj_geocentric_to_geodetic( - P->a_orig, P->es_orig, - n, dist, - x, y, z - ); -} - - - - - - - - - - -/* -------------------------------------------------------------------- */ -/* Transform destination points to projection coordinates, if */ -/* desired. */ -/* */ -/* Ought to fold this into projected_to_geographic */ -/* -------------------------------------------------------------------- */ -static int geographic_to_projected (PJ *P, long n, int dist, double *x, double *y, double *z) { - long i; - - /* Nothing to do? */ - if (P->is_latlong && !P->geoc && P->vto_meter == 1.0) - return 0; - if (P->is_geocent) - return 0; - - if(P->fwd3d != nullptr && !(z == nullptr && P->is_latlong)) - { - /* Three dimensions must be defined */ - if ( z == nullptr) - { - pj_ctx_set_errno( pj_get_ctx(P), PJD_ERR_GEOCENTRIC); - return PJD_ERR_GEOCENTRIC; - } - - for( i = 0; i < n; i++ ) - { - PJ_XYZ projected_loc; - PJ_LPZ geodetic_loc; - - geodetic_loc.lam = x[dist*i]; - geodetic_loc.phi = y[dist*i]; - geodetic_loc.z = z[dist*i]; - - if (geodetic_loc.lam == HUGE_VAL) - continue; - - proj_errno_reset( P ); - projected_loc = pj_fwd3d( geodetic_loc, P); - if( P->ctx->last_errno != 0 ) - { - if( (P->ctx->last_errno != EDOM - && P->ctx->last_errno != ERANGE) - && (P->ctx->last_errno > 0 - || P->ctx->last_errno < -44 || n == 1 - || get_transient_error_value(-P->ctx->last_errno) == 0 ) ) - { - return P->ctx->last_errno; - } - else - { - projected_loc.x = HUGE_VAL; - projected_loc.y = HUGE_VAL; - projected_loc.z = HUGE_VAL; - } - } - - x[dist*i] = projected_loc.x; - y[dist*i] = projected_loc.y; - z[dist*i] = projected_loc.z; - } - return 0; - } - - // Ugly hack. See https://github.com/OSGeo/PROJ/issues/1782 - if( P->right == PJ_IO_UNITS_WHATEVER && P->descr && - strncmp(P->descr, "General Oblique Transformation", - strlen("General Oblique Transformation")) == 0 ) - { - P->right = PJ_IO_UNITS_PROJECTED; - } - - for( i = 0; i ctx->last_errno != 0 ) - { - if( (P->ctx->last_errno != EDOM - && P->ctx->last_errno != ERANGE) - && (P->ctx->last_errno > 0 - || P->ctx->last_errno < -44 || n == 1 - || get_transient_error_value(-P->ctx->last_errno) == 0 ) ) - { - return P->ctx->last_errno; - } - else - { - projected_loc.x = HUGE_VAL; - projected_loc.y = HUGE_VAL; - } - } - - x[dist*i] = projected_loc.x; - y[dist*i] = projected_loc.y; - } - return 0; -} - - - - - -/* ----------------------------------------------------------------------- */ -/* Transform projected source coordinates to lat/long, if needed */ -/* ----------------------------------------------------------------------- */ -static int projected_to_geographic (PJ *P, long n, int dist, double *x, double *y, double *z) { - long i; - - /* Nothing to do? */ - if (P->is_latlong && !P->geoc && P->vto_meter == 1.0) - return 0; - if (P->is_geocent) - return 0; - - /* Check first if projection is invertible. */ - if( (P->inv3d == nullptr) && (P->inv == nullptr)) - { - pj_ctx_set_errno(pj_get_ctx(P), PJD_ERR_NON_CONV_INV_MERI_DIST); - pj_log( pj_get_ctx(P), PJ_LOG_ERROR, - "pj_transform(): source projection not invertable" ); - return PJD_ERR_NON_CONV_INV_MERI_DIST; - } - - /* If invertible - First try inv3d if defined */ - if (P->inv3d != nullptr && !(z == nullptr && P->is_latlong)) - { - /* Three dimensions must be defined */ - if ( z == nullptr) - { - pj_ctx_set_errno( pj_get_ctx(P), PJD_ERR_GEOCENTRIC); - return PJD_ERR_GEOCENTRIC; - } - - for (i=0; i < n; i++) - { - PJ_XYZ projected_loc; - PJ_LPZ geodetic_loc; - - projected_loc.x = x[dist*i]; - projected_loc.y = y[dist*i]; - projected_loc.z = z[dist*i]; - - if (projected_loc.x == HUGE_VAL) - continue; - - proj_errno_reset( P ); - geodetic_loc = pj_inv3d(projected_loc, P); - if( P->ctx->last_errno != 0 ) - { - if( (P->ctx->last_errno != EDOM - && P->ctx->last_errno != ERANGE) - && (P->ctx->last_errno > 0 - || P->ctx->last_errno < -44 || n == 1 - || get_transient_error_value(-P->ctx->last_errno) == 0 ) ) - { - return P->ctx->last_errno; - } - else - { - geodetic_loc.lam = HUGE_VAL; - geodetic_loc.phi = HUGE_VAL; - geodetic_loc.z = HUGE_VAL; - } - } - - x[dist*i] = geodetic_loc.lam; - y[dist*i] = geodetic_loc.phi; - z[dist*i] = geodetic_loc.z; - - } - return 0; - } - - // Ugly hack. See https://github.com/OSGeo/PROJ/issues/1782 - if( P->right == PJ_IO_UNITS_WHATEVER && P->descr && - strncmp(P->descr, "General Oblique Transformation", - strlen("General Oblique Transformation")) == 0 ) - { - P->right = PJ_IO_UNITS_PROJECTED; - } - - /* Fallback to the original PROJ.4 API 2d inversion - inv */ - for( i = 0; i < n; i++ ) { - PJ_XY projected_loc; - PJ_LP geodetic_loc; - - projected_loc.x = x[dist*i]; - projected_loc.y = y[dist*i]; - - if( projected_loc.x == HUGE_VAL ) - continue; - - proj_errno_reset( P ); - geodetic_loc = pj_inv( projected_loc, P ); - if( P->ctx->last_errno != 0 ) - { - if( (P->ctx->last_errno != EDOM - && P->ctx->last_errno != ERANGE) - && (P->ctx->last_errno > 0 - || P->ctx->last_errno < -44 || n == 1 - || get_transient_error_value(-P->ctx->last_errno) == 0 ) ) - { - return P->ctx->last_errno; - } - else - { - geodetic_loc.lam = HUGE_VAL; - geodetic_loc.phi = HUGE_VAL; - } - } - - x[dist*i] = geodetic_loc.lam; - y[dist*i] = geodetic_loc.phi; - } - return 0; -} - - - -/* -------------------------------------------------------------------- */ -/* Adjust for the prime meridian if needed. */ -/* -------------------------------------------------------------------- */ -static int prime_meridian (PJ *P, PJ_DIRECTION dir, long n, int dist, double *x) { - int i; - double pm = P->from_greenwich; - - /* Nothing to do? */ - if (pm==0.0) - return 0; - if (!(P->is_geocent || P->is_latlong)) - return 0; - - if (dir==PJ_FWD) - pm = -pm; - - for (i = 0; i < n; i++) - if (x[dist*i] != HUGE_VAL) - x[dist*i] += pm; - - return 0; -} - - - -/* -------------------------------------------------------------------- */ -/* Adjust for vertical scale factor if needed */ -/* -------------------------------------------------------------------- */ -static int height_unit (PJ *P, PJ_DIRECTION dir, long n, int dist, double *z) { - int i; - double fac = P->vto_meter; - - if (PJ_FWD==dir) - fac = P->vfr_meter; - - /* Nothing to do? */ - if (fac==1.0) - return 0; - if (nullptr==z) - return 0; - if (P->is_latlong) - return 0; /* done in pj_inv3d() / pj_fwd3d() */ - - for (i = 0; i < n; i++) - if (z[dist*i] != HUGE_VAL ) - z[dist*i] *= fac; - - return 0; -} - - -/************************************************************************/ -/* pj_apply_vgridshift() */ -/* */ -/* This implementation takes uses the gridlist from a coordinate */ -/* system definition. If the gridlist has not yet been */ -/* populated in the coordinate system definition we set it up */ -/* now. */ -/************************************************************************/ -static int pj_apply_vgridshift( PJ *defn, - int inverse, - long point_count, int point_offset, - double *x, double *y, double *z ) - -{ - if( defn->vgrids_legacy == nullptr ) - { - defn->vgrids_legacy = new ListOfVGrids; - auto vgrids = pj_vgrid_init(defn, "geoidgrids"); - if( vgrids.empty() ) - return 0; - *static_cast(defn->vgrids_legacy) = std::move(vgrids); - } - if( static_cast(defn->vgrids_legacy)->empty() ) - { - return 0; - } - - for( int i = 0; i < point_count; i++ ) - { - double value; - long io = i * point_offset; - PJ_LP input; - - input.phi = y[io]; - input.lam = x[io]; - - value = pj_vgrid_value(defn, *static_cast(defn->vgrids_legacy), input, 1.0); - - if( inverse ) - z[io] -= value; - else - z[io] += value; - - if( value == HUGE_VAL ) - { - std::string gridlist; - - proj_log_debug(defn, - "pj_apply_vgridshift(): failed to find a grid shift table for\n" - " location (%.7fdW,%.7fdN)", - x[io] * RAD_TO_DEG, - y[io] * RAD_TO_DEG ); - - for( const auto& gridset: *static_cast(defn->vgrids_legacy) ) - { - if( gridlist.empty() ) - gridlist += " tried: "; - else - gridlist += ','; - gridlist += gridset->name(); - } - - proj_log_debug(defn, "%s", gridlist.c_str()); - pj_ctx_set_errno( defn->ctx, PJD_ERR_GRID_AREA ); - - return PJD_ERR_GRID_AREA; - } - } - - return 0; -} - - -/* -------------------------------------------------------------------- */ -/* Transform to ellipsoidal heights if needed */ -/* -------------------------------------------------------------------- */ -static int geometric_to_orthometric (PJ *P, PJ_DIRECTION dir, long n, int dist, double *x, double *y, double *z) { - int err; - if (0==P->has_geoid_vgrids) - return 0; - if (z==nullptr) - return PJD_ERR_GEOCENTRIC; - err = pj_apply_vgridshift (P, dir==PJ_FWD ? 1 : 0, n, dist, x, y, z ); - if (err) - return pj_ctx_get_errno(P->ctx); - return 0; -} - - - -/* -------------------------------------------------------------------- */ -/* Convert datums if needed, and possible. */ -/* -------------------------------------------------------------------- */ -static int datum_transform (PJ *P, PJ *Q, long n, int dist, double *x, double *y, double *z) { - if (0==pj_datum_transform (P, Q, n, dist, x, y, z)) - return 0; - if (P->ctx->last_errno) - return P->ctx->last_errno; - return Q->ctx->last_errno; -} - - - - - -/* -------------------------------------------------------------------- */ -/* If a wrapping center other than 0 is provided, rewrap around */ -/* the suggested center (for latlong coordinate systems only). */ -/* -------------------------------------------------------------------- */ -static int long_wrap (PJ *P, long n, int dist, double *x) { - long i; - - /* Nothing to do? */ - if (P->is_geocent) - return 0; - if (!P->is_long_wrap_set) - return 0; - if (!P->is_latlong) - return 0; - - for (i = 0; i < n; i++ ) { - double val = x[dist*i]; - if (val == HUGE_VAL) - continue; - - /* Get fast in ] -2 PI, 2 PI [ range */ - val = fmod(val, M_TWOPI); - while( val < P->long_wrap_center - M_PI ) - val += M_TWOPI; - while( val > P->long_wrap_center + M_PI ) - val -= M_TWOPI; - x[dist*i] = val; - } - return 0; -} - - - -/************************************************************************/ -/* pj_transform() */ -/* */ -/* Currently this function doesn't recognise if two projections */ -/* are identical (to short circuit reprojection) because it is */ -/* difficult to compare PJ structures (since there are some */ -/* projection specific components). */ -/************************************************************************/ - -int pj_transform( - PJ *src, PJ *dst, - long point_count, int point_offset, - double *x, double *y, double *z -){ - int err; - - src->ctx->last_errno = 0; - dst->ctx->last_errno = 0; - - if( point_offset == 0 ) - point_offset = 1; - - /* Bring input to "normal form": longitude, latitude, ellipsoidal height */ - - err = adjust_axes (src, PJ_INV, point_count, point_offset, x, y, z); - if (err) - return err; - err = geographic_to_cartesian (src, PJ_INV, point_count, point_offset, x, y, z); - if (err) - return err; - err = projected_to_geographic (src, point_count, point_offset, x, y, z); - if (err) - return err; - err = prime_meridian (src, PJ_INV, point_count, point_offset, x); - if (err) - return err; - err = height_unit (src, PJ_INV, point_count, point_offset, z); - if (err) - return err; - err = geometric_to_orthometric (src, PJ_INV, point_count, point_offset, x, y, z); - if (err) - return err; - - /* At the center of the process we do the datum shift (if needed) */ - - err = datum_transform(src, dst, point_count, point_offset, x, y, z ); - if (err) - return err; - - /* Now get out on the other side: Bring "normal form" to output form */ - - err = geometric_to_orthometric (dst, PJ_FWD, point_count, point_offset, x, y, z); - if (err) - return err; - err = height_unit (dst, PJ_FWD, point_count, point_offset, z); - if (err) - return err; - err = prime_meridian (dst, PJ_FWD, point_count, point_offset, x); - if (err) - return err; - err = geographic_to_cartesian (dst, PJ_FWD, point_count, point_offset, x, y, z); - if (err) - return err; - err = geographic_to_projected (dst, point_count, point_offset, x, y, z); - if (err) - return err; - err = long_wrap (dst, point_count, point_offset, x); - if (err) - return err; - err = adjust_axes (dst, PJ_FWD, point_count, point_offset, x, y, z); - if (err) - return err; - - return 0; -} - - - -/************************************************************************/ -/* pj_geodetic_to_geocentric() */ -/************************************************************************/ - -int pj_geodetic_to_geocentric( double a, double es, - long point_count, int point_offset, - double *x, double *y, double *z ) - -{ - double b; - int i; - GeocentricInfo gi; - int ret_errno = 0; - - if( es == 0.0 ) - b = a; - else - b = a * sqrt(1-es); - - if( pj_Set_Geocentric_Parameters( &gi, a, b ) != 0 ) - { - return PJD_ERR_GEOCENTRIC; - } - - for( i = 0; i < point_count; i++ ) - { - long io = i * point_offset; - - if( x[io] == HUGE_VAL ) - continue; - - if( pj_Convert_Geodetic_To_Geocentric( &gi, y[io], x[io], z[io], - x+io, y+io, z+io ) != 0 ) - { - ret_errno = PJD_ERR_LAT_OR_LON_EXCEED_LIMIT; - x[io] = y[io] = HUGE_VAL; - /* but keep processing points! */ - } - } - - return ret_errno; -} - -/************************************************************************/ -/* pj_geocentric_to_geodetic() */ -/************************************************************************/ - -int pj_geocentric_to_geodetic( double a, double es, - long point_count, int point_offset, - double *x, double *y, double *z ) - -{ - double b; - int i; - GeocentricInfo gi; - - if( es == 0.0 ) - b = a; - else - b = a * sqrt(1-es); - - if( pj_Set_Geocentric_Parameters( &gi, a, b ) != 0 ) - { - return PJD_ERR_GEOCENTRIC; - } - - for( i = 0; i < point_count; i++ ) - { - long io = i * point_offset; - - if( x[io] == HUGE_VAL ) - continue; - - pj_Convert_Geocentric_To_Geodetic( &gi, x[io], y[io], z[io], - y+io, x+io, z+io ); - } - - return 0; -} - -/************************************************************************/ -/* pj_compare_datums() */ -/* */ -/* Returns TRUE if the two datums are identical, otherwise */ -/* FALSE. */ -/************************************************************************/ - -int pj_compare_datums( PJ *srcdefn, PJ *dstdefn ) - -{ - if( srcdefn->datum_type != dstdefn->datum_type ) - { - return 0; - } - else if( srcdefn->a_orig != dstdefn->a_orig - || ABS(srcdefn->es_orig - dstdefn->es_orig) > 0.000000000050 ) - { - /* the tolerance for es is to ensure that GRS80 and WGS84 are - considered identical */ - return 0; - } - else if( srcdefn->datum_type == PJD_3PARAM ) - { - return (srcdefn->datum_params[0] == dstdefn->datum_params[0] - && srcdefn->datum_params[1] == dstdefn->datum_params[1] - && srcdefn->datum_params[2] == dstdefn->datum_params[2]); - } - else if( srcdefn->datum_type == PJD_7PARAM ) - { - return (srcdefn->datum_params[0] == dstdefn->datum_params[0] - && srcdefn->datum_params[1] == dstdefn->datum_params[1] - && srcdefn->datum_params[2] == dstdefn->datum_params[2] - && srcdefn->datum_params[3] == dstdefn->datum_params[3] - && srcdefn->datum_params[4] == dstdefn->datum_params[4] - && srcdefn->datum_params[5] == dstdefn->datum_params[5] - && srcdefn->datum_params[6] == dstdefn->datum_params[6]); - } - else if( srcdefn->datum_type == PJD_GRIDSHIFT ) - { - const char* srcnadgrids = - pj_param(srcdefn->ctx, srcdefn->params,"snadgrids").s; - const char* dstnadgrids = - pj_param(dstdefn->ctx, dstdefn->params,"snadgrids").s; - return srcnadgrids != nullptr && dstnadgrids != nullptr && - strcmp( srcnadgrids, dstnadgrids ) == 0; - } - else - return 1; -} - -/************************************************************************/ -/* pj_geocentic_to_wgs84() */ -/************************************************************************/ - -static -int pj_geocentric_to_wgs84( PJ *defn, - long point_count, int point_offset, - double *x, double *y, double *z ) - -{ - int i; - - if( defn->datum_type == PJD_3PARAM ) - { - for( i = 0; i < point_count; i++ ) - { - long io = i * point_offset; - - if( x[io] == HUGE_VAL ) - continue; - - x[io] = x[io] + Dx_BF; - y[io] = y[io] + Dy_BF; - z[io] = z[io] + Dz_BF; - } - } - else if( defn->datum_type == PJD_7PARAM ) - { - for( i = 0; i < point_count; i++ ) - { - long io = i * point_offset; - double x_out, y_out, z_out; - - if( x[io] == HUGE_VAL ) - continue; - - x_out = M_BF*( x[io] - Rz_BF*y[io] + Ry_BF*z[io]) + Dx_BF; - y_out = M_BF*( Rz_BF*x[io] + y[io] - Rx_BF*z[io]) + Dy_BF; - z_out = M_BF*(-Ry_BF*x[io] + Rx_BF*y[io] + z[io]) + Dz_BF; - - x[io] = x_out; - y[io] = y_out; - z[io] = z_out; - } - } - - return 0; -} - -/************************************************************************/ -/* pj_geocentic_from_wgs84() */ -/************************************************************************/ - -static -int pj_geocentric_from_wgs84( PJ *defn, - long point_count, int point_offset, - double *x, double *y, double *z ) - -{ - int i; - - if( defn->datum_type == PJD_3PARAM ) - { - for( i = 0; i < point_count; i++ ) - { - long io = i * point_offset; - - if( x[io] == HUGE_VAL ) - continue; - - x[io] = x[io] - Dx_BF; - y[io] = y[io] - Dy_BF; - z[io] = z[io] - Dz_BF; - } - } - else if( defn->datum_type == PJD_7PARAM ) - { - for( i = 0; i < point_count; i++ ) - { - long io = i * point_offset; - double x_tmp, y_tmp, z_tmp; - - if( x[io] == HUGE_VAL ) - continue; - - x_tmp = (x[io] - Dx_BF) / M_BF; - y_tmp = (y[io] - Dy_BF) / M_BF; - z_tmp = (z[io] - Dz_BF) / M_BF; - - x[io] = x_tmp + Rz_BF*y_tmp - Ry_BF*z_tmp; - y[io] = -Rz_BF*x_tmp + y_tmp + Rx_BF*z_tmp; - z[io] = Ry_BF*x_tmp - Rx_BF*y_tmp + z_tmp; - } - } - - return 0; -} - - -/************************************************************************/ -/* pj_apply_gridshift_2() */ -/* */ -/* This implementation uses the gridlist from a coordinate */ -/* system definition. If the gridlist has not yet been */ -/* populated in the coordinate system definition we set it up */ -/* now. */ -/************************************************************************/ -static -int pj_apply_gridshift_2( PJ *defn, int inverse, - long point_count, int point_offset, - double *x, double *y, double * /*z*/ ) - -{ - if( defn->hgrids_legacy == nullptr ) - { - defn->hgrids_legacy = new ListOfHGrids; - auto hgrids = pj_hgrid_init(defn, "nadgrids"); - if( hgrids.empty() ) - return 0; - *static_cast(defn->hgrids_legacy) = std::move(hgrids); - } - if( static_cast(defn->hgrids_legacy)->empty() ) - { - return 0; - } - - for( long i = 0; i < point_count; i++ ) - { - PJ_LP input; - - long io = i * point_offset; - input.phi = y[io]; - input.lam = x[io]; - - auto output = pj_hgrid_apply(defn->ctx, *static_cast(defn->hgrids_legacy), input, inverse ? PJ_INV : PJ_FWD); - - if ( output.lam != HUGE_VAL ) - { - y[io] = output.phi; - x[io] = output.lam; - } - else - { - if( defn->ctx->debug_level >= PJ_LOG_DEBUG_MAJOR ) - { - pj_log( defn->ctx, PJ_LOG_DEBUG_MAJOR, - "pj_apply_gridshift(): failed to find a grid shift table for\n" - " location (%.7fdW,%.7fdN)", - x[io] * RAD_TO_DEG, - y[io] * RAD_TO_DEG ); - } - } - } - - return 0; -} - - -/************************************************************************/ -/* pj_datum_transform() */ -/* */ -/* The input should be long/lat/z coordinates in radians in the */ -/* source datum, and the output should be long/lat/z */ -/* coordinates in radians in the destination datum. */ -/************************************************************************/ - -int pj_datum_transform( PJ *src, PJ *dst, - long point_count, int point_offset, - double *x, double *y, double *z ) - -{ - double src_a, src_es, dst_a, dst_es; - int z_is_temp = FALSE; - -/* -------------------------------------------------------------------- */ -/* We cannot do any meaningful datum transformation if either */ -/* the source or destination are of an unknown datum type */ -/* (ie. only a +ellps declaration, no +datum). This is new */ -/* behavior for PROJ 4.6.0. */ -/* -------------------------------------------------------------------- */ - if( src->datum_type == PJD_UNKNOWN - || dst->datum_type == PJD_UNKNOWN ) - return 0; - -/* -------------------------------------------------------------------- */ -/* Short cut if the datums are identical. */ -/* -------------------------------------------------------------------- */ - if( pj_compare_datums( src, dst ) ) - return 0; - - src_a = src->a_orig; - src_es = src->es_orig; - - dst_a = dst->a_orig; - dst_es = dst->es_orig; - -/* -------------------------------------------------------------------- */ -/* Create a temporary Z array if one is not provided. */ -/* -------------------------------------------------------------------- */ - if( z == nullptr ) - { - size_t bytes = sizeof(double) * point_count * point_offset; - z = (double *) pj_malloc(bytes); - memset( z, 0, bytes ); - z_is_temp = TRUE; - } - -#define CHECK_RETURN(defn) {if( defn->ctx->last_errno != 0 && (defn->ctx->last_errno > 0 || get_transient_error_value(-defn->ctx->last_errno) == 0) ) { if( z_is_temp ) pj_dalloc(z); return defn->ctx->last_errno; }} - -/* -------------------------------------------------------------------- */ -/* If this datum requires grid shifts, then apply it to geodetic */ -/* coordinates. */ -/* -------------------------------------------------------------------- */ - if( src->datum_type == PJD_GRIDSHIFT ) - { - pj_apply_gridshift_2( src, 0, point_count, point_offset, x, y, z ); - CHECK_RETURN(src); - - src_a = SRS_WGS84_SEMIMAJOR; - src_es = SRS_WGS84_ESQUARED; - } - - if( dst->datum_type == PJD_GRIDSHIFT ) - { - dst_a = SRS_WGS84_SEMIMAJOR; - dst_es = SRS_WGS84_ESQUARED; - } - -/* ==================================================================== */ -/* Do we need to go through geocentric coordinates? */ -/* ==================================================================== */ - if( src_es != dst_es || src_a != dst_a - || src->datum_type == PJD_3PARAM - || src->datum_type == PJD_7PARAM - || dst->datum_type == PJD_3PARAM - || dst->datum_type == PJD_7PARAM) - { -/* -------------------------------------------------------------------- */ -/* Convert to geocentric coordinates. */ -/* -------------------------------------------------------------------- */ - src->ctx->last_errno = - pj_geodetic_to_geocentric( src_a, src_es, - point_count, point_offset, x, y, z ); - CHECK_RETURN(src); - -/* -------------------------------------------------------------------- */ -/* Convert between datums. */ -/* -------------------------------------------------------------------- */ - if( src->datum_type == PJD_3PARAM - || src->datum_type == PJD_7PARAM ) - { - pj_geocentric_to_wgs84( src, point_count, point_offset,x,y,z); - CHECK_RETURN(src); - } - - if( dst->datum_type == PJD_3PARAM - || dst->datum_type == PJD_7PARAM ) - { - pj_geocentric_from_wgs84( dst, point_count,point_offset,x,y,z); - CHECK_RETURN(dst); - } - -/* -------------------------------------------------------------------- */ -/* Convert back to geodetic coordinates. */ -/* -------------------------------------------------------------------- */ - dst->ctx->last_errno = - pj_geocentric_to_geodetic( dst_a, dst_es, - point_count, point_offset, x, y, z ); - CHECK_RETURN(dst); - } - -/* -------------------------------------------------------------------- */ -/* Apply grid shift to destination if required. */ -/* -------------------------------------------------------------------- */ - if( dst->datum_type == PJD_GRIDSHIFT ) - { - pj_apply_gridshift_2( dst, 1, point_count, point_offset, x, y, z ); - CHECK_RETURN(dst); - } - - if( z_is_temp ) - pj_dalloc( z ); - - return 0; -} - -/************************************************************************/ -/* adjust_axis() */ -/* */ -/* Normalize or de-normalized the x/y/z axes. The normal form */ -/* is "enu" (easting, northing, up). */ -/************************************************************************/ -static int adjust_axis( projCtx ctx, - const char *axis, int denormalize_flag, - long point_count, int point_offset, - double *x, double *y, double *z ) - -{ - double x_in, y_in, z_in = 0.0; - int i, i_axis; - - if( !denormalize_flag ) - { - for( i = 0; i < point_count; i++ ) - { - x_in = x[point_offset*i]; - y_in = y[point_offset*i]; - if( z ) - z_in = z[point_offset*i]; - - for( i_axis = 0; i_axis < 3; i_axis++ ) - { - double value; - - if( i_axis == 0 ) - value = x_in; - else if( i_axis == 1 ) - value = y_in; - else - value = z_in; - - switch( axis[i_axis] ) - { - case 'e': - x[point_offset*i] = value; - break; - case 'w': - x[point_offset*i] = -value; - break; - case 'n': - y[point_offset*i] = value; - break; - case 's': - y[point_offset*i] = -value; - break; - case 'u': - if( z ) - z[point_offset*i] = value; - break; - case 'd': - if( z ) - z[point_offset*i] = -value; - break; - default: - pj_ctx_set_errno( ctx, PJD_ERR_AXIS ); - return PJD_ERR_AXIS; - } - } /* i_axis */ - } /* i (point) */ - } - - else /* denormalize */ - { - for( i = 0; i < point_count; i++ ) - { - x_in = x[point_offset*i]; - y_in = y[point_offset*i]; - if( z ) - z_in = z[point_offset*i]; - - for( i_axis = 0; i_axis < 3; i_axis++ ) - { - double *target; - - if( i_axis == 2 && z == nullptr ) - continue; - - if( i_axis == 0 ) - target = x; - else if( i_axis == 1 ) - target = y; - else - target = z; - - switch( axis[i_axis] ) - { - case 'e': - target[point_offset*i] = x_in; break; - case 'w': - target[point_offset*i] = -x_in; break; - case 'n': - target[point_offset*i] = y_in; break; - case 's': - target[point_offset*i] = -y_in; break; - case 'u': - target[point_offset*i] = z_in; break; - case 'd': - target[point_offset*i] = -z_in; break; - default: - pj_ctx_set_errno( ctx, PJD_ERR_AXIS ); - return PJD_ERR_AXIS; - } - } /* i_axis */ - } /* i (point) */ - } - - return 0; -} -// --------------------------------------------------------------------------- - -void pj_deallocate_grids() -{ -} -- cgit v1.2.3 From aa46197d66ce70ece382bf955326c46b13f35864 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Sat, 14 Nov 2020 22:55:31 +0100 Subject: Weed out proj_api.h datatypes and replace them with their proj.h counterparts --- src/aasincos.cpp | 4 +- src/ctx.cpp | 55 ++++++++------- src/datum_set.cpp | 2 +- src/dmstor.cpp | 2 +- src/ell_set.cpp | 2 +- src/fileapi.cpp | 22 +++--- src/filemanager.cpp | 16 ++--- src/gauss.cpp | 4 +- src/grids.cpp | 4 +- src/init.cpp | 6 +- src/internal.cpp | 2 +- src/iso19111/datum.cpp | 2 +- src/log.cpp | 6 +- src/mlfn.cpp | 2 +- src/mlfn.hpp | 2 +- src/param.cpp | 2 +- src/phi2.cpp | 4 +- src/proj.h | 6 +- src/proj_internal.h | 155 +++++++++++++++++------------------------- src/proj_mdist.cpp | 2 +- src/projections/chamb.cpp | 4 +- src/tests/multistresstest.cpp | 14 ++-- src/tests/test228.cpp | 6 +- src/utils.cpp | 2 +- 24 files changed, 150 insertions(+), 176 deletions(-) (limited to 'src') diff --git a/src/aasincos.cpp b/src/aasincos.cpp index 398a8cfc..c3229d39 100644 --- a/src/aasincos.cpp +++ b/src/aasincos.cpp @@ -9,7 +9,7 @@ #define ATOL 1e-50 double -aasin(projCtx ctx,double v) { +aasin(PJ_CONTEXT *ctx,double v) { double av; if ((av = fabs(v)) >= 1.) { @@ -21,7 +21,7 @@ aasin(projCtx ctx,double v) { } double -aacos(projCtx ctx, double v) { +aacos(PJ_CONTEXT *ctx, double v) { double av; if ((av = fabs(v)) >= 1.) { diff --git a/src/ctx.cpp b/src/ctx.cpp index 6dbe0de5..24d3773b 100644 --- a/src/ctx.cpp +++ b/src/ctx.cpp @@ -1,6 +1,6 @@ /****************************************************************************** * Project: PROJ.4 - * Purpose: Implementation of the projCtx thread context object. + * Purpose: Implementation of the PJ_CONTEXT thread context object. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** @@ -43,7 +43,7 @@ /* pj_get_ctx() */ /************************************************************************/ -projCtx pj_get_ctx( projPJ pj ) +PJ_CONTEXT* pj_get_ctx( PJ *pj ) { if (nullptr==pj) @@ -59,7 +59,7 @@ projCtx pj_get_ctx( projPJ pj ) /* Note we do not deallocate the old context! */ /************************************************************************/ -void pj_set_ctx( projPJ pj, projCtx ctx ) +void pj_set_ctx( PJ *pj, PJ_CONTEXT *ctx ) { if (pj==nullptr) @@ -86,7 +86,7 @@ void pj_set_ctx( projPJ pj, projCtx ctx ) * the user may want to assign another thread-specific context to the * object. */ -void proj_assign_context( PJ* pj, PJ_CONTEXT* ctx ) +void proj_assign_context( PJ* pj, PJ_CONTEXT *ctx ) { pj_set_ctx( pj, ctx ); } @@ -95,9 +95,9 @@ void proj_assign_context( PJ* pj, PJ_CONTEXT* ctx ) /* createDefault() */ /************************************************************************/ -projCtx_t projCtx_t::createDefault() +pj_ctx pj_ctx::createDefault() { - projCtx_t ctx; + pj_ctx ctx; ctx.debug_level = PJ_LOG_NONE; ctx.logger = pj_stderr_logger; ctx.fileapi_legacy = pj_get_default_fileapi(); @@ -117,7 +117,7 @@ projCtx_t projCtx_t::createDefault() /* get_cpp_context() */ /**************************************************************************/ -projCppContext* projCtx_t::get_cpp_context() +projCppContext* pj_ctx::get_cpp_context() { if (cpp_context == nullptr) { cpp_context = new projCppContext(this); @@ -125,12 +125,11 @@ projCppContext* projCtx_t::get_cpp_context() return cpp_context; } - /**************************************************************************/ /* safeAutoCloseDbIfNeeded() */ /**************************************************************************/ -void projCtx_t::safeAutoCloseDbIfNeeded() +void pj_ctx::safeAutoCloseDbIfNeeded() { if (cpp_context) { cpp_context->autoCloseDbIfNeeded(); @@ -141,7 +140,7 @@ void projCtx_t::safeAutoCloseDbIfNeeded() /* set_search_paths() */ /************************************************************************/ -void projCtx_t::set_search_paths(const std::vector& search_paths_in ) +void pj_ctx::set_search_paths(const std::vector& search_paths_in ) { search_paths = search_paths_in; delete[] c_compat_paths; @@ -158,16 +157,16 @@ void projCtx_t::set_search_paths(const std::vector& search_paths_in /* set_ca_bundle_path() */ /**************************************************************************/ -void projCtx_t::set_ca_bundle_path(const std::string& ca_bundle_path_in) +void pj_ctx::set_ca_bundle_path(const std::string& ca_bundle_path_in) { ca_bundle_path = ca_bundle_path_in; } /************************************************************************/ -/* projCtx_t(const projCtx_t& other) */ +/* pj_ctx(const pj_ctx& other) */ /************************************************************************/ -projCtx_t::projCtx_t(const projCtx_t& other) : +pj_ctx::pj_ctx(const pj_ctx& other) : debug_level(other.debug_level), logger(other.logger), logger_app_data(other.logger_app_data), @@ -197,19 +196,19 @@ projCtx_t::projCtx_t(const projCtx_t& other) : /* pj_get_default_ctx() */ /************************************************************************/ -projCtx pj_get_default_ctx() +PJ_CONTEXT* pj_get_default_ctx() { // C++11 rules guarantee a thread-safe instantiation. - static projCtx_t default_context(projCtx_t::createDefault()); + static pj_ctx default_context(pj_ctx::createDefault()); return &default_context; } /************************************************************************/ -/* ~projCtx_t() */ +/* ~pj_ctx() */ /************************************************************************/ -projCtx_t::~projCtx_t() +pj_ctx::~pj_ctx() { delete[] c_compat_paths; proj_context_delete_cpp_context(cpp_context); @@ -219,10 +218,10 @@ projCtx_t::~projCtx_t() /* pj_ctx_alloc() */ /************************************************************************/ -projCtx pj_ctx_alloc() +PJ_CONTEXT* pj_ctx_alloc() { - return new (std::nothrow) projCtx_t(*pj_get_default_ctx()); + return new (std::nothrow) pj_ctx(*pj_get_default_ctx()); } /************************************************************************/ @@ -230,19 +229,19 @@ projCtx pj_ctx_alloc() /* Create a new context based on a custom context */ /************************************************************************/ -PJ_CONTEXT *proj_context_clone (PJ_CONTEXT *ctx) +PJ_CONTEXT* proj_context_clone (PJ_CONTEXT *ctx) { if (nullptr==ctx) return pj_ctx_alloc (); - return new (std::nothrow) projCtx_t(*ctx); + return new (std::nothrow) pj_ctx(*ctx); } /************************************************************************/ /* pj_ctx_free() */ /************************************************************************/ -void pj_ctx_free( projCtx ctx ) +void pj_ctx_free( PJ_CONTEXT *ctx ) { delete ctx; @@ -252,7 +251,7 @@ void pj_ctx_free( projCtx ctx ) /* pj_ctx_get_errno() */ /************************************************************************/ -int pj_ctx_get_errno( projCtx ctx ) +int pj_ctx_get_errno( PJ_CONTEXT *ctx ) { if (nullptr==ctx) @@ -266,7 +265,7 @@ int pj_ctx_get_errno( projCtx ctx ) /* Also sets the global errno */ /************************************************************************/ -void pj_ctx_set_errno( projCtx ctx, int new_errno ) +void pj_ctx_set_errno( PJ_CONTEXT *ctx, int new_errno ) { ctx->last_errno = new_errno; @@ -280,7 +279,7 @@ void pj_ctx_set_errno( projCtx ctx, int new_errno ) /* pj_ctx_set_debug() */ /************************************************************************/ -void pj_ctx_set_debug( projCtx ctx, int new_debug ) +void pj_ctx_set_debug( PJ_CONTEXT *ctx, int new_debug ) { if (nullptr==ctx) @@ -292,7 +291,7 @@ void pj_ctx_set_debug( projCtx ctx, int new_debug ) /* pj_ctx_set_logger() */ /************************************************************************/ -void pj_ctx_set_logger( projCtx ctx, void (*new_logger)(void*,int,const char*) ) +void pj_ctx_set_logger( PJ_CONTEXT *ctx, void (*new_logger)(void*,int,const char*) ) { if (nullptr==ctx) @@ -304,7 +303,7 @@ void pj_ctx_set_logger( projCtx ctx, void (*new_logger)(void*,int,const char*) ) /* pj_ctx_set_app_data() */ /************************************************************************/ -void pj_ctx_set_app_data( projCtx ctx, void *new_app_data ) +void pj_ctx_set_app_data( PJ_CONTEXT *ctx, void *new_app_data ) { if (nullptr==ctx) @@ -316,7 +315,7 @@ void pj_ctx_set_app_data( projCtx ctx, void *new_app_data ) /* pj_ctx_get_app_data() */ /************************************************************************/ -void *pj_ctx_get_app_data( projCtx ctx ) +void *pj_ctx_get_app_data( PJ_CONTEXT *ctx ) { if (nullptr==ctx) diff --git a/src/datum_set.cpp b/src/datum_set.cpp index 15d51613..cc6f3dbe 100644 --- a/src/datum_set.cpp +++ b/src/datum_set.cpp @@ -38,7 +38,7 @@ /* pj_datum_set() */ /************************************************************************/ -int pj_datum_set(projCtx ctx, paralist *pl, PJ *projdef) +int pj_datum_set(PJ_CONTEXT *ctx, paralist *pl, PJ *projdef) { const char *name, *towgs84, *nadgrids; diff --git a/src/dmstor.cpp b/src/dmstor.cpp index 3ba66030..e72d9930 100644 --- a/src/dmstor.cpp +++ b/src/dmstor.cpp @@ -26,7 +26,7 @@ dmstor(const char *is, char **rs) { } double -dmstor_ctx(projCtx ctx, const char *is, char **rs) { +dmstor_ctx(PJ_CONTEXT *ctx, const char *is, char **rs) { int sign, n, nl; char *s, work[MAX_WORK]; const char* p; diff --git a/src/ell_set.cpp b/src/ell_set.cpp index ddd507ac..ec3e03eb 100644 --- a/src/ell_set.cpp +++ b/src/ell_set.cpp @@ -609,7 +609,7 @@ int pj_ell_set (PJ_CONTEXT *ctx, paralist *pl, double *a, double *es) { /**************************************************************************************/ -int pj_ell_set (projCtx ctx, paralist *pl, double *a, double *es) { +int pj_ell_set (PJ_CONTEXT *ctx, paralist *pl, double *a, double *es) { /*************************************************************************************** Initialize ellipsoidal parameters: This is the original ellipsoid setup function by Gerald Evenden - significantly more compact than pj_ellipsoid and diff --git a/src/fileapi.cpp b/src/fileapi.cpp index 70be2502..0af83926 100644 --- a/src/fileapi.cpp +++ b/src/fileapi.cpp @@ -36,7 +36,7 @@ #include "proj_internal.h" #include "filemanager.hpp" -static PAFile stdio_fopen(projCtx ctx, const char *filename, +static PAFile stdio_fopen(PJ_CONTEXT *ctx, const char *filename, const char *access); static size_t stdio_fread(void *buffer, size_t size, size_t nmemb, PAFile file); @@ -53,7 +53,7 @@ static projFileAPI default_fileapi = { }; typedef struct { - projCtx ctx; + PJ_CONTEXT *ctx; FILE *fp; } stdio_pafile; @@ -70,7 +70,7 @@ projFileAPI *pj_get_default_fileapi(void) /* stdio_fopen() */ /************************************************************************/ -static PAFile stdio_fopen(projCtx ctx, const char *filename, +static PAFile stdio_fopen(PJ_CONTEXT *ctx, const char *filename, const char *access) { stdio_pafile *pafile; @@ -140,7 +140,7 @@ static void stdio_fclose(PAFile file) /* Open a file using the provided file io hooks. */ /************************************************************************/ -PAFile pj_ctx_fopen(projCtx ctx, const char *filename, const char *access) +PAFile pj_ctx_fopen(PJ_CONTEXT *ctx, const char *filename, const char *access) { return ctx->fileapi_legacy->FOpen(ctx, filename, access); } @@ -148,7 +148,7 @@ PAFile pj_ctx_fopen(projCtx ctx, const char *filename, const char *access) /************************************************************************/ /* pj_ctx_fread() */ /************************************************************************/ -size_t pj_ctx_fread(projCtx ctx, void *buffer, size_t size, size_t nmemb, PAFile file) +size_t pj_ctx_fread(PJ_CONTEXT *ctx, void *buffer, size_t size, size_t nmemb, PAFile file) { return ctx->fileapi_legacy->FRead(buffer, size, nmemb, file); } @@ -156,7 +156,7 @@ size_t pj_ctx_fread(projCtx ctx, void *buffer, size_t size, size_t nmemb, PAFile /************************************************************************/ /* pj_ctx_fseek() */ /************************************************************************/ -int pj_ctx_fseek(projCtx ctx, PAFile file, long offset, int whence) +int pj_ctx_fseek(PJ_CONTEXT *ctx, PAFile file, long offset, int whence) { return ctx->fileapi_legacy->FSeek(file, offset, whence); } @@ -164,7 +164,7 @@ int pj_ctx_fseek(projCtx ctx, PAFile file, long offset, int whence) /************************************************************************/ /* pj_ctx_ftell() */ /************************************************************************/ -long pj_ctx_ftell(projCtx ctx, PAFile file) +long pj_ctx_ftell(PJ_CONTEXT *ctx, PAFile file) { return ctx->fileapi_legacy->FTell(file); } @@ -172,7 +172,7 @@ long pj_ctx_ftell(projCtx ctx, PAFile file) /************************************************************************/ /* pj_ctx_fclose() */ /************************************************************************/ -void pj_ctx_fclose(projCtx ctx, PAFile file) +void pj_ctx_fclose(PJ_CONTEXT *ctx, PAFile file) { ctx->fileapi_legacy->FClose(file); } @@ -185,7 +185,7 @@ void pj_ctx_fclose(projCtx ctx, PAFile file) /* taken. */ /************************************************************************/ -char *pj_ctx_fgets(projCtx ctx, char *line, int size, PAFile file) +char *pj_ctx_fgets(PJ_CONTEXT *ctx, char *line, int size, PAFile file) { long start = pj_ctx_ftell(ctx, file); size_t bytes_read; @@ -218,7 +218,7 @@ char *pj_ctx_fgets(projCtx ctx, char *line, int size, PAFile file) /* pj_ctx_set_fileapi() */ /************************************************************************/ -void pj_ctx_set_fileapi( projCtx ctx, projFileAPI *fileapi ) +void pj_ctx_set_fileapi( PJ_CONTEXT *ctx, projFileAPI *fileapi ) { if (nullptr==ctx) @@ -230,7 +230,7 @@ void pj_ctx_set_fileapi( projCtx ctx, projFileAPI *fileapi ) /* pj_ctx_get_fileapi() */ /************************************************************************/ -projFileAPI *pj_ctx_get_fileapi( projCtx ctx ) +projFileAPI *pj_ctx_get_fileapi( PJ_CONTEXT *ctx ) { if (nullptr==ctx) diff --git a/src/filemanager.cpp b/src/filemanager.cpp index e6a9ed95..37dc920e 100644 --- a/src/filemanager.cpp +++ b/src/filemanager.cpp @@ -1445,8 +1445,8 @@ static bool dontReadUserWritableDirectory() { } static void * -pj_open_lib_internal(projCtx ctx, const char *name, const char *mode, - void *(*open_file)(projCtx, const char *, const char *), +pj_open_lib_internal(PJ_CONTEXT *ctx, const char *name, const char *mode, + void *(*open_file)(PJ_CONTEXT *, const char *, const char *), char *out_full_filename, size_t out_full_filename_size) { try { std::string fname; @@ -1617,7 +1617,7 @@ std::vector pj_get_default_searchpaths(PJ_CONTEXT *ctx) { /* pj_open_file_with_manager() */ /************************************************************************/ -static void *pj_open_file_with_manager(projCtx ctx, const char *name, +static void *pj_open_file_with_manager(PJ_CONTEXT *ctx, const char *name, const char * /* mode */) { return NS_PROJ::FileManager::open(ctx, name, NS_PROJ::FileAccess::READ_ONLY) .release(); @@ -1639,7 +1639,7 @@ static NS_PROJ::io::DatabaseContextPtr getDBcontext(PJ_CONTEXT *ctx) { /************************************************************************/ std::unique_ptr -NS_PROJ::FileManager::open_resource_file(projCtx ctx, const char *name) { +NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name) { if (ctx == nullptr) { ctx = pj_get_default_ctx(); @@ -1735,13 +1735,13 @@ NS_PROJ::FileManager::open_resource_file(projCtx ctx, const char *name) { #ifndef REMOVE_LEGACY_SUPPORT // Used by following legacy function -static void *pj_ctx_fopen_adapter(projCtx ctx, const char *name, +static void *pj_ctx_fopen_adapter(PJ_CONTEXT *ctx, const char *name, const char *mode) { return pj_ctx_fopen(ctx, name, mode); } // Legacy function -PAFile pj_open_lib(projCtx ctx, const char *name, const char *mode) { +PAFile pj_open_lib(PJ_CONTEXT *ctx, const char *name, const char *mode) { return (PAFile)pj_open_lib_internal(ctx, name, mode, pj_ctx_fopen_adapter, nullptr, 0); } @@ -1764,7 +1764,7 @@ PAFile pj_open_lib(projCtx ctx, const char *name, const char *mode) { * @param out_full_filename_size size of out_full_filename. * @return 1 if the file was found, 0 otherwise. */ -int pj_find_file(projCtx ctx, const char *short_filename, +int pj_find_file(PJ_CONTEXT *ctx, const char *short_filename, char *out_full_filename, size_t out_full_filename_size) { auto file = std::unique_ptr( reinterpret_cast(pj_open_lib_internal( @@ -1812,7 +1812,7 @@ static std::string trim(const std::string &s) { /* pj_load_ini() */ /************************************************************************/ -void pj_load_ini(projCtx ctx) { +void pj_load_ini(PJ_CONTEXT *ctx) { if (ctx->iniFileLoaded) return; diff --git a/src/gauss.cpp b/src/gauss.cpp index a34a8f5b..54dff5a8 100644 --- a/src/gauss.cpp +++ b/src/gauss.cpp @@ -81,7 +81,7 @@ void *pj_gauss_ini(double e, double phi0, double *chi, double *rc) { return ((void *)en); } -PJ_LP pj_gauss(projCtx ctx, PJ_LP elp, const void *data) { +PJ_LP pj_gauss(PJ_CONTEXT *ctx, PJ_LP elp, const void *data) { const struct GAUSS *en = (const struct GAUSS *)data; PJ_LP slp; (void) ctx; @@ -93,7 +93,7 @@ PJ_LP pj_gauss(projCtx ctx, PJ_LP elp, const void *data) { return(slp); } -PJ_LP pj_inv_gauss(projCtx ctx, PJ_LP slp, const void *data) { +PJ_LP pj_inv_gauss(PJ_CONTEXT *ctx, PJ_LP slp, const void *data) { const struct GAUSS *en = (const struct GAUSS *)data; PJ_LP elp; double num; diff --git a/src/grids.cpp b/src/grids.cpp index 8065813a..8c1bc4cc 100644 --- a/src/grids.cpp +++ b/src/grids.cpp @@ -2948,7 +2948,7 @@ static PJ_LP pj_hgrid_interpolate(PJ_LP t, const HorizontalShiftGrid *grid, #define MAX_ITERATIONS 10 #define TOL 1e-12 -static PJ_LP pj_hgrid_apply_internal(projCtx ctx, PJ_LP in, +static PJ_LP pj_hgrid_apply_internal(PJ_CONTEXT *ctx, PJ_LP in, PJ_DIRECTION direction, const HorizontalShiftGrid *grid, HorizontalShiftGridSet *gridset, @@ -3452,7 +3452,7 @@ NS_PROJ_END /* it to honour our public api. */ /************************************************************************/ -int pj_apply_gridshift(projCtx ctx, const char *nadgrids, int inverse, +int pj_apply_gridshift(PJ_CONTEXT *ctx, const char *nadgrids, int inverse, long point_count, int point_offset, double *x, double *y, double * /*z */) diff --git a/src/init.cpp b/src/init.cpp index 101fc8ad..a42bf963 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -415,7 +415,7 @@ pj_init_plus( const char *definition ) } PJ * -pj_init_plus_ctx( projCtx ctx, const char *definition ) +pj_init_plus_ctx( PJ_CONTEXT *ctx, const char *definition ) { #define MAX_ARG 200 char *argv[MAX_ARG]; @@ -511,7 +511,7 @@ static PJ_CONSTRUCTOR locate_constructor (const char *name) { PJ * -pj_init_ctx(projCtx ctx, int argc, char **argv) { +pj_init_ctx(PJ_CONTEXT *ctx, int argc, char **argv) { /* Legacy interface: allow init=epsg:XXXX syntax by default */ int allow_init_epsg = proj_context_get_use_proj4_init_rules(ctx, TRUE); return pj_init_ctx_with_allow_init_epsg(ctx, argc, argv, allow_init_epsg); @@ -519,7 +519,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { PJ * -pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_init_epsg) { +pj_init_ctx_with_allow_init_epsg(PJ_CONTEXT *ctx, int argc, char **argv, int allow_init_epsg) { const char *s; char *name; PJ_CONSTRUCTOR proj; diff --git a/src/internal.cpp b/src/internal.cpp index 91994077..32dc1bba 100644 --- a/src/internal.cpp +++ b/src/internal.cpp @@ -417,7 +417,7 @@ to that context. /* logging */ /* pj_vlog resides in pj_log.c and relates to pj_log as vsprintf relates to sprintf */ -void pj_vlog( projCtx ctx, int level, const char *fmt, va_list args ); +void pj_vlog( PJ_CONTEXT *ctx, int level, const char *fmt, va_list args ); /***************************************************************************************/ diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 28dbc462..4d7e78d3 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -417,7 +417,7 @@ std::string PrimeMeridian::getPROJStringWellKnownName(const common::Angle &angle) { const double valRad = angle.getSIValue(); std::string projPMName; - projCtx ctxt = pj_ctx_alloc(); + PJ_CONTEXT *ctxt = pj_ctx_alloc(); auto proj_pm = proj_list_prime_meridians(); for (int i = 0; proj_pm[i].id != nullptr; ++i) { double valRefRad = dmstor_ctx(ctxt, proj_pm[i].defn, nullptr); diff --git a/src/log.cpp b/src/log.cpp index 3cc10cfd..c343e65b 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -48,9 +48,9 @@ void pj_stderr_logger( void *app_data, int level, const char *msg ) /************************************************************************/ /* pj_vlog() */ /************************************************************************/ -void pj_vlog( projCtx ctx, int level, const char *fmt, va_list args ); +void pj_vlog( PJ_CONTEXT *ctx, int level, const char *fmt, va_list args ); /* Workhorse for the log functions - relates to pj_log as vsprintf relates to sprintf */ -void pj_vlog( projCtx ctx, int level, const char *fmt, va_list args ) +void pj_vlog( PJ_CONTEXT *ctx, int level, const char *fmt, va_list args ) { char *msg_buf; @@ -84,7 +84,7 @@ void pj_vlog( projCtx ctx, int level, const char *fmt, va_list args ) /* pj_log() */ /************************************************************************/ -void pj_log( projCtx ctx, int level, const char *fmt, ... ) +void pj_log( PJ_CONTEXT *ctx, int level, const char *fmt, ... ) { va_list args; diff --git a/src/mlfn.cpp b/src/mlfn.cpp index 80f9163b..d4037897 100644 --- a/src/mlfn.cpp +++ b/src/mlfn.cpp @@ -45,7 +45,7 @@ pj_mlfn(double phi, double sphi, double cphi, const double *en) { } double -pj_inv_mlfn(projCtx ctx, double arg, double es, const double *en) { +pj_inv_mlfn(PJ_CONTEXT *ctx, double arg, double es, const double *en) { double sinphi_ignored; double cosphi_ignored; return inline_pj_inv_mlfn(ctx, arg, es, en, &sinphi_ignored, &cosphi_ignored); diff --git a/src/mlfn.hpp b/src/mlfn.hpp index 26a2959f..e7138c63 100644 --- a/src/mlfn.hpp +++ b/src/mlfn.hpp @@ -15,7 +15,7 @@ inline static double inline_pj_mlfn(double phi, double sphi, double cphi, const } inline static double -inline_pj_inv_mlfn(projCtx ctx, double arg, double es, const double *en, +inline_pj_inv_mlfn(PJ_CONTEXT *ctx, double arg, double es, const double *en, double* sinphi, double* cosphi) { const double k = 1./(1.-es); constexpr double INV_MLFN_EPS = 1e-11; diff --git a/src/param.cpp b/src/param.cpp index 289faca3..9a3888e1 100644 --- a/src/param.cpp +++ b/src/param.cpp @@ -151,7 +151,7 @@ paralist *pj_param_exists (paralist *list, const char *parameter) { /* */ /************************************************************************/ -PROJVALUE pj_param (projCtx ctx, paralist *pl, const char *opt) { +PROJVALUE pj_param (PJ_CONTEXT *ctx, paralist *pl, const char *opt) { int type; unsigned l; diff --git a/src/phi2.cpp b/src/phi2.cpp index 1c48d67f..214d1058 100644 --- a/src/phi2.cpp +++ b/src/phi2.cpp @@ -7,7 +7,7 @@ #include "proj.h" #include "proj_internal.h" -double pj_sinhpsi2tanphi(projCtx ctx, const double taup, const double e) { +double pj_sinhpsi2tanphi(PJ_CONTEXT *ctx, const double taup, const double e) { /**************************************************************************** * Convert tau' = sinh(psi) = tan(chi) to tau = tan(phi). The code is taken * from GeographicLib::Math::tauf(taup, e). @@ -108,7 +108,7 @@ double pj_sinhpsi2tanphi(projCtx ctx, const double taup, const double e) { } /*****************************************************************************/ -double pj_phi2(projCtx ctx, const double ts0, const double e) { +double pj_phi2(PJ_CONTEXT *ctx, const double ts0, const double e) { /**************************************************************************** * Determine latitude angle phi-2. * Inputs: diff --git a/src/proj.h b/src/proj.h index e2c47a17..d4defc47 100644 --- a/src/proj.h +++ b/src/proj.h @@ -340,9 +340,9 @@ typedef enum PJ_LOG_LEVEL { typedef void (*PJ_LOG_FUNCTION)(void *, int, const char *); -/* The context type - properly namespaced synonym for projCtx */ -struct projCtx_t; -typedef struct projCtx_t PJ_CONTEXT; +/* The context type - properly namespaced synonym for pj_ctx */ +struct pj_ctx; +typedef struct pj_ctx PJ_CONTEXT; /* A P I */ diff --git a/src/proj_internal.h b/src/proj_internal.h index 062f240b..273c1efd 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -240,8 +240,6 @@ struct PJ_AREA { double north_lat_degree; }; -struct projCtx_t; -typedef struct projCtx_t projCtx_t; /***************************************************************************** @@ -352,7 +350,7 @@ struct PJconsts { **************************************************************************************/ - projCtx_t *ctx = nullptr; + PJ_CONTEXT *ctx = nullptr; const char *descr = nullptr; /* From pj_list.h or individual PJ_*.c file */ paralist *params = nullptr; /* Parameter list */ char *def_full = nullptr; /* Full textual definition (usually 0 - set by proj_pj_info) */ @@ -393,7 +391,7 @@ struct PJconsts { PJ_OPERATOR inv4d = nullptr; PJ_DESTRUCTOR destructor = nullptr; - void (*reassign_context)(PJ*, projCtx_t *) = nullptr; + void (*reassign_context)(PJ*, PJ_CONTEXT*) = nullptr; /************************************************************************************* @@ -708,7 +706,7 @@ struct projFileApiCallbackAndData }; /* proj thread context */ -struct projCtx_t { +struct pj_ctx{ int last_errno = 0; int debug_level = 0; void (*logger)(void *, int, const char *) = nullptr; @@ -745,18 +743,18 @@ struct projCtx_t { int pipelineInitRecursiongCounter = 0; // to avoid potential infinite recursion in pipeline.cpp - projCtx_t() = default; - projCtx_t(const projCtx_t&); - ~projCtx_t(); + pj_ctx() = default; + pj_ctx(const pj_ctx&); + ~pj_ctx(); - projCtx_t& operator= (const projCtx_t&) = delete; + pj_ctx& operator= (const pj_ctx&) = delete; projCppContext* get_cpp_context(); void safeAutoCloseDbIfNeeded(); void set_search_paths(const std::vector& search_paths_in); void set_ca_bundle_path(const std::string& ca_bundle_path_in); - static projCtx_t createDefault(); + static pj_ctx createDefault(); }; /* Generate pj_list external or make list from include file */ @@ -804,41 +802,41 @@ PJ *pj_projection_specific_setup_##name (PJ *P) /* procedure prototypes */ double PROJ_DLL dmstor(const char *, char **); -double dmstor_ctx(projCtx_t *ctx, const char *, char **); +double dmstor_ctx(PJ_CONTEXT *ctx, const char *, char **); void PROJ_DLL set_rtodms(int, int); char PROJ_DLL *rtodms(char *, double, int, int); double PROJ_DLL adjlon(double); -double aacos(projCtx_t *,double); -double aasin(projCtx_t *,double); +double aacos(PJ_CONTEXT *,double); +double aasin(PJ_CONTEXT *,double); double asqrt(double); double aatan2(double, double); -PROJVALUE PROJ_DLL pj_param(projCtx_t *ctx, paralist *, const char *); +PROJVALUE PROJ_DLL pj_param(PJ_CONTEXT *ctx, paralist *, const char *); paralist PROJ_DLL *pj_param_exists (paralist *list, const char *parameter); paralist PROJ_DLL *pj_mkparam(const char *); paralist *pj_mkparam_ws (const char *str, const char **next_str); -int PROJ_DLL pj_ell_set(projCtx_t *ctx, paralist *, double *, double *); -int pj_datum_set(projCtx_t *,paralist *, PJ *); +int PROJ_DLL pj_ell_set(PJ_CONTEXT *ctx, paralist *, double *, double *); +int pj_datum_set(PJ_CONTEXT *,paralist *, PJ *); int pj_angular_units_set(paralist *, PJ *); paralist *pj_clone_paralist( const paralist* ); paralist *pj_search_initcache( const char *filekey ); void pj_insert_initcache( const char *filekey, const paralist *list); -paralist *pj_expand_init(projCtx_t *ctx, paralist *init); +paralist *pj_expand_init(PJ_CONTEXT *ctx, paralist *init); -void *pj_dealloc_params (projCtx_t *ctx, paralist *start, int errlev); +void *pj_dealloc_params (PJ_CONTEXT *ctx, paralist *start, int errlev); double *pj_enfn(double); double pj_mlfn(double, double, double, const double *); -double pj_inv_mlfn(projCtx_t *, double, double, const double *); +double pj_inv_mlfn(PJ_CONTEXT *, double, double, const double *); double pj_qsfn(double, double, double); double pj_tsfn(double, double, double); double pj_msfn(double, double, double); -double PROJ_DLL pj_phi2(projCtx_t *, const double, const double); -double pj_sinhpsi2tanphi(projCtx_t *, const double, const double); +double PROJ_DLL pj_phi2(PJ_CONTEXT *, const double, const double); +double pj_sinhpsi2tanphi(PJ_CONTEXT *, const double, const double); double pj_qsfn_(double, PJ *); double *pj_authset(double); double pj_authlat(double, double *); @@ -851,10 +849,10 @@ int pj_factors(PJ_LP, const PJ *, double, struct FACTORS *); void *proj_mdist_ini(double); double proj_mdist(double, double, double, const void *); -double proj_inv_mdist(projCtx_t *ctx, double, const void *); +double proj_inv_mdist(PJ_CONTEXT *ctx, double, const void *); void *pj_gauss_ini(double, double, double *,double *); -PJ_LP pj_gauss(projCtx_t *, PJ_LP, const void *); -PJ_LP pj_inv_gauss(projCtx_t *, PJ_LP, const void *); +PJ_LP pj_gauss(PJ_CONTEXT *, PJ_LP, const void *); +PJ_LP pj_inv_gauss(PJ_CONTEXT *, PJ_LP, const void *); struct PJ_DATUMS PROJ_DLL *pj_get_datums_ref( void ); @@ -865,7 +863,7 @@ double PROJ_DLL pj_atof( const char* nptr ); double pj_strtod( const char *nptr, char **endptr ); void pj_freeup_plain (PJ *P); -PJ* pj_init_ctx_with_allow_init_epsg( projCtx_t *ctx, int argc, char **argv, int allow_init_epsg ); +PJ* pj_init_ctx_with_allow_init_epsg( PJ_CONTEXT *ctx, int argc, char **argv, int allow_init_epsg ); std::string PROJ_DLL pj_add_type_crs_if_needed(const std::string& str); std::string pj_double_quote_string_param_if_needed(const std::string& str); @@ -921,10 +919,6 @@ PJ_LP pj_generic_inverse_2d(PJ_XY xy, PJ *P, PJ_LP lpInitial); #define DEG_TO_RAD .017453292519943296 -#if defined(PROJ_H) -#define PROJ_API_H_NOT_INVOKED_AS_PRIMARY_API -#endif - extern char const PROJ_DLL pj_release[]; /* global release id string */ @@ -938,33 +932,12 @@ PROJ_DLL extern int pj_errno; /* global error return code */ #define PJ_LOG_DEBUG_MINOR 3 #endif -#ifdef PROJ_API_H_NOT_INVOKED_AS_PRIMARY_API - /* These make the function declarations below conform with classic proj */ - typedef PJ *projPJ; /* projPJ is a pointer to PJ */ - typedef struct projCtx_t *projCtx; /* projCtx is a pointer to projCtx_t */ -# define projXY PJ_XY -# define projLP PJ_LP -# define projXYZ PJ_XYZ -# define projLPZ PJ_LPZ - -#else - /* i.e. proj_api invoked as primary API */ - typedef struct { double u, v; } projUV; - typedef struct { double u, v, w; } projUVW; - typedef void *projPJ; - #define projXY projUV - #define projLP projUV - #define projXYZ projUVW - #define projLPZ projUVW - typedef void *projCtx; -#endif - /* If included *after* proj.h finishes, we have alternative names */ /* file reading api, like stdio */ typedef int *PAFile; typedef struct projFileAPI_t { - PAFile (*FOpen)(projCtx ctx, const char *filename, const char *access); + PAFile (*FOpen)(PJ_CONTEXT * ctx, const char *filename, const char *access); size_t (*FRead)(void *buffer, size_t size, size_t nmemb, PAFile file); int (*FSeek)(PAFile file, long offset, int whence); long (*FTell)(PAFile file); @@ -975,34 +948,34 @@ typedef struct projFileAPI_t { /* procedure prototypes */ -projCtx PROJ_DLL pj_get_default_ctx(void); -projCtx PROJ_DLL pj_get_ctx( projPJ ); +PJ_CONTEXT PROJ_DLL *pj_get_default_ctx(void); +PJ_CONTEXT PROJ_DLL *pj_get_ctx( PJ *); -projXY PROJ_DLL pj_fwd(projLP, projPJ); -projLP PROJ_DLL pj_inv(projXY, projPJ); +PJ_XY PROJ_DLL pj_fwd(PJ_LP, PJ *); +PJ_LP PROJ_DLL pj_inv(PJ_XY, PJ *); -projXYZ PROJ_DLL pj_fwd3d(projLPZ, projPJ); -projLPZ PROJ_DLL pj_inv3d(projXYZ, projPJ); +PJ_XYZ PROJ_DLL pj_fwd3d(PJ_LPZ, PJ *); +PJ_LPZ PROJ_DLL pj_inv3d(PJ_XYZ, PJ *); -int PROJ_DLL pj_apply_gridshift( projCtx, const char *, int, +int PROJ_DLL pj_apply_gridshift( PJ_CONTEXT *, const char *, int, long point_count, int point_offset, double *x, double *y, double *z ); void PROJ_DLL pj_clear_initcache(void); -int PROJ_DLL pj_is_latlong(projPJ); -int PROJ_DLL pj_is_geocent(projPJ); -void PROJ_DLL pj_get_spheroid_defn(projPJ defn, double *major_axis, double *eccentricity_squared); -void PROJ_DLL pj_pr_list(projPJ); -void PROJ_DLL pj_free(projPJ); +int PROJ_DLL pj_is_latlong(PJ *); +int PROJ_DLL pj_is_geocent(PJ *); +void PROJ_DLL pj_get_spheroid_defn(PJ *defn, double *major_axis, double *eccentricity_squared); +void PROJ_DLL pj_pr_list(PJ *); +void PROJ_DLL pj_free(PJ *); void PROJ_DLL pj_set_finder( const char *(*)(const char *) ); void PROJ_DLL pj_set_searchpath ( int count, const char **path ); -projPJ PROJ_DLL pj_init(int, char **); -projPJ PROJ_DLL pj_init_plus(const char *); -projPJ PROJ_DLL pj_init_ctx( projCtx, int, char ** ); -projPJ PROJ_DLL pj_init_plus_ctx( projCtx, const char * ); -char PROJ_DLL *pj_get_def(projPJ, int); -projPJ PROJ_DLL pj_latlong_from_proj( projPJ ); -int PROJ_DLL pj_has_inverse(projPJ); +PJ PROJ_DLL *pj_init(int, char **); +PJ PROJ_DLL *pj_init_plus(const char *); +PJ PROJ_DLL *pj_init_ctx( PJ_CONTEXT *, int, char ** ); +PJ PROJ_DLL *pj_init_plus_ctx( PJ_CONTEXT *, const char * ); +char PROJ_DLL *pj_get_def(PJ *, int); +PJ PROJ_DLL *pj_latlong_from_proj( PJ *); +int PROJ_DLL pj_has_inverse(PJ *); void PROJ_DLL *pj_malloc(size_t); @@ -1017,33 +990,33 @@ void PROJ_DLL pj_acquire_lock(void); void PROJ_DLL pj_release_lock(void); void PROJ_DLL pj_cleanup_lock(void); -void PROJ_DLL pj_set_ctx( projPJ, projCtx ); -projCtx PROJ_DLL pj_ctx_alloc(void); -void PROJ_DLL pj_ctx_free( projCtx ); -int PROJ_DLL pj_ctx_get_errno( projCtx ); -void PROJ_DLL pj_ctx_set_errno( projCtx, int ); -void PROJ_DLL pj_ctx_set_debug( projCtx, int ); -void PROJ_DLL pj_ctx_set_logger( projCtx, void (*)(void *, int, const char *) ); -void PROJ_DLL pj_ctx_set_app_data( projCtx, void * ); -void PROJ_DLL *pj_ctx_get_app_data( projCtx ); -void PROJ_DLL pj_ctx_set_fileapi( projCtx, projFileAPI *); -projFileAPI PROJ_DLL *pj_ctx_get_fileapi( projCtx ); - -void PROJ_DLL pj_log( projCtx ctx, int level, const char *fmt, ... ); +void PROJ_DLL pj_set_ctx( PJ *, PJ_CONTEXT * ); +PJ_CONTEXT PROJ_DLL *pj_ctx_alloc(void); +void PROJ_DLL pj_ctx_free( PJ_CONTEXT * ); +int PROJ_DLL pj_ctx_get_errno( PJ_CONTEXT * ); +void PROJ_DLL pj_ctx_set_errno( PJ_CONTEXT *, int ); +void PROJ_DLL pj_ctx_set_debug( PJ_CONTEXT *, int ); +void PROJ_DLL pj_ctx_set_logger( PJ_CONTEXT *, void (*)(void *, int, const char *) ); +void PROJ_DLL pj_ctx_set_app_data( PJ_CONTEXT *, void * ); +void PROJ_DLL *pj_ctx_get_app_data( PJ_CONTEXT * ); +void PROJ_DLL pj_ctx_set_fileapi( PJ_CONTEXT *, projFileAPI *); +projFileAPI PROJ_DLL *pj_ctx_get_fileapi( PJ_CONTEXT * ); + +void PROJ_DLL pj_log( PJ_CONTEXT * ctx, int level, const char *fmt, ... ); void PROJ_DLL pj_stderr_logger( void *, int, const char * ); /* file api */ projFileAPI PROJ_DLL *pj_get_default_fileapi(void); -PAFile PROJ_DLL pj_ctx_fopen(projCtx ctx, const char *filename, const char *access); -size_t PROJ_DLL pj_ctx_fread(projCtx ctx, void *buffer, size_t size, size_t nmemb, PAFile file); -int PROJ_DLL pj_ctx_fseek(projCtx ctx, PAFile file, long offset, int whence); -long PROJ_DLL pj_ctx_ftell(projCtx ctx, PAFile file); -void PROJ_DLL pj_ctx_fclose(projCtx ctx, PAFile file); -char PROJ_DLL *pj_ctx_fgets(projCtx ctx, char *line, int size, PAFile file); +PAFile PROJ_DLL pj_ctx_fopen(PJ_CONTEXT * ctx, const char *filename, const char *access); +size_t PROJ_DLL pj_ctx_fread(PJ_CONTEXT * ctx, void *buffer, size_t size, size_t nmemb, PAFile file); +int PROJ_DLL pj_ctx_fseek(PJ_CONTEXT * ctx, PAFile file, long offset, int whence); +long PROJ_DLL pj_ctx_ftell(PJ_CONTEXT * ctx, PAFile file); +void PROJ_DLL pj_ctx_fclose(PJ_CONTEXT * ctx, PAFile file); +char PROJ_DLL *pj_ctx_fgets(PJ_CONTEXT * ctx, char *line, int size, PAFile file); -PAFile PROJ_DLL pj_open_lib(projCtx, const char *, const char *); -int PROJ_DLL pj_find_file(projCtx ctx, const char *short_filename, +PAFile PROJ_DLL pj_open_lib(PJ_CONTEXT *, const char *, const char *); +int PROJ_DLL pj_find_file(PJ_CONTEXT * ctx, const char *short_filename, char* out_full_filename, size_t out_full_filename_size); diff --git a/src/proj_mdist.cpp b/src/proj_mdist.cpp index c515f6c5..086521b7 100644 --- a/src/proj_mdist.cpp +++ b/src/proj_mdist.cpp @@ -107,7 +107,7 @@ proj_mdist(double phi, double sphi, double cphi, const void *data) { return(D + sc * sum); } double -proj_inv_mdist(projCtx ctx, double dist, const void *data) { +proj_inv_mdist(PJ_CONTEXT *ctx, double dist, const void *data) { const struct MDIST *b = (const struct MDIST *)data; double s, t, phi, k; int i; diff --git a/src/projections/chamb.cpp b/src/projections/chamb.cpp index 36609e79..1b926b8a 100644 --- a/src/projections/chamb.cpp +++ b/src/projections/chamb.cpp @@ -29,7 +29,7 @@ PROJ_HEAD(chamb, "Chamberlin Trimetric") "\n\tMisc Sph, no inv" #define TOL 1e-9 /* distance and azimuth from point 1 to point 2 */ -static VECT vect(projCtx ctx, double dphi, double c1, double s1, double c2, double s2, double dlam) { +static VECT vect(PJ_CONTEXT *ctx, double dphi, double c1, double s1, double c2, double s2, double dlam) { VECT v; double cdl, dp, dl; @@ -49,7 +49,7 @@ static VECT vect(projCtx ctx, double dphi, double c1, double s1, double c2, doub } /* law of cosines */ -static double lc(projCtx ctx, double b,double c,double a) { +static double lc(PJ_CONTEXT *ctx, double b,double c,double a) { return aacos(ctx, .5 * (b * b + c * c - a * a) / (b * c)); } diff --git a/src/tests/multistresstest.cpp b/src/tests/multistresstest.cpp index 51720fbd..674f5ded 100644 --- a/src/tests/multistresstest.cpp +++ b/src/tests/multistresstest.cpp @@ -172,7 +172,7 @@ static TestItem test_list[] = { static volatile int active_thread_count = 0; -static projPJ custom_pj_init_plus_ctx(projCtx ctx, const char* def) +static PJ *custom_pj_init_plus_ctx(PJ_CONTEXT *ctx, const char* def) { return pj_init_plus_ctx(ctx, def); } @@ -191,11 +191,12 @@ static void TestThread() /* -------------------------------------------------------------------- */ /* Initialize coordinate system definitions. */ /* -------------------------------------------------------------------- */ - projPJ *src_pj_list, *dst_pj_list; - projCtx ctx = pj_ctx_alloc(); + PJ **src_pj_list; + PJ **dst_pj_list; + PJ_CONTEXT *ctx = pj_ctx_alloc(); - src_pj_list = (projPJ *) calloc(test_count,sizeof(projPJ)); - dst_pj_list = (projPJ *) calloc(test_count,sizeof(projPJ)); + src_pj_list = (PJ **) calloc(test_count,sizeof(PJ)); + dst_pj_list = (PJ **) calloc(test_count,sizeof(PJ)); if(!reinit_every_iteration) { @@ -345,7 +346,8 @@ static int do_main(void) { TestItem *test = test_list + i; - projPJ src_pj, dst_pj; + PJ *src_pj; + PJ *dst_pj; src_pj = custom_pj_init_plus_ctx( pj_get_default_ctx(), test->src_def ); dst_pj = custom_pj_init_plus_ctx( pj_get_default_ctx(), test->dst_def ); diff --git a/src/tests/test228.cpp b/src/tests/test228.cpp index bffb8e79..ae2eb9cc 100644 --- a/src/tests/test228.cpp +++ b/src/tests/test228.cpp @@ -50,9 +50,9 @@ static volatile int started = 0; static void* thread_main(void* unused) { - projCtx p_proj_ctxt; - projPJ p_WGS84_proj; - projPJ p_OSGB36_proj; + PJ_CONTEXT *p_proj_ctxt; + PJ *p_WGS84_proj; + PJ * p_OSGB36_proj; (void)unused; __sync_add_and_fetch(&started, 1); diff --git a/src/utils.cpp b/src/utils.cpp index 9cb13f44..d3ec7e35 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -172,7 +172,7 @@ PJ *pj_latlong_from_proj( PJ *pj_in ) /* b = a * sqrt(1 - es) */ /************************************************************************/ -void pj_get_spheroid_defn(projPJ defn, double *major_axis, double *eccentricity_squared) +void pj_get_spheroid_defn(PJ * defn, double *major_axis, double *eccentricity_squared) { if ( major_axis ) *major_axis = defn->a; -- cgit v1.2.3 From 70c4c417313c5416fda1cac2f9ed48a201d1e4aa Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Mon, 16 Nov 2020 13:03:48 +0100 Subject: Convert multistresstest to new API --- src/tests/multistresstest.cpp | 170 ++++++++++++++++++------------------------ 1 file changed, 73 insertions(+), 97 deletions(-) (limited to 'src') diff --git a/src/tests/multistresstest.cpp b/src/tests/multistresstest.cpp index 674f5ded..6b7099ce 100644 --- a/src/tests/multistresstest.cpp +++ b/src/tests/multistresstest.cpp @@ -30,7 +30,7 @@ #include #include -#include "proj_internal.h" +#include "proj.h" #ifdef _WIN32 #include @@ -47,8 +47,8 @@ typedef struct { const char *src_def; const char *dst_def; - double src_x, src_y, src_z; - double dst_x, dst_y, dst_z; + PJ_COORD src; + PJ_COORD dst; int dst_error; int skip; @@ -58,125 +58,120 @@ static TestItem test_list[] = { { "+proj=utm +zone=11 +datum=WGS84", "+proj=latlong +datum=WGS84", - 150000.0, 3000000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 3000000.0, 0.0, 0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+proj=utm +zone=11 +datum=NAD83", "+proj=latlong +datum=NAD27", - 150000.0, 3000000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 3000000.0, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+proj=utm +zone=11 +datum=NAD83", "+proj=latlong +nadgrids=@null +ellps=WGS84", - 150000.0, 3000000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 3000000.0, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+proj=utm +zone=11 +datum=WGS84", "+proj=merc +datum=potsdam", - 150000.0, 3000000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 3000000.0, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+proj=latlong +nadgrids=nzgd2kgrid0005.gsb", "+proj=latlong +datum=WGS84", - 150000.0, 3000000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 3000000.0, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+proj=latlong +nadgrids=nzgd2kgrid0005.gsb", "+proj=latlong +datum=WGS84", - 170 * DEG_TO_RAD, -40 * DEG_TO_RAD, 0.0, - 0.0, 0.0, 0.0, + proj_coord(170, -40, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+proj=latlong +ellps=GRS80 +towgs84=2,3,5", "+proj=latlong +ellps=intl +towgs84=10,12,15", - 170 * DEG_TO_RAD, -40 * DEG_TO_RAD, 0.0, - 0.0, 0.0, 0.0, + proj_coord(170, -40, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+proj=eqc +lat_0=11 +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ", "+proj=stere +lat_0=11 +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ", - 150000.0, 250000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 250000.0, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+proj=cea +lat_ts=11 +lon_0=12 +y_0=200000 +datum=WGS84 ", "+proj=merc +lon_0=12 +k=0.999 +x_0=100000 +y_0=200000 +datum=WGS84 ", - 150000.0, 250000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 250000.0, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+proj=bonne +lat_1=11 +lon_0=12 +y_0=200000 +datum=WGS84 ", "+proj=cass +lat_0=11 +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ", - 150000.0, 250000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 250000.0, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+proj=nzmg +lat_0=11 +lon_0=12 +y_0=200000 +datum=WGS84 ", "+proj=gnom +lat_0=11 +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ", - 150000.0, 250000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 250000.0, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+proj=ortho +lat_0=11 +lon_0=12 +y_0=200000 +datum=WGS84 ", "+proj=laea +lat_0=11 +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ", - 150000.0, 250000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 250000.0, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+proj=aeqd +lat_0=11 +lon_0=12 +y_0=200000 +datum=WGS84 ", "+proj=eqdc +lat_1=20 +lat_2=5 +lat_0=11 +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ", - 150000.0, 250000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 250000.0, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+proj=mill +lat_0=11 +lon_0=12 +y_0=200000 +datum=WGS84 ", "+proj=moll +lon_0=12 +x_0=100000 +y_0=200000 +datum=WGS84 ", - 150000.0, 250000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 250000.0, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { "+init=epsg:3309", "+init=epsg:4326", - 150000.0, 30000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 30000.0, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 }, { /* Bad projection (invalid ellipsoid parameter +R_A=0) */ "+proj=utm +zone=11 +datum=WGS84", "+proj=merc +datum=potsdam +R_A=0", - 150000.0, 3000000.0, 0.0, - 0.0, 0.0, 0.0, + proj_coord(150000.0, 3000000.0, 0.0, 0.0), + proj_coord(0.0, 0.0, 0.0, 0.0), 0, 0 } }; static volatile int active_thread_count = 0; -static PJ *custom_pj_init_plus_ctx(PJ_CONTEXT *ctx, const char* def) -{ - return pj_init_plus_ctx(ctx, def); -} - /************************************************************************/ /* TestThread() */ /************************************************************************/ @@ -191,12 +186,10 @@ static void TestThread() /* -------------------------------------------------------------------- */ /* Initialize coordinate system definitions. */ /* -------------------------------------------------------------------- */ - PJ **src_pj_list; - PJ **dst_pj_list; - PJ_CONTEXT *ctx = pj_ctx_alloc(); + PJ **pj_list; + PJ_CONTEXT *ctx = proj_context_create(); - src_pj_list = (PJ **) calloc(test_count,sizeof(PJ)); - dst_pj_list = (PJ **) calloc(test_count,sizeof(PJ)); + pj_list = (PJ **) calloc(test_count,sizeof(PJ*)); if(!reinit_every_iteration) { @@ -204,8 +197,9 @@ static void TestThread() { TestItem *test = test_list + i; - src_pj_list[i] = custom_pj_init_plus_ctx( ctx, test->src_def ); - dst_pj_list[i] = custom_pj_init_plus_ctx( ctx, test->dst_def ); + pj_list[i] = proj_create_crs_to_crs( + ctx, test->src_def, test->dst_def, nullptr + ); } } @@ -218,28 +212,23 @@ static void TestThread() for( i = 0; i < test_count; i++ ) { TestItem *test = test_list + i; - double x, y, z; - int error; - - x = test->src_x; - y = test->src_y; - z = test->src_z; if( reinit_every_iteration ) { - src_pj_list[i] = custom_pj_init_plus_ctx( ctx, test->src_def ); - dst_pj_list[i] = custom_pj_init_plus_ctx( ctx, test->dst_def ); + proj_context_use_proj4_init_rules(nullptr, true); + pj_list[i] = proj_create_crs_to_crs( + ctx, test->src_def, test->dst_def, nullptr + ); { - int skipTest = (src_pj_list[i] == nullptr || dst_pj_list[i] == nullptr); + int skipTest = (pj_list[i] == nullptr); if ( skipTest != test->skip ) fprintf( stderr, "Threaded projection initialization does not match unthreaded initialization\n" ); if (skipTest) { - pj_free( src_pj_list[i] ); - pj_free( dst_pj_list[i] ); + proj_destroy( pj_list[i] ); continue; } } @@ -248,31 +237,32 @@ static void TestThread() if ( test->skip ) continue; - error = pj_transform( src_pj_list[i], dst_pj_list[i], 1, 0, - &x, &y, &z ); + PJ_COORD out = proj_trans(pj_list[i], PJ_FWD, test->src); + int error = proj_errno(pj_list[i]); if( error != test->dst_error ) { fprintf( stderr, "Got error %d, expected %d\n", error, test->dst_error ); } + proj_errno_reset(pj_list[i]); - if( x != test->dst_x || y != test->dst_y || z != test->dst_z ) + if ( out.xyz.x != test->dst.xyz.x || out.xyz.y != test->dst.xyz.y || out.xyz.z != test->dst.xyz.z) + //if( x != test->dst_x || y != test->dst_y || z != test->dst_z ) { fprintf( stderr, "Got %.15g,%.15g,%.15g\n" "Expected %.15g,%.15g,%.15g\n" "Diff %.15g,%.15g,%.15g\n", - x, y, z, - test->dst_x, test->dst_y, test->dst_z, - x-test->dst_x, y-test->dst_y, z-test->dst_z); + out.xyz.x, out.xyz.y, out.xyz.z, + test->dst.xyz.x, test->dst.xyz.y, test->dst.xyz.z, + out.xyz.x-test->dst.xyz.x, out.xyz.y-test->dst.xyz.y, out.xyz.z-test->dst.xyz.z); } if( reinit_every_iteration ) { - pj_free( src_pj_list[i] ); - pj_free( dst_pj_list[i] ); + proj_destroy( pj_list[i] ); } } } @@ -284,15 +274,13 @@ static void TestThread() { for( i = 0; i < test_count; i++ ) { - pj_free( src_pj_list[i] ); - pj_free( dst_pj_list[i] ); + proj_destroy( pj_list[i] ); } } - free( src_pj_list ); - free( dst_pj_list ); + free( pj_list ); - pj_ctx_free( ctx ); + proj_context_destroy( ctx ); printf( "%d iterations of the %d tests complete in thread X\n", repeat_count, test_count ); @@ -346,44 +334,32 @@ static int do_main(void) { TestItem *test = test_list + i; - PJ *src_pj; - PJ *dst_pj; - - src_pj = custom_pj_init_plus_ctx( pj_get_default_ctx(), test->src_def ); - dst_pj = custom_pj_init_plus_ctx( pj_get_default_ctx(), test->dst_def ); + PJ *pj; - if( src_pj == nullptr ) - { - printf( "Unable to translate:\n%s\n", test->src_def ); - test->skip = 1; - pj_free (dst_pj); - continue; - } + proj_context_use_proj4_init_rules(nullptr, true); + pj = proj_create_crs_to_crs( + nullptr, test->src_def, test->dst_def, nullptr + ); - if( dst_pj == nullptr ) + if( pj == nullptr ) { - printf( "Unable to translate:\n%s\n", test->dst_def ); + printf( "Unable to translate:\n%s\n or\n%s\n", test->src_def, test->dst_def ); test->skip = 1; - pj_free (src_pj); + proj_destroy(pj); continue; } - test->dst_x = test->src_x; - test->dst_y = test->src_y; - test->dst_z = test->src_z; - test->dst_error = pj_transform( src_pj, dst_pj, 1, 0, - &(test->dst_x), - &(test->dst_y), - &(test->dst_z) ); + PJ_COORD out = proj_trans(pj, PJ_FWD, test->src); + test->dst = out; + test->dst_error = proj_errno(pj); - pj_free( src_pj ); - pj_free( dst_pj ); + proj_destroy(pj); test->skip = 0; -#ifdef notdef - printf( "Test %d - output %.14g,%.14g,%g\n", i, test->dst_x, test->dst_y, test->dst_z ); +#ifdef nodef + printf( "Test %d - output %.14g,%.14g,%g\n", i, test->dst.xyz.x, test->dst.xyz.y, test->dst.xyz.z ); #endif } -- cgit v1.2.3 From 7f79fe7325a74d2a9eac93d7081a107ae54bb877 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Mon, 16 Nov 2020 21:10:45 +0100 Subject: Remove legacy file API --- src/Makefile.am | 1 - src/ctx.cpp | 2 - src/fileapi.cpp | 240 ---------------------------------------------------- src/filemanager.cpp | 95 --------------------- src/lib_proj.cmake | 1 - src/proj_internal.h | 27 ------ 6 files changed, 366 deletions(-) delete mode 100644 src/fileapi.cpp (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index edfd05ef..2c175e42 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -216,7 +216,6 @@ libproj_la_SOURCES = \ qsfn.cpp strerrno.cpp \ tsfn.cpp units.cpp ctx.cpp log.cpp zpoly1.cpp rtodms.cpp \ release.cpp gauss.cpp \ - fileapi.cpp \ generic_inverse.cpp \ quadtree.hpp \ \ diff --git a/src/ctx.cpp b/src/ctx.cpp index 24d3773b..d3eee39f 100644 --- a/src/ctx.cpp +++ b/src/ctx.cpp @@ -100,7 +100,6 @@ pj_ctx pj_ctx::createDefault() pj_ctx ctx; ctx.debug_level = PJ_LOG_NONE; ctx.logger = pj_stderr_logger; - ctx.fileapi_legacy = pj_get_default_fileapi(); NS_PROJ::FileManager::fillDefaultNetworkInterface(&ctx); if( getenv("PROJ_DEBUG") != nullptr ) @@ -170,7 +169,6 @@ pj_ctx::pj_ctx(const pj_ctx& other) : debug_level(other.debug_level), logger(other.logger), logger_app_data(other.logger_app_data), - fileapi_legacy(other.fileapi_legacy), cpp_context(other.cpp_context ? other.cpp_context->clone(this) : nullptr), use_proj4_init_rules(other.use_proj4_init_rules), epsg_file_exists(other.epsg_file_exists), diff --git a/src/fileapi.cpp b/src/fileapi.cpp deleted file mode 100644 index 0af83926..00000000 --- a/src/fileapi.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/****************************************************************************** - * Project: PROJ.4 - * Purpose: Implementation of the pj_ctx_* file api, and the default stdio - * based implementation. - * Author: Frank Warmerdam, warmerdam@pobox.com - * - ****************************************************************************** - * Copyright (c) 2013, 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. - *****************************************************************************/ - -#include -#include -#include -#include -#include - -#include "proj.h" -#include "proj_internal.h" -#include "filemanager.hpp" - -static PAFile stdio_fopen(PJ_CONTEXT *ctx, const char *filename, - const char *access); -static size_t stdio_fread(void *buffer, size_t size, size_t nmemb, - PAFile file); -static int stdio_fseek(PAFile file, long offset, int whence); -static long stdio_ftell(PAFile file); -static void stdio_fclose(PAFile file); - -static projFileAPI default_fileapi = { - stdio_fopen, - stdio_fread, - stdio_fseek, - stdio_ftell, - stdio_fclose -}; - -typedef struct { - PJ_CONTEXT *ctx; - FILE *fp; -} stdio_pafile; - -/************************************************************************/ -/* pj_get_default_fileapi() */ -/************************************************************************/ - -projFileAPI *pj_get_default_fileapi(void) -{ - return &default_fileapi; -} - -/************************************************************************/ -/* stdio_fopen() */ -/************************************************************************/ - -static PAFile stdio_fopen(PJ_CONTEXT *ctx, const char *filename, - const char *access) -{ - stdio_pafile *pafile; - FILE *fp; - - fp = fopen(filename, access); - if (fp == nullptr) - { - return nullptr; - } - - pafile = (stdio_pafile *) malloc(sizeof(stdio_pafile)); - if (!pafile) - { - pj_ctx_set_errno(ctx, ENOMEM); - fclose(fp); - return nullptr; - } - - pafile->fp = fp; - pafile->ctx = ctx; - return (PAFile) pafile; -} - -/************************************************************************/ -/* stdio_fread() */ -/************************************************************************/ - -static size_t stdio_fread(void *buffer, size_t size, size_t nmemb, - PAFile file) -{ - stdio_pafile *pafile = (stdio_pafile *) file; - return fread(buffer, size, nmemb, pafile->fp); -} - -/************************************************************************/ -/* stdio_fseek() */ -/************************************************************************/ -static int stdio_fseek(PAFile file, long offset, int whence) -{ - stdio_pafile *pafile = (stdio_pafile *) file; - return fseek(pafile->fp, offset, whence); -} - -/************************************************************************/ -/* stdio_ftell() */ -/************************************************************************/ -static long stdio_ftell(PAFile file) -{ - stdio_pafile *pafile = (stdio_pafile *) file; - return ftell(pafile->fp); -} - -/************************************************************************/ -/* stdio_fclose() */ -/************************************************************************/ -static void stdio_fclose(PAFile file) -{ - stdio_pafile *pafile = (stdio_pafile *) file; - fclose(pafile->fp); - free(pafile); -} - -/************************************************************************/ -/* pj_ctx_fopen() */ -/* */ -/* Open a file using the provided file io hooks. */ -/************************************************************************/ - -PAFile pj_ctx_fopen(PJ_CONTEXT *ctx, const char *filename, const char *access) -{ - return ctx->fileapi_legacy->FOpen(ctx, filename, access); -} - -/************************************************************************/ -/* pj_ctx_fread() */ -/************************************************************************/ -size_t pj_ctx_fread(PJ_CONTEXT *ctx, void *buffer, size_t size, size_t nmemb, PAFile file) -{ - return ctx->fileapi_legacy->FRead(buffer, size, nmemb, file); -} - -/************************************************************************/ -/* pj_ctx_fseek() */ -/************************************************************************/ -int pj_ctx_fseek(PJ_CONTEXT *ctx, PAFile file, long offset, int whence) -{ - return ctx->fileapi_legacy->FSeek(file, offset, whence); -} - -/************************************************************************/ -/* pj_ctx_ftell() */ -/************************************************************************/ -long pj_ctx_ftell(PJ_CONTEXT *ctx, PAFile file) -{ - return ctx->fileapi_legacy->FTell(file); -} - -/************************************************************************/ -/* pj_ctx_fclose() */ -/************************************************************************/ -void pj_ctx_fclose(PJ_CONTEXT *ctx, PAFile file) -{ - ctx->fileapi_legacy->FClose(file); -} - -/************************************************************************/ -/* pj_ctx_fgets() */ -/* */ -/* A not very optimal implementation of fgets on top of */ -/* fread(). If we end up using this a lot more care should be */ -/* taken. */ -/************************************************************************/ - -char *pj_ctx_fgets(PJ_CONTEXT *ctx, char *line, int size, PAFile file) -{ - long start = pj_ctx_ftell(ctx, file); - size_t bytes_read; - int i; - int max_size; - - line[size-1] = '\0'; - bytes_read = pj_ctx_fread(ctx, line, 1, size-1, file); - if(bytes_read == 0) - return nullptr; - if(bytes_read < (size_t)size) - { - line[bytes_read] = '\0'; - } - - max_size = (int)MIN(bytes_read, (size_t)(size > 2 ? size - 2 : 0)); - for( i = 0; i < max_size; i++) - { - if (line[i] == '\n') - { - line[i+1] = '\0'; - pj_ctx_fseek(ctx, file, start + i + 1, SEEK_SET); - break; - } - } - return line; -} - -/************************************************************************/ -/* pj_ctx_set_fileapi() */ -/************************************************************************/ - -void pj_ctx_set_fileapi( PJ_CONTEXT *ctx, projFileAPI *fileapi ) - -{ - if (nullptr==ctx) - return; - ctx->fileapi_legacy = fileapi; -} - -/************************************************************************/ -/* pj_ctx_get_fileapi() */ -/************************************************************************/ - -projFileAPI *pj_ctx_get_fileapi( PJ_CONTEXT *ctx ) - -{ - if (nullptr==ctx) - return nullptr; - return ctx->fileapi_legacy; -} - diff --git a/src/filemanager.cpp b/src/filemanager.cpp index 37dc920e..66a8faf8 100644 --- a/src/filemanager.cpp +++ b/src/filemanager.cpp @@ -786,75 +786,6 @@ std::unique_ptr FileStdio::open(PJ_CONTEXT *ctx, const char *filename, // --------------------------------------------------------------------------- -#ifndef REMOVE_LEGACY_SUPPORT - -class FileLegacyAdapter : public File { - PJ_CONTEXT *m_ctx; - PAFile m_fp; - - FileLegacyAdapter(const FileLegacyAdapter &) = delete; - FileLegacyAdapter &operator=(const FileLegacyAdapter &) = delete; - - protected: - FileLegacyAdapter(const std::string &filename, PJ_CONTEXT *ctx, PAFile fp) - : File(filename), m_ctx(ctx), m_fp(fp) {} - - public: - ~FileLegacyAdapter() override; - - size_t read(void *buffer, size_t sizeBytes) override; - size_t write(const void *, size_t) override { return 0; } - bool seek(unsigned long long offset, int whence = SEEK_SET) override; - unsigned long long tell() override; - void reassign_context(PJ_CONTEXT *ctx) override { m_ctx = ctx; } - - // We may lie, but the real use case is only for network files - bool hasChanged() const override { return false; } - - static std::unique_ptr open(PJ_CONTEXT *ctx, const char *filename, - FileAccess access); -}; - -// --------------------------------------------------------------------------- - -FileLegacyAdapter::~FileLegacyAdapter() { pj_ctx_fclose(m_ctx, m_fp); } - -// --------------------------------------------------------------------------- - -size_t FileLegacyAdapter::read(void *buffer, size_t sizeBytes) { - return pj_ctx_fread(m_ctx, buffer, 1, sizeBytes, m_fp); -} - -// --------------------------------------------------------------------------- - -bool FileLegacyAdapter::seek(unsigned long long offset, int whence) { - if (offset != static_cast(static_cast(offset))) { - pj_log(m_ctx, PJ_LOG_ERROR, - "Attempt at seeking to a 64 bit offset. Not supported yet"); - return false; - } - return pj_ctx_fseek(m_ctx, m_fp, static_cast(offset), whence) == 0; -} - -// --------------------------------------------------------------------------- - -unsigned long long FileLegacyAdapter::tell() { - return pj_ctx_ftell(m_ctx, m_fp); -} - -// --------------------------------------------------------------------------- - -std::unique_ptr -FileLegacyAdapter::open(PJ_CONTEXT *ctx, const char *filename, FileAccess) { - auto fid = pj_ctx_fopen(ctx, filename, "rb"); - return std::unique_ptr(fid ? new FileLegacyAdapter(filename, ctx, fid) - : nullptr); -} - -#endif // REMOVE_LEGACY_SUPPORT - -// --------------------------------------------------------------------------- - class FileApiAdapter : public File { PJ_CONTEXT *m_ctx; PROJ_FILE_HANDLE *m_fp; @@ -954,12 +885,6 @@ std::unique_ptr FileManager::open(PJ_CONTEXT *ctx, const char *filename, } return pj_network_file_open(ctx, filename); } -#ifndef REMOVE_LEGACY_SUPPORT - // If the user has specified a legacy fileapi, use it - if (ctx->fileapi_legacy != pj_get_default_fileapi()) { - return FileLegacyAdapter::open(ctx, filename, access); - } -#endif if (ctx->fileApi.open_cbk != nullptr) { return FileApiAdapter::open(ctx, filename, access); } @@ -1728,26 +1653,6 @@ NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name) { return file; } -/************************************************************************/ -/* pj_open_lib() */ -/************************************************************************/ - -#ifndef REMOVE_LEGACY_SUPPORT - -// Used by following legacy function -static void *pj_ctx_fopen_adapter(PJ_CONTEXT *ctx, const char *name, - const char *mode) { - return pj_ctx_fopen(ctx, name, mode); -} - -// Legacy function -PAFile pj_open_lib(PJ_CONTEXT *ctx, const char *name, const char *mode) { - return (PAFile)pj_open_lib_internal(ctx, name, mode, pj_ctx_fopen_adapter, - nullptr, 0); -} - -#endif // REMOVE_LEGACY_SUPPORT - /************************************************************************/ /* pj_find_file() */ /************************************************************************/ diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index b0f9a6ba..997eb22d 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -219,7 +219,6 @@ set(SRC_LIBPROJ_CORE ellps.cpp errno.cpp factors.cpp - fileapi.cpp fwd.cpp gauss.cpp generic_inverse.cpp diff --git a/src/proj_internal.h b/src/proj_internal.h index 273c1efd..3c1571eb 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -711,7 +711,6 @@ struct pj_ctx{ int debug_level = 0; void (*logger)(void *, int, const char *) = nullptr; void *logger_app_data = nullptr; - struct projFileAPI_t *fileapi_legacy = nullptr; // for proj_api.h legacy API struct projCppContext* cpp_context = nullptr; /* internal context for C++ code */ int use_proj4_init_rules = -1; /* -1 = unknown, 0 = no, 1 = yes */ int epsg_file_exists = -1; /* -1 = unknown, 0 = no, 1 = yes */ @@ -933,19 +932,6 @@ PROJ_DLL extern int pj_errno; /* global error return code */ #endif -/* If included *after* proj.h finishes, we have alternative names */ -/* file reading api, like stdio */ -typedef int *PAFile; -typedef struct projFileAPI_t { - PAFile (*FOpen)(PJ_CONTEXT * ctx, const char *filename, const char *access); - size_t (*FRead)(void *buffer, size_t size, size_t nmemb, PAFile file); - int (*FSeek)(PAFile file, long offset, int whence); - long (*FTell)(PAFile file); - void (*FClose)(PAFile); -} projFileAPI; - - - /* procedure prototypes */ PJ_CONTEXT PROJ_DLL *pj_get_default_ctx(void); @@ -999,23 +985,10 @@ void PROJ_DLL pj_ctx_set_debug( PJ_CONTEXT *, int ); void PROJ_DLL pj_ctx_set_logger( PJ_CONTEXT *, void (*)(void *, int, const char *) ); void PROJ_DLL pj_ctx_set_app_data( PJ_CONTEXT *, void * ); void PROJ_DLL *pj_ctx_get_app_data( PJ_CONTEXT * ); -void PROJ_DLL pj_ctx_set_fileapi( PJ_CONTEXT *, projFileAPI *); -projFileAPI PROJ_DLL *pj_ctx_get_fileapi( PJ_CONTEXT * ); void PROJ_DLL pj_log( PJ_CONTEXT * ctx, int level, const char *fmt, ... ); void PROJ_DLL pj_stderr_logger( void *, int, const char * ); -/* file api */ -projFileAPI PROJ_DLL *pj_get_default_fileapi(void); - -PAFile PROJ_DLL pj_ctx_fopen(PJ_CONTEXT * ctx, const char *filename, const char *access); -size_t PROJ_DLL pj_ctx_fread(PJ_CONTEXT * ctx, void *buffer, size_t size, size_t nmemb, PAFile file); -int PROJ_DLL pj_ctx_fseek(PJ_CONTEXT * ctx, PAFile file, long offset, int whence); -long PROJ_DLL pj_ctx_ftell(PJ_CONTEXT * ctx, PAFile file); -void PROJ_DLL pj_ctx_fclose(PJ_CONTEXT * ctx, PAFile file); -char PROJ_DLL *pj_ctx_fgets(PJ_CONTEXT * ctx, char *line, int size, PAFile file); - -PAFile PROJ_DLL pj_open_lib(PJ_CONTEXT *, const char *, const char *); int PROJ_DLL pj_find_file(PJ_CONTEXT * ctx, const char *short_filename, char* out_full_filename, size_t out_full_filename_size); -- cgit v1.2.3 From a74b985b5006c2d279353a245cfcb850cf7fcc94 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Tue, 17 Nov 2020 12:54:24 +0100 Subject: Remove pj_ctx_* functions and use their proj_context counterparts --- src/4D_api.cpp | 15 ++--- src/aasincos.cpp | 4 +- src/apps/cs2cs.cpp | 15 ++++- src/ctx.cpp | 127 ++++-------------------------------------- src/datum_set.cpp | 6 +- src/dmstor.cpp | 4 +- src/ell_set.cpp | 22 ++++---- src/filemanager.cpp | 8 +-- src/gauss.cpp | 2 +- src/generic_inverse.cpp | 2 +- src/grids.cpp | 74 ++++++++++++------------ src/init.cpp | 10 ++-- src/internal.cpp | 12 ++-- src/iso19111/c_api.cpp | 4 +- src/iso19111/datum.cpp | 4 +- src/malloc.cpp | 4 +- src/mlfn.hpp | 2 +- src/networkfilemanager.cpp | 6 +- src/param.cpp | 2 +- src/phi2.cpp | 2 +- src/proj_internal.h | 10 ---- src/proj_mdist.cpp | 2 +- src/projections/aitoff.cpp | 2 +- src/projections/comill.cpp | 2 +- src/projections/eqearth.cpp | 2 +- src/projections/healpix.cpp | 8 +-- src/projections/krovak.cpp | 2 +- src/projections/natearth.cpp | 2 +- src/projections/natearth2.cpp | 2 +- src/projections/ortho.cpp | 2 +- src/projections/patterson.cpp | 2 +- src/projections/robin.cpp | 2 +- src/projections/tmerc.cpp | 6 +- src/utils.cpp | 2 +- 34 files changed, 137 insertions(+), 234 deletions(-) (limited to 'src') diff --git a/src/4D_api.cpp b/src/4D_api.cpp index 86c0e071..70b04bf1 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -1363,7 +1363,7 @@ int proj_errno (const PJ *P) { /****************************************************************************** Read an error level from the context of a PJ. ******************************************************************************/ - return pj_ctx_get_errno (pj_get_ctx ((PJ *) P)); + return proj_context_errno (pj_get_ctx ((PJ *) P)); } /*****************************************************************************/ @@ -1374,7 +1374,7 @@ int proj_context_errno (PJ_CONTEXT *ctx) { ******************************************************************************/ if (nullptr==ctx) ctx = pj_get_default_ctx(); - return pj_ctx_get_errno (ctx); + return ctx->last_errno; } /*****************************************************************************/ @@ -1389,6 +1389,7 @@ int proj_errno_set (const PJ *P, int err) { /* For P==0 err goes to the default context */ proj_context_errno_set (pj_get_ctx ((PJ *) P), err); errno = err; + return err; } @@ -1439,7 +1440,7 @@ int proj_errno_reset (const PJ *P) { int last_errno; last_errno = proj_errno (P); - pj_ctx_set_errno (pj_get_ctx ((PJ *) P), 0); + proj_context_errno_set (pj_get_ctx ((PJ *) P), 0); errno = 0; pj_errno = 0; return last_errno; @@ -1448,7 +1449,7 @@ int proj_errno_reset (const PJ *P) { /* Create a new context based on the default context */ PJ_CONTEXT *proj_context_create (void) { - return pj_ctx_alloc (); + return new (std::nothrow) pj_ctx(*pj_get_default_ctx()); } @@ -1460,7 +1461,7 @@ PJ_CONTEXT *proj_context_destroy (PJ_CONTEXT *ctx) { if (pj_get_default_ctx ()==ctx) return nullptr; - pj_ctx_free (ctx); + delete ctx; return nullptr; } @@ -1746,7 +1747,7 @@ PJ_INIT_INFO proj_init_info(const char *initname){ if( strcmp(initname, "epsg") == 0 || strcmp(initname, "EPSG") == 0 ) { const char* val; - pj_ctx_set_errno( ctx, 0 ); + proj_context_errno_set( ctx, 0 ); strncpy (ininfo.name, initname, sizeof(ininfo.name) - 1); strcpy(ininfo.origin, "EPSG"); @@ -1764,7 +1765,7 @@ PJ_INIT_INFO proj_init_info(const char *initname){ if( strcmp(initname, "IGNF") == 0 ) { const char* val; - pj_ctx_set_errno( ctx, 0 ); + proj_context_errno_set( ctx, 0 ); strncpy (ininfo.name, initname, sizeof(ininfo.name) - 1); strcpy(ininfo.origin, "IGNF"); diff --git a/src/aasincos.cpp b/src/aasincos.cpp index c3229d39..c4314c67 100644 --- a/src/aasincos.cpp +++ b/src/aasincos.cpp @@ -14,7 +14,7 @@ aasin(PJ_CONTEXT *ctx,double v) { if ((av = fabs(v)) >= 1.) { if (av > ONE_TOL) - pj_ctx_set_errno( ctx, PJD_ERR_ACOS_ASIN_ARG_TOO_LARGE ); + proj_context_errno_set( ctx, PJD_ERR_ACOS_ASIN_ARG_TOO_LARGE ); return (v < 0. ? -M_HALFPI : M_HALFPI); } return asin(v); @@ -26,7 +26,7 @@ aacos(PJ_CONTEXT *ctx, double v) { if ((av = fabs(v)) >= 1.) { if (av > ONE_TOL) - pj_ctx_set_errno( ctx, PJD_ERR_ACOS_ASIN_ARG_TOO_LARGE ); + proj_context_errno_set( ctx, PJD_ERR_ACOS_ASIN_ARG_TOO_LARGE ); return (v < 0. ? M_PI : 0.); } return acos(v); diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp index 1a33d444..92e4441e 100644 --- a/src/apps/cs2cs.cpp +++ b/src/apps/cs2cs.cpp @@ -468,10 +468,23 @@ int main(int argc, char **argv) { reverseout = 1; continue; case 'D': /* set debug level */ + { if (--argc <= 0) goto noargument; - pj_ctx_set_debug(pj_get_default_ctx(), atoi(*++argv)); + int log_level = atoi(*++argv); + if (log_level <= 0) { + proj_log_level(pj_get_default_ctx(), PJ_LOG_NONE); + } else if (log_level == 1) { + proj_log_level(pj_get_default_ctx(), PJ_LOG_ERROR); + } else if (log_level == 2) { + proj_log_level(pj_get_default_ctx(), PJ_LOG_DEBUG); + } else if (log_level == 3) { + proj_log_level(pj_get_default_ctx(), PJ_LOG_TRACE); + } else { + proj_log_level(pj_get_default_ctx(), PJ_LOG_TELL); + } continue; + } case 'd': if (--argc <= 0) goto noargument; diff --git a/src/ctx.cpp b/src/ctx.cpp index d3eee39f..8e25db2a 100644 --- a/src/ctx.cpp +++ b/src/ctx.cpp @@ -54,13 +54,17 @@ PJ_CONTEXT* pj_get_ctx( PJ *pj ) } /************************************************************************/ -/* pj_set_ctx() */ -/* */ -/* Note we do not deallocate the old context! */ +/* proj_assign_context() */ /************************************************************************/ -void pj_set_ctx( PJ *pj, PJ_CONTEXT *ctx ) - +/** \brief Re-assign a context to a PJ* object. + * + * This may be useful if the PJ* has been created with a context that is + * thread-specific, and is later used in another thread. In that case, + * the user may want to assign another thread-specific context to the + * object. + */ +void proj_assign_context( PJ* pj, PJ_CONTEXT *ctx ) { if (pj==nullptr) return; @@ -71,24 +75,9 @@ void pj_set_ctx( PJ *pj, PJ_CONTEXT *ctx ) } for( const auto &alt: pj->alternativeCoordinateOperations ) { - pj_set_ctx(alt.pj, ctx); + proj_assign_context(alt.pj, ctx); } -} -/************************************************************************/ -/* proj_assign_context() */ -/************************************************************************/ - -/** \brief Re-assign a context to a PJ* object. - * - * This may be useful if the PJ* has been created with a context that is - * thread-specific, and is later used in another thread. In that case, - * the user may want to assign another thread-specific context to the - * object. - */ -void proj_assign_context( PJ* pj, PJ_CONTEXT *ctx ) -{ - pj_set_ctx( pj, ctx ); } /************************************************************************/ @@ -212,16 +201,6 @@ pj_ctx::~pj_ctx() proj_context_delete_cpp_context(cpp_context); } -/************************************************************************/ -/* pj_ctx_alloc() */ -/************************************************************************/ - -PJ_CONTEXT* pj_ctx_alloc() - -{ - return new (std::nothrow) pj_ctx(*pj_get_default_ctx()); -} - /************************************************************************/ /* proj_context_clone() */ /* Create a new context based on a custom context */ @@ -230,93 +209,9 @@ PJ_CONTEXT* pj_ctx_alloc() PJ_CONTEXT* proj_context_clone (PJ_CONTEXT *ctx) { if (nullptr==ctx) - return pj_ctx_alloc (); + return proj_context_create(); return new (std::nothrow) pj_ctx(*ctx); } -/************************************************************************/ -/* pj_ctx_free() */ -/************************************************************************/ - -void pj_ctx_free( PJ_CONTEXT *ctx ) - -{ - delete ctx; -} - -/************************************************************************/ -/* pj_ctx_get_errno() */ -/************************************************************************/ - -int pj_ctx_get_errno( PJ_CONTEXT *ctx ) -{ - if (nullptr==ctx) - return pj_get_default_ctx ()->last_errno; - return ctx->last_errno; -} - -/************************************************************************/ -/* pj_ctx_set_errno() */ -/* */ -/* Also sets the global errno */ -/************************************************************************/ - -void pj_ctx_set_errno( PJ_CONTEXT *ctx, int new_errno ) - -{ - ctx->last_errno = new_errno; - if( new_errno == 0 ) - return; - errno = new_errno; - pj_errno = new_errno; -} - -/************************************************************************/ -/* pj_ctx_set_debug() */ -/************************************************************************/ - -void pj_ctx_set_debug( PJ_CONTEXT *ctx, int new_debug ) - -{ - if (nullptr==ctx) - return; - ctx->debug_level = new_debug; -} - -/************************************************************************/ -/* pj_ctx_set_logger() */ -/************************************************************************/ - -void pj_ctx_set_logger( PJ_CONTEXT *ctx, void (*new_logger)(void*,int,const char*) ) - -{ - if (nullptr==ctx) - return; - ctx->logger = new_logger; -} - -/************************************************************************/ -/* pj_ctx_set_app_data() */ -/************************************************************************/ - -void pj_ctx_set_app_data( PJ_CONTEXT *ctx, void *new_app_data ) - -{ - if (nullptr==ctx) - return; - ctx->logger_app_data = new_app_data; -} - -/************************************************************************/ -/* pj_ctx_get_app_data() */ -/************************************************************************/ - -void *pj_ctx_get_app_data( PJ_CONTEXT *ctx ) - -{ - if (nullptr==ctx) - return nullptr; - return ctx->logger_app_data; -} diff --git a/src/datum_set.cpp b/src/datum_set.cpp index cc6f3dbe..398d85cd 100644 --- a/src/datum_set.cpp +++ b/src/datum_set.cpp @@ -71,7 +71,7 @@ int pj_datum_set(PJ_CONTEXT *ctx, paralist *pl, PJ *projdef) for (i = 0; (s = pj_datums[i].id) && strcmp(name, s) ; ++i) {} if (!s) { - pj_ctx_set_errno(ctx, PJD_ERR_UNKNOWN_ELLP_PARAM); + proj_context_errno_set(ctx, PJD_ERR_UNKNOWN_ELLP_PARAM); return 1; } @@ -87,7 +87,7 @@ int pj_datum_set(PJ_CONTEXT *ctx, paralist *pl, PJ *projdef) curr = curr->next = pj_mkparam(entry); if (nullptr == curr) { - pj_ctx_set_errno(ctx, ENOMEM); + proj_context_errno_set(ctx, ENOMEM); return 1; } } @@ -97,7 +97,7 @@ int pj_datum_set(PJ_CONTEXT *ctx, paralist *pl, PJ *projdef) curr = curr->next = pj_mkparam(pj_datums[i].defn); if (nullptr == curr) { - pj_ctx_set_errno(ctx, ENOMEM); + proj_context_errno_set(ctx, ENOMEM); return 1; } } diff --git a/src/dmstor.cpp b/src/dmstor.cpp index e72d9930..24887a11 100644 --- a/src/dmstor.cpp +++ b/src/dmstor.cpp @@ -61,7 +61,7 @@ dmstor_ctx(PJ_CONTEXT *ctx, const char *is, char **rs) { n = 2; break; case 'r': case 'R': if (nl) { - pj_ctx_set_errno( ctx, PJD_ERR_WRONG_FORMAT_DMS_VALUE ); + proj_context_errno_set( ctx, PJD_ERR_WRONG_FORMAT_DMS_VALUE ); return HUGE_VAL; } ++s; @@ -73,7 +73,7 @@ dmstor_ctx(PJ_CONTEXT *ctx, const char *is, char **rs) { continue; } if (n < nl) { - pj_ctx_set_errno( ctx, PJD_ERR_WRONG_FORMAT_DMS_VALUE ); + proj_context_errno_set( ctx, PJD_ERR_WRONG_FORMAT_DMS_VALUE ); return HUGE_VAL; } v += tv * vm[n]; diff --git a/src/ell_set.cpp b/src/ell_set.cpp index ec3e03eb..c7cbeb48 100644 --- a/src/ell_set.cpp +++ b/src/ell_set.cpp @@ -552,7 +552,7 @@ int pj_calc_ellipsoid_params (PJ *P, double a, double es) { if (0==P->f) P->f = 1 - cos (P->alpha); /* = 1 - sqrt (1 - PIN->es); */ if (P->f == 1.0) { - pj_ctx_set_errno( P->ctx, PJD_ERR_INVALID_ECCENTRICITY); + proj_context_errno_set( P->ctx, PJD_ERR_INVALID_ECCENTRICITY); return PJD_ERR_INVALID_ECCENTRICITY; } P->rf = P->f != 0.0 ? 1.0/P->f: HUGE_VAL; @@ -573,7 +573,7 @@ int pj_calc_ellipsoid_params (PJ *P, double a, double es) { P->one_es = 1. - P->es; if (P->one_es == 0.) { - pj_ctx_set_errno( P->ctx, PJD_ERR_INVALID_ECCENTRICITY); + proj_context_errno_set( P->ctx, PJD_ERR_INVALID_ECCENTRICITY); return PJD_ERR_INVALID_ECCENTRICITY; } @@ -630,7 +630,7 @@ int pj_ell_set (PJ_CONTEXT *ctx, paralist *pl, double *a, double *es) { paralist *start = 0; /* clear any previous error */ - pj_ctx_set_errno(ctx,0); + proj_context_errno_set(ctx,0); /* check for varying forms of ellipsoid input */ *a = *es = 0.; @@ -648,7 +648,7 @@ int pj_ell_set (PJ_CONTEXT *ctx, paralist *pl, double *a, double *es) { for (start = pl; start && start->next ; start = start->next) ; for (i = 0; (s = pj_ellps[i].id) && strcmp(name, s) ; ++i) ; if (!s) { - pj_ctx_set_errno( ctx, PJD_ERR_UNKNOWN_ELLP_PARAM); + proj_context_errno_set( ctx, PJD_ERR_UNKNOWN_ELLP_PARAM); return 1; } start->next = pj_mkparam(pj_ellps[i].major); @@ -662,14 +662,14 @@ int pj_ell_set (PJ_CONTEXT *ctx, paralist *pl, double *a, double *es) { else if (pj_param(ctx,pl, "te").i) { /* eccentricity */ e = pj_param(ctx,pl, "de").f; if (e < 0) { - pj_ctx_set_errno(ctx, PJD_ERR_INVALID_ECCENTRICITY); + proj_context_errno_set(ctx, PJD_ERR_INVALID_ECCENTRICITY); return 1; } *es = e * e; } else if (pj_param(ctx,pl, "trf").i) { /* recip flattening */ *es = pj_param(ctx,pl, "drf").f; if (*es == 0.0) { - pj_ctx_set_errno(ctx, PJD_ERR_REV_FLATTENING_IS_ZERO); + proj_context_errno_set(ctx, PJD_ERR_REV_FLATTENING_IS_ZERO); goto bomb; } *es = 1./ *es; @@ -700,7 +700,7 @@ int pj_ell_set (PJ_CONTEXT *ctx, paralist *pl, double *a, double *es) { *es = 0.; } else if (pj_param(ctx,pl, "bR_h").i) { /* sphere--harmonic mean */ if ( (*a + b) == 0.0) { - pj_ctx_set_errno(ctx, PJD_ERR_TOLERANCE_CONDITION); + proj_context_errno_set(ctx, PJD_ERR_TOLERANCE_CONDITION); goto bomb; } *a = 2. * *a * b / (*a + b); @@ -711,7 +711,7 @@ int pj_ell_set (PJ_CONTEXT *ctx, paralist *pl, double *a, double *es) { tmp = sin(pj_param(ctx,pl, i ? "rR_lat_a" : "rR_lat_g").f); if (fabs(tmp) > M_HALFPI) { - pj_ctx_set_errno(ctx, PJD_ERR_REF_RAD_LARGER_THAN_90); + proj_context_errno_set(ctx, PJD_ERR_REF_RAD_LARGER_THAN_90); goto bomb; } tmp = 1. - *es * tmp * tmp; @@ -730,15 +730,15 @@ bomb: } /* some remaining checks */ if (*es < 0.) { - pj_ctx_set_errno(ctx, PJD_ERR_ES_LESS_THAN_ZERO); + proj_context_errno_set(ctx, PJD_ERR_ES_LESS_THAN_ZERO); return 1; } if (*es >= 1.) { - pj_ctx_set_errno(ctx, PJD_ERR_INVALID_ECCENTRICITY); + proj_context_errno_set(ctx, PJD_ERR_INVALID_ECCENTRICITY); return 1; } if (*a <= 0.) { - pj_ctx_set_errno(ctx, PJD_ERR_MAJOR_AXIS_NOT_GIVEN); + proj_context_errno_set(ctx, PJD_ERR_MAJOR_AXIS_NOT_GIVEN); return 1; } return 0; diff --git a/src/filemanager.cpp b/src/filemanager.cpp index 66a8faf8..dbcb8ddc 100644 --- a/src/filemanager.cpp +++ b/src/filemanager.cpp @@ -1491,7 +1491,7 @@ pj_open_lib_internal(PJ_CONTEXT *ctx, const char *name, const char *mode, } if (ctx->last_errno == 0 && errno != 0) - pj_ctx_set_errno(ctx, errno); + proj_context_errno_set(ctx, errno); pj_log(ctx, PJ_LOG_DEBUG_MAJOR, "pj_open_lib(%s): call fopen(%s) - %s", name, sysname, fid == nullptr ? "failed" : "succeeded"); @@ -1591,7 +1591,7 @@ NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name) { pj_open_file_with_manager, nullptr, 0))); if (file) { - pj_ctx_set_errno(ctx, 0); + proj_context_errno_set(ctx, 0); } else { // For final network access attempt, use the new // name. @@ -1621,7 +1621,7 @@ NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name) { pj_open_file_with_manager, nullptr, 0))); if (file) { - pj_ctx_set_errno(ctx, 0); + proj_context_errno_set(ctx, 0); } } } catch (const std::exception &e) { @@ -1646,7 +1646,7 @@ NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name) { if (file) { pj_log(ctx, PJ_LOG_DEBUG_MAJOR, "Using %s", remote_file.c_str()); - pj_ctx_set_errno(ctx, 0); + proj_context_errno_set(ctx, 0); } } } diff --git a/src/gauss.cpp b/src/gauss.cpp index 54dff5a8..96bd5166 100644 --- a/src/gauss.cpp +++ b/src/gauss.cpp @@ -109,6 +109,6 @@ PJ_LP pj_inv_gauss(PJ_CONTEXT *ctx, PJ_LP slp, const void *data) { } /* convergence failed */ if (!i) - pj_ctx_set_errno(ctx, PJD_ERR_NON_CONV_INV_MERI_DIST); + proj_context_errno_set(ctx, PJD_ERR_NON_CONV_INV_MERI_DIST); return (elp); } diff --git a/src/generic_inverse.cpp b/src/generic_inverse.cpp index a15cfae1..ddd5060b 100644 --- a/src/generic_inverse.cpp +++ b/src/generic_inverse.cpp @@ -109,6 +109,6 @@ PJ_LP pj_generic_inverse_2d(PJ_XY xy, PJ *P, PJ_LP lpInitial) { lp.phi = M_HALFPI; } } - pj_ctx_set_errno(P->ctx, PJD_ERR_NON_CONVERGENT); + proj_context_errno_set(P->ctx, PJD_ERR_NON_CONVERGENT); return lp; } diff --git a/src/grids.cpp b/src/grids.cpp index 8c1bc4cc..671485d7 100644 --- a/src/grids.cpp +++ b/src/grids.cpp @@ -197,7 +197,7 @@ GTXVerticalShiftGrid *GTXVerticalShiftGrid::open(PJ_CONTEXT *ctx, /* Read the header. */ /* -------------------------------------------------------------------- */ if (fp->read(header, sizeof(header)) != sizeof(header)) { - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } @@ -223,7 +223,7 @@ GTXVerticalShiftGrid *GTXVerticalShiftGrid::open(PJ_CONTEXT *ctx, if (xorigin < -360 || xorigin > 360 || yorigin < -90 || yorigin > 90) { pj_log(ctx, PJ_LOG_ERROR, "gtx file header has invalid extents, corrupt?"); - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } @@ -258,7 +258,7 @@ bool GTXVerticalShiftGrid::valueAt(int x, int y, float &out) const { m_fp->seek(40 + sizeof(float) * (y * m_width + x)); if (m_fp->read(&out, sizeof(out)) != sizeof(out)) { - pj_ctx_set_errno(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return false; } if (IS_LSB) { @@ -1389,7 +1389,7 @@ VerticalShiftGridSet::open(PJ_CONTEXT *ctx, const std::string &filename) { auto set = std::unique_ptr( GTiffVGridShiftSet::open(ctx, std::move(fp), actualName)); if (!set) - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return set; #else pj_log(ctx, PJ_LOG_ERROR, @@ -1570,7 +1570,7 @@ NTv1Grid *NTv1Grid::open(PJ_CONTEXT *ctx, std::unique_ptr fp, /* Read the header. */ /* -------------------------------------------------------------------- */ if (fp->read(header, sizeof(header)) != sizeof(header)) { - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } @@ -1590,7 +1590,7 @@ NTv1Grid *NTv1Grid::open(PJ_CONTEXT *ctx, std::unique_ptr fp, if (*((int *)(header + 8)) != 12) { pj_log(ctx, PJ_LOG_ERROR, "NTv1 grid shift file has wrong record count, corrupt?"); - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } @@ -1609,7 +1609,7 @@ NTv1Grid *NTv1Grid::open(PJ_CONTEXT *ctx, std::unique_ptr fp, extent.resY > 1e-10)) { pj_log(ctx, PJ_LOG_ERROR, "Inconsistent georeferencing for %s", filename.c_str()); - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } const int columns = static_cast( @@ -1631,7 +1631,7 @@ bool NTv1Grid::valueAt(int x, int y, bool compensateNTConvention, m_fp->seek(192 + 2 * sizeof(double) * (y * m_width + m_width - 1 - x)); if (m_fp->read(&two_doubles[0], sizeof(two_doubles)) != sizeof(two_doubles)) { - pj_ctx_set_errno(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return false; } if (IS_LSB) { @@ -1692,7 +1692,7 @@ CTable2Grid *CTable2Grid::open(PJ_CONTEXT *ctx, std::unique_ptr fp, /* Read the header. */ /* -------------------------------------------------------------------- */ if (fp->read(header, sizeof(header)) != sizeof(header)) { - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } @@ -1718,7 +1718,7 @@ CTable2Grid *CTable2Grid::open(PJ_CONTEXT *ctx, std::unique_ptr fp, extent.resX > 1e-10 && extent.resY > 1e-10)) { pj_log(ctx, PJ_LOG_ERROR, "Inconsistent georeferencing for %s", filename.c_str()); - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } int width; @@ -1726,7 +1726,7 @@ CTable2Grid *CTable2Grid::open(PJ_CONTEXT *ctx, std::unique_ptr fp, memcpy(&width, header + 128, 4); memcpy(&height, header + 132, 4); if (width <= 0 || height <= 0) { - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } extent.east = extent.west + (width - 1) * extent.resX; @@ -1744,7 +1744,7 @@ bool CTable2Grid::valueAt(int x, int y, bool compensateNTConvention, float two_floats[2]; m_fp->seek(160 + 2 * sizeof(float) * (y * m_width + x)); if (m_fp->read(&two_floats[0], sizeof(two_floats)) != sizeof(two_floats)) { - pj_ctx_set_errno(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return false; } if (!IS_LSB) { @@ -1828,7 +1828,7 @@ bool NTv2Grid::valueAt(int x, int y, bool compensateNTConvention, 4 * sizeof(float) * (static_cast(y) * m_width + m_width - 1 - x)); if (m_fp->read(&two_float[0], sizeof(two_float)) != sizeof(two_float)) { - pj_ctx_set_errno(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(m_ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return false; } if (m_mustSwap) { @@ -1862,14 +1862,14 @@ std::unique_ptr NTv2GridSet::open(PJ_CONTEXT *ctx, /* Read the header. */ /* -------------------------------------------------------------------- */ if (fpRaw->read(header, sizeof(header)) != sizeof(header)) { - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } constexpr int OFFSET_GS_TYPE = 56; if (memcmp(header + OFFSET_GS_TYPE, "SECONDS", 7) != 0) { pj_log(ctx, PJ_LOG_ERROR, "Only GS_TYPE=SECONDS is supported"); - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } @@ -1899,12 +1899,12 @@ std::unique_ptr NTv2GridSet::open(PJ_CONTEXT *ctx, for (unsigned subfile = 0; subfile < num_subfiles; subfile++) { // Read header if (fpRaw->read(header, sizeof(header)) != sizeof(header)) { - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } if (strncmp(header, "SUB_NAME", 8) != 0) { - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } @@ -1946,7 +1946,7 @@ std::unique_ptr NTv2GridSet::open(PJ_CONTEXT *ctx, extent.resY > 1e-10)) { pj_log(ctx, PJ_LOG_ERROR, "Inconsistent georeferencing for %s", filename.c_str()); - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } const int columns = static_cast( @@ -1966,7 +1966,7 @@ std::unique_ptr NTv2GridSet::open(PJ_CONTEXT *ctx, pj_log(ctx, PJ_LOG_ERROR, "GS_COUNT(%u) does not match expected cells (%dx%d)", gs_count, columns, rows); - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return nullptr; } @@ -2367,7 +2367,7 @@ HorizontalShiftGridSet::open(PJ_CONTEXT *ctx, const std::string &filename) { auto set = std::unique_ptr( GTiffHGridShiftSet::open(ctx, std::move(fp), actualName)); if (!set) - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return set; #else pj_log(ctx, PJ_LOG_ERROR, @@ -2703,7 +2703,7 @@ GenericShiftGridSet::open(PJ_CONTEXT *ctx, const std::string &filename) { auto set = std::unique_ptr( GTiffGenericGridShiftSet::open(ctx, std::move(fp), actualName)); if (!set) - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return set; #else pj_log(ctx, PJ_LOG_ERROR, @@ -2786,11 +2786,11 @@ ListOfGenericGrids pj_generic_grid_init(PJ *P, const char *gridkey) { if (!gridSet) { if (!canFail) { if (proj_context_errno(P->ctx) != PJD_ERR_NETWORK_ERROR) { - pj_ctx_set_errno(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID); } return {}; } - pj_ctx_set_errno(P->ctx, 0); // don't treat as a persistent error + proj_context_errno_set(P->ctx, 0); // don't treat as a persistent error } else { grids.emplace_back(std::move(gridSet)); } @@ -2830,11 +2830,11 @@ static ListOfHGrids getListOfGridSets(PJ_CONTEXT *ctx, const char *grids) { if (!gridSet) { if (!canFail) { if (proj_context_errno(ctx) != PJD_ERR_NETWORK_ERROR) { - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); } return {}; } - pj_ctx_set_errno(ctx, 0); // don't treat as a persistent error + proj_context_errno_set(ctx, 0); // don't treat as a persistent error } else { list.emplace_back(std::move(gridSet)); } @@ -3066,7 +3066,7 @@ PJ_LP pj_hgrid_apply(PJ_CONTEXT *ctx, const ListOfHGrids &grids, PJ_LP lp, HorizontalShiftGridSet *gridset = nullptr; const auto grid = findGrid(grids, lp, gridset); if (!grid) { - pj_ctx_set_errno(ctx, PJD_ERR_GRID_AREA); + proj_context_errno_set(ctx, PJD_ERR_GRID_AREA); return out; } if (grid->isNullGrid()) { @@ -3082,7 +3082,7 @@ PJ_LP pj_hgrid_apply(PJ_CONTEXT *ctx, const ListOfHGrids &grids, PJ_LP lp, } if (out.lam == HUGE_VAL || out.phi == HUGE_VAL) - pj_ctx_set_errno(ctx, PJD_ERR_GRID_AREA); + proj_context_errno_set(ctx, PJD_ERR_GRID_AREA); return out; } @@ -3098,7 +3098,7 @@ PJ_LP pj_hgrid_value(PJ *P, const ListOfHGrids &grids, PJ_LP lp) { HorizontalShiftGridSet *gridset = nullptr; const auto grid = findGrid(grids, lp, gridset); if (!grid) { - pj_ctx_set_errno(P->ctx, PJD_ERR_GRID_AREA); + proj_context_errno_set(P->ctx, PJD_ERR_GRID_AREA); return out; } @@ -3107,7 +3107,7 @@ PJ_LP pj_hgrid_value(PJ *P, const ListOfHGrids &grids, PJ_LP lp) { if (!extent.isGeographic) { pj_log(P->ctx, PJ_LOG_ERROR, "Can only handle grids referenced in a geographic CRS"); - pj_ctx_set_errno(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return out; } @@ -3130,7 +3130,7 @@ PJ_LP pj_hgrid_value(PJ *P, const ListOfHGrids &grids, PJ_LP lp) { } if (out.lam == HUGE_VAL || out.phi == HUGE_VAL) { - pj_ctx_set_errno(P->ctx, PJD_ERR_GRID_AREA); + proj_context_errno_set(P->ctx, PJD_ERR_GRID_AREA); } return out; @@ -3157,7 +3157,7 @@ static double read_vgrid_value(PJ_CONTEXT *ctx, const ListOfVGrids &grids, } } if (!grid) { - pj_ctx_set_errno(ctx, PJD_ERR_GRID_AREA); + proj_context_errno_set(ctx, PJD_ERR_GRID_AREA); return HUGE_VAL; } if (grid->isNullGrid()) { @@ -3168,7 +3168,7 @@ static double read_vgrid_value(PJ_CONTEXT *ctx, const ListOfVGrids &grids, if (!extent.isGeographic) { pj_log(ctx, PJ_LOG_ERROR, "Can only handle grids referenced in a geographic CRS"); - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return HUGE_VAL; } @@ -3200,7 +3200,7 @@ static double read_vgrid_value(PJ_CONTEXT *ctx, const ListOfVGrids &grids, if (!(grid_ix >= 0 && grid_ix < grid->width())) { // in the unlikely case we end up here... pj_log(ctx, PJ_LOG_ERROR, "grid_ix not in grid"); - pj_ctx_set_errno(ctx, PJD_ERR_GRID_AREA); + proj_context_errno_set(ctx, PJD_ERR_GRID_AREA); return HUGE_VAL; } int grid_iy = static_cast(lround(floor(grid_y))); @@ -3309,11 +3309,11 @@ ListOfVGrids pj_vgrid_init(PJ *P, const char *gridkey) { if (!gridSet) { if (!canFail) { if (proj_context_errno(P->ctx) != PJD_ERR_NETWORK_ERROR) { - pj_ctx_set_errno(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID); } return {}; } - pj_ctx_set_errno(P->ctx, 0); // don't treat as a persistent error + proj_context_errno_set(P->ctx, 0); // don't treat as a persistent error } else { grids.emplace_back(std::move(gridSet)); } @@ -3377,7 +3377,7 @@ bool pj_bilinear_interpolation_three_samples( if (!extent.isGeographic) { pj_log(ctx, PJ_LOG_ERROR, "Can only handle grids referenced in a geographic CRS"); - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return false; } @@ -3459,7 +3459,7 @@ int pj_apply_gridshift(PJ_CONTEXT *ctx, const char *nadgrids, int inverse, { auto hgrids = NS_PROJ::getListOfGridSets(ctx, nadgrids); if (hgrids.empty()) { - pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); return 1; } diff --git a/src/init.cpp b/src/init.cpp index a42bf963..2d679618 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -257,7 +257,7 @@ Expand key from buffer or (if not in buffer) from init file PJ* src; const char* proj_string; - pj_ctx_set_errno( ctx, 0 ); + proj_context_errno_set( ctx, 0 ); if( !allow_init_epsg ) { pj_log (ctx, PJ_LOG_TRACE, "%s expansion disallowed", xkey); @@ -448,7 +448,7 @@ pj_init_plus_ctx( PJ_CONTEXT *ctx, const char *definition ) if( argc+1 == MAX_ARG ) { pj_dalloc( defn_copy ); - pj_ctx_set_errno( ctx, PJD_ERR_UNPARSEABLE_CS_DEF ); + proj_context_errno_set( ctx, PJD_ERR_UNPARSEABLE_CS_DEF ); return nullptr; } @@ -538,7 +538,7 @@ pj_init_ctx_with_allow_init_epsg(PJ_CONTEXT *ctx, int argc, char **argv, int all ctx->last_errno = 0; if (argc <= 0) { - pj_ctx_set_errno (ctx, PJD_ERR_NO_ARGS); + proj_context_errno_set (ctx, PJD_ERR_NO_ARGS); return nullptr; } @@ -552,13 +552,13 @@ pj_init_ctx_with_allow_init_epsg(PJ_CONTEXT *ctx, int argc, char **argv, int all /* can't have nested pipelines directly */ if (n_pipelines > 1) { - pj_ctx_set_errno (ctx, PJD_ERR_MALFORMED_PIPELINE); + proj_context_errno_set (ctx, PJD_ERR_MALFORMED_PIPELINE); return nullptr; } /* don't allow more than one +init in non-pipeline operations */ if (n_pipelines == 0 && n_inits > 1) { - pj_ctx_set_errno (ctx, PJD_ERR_TOO_MANY_INITS); + proj_context_errno_set (ctx, PJD_ERR_TOO_MANY_INITS); return nullptr; } diff --git a/src/internal.cpp b/src/internal.cpp index 32dc1bba..c1ffc408 100644 --- a/src/internal.cpp +++ b/src/internal.cpp @@ -141,15 +141,15 @@ Check if a a PJ has an inverse. void proj_context_set (PJ *P, PJ_CONTEXT *ctx) { if (nullptr==ctx) ctx = pj_get_default_ctx (); - pj_set_ctx (P, ctx); + proj_assign_context (P, ctx); } void proj_context_inherit (PJ *parent, PJ *child) { if (nullptr==parent) - pj_set_ctx (child, pj_get_default_ctx()); + proj_assign_context (child, pj_get_default_ctx()); else - pj_set_ctx (child, pj_get_ctx(parent)); + proj_assign_context (child, pj_get_ctx(parent)); } @@ -411,7 +411,11 @@ to that context. ******************************************************************************/ if (nullptr==ctx) ctx = pj_get_default_ctx(); - pj_ctx_set_errno (ctx, err); + ctx->last_errno = err; + if( err == 0 ) + return; + errno = err; + pj_errno = err; } /* logging */ diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index cbbdcaa8..d6308c49 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -79,10 +79,10 @@ static void PROJ_NO_INLINE proj_log_error(PJ_CONTEXT *ctx, const char *function, msg += ": "; msg += text; ctx->logger(ctx->logger_app_data, PJ_LOG_ERROR, msg.c_str()); - auto previous_errno = pj_ctx_get_errno(ctx); + auto previous_errno = proj_context_errno(ctx); if (previous_errno == 0) { // only set errno if it wasn't set deeper down the call stack - pj_ctx_set_errno(ctx, PJD_ERR_GENERIC_ERROR); + proj_context_errno_set(ctx, PJD_ERR_GENERIC_ERROR); } } diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 4d7e78d3..60244779 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -417,7 +417,7 @@ std::string PrimeMeridian::getPROJStringWellKnownName(const common::Angle &angle) { const double valRad = angle.getSIValue(); std::string projPMName; - PJ_CONTEXT *ctxt = pj_ctx_alloc(); + PJ_CONTEXT *ctxt = proj_context_create(); auto proj_pm = proj_list_prime_meridians(); for (int i = 0; proj_pm[i].id != nullptr; ++i) { double valRefRad = dmstor_ctx(ctxt, proj_pm[i].defn, nullptr); @@ -426,7 +426,7 @@ PrimeMeridian::getPROJStringWellKnownName(const common::Angle &angle) { break; } } - pj_ctx_free(ctxt); + proj_context_destroy(ctxt); return projPMName; } //! @endcond diff --git a/src/malloc.cpp b/src/malloc.cpp index eb64023f..b1bcea1d 100644 --- a/src/malloc.cpp +++ b/src/malloc.cpp @@ -166,7 +166,7 @@ void *pj_dealloc_params (PJ_CONTEXT *ctx, paralist *start, int errlev) { n = t->next; pj_dealloc(t); } - pj_ctx_set_errno (ctx, errlev); + proj_context_errno_set (ctx, errlev); return (void *) nullptr; } @@ -218,7 +218,7 @@ PJ *pj_default_destructor (PJ *P, int errlev) { /* Destructor */ /* Note that both, in the multithreaded case, may then contain undefined */ /* values. This is expected behavior. For MT have one ctx per thread */ if (0!=errlev) - pj_ctx_set_errno (pj_get_ctx(P), errlev); + proj_context_errno_set (pj_get_ctx(P), errlev); if (nullptr==P) return nullptr; diff --git a/src/mlfn.hpp b/src/mlfn.hpp index e7138c63..228c65a4 100644 --- a/src/mlfn.hpp +++ b/src/mlfn.hpp @@ -66,7 +66,7 @@ inline_pj_inv_mlfn(PJ_CONTEXT *ctx, double arg, double es, const double *en, } *sinphi = s; *cosphi = c; - pj_ctx_set_errno( ctx, PJD_ERR_NON_CONV_INV_MERI_DIST ); + proj_context_errno_set( ctx, PJD_ERR_NON_CONV_INV_MERI_DIST ); return phi; } diff --git a/src/networkfilemanager.cpp b/src/networkfilemanager.cpp index f6521ed2..9edffaad 100644 --- a/src/networkfilemanager.cpp +++ b/src/networkfilemanager.cpp @@ -1315,7 +1315,7 @@ std::unique_ptr NetworkFile::open(PJ_CONTEXT *ctx, const char *filename) { errorBuffer.resize(strlen(errorBuffer.data())); pj_log(ctx, PJ_LOG_ERROR, "Cannot open %s: %s", filename, errorBuffer.c_str()); - pj_ctx_set_errno(ctx, PJD_ERR_NETWORK_ERROR); + proj_context_errno_set(ctx, PJD_ERR_NETWORK_ERROR); } bool ok = false; @@ -1404,7 +1404,7 @@ size_t NetworkFile::read(void *buffer, size_t sizeBytes) { &nRead, errorBuffer.size(), &errorBuffer[0], m_ctx->networking.user_data); if (!m_handle) { - pj_ctx_set_errno(m_ctx, PJD_ERR_NETWORK_ERROR); + proj_context_errno_set(m_ctx, PJD_ERR_NETWORK_ERROR); return 0; } } else { @@ -1420,7 +1420,7 @@ size_t NetworkFile::read(void *buffer, size_t sizeBytes) { pj_log(m_ctx, PJ_LOG_ERROR, "Cannot read in %s: %s", m_url.c_str(), errorBuffer.c_str()); } - pj_ctx_set_errno(m_ctx, PJD_ERR_NETWORK_ERROR); + proj_context_errno_set(m_ctx, PJD_ERR_NETWORK_ERROR); return 0; } diff --git a/src/param.cpp b/src/param.cpp index 9a3888e1..3e13b391 100644 --- a/src/param.cpp +++ b/src/param.cpp @@ -220,7 +220,7 @@ PROJVALUE pj_param (PJ_CONTEXT *ctx, paralist *pl, const char *opt) { value.i = 1; break; default: - pj_ctx_set_errno (ctx, PJD_ERR_INVALID_BOOLEAN_PARAM); + proj_context_errno_set (ctx, PJD_ERR_INVALID_BOOLEAN_PARAM); value.i = 0; break; } diff --git a/src/phi2.cpp b/src/phi2.cpp index 214d1058..2f258e47 100644 --- a/src/phi2.cpp +++ b/src/phi2.cpp @@ -103,7 +103,7 @@ double pj_sinhpsi2tanphi(PJ_CONTEXT *ctx, const double taup, const double e) { break; } if (i == 0) - pj_ctx_set_errno(ctx, PJD_ERR_NON_CONV_SINHPSI2TANPHI); + proj_context_errno_set(ctx, PJD_ERR_NON_CONV_SINHPSI2TANPHI); return tau; } diff --git a/src/proj_internal.h b/src/proj_internal.h index 3c1571eb..d9b01ab2 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -976,16 +976,6 @@ void PROJ_DLL pj_acquire_lock(void); void PROJ_DLL pj_release_lock(void); void PROJ_DLL pj_cleanup_lock(void); -void PROJ_DLL pj_set_ctx( PJ *, PJ_CONTEXT * ); -PJ_CONTEXT PROJ_DLL *pj_ctx_alloc(void); -void PROJ_DLL pj_ctx_free( PJ_CONTEXT * ); -int PROJ_DLL pj_ctx_get_errno( PJ_CONTEXT * ); -void PROJ_DLL pj_ctx_set_errno( PJ_CONTEXT *, int ); -void PROJ_DLL pj_ctx_set_debug( PJ_CONTEXT *, int ); -void PROJ_DLL pj_ctx_set_logger( PJ_CONTEXT *, void (*)(void *, int, const char *) ); -void PROJ_DLL pj_ctx_set_app_data( PJ_CONTEXT *, void * ); -void PROJ_DLL *pj_ctx_get_app_data( PJ_CONTEXT * ); - void PROJ_DLL pj_log( PJ_CONTEXT * ctx, int level, const char *fmt, ... ); void PROJ_DLL pj_stderr_logger( void *, int, const char * ); diff --git a/src/proj_mdist.cpp b/src/proj_mdist.cpp index 086521b7..ed07ffd1 100644 --- a/src/proj_mdist.cpp +++ b/src/proj_mdist.cpp @@ -124,6 +124,6 @@ proj_inv_mdist(PJ_CONTEXT *ctx, double dist, const void *data) { return phi; } /* convergence failed */ - pj_ctx_set_errno(ctx, PJD_ERR_NON_CONV_INV_MERI_DIST); + proj_context_errno_set(ctx, PJD_ERR_NON_CONV_INV_MERI_DIST); return phi; } diff --git a/src/projections/aitoff.cpp b/src/projections/aitoff.cpp index 7920309c..d02e7761 100644 --- a/src/projections/aitoff.cpp +++ b/src/projections/aitoff.cpp @@ -170,7 +170,7 @@ static PJ_LP aitoff_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inver if (iter == MAXITER && round == MAXROUND) { - pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT ); + proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT ); /* fprintf(stderr, "Warning: Accuracy of 1e-12 not reached. Last increments: dlat=%e and dlon=%e\n", dp, dl); */ } diff --git a/src/projections/comill.cpp b/src/projections/comill.cpp index 189e583e..44524990 100644 --- a/src/projections/comill.cpp +++ b/src/projections/comill.cpp @@ -66,7 +66,7 @@ static PJ_LP comill_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inver } } if( i == 0 ) - pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT ); + proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT ); lp.phi = yc; /* longitude */ diff --git a/src/projections/eqearth.cpp b/src/projections/eqearth.cpp index 832c9444..60effde0 100644 --- a/src/projections/eqearth.cpp +++ b/src/projections/eqearth.cpp @@ -110,7 +110,7 @@ static PJ_LP eqearth_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal/sphe } if( i == 0 ) { - pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT ); + proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT ); return lp; } diff --git a/src/projections/healpix.cpp b/src/projections/healpix.cpp index aab5c41e..5a06125d 100644 --- a/src/projections/healpix.cpp +++ b/src/projections/healpix.cpp @@ -524,7 +524,7 @@ static PJ_LP s_healpix_inverse(PJ_XY xy, PJ *P) { /* sphere */ PJ_LP lp; lp.lam = HUGE_VAL; lp.phi = HUGE_VAL; - pj_ctx_set_errno(P->ctx, PJD_ERR_INVALID_X_OR_Y); + proj_context_errno_set(P->ctx, PJD_ERR_INVALID_X_OR_Y); return lp; } return healpix_spherhealpix_e_inverse(xy); @@ -540,7 +540,7 @@ static PJ_LP e_healpix_inverse(PJ_XY xy, PJ *P) { /* ellipsoid */ if (in_image(xy.x, xy.y, 0, 0, 0) == 0) { lp.lam = HUGE_VAL; lp.phi = HUGE_VAL; - pj_ctx_set_errno(P->ctx, PJD_ERR_INVALID_X_OR_Y); + proj_context_errno_set(P->ctx, PJD_ERR_INVALID_X_OR_Y); return lp; } lp = healpix_spherhealpix_e_inverse(xy); @@ -574,7 +574,7 @@ static PJ_LP s_rhealpix_inverse(PJ_XY xy, PJ *P) { /* sphere */ PJ_LP lp; lp.lam = HUGE_VAL; lp.phi = HUGE_VAL; - pj_ctx_set_errno(P->ctx, PJD_ERR_INVALID_X_OR_Y); + proj_context_errno_set(P->ctx, PJD_ERR_INVALID_X_OR_Y); return lp; } xy = combine_caps(xy.x, xy.y, Q->north_square, Q->south_square, 1); @@ -590,7 +590,7 @@ static PJ_LP e_rhealpix_inverse(PJ_XY xy, PJ *P) { /* ellipsoid */ if (in_image(xy.x, xy.y, 1, Q->north_square, Q->south_square) == 0) { lp.lam = HUGE_VAL; lp.phi = HUGE_VAL; - pj_ctx_set_errno(P->ctx, PJD_ERR_INVALID_X_OR_Y); + proj_context_errno_set(P->ctx, PJD_ERR_INVALID_X_OR_Y); return lp; } xy = combine_caps(xy.x, xy.y, Q->north_square, Q->south_square, 1); diff --git a/src/projections/krovak.cpp b/src/projections/krovak.cpp index aef44d42..3e6a5c30 100644 --- a/src/projections/krovak.cpp +++ b/src/projections/krovak.cpp @@ -181,7 +181,7 @@ static PJ_LP krovak_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, fi1 = lp.phi; } if( i == 0 ) - pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT ); + proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT ); lp.lam -= P->lam0; diff --git a/src/projections/natearth.cpp b/src/projections/natearth.cpp index 5c096605..e1f71089 100644 --- a/src/projections/natearth.cpp +++ b/src/projections/natearth.cpp @@ -82,7 +82,7 @@ static PJ_LP natearth_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inv } } if( i == 0 ) - pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT ); + proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT ); lp.phi = yc; /* longitude */ diff --git a/src/projections/natearth2.cpp b/src/projections/natearth2.cpp index d149ca85..e4516a0a 100644 --- a/src/projections/natearth2.cpp +++ b/src/projections/natearth2.cpp @@ -76,7 +76,7 @@ static PJ_LP natearth2_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, in } } if( i == 0 ) - pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT ); + proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT ); lp.phi = yc; /* longitude */ diff --git a/src/projections/ortho.cpp b/src/projections/ortho.cpp index 8dcfb53c..d9c84dba 100644 --- a/src/projections/ortho.cpp +++ b/src/projections/ortho.cpp @@ -273,7 +273,7 @@ static PJ_LP ortho_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inver return lp; } } - pj_ctx_set_errno(P->ctx, PJD_ERR_NON_CONVERGENT); + proj_context_errno_set(P->ctx, PJD_ERR_NON_CONVERGENT); return lp; } diff --git a/src/projections/patterson.cpp b/src/projections/patterson.cpp index 71099cdb..32544580 100644 --- a/src/projections/patterson.cpp +++ b/src/projections/patterson.cpp @@ -100,7 +100,7 @@ static PJ_LP patterson_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, in } } if( i == 0 ) - pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT ); + proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT ); lp.phi = yc; /* longitude */ diff --git a/src/projections/robin.cpp b/src/projections/robin.cpp index 8b646502..6a1405b6 100644 --- a/src/projections/robin.cpp +++ b/src/projections/robin.cpp @@ -138,7 +138,7 @@ static PJ_LP robin_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers break; } if( iters == 0 ) - pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT ); + proj_context_errno_set( P->ctx, PJD_ERR_NON_CONVERGENT ); lp.phi = (5 * i + t) * DEG_TO_RAD; if (xy.y < 0.) lp.phi = -lp.phi; lp.lam /= V(X[i], t); diff --git a/src/projections/tmerc.cpp b/src/projections/tmerc.cpp index 69f4d352..ff1bc2a5 100644 --- a/src/projections/tmerc.cpp +++ b/src/projections/tmerc.cpp @@ -89,7 +89,7 @@ static PJ_XY approx_e_fwd (PJ_LP lp, PJ *P) if( lp.lam < -M_HALFPI || lp.lam > M_HALFPI ) { xy.x = HUGE_VAL; xy.y = HUGE_VAL; - pj_ctx_set_errno( P->ctx, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT ); + proj_context_errno_set( P->ctx, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT ); return xy; } @@ -130,7 +130,7 @@ static PJ_XY approx_s_fwd (PJ_LP lp, PJ *P) { if( lp.lam < -M_HALFPI || lp.lam > M_HALFPI ) { xy.x = HUGE_VAL; xy.y = HUGE_VAL; - pj_ctx_set_errno( P->ctx, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT ); + proj_context_errno_set( P->ctx, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT ); return xy; } @@ -679,7 +679,7 @@ static bool getAlgoFromParams(PJ* P, TMercAlgo& algo) else { pj_load_ini(P->ctx); // if not already done - pj_ctx_set_errno(P->ctx, 0); // reset error in case proj.ini couldn't be found + proj_context_errno_set(P->ctx, 0); // reset error in case proj.ini couldn't be found algo = P->ctx->defaultTmercAlgo; } diff --git a/src/utils.cpp b/src/utils.cpp index d3ec7e35..82449617 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -117,7 +117,7 @@ PJ *pj_latlong_from_proj( PJ *pj_in ) } else { - pj_ctx_set_errno( pj_in->ctx, PJD_ERR_MAJOR_AXIS_NOT_GIVEN ); + proj_context_errno_set( pj_in->ctx, PJD_ERR_MAJOR_AXIS_NOT_GIVEN ); return nullptr; } -- cgit v1.2.3 From 8e13c3acd86d1705ed865093f000835b51aec63e Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Tue, 17 Nov 2020 21:34:13 +0100 Subject: Removed unused functions from src/utils.cpp --- src/Makefile.am | 1 - src/lib_proj.cmake | 1 - src/proj_internal.h | 4 -- src/utils.cpp | 182 ---------------------------------------------------- 4 files changed, 188 deletions(-) delete mode 100644 src/utils.cpp (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 2c175e42..e394b95b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -220,7 +220,6 @@ libproj_la_SOURCES = \ quadtree.hpp \ \ datums.cpp datum_set.cpp \ - utils.cpp \ mutex.cpp initcache.cpp geodesic.c \ strtod.cpp \ \ diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 997eb22d..1361294d 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -247,7 +247,6 @@ set(SRC_LIBPROJ_CORE strtod.cpp tsfn.cpp units.cpp - utils.cpp wkt1_generated_parser.c wkt1_generated_parser.h wkt1_parser.cpp diff --git a/src/proj_internal.h b/src/proj_internal.h index d9b01ab2..e83c6f88 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -948,9 +948,6 @@ int PROJ_DLL pj_apply_gridshift( PJ_CONTEXT *, const char *, int, long point_count, int point_offset, double *x, double *y, double *z ); void PROJ_DLL pj_clear_initcache(void); -int PROJ_DLL pj_is_latlong(PJ *); -int PROJ_DLL pj_is_geocent(PJ *); -void PROJ_DLL pj_get_spheroid_defn(PJ *defn, double *major_axis, double *eccentricity_squared); void PROJ_DLL pj_pr_list(PJ *); void PROJ_DLL pj_free(PJ *); void PROJ_DLL pj_set_finder( const char *(*)(const char *) ); @@ -960,7 +957,6 @@ PJ PROJ_DLL *pj_init_plus(const char *); PJ PROJ_DLL *pj_init_ctx( PJ_CONTEXT *, int, char ** ); PJ PROJ_DLL *pj_init_plus_ctx( PJ_CONTEXT *, const char * ); char PROJ_DLL *pj_get_def(PJ *, int); -PJ PROJ_DLL *pj_latlong_from_proj( PJ *); int PROJ_DLL pj_has_inverse(PJ *); diff --git a/src/utils.cpp b/src/utils.cpp deleted file mode 100644 index 82449617..00000000 --- a/src/utils.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/****************************************************************************** - * Project: PROJ.4 - * Purpose: Some utility functions we don't want to bother putting in - * their own source files. - * Author: Frank Warmerdam, warmerdam@pobox.com - * - ****************************************************************************** - * Copyright (c) 2001, 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. - *****************************************************************************/ - -#define PJ_LIB__ - -#include -#include - -#include "proj.h" -#include "proj_internal.h" - -/************************************************************************/ -/* pj_is_latlong() */ -/* */ -/* Returns TRUE if this coordinate system object is */ -/* geographic. */ -/************************************************************************/ - -int pj_is_latlong( PJ *pj ) - -{ - return pj == nullptr || pj->is_latlong; -} - -/************************************************************************/ -/* pj_is_geocent() */ -/* */ -/* Returns TRUE if this coordinate system object is geocentric. */ -/************************************************************************/ - -int pj_is_geocent( PJ *pj ) - -{ - return pj != nullptr && pj->is_geocent; -} - -/************************************************************************/ -/* pj_latlong_from_proj() */ -/* */ -/* Return a PJ* definition defining the lat/long coordinate */ -/* system on which a projection is based. If the coordinate */ -/* system passed in is latlong, a clone of the same will be */ -/* returned. */ -/************************************************************************/ - -PJ *pj_latlong_from_proj( PJ *pj_in ) - -{ - char defn[512]; - int got_datum = FALSE; - - pj_errno = 0; - strcpy( defn, "+proj=latlong" ); - - if( pj_param(pj_in->ctx, pj_in->params, "tdatum").i ) - { - got_datum = TRUE; - sprintf( defn+strlen(defn), " +datum=%s", - pj_param(pj_in->ctx, pj_in->params,"sdatum").s ); - } - else if( pj_param(pj_in->ctx, pj_in->params, "tellps").i ) - { - sprintf( defn+strlen(defn), " +ellps=%s", - pj_param(pj_in->ctx, pj_in->params,"sellps").s ); - } - else if( pj_param(pj_in->ctx,pj_in->params, "ta").i ) - { - sprintf( defn+strlen(defn), " +a=%s", - pj_param(pj_in->ctx,pj_in->params,"sa").s ); - - if( pj_param(pj_in->ctx,pj_in->params, "tb").i ) - sprintf( defn+strlen(defn), " +b=%s", - pj_param(pj_in->ctx,pj_in->params,"sb").s ); - else if( pj_param(pj_in->ctx,pj_in->params, "tes").i ) - sprintf( defn+strlen(defn), " +es=%s", - pj_param(pj_in->ctx,pj_in->params,"ses").s ); - else if( pj_param(pj_in->ctx,pj_in->params, "tf").i ) - sprintf( defn+strlen(defn), " +f=%s", - pj_param(pj_in->ctx,pj_in->params,"sf").s ); - else - { - char* ptr = defn+strlen(defn); - sprintf( ptr, " +es=%.16g", pj_in->es ); - /* TODO later: use C++ ostringstream with imbue(std::locale::classic()) */ - /* to be locale unaware */ - for(; *ptr; ptr++) - { - if( *ptr == ',' ) - *ptr = '.'; - } - } - } - else - { - proj_context_errno_set( pj_in->ctx, PJD_ERR_MAJOR_AXIS_NOT_GIVEN ); - - return nullptr; - } - - if( !got_datum ) - { - if( pj_param(pj_in->ctx,pj_in->params, "ttowgs84").i ) - sprintf( defn+strlen(defn), " +towgs84=%s", - pj_param(pj_in->ctx,pj_in->params,"stowgs84").s ); - - if( pj_param(pj_in->ctx,pj_in->params, "tnadgrids").i ) - sprintf( defn+strlen(defn), " +nadgrids=%s", - pj_param(pj_in->ctx,pj_in->params,"snadgrids").s ); - } - - /* copy over some other information related to ellipsoid */ - if( pj_param(pj_in->ctx,pj_in->params, "tR").i ) - sprintf( defn+strlen(defn), " +R=%s", - pj_param(pj_in->ctx,pj_in->params,"sR").s ); - - if( pj_param(pj_in->ctx,pj_in->params, "tR_A").i ) - sprintf( defn+strlen(defn), " +R_A" ); - - if( pj_param(pj_in->ctx,pj_in->params, "tR_V").i ) - sprintf( defn+strlen(defn), " +R_V" ); - - if( pj_param(pj_in->ctx,pj_in->params, "tR_a").i ) - sprintf( defn+strlen(defn), " +R_a" ); - - if( pj_param(pj_in->ctx,pj_in->params, "tR_lat_a").i ) - sprintf( defn+strlen(defn), " +R_lat_a=%s", - pj_param(pj_in->ctx,pj_in->params,"sR_lat_a").s ); - - if( pj_param(pj_in->ctx,pj_in->params, "tR_lat_g").i ) - sprintf( defn+strlen(defn), " +R_lat_g=%s", - pj_param(pj_in->ctx,pj_in->params,"sR_lat_g").s ); - - /* copy over prime meridian */ - if( pj_param(pj_in->ctx,pj_in->params, "tpm").i ) - sprintf( defn+strlen(defn), " +pm=%s", - pj_param(pj_in->ctx,pj_in->params,"spm").s ); - - return pj_init_plus_ctx( pj_in->ctx, defn ); -} - -/************************************************************************/ -/* pj_get_spheroid_defn() */ -/* */ -/* Fetch the internal definition of the spheroid. Note that */ -/* you can compute "b" from eccentricity_squared as: */ -/* */ -/* b = a * sqrt(1 - es) */ -/************************************************************************/ - -void pj_get_spheroid_defn(PJ * defn, double *major_axis, double *eccentricity_squared) -{ - if ( major_axis ) - *major_axis = defn->a; - - if ( eccentricity_squared ) - *eccentricity_squared = defn->es; -} -- cgit v1.2.3 From eb04ffca4c62d48378ff4c4ffe230de76d218b64 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Wed, 18 Nov 2020 09:16:34 +0100 Subject: Remove unused pj_apply_gridshift() --- src/grids.cpp | 46 ---------------------------------------------- src/proj_internal.h | 3 --- 2 files changed, 49 deletions(-) (limited to 'src') diff --git a/src/grids.cpp b/src/grids.cpp index 671485d7..8bb865d8 100644 --- a/src/grids.cpp +++ b/src/grids.cpp @@ -3443,49 +3443,3 @@ bool pj_bilinear_interpolation_three_samples( NS_PROJ_END -/************************************************************************/ -/* pj_apply_gridshift() */ -/* */ -/* This is the externally callable interface - part of the */ -/* public API - though it is not used internally any more and I */ -/* doubt it is used by any other applications. But we preserve */ -/* it to honour our public api. */ -/************************************************************************/ - -int pj_apply_gridshift(PJ_CONTEXT *ctx, const char *nadgrids, int inverse, - long point_count, int point_offset, double *x, double *y, - double * /*z */) - -{ - auto hgrids = NS_PROJ::getListOfGridSets(ctx, nadgrids); - if (hgrids.empty()) { - proj_context_errno_set(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); - return 1; - } - - for (long i = 0; i < point_count; i++) { - PJ_LP input; - - long io = i * point_offset; - input.phi = y[io]; - input.lam = x[io]; - - auto output = - pj_hgrid_apply(ctx, hgrids, input, inverse ? PJ_INV : PJ_FWD); - - if (output.lam != HUGE_VAL) { - y[io] = output.phi; - x[io] = output.lam; - } else { - if (ctx->debug_level >= PJ_LOG_DEBUG_MAJOR) { - pj_log(ctx, PJ_LOG_DEBUG_MAJOR, - "pj_apply_gridshift(): failed to find a grid shift " - "table for\n" - " location (%.7fdW,%.7fdN)", - x[io] * RAD_TO_DEG, y[io] * RAD_TO_DEG); - } - } - } - - return 0; -} diff --git a/src/proj_internal.h b/src/proj_internal.h index e83c6f88..2915284c 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -944,9 +944,6 @@ PJ_XYZ PROJ_DLL pj_fwd3d(PJ_LPZ, PJ *); PJ_LPZ PROJ_DLL pj_inv3d(PJ_XYZ, PJ *); -int PROJ_DLL pj_apply_gridshift( PJ_CONTEXT *, const char *, int, - long point_count, int point_offset, - double *x, double *y, double *z ); void PROJ_DLL pj_clear_initcache(void); void PROJ_DLL pj_pr_list(PJ *); void PROJ_DLL pj_free(PJ *); -- cgit v1.2.3 From ddb3b8da0756acbb8713aeb452de209eb350e996 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Wed, 18 Nov 2020 09:32:45 +0100 Subject: Removed unused function pj_set_searchpath() and pj_set_finder() --- src/ctx.cpp | 1 - src/filemanager.cpp | 30 ------------------------------ src/proj_internal.h | 2 -- 3 files changed, 33 deletions(-) (limited to 'src') diff --git a/src/ctx.cpp b/src/ctx.cpp index 8e25db2a..2093950b 100644 --- a/src/ctx.cpp +++ b/src/ctx.cpp @@ -163,7 +163,6 @@ pj_ctx::pj_ctx(const pj_ctx& other) : epsg_file_exists(other.epsg_file_exists), ca_bundle_path(other.ca_bundle_path), env_var_proj_lib(other.env_var_proj_lib), - file_finder_legacy(other.file_finder_legacy), file_finder(other.file_finder), file_finder_user_data(other.file_finder_user_data), custom_sqlite3_vfs_name(other.custom_sqlite3_vfs_name), diff --git a/src/filemanager.cpp b/src/filemanager.cpp index dbcb8ddc..b3b074a2 100644 --- a/src/filemanager.cpp +++ b/src/filemanager.cpp @@ -1418,10 +1418,6 @@ pj_open_lib_internal(PJ_CONTEXT *ctx, const char *name, const char *mode, ctx, name, ctx->file_finder_user_data)) != nullptr) ; - else if (ctx->file_finder_legacy != nullptr && - (sysname = ctx->file_finder_legacy(name)) != nullptr) - ; - /* The user has search paths set */ else if (!ctx->search_paths.empty()) { for (const auto &path : ctx->search_paths) { @@ -1795,19 +1791,6 @@ void pj_load_ini(PJ_CONTEXT *ctx) { //! @endcond -/************************************************************************/ -/* pj_set_finder() */ -/************************************************************************/ - -void pj_set_finder(const char *(*new_finder)(const char *)) - -{ - auto ctx = pj_get_default_ctx(); - if (ctx) { - ctx->file_finder_legacy = new_finder; - } -} - /************************************************************************/ /* proj_context_set_file_finder() */ /************************************************************************/ @@ -1878,19 +1861,6 @@ void proj_context_set_search_paths(PJ_CONTEXT *ctx, int count_paths, } } -/************************************************************************/ -/* pj_set_searchpath() */ -/* */ -/* Path control for callers that can't practically provide */ -/* pj_set_finder() style callbacks. Call with (0,NULL) as args */ -/* to clear the searchpath set. */ -/************************************************************************/ - -void pj_set_searchpath(int count, const char **path) { - proj_context_set_search_paths(nullptr, count, - const_cast(path)); -} - /************************************************************************/ /* proj_context_set_ca_bundle_path() */ /************************************************************************/ diff --git a/src/proj_internal.h b/src/proj_internal.h index 2915284c..24c9b653 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -947,8 +947,6 @@ PJ_LPZ PROJ_DLL pj_inv3d(PJ_XYZ, PJ *); void PROJ_DLL pj_clear_initcache(void); void PROJ_DLL pj_pr_list(PJ *); void PROJ_DLL pj_free(PJ *); -void PROJ_DLL pj_set_finder( const char *(*)(const char *) ); -void PROJ_DLL pj_set_searchpath ( int count, const char **path ); PJ PROJ_DLL *pj_init(int, char **); PJ PROJ_DLL *pj_init_plus(const char *); PJ PROJ_DLL *pj_init_ctx( PJ_CONTEXT *, int, char ** ); -- cgit v1.2.3 From 43efca4ab87fb37a0931edcb6be11c0bd3784098 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Wed, 18 Nov 2020 09:57:42 +0100 Subject: Remove pj_free() and move it's functional parts to proj_destroy() --- src/4D_api.cpp | 6 +----- src/apps/cct.cpp | 2 +- src/apps/proj.cpp | 2 +- src/init.cpp | 4 ++-- src/malloc.cpp | 19 ++++++++++--------- src/proj_internal.h | 1 - src/projections/goode.cpp | 4 ++-- 7 files changed, 17 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/4D_api.cpp b/src/4D_api.cpp index 70b04bf1..78e9bdc3 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -1353,10 +1353,6 @@ PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, cons return P; } -PJ *proj_destroy (PJ *P) { - pj_free (P); - return nullptr; -} /*****************************************************************************/ int proj_errno (const PJ *P) { @@ -1636,7 +1632,7 @@ PJ_PROJ_INFO proj_pj_info(PJ *P) { pjinfo.definition = empty; else pjinfo.definition = pj_shrink (def); - /* Make pj_free clean this up eventually */ + /* Make proj_destroy clean this up eventually */ P->def_full = def; pjinfo.has_inverse = pj_has_inverse(P); diff --git a/src/apps/cct.cpp b/src/apps/cct.cpp index fa75267a..e63a5fc2 100644 --- a/src/apps/cct.cpp +++ b/src/apps/cct.cpp @@ -387,7 +387,7 @@ int main(int argc, char **argv) { buf = static_cast(calloc (1, 10000)); if (nullptr==buf) { print (PJ_LOG_ERROR, "%s: Out of memory", o->progname); - pj_free (P); + proj_destroy (P); free (o); if (stdout != fout) fclose (fout); diff --git a/src/apps/proj.cpp b/src/apps/proj.cpp index c9bd8950..8bfd99a3 100644 --- a/src/apps/proj.cpp +++ b/src/apps/proj.cpp @@ -562,7 +562,7 @@ int main(int argc, char **argv) { } if( Proj ) - pj_free(Proj); + proj_destroy(Proj); exit(0); /* normal completion */ } diff --git a/src/init.cpp b/src/init.cpp index 2d679618..95bb404f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1,7 +1,7 @@ /****************************************************************************** * Project: PROJ.4 * Purpose: Initialize projection object from string definition. Includes - * pj_init(), pj_init_plus() and pj_free() function. + * pj_init(), and pj_init_plus() function. * Author: Gerald Evenden, Frank Warmerdam * ****************************************************************************** @@ -829,7 +829,7 @@ pj_init_ctx_with_allow_init_epsg(PJ_CONTEXT *ctx, int argc, char **argv, int all err = proj_errno_reset (PIN); PIN = proj(PIN); if (proj_errno (PIN)) { - pj_free(PIN); + proj_destroy(PIN); return nullptr; } proj_errno_restore (PIN, err); diff --git a/src/malloc.cpp b/src/malloc.cpp index b1bcea1d..590dd27f 100644 --- a/src/malloc.cpp +++ b/src/malloc.cpp @@ -174,7 +174,7 @@ void *pj_dealloc_params (PJ_CONTEXT *ctx, paralist *start, int errlev) { /************************************************************************/ -/* pj_free() */ +/* proj_destroy() */ /* */ /* This is the application callable entry point for destroying */ /* a projection definition. It does work generic to all */ @@ -183,15 +183,16 @@ void *pj_dealloc_params (PJ_CONTEXT *ctx, paralist *start, int errlev) { /* In most cases P->destructor()==pj_default_destructor. */ /************************************************************************/ -void pj_free(PJ *P) { +PJ *proj_destroy(PJ *P) { if (nullptr==P || !P->destructor) - return; + return nullptr; /* free projection parameters - all the hard work is done by */ /* pj_default_destructor, which is supposed */ /* to be called as the last step of the local destructor */ /* pointed to by P->destructor. In most cases, */ /* pj_default_destructor actually *is* what is pointed to */ P->destructor (P, proj_errno(P)); + return nullptr; } /*****************************************************************************/ @@ -246,12 +247,12 @@ PJ *pj_default_destructor (PJ *P, int errlev) { /* Destructor */ pj_dealloc (P->def_full); /* free the cs2cs emulation elements */ - pj_free (P->axisswap); - pj_free (P->helmert); - pj_free (P->cart); - pj_free (P->cart_wgs84); - pj_free (P->hgridshift); - pj_free (P->vgridshift); + proj_destroy (P->axisswap); + proj_destroy (P->helmert); + proj_destroy (P->cart); + proj_destroy (P->cart_wgs84); + proj_destroy (P->hgridshift); + proj_destroy (P->vgridshift); pj_dealloc (static_cast(P->opaque)); delete P; diff --git a/src/proj_internal.h b/src/proj_internal.h index 24c9b653..d57e87a2 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -946,7 +946,6 @@ PJ_LPZ PROJ_DLL pj_inv3d(PJ_XYZ, PJ *); void PROJ_DLL pj_clear_initcache(void); void PROJ_DLL pj_pr_list(PJ *); -void PROJ_DLL pj_free(PJ *); PJ PROJ_DLL *pj_init(int, char **); PJ PROJ_DLL *pj_init_plus(const char *); PJ PROJ_DLL *pj_init_ctx( PJ_CONTEXT *, int, char ** ); diff --git a/src/projections/goode.cpp b/src/projections/goode.cpp index fdace387..9a6fb86c 100644 --- a/src/projections/goode.cpp +++ b/src/projections/goode.cpp @@ -54,8 +54,8 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor */ return nullptr; if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_free (static_cast(P->opaque)->sinu); - pj_free (static_cast(P->opaque)->moll); + proj_destroy (static_cast(P->opaque)->sinu); + proj_destroy (static_cast(P->opaque)->moll); return pj_default_destructor (P, errlev); } -- cgit v1.2.3 From 56f0ad70054eea15e9671cd67aafd14bf7c11c74 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Wed, 18 Nov 2020 10:43:16 +0100 Subject: Remove pj_errno and related functions --- src/4D_api.cpp | 1 - src/Makefile.am | 2 +- src/apps/cct.cpp | 4 ++-- src/apps/cs2cs.cpp | 2 +- src/apps/gie.cpp | 8 ++++---- src/apps/proj.cpp | 8 +++----- src/errno.cpp | 18 ------------------ src/internal.cpp | 1 - src/lib_proj.cmake | 1 - src/pipeline.cpp | 2 +- src/proj_internal.h | 3 --- src/strerrno.cpp | 13 +++++-------- 12 files changed, 17 insertions(+), 46 deletions(-) delete mode 100644 src/errno.cpp (limited to 'src') diff --git a/src/4D_api.cpp b/src/4D_api.cpp index 78e9bdc3..83fda02c 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -1438,7 +1438,6 @@ int proj_errno_reset (const PJ *P) { proj_context_errno_set (pj_get_ctx ((PJ *) P), 0); errno = 0; - pj_errno = 0; return last_errno; } diff --git a/src/Makefile.am b/src/Makefile.am index e394b95b..4f3db3ed 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -209,7 +209,7 @@ libproj_la_SOURCES = \ \ aasincos.cpp adjlon.cpp \ dmstor.cpp auth.cpp \ - deriv.cpp ell_set.cpp ellps.cpp errno.cpp \ + deriv.cpp ell_set.cpp ellps.cpp \ factors.cpp fwd.cpp init.cpp inv.cpp \ list.cpp malloc.cpp mlfn.cpp mlfn.hpp msfn.cpp proj_mdist.cpp \ param.cpp phi2.cpp pr_list.cpp \ diff --git a/src/apps/cct.cpp b/src/apps/cct.cpp index e63a5fc2..92867b3a 100644 --- a/src/apps/cct.cpp +++ b/src/apps/cct.cpp @@ -360,7 +360,7 @@ int main(int argc, char **argv) { if (nullptr==P) { print (PJ_LOG_ERROR, "%s: Bad transformation arguments - (%s)\n '%s -h' for help", - o->progname, pj_strerrno (proj_errno(P)), o->progname); + o->progname, proj_errno_string (proj_errno(P)), o->progname); free (o); if (stdout != fout) fclose (fout); @@ -435,7 +435,7 @@ int main(int argc, char **argv) { if (HUGE_VAL==point.xyzt.x) { /* transformation error */ print (PJ_LOG_NONE, "# Record %d TRANSFORMATION ERROR: %s (%s)", - (int) o->record_index, buf, pj_strerrno (proj_errno(P))); + (int) o->record_index, buf, proj_errno_string (proj_errno(P))); proj_errno_restore (P, err); continue; } diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp index 92e4441e..12e045bb 100644 --- a/src/apps/cs2cs.cpp +++ b/src/apps/cs2cs.cpp @@ -624,7 +624,7 @@ int main(int argc, char **argv) { if (!transformation) { emess(3, "cannot initialize transformation\ncause: %s", - pj_strerrno(pj_errno)); + proj_errno_string(proj_context_errno(nullptr))); } if (use_env_locale) { diff --git a/src/apps/gie.cpp b/src/apps/gie.cpp index 2fe854fa..b504b922 100644 --- a/src/apps/gie.cpp +++ b/src/apps/gie.cpp @@ -880,8 +880,8 @@ static int expect_failure_with_errno_message (int expected, int got) { banner (T.operation); fprintf (T.fout, "%s", T.op_ko? " -----\n": delim); fprintf (T.fout, " FAILURE in %s(%d):\n", opt_strip_path (T.curr_file), (int) F->lineno); - fprintf (T.fout, " got errno %s (%d): %s\n", err_const_from_errno(got), got, pj_strerrno (got)); - fprintf (T.fout, " expected %s (%d): %s", err_const_from_errno(expected), expected, pj_strerrno (expected)); + fprintf (T.fout, " got errno %s (%d): %s\n", err_const_from_errno(got), got, proj_errno_string (got)); + fprintf (T.fout, " expected %s (%d): %s", err_const_from_errno(expected), expected, proj_errno_string (expected)); fprintf (T.fout, "\n"); return 1; } @@ -934,7 +934,7 @@ Tell GIE what to expect, when transforming the ACCEPTed input /* Otherwise, it's a true failure */ banner (T.operation); errmsg (3, "%sInvalid operation definition in line no. %d:\n %s (errno=%s/%d)\n", - delim, (int) T.operation_lineno, pj_strerrno(proj_errno(T.P)), + delim, (int) T.operation_lineno, proj_errno_string (proj_errno(T.P)), err_const_from_errno (proj_errno(T.P)), proj_errno(T.P) ); return another_failing_failure (); @@ -1186,7 +1186,7 @@ static int list_err_codes (void) { if (9999==lookup[i].the_errno) break; fprintf (T.fout, "%25s (%2.2d): %s\n", lookup[i].the_err_const + 8, - lookup[i].the_errno, pj_strerrno(lookup[i].the_errno)); + lookup[i].the_errno, proj_errno_string (lookup[i].the_errno)); } return 0; } diff --git a/src/apps/proj.cpp b/src/apps/proj.cpp index 8bfd99a3..a5c917f6 100644 --- a/src/apps/proj.cpp +++ b/src/apps/proj.cpp @@ -250,10 +250,8 @@ static void vprocess(FILE *fid) { if (postscale) { dat_xy.x *= fscale; dat_xy.y *= fscale; } } - /* For some reason pj_errno does not work as expected in some */ - /* versions of Visual Studio, so using pj_get_errno_ref instead */ - if (*pj_get_errno_ref()) { - emess(-1, pj_strerrno(*pj_get_errno_ref())); + if (proj_context_errno(nullptr)) { + emess(-1, proj_errno_string(proj_context_errno(nullptr))); continue; } @@ -477,7 +475,7 @@ int main(int argc, char **argv) { } if (!(Proj = pj_init(pargc, pargv))) emess(3,"projection initialization failure\ncause: %s", - pj_strerrno(pj_errno)); + proj_errno_string(proj_context_errno(nullptr))); if (!proj_angular_input(Proj, PJ_FWD)) { emess(3, "can't initialize operations that take non-angular input coordinates"); diff --git a/src/errno.cpp b/src/errno.cpp deleted file mode 100644 index 4f3119b3..00000000 --- a/src/errno.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* For full ANSI compliance of global variable */ - -#include "proj.h" -#include "proj_internal.h" - -int pj_errno = 0; - -/************************************************************************/ -/* pj_get_errno_ref() */ -/************************************************************************/ - -int *pj_get_errno_ref() - -{ - return &pj_errno; -} - -/* end */ diff --git a/src/internal.cpp b/src/internal.cpp index c1ffc408..175ffa9b 100644 --- a/src/internal.cpp +++ b/src/internal.cpp @@ -415,7 +415,6 @@ to that context. if( err == 0 ) return; errno = err; - pj_errno = err; } /* logging */ diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 1361294d..7ca7f3a4 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -217,7 +217,6 @@ set(SRC_LIBPROJ_CORE dmstor.cpp ell_set.cpp ellps.cpp - errno.cpp factors.cpp fwd.cpp gauss.cpp diff --git a/src/pipeline.cpp b/src/pipeline.cpp index 80ee0397..56a80848 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -533,7 +533,7 @@ PJ *OPERATION(pipeline,0) { int err_to_report = proj_errno(P); if (0==err_to_report) err_to_report = PJD_ERR_MALFORMED_PIPELINE; - proj_log_error (P, "Pipeline: Bad step definition: %s (%s)", current_argv[0], pj_strerrno (err_to_report)); + proj_log_error (P, "Pipeline: Bad step definition: %s (%s)", current_argv[0], proj_errno_string (err_to_report)); return destructor (P, err_to_report); /* ERROR: bad pipeline def */ } next_step->parent = P; diff --git a/src/proj_internal.h b/src/proj_internal.h index d57e87a2..7e41f0f9 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -921,7 +921,6 @@ PJ_LP pj_generic_inverse_2d(PJ_XY xy, PJ *P, PJ_LP lpInitial); extern char const PROJ_DLL pj_release[]; /* global release id string */ -PROJ_DLL extern int pj_errno; /* global error return code */ #ifndef PROJ_INTERNAL_H /* replaced by enum proj_log_level in proj_internal.h */ @@ -959,8 +958,6 @@ void PROJ_DLL pj_dalloc(void *); void PROJ_DLL *pj_calloc (size_t n, size_t size); void PROJ_DLL *pj_dealloc (void *ptr); char PROJ_DLL *pj_strdup(const char *str); -char PROJ_DLL *pj_strerrno(int); -int PROJ_DLL *pj_get_errno_ref(void); const char PROJ_DLL *pj_get_release(void); void PROJ_DLL pj_acquire_lock(void); void PROJ_DLL pj_release_lock(void); diff --git a/src/strerrno.cpp b/src/strerrno.cpp index 1c8673d0..3d0131c6 100644 --- a/src/strerrno.cpp +++ b/src/strerrno.cpp @@ -1,4 +1,4 @@ -/* list of projection system pj_errno values */ +/* list of projection system errno values */ #include #include @@ -74,10 +74,11 @@ pj_err_list[] = { "network error", /* -62 */ /* When adding error messages, remember to update ID defines in - projects.h, and transient_error array in pj_transform */ + src/proj_internal.h and src/apps/gie.cpp */ }; -char *pj_strerrno(int err) { + +const char* proj_errno_string(int err) { const int max_error = 9999; static char note[50]; size_t adjusted_err; @@ -98,7 +99,7 @@ char *pj_strerrno(int err) { #endif } - /* PROJ.4 error codes are negative: -1 to -9999 */ + /* PROJ error codes are negative: -1 to -9999 */ adjusted_err = err < -max_error ? max_error : -err - 1; if (adjusted_err < (sizeof(pj_err_list) / sizeof(char *))) return (char *)pj_err_list[adjusted_err]; @@ -107,7 +108,3 @@ char *pj_strerrno(int err) { (err > -max_error) ? err: -max_error); return note; } - -const char* proj_errno_string(int err) { - return pj_strerrno(err); -} -- cgit v1.2.3 From 046270a85faf20f38d01e02942d197db74bb8542 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Fri, 20 Nov 2020 16:37:12 +0100 Subject: Remove old pj_ memory (de)allocation functions Gone are pj_malloc, pj_calloc, pj_dalloc and pj_dealloc. Their primary function as API memory functions in proj_api.h is no longer there and the other use as a workaround for old errno problems is no longer valid either. Replaced with malloc and free across the codebase. --- src/4D_api.cpp | 26 ++++----- src/apps/geod_set.cpp | 2 +- src/auth.cpp | 2 +- src/conversions/axisswap.cpp | 2 +- src/conversions/set.cpp | 2 +- src/conversions/unitconvert.cpp | 2 +- src/ell_set.cpp | 22 ++++---- src/init.cpp | 50 ++++++++--------- src/initcache.cpp | 20 +++---- src/iso19111/c_api.cpp | 20 +++---- src/iso19111/io.cpp | 4 +- src/malloc.cpp | 112 +++++-------------------------------- src/mlfn.cpp | 2 +- src/param.cpp | 4 +- src/pipeline.cpp | 10 ++-- src/pr_list.cpp | 8 +-- src/proj_internal.h | 6 +- src/projections/adams.cpp | 2 +- src/projections/aea.cpp | 6 +- src/projections/aeqd.cpp | 4 +- src/projections/airy.cpp | 2 +- src/projections/aitoff.cpp | 4 +- src/projections/bacon.cpp | 6 +- src/projections/bertin1953.cpp | 2 +- src/projections/bipc.cpp | 2 +- src/projections/bonne.cpp | 4 +- src/projections/cass.cpp | 4 +- src/projections/ccon.cpp | 4 +- src/projections/cea.cpp | 4 +- src/projections/chamb.cpp | 2 +- src/projections/col_urban.cpp | 2 +- src/projections/eck3.cpp | 8 +-- src/projections/eqc.cpp | 2 +- src/projections/eqdc.cpp | 4 +- src/projections/eqearth.cpp | 4 +- src/projections/fouc_s.cpp | 2 +- src/projections/geos.cpp | 2 +- src/projections/gn_sinu.cpp | 10 ++-- src/projections/gnom.cpp | 2 +- src/projections/goode.cpp | 2 +- src/projections/gstmerc.cpp | 2 +- src/projections/hammer.cpp | 2 +- src/projections/healpix.cpp | 6 +- src/projections/igh.cpp | 2 +- src/projections/igh_o.cpp | 2 +- src/projections/imw_p.cpp | 4 +- src/projections/isea.cpp | 2 +- src/projections/krovak.cpp | 2 +- src/projections/labrd.cpp | 2 +- src/projections/laea.cpp | 4 +- src/projections/lagrng.cpp | 2 +- src/projections/lcc.cpp | 2 +- src/projections/lcca.cpp | 4 +- src/projections/loxim.cpp | 2 +- src/projections/lsat.cpp | 2 +- src/projections/misrsom.cpp | 2 +- src/projections/mod_ster.cpp | 10 ++-- src/projections/moll.cpp | 6 +- src/projections/nsper.cpp | 4 +- src/projections/ob_tran.cpp | 8 +-- src/projections/ocea.cpp | 2 +- src/projections/oea.cpp | 2 +- src/projections/omerc.cpp | 2 +- src/projections/ortho.cpp | 2 +- src/projections/poly.cpp | 4 +- src/projections/putp3.cpp | 4 +- src/projections/putp4p.cpp | 4 +- src/projections/putp5.cpp | 4 +- src/projections/putp6.cpp | 4 +- src/projections/qsc.cpp | 2 +- src/projections/rouss.cpp | 4 +- src/projections/rpoly.cpp | 2 +- src/projections/sch.cpp | 2 +- src/projections/sconics.cpp | 2 +- src/projections/somerc.cpp | 2 +- src/projections/stere.cpp | 4 +- src/projections/sterea.cpp | 4 +- src/projections/sts.cpp | 8 +-- src/projections/tmerc.cpp | 4 +- src/projections/tpeqd.cpp | 2 +- src/projections/urm5.cpp | 2 +- src/projections/urmfps.cpp | 4 +- src/projections/vandg2.cpp | 4 +- src/projections/wag3.cpp | 2 +- src/projections/wink1.cpp | 2 +- src/projections/wink2.cpp | 2 +- src/transformations/affine.cpp | 2 +- src/transformations/helmert.cpp | 2 +- src/transformations/horner.cpp | 10 ++-- src/transformations/molodensky.cpp | 2 +- 90 files changed, 227 insertions(+), 317 deletions(-) (limited to 'src') diff --git a/src/4D_api.cpp b/src/4D_api.cpp index 83fda02c..15bc73c8 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -778,14 +778,14 @@ PJ *pj_create_internal (PJ_CONTEXT *ctx, const char *definition) { argc = pj_trim_argc (args); if (argc==0) { - pj_dealloc (args); + free (args); proj_context_errno_set(ctx, PJD_ERR_NO_ARGS); return nullptr; } argv = pj_trim_argv (argc, args); if (!argv) { - pj_dealloc(args); + free(args); proj_context_errno_set(ctx, ENOMEM); return nullptr; } @@ -795,8 +795,8 @@ PJ *pj_create_internal (PJ_CONTEXT *ctx, const char *definition) { allow_init_epsg = proj_context_get_use_proj4_init_rules(ctx, FALSE); P = pj_init_ctx_with_allow_init_epsg (ctx, (int) argc, argv, allow_init_epsg); - pj_dealloc (argv); - pj_dealloc (args); + free (argv); + free (args); /* Support cs2cs-style modifiers */ ret = cs2cs_emulation_setup (P); @@ -834,7 +834,7 @@ indicator, as in {"+proj=utm", "+zone=32"}, or leave it out, as in {"proj=utm", P = proj_create (ctx, c); - pj_dealloc ((char *) c); + free ((char *) c); return P; } @@ -862,13 +862,13 @@ Same as proj_create_argv() but calls pj_create_internal() instead of proj_create P = pj_create_internal (ctx, c); - pj_dealloc ((char *) c); + free ((char *) c); return P; } /** Create an area of use */ PJ_AREA * proj_area_create(void) { - return static_cast(pj_calloc(1, sizeof(PJ_AREA))); + return static_cast(calloc(1, sizeof(PJ_AREA))); } /** Assign a bounding box to an area of use. */ @@ -886,7 +886,7 @@ void proj_area_set_bbox(PJ_AREA *area, /** Free an area of use */ void proj_area_destroy(PJ_AREA* area) { - pj_dealloc(area); + free(area); } /************************************************************************/ @@ -1495,15 +1495,15 @@ static char *path_append (char *buf, const char *app, size_t *buf_size) { /* "pj_realloc", so to speak */ if (*buf_size < len) { - p = static_cast(pj_calloc (2 * len, sizeof (char))); + p = static_cast(calloc (2 * len, sizeof (char))); if (nullptr==p) { - pj_dealloc (buf); + free (buf); return nullptr; } *buf_size = 2 * len; if (buf != nullptr) strcpy (p, buf); - pj_dealloc (buf); + free (buf); buf = p; } assert(buf); @@ -1556,7 +1556,7 @@ PJ_INFO proj_info (void) { } } - pj_dalloc(const_cast(info.searchpath)); + free(const_cast(info.searchpath)); info.searchpath = buf ? buf : empty; info.paths = ctx ? ctx->c_compat_paths : nullptr; @@ -1805,7 +1805,7 @@ PJ_INIT_INFO proj_init_info(const char *initname){ for ( ; start; start = next) { next = start->next; - pj_dalloc(start); + free(start); } return ininfo; diff --git a/src/apps/geod_set.cpp b/src/apps/geod_set.cpp index 603f0d95..d6516f22 100644 --- a/src/apps/geod_set.cpp +++ b/src/apps/geod_set.cpp @@ -75,6 +75,6 @@ geod_set(int argc, char **argv) { /* free up linked list */ for ( ; start; start = curr) { curr = start->next; - pj_dalloc(start); + free(start); } } diff --git a/src/auth.cpp b/src/auth.cpp index a8ee262a..ced02fb4 100644 --- a/src/auth.cpp +++ b/src/auth.cpp @@ -18,7 +18,7 @@ pj_authset(double es) { double t, *APA; - if ((APA = (double *)pj_malloc(APA_SIZE * sizeof(double))) != nullptr) { + if ((APA = (double *)malloc(APA_SIZE * sizeof(double))) != nullptr) { APA[0] = es * P00; t = es * es; APA[0] += t * P01; diff --git a/src/conversions/axisswap.cpp b/src/conversions/axisswap.cpp index 4ae2b4e4..1aa339c3 100644 --- a/src/conversions/axisswap.cpp +++ b/src/conversions/axisswap.cpp @@ -169,7 +169,7 @@ static PJ_COORD reverse_4d(PJ_COORD coo, PJ *P) { /***********************************************************************/ PJ *CONVERSION(axisswap,0) { /***********************************************************************/ - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); char *s; unsigned int i, j, n = 0; diff --git a/src/conversions/set.cpp b/src/conversions/set.cpp index 7628bf4f..2f30bda8 100644 --- a/src/conversions/set.cpp +++ b/src/conversions/set.cpp @@ -39,7 +39,7 @@ PJ *OPERATION(set, 0) { P->inv4d = set_fwd_inv; P->fwd4d = set_fwd_inv; - auto set = static_cast(pj_calloc (1, sizeof(struct Set))); + auto set = static_cast(calloc (1, sizeof(struct Set))); P->opaque = set; if (nullptr==P->opaque) return pj_default_destructor(P, ENOMEM); diff --git a/src/conversions/unitconvert.cpp b/src/conversions/unitconvert.cpp index 172e2c48..61bccbf1 100644 --- a/src/conversions/unitconvert.cpp +++ b/src/conversions/unitconvert.cpp @@ -433,7 +433,7 @@ static double get_unit_conversion_factor(const char* name, /***********************************************************************/ PJ *CONVERSION(unitconvert,0) { /***********************************************************************/ - struct pj_opaque_unitconvert *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque_unitconvert))); + struct pj_opaque_unitconvert *Q = static_cast(calloc (1, sizeof (struct pj_opaque_unitconvert))); const char *s, *name; int i; double f; diff --git a/src/ell_set.cpp b/src/ell_set.cpp index c7cbeb48..176fc553 100644 --- a/src/ell_set.cpp +++ b/src/ell_set.cpp @@ -77,13 +77,13 @@ int pj_ellipsoid (PJ *P) { int err = proj_errno_reset (P); const char *empty = {""}; - pj_dealloc(P->def_size); + free(P->def_size); P->def_size = nullptr; - pj_dealloc(P->def_shape); + free(P->def_shape); P->def_shape = nullptr; - pj_dealloc(P->def_spherification); + free(P->def_spherification); P->def_spherification = nullptr; - pj_dealloc(P->def_ellps); + free(P->def_ellps); P->def_ellps = nullptr; /* Specifying R overrules everything */ @@ -162,7 +162,7 @@ static int ellps_ellps (PJ *P) { new_params->next = pj_mkparam (ellps->ell); if (nullptr == new_params->next) { - pj_dealloc(new_params); + free(new_params); return proj_errno_set (P, ENOMEM); } paralist* old_params = P->params; @@ -176,8 +176,8 @@ static int ellps_ellps (PJ *P) { ellps_shape (P); P->params = old_params; - pj_dealloc (new_params->next); - pj_dealloc (new_params); + free (new_params->next); + free (new_params); if (proj_errno (P)) return proj_errno (P); @@ -195,7 +195,7 @@ static int ellps_size (PJ *P) { paralist *par = nullptr; int a_was_set = 0; - pj_dealloc(P->def_size); + free(P->def_size); P->def_size = nullptr; /* A size parameter *must* be given, but may have been given as ellps prior */ @@ -235,7 +235,7 @@ static int ellps_shape (PJ *P) { par = nullptr; len = sizeof (keys) / sizeof (char *); - pj_dealloc(P->def_shape); + free(P->def_shape); P->def_shape = nullptr; /* Check which shape key is specified */ @@ -721,8 +721,8 @@ int pj_ell_set (PJ_CONTEXT *ctx, paralist *pl, double *a, double *es) { } bomb: if (start) { /* clean up temporary extension of list */ - pj_dalloc(start->next->next); - pj_dalloc(start->next); + free(start->next->next); + free(start->next); start->next = 0; } if (ctx->last_errno) diff --git a/src/init.cpp b/src/init.cpp index 95bb404f..7b614c5f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -55,7 +55,7 @@ static paralist *string_to_paralist (PJ_CONTEXT *ctx, char *definition) { /* Keep a handle to the start of the list, so we have something to return */ auto param = pj_mkparam_ws (c, &c); if (nullptr==param) { - pj_dealloc_params (ctx, first, ENOMEM); + free_params (ctx, first, ENOMEM); return nullptr; } if (nullptr==last) { @@ -84,7 +84,7 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) { char *buffer = nullptr; size_t n; - fname = static_cast(pj_malloc (MAX_PATH_FILENAME+ID_TAG_MAX+3)); + fname = static_cast(malloc (MAX_PATH_FILENAME+ID_TAG_MAX+3)); if (nullptr==fname) { return nullptr; } @@ -96,7 +96,7 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) { else key += 5; if (MAX_PATH_FILENAME + ID_TAG_MAX + 2 < strlen (key)) { - pj_dealloc (fname); + free (fname); return nullptr; } memmove (fname, key, strlen (key) + 1); @@ -105,7 +105,7 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) { section = strrchr(fname, ':'); if (nullptr==section) { proj_context_errno_set (ctx, PJD_ERR_NO_COLON_IN_INIT_STRING); - pj_dealloc (fname); + free (fname); return nullptr; } *section = 0; @@ -117,7 +117,7 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) { auto file = NS_PROJ::FileManager::open_resource_file(ctx, fname); if (nullptr==file) { - pj_dealloc (fname); + free (fname); proj_context_errno_set (ctx, PJD_ERR_NO_OPTION_IN_INIT_FILE); return nullptr; } @@ -131,7 +131,7 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) { line = file->read_line(MAX_LINE_LENGTH, maxLenReached, eofReached); /* End of file? */ if (maxLenReached || eofReached) { - pj_dealloc (fname); + free (fname); proj_context_errno_set (ctx, PJD_ERR_NO_OPTION_IN_INIT_FILE); return nullptr; } @@ -149,9 +149,9 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) { } /* We're at the first line of the right section - copy line to buffer */ - buffer = static_cast(pj_malloc (current_buffer_size)); + buffer = static_cast(malloc (current_buffer_size)); if (nullptr==buffer) { - pj_dealloc (fname); + free (fname); return nullptr; } @@ -183,22 +183,22 @@ static char *get_init_string (PJ_CONTEXT *ctx, const char *name) { pj_chomp (&line[0]); /* Remove '#' style comments */ next_length = strlen (line.data()) + buffer_length + 2; if (next_length > current_buffer_size) { - char *b = static_cast(pj_malloc (2 * current_buffer_size)); + char *b = static_cast(malloc (2 * current_buffer_size)); if (nullptr==b) { - pj_dealloc (buffer); + free (buffer); buffer = nullptr; break; } strcpy (b, buffer); current_buffer_size *= 2; - pj_dealloc (buffer); + free (buffer); buffer = b; } buffer[buffer_length] = ' '; strcpy (buffer + buffer_length + 1, line.data()); } - pj_dealloc (fname); + free (fname); if (nullptr==buffer) return nullptr; pj_shrink (buffer); @@ -306,7 +306,7 @@ Expand key from buffer or (if not in buffer) from init file definition, init_items->param, init_items->next ? init_items->next->param : "(empty)"); - pj_dealloc (definition); + free (definition); if (nullptr==init_items) return nullptr; @@ -424,7 +424,7 @@ pj_init_plus_ctx( PJ_CONTEXT *ctx, const char *definition ) PJ *result = nullptr; /* make a copy that we can manipulate */ - defn_copy = (char *) pj_malloc( strlen(definition)+1 ); + defn_copy = (char *) malloc( strlen(definition)+1 ); if (!defn_copy) return nullptr; strcpy( defn_copy, definition ); @@ -447,7 +447,7 @@ pj_init_plus_ctx( PJ_CONTEXT *ctx, const char *definition ) if( argc+1 == MAX_ARG ) { - pj_dalloc( defn_copy ); + free( defn_copy ); proj_context_errno_set( ctx, PJD_ERR_UNPARSEABLE_CS_DEF ); return nullptr; } @@ -477,7 +477,7 @@ pj_init_plus_ctx( PJ_CONTEXT *ctx, const char *definition ) /* perform actual initialization */ result = pj_init_ctx( ctx, argc, argv ); - pj_dalloc( defn_copy ); + free( defn_copy ); return result; } @@ -566,14 +566,14 @@ pj_init_ctx_with_allow_init_epsg(PJ_CONTEXT *ctx, int argc, char **argv, int all /* put arguments into internal linked list */ start = curr = pj_mkparam(argv[0]); if (!curr) { - pj_dealloc_params (ctx, start, ENOMEM); + free_params (ctx, start, ENOMEM); return nullptr; } for (i = 1; i < argc; ++i) { curr->next = pj_mkparam(argv[i]); if (!curr->next) { - pj_dealloc_params (ctx, start, ENOMEM); + free_params (ctx, start, ENOMEM); return nullptr; } curr = curr->next; @@ -588,31 +588,31 @@ pj_init_ctx_with_allow_init_epsg(PJ_CONTEXT *ctx, int argc, char **argv, int all if (init && n_pipelines == 0) { init = pj_expand_init_internal (ctx, init, allow_init_epsg); if (!init) { - pj_dealloc_params (ctx, start, PJD_ERR_NO_ARGS); + free_params (ctx, start, PJD_ERR_NO_ARGS); return nullptr; } } if (ctx->last_errno) { - pj_dealloc_params (ctx, start, ctx->last_errno); + free_params (ctx, start, ctx->last_errno); return nullptr; } /* Find projection selection */ curr = pj_param_exists (start, "proj"); if (nullptr==curr) { - pj_dealloc_params (ctx, start, PJD_ERR_PROJ_NOT_NAMED); + free_params (ctx, start, PJD_ERR_PROJ_NOT_NAMED); return nullptr; } name = curr->param; if (strlen (name) < 6) { - pj_dealloc_params (ctx, start, PJD_ERR_PROJ_NOT_NAMED); + free_params (ctx, start, PJD_ERR_PROJ_NOT_NAMED); return nullptr; } name += 5; proj = locate_constructor (name); if (nullptr==proj) { - pj_dealloc_params (ctx, start, PJD_ERR_UNKNOWN_PROJECTION_ID); + free_params (ctx, start, PJD_ERR_UNKNOWN_PROJECTION_ID); return nullptr; } @@ -621,7 +621,7 @@ pj_init_ctx_with_allow_init_epsg(PJ_CONTEXT *ctx, int argc, char **argv, int all /* Allocate projection structure */ PIN = proj(nullptr); if (nullptr==PIN) { - pj_dealloc_params (ctx, start, ENOMEM); + free_params (ctx, start, ENOMEM); return nullptr; } @@ -820,7 +820,7 @@ pj_init_ctx_with_allow_init_epsg(PJ_CONTEXT *ctx, int argc, char **argv, int all PIN->from_greenwich = 0.0; /* Private object for the geodesic functions */ - PIN->geod = static_cast(pj_calloc (1, sizeof (struct geod_geodesic))); + PIN->geod = static_cast(calloc (1, sizeof (struct geod_geodesic))); if (nullptr==PIN->geod) return pj_default_destructor (PIN, ENOMEM); geod_init(PIN->geod, PIN->a, (1 - sqrt (1 - PIN->es))); diff --git a/src/initcache.cpp b/src/initcache.cpp index af20fb82..cf9460ab 100644 --- a/src/initcache.cpp +++ b/src/initcache.cpp @@ -48,7 +48,7 @@ paralist *pj_clone_paralist( const paralist *list) for( ; list != nullptr; list = list->next ) { paralist *newitem = (paralist *) - pj_malloc(sizeof(paralist) + strlen(list->param)); + malloc(sizeof(paralist) + strlen(list->param)); newitem->used = 0; newitem->next = nullptr; @@ -83,17 +83,17 @@ void pj_clear_initcache() { paralist *n, *t = cache_paralist[i]; - pj_dalloc( cache_key[i] ); + free( cache_key[i] ); /* free parameter list elements */ for (; t != nullptr; t = n) { n = t->next; - pj_dalloc(t); + free(t); } } - pj_dalloc( cache_key ); - pj_dalloc( cache_paralist ); + free( cache_key ); + free( cache_paralist ); cache_count = 0; cache_alloc= 0; cache_key = nullptr; @@ -151,29 +151,29 @@ void pj_insert_initcache( const char *filekey, const paralist *list ) cache_alloc = cache_alloc * 2 + 15; - cache_key_new = (char **) pj_malloc(sizeof(char*) * cache_alloc); + cache_key_new = (char **) malloc(sizeof(char*) * cache_alloc); if( cache_key && cache_count ) { memcpy( cache_key_new, cache_key, sizeof(char*) * cache_count); } - pj_dalloc( cache_key ); + free( cache_key ); cache_key = cache_key_new; cache_paralist_new = (paralist **) - pj_malloc(sizeof(paralist*) * cache_alloc); + malloc(sizeof(paralist*) * cache_alloc); if( cache_paralist && cache_count ) { memcpy( cache_paralist_new, cache_paralist, sizeof(paralist*) * cache_count ); } - pj_dalloc( cache_paralist ); + free( cache_paralist ); cache_paralist = cache_paralist_new; } /* ** Duplicate the filekey and paralist, and insert in cache. */ - cache_key[cache_count] = (char *) pj_malloc(strlen(filekey)+1); + cache_key[cache_count] = (char *) malloc(strlen(filekey)+1); strcpy( cache_key[cache_count], filekey ); cache_paralist[cache_count] = pj_clone_paralist( list ); diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index d6308c49..8fdebcbd 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -2690,11 +2690,11 @@ proj_get_crs_info_list_from_database(PJ_CONTEXT *ctx, const char *auth_name, void proj_crs_info_list_destroy(PROJ_CRS_INFO **list) { if (list) { for (int i = 0; list[i] != nullptr; i++) { - pj_dalloc(list[i]->auth_name); - pj_dalloc(list[i]->code); - pj_dalloc(list[i]->name); - pj_dalloc(list[i]->area_name); - pj_dalloc(list[i]->projection_method_name); + free(list[i]->auth_name); + free(list[i]->code); + free(list[i]->name); + free(list[i]->area_name); + free(list[i]->projection_method_name); delete list[i]; } delete[] list; @@ -2784,11 +2784,11 @@ PROJ_UNIT_INFO **proj_get_units_from_database(PJ_CONTEXT *ctx, void proj_unit_list_destroy(PROJ_UNIT_INFO **list) { if (list) { for (int i = 0; list[i] != nullptr; i++) { - pj_dalloc(list[i]->auth_name); - pj_dalloc(list[i]->code); - pj_dalloc(list[i]->name); - pj_dalloc(list[i]->category); - pj_dalloc(list[i]->proj_short_name); + free(list[i]->auth_name); + free(list[i]->code); + free(list[i]->name); + free(list[i]->category); + free(list[i]->proj_short_name); delete list[i]; } delete[] list; diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 8c815f36..6c710697 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -9778,7 +9778,7 @@ PROJStringParser::createFromPROJString(const std::string &projString) { paralist *list = pj_expand_init(ctx, init); ctx->projStringParserCreateFromPROJStringRecursionCounter--; if (!list) { - pj_dealloc(init); + free(init); throw ParsingException("cannot expand " + projString); } std::string expanded; @@ -9801,7 +9801,7 @@ PROJStringParser::createFromPROJString(const std::string &projString) { } auto n = t->next; - pj_dealloc(t); + free(t); t = n; } for (const auto &pair : d->steps_[0].paramValues) { diff --git a/src/malloc.cpp b/src/malloc.cpp index 590dd27f..6b7fbf26 100644 --- a/src/malloc.cpp +++ b/src/malloc.cpp @@ -53,99 +53,13 @@ using namespace NS_PROJ; -/**********************************************************************/ -void *pj_malloc(size_t size) { -/*********************************************************************** -Currently, pj_malloc is a hack to solve an errno problem. -The problem is described in more details at -https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=86420. -It seems, that pj_init and similar functions incorrectly -(under debian/glibs-2.3.2) assume that pj_malloc resets -errno after success. pj_malloc tries to mimic this. - -NOTE (2017-09-29): The problem described at the bugzilla page -referred to above, is most likely a case of someone not -understanding the proper usage of errno. We should review -whether "the problem is actually a problem" in PROJ.4 code. - -Library specific allocators can be useful, and improve -interoperability, if properly used. That is, by making them -run/initialization time switchable, somewhat like the file i/o -interface. - -But as things stand, we are more likely to get benefit -from reviewing the code for proper errno usage, which is hard, -due to the presence of context local and global pj_errnos. - -Probably, these were introduced in order to support incomplete -implementations of thread local errnos at an early phase of the -implementation of multithreading support in PROJ.4). - -It is likely too late to get rid of contexts, but we can still -benefit from a better usage of errno. -***********************************************************************/ - int old_errno = errno; - void *res = malloc(size); - if ( res && !old_errno ) - errno = 0; - return res; -} - - -/**********************************************************************/ -void *pj_calloc (size_t n, size_t size) { -/*********************************************************************** -pj_calloc is the pj-equivalent of calloc(). - -It allocates space for an array of elements of size . -The array is initialized to zeros. -***********************************************************************/ - void *res = pj_malloc (n*size); - if (nullptr==res) - return nullptr; - memset (res, 0, n*size); - return res; -} - - -/**********************************************************************/ -void pj_dalloc(void *ptr) { -/**********************************************************************/ - free(ptr); -} - - -/**********************************************************************/ -void *pj_dealloc (void *ptr) { -/*********************************************************************** -pj_dealloc supports the common use case of "clean up and return a null -pointer" to signal an error in a multi level allocation: - - struct foo { int bar; int *baz; }; - - struct foo *p = pj_calloc (1, sizeof (struct foo)); - if (0==p) - return 0; - - p->baz = pj_calloc (10, sizeof(int)); - if (0==p->baz) - return pj_dealloc (p); // clean up + signal error by 0-return - - return p; // success - -***********************************************************************/ - if (nullptr==ptr) - return nullptr; - pj_dalloc (ptr); - return nullptr; -} /**********************************************************************/ char *pj_strdup(const char *str) /**********************************************************************/ { size_t len = strlen(str) + 1; - char *dup = static_cast(pj_malloc(len)); + char *dup = static_cast(malloc(len)); if (dup) memcpy(dup, str, len); return dup; @@ -153,7 +67,7 @@ char *pj_strdup(const char *str) /*****************************************************************************/ -void *pj_dealloc_params (PJ_CONTEXT *ctx, paralist *start, int errlev) { +void *free_params (PJ_CONTEXT *ctx, paralist *start, int errlev) { /***************************************************************************** Companion to pj_default_destructor (below). Deallocates a linked list of "+proj=xxx" initialization parameters. @@ -164,7 +78,7 @@ void *pj_dealloc_params (PJ_CONTEXT *ctx, paralist *start, int errlev) { paralist *t, *n; for (t = start; t; t = n) { n = t->next; - pj_dealloc(t); + free(t); } proj_context_errno_set (ctx, errlev); return (void *) nullptr; @@ -225,26 +139,26 @@ PJ *pj_default_destructor (PJ *P, int errlev) { /* Destructor */ return nullptr; - pj_dealloc(P->def_size); - pj_dealloc(P->def_shape); - pj_dealloc(P->def_spherification); - pj_dealloc(P->def_ellps); + free(P->def_size); + free(P->def_shape); + free(P->def_spherification); + free(P->def_ellps); delete static_cast(P->hgrids_legacy); delete static_cast(P->vgrids_legacy); - /* We used to call pj_dalloc( P->catalog ), but this will leak */ + /* We used to call free( P->catalog ), but this will leak */ /* memory. The safe way to clear catalog and grid is to call */ - /* pj_gc_unloadall(pj_get_default_ctx()); and pj_deallocate_grids(); */ + /* pj_gc_unloadall(pj_get_default_ctx()); and freeate_grids(); */ /* TODO: we should probably have a public pj_cleanup() method to do all */ /* that */ /* free the interface to Charles Karney's geodesic library */ - pj_dealloc( P->geod ); + free( P->geod ); /* free parameter list elements */ - pj_dealloc_params (pj_get_ctx(P), P->params, errlev); - pj_dealloc (P->def_full); + free_params (pj_get_ctx(P), P->params, errlev); + free (P->def_full); /* free the cs2cs emulation elements */ proj_destroy (P->axisswap); @@ -254,7 +168,7 @@ PJ *pj_default_destructor (PJ *P, int errlev) { /* Destructor */ proj_destroy (P->hgridshift); proj_destroy (P->vgridshift); - pj_dealloc (static_cast(P->opaque)); + free (static_cast(P->opaque)); delete P; return nullptr; } diff --git a/src/mlfn.cpp b/src/mlfn.cpp index d4037897..763d83ee 100644 --- a/src/mlfn.cpp +++ b/src/mlfn.cpp @@ -26,7 +26,7 @@ double *pj_enfn(double es) { double t, *en; - en = (double *) pj_malloc(EN_SIZE * sizeof (double)); + en = (double *) malloc(EN_SIZE * sizeof (double)); if (nullptr==en) return nullptr; diff --git a/src/param.cpp b/src/param.cpp index 3e13b391..28d6bc3e 100644 --- a/src/param.cpp +++ b/src/param.cpp @@ -38,7 +38,7 @@ static void unquote_string(char* param_str) { paralist *pj_mkparam(const char *str) { paralist *newitem; - if((newitem = (paralist *)pj_malloc(sizeof(paralist) + strlen(str))) != nullptr) { + if((newitem = (paralist *)malloc(sizeof(paralist) + strlen(str))) != nullptr) { newitem->used = 0; newitem->next = nullptr; if (*str == '+') @@ -82,7 +82,7 @@ paralist *pj_mkparam_ws (const char *str, const char **next_str) { *next_str = str + len; /* Use calloc to automagically 0-terminate the copy */ - newitem = (paralist *) pj_calloc (1, sizeof(paralist) + len + 1); + newitem = (paralist *) calloc (1, sizeof(paralist) + len + 1); if (nullptr==newitem) return nullptr; memcpy(newitem->param, str, len); diff --git a/src/pipeline.cpp b/src/pipeline.cpp index 56a80848..e9d11604 100644 --- a/src/pipeline.cpp +++ b/src/pipeline.cpp @@ -294,8 +294,8 @@ static PJ *destructor (PJ *P, int errlev) { auto pipeline = static_cast(P->opaque); - pj_dealloc (pipeline->argv); - pj_dealloc (pipeline->current_argv); + free (pipeline->argv); + free (pipeline->current_argv); delete pipeline; P->opaque = nullptr; @@ -321,7 +321,7 @@ static const char *argv_sentinel = "step"; static char **argv_params (paralist *params, size_t argc) { char **argv; size_t i = 0; - argv = static_cast(pj_calloc (argc, sizeof (char *))); + argv = static_cast(calloc (argc, sizeof (char *))); if (nullptr==argv) return nullptr; for (; params != nullptr; params = params->next) @@ -461,7 +461,7 @@ PJ *OPERATION(pipeline,0) { if (nullptr==argv) return destructor (P, ENOMEM); - pipeline->current_argv = current_argv = static_cast(pj_calloc (argc, sizeof (char *))); + pipeline->current_argv = current_argv = static_cast(calloc (argc, sizeof (char *))); if (nullptr==current_argv) return destructor (P, ENOMEM); @@ -679,7 +679,7 @@ static PJ_COORD pop(PJ_COORD point, PJ *P) { static PJ *setup_pushpop(PJ *P) { - auto pushpop = static_cast(pj_calloc (1, sizeof(struct PushPop))); + auto pushpop = static_cast(calloc (1, sizeof(struct PushPop))); P->opaque = pushpop; if (nullptr==P->opaque) return destructor(P, ENOMEM); diff --git a/src/pr_list.cpp b/src/pr_list.cpp index 77db5bfb..30fc6571 100644 --- a/src/pr_list.cpp +++ b/src/pr_list.cpp @@ -66,7 +66,7 @@ char *pj_get_def( PJ *P, int options ) size_t def_max = 10; (void) options; - definition = (char *) pj_malloc(def_max); + definition = (char *) malloc(def_max); if (!definition) return nullptr; definition[0] = '\0'; @@ -84,14 +84,14 @@ char *pj_get_def( PJ *P, int options ) char *def2; def_max = def_max * 2 + l + 5; - def2 = (char *) pj_malloc(def_max); + def2 = (char *) malloc(def_max); if (def2) { strcpy( def2, definition ); - pj_dalloc( definition ); + free( definition ); definition = def2; } else { - pj_dalloc( definition ); + free( definition ); return nullptr; } } diff --git a/src/proj_internal.h b/src/proj_internal.h index 7e41f0f9..234ff80e 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -825,7 +825,7 @@ paralist *pj_search_initcache( const char *filekey ); void pj_insert_initcache( const char *filekey, const paralist *list); paralist *pj_expand_init(PJ_CONTEXT *ctx, paralist *init); -void *pj_dealloc_params (PJ_CONTEXT *ctx, paralist *start, int errlev); +void *free_params (PJ_CONTEXT *ctx, paralist *start, int errlev); double *pj_enfn(double); @@ -953,10 +953,6 @@ char PROJ_DLL *pj_get_def(PJ *, int); int PROJ_DLL pj_has_inverse(PJ *); -void PROJ_DLL *pj_malloc(size_t); -void PROJ_DLL pj_dalloc(void *); -void PROJ_DLL *pj_calloc (size_t n, size_t size); -void PROJ_DLL *pj_dealloc (void *ptr); char PROJ_DLL *pj_strdup(const char *str); const char PROJ_DLL *pj_get_release(void); void PROJ_DLL pj_acquire_lock(void); diff --git a/src/projections/adams.cpp b/src/projections/adams.cpp index 4f7d1a03..d1217ff1 100644 --- a/src/projections/adams.cpp +++ b/src/projections/adams.cpp @@ -205,7 +205,7 @@ static PJ_LP adams_inverse(PJ_XY xy, PJ *P) static PJ *setup(PJ *P, projection_type mode) { struct pj_opaque *Q = static_cast( - pj_calloc (1, sizeof (struct pj_opaque))); + calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); diff --git a/src/projections/aea.cpp b/src/projections/aea.cpp index 6ffb4fd6..af0f292d 100644 --- a/src/projections/aea.cpp +++ b/src/projections/aea.cpp @@ -94,7 +94,7 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_dealloc (static_cast(P->opaque)->en); + free (static_cast(P->opaque)->en); return pj_default_destructor (P, errlev); } @@ -219,7 +219,7 @@ static PJ *setup(PJ *P) { PJ *PROJECTION(aea) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -232,7 +232,7 @@ PJ *PROJECTION(aea) { PJ *PROJECTION(leac) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/aeqd.cpp b/src/projections/aeqd.cpp index ad8c289e..d5d90b62 100644 --- a/src/projections/aeqd.cpp +++ b/src/projections/aeqd.cpp @@ -69,7 +69,7 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_dealloc (static_cast(P->opaque)->en); + free (static_cast(P->opaque)->en); return pj_default_destructor (P, errlev); } @@ -274,7 +274,7 @@ static PJ_LP aeqd_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse PJ *PROJECTION(aeqd) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/airy.cpp b/src/projections/airy.cpp index f7602e53..15ff60d8 100644 --- a/src/projections/airy.cpp +++ b/src/projections/airy.cpp @@ -120,7 +120,7 @@ static PJ_XY airy_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward PJ *PROJECTION(airy) { double beta; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); diff --git a/src/projections/aitoff.cpp b/src/projections/aitoff.cpp index d02e7761..857ebb80 100644 --- a/src/projections/aitoff.cpp +++ b/src/projections/aitoff.cpp @@ -187,7 +187,7 @@ static PJ *setup(PJ *P) { PJ *PROJECTION(aitoff) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; @@ -198,7 +198,7 @@ PJ *PROJECTION(aitoff) { PJ *PROJECTION(wintri) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; diff --git a/src/projections/bacon.cpp b/src/projections/bacon.cpp index 3efd4dbe..7ff2a7ac 100644 --- a/src/projections/bacon.cpp +++ b/src/projections/bacon.cpp @@ -43,7 +43,7 @@ static PJ_XY bacon_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forwar PJ *PROJECTION(bacon) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -57,7 +57,7 @@ PJ *PROJECTION(bacon) { PJ *PROJECTION(apian) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -70,7 +70,7 @@ PJ *PROJECTION(apian) { PJ *PROJECTION(ortel) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/bertin1953.cpp b/src/projections/bertin1953.cpp index b864f83a..58509e16 100644 --- a/src/projections/bertin1953.cpp +++ b/src/projections/bertin1953.cpp @@ -75,7 +75,7 @@ static PJ_XY bertin1953_s_forward (PJ_LP lp, PJ *P) { PJ *PROJECTION(bertin1953) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/bipc.cpp b/src/projections/bipc.cpp index bf4ba834..743acd1c 100644 --- a/src/projections/bipc.cpp +++ b/src/projections/bipc.cpp @@ -168,7 +168,7 @@ static PJ_LP bipc_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse PJ *PROJECTION(bipc) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/bonne.cpp b/src/projections/bonne.cpp index c94764cf..7817e968 100644 --- a/src/projections/bonne.cpp +++ b/src/projections/bonne.cpp @@ -106,14 +106,14 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_dealloc (static_cast(P->opaque)->en); + free (static_cast(P->opaque)->en); return pj_default_destructor (P, errlev); } PJ *PROJECTION(bonne) { double c; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/cass.cpp b/src/projections/cass.cpp index e253cafc..f5531f6a 100644 --- a/src/projections/cass.cpp +++ b/src/projections/cass.cpp @@ -95,7 +95,7 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_dealloc (static_cast(P->opaque)->en); + free (static_cast(P->opaque)->en); return pj_default_destructor (P, errlev); } @@ -111,7 +111,7 @@ PJ *PROJECTION(cass) { } /* otherwise it's ellipsoidal */ - P->opaque = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + P->opaque = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==P->opaque) return pj_default_destructor (P, ENOMEM); P->destructor = destructor; diff --git a/src/projections/ccon.cpp b/src/projections/ccon.cpp index df995f21..7b3b7105 100644 --- a/src/projections/ccon.cpp +++ b/src/projections/ccon.cpp @@ -75,14 +75,14 @@ static PJ *destructor (PJ *P, int errlev) { if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_dealloc (static_cast(P->opaque)->en); + free (static_cast(P->opaque)->en); return pj_default_destructor (P, errlev); } PJ *PROJECTION(ccon) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/cea.cpp b/src/projections/cea.cpp index 7e6d3212..b7874b90 100644 --- a/src/projections/cea.cpp +++ b/src/projections/cea.cpp @@ -66,14 +66,14 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_dealloc (static_cast(P->opaque)->apa); + free (static_cast(P->opaque)->apa); return pj_default_destructor (P, errlev); } PJ *PROJECTION(cea) { double t = 0.0; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/chamb.cpp b/src/projections/chamb.cpp index 1b926b8a..b315832a 100644 --- a/src/projections/chamb.cpp +++ b/src/projections/chamb.cpp @@ -103,7 +103,7 @@ static PJ_XY chamb_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forwar PJ *PROJECTION(chamb) { int i, j; char line[10]; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/col_urban.cpp b/src/projections/col_urban.cpp index 5bc8407f..de0c178f 100644 --- a/src/projections/col_urban.cpp +++ b/src/projections/col_urban.cpp @@ -54,7 +54,7 @@ static PJ_LP col_urban_inverse (PJ_XY xy, PJ *P) { } PJ *PROJECTION(col_urban) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/eck3.cpp b/src/projections/eck3.cpp index 0deeb4f3..2563053f 100644 --- a/src/projections/eck3.cpp +++ b/src/projections/eck3.cpp @@ -52,7 +52,7 @@ static PJ *setup(PJ *P) { PJ *PROJECTION(eck3) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -67,7 +67,7 @@ PJ *PROJECTION(eck3) { PJ *PROJECTION(kav7) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -85,7 +85,7 @@ PJ *PROJECTION(kav7) { PJ *PROJECTION(wag6) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -100,7 +100,7 @@ PJ *PROJECTION(wag6) { PJ *PROJECTION(putp1) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/eqc.cpp b/src/projections/eqc.cpp index 194625ef..9ebc9286 100644 --- a/src/projections/eqc.cpp +++ b/src/projections/eqc.cpp @@ -39,7 +39,7 @@ static PJ_LP eqc_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse PJ *PROJECTION(eqc) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/eqdc.cpp b/src/projections/eqdc.cpp index 659488b1..28767d74 100644 --- a/src/projections/eqdc.cpp +++ b/src/projections/eqdc.cpp @@ -68,7 +68,7 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_dealloc (static_cast(P->opaque)->en); + free (static_cast(P->opaque)->en); return pj_default_destructor (P, errlev); } @@ -77,7 +77,7 @@ PJ *PROJECTION(eqdc) { double cosphi, sinphi; int secant; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/eqearth.cpp b/src/projections/eqearth.cpp index 60effde0..2ef2775b 100644 --- a/src/projections/eqearth.cpp +++ b/src/projections/eqearth.cpp @@ -137,13 +137,13 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor */ if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_dealloc (static_cast(P->opaque)->apa); + free (static_cast(P->opaque)->apa); return pj_default_destructor (P, errlev); } PJ *PROJECTION(eqearth) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/fouc_s.cpp b/src/projections/fouc_s.cpp index c5989514..f7607635 100644 --- a/src/projections/fouc_s.cpp +++ b/src/projections/fouc_s.cpp @@ -55,7 +55,7 @@ static PJ_LP fouc_s_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inver PJ *PROJECTION(fouc_s) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/geos.cpp b/src/projections/geos.cpp index 338f07c2..5de4c7ca 100644 --- a/src/projections/geos.cpp +++ b/src/projections/geos.cpp @@ -199,7 +199,7 @@ static PJ_LP geos_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse PJ *PROJECTION(geos) { char *sweep_axis; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/gn_sinu.cpp b/src/projections/gn_sinu.cpp index 815de8be..ef312613 100644 --- a/src/projections/gn_sinu.cpp +++ b/src/projections/gn_sinu.cpp @@ -102,7 +102,7 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_dealloc (static_cast(P->opaque)->en); + free (static_cast(P->opaque)->en); return pj_default_destructor (P, errlev); } @@ -121,7 +121,7 @@ static void setup(PJ *P) { PJ *PROJECTION(sinu) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -143,7 +143,7 @@ PJ *PROJECTION(sinu) { PJ *PROJECTION(eck6) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -158,7 +158,7 @@ PJ *PROJECTION(eck6) { PJ *PROJECTION(mbtfps) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -173,7 +173,7 @@ PJ *PROJECTION(mbtfps) { PJ *PROJECTION(gn_sinu) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/gnom.cpp b/src/projections/gnom.cpp index 23dee030..9abbb7ce 100644 --- a/src/projections/gnom.cpp +++ b/src/projections/gnom.cpp @@ -124,7 +124,7 @@ static PJ_LP gnom_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse PJ *PROJECTION(gnom) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/goode.cpp b/src/projections/goode.cpp index 9a6fb86c..c0afd2d8 100644 --- a/src/projections/goode.cpp +++ b/src/projections/goode.cpp @@ -62,7 +62,7 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor */ PJ *PROJECTION(goode) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/gstmerc.cpp b/src/projections/gstmerc.cpp index 50814bb5..b21f6ffd 100644 --- a/src/projections/gstmerc.cpp +++ b/src/projections/gstmerc.cpp @@ -54,7 +54,7 @@ static PJ_LP gstmerc_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inve PJ *PROJECTION(gstmerc) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/hammer.cpp b/src/projections/hammer.cpp index 8d6d9408..d9bcafc7 100644 --- a/src/projections/hammer.cpp +++ b/src/projections/hammer.cpp @@ -57,7 +57,7 @@ static PJ_LP hammer_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inver PJ *PROJECTION(hammer) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/healpix.cpp b/src/projections/healpix.cpp index 5a06125d..c778f28f 100644 --- a/src/projections/healpix.cpp +++ b/src/projections/healpix.cpp @@ -607,13 +607,13 @@ static PJ *destructor (PJ *P, int errlev) { /* Destructor if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_dealloc (static_cast(P->opaque)->apa); + free (static_cast(P->opaque)->apa); return pj_default_destructor (P, errlev); } PJ *PROJECTION(healpix) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -641,7 +641,7 @@ PJ *PROJECTION(healpix) { PJ *PROJECTION(rhealpix) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/igh.cpp b/src/projections/igh.cpp index 2be94889..8aaaaba1 100644 --- a/src/projections/igh.cpp +++ b/src/projections/igh.cpp @@ -208,7 +208,7 @@ static bool setup_zone(PJ *P, struct pj_opaque *Q, int n, PJ *PROJECTION(igh) { PJ_XY xy1, xy3; PJ_LP lp = { 0, phi_boundary }; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/igh_o.cpp b/src/projections/igh_o.cpp index b14d79a5..80874845 100644 --- a/src/projections/igh_o.cpp +++ b/src/projections/igh_o.cpp @@ -222,7 +222,7 @@ static bool setup_zone(PJ *P, struct pj_opaque *Q, int n, PJ *PROJECTION(igh_o) { PJ_XY xy1, xy4; PJ_LP lp = { 0, phi_boundary }; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/imw_p.cpp b/src/projections/imw_p.cpp index ee206091..6e82d287 100644 --- a/src/projections/imw_p.cpp +++ b/src/projections/imw_p.cpp @@ -160,7 +160,7 @@ static PJ *destructor (PJ *P, int errlev) { return pj_default_destructor (P, errlev); if( static_cast(P->opaque)->en ) - pj_dealloc (static_cast(P->opaque)->en); + free (static_cast(P->opaque)->en); return pj_default_destructor(P, errlev); } @@ -169,7 +169,7 @@ static PJ *destructor (PJ *P, int errlev) { PJ *PROJECTION(imw_p) { double del, sig, s, t, x1, x2, T2, y1, m1, m2, y2; int err; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/isea.cpp b/src/projections/isea.cpp index dd1d48ff..77a5689b 100644 --- a/src/projections/isea.cpp +++ b/src/projections/isea.cpp @@ -1039,7 +1039,7 @@ static PJ_XY isea_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward PJ *PROJECTION(isea) { char *opt; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/krovak.cpp b/src/projections/krovak.cpp index 3e6a5c30..adc039fe 100644 --- a/src/projections/krovak.cpp +++ b/src/projections/krovak.cpp @@ -191,7 +191,7 @@ static PJ_LP krovak_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, PJ *PROJECTION(krovak) { double u0, n0, g; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/labrd.cpp b/src/projections/labrd.cpp index c9dfdfc6..4fbcf460 100644 --- a/src/projections/labrd.cpp +++ b/src/projections/labrd.cpp @@ -105,7 +105,7 @@ static PJ_LP labrd_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, invers PJ *PROJECTION(labrd) { double Az, sinp, R, N, t; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/laea.cpp b/src/projections/laea.cpp index 3d135864..2d19cab1 100644 --- a/src/projections/laea.cpp +++ b/src/projections/laea.cpp @@ -234,7 +234,7 @@ static PJ *destructor (PJ *P, int errlev) { if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_dealloc (static_cast(P->opaque)->apa); + free (static_cast(P->opaque)->apa); return pj_default_destructor(P, errlev); } @@ -242,7 +242,7 @@ static PJ *destructor (PJ *P, int errlev) { PJ *PROJECTION(laea) { double t; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/lagrng.cpp b/src/projections/lagrng.cpp index d37a00e6..1029bf8d 100644 --- a/src/projections/lagrng.cpp +++ b/src/projections/lagrng.cpp @@ -71,7 +71,7 @@ static PJ_LP lagrng_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inver PJ *PROJECTION(lagrng) { double sin_phi1; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/lcc.cpp b/src/projections/lcc.cpp index 46378ce4..525281f4 100644 --- a/src/projections/lcc.cpp +++ b/src/projections/lcc.cpp @@ -80,7 +80,7 @@ static PJ_LP lcc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse PJ *PROJECTION(lcc) { double cosphi, sinphi; int secant; - struct pj_opaque *Q = static_cast(pj_calloc(1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc(1, sizeof (struct pj_opaque))); if (nullptr == Q) return pj_default_destructor(P, ENOMEM); diff --git a/src/projections/lcca.cpp b/src/projections/lcca.cpp index 51dd28aa..53646fc6 100644 --- a/src/projections/lcca.cpp +++ b/src/projections/lcca.cpp @@ -128,14 +128,14 @@ static PJ *destructor (PJ *P, int errlev) { if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_dealloc (static_cast(P->opaque)->en); + free (static_cast(P->opaque)->en); return pj_default_destructor (P, errlev); } PJ *PROJECTION(lcca) { double s2p0, N0, R0, tan0; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/loxim.cpp b/src/projections/loxim.cpp index 2ee88037..64124bdd 100644 --- a/src/projections/loxim.cpp +++ b/src/projections/loxim.cpp @@ -56,7 +56,7 @@ static PJ_LP loxim_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers PJ *PROJECTION(loxim) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/lsat.cpp b/src/projections/lsat.cpp index f6114485..a811a3a6 100644 --- a/src/projections/lsat.cpp +++ b/src/projections/lsat.cpp @@ -158,7 +158,7 @@ static PJ_LP lsat_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse PJ *PROJECTION(lsat) { int land, path; double lam, alf, esc, ess; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; diff --git a/src/projections/misrsom.cpp b/src/projections/misrsom.cpp index 71116e1e..d7e199f2 100644 --- a/src/projections/misrsom.cpp +++ b/src/projections/misrsom.cpp @@ -178,7 +178,7 @@ PJ *PROJECTION(misrsom) { int path; double lam, alf, esc, ess; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/mod_ster.cpp b/src/projections/mod_ster.cpp index c7a8e899..0c30b7b6 100644 --- a/src/projections/mod_ster.cpp +++ b/src/projections/mod_ster.cpp @@ -134,7 +134,7 @@ PJ *PROJECTION(mil_os) { {0.019430, 0.} }; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -157,7 +157,7 @@ PJ *PROJECTION(lee_os) { {-0.0088162, -0.00617325} }; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -182,7 +182,7 @@ PJ *PROJECTION(gs48) { {0.075528, 0.} }; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -217,7 +217,7 @@ PJ *PROJECTION(alsk) { { .3660976, -.2937382} }; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -265,7 +265,7 @@ PJ *PROJECTION(gs50) { {-.0225161, .0853673} }; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/moll.cpp b/src/projections/moll.cpp index 5d4f7825..4864c8e1 100644 --- a/src/projections/moll.cpp +++ b/src/projections/moll.cpp @@ -77,7 +77,7 @@ static PJ * setup(PJ *P, double p) { PJ *PROJECTION(moll) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -87,7 +87,7 @@ PJ *PROJECTION(moll) { PJ *PROJECTION(wag4) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -96,7 +96,7 @@ PJ *PROJECTION(wag4) { } PJ *PROJECTION(wag5) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/nsper.cpp b/src/projections/nsper.cpp index 903946b9..951111ac 100644 --- a/src/projections/nsper.cpp +++ b/src/projections/nsper.cpp @@ -180,7 +180,7 @@ static PJ *setup(PJ *P) { PJ *PROJECTION(nsper) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -194,7 +194,7 @@ PJ *PROJECTION(nsper) { PJ *PROJECTION(tpers) { double omega, gamma; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/ob_tran.cpp b/src/projections/ob_tran.cpp index 7cf1cf98..4990ab2a 100644 --- a/src/projections/ob_tran.cpp +++ b/src/projections/ob_tran.cpp @@ -142,7 +142,7 @@ static ARGS ob_tran_target_params (paralist *params) { return args; /* all args except the proj_ob_tran */ - args.argv = static_cast(pj_calloc (argc - 1, sizeof (char *))); + args.argv = static_cast(calloc (argc - 1, sizeof (char *))); if (nullptr==args.argv) return args; @@ -160,7 +160,7 @@ static ARGS ob_tran_target_params (paralist *params) { continue; args.argv[i] += 2; if (strcmp(args.argv[i], "proj=ob_tran") == 0 ) { - pj_dealloc (args.argv); + free (args.argv); args.argc = 0; args.argv = nullptr; } @@ -177,7 +177,7 @@ PJ *PROJECTION(ob_tran) { ARGS args; PJ *R; /* projection to rotate */ - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return destructor(P, ENOMEM); @@ -195,7 +195,7 @@ PJ *PROJECTION(ob_tran) { return destructor(P, PJD_ERR_FAILED_TO_FIND_PROJ); } R = pj_init_ctx (pj_get_ctx(P), args.argc, args.argv); - pj_dealloc (args.argv); + free (args.argv); if (nullptr==R) return destructor (P, PJD_ERR_UNKNOWN_PROJECTION_ID); diff --git a/src/projections/ocea.cpp b/src/projections/ocea.cpp index de9838cb..c78e1ebc 100644 --- a/src/projections/ocea.cpp +++ b/src/projections/ocea.cpp @@ -52,7 +52,7 @@ static PJ_LP ocea_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse PJ *PROJECTION(ocea) { double phi_1, phi_2, lam_1, lam_2, lonz, alpha; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/oea.cpp b/src/projections/oea.cpp index 61fb0647..46c00d16 100644 --- a/src/projections/oea.cpp +++ b/src/projections/oea.cpp @@ -58,7 +58,7 @@ static PJ_LP oea_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse PJ *PROJECTION(oea) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/omerc.cpp b/src/projections/omerc.cpp index e9f3b833..90067cc3 100644 --- a/src/projections/omerc.cpp +++ b/src/projections/omerc.cpp @@ -126,7 +126,7 @@ PJ *PROJECTION(omerc) { gamma0, lamc=0, lam1=0, lam2=0, phi1=0, phi2=0, alpha_c=0; int alp, gam, no_off = 0; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/ortho.cpp b/src/projections/ortho.cpp index d9c84dba..4417dac7 100644 --- a/src/projections/ortho.cpp +++ b/src/projections/ortho.cpp @@ -279,7 +279,7 @@ static PJ_LP ortho_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inver PJ *PROJECTION(ortho) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; diff --git a/src/projections/poly.cpp b/src/projections/poly.cpp index 10d93ed2..4ea95cc7 100644 --- a/src/projections/poly.cpp +++ b/src/projections/poly.cpp @@ -147,14 +147,14 @@ static PJ *destructor(PJ *P, int errlev) { return pj_default_destructor (P, errlev); if (static_cast(P->opaque)->en) - pj_dealloc (static_cast(P->opaque)->en); + free (static_cast(P->opaque)->en); return pj_default_destructor(P, errlev); } PJ *PROJECTION(poly) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); diff --git a/src/projections/putp3.cpp b/src/projections/putp3.cpp index c2df20e8..09763851 100644 --- a/src/projections/putp3.cpp +++ b/src/projections/putp3.cpp @@ -38,7 +38,7 @@ static PJ_LP putp3_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers PJ *PROJECTION(putp3) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -53,7 +53,7 @@ PJ *PROJECTION(putp3) { } PJ *PROJECTION(putp3p) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/putp4p.cpp b/src/projections/putp4p.cpp index 365f7c1b..8df18972 100644 --- a/src/projections/putp4p.cpp +++ b/src/projections/putp4p.cpp @@ -45,7 +45,7 @@ static PJ_LP putp4p_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inver PJ *PROJECTION(putp4p) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -62,7 +62,7 @@ PJ *PROJECTION(putp4p) { PJ *PROJECTION(weren) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/putp5.cpp b/src/projections/putp5.cpp index 1847e7a9..5e70382d 100644 --- a/src/projections/putp5.cpp +++ b/src/projections/putp5.cpp @@ -43,7 +43,7 @@ static PJ_LP putp5_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers PJ *PROJECTION(putp5) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -60,7 +60,7 @@ PJ *PROJECTION(putp5) { PJ *PROJECTION(putp5p) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/putp6.cpp b/src/projections/putp6.cpp index db334ff9..da8c0a7c 100644 --- a/src/projections/putp6.cpp +++ b/src/projections/putp6.cpp @@ -59,7 +59,7 @@ static PJ_LP putp6_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers PJ *PROJECTION(putp6) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; @@ -79,7 +79,7 @@ PJ *PROJECTION(putp6) { PJ *PROJECTION(putp6p) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; diff --git a/src/projections/qsc.cpp b/src/projections/qsc.cpp index 98e3755e..dd9ce965 100644 --- a/src/projections/qsc.cpp +++ b/src/projections/qsc.cpp @@ -377,7 +377,7 @@ static PJ_LP qsc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inverse PJ *PROJECTION(qsc) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/rouss.cpp b/src/projections/rouss.cpp index f5a8f12f..2eb13b3d 100644 --- a/src/projections/rouss.cpp +++ b/src/projections/rouss.cpp @@ -93,7 +93,7 @@ static PJ *destructor (PJ *P, int errlev) { return pj_default_destructor (P, errlev); if (static_cast(P->opaque)->en) - pj_dealloc (static_cast(P->opaque)->en); + free (static_cast(P->opaque)->en); return pj_default_destructor (P, ENOMEM); } @@ -102,7 +102,7 @@ static PJ *destructor (PJ *P, int errlev) { PJ *PROJECTION(rouss) { double N0, es2, t, t2, R_R0_2, R_R0_4; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; diff --git a/src/projections/rpoly.cpp b/src/projections/rpoly.cpp index b065861f..e3f09c59 100644 --- a/src/projections/rpoly.cpp +++ b/src/projections/rpoly.cpp @@ -44,7 +44,7 @@ static PJ_XY rpoly_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forwar PJ *PROJECTION(rpoly) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; diff --git a/src/projections/sch.cpp b/src/projections/sch.cpp index 7548039d..359e8efc 100644 --- a/src/projections/sch.cpp +++ b/src/projections/sch.cpp @@ -184,7 +184,7 @@ static PJ *setup(PJ *P) { /* general initialization */ PJ *PROJECTION(sch) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; diff --git a/src/projections/sconics.cpp b/src/projections/sconics.cpp index f305e291..c12b05a2 100644 --- a/src/projections/sconics.cpp +++ b/src/projections/sconics.cpp @@ -117,7 +117,7 @@ static PJ_LP sconics_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, (and ellipsoi static PJ *setup(PJ *P, enum Type type) { double del, cs; int err; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/somerc.cpp b/src/projections/somerc.cpp index fe6477fa..a184500c 100644 --- a/src/projections/somerc.cpp +++ b/src/projections/somerc.cpp @@ -71,7 +71,7 @@ static PJ_LP somerc_e_inverse (PJ_XY xy, PJ *P) { /* Ellipsoidal, inver PJ *PROJECTION(somerc) { double cp, phip0, sp; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/stere.cpp b/src/projections/stere.cpp index 3fff722d..ad1caae2 100644 --- a/src/projections/stere.cpp +++ b/src/projections/stere.cpp @@ -302,7 +302,7 @@ static PJ *setup(PJ *P) { /* general initialization */ PJ *PROJECTION(stere) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -315,7 +315,7 @@ PJ *PROJECTION(stere) { PJ *PROJECTION(ups) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/sterea.cpp b/src/projections/sterea.cpp index 55404c86..4dd22d2f 100644 --- a/src/projections/sterea.cpp +++ b/src/projections/sterea.cpp @@ -93,14 +93,14 @@ static PJ *destructor (PJ *P, int errlev) { if (nullptr==P->opaque) return pj_default_destructor (P, errlev); - pj_dealloc (static_cast(P->opaque)->en); + free (static_cast(P->opaque)->en); return pj_default_destructor (P, errlev); } PJ *PROJECTION(sterea) { double R; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); diff --git a/src/projections/sts.cpp b/src/projections/sts.cpp index cbc36b7d..75190e85 100644 --- a/src/projections/sts.cpp +++ b/src/projections/sts.cpp @@ -70,7 +70,7 @@ static PJ *setup(PJ *P, double p, double q, int mode) { PJ *PROJECTION(fouc) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; @@ -80,7 +80,7 @@ PJ *PROJECTION(fouc) { PJ *PROJECTION(kav5) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; @@ -91,7 +91,7 @@ PJ *PROJECTION(kav5) { PJ *PROJECTION(qua_aut) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; @@ -101,7 +101,7 @@ PJ *PROJECTION(qua_aut) { PJ *PROJECTION(mbt_s) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; diff --git a/src/projections/tmerc.cpp b/src/projections/tmerc.cpp index ff1bc2a5..8cae9968 100644 --- a/src/projections/tmerc.cpp +++ b/src/projections/tmerc.cpp @@ -221,7 +221,7 @@ static PJ *destructor(PJ *P, int errlev) { if (nullptr==P->opaque) return pj_default_destructor(P, errlev); - pj_dealloc (static_cast(P->opaque)->approx.en); + free (static_cast(P->opaque)->approx.en); return pj_default_destructor(P, errlev); } @@ -592,7 +592,7 @@ static PJ_LP auto_e_inv (PJ_XY xy, PJ *P) { static PJ *setup(PJ *P, TMercAlgo eAlg) { - struct tmerc_data *Q = static_cast(pj_calloc (1, sizeof (struct tmerc_data))); + struct tmerc_data *Q = static_cast(calloc (1, sizeof (struct tmerc_data))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/tpeqd.cpp b/src/projections/tpeqd.cpp index 58aeb8e1..90efb395 100644 --- a/src/projections/tpeqd.cpp +++ b/src/projections/tpeqd.cpp @@ -64,7 +64,7 @@ static PJ_LP tpeqd_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers PJ *PROJECTION(tpeqd) { double lam_1, lam_2, phi_1, phi_2, A12; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; diff --git a/src/projections/urm5.cpp b/src/projections/urm5.cpp index 499644d2..c3021841 100644 --- a/src/projections/urm5.cpp +++ b/src/projections/urm5.cpp @@ -30,7 +30,7 @@ static PJ_XY urm5_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forward PJ *PROJECTION(urm5) { double alpha, t; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; diff --git a/src/projections/urmfps.cpp b/src/projections/urmfps.cpp index 3f9fdf23..5d689f9f 100644 --- a/src/projections/urmfps.cpp +++ b/src/projections/urmfps.cpp @@ -47,7 +47,7 @@ static PJ *setup(PJ *P) { PJ *PROJECTION(urmfps) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); @@ -66,7 +66,7 @@ PJ *PROJECTION(urmfps) { PJ *PROJECTION(wag1) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; diff --git a/src/projections/vandg2.cpp b/src/projections/vandg2.cpp index 223620d6..cd7e7b6c 100644 --- a/src/projections/vandg2.cpp +++ b/src/projections/vandg2.cpp @@ -53,7 +53,7 @@ static PJ_XY vandg2_s_forward (PJ_LP lp, PJ *P) { /* Spheroidal, forwa PJ *PROJECTION(vandg2) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; @@ -65,7 +65,7 @@ PJ *PROJECTION(vandg2) { } PJ *PROJECTION(vandg3) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; diff --git a/src/projections/wag3.cpp b/src/projections/wag3.cpp index 33313cdb..ed3250ef 100644 --- a/src/projections/wag3.cpp +++ b/src/projections/wag3.cpp @@ -35,7 +35,7 @@ static PJ_LP wag3_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, inverse PJ *PROJECTION(wag3) { double ts; - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); diff --git a/src/projections/wink1.cpp b/src/projections/wink1.cpp index d097978f..f4ffafe3 100644 --- a/src/projections/wink1.cpp +++ b/src/projections/wink1.cpp @@ -33,7 +33,7 @@ static PJ_LP wink1_s_inverse (PJ_XY xy, PJ *P) { /* Spheroidal, invers PJ *PROJECTION(wink1) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; diff --git a/src/projections/wink2.cpp b/src/projections/wink2.cpp index d457f842..b5b1e812 100644 --- a/src/projections/wink2.cpp +++ b/src/projections/wink2.cpp @@ -53,7 +53,7 @@ static PJ_LP wink2_s_inverse(PJ_XY xy, PJ *P) PJ *PROJECTION(wink2) { - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; diff --git a/src/transformations/affine.cpp b/src/transformations/affine.cpp index 28f73b9a..43fd8642 100644 --- a/src/transformations/affine.cpp +++ b/src/transformations/affine.cpp @@ -110,7 +110,7 @@ static PJ_LP reverse_2d(PJ_XY xy, PJ *P) { } static struct pj_opaque_affine * initQ() { - struct pj_opaque_affine *Q = static_cast(pj_calloc(1, sizeof(struct pj_opaque_affine))); + struct pj_opaque_affine *Q = static_cast(calloc(1, sizeof(struct pj_opaque_affine))); if (nullptr==Q) return nullptr; diff --git a/src/transformations/helmert.cpp b/src/transformations/helmert.cpp index d3857d89..99aa74a4 100644 --- a/src/transformations/helmert.cpp +++ b/src/transformations/helmert.cpp @@ -476,7 +476,7 @@ static PJ_COORD helmert_reverse_4d (PJ_COORD point, PJ *P) { static PJ* init_helmert_six_parameters(PJ* P) { - struct pj_opaque_helmert *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque_helmert))); + struct pj_opaque_helmert *Q = static_cast(calloc (1, sizeof (struct pj_opaque_helmert))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = (void *) Q; diff --git a/src/transformations/horner.cpp b/src/transformations/horner.cpp index a6638773..2c049186 100644 --- a/src/transformations/horner.cpp +++ b/src/transformations/horner.cpp @@ -89,8 +89,8 @@ PROJ_HEAD(horner, "Horner polynomial evaluation"); /* make horner.h interface with proj's memory management */ -#define horner_dealloc(x) pj_dealloc(x) -#define horner_calloc(n,x) pj_calloc(n,x) +#define horner_dealloc(x) free(x) +#define horner_calloc(n,x) calloc(n,x) namespace { // anonymous namespace struct horner { @@ -412,7 +412,7 @@ static int parse_coefs (PJ *P, double *coefs, const char *param, int ncoefs) { char *buf, *init, *next = nullptr; int i; - buf = static_cast(pj_calloc (strlen (param) + 2, sizeof(char))); + buf = static_cast(calloc (strlen (param) + 2, sizeof(char))); if (nullptr==buf) { proj_log_error (P, "Horner: No memory left"); return 0; @@ -420,12 +420,12 @@ static int parse_coefs (PJ *P, double *coefs, const char *param, int ncoefs) { sprintf (buf, "t%s", param); if (0==pj_param (P->ctx, P->params, buf).i) { - pj_dealloc (buf); + free (buf); return 0; } sprintf (buf, "s%s", param); init = pj_param(P->ctx, P->params, buf).s; - pj_dealloc (buf); + free (buf); for (i = 0; i < ncoefs; i++) { if (i > 0) { diff --git a/src/transformations/molodensky.cpp b/src/transformations/molodensky.cpp index 7d17f64c..bf5960d2 100644 --- a/src/transformations/molodensky.cpp +++ b/src/transformations/molodensky.cpp @@ -298,7 +298,7 @@ static PJ_COORD reverse_4d(PJ_COORD obs, PJ *P) { PJ *TRANSFORMATION(molodensky,1) { int count_required_params = 0; - struct pj_opaque_molodensky *Q = static_cast(pj_calloc(1, sizeof(struct pj_opaque_molodensky))); + struct pj_opaque_molodensky *Q = static_cast(calloc(1, sizeof(struct pj_opaque_molodensky))); if (nullptr==Q) return pj_default_destructor(P, ENOMEM); P->opaque = (void *) Q; -- cgit v1.2.3 From 3dea81d9be4712aa90ba79f333338c0b3ecb21e2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 21 Nov 2020 13:55:11 +0100 Subject: Make GeographicCRS/GeodeticCRS::isEquivalentTo() work properly when comparing to a DerivedGeographicCRS/DerivedGeodeticCRS --- src/iso19111/crs.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 84b98984..de882105 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -1924,13 +1924,21 @@ getStandardCriterion(util::IComparable::Criterion criterion) { //! @cond Doxygen_Suppress bool GeodeticCRS::_isEquivalentTo( + const util::IComparable *other, util::IComparable::Criterion criterion, + const io::DatabaseContextPtr &dbContext) const { + if (other == nullptr || !util::isOfExactType(*other)) { + return false; + } + return _isEquivalentToNoTypeCheck(other, criterion, dbContext); +} + +bool GeodeticCRS::_isEquivalentToNoTypeCheck( const util::IComparable *other, util::IComparable::Criterion criterion, const io::DatabaseContextPtr &dbContext) const { const auto standardCriterion = getStandardCriterion(criterion); - auto otherGeodCRS = dynamic_cast(other); + // TODO test velocityModel - return otherGeodCRS != nullptr && - SingleCRS::baseIsEquivalentTo(other, standardCriterion, dbContext); + return SingleCRS::baseIsEquivalentTo(other, standardCriterion, dbContext); } //! @endcond @@ -2486,12 +2494,13 @@ bool GeographicCRS::is2DPartOf3D(util::nn other, bool GeographicCRS::_isEquivalentTo( const util::IComparable *other, util::IComparable::Criterion criterion, const io::DatabaseContextPtr &dbContext) const { - auto otherGeogCRS = dynamic_cast(other); - if (otherGeogCRS == nullptr) { + if (other == nullptr || !util::isOfExactType(*other)) { return false; } + const auto standardCriterion = getStandardCriterion(criterion); - if (GeodeticCRS::_isEquivalentTo(other, standardCriterion, dbContext)) { + if (GeodeticCRS::_isEquivalentToNoTypeCheck(other, standardCriterion, + dbContext)) { return true; } if (criterion != @@ -2510,7 +2519,8 @@ bool GeographicCRS::_isEquivalentTo( cs::EllipsoidalCS::AxisOrder::LONG_EAST_LAT_NORTH ? cs::EllipsoidalCS::createLatitudeLongitude(unit) : cs::EllipsoidalCS::createLongitudeLatitude(unit)) - ->GeodeticCRS::_isEquivalentTo(other, standardCriterion, dbContext); + ->GeodeticCRS::_isEquivalentToNoTypeCheck(other, standardCriterion, + dbContext); } return false; } @@ -3889,8 +3899,7 @@ ProjectedCRS::create(const util::PropertyMap &properties, bool ProjectedCRS::_isEquivalentTo( const util::IComparable *other, util::IComparable::Criterion criterion, const io::DatabaseContextPtr &dbContext) const { - auto otherProjCRS = dynamic_cast(other); - return otherProjCRS != nullptr && + return other != nullptr && util::isOfExactType(*other) && DerivedCRS::_isEquivalentTo(other, criterion, dbContext); } -- cgit v1.2.3 From c2edd467c591f936f4eb81dfadd62a20f6bff371 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 21 Nov 2020 13:56:18 +0100 Subject: createOperation(): make it work properly when one of the CRS is a BoundCRS of a DerivedGeographicCRS (+proj=ob_tran +o_proj=lonlat +towgs84=....) --- src/iso19111/coordinateoperation.cpp | 53 +++++++++++++++++++++++++++++++++++- src/iso19111/io.cpp | 4 +-- 2 files changed, 54 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 4cf1ae89..1d3b7a90 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -64,6 +64,30 @@ // #define DEBUG_CONCATENATED_OPERATION #if defined(DEBUG_SORT) || defined(DEBUG_CONCATENATED_OPERATION) #include + +void dumpWKT(const NS_PROJ::crs::CRS *crs); +void dumpWKT(const NS_PROJ::crs::CRS *crs) { + auto f(NS_PROJ::io::WKTFormatter::create( + NS_PROJ::io::WKTFormatter::Convention::WKT2_2019)); + std::cerr << crs->exportToWKT(f.get()) << std::endl; +} + +void dumpWKT(const NS_PROJ::crs::CRSPtr &crs); +void dumpWKT(const NS_PROJ::crs::CRSPtr &crs) { dumpWKT(crs.get()); } + +void dumpWKT(const NS_PROJ::crs::CRSNNPtr &crs); +void dumpWKT(const NS_PROJ::crs::CRSNNPtr &crs) { + dumpWKT(crs.as_nullable().get()); +} + +void dumpWKT(const NS_PROJ::crs::GeographicCRSPtr &crs); +void dumpWKT(const NS_PROJ::crs::GeographicCRSPtr &crs) { dumpWKT(crs.get()); } + +void dumpWKT(const NS_PROJ::crs::GeographicCRSNNPtr &crs); +void dumpWKT(const NS_PROJ::crs::GeographicCRSNNPtr &crs) { + dumpWKT(crs.as_nullable().get()); +} + #endif using namespace NS_PROJ::internal; @@ -9184,6 +9208,14 @@ static void setupPROJGeodeticSourceCRS(io::PROJStringFormatter *formatter, formatter->startInversion(); sourceCRSGeog->_exportToPROJString(formatter); formatter->stopInversion(); + if (util::isOfExactType( + *(sourceCRSGeog.get()))) { + // The export of a DerivedGeographicCRS in non-CRS mode adds + // unit conversion and axis swapping. We must compensate for that + formatter->startInversion(); + sourceCRSGeog->addAngularUnitConvertAndAxisSwap(formatter); + formatter->stopInversion(); + } if (addPushV3) { formatter->addStep("push"); @@ -9217,7 +9249,12 @@ static void setupPROJGeodeticTargetCRS(io::PROJStringFormatter *formatter, formatter->addStep("pop"); formatter->addParam("v_3"); } - + if (util::isOfExactType( + *(targetCRSGeog.get()))) { + // The export of a DerivedGeographicCRS in non-CRS mode adds + // unit conversion and axis swapping. We must compensate for that + targetCRSGeog->addAngularUnitConvertAndAxisSwap(formatter); + } targetCRSGeog->_exportToPROJString(formatter); } else { auto targetCRSGeod = dynamic_cast(crs.get()); @@ -14290,6 +14327,20 @@ void CoordinateOperationFactory::Private::createOperationsBoundToGeog( const auto &hubSrc = boundSrc->hubCRS(); auto hubSrcGeog = dynamic_cast(hubSrc.get()); auto geogCRSOfBaseOfBoundSrc = boundSrc->baseCRS()->extractGeographicCRS(); + { + // If geogCRSOfBaseOfBoundSrc is a DerivedGeographicCRS, use its base + // instead (if it is a GeographicCRS) + auto derivedGeogCRS = + std::dynamic_pointer_cast( + geogCRSOfBaseOfBoundSrc); + if (derivedGeogCRS) { + auto baseCRS = std::dynamic_pointer_cast( + derivedGeogCRS->baseCRS().as_nullable()); + if (baseCRS) { + geogCRSOfBaseOfBoundSrc = baseCRS; + } + } + } const auto &authFactory = context.context->getAuthorityFactory(); const auto dbContext = diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 623ad6f9..fa359d39 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -9478,8 +9478,8 @@ CRSNNPtr PROJStringParser::Private::buildProjectedCRS( std::string methodName = "PROJ " + step.name; for (const auto ¶m : step.paramValues) { if (is_in_stringlist(param.key, - "wktext,no_defs,datum,ellps,a,b,R,towgs84," - "nadgrids,geoidgrids," + "wktext,no_defs,datum,ellps,a,b,R,f,rf," + "towgs84,nadgrids,geoidgrids," "units,to_meter,vunits,vto_meter,type")) { continue; } -- cgit v1.2.3 From eb66679cde834096ff18f40b5b1d4bc10e3f4c1d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 21 Nov 2020 22:58:05 +0100 Subject: WKT parsing: fix ingestion of WKT with a Geocentric CRS as the base of the projected CRS --- src/iso19111/io.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src') diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index fa359d39..284729cd 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -2794,6 +2794,32 @@ WKTParser::Private::buildGeodeticCRS(const WKTNodeNNPtr &node) { .as_nullable() : nullptr; auto cs = buildCS(csNode, node, angularUnit); + + // If there's no CS[] node, typically for a BASEGEODCRS of a projected CRS, + // in a few rare cases, this might be a Geocentric CRS, and thus a + // Cartesian CS, and not the ellipsoidalCS we assumed above. The only way + // to figure that is to resolve the CRS from its code... + if (isNull(csNode) && dbContext_ && + ci_equal(nodeName, WKTConstants::BASEGEODCRS)) { + const auto &nodeChildren = nodeP->children(); + for (const auto &subNode : nodeChildren) { + const auto &subNodeName(subNode->GP()->value()); + if (ci_equal(subNodeName, WKTConstants::ID) || + ci_equal(subNodeName, WKTConstants::AUTHORITY)) { + auto id = buildId(subNode, true, false); + if (id) { + try { + auto authFactory = AuthorityFactory::create( + NN_NO_CHECK(dbContext_), *id->codeSpace()); + auto dbCRS = authFactory->createGeodeticCRS(id->code()); + cs = dbCRS->coordinateSystem(); + } catch (const util::Exception &) { + } + } + } + } + } + auto ellipsoidalCS = nn_dynamic_pointer_cast(cs); if (ellipsoidalCS) { if (ci_equal(nodeName, WKTConstants::GEOCCS)) { -- cgit v1.2.3 From 650e37f159b96d18f5ff03784466784a769688e4 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 21 Nov 2020 23:59:33 +0100 Subject: PROJJSON parsing: fix parsing of a Geodetic CRS with a DatumEnsemble, and fix parsing of a ProjectedCRS whose base is a Geocentric CRS --- src/iso19111/io.cpp | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 284729cd..713a471d 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -4980,6 +4980,10 @@ class JSONParser { TransformationNNPtr buildTransformation(const json &j); ConcatenatedOperationNNPtr buildConcatenatedOperation(const json &j); + void buildGeodeticDatumOrDatumEnsemble(const json &j, + GeodeticReferenceFramePtr &datum, + DatumEnsemblePtr &datumEnsemble); + static util::optional getAnchor(const json &j) { util::optional anchor; if (j.contains("anchor")) { @@ -5439,9 +5443,9 @@ BaseObjectNNPtr JSONParser::create(const json &j) // --------------------------------------------------------------------------- -GeographicCRSNNPtr JSONParser::buildGeographicCRS(const json &j) { - GeodeticReferenceFramePtr datum; - DatumEnsemblePtr datumEnsemble; +void JSONParser::buildGeodeticDatumOrDatumEnsemble( + const json &j, GeodeticReferenceFramePtr &datum, + DatumEnsemblePtr &datumEnsemble) { if (j.contains("datum")) { auto datumJ = getObject(j, "datum"); datum = util::nn_dynamic_pointer_cast( @@ -5454,6 +5458,14 @@ GeographicCRSNNPtr JSONParser::buildGeographicCRS(const json &j) { datumEnsemble = buildDatumEnsemble(getObject(j, "datum_ensemble")).as_nullable(); } +} + +// --------------------------------------------------------------------------- + +GeographicCRSNNPtr JSONParser::buildGeographicCRS(const json &j) { + GeodeticReferenceFramePtr datum; + DatumEnsemblePtr datumEnsemble; + buildGeodeticDatumOrDatumEnsemble(j, datum, datumEnsemble); auto csJ = getObject(j, "coordinate_system"); auto ellipsoidalCS = util::nn_dynamic_pointer_cast(buildCS(csJ)); @@ -5467,12 +5479,9 @@ GeographicCRSNNPtr JSONParser::buildGeographicCRS(const json &j) { // --------------------------------------------------------------------------- GeodeticCRSNNPtr JSONParser::buildGeodeticCRS(const json &j) { - auto datumJ = getObject(j, "datum"); - if (getType(datumJ) != "GeodeticReferenceFrame") { - throw ParsingException("Unsupported type for datum."); - } - auto datum = buildGeodeticReferenceFrame(datumJ); + GeodeticReferenceFramePtr datum; DatumEnsemblePtr datumEnsemble; + buildGeodeticDatumOrDatumEnsemble(j, datum, datumEnsemble); auto csJ = getObject(j, "coordinate_system"); auto cs = buildCS(csJ); auto props = buildProperties(j); @@ -5507,7 +5516,13 @@ GeodeticCRSNNPtr JSONParser::buildGeodeticCRS(const json &j) { // --------------------------------------------------------------------------- ProjectedCRSNNPtr JSONParser::buildProjectedCRS(const json &j) { - auto baseCRS = buildGeographicCRS(getObject(j, "base_crs")); + auto jBaseCRS = getObject(j, "base_crs"); + auto jBaseCS = getObject(jBaseCRS, "coordinate_system"); + auto baseCS = buildCS(jBaseCS); + auto baseCRS = dynamic_cast(baseCS.get()) != nullptr + ? util::nn_static_pointer_cast( + buildGeographicCRS(jBaseCRS)) + : buildGeodeticCRS(jBaseCRS); auto csJ = getObject(j, "coordinate_system"); auto cartesianCS = util::nn_dynamic_pointer_cast(buildCS(csJ)); if (!cartesianCS) { -- cgit v1.2.3 From f50221ed6606a67ef0354cacd449f02aca3faba7 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 22 Nov 2020 23:16:48 +0100 Subject: projinfo.cpp: improve hint when to use --spatial-test intersects --- src/apps/projinfo.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 6ee5925a..3d57dcd6 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -693,6 +693,7 @@ static void outputOperations( std::vector list; size_t spatialCriterionPartialIntersectionResultCount = 0; + bool spatialCriterionPartialIntersectionMoreRelevant = false; try { auto authFactory = dbContext @@ -718,10 +719,15 @@ static void outputOperations( ctxt->setSpatialCriterion( CoordinateOperationContext::SpatialCriterion:: PARTIAL_INTERSECTION); - spatialCriterionPartialIntersectionResultCount = - CoordinateOperationFactory::create() - ->createOperations(nnSourceCRS, nnTargetCRS, ctxt) - .size(); + auto list2 = + CoordinateOperationFactory::create()->createOperations( + nnSourceCRS, nnTargetCRS, ctxt); + spatialCriterionPartialIntersectionResultCount = list2.size(); + if (spatialCriterionPartialIntersectionResultCount == 1 && + list.size() == 1 && + list2[0]->nameStr() != list[0]->nameStr()) { + spatialCriterionPartialIntersectionMoreRelevant = true; + } } catch (const std::exception &) { } } @@ -740,6 +746,10 @@ static void outputOperations( "more results (" << spatialCriterionPartialIntersectionResultCount << ")" << std::endl; + } else if (spatialCriterionPartialIntersectionMoreRelevant) { + std::cout << "Note: using '--spatial-test intersects' would bring " + "more relevant results." + << std::endl; } if (summary) { for (const auto &op : list) { -- cgit v1.2.3 From b503c2e5ae4b90da5e390be929ab5a37ab534232 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 23 Nov 2020 16:54:48 +0100 Subject: GeographicCRS::_isEquivalentTo(EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS): make it work when comparing easting,northing,up and northing,easting,up --- src/iso19111/crs.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src') diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index de882105..5d2c6d7b 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -2522,6 +2522,27 @@ bool GeographicCRS::_isEquivalentTo( ->GeodeticCRS::_isEquivalentToNoTypeCheck(other, standardCriterion, dbContext); } + if (axisOrder == + cs::EllipsoidalCS::AxisOrder::LONG_EAST_LAT_NORTH_HEIGHT_UP || + axisOrder == + cs::EllipsoidalCS::AxisOrder::LAT_NORTH_LONG_EAST_HEIGHT_UP) { + const auto &angularUnit = coordinateSystem()->axisList()[0]->unit(); + const auto &linearUnit = coordinateSystem()->axisList()[2]->unit(); + return GeographicCRS::create( + util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, + nameStr()), + datum(), datumEnsemble(), + axisOrder == cs::EllipsoidalCS::AxisOrder:: + LONG_EAST_LAT_NORTH_HEIGHT_UP + ? cs::EllipsoidalCS:: + createLatitudeLongitudeEllipsoidalHeight( + angularUnit, linearUnit) + : cs::EllipsoidalCS:: + createLongitudeLatitudeEllipsoidalHeight( + angularUnit, linearUnit)) + ->GeodeticCRS::_isEquivalentToNoTypeCheck(other, standardCriterion, + dbContext); + } return false; } //! @endcond -- cgit v1.2.3 From d8fe9964bcbc6d1eeaddf6f5d47ca6d444dc8744 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 22 Nov 2020 15:08:41 +0100 Subject: Add +proj=topocentric geocentric->topocentric conversion (fixes #500) --- src/Makefile.am | 1 + src/conversions/topocentric.cpp | 165 +++++++++++++++++++++++++++++++++++ src/iso19111/coordinateoperation.cpp | 55 ++++++++++-- src/lib_proj.cmake | 1 + src/pj_list.h | 1 + src/proj_constants.h | 20 +++++ 6 files changed, 235 insertions(+), 8 deletions(-) create mode 100644 src/conversions/topocentric.cpp (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 5b36c8bd..4b904d9f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -187,6 +187,7 @@ libproj_la_SOURCES = \ conversions/geoc.cpp \ conversions/geocent.cpp \ conversions/noop.cpp \ + conversions/topocentric.cpp \ conversions/set.cpp \ conversions/unitconvert.cpp \ \ diff --git a/src/conversions/topocentric.cpp b/src/conversions/topocentric.cpp new file mode 100644 index 00000000..214f8221 --- /dev/null +++ b/src/conversions/topocentric.cpp @@ -0,0 +1,165 @@ +/****************************************************************************** + * Project: PROJ + * Purpose: Convert between geocentric coordinates and topocentric (ENU) coordinates + * + ****************************************************************************** + * Copyright (c) 2020, Even Rouault + * + * 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. + *****************************************************************************/ + +#define PJ_LIB__ + +#include "proj_internal.h" +#include +#include + +PROJ_HEAD(topocentric, "Geocentric/Topocentric conversion"); + +// Notations and formulas taken from IOGP Publication 373-7-2 - +// Geomatics Guidance Note number 7, part 2 - October 2020 + +namespace { // anonymous namespace +struct pj_opaque { + double X0; + double Y0; + double Z0; + double sinphi0; + double cosphi0; + double sinlam0; + double coslam0; +}; +} // anonymous namespace + +// Convert from geocentric to topocentric +static PJ_COORD topocentric_fwd(PJ_COORD in, PJ * P) +{ + struct pj_opaque *Q = static_cast(P->opaque); + PJ_COORD out; + const double dX = in.xyz.x - Q->X0; + const double dY = in.xyz.y - Q->Y0; + const double dZ = in.xyz.z - Q->Z0; + out.xyz.x = -dX * Q->sinlam0 + dY * Q->coslam0; + out.xyz.y = -dX * Q->sinphi0 * Q->coslam0 - dY * Q->sinphi0 * Q->sinlam0 + dZ * Q->cosphi0; + out.xyz.z = dX * Q->cosphi0 * Q->coslam0 + dY * Q->cosphi0 * Q->sinlam0 + dZ * Q->sinphi0; + return out; +} + +// Convert from topocentric to geocentric +static PJ_COORD topocentric_inv(PJ_COORD in, PJ * P) +{ + struct pj_opaque *Q = static_cast(P->opaque); + PJ_COORD out; + out.xyz.x = Q->X0 - in.xyz.x * Q->sinlam0 - in.xyz.y * Q->sinphi0 * Q->coslam0 + in.xyz.z * Q->cosphi0 * Q->coslam0; + out.xyz.y = Q->Y0 + in.xyz.x * Q->coslam0 - in.xyz.y * Q->sinphi0 * Q->sinlam0 + in.xyz.z * Q->cosphi0 * Q->sinlam0; + out.xyz.z = Q->Z0 + in.xyz.y * Q->cosphi0 + in.xyz.z * Q->sinphi0; + return out; +} + + +/*********************************************************************/ +PJ *CONVERSION(topocentric,1) { +/*********************************************************************/ + struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + if (nullptr==Q) + return pj_default_destructor (P, ENOMEM); + P->opaque = static_cast(Q); + + // The topocentric origin can be specified either in geocentric coordinates + // (X_0,Y_0,Z_0) or as geographic coordinates (lon_0,lat_0,h_0) + // Checks: + // - X_0 or lon_0 must be specified + // - If X_0 is specified, the Y_0 and Z_0 must also be + // - If lon_0 is specified, then lat_0 must also be + // - If any of X_0, Y_0, Z_0 is specified, then any of lon_0,lat_0,h_0 must + // not be, and vice versa. + const auto hasX0 = pj_param_exists(P->params, "X_0"); + const auto hasY0 = pj_param_exists(P->params, "Y_0"); + const auto hasZ0 = pj_param_exists(P->params, "Z_0"); + const auto hasLon0 = pj_param_exists(P->params, "lon_0"); + const auto hasLat0 = pj_param_exists(P->params, "lat_0"); + const auto hash0 = pj_param_exists(P->params, "h_0"); + if( !hasX0 && !hasLon0 ) + { + return pj_default_destructor(P, PJD_ERR_MISSING_ARGS); + } + if ( (hasX0 || hasY0 || hasZ0) && + (hasLon0 || hasLat0 || hash0) ) + { + return pj_default_destructor(P, PJD_ERR_MUTUALLY_EXCLUSIVE_ARGS); + } + if( hasX0 && (!hasY0 || !hasZ0) ) + { + return pj_default_destructor(P, PJD_ERR_MISSING_ARGS); + } + if( hasLon0 && !hasLat0 ) // allow missing h_0 + { + return pj_default_destructor(P, PJD_ERR_MISSING_ARGS); + } + + // Pass a dummy ellipsoid definition that will be overridden just afterwards + PJ* cart = proj_create(P->ctx, "+proj=cart +a=1"); + if (cart == nullptr) + return pj_default_destructor(P, ENOMEM); + /* inherit ellipsoid definition from P to cart */ + pj_inherit_ellipsoid_def (P, cart); + + if( hasX0 ) + { + Q->X0 = pj_param(P->ctx, P->params, "dX_0").f; + Q->Y0 = pj_param(P->ctx, P->params, "dY_0").f; + Q->Z0 = pj_param(P->ctx, P->params, "dZ_0").f; + + // Compute lam0, phi0 from X0,Y0,Z0 + PJ_XYZ xyz; + xyz.x = Q->X0; + xyz.y = Q->Y0; + xyz.z = Q->Z0; + const auto lpz = pj_inv3d(xyz, cart); + Q->sinphi0 = sin(lpz.phi); + Q->cosphi0 = cos(lpz.phi); + Q->sinlam0 = sin(lpz.lam); + Q->coslam0 = cos(lpz.lam); + } + else + { + // Compute X0,Y0,Z0 from lam0, phi0, h0 + PJ_LPZ lpz; + lpz.lam = P->lam0; + lpz.phi = P->phi0; + lpz.z = pj_param(P->ctx, P->params, "dh_0").f; + const auto xyz = pj_fwd3d(lpz, cart); + Q->X0 = xyz.x; + Q->Y0 = xyz.y; + Q->Z0 = xyz.z; + + Q->sinphi0 = sin(P->phi0); + Q->cosphi0 = cos(P->phi0); + Q->sinlam0 = sin(P->lam0); + Q->coslam0 = cos(P->lam0); + } + + proj_destroy(cart); + + P->fwd4d = topocentric_fwd; + P->inv4d = topocentric_inv; + P->left = PJ_IO_UNITS_CARTESIAN; + P->right = PJ_IO_UNITS_CARTESIAN; + return P; +} diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 1d3b7a90..dfd349b5 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -6034,28 +6034,39 @@ void Conversion::_exportToPROJString( !isHeightDepthReversal; bool applyTargetCRSModifiers = applySourceCRSModifiers; + if (formatter->getCRSExport()) { + if (methodEPSGCode == EPSG_CODE_METHOD_GEOCENTRIC_TOPOCENTRIC || + methodEPSGCode == EPSG_CODE_METHOD_GEOGRAPHIC_TOPOCENTRIC) { + throw io::FormattingException("Transformation cannot be exported " + "as a PROJ.4 string (but can be part " + "of a PROJ pipeline)"); + } + } + auto l_sourceCRS = sourceCRS(); + crs::GeographicCRSPtr srcGeogCRS; if (!formatter->getCRSExport() && l_sourceCRS && applySourceCRSModifiers) { - crs::CRS *horiz = l_sourceCRS.get(); - const auto compound = dynamic_cast(horiz); + crs::CRSPtr horiz = l_sourceCRS; + const auto compound = + dynamic_cast(l_sourceCRS.get()); if (compound) { const auto &components = compound->componentReferenceSystems(); if (!components.empty()) { - horiz = components.front().get(); + horiz = components.front().as_nullable(); } } - auto geogCRS = dynamic_cast(horiz); - if (geogCRS) { + srcGeogCRS = std::dynamic_pointer_cast(horiz); + if (srcGeogCRS) { formatter->setOmitProjLongLatIfPossible(true); formatter->startInversion(); - geogCRS->_exportToPROJString(formatter); + srcGeogCRS->_exportToPROJString(formatter); formatter->stopInversion(); formatter->setOmitProjLongLatIfPossible(false); } - auto projCRS = dynamic_cast(horiz); + auto projCRS = dynamic_cast(horiz.get()); if (projCRS) { formatter->startInversion(); formatter->pushOmitZUnitConversion(); @@ -6325,6 +6336,30 @@ void Conversion::_exportToPROJString( } bConversionDone = true; bEllipsoidParametersDone = true; + } else if (methodEPSGCode == EPSG_CODE_METHOD_GEOGRAPHIC_TOPOCENTRIC) { + if (!srcGeogCRS) { + throw io::FormattingException( + "Export of Geographic/Topocentric conversion to a PROJ string " + "requires an input geographic CRS"); + } + + formatter->addStep("cart"); + srcGeogCRS->ellipsoid()->_exportToPROJString(formatter); + + formatter->addStep("topocentric"); + const auto latOrigin = parameterValueNumeric( + EPSG_CODE_PARAMETER_LATITUDE_TOPOGRAPHIC_ORIGIN, + common::UnitOfMeasure::DEGREE); + const auto lonOrigin = parameterValueNumeric( + EPSG_CODE_PARAMETER_LONGITUDE_TOPOGRAPHIC_ORIGIN, + common::UnitOfMeasure::DEGREE); + const auto heightOrigin = parameterValueNumeric( + EPSG_CODE_PARAMETER_ELLIPSOIDAL_HEIGHT_TOPOCENTRIC_ORIGIN, + common::UnitOfMeasure::METRE); + formatter->addParam("lat_0", latOrigin); + formatter->addParam("lon_0", lonOrigin); + formatter->addParam("h_0", heightOrigin); + bConversionDone = true; } auto l_targetCRS = targetCRS(); @@ -6449,7 +6484,9 @@ void Conversion::_exportToPROJString( } if (!bEllipsoidParametersDone) { - auto targetGeogCRS = horiz->extractGeographicCRS(); + auto targetGeodCRS = horiz->extractGeodeticCRS(); + auto targetGeogCRS = + std::dynamic_pointer_cast(targetGeodCRS); if (targetGeogCRS) { if (formatter->getCRSExport()) { targetGeogCRS->addDatumInfoToPROJString(formatter); @@ -6458,6 +6495,8 @@ void Conversion::_exportToPROJString( targetGeogCRS->primeMeridian()->_exportToPROJString( formatter); } + } else if (targetGeodCRS) { + targetGeodCRS->ellipsoid()->_exportToPROJString(formatter); } } diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 67bc1f4e..9f482d19 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -173,6 +173,7 @@ set(SRC_LIBPROJ_CONVERSIONS conversions/geoc.cpp conversions/geocent.cpp conversions/noop.cpp + conversions/topocentric.cpp conversions/set.cpp conversions/unitconvert.cpp ) diff --git a/src/pj_list.h b/src/pj_list.h index bcdc189e..d00e780f 100644 --- a/src/pj_list.h +++ b/src/pj_list.h @@ -155,6 +155,7 @@ PROJ_HEAD(tinshift, "Triangulation based transformation") PROJ_HEAD(tissot, "Tissot Conic") PROJ_HEAD(tmerc, "Transverse Mercator") PROJ_HEAD(tobmerc, "Tobler-Mercator") +PROJ_HEAD(topocentric, "Geocentric/Topocentric conversion") PROJ_HEAD(tpeqd, "Two Point Equidistant") PROJ_HEAD(tpers, "Tilted perspective") PROJ_HEAD(unitconvert, "Unit conversion") diff --git a/src/proj_constants.h b/src/proj_constants.h index a3da2c10..ce3b2157 100644 --- a/src/proj_constants.h +++ b/src/proj_constants.h @@ -651,4 +651,24 @@ #define EPSG_CODE_METHOD_HEIGHT_DEPTH_REVERSAL 1068 #define EPSG_NAME_METHOD_HEIGHT_DEPTH_REVERSAL "Height Depth Reversal" +/* ------------------------------------------------------------------------ */ + +#define EPSG_NAME_METHOD_GEOCENTRIC_TOPOCENTRIC "Geocentric/topocentric conversions" +#define EPSG_CODE_METHOD_GEOCENTRIC_TOPOCENTRIC 9836 + +#define EPSG_NAME_PARAMETER_GEOCENTRIC_X_TOPOCENTRIC_ORIGIN "Geocentric X of topocentric origin" +#define EPSG_CODE_PARAMETER_GEOCENTRIC_X_TOPOCENTRIC_ORIGIN 8837 + +#define EPSG_NAME_PARAMETER_GEOCENTRIC_Y_TOPOCENTRIC_ORIGIN "Geocentric Y of topocentric origin" +#define EPSG_CODE_PARAMETER_GEOCENTRIC_Y_TOPOCENTRIC_ORIGIN 8838 + +#define EPSG_NAME_PARAMETER_GEOCENTRIC_Z_TOPOCENTRIC_ORIGIN "Geocentric Z of topocentric origin" +#define EPSG_CODE_PARAMETER_GEOCENTRIC_Z_TOPOCENTRIC_ORIGIN 8839 + +/* ------------------------------------------------------------------------ */ + +#define EPSG_NAME_METHOD_GEOGRAPHIC_TOPOCENTRIC "Geographic/topocentric conversions" +#define EPSG_CODE_METHOD_GEOGRAPHIC_TOPOCENTRIC 9837 + + #endif /* PROJ_CONSTANTS_INCLUDED */ -- cgit v1.2.3 From 452f1dbb258b573c97ad0083a891b43d0b543cd1 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 24 Nov 2020 01:04:23 +0100 Subject: mutex.cpp: replace NULL by nullptr --- src/mutex.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/mutex.cpp b/src/mutex.cpp index da415e55..60ed5be1 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -184,7 +184,7 @@ void pj_cleanup_lock() #include -static HANDLE mutex_lock = NULL; +static HANDLE mutex_lock = nullptr; #if _WIN32_WINNT >= 0x0600 @@ -199,7 +199,7 @@ static BOOL CALLBACK pj_create_lock(PINIT_ONCE InitOnce, (void)InitOnce; (void)Parameter; (void)Context; - mutex_lock = CreateMutex( NULL, FALSE, NULL ); + mutex_lock = CreateMutex( nullptr, FALSE, nullptr ); return TRUE; } #endif @@ -213,10 +213,10 @@ static void pj_init_lock() { #if _WIN32_WINNT >= 0x0600 static INIT_ONCE sInitOnce = INIT_ONCE_STATIC_INIT; - InitOnceExecuteOnce( &sInitOnce, pj_create_lock, NULL, NULL ); + InitOnceExecuteOnce( &sInitOnce, pj_create_lock, nullptr, nullptr ); #else - if( mutex_lock == NULL ) - mutex_lock = CreateMutex( NULL, FALSE, NULL ); + if( mutex_lock == nullptr ) + mutex_lock = CreateMutex( nullptr, FALSE, nullptr ); #endif } @@ -228,7 +228,7 @@ static void pj_init_lock() void pj_acquire_lock() { - if( mutex_lock == NULL ) + if( mutex_lock == nullptr ) pj_init_lock(); WaitForSingleObject( mutex_lock, INFINITE ); @@ -242,7 +242,7 @@ void pj_acquire_lock() void pj_release_lock() { - if( mutex_lock == NULL ) + if( mutex_lock == nullptr ) pj_init_lock(); else ReleaseMutex( mutex_lock ); @@ -253,10 +253,10 @@ void pj_release_lock() /************************************************************************/ void pj_cleanup_lock() { - if( mutex_lock != NULL ) + if( mutex_lock != nullptr ) { CloseHandle( mutex_lock ); - mutex_lock = NULL; + mutex_lock = nullptr; } } -- cgit v1.2.3 From 2414eb2bb655588b4b7e9fe86bba70592bd7f911 Mon Sep 17 00:00:00 2001 From: Charles Karney Date: Mon, 23 Nov 2020 19:13:24 -0500 Subject: Sync w GeographicLib 1.51. Remove C99 compatibility functions. (#2445) Should be no changes in the compiled code. --- src/geodesic.c | 149 ++++++++------------------------------------------------- src/geodesic.h | 6 +-- 2 files changed, 22 insertions(+), 133 deletions(-) (limited to 'src') diff --git a/src/geodesic.c b/src/geodesic.c index 7d612d3f..53ec9ed6 100644 --- a/src/geodesic.c +++ b/src/geodesic.c @@ -18,7 +18,7 @@ * * See the comments in geodesic.h for documentation. * - * Copyright (c) Charles Karney (2012-2019) and licensed + * Copyright (c) Charles Karney (2012-2020) and licensed * under the MIT/X11 License. For more information, see * https://geographiclib.sourceforge.io/ */ @@ -28,15 +28,6 @@ #include #include -#if !defined(HAVE_C99_MATH) -#if defined(PROJ_LIB) -/* PROJ requires C99 so HAVE_C99_MATH is implicit */ -#define HAVE_C99_MATH 1 -#else -#define HAVE_C99_MATH 0 -#endif -#endif - #if !defined(__cplusplus) #define nullptr 0 #endif @@ -88,19 +79,7 @@ static void Init() { tolb = tol0 * tol2; xthresh = 1000 * tol2; degree = pi/180; -#if defined(NAN) - NaN = NAN; /* NAN is defined in C99 */ -#else -#if HAVE_C99_MATH NaN = nan("0"); -#else - { - real minus1 = -1; - /* cppcheck-suppress wrongmathcall */ - NaN = sqrt(minus1); - } -#endif -#endif init = 1; } } @@ -116,95 +95,6 @@ enum captype { OUT_ALL = 0x7F80U }; -#if HAVE_C99_MATH -#define hypotx hypot -/* no need to redirect log1px, since it's only used by atanhx */ -#define atanhx atanh -#define copysignx copysign -#define cbrtx cbrt -#define remainderx remainder -#define remquox remquo -#else -/* Replacements for C99 math functions */ - -static real hypotx(real x, real y) { - x = fabs(x); y = fabs(y); - if (x < y) { - x /= y; /* y is nonzero */ - return y * sqrt(1 + x * x); - } else { - y /= (x != 0 ? x : 1); - return x * sqrt(1 + y * y); - } -} - -static real log1px(real x) { - volatile real - y = 1 + x, - z = y - 1; - /* Here's the explanation for this magic: y = 1 + z, exactly, and z - * approx x, thus log(y)/z (which is nearly constant near z = 0) returns - * a good approximation to the true log(1 + x)/x. The multiplication x * - * (log(y)/z) introduces little additional error. */ - return z == 0 ? x : x * log(y) / z; -} - -static real atanhx(real x) { - real y = fabs(x); /* Enforce odd parity */ - y = log1px(2 * y/(1 - y))/2; - return x > 0 ? y : (x < 0 ? -y : x); /* atanh(-0.0) = -0.0 */ -} - -static real copysignx(real x, real y) { - /* 1/y trick to get the sign of -0.0 */ - return fabs(x) * (y < 0 || (y == 0 && 1/y < 0) ? -1 : 1); -} - -static real cbrtx(real x) { - real y = pow(fabs(x), 1/(real)(3)); /* Return the real cube root */ - return x > 0 ? y : (x < 0 ? -y : x); /* cbrt(-0.0) = -0.0 */ -} - -static real remainderx(real x, real y) { - real z; - y = fabs(y); /* The result doesn't depend on the sign of y */ - z = fmod(x, y); - if (z == 0) - /* This shouldn't be necessary. However, before version 14 (2015), - * Visual Studio had problems dealing with -0.0. Specifically - * VC 10,11,12 and 32-bit compile: fmod(-0.0, 360.0) -> +0.0 - * python 2.7 on Windows 32-bit machines has the same problem. */ - z = copysignx(z, x); - else if (2 * fabs(z) == y) - z -= fmod(x, 2 * y) - z; /* Implement ties to even */ - else if (2 * fabs(z) > y) - z += (z < 0 ? y : -y); /* Fold remaining cases to (-y/2, y/2) */ - return z; -} - -static real remquox(real x, real y, int* n) { - real z = remainderx(x, y); - if (n) { - real - a = remainderx(x, 2 * y), - b = remainderx(x, 4 * y), - c = remainderx(x, 8 * y); - *n = (a > z ? 1 : (a < z ? -1 : 0)); - *n += (b > a ? 2 : (b < a ? -2 : 0)); - *n += (c > b ? 4 : (c < b ? -4 : 0)); - if (y < 0) *n *= -1; - if (y != 0) { - if (x/y > 0 && *n <= 0) - *n += 8; - else if (x/y < 0 && *n >= 0) - *n -= 8; - } - } - return z; -} - -#endif - static real sq(real x) { return x * x; } static real sumx(real u, real v, real* t) { @@ -237,13 +127,13 @@ static void swapx(real* x, real* y) { real t = *x; *x = *y; *y = t; } static void norm2(real* sinx, real* cosx) { - real r = hypotx(*sinx, *cosx); + real r = hypot(*sinx, *cosx); *sinx /= r; *cosx /= r; } static real AngNormalize(real x) { - x = remainderx(x, (real)(360)); + x = remainder(x, (real)(360)); return x != -180 ? x : 180; } @@ -275,7 +165,7 @@ static void sincosdx(real x, real* sinx, real* cosx) { /* In order to minimize round-off errors, this function exactly reduces * the argument to the range [-45, 45] before converting it to radians. */ real r, s, c; int q; - r = remquox(x, (real)(90), &q); + r = remquo(x, (real)(90), &q); /* now abs(r) <= 45 */ r *= degree; /* Possibly could call the gnu extension sincos */ @@ -396,7 +286,7 @@ void geod_init(struct geod_geodesic* g, real a, real f) { g->b = g->a * g->f1; g->c2 = (sq(g->a) + sq(g->b) * (g->e2 == 0 ? 1 : - (g->e2 > 0 ? atanhx(sqrt(g->e2)) : atan(sqrt(-g->e2))) / + (g->e2 > 0 ? atanh(sqrt(g->e2)) : atan(sqrt(-g->e2))) / sqrt(fabs(g->e2))))/2; /* authalic radius squared */ /* The sig12 threshold for "really short". Using the auxiliary sphere * solution with dnm computed at (bet1 + bet2) / 2, the relative error in the @@ -446,7 +336,7 @@ static void geod_lineinit_int(struct geod_geodesicline* l, l->salp0 = l->salp1 * cbet1; /* alp0 in [0, pi/2 - |bet1|] */ /* Alt: calp0 = hypot(sbet1, calp1 * cbet1). The following * is slightly better (consider the case salp1 = 0). */ - l->calp0 = hypotx(l->calp1, l->salp1 * sbet1); + l->calp0 = hypot(l->calp1, l->salp1 * sbet1); /* Evaluate sig with tan(bet1) = tan(sig1) * cos(alp1). * sig = 0 is nearest northward crossing of equator. * With bet1 = 0, alp1 = pi/2, we have sig1 = 0 (equatorial line). @@ -550,9 +440,8 @@ real geod_genposition(const struct geod_geodesicline* l, (pS12 ? GEOD_AREA : GEOD_NONE); outmask &= l->caps & OUT_ALL; - if (!( /*Init() &&*/ - (flags & GEOD_ARCMODE || (l->caps & (GEOD_DISTANCE_IN & OUT_ALL))) )) - /* Uninitialized or impossible distance calculation requested */ + if (!( (flags & GEOD_ARCMODE || (l->caps & (GEOD_DISTANCE_IN & OUT_ALL))) )) + /* Impossible distance calculation requested */ return NaN; if (flags & GEOD_ARCMODE) { @@ -617,7 +506,7 @@ real geod_genposition(const struct geod_geodesicline* l, /* sin(bet2) = cos(alp0) * sin(sig2) */ sbet2 = l->calp0 * ssig2; /* Alt: cbet2 = hypot(csig2, salp0 * ssig2); */ - cbet2 = hypotx(l->salp0, l->calp0 * csig2); + cbet2 = hypot(l->salp0, l->calp0 * csig2); if (cbet2 == 0) /* I.e., salp0 = 0, csig2 = 0. Break the degeneracy in this case */ cbet2 = csig2 = tiny; @@ -630,7 +519,7 @@ real geod_genposition(const struct geod_geodesicline* l, s12_a12; if (outmask & GEOD_LONGITUDE) { - real E = copysignx(1, l->salp0); /* east or west going? */ + real E = copysign(1, l->salp0); /* east or west going? */ /* tan(omg2) = sin(alp0) * tan(sig2) */ somg2 = l->salp0 * ssig2; comg2 = csig2; /* No need to normalize */ /* omg12 = omg2 - omg1 */ @@ -1045,7 +934,7 @@ static real geod_geninverse_int(const struct geod_geodesic* g, real /* From Lambda12: sin(alp1) * cos(bet1) = sin(alp0) */ salp0 = salp1 * cbet1, - calp0 = hypotx(calp1, salp1 * sbet1); /* calp0 > 0 */ + calp0 = hypot(calp1, salp1 * sbet1); /* calp0 > 0 */ real alp12; if (calp0 != 0 && salp0 != 0) { real @@ -1279,8 +1168,8 @@ real Astroid(real x, real y) { * of precision due to cancellation. The result is unchanged because * of the way the T is used in definition of u. */ T3 += T3 < 0 ? -sqrt(disc) : sqrt(disc); /* T3 = (r * t)^3 */ - /* N.B. cbrtx always returns the real root. cbrtx(-8) = -2. */ - T = cbrtx(T3); /* T = r * t */ + /* N.B. cbrt always returns the real root. cbrt(-8) = -2. */ + T = cbrt(T3); /* T = r * t */ /* T can be zero; but then r2 / T -> 0. */ u += T + (T != 0 ? r2 / T : 0); } else { @@ -1348,7 +1237,7 @@ real InverseStart(const struct geod_geodesic* g, sbet12 + cbet2 * sbet1 * sq(somg12) / (1 + comg12) : sbet12a - cbet2 * sbet1 * sq(somg12) / (1 - comg12); - ssig12 = hypotx(salp1, calp1); + ssig12 = hypot(salp1, calp1); csig12 = sbet1 * sbet2 + cbet1 * cbet2 * comg12; if (shortline && ssig12 < g->etol2) { @@ -1500,7 +1389,7 @@ real Lambda12(const struct geod_geodesic* g, /* sin(alp1) * cos(bet1) = sin(alp0) */ salp0 = salp1 * cbet1; - calp0 = hypotx(calp1, salp1 * sbet1); /* calp0 > 0 */ + calp0 = hypot(calp1, salp1 * sbet1); /* calp0 > 0 */ /* tan(bet1) = tan(sig1) * cos(alp1) * tan(omg1) = sin(alp0) * tan(sig1) = tan(omg1)=tan(alp1)*sin(bet1) */ @@ -1850,8 +1739,8 @@ int transit(real lon1, real lon2) { int transitdirect(real lon1, real lon2) { /* Compute exactly the parity of int(ceil(lon2 / 360)) - int(ceil(lon1 / 360)) */ - lon1 = remainderx(lon1, (real)(720)); - lon2 = remainderx(lon2, (real)(720)); + lon1 = remainder(lon1, (real)(720)); + lon2 = remainder(lon2, (real)(720)); return ( (lon2 <= 0 && lon2 > -360 ? 1 : 0) - (lon1 <= 0 && lon1 > -360 ? 1 : 0) ); } @@ -1891,7 +1780,7 @@ void accneg(real s[]) { void accrem(real s[], real y) { /* Reduce to [-y/2, y/2]. */ - s[0] = remainderx(s[0], y); + s[0] = remainder(s[0], y); accadd(s, (real)(0)); } @@ -2093,7 +1982,7 @@ real areareduceA(real area[], real area0, real areareduceB(real area, real area0, int crossings, boolx reverse, boolx sign) { - area = remainderx(area, area0); + area = remainder(area, area0); if (crossings & 1) area += (area < 0 ? 1 : -1) * area0/2; /* area is with the clockwise sense. If !reverse convert to diff --git a/src/geodesic.h b/src/geodesic.h index b21e6c8c..548fbf47 100644 --- a/src/geodesic.h +++ b/src/geodesic.h @@ -107,12 +107,12 @@ * twice about restructuring the internals of the C code since this may make * porting fixes from the C++ code more difficult. * - * Copyright (c) Charles Karney (2012-2019) and licensed + * Copyright (c) Charles Karney (2012-2020) and licensed * under the MIT/X11 License. For more information, see * https://geographiclib.sourceforge.io/ * * This library was distributed with - * GeographicLib 1.50. + * GeographicLib 1.51. **********************************************************************/ #if !defined(GEODESIC_H) @@ -127,7 +127,7 @@ * The minor version of the geodesic library. (This tracks the version of * GeographicLib.) **********************************************************************/ -#define GEODESIC_VERSION_MINOR 50 +#define GEODESIC_VERSION_MINOR 51 /** * The patch level of the geodesic library. (This tracks the version of * GeographicLib.) -- cgit v1.2.3 From d6f6862352d0caeb827c0c3ec98ccf9aa2f9a1d2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 24 Nov 2020 16:41:06 +0100 Subject: createOperation(): add a ballpark vertical transformation when dealing with GEOIDMODEL[] --- src/iso19111/coordinateoperation.cpp | 99 +++++++++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 1d3b7a90..0f1c680b 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -11233,6 +11233,12 @@ struct CoordinateOperationFactory::Private { const crs::GeographicCRS *geogDst, std::vector &res); + static void createOperationsVertToGeogBallpark( + const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS, + Private::Context &context, const crs::VerticalCRS *vertSrc, + const crs::GeographicCRS *geogDst, + std::vector &res); + static void createOperationsBoundToBound( const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS, Private::Context &context, const crs::BoundCRS *boundSrc, @@ -11334,6 +11340,7 @@ struct PrecomputedOpCharacteristics { bool gridsKnown_ = false; size_t stepCount_ = 0; bool isApprox_ = false; + bool hasBallparkVertical_ = false; bool isNullTransformation_ = false; PrecomputedOpCharacteristics() = default; @@ -11341,10 +11348,12 @@ struct PrecomputedOpCharacteristics { bool isPROJExportable, bool hasGrids, bool gridsAvailable, bool gridsKnown, size_t stepCount, bool isApprox, + bool hasBallparkVertical, bool isNullTransformation) : area_(area), accuracy_(accuracy), isPROJExportable_(isPROJExportable), hasGrids_(hasGrids), gridsAvailable_(gridsAvailable), gridsKnown_(gridsKnown), stepCount_(stepCount), isApprox_(isApprox), + hasBallparkVertical_(hasBallparkVertical), isNullTransformation_(isNullTransformation) {} }; @@ -11388,6 +11397,15 @@ struct SortFunction { return false; } + if (!iterA->second.hasBallparkVertical_ && + iterB->second.hasBallparkVertical_) { + return true; + } + if (iterA->second.hasBallparkVertical_ && + !iterB->second.hasBallparkVertical_) { + return false; + } + if (!iterA->second.isNullTransformation_ && iterB->second.isNullTransformation_) { return true; @@ -11654,7 +11672,9 @@ struct FilterResults { ? CoordinateOperationContext::SpatialCriterion:: STRICT_CONTAINMENT : context->getSpatialCriterion(); - bool hasFoundOpWithExtent = false; + bool hasOnlyBallpark = true; + bool hasNonBallparkWithoutExtent = false; + bool hasNonBallparkOpWithExtent = false; const bool allowBallpark = context->getAllowBallparkTransformations(); for (const auto &op : sourceList) { if (desiredAccuracy != 0) { @@ -11669,9 +11689,15 @@ struct FilterResults { if (areaOfInterest) { bool emptyIntersection = false; auto extent = getExtent(op, true, emptyIntersection); - if (!extent) + if (!extent) { + if (!op->hasBallparkTransformation()) { + hasNonBallparkWithoutExtent = true; + } continue; - hasFoundOpWithExtent = true; + } + if (!op->hasBallparkTransformation()) { + hasNonBallparkOpWithExtent = true; + } bool extentContains = extent->contains(NN_NO_CHECK(areaOfInterest)); if (!hasOpThatContainsAreaOfInterestAndNoGrid && @@ -11698,9 +11724,15 @@ struct FilterResults { BOTH) { bool emptyIntersection = false; auto extent = getExtent(op, true, emptyIntersection); - if (!extent) + if (!extent) { + if (!op->hasBallparkTransformation()) { + hasNonBallparkWithoutExtent = true; + } continue; - hasFoundOpWithExtent = true; + } + if (!op->hasBallparkTransformation()) { + hasNonBallparkOpWithExtent = true; + } bool extentContainsExtent1 = !extent1 || extent->contains(NN_NO_CHECK(extent1)); bool extentContainsExtent2 = @@ -11730,12 +11762,16 @@ struct FilterResults { } } } + if (!op->hasBallparkTransformation()) { + hasOnlyBallpark = false; + } res.emplace_back(op); } // In case no operation has an extent and no result is found, // retain all initial operations that match accuracy criterion. - if (res.empty() && !hasFoundOpWithExtent) { + if ((res.empty() && !hasNonBallparkOpWithExtent) || + (hasOnlyBallpark && hasNonBallparkWithoutExtent)) { for (const auto &op : sourceList) { if (desiredAccuracy != 0) { const double accuracy = getAccuracy(op); @@ -11839,6 +11875,8 @@ struct FilterResults { area, getAccuracy(op), isPROJExportable, hasGrids, gridsAvailable, gridsKnown, stepCount, op->hasBallparkTransformation(), + op->nameStr().find("ballpark vertical transformation") != + std::string::npos, isNullTransformation(op->nameStr())); } @@ -13647,11 +13685,17 @@ bool CoordinateOperationFactory::Private::createOperationsFromDatabase( ENTER_FUNCTION(); if (geogSrc && vertDst) { - res = createOperationsGeogToVertFromGeoid(sourceCRS, targetCRS, vertDst, - context); + createOperationsFromDatabase(targetCRS, sourceCRS, context, geodDst, + geodSrc, geogDst, geogSrc, vertDst, + vertSrc, res); + res = applyInverse(res); } else if (geogDst && vertSrc) { res = applyInverse(createOperationsGeogToVertFromGeoid( targetCRS, sourceCRS, vertSrc, context)); + if (!res.empty()) { + createOperationsVertToGeogBallpark(sourceCRS, targetCRS, context, + vertSrc, geogDst, res); + } } if (!res.empty()) { @@ -14762,17 +14806,32 @@ void CoordinateOperationFactory::Private::createOperationsVertToGeog( match.get(), util::IComparable::Criterion::EQUIVALENT) && !match->identifiers().empty()) { - res = createOperations( + auto resTmp = createOperations( NN_NO_CHECK( util::nn_dynamic_pointer_cast( match)), targetCRS, context); + res.insert(res.end(), resTmp.begin(), resTmp.end()); return; } } } } + createOperationsVertToGeogBallpark(sourceCRS, targetCRS, context, vertSrc, + geogDst, res); +} + +// --------------------------------------------------------------------------- + +void CoordinateOperationFactory::Private::createOperationsVertToGeogBallpark( + const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS, + Private::Context &, const crs::VerticalCRS *vertSrc, + const crs::GeographicCRS *geogDst, + std::vector &res) { + + ENTER_FUNCTION(); + const auto &srcAxis = vertSrc->coordinateSystem()->axisList()[0]; const double convSrc = srcAxis->unit().conversionToSI(); double convDst = 1.0; @@ -14791,12 +14850,24 @@ void CoordinateOperationFactory::Private::createOperationsVertToGeog( ((srcIsUp && dstIsDown) || (srcIsDown && dstIsUp)); const double factor = convSrc / convDst; - auto conv = Transformation::createChangeVerticalUnit( - util::PropertyMap().set( - common::IdentifiedObject::NAME_KEY, + + const auto &sourceCRSExtent = getExtent(sourceCRS); + const auto &targetCRSExtent = getExtent(targetCRS); + const bool sameExtent = + sourceCRSExtent && targetCRSExtent && + sourceCRSExtent->_isEquivalentTo( + targetCRSExtent.get(), util::IComparable::Criterion::EQUIVALENT); + + util::PropertyMap map; + map.set(common::IdentifiedObject::NAME_KEY, buildTransfName(sourceCRS->nameStr(), targetCRS->nameStr()) + - BALLPARK_VERTICAL_TRANSFORMATION_NO_ELLIPSOID_VERT_HEIGHT), - sourceCRS, targetCRS, + BALLPARK_VERTICAL_TRANSFORMATION_NO_ELLIPSOID_VERT_HEIGHT) + .set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY, + sameExtent ? NN_NO_CHECK(sourceCRSExtent) + : metadata::Extent::WORLD); + + auto conv = Transformation::createChangeVerticalUnit( + map, sourceCRS, targetCRS, common::Scale(heightDepthReversal ? -factor : factor), {}); conv->setHasBallparkTransformation(true); res.push_back(conv); -- cgit v1.2.3 From 4caf32aedd4da6b1fd1b1ce0e04a1a08dc1e3f33 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 24 Nov 2020 19:16:12 +0100 Subject: Add option to allow export of Geographic/Projected 3D CRS in WKT1_GDAL as CompoundCRS with a VerticalCRS being an ellipsoidal height, which is not conformant. But needed for LAS 1.4 that only supports WKT1 --- src/apps/projinfo.cpp | 7 +++++++ src/iso19111/c_api.cpp | 12 ++++++++++++ src/iso19111/crs.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ src/iso19111/io.cpp | 25 +++++++++++++++++++++++++ 4 files changed, 87 insertions(+) (limited to 'src') diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 3d57dcd6..da885fbb 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -72,6 +72,7 @@ struct OutputOptions { bool singleLine = false; bool strict = true; bool ballparkAllowed = true; + bool allowEllipsoidalHeightAsVerticalCRS = false; }; } // anonymous namespace @@ -95,6 +96,8 @@ static void usage() { << " [--pivot-crs always|if_no_direct_transformation|" << "never|{auth:code[,auth:code]*}]" << std::endl << " [--show-superseded] [--hide-ballpark]" << std::endl + << " [--allow-ellipsoidal-height-as-vertical-crs]" + << std::endl << " [--boundcrs-to-wgs84]" << std::endl << " [--main-db-path path] [--aux-db-path path]*" << std::endl @@ -487,6 +490,8 @@ static void outputObject( formatter->setMultiLine(false); } formatter->setStrict(outputOpt.strict); + formatter->setAllowEllipsoidalHeightAsVerticalCRS( + outputOpt.allowEllipsoidalHeightAsVerticalCRS); auto wkt = wktExportable->exportToWKT(formatter.get()); if (outputOpt.c_ify) { wkt = c_ify_string(wkt); @@ -1070,6 +1075,8 @@ int main(int argc, char **argv) { showSuperseded = true; } else if (arg == "--lax") { outputOpt.strict = false; + } else if (arg == "--allow-ellipsoidal-height-as-vertical-crs") { + outputOpt.allowEllipsoidalHeightAsVerticalCRS = true; } else if (arg == "--hide-ballpark") { outputOpt.ballparkAllowed = false; } else if (ci_equal(arg, "--3d")) { diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index cbbdcaa8..d3c01e8f 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -1421,6 +1421,13 @@ const char *proj_get_id_code(const PJ *obj, int index) { * variants, for WKT1_GDAL for ProjectedCRS with easting/northing ordering * (otherwise stripped), but not for WKT1_ESRI. Setting to YES will output * them unconditionally, and to NO will omit them unconditionally. + *
  • STRICT=YES/NO. Default is YES. If NO, a Geographic 3D CRS can be for + * example exported as WKT1_GDAL with 3 axes, whereas this is normally not + * allowed.
  • + *
  • ALLOW_ELLIPSOIDAL_HEIGHT_AS_VERTICAL_CRS=YES/NO. Default is NO. If set + * to YES and type == PJ_WKT1_GDAL, a Geographic 3D CRS or a Projected 3D CRS + * will be exported as a compound CRS whose vertical part represents an + * ellipsoidal height (for example for use with LAS 1.4 WKT1).
  • * * @return a string, or NULL in case of error. */ @@ -1471,6 +1478,11 @@ const char *proj_as_wkt(PJ_CONTEXT *ctx, const PJ *obj, PJ_WKT_TYPE type, } } else if ((value = getOptionValue(*iter, "STRICT="))) { formatter->setStrict(ci_equal(value, "YES")); + } else if ((value = getOptionValue( + *iter, + "ALLOW_ELLIPSOIDAL_HEIGHT_AS_VERTICAL_CRS="))) { + formatter->setAllowEllipsoidalHeightAsVerticalCRS( + ci_equal(value, "YES")); } else { std::string msg("Unknown option :"); msg += *iter; diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 5d2c6d7b..573dd6db 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -1620,6 +1620,34 @@ static bool exportAsESRIWktCompoundCRSWithEllipsoidalHeight( vertCRSList.front()->_exportToWKT(formatter); return true; } + +// --------------------------------------------------------------------------- + +// Try to format a Geographic/ProjectedCRS 3D CRS as a +// GEOGCS[]/PROJCS[],VERTCS["Ellipsoid (metre)",DATUM["Ellipsoid",2002],...] +static bool exportAsWKT1CompoundCRSWithEllipsoidalHeight( + const CRSNNPtr &base2DCRS, + const cs::CoordinateSystemAxisNNPtr &verticalAxis, + io::WKTFormatter *formatter) { + std::string verticalCRSName = "Ellipsoid ("; + verticalCRSName += verticalAxis->unit().name(); + verticalCRSName += ')'; + auto vertDatum = datum::VerticalReferenceFrame::create( + util::PropertyMap() + .set(common::IdentifiedObject::NAME_KEY, "Ellipsoid") + .set("VERT_DATUM_TYPE", "2002")); + auto vertCRS = VerticalCRS::create( + util::PropertyMap().set(common::IdentifiedObject::NAME_KEY, + verticalCRSName), + vertDatum.as_nullable(), nullptr, + cs::VerticalCS::create(util::PropertyMap(), verticalAxis)); + formatter->startNode(io::WKTConstants::COMPD_CS, false); + formatter->addQuotedString(base2DCRS->nameStr() + " + " + verticalCRSName); + base2DCRS->_exportToWKT(formatter); + vertCRS->_exportToWKT(formatter); + formatter->endNode(); + return true; +} //! @endcond // --------------------------------------------------------------------------- @@ -1687,6 +1715,13 @@ void GeodeticCRS::_exportToWKT(io::WKTFormatter *formatter) const { return; } + if (formatter->isAllowedEllipsoidalHeightAsVerticalCRS()) { + if (exportAsWKT1CompoundCRSWithEllipsoidalHeight( + geogCRS2D, axisList[2], formatter)) { + return; + } + } + io::FormattingException::Throw( "WKT1 does not support Geographic 3D CRS."); } @@ -3640,6 +3675,14 @@ void ProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const { return; } + if (!formatter->useESRIDialect() && + formatter->isAllowedEllipsoidalHeightAsVerticalCRS()) { + if (exportAsWKT1CompoundCRSWithEllipsoidalHeight( + projCRS2D, axisList[2], formatter)) { + return; + } + } + io::FormattingException::Throw( "Projected 3D CRS can only be exported since WKT2:2019"); } diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 713a471d..b6a09bb6 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -140,6 +140,7 @@ struct WKTFormatter::Private { bool primeMeridianInDegree_ = false; bool use2019Keywords_ = false; bool useESRIDialect_ = false; + bool allowEllipsoidalHeightAsVerticalCRS_ = false; OutputAxisRule outputAxis_ = WKTFormatter::OutputAxisRule::YES; }; Params params_{}; @@ -251,6 +252,8 @@ WKTFormatter::setOutputAxis(OutputAxisRule outputAxisIn) noexcept { * * The default is strict mode, in which case a FormattingException can be * thrown. + * In non-strict mode, a Geographic 3D CRS can be for example exported as + * WKT1_GDAL with 3 axes, whereas this is normally not allowed. */ WKTFormatter &WKTFormatter::setStrict(bool strictIn) noexcept { d->params_.strict_ = strictIn; @@ -264,6 +267,28 @@ bool WKTFormatter::isStrict() const noexcept { return d->params_.strict_; } // --------------------------------------------------------------------------- +/** \brief Set whether the formatter should export, in WKT1, a Geographic or + * Projected 3D CRS as a compound CRS whose vertical part represents an + * ellipsoidal height. + */ +WKTFormatter & +WKTFormatter::setAllowEllipsoidalHeightAsVerticalCRS(bool allow) noexcept { + d->params_.allowEllipsoidalHeightAsVerticalCRS_ = allow; + return *this; +} + +// --------------------------------------------------------------------------- + +/** \brief Return whether the formatter should export, in WKT1, a Geographic or + * Projected 3D CRS as a compound CRS whose vertical part represents an + * ellipsoidal height. + */ +bool WKTFormatter::isAllowedEllipsoidalHeightAsVerticalCRS() const noexcept { + return d->params_.allowEllipsoidalHeightAsVerticalCRS_; +} + +// --------------------------------------------------------------------------- + /** Returns the WKT string from the formatter. */ const std::string &WKTFormatter::toString() const { if (d->indentLevel_ > 0 || d->level_ > 0) { -- cgit v1.2.3 From 83754e1f77bc407f6fa5fd34e07d3625e619ce41 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 26 Nov 2020 21:12:00 +0100 Subject: Fix mingw_w64 warning about pj_acquire_lock() prototype being missing --- src/mutex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mutex.cpp b/src/mutex.cpp index 9fc78acf..b1a23ccd 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -33,8 +33,8 @@ #include "proj.h" #ifndef _WIN32 #include "proj_config.h" -#include "proj_internal.h" #endif +#include "proj_internal.h" /* on win32 we always use win32 mutexes, even if pthreads are available */ #if defined(_WIN32) && !defined(MUTEX_stub) -- cgit v1.2.3 From b27efedef0b3deb488d322d42b3d5b652ab55662 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 26 Nov 2020 18:49:25 +0100 Subject: PRIMEM WKT handling: fixes on import for 'sexagesimal DMS' or from WKT1:GDAL/ESRI when GEOGCS UNIT != Degree; morph to ESRI the PRIMEM name on export --- src/iso19111/datum.cpp | 17 +++++++++++ src/iso19111/io.cpp | 76 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 89 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 60244779..8e1b8257 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -351,6 +351,23 @@ void PrimeMeridian::_exportToWKT( if (!(isWKT2 && formatter->primeMeridianOmittedIfGreenwich() && l_name == "Greenwich")) { formatter->startNode(io::WKTConstants::PRIMEM, !identifiers().empty()); + + if (formatter->useESRIDialect()) { + bool aliasFound = false; + const auto &dbContext = formatter->databaseContext(); + if (dbContext) { + auto l_alias = dbContext->getAliasFromOfficialName( + l_name, "prime_meridian", "ESRI"); + if (!l_alias.empty()) { + l_name = l_alias; + aliasFound = true; + } + } + if (!aliasFound) { + l_name = io::WKTFormatter::morphNameToESRI(l_name); + } + } + formatter->addQuotedString(l_name); const auto &l_long = longitude(); if (formatter->primeMeridianInDegree()) { diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 867a0d53..52d46d27 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -1978,14 +1978,80 @@ PrimeMeridianNNPtr WKTParser::Private::buildPrimeMeridian( try { double angleValue = asDouble(children[1]); - // Correct for GDAL WKT1 departure + // Correct for GDAL WKT1 and WKT1-ESRI departure if (name == "Paris" && std::fabs(angleValue - 2.33722917) < 1e-8 && - unit == UnitOfMeasure::GRAD) { + unit._isEquivalentTo(UnitOfMeasure::GRAD, + util::IComparable::Criterion::EQUIVALENT)) { angleValue = 2.5969213; + } else { + static const struct { + const char *name; + int deg; + int min; + double sec; + } primeMeridiansDMS[] = { + {"Lisbon", -9, 7, 54.862}, {"Bogota", -74, 4, 51.3}, + {"Madrid", -3, 41, 14.55}, {"Rome", 12, 27, 8.4}, + {"Bern", 7, 26, 22.5}, {"Jakarta", 106, 48, 27.79}, + {"Ferro", -17, 40, 0}, {"Brussels", 4, 22, 4.71}, + {"Stockholm", 18, 3, 29.8}, {"Athens", 23, 42, 58.815}, + {"Oslo", 10, 43, 22.5}, {"Paris RGS", 2, 20, 13.95}, + {"Paris_RGS", 2, 20, 13.95}}; + + // Current epsg.org output may use the EPSG:9110 "sexagesimal DMS" + // unit and a DD.MMSSsss value, but this will likely be changed to + // use decimal degree. + // Or WKT1 may for example use the Paris RGS decimal degree value + // but with a GEOGCS with UNIT["Grad"] + for (const auto &pmDef : primeMeridiansDMS) { + if (name == pmDef.name) { + double dmsAsDecimalValue = + (pmDef.deg >= 0 ? 1 : -1) * + (std::abs(pmDef.deg) + pmDef.min / 100. + + pmDef.sec / 10000.); + double dmsAsDecimalDegreeValue = + (pmDef.deg >= 0 ? 1 : -1) * + (std::abs(pmDef.deg) + pmDef.min / 60. + + pmDef.sec / 3600.); + if (std::fabs(angleValue - dmsAsDecimalValue) < 1e-8 || + std::fabs(angleValue - dmsAsDecimalDegreeValue) < + 1e-8) { + angleValue = dmsAsDecimalDegreeValue; + unit = UnitOfMeasure::DEGREE; + } + break; + } + } + } + + auto &properties = buildProperties(node); + if (dbContext_ && esriStyle_) { + std::string outTableName; + std::string codeFromAlias; + std::string authNameFromAlias; + auto authFactory = AuthorityFactory::create(NN_NO_CHECK(dbContext_), + std::string()); + auto officialName = authFactory->getOfficialNameFromAlias( + name, "prime_meridian", "ESRI", false, outTableName, + authNameFromAlias, codeFromAlias); + if (!officialName.empty()) { + properties.set(IdentifiedObject::NAME_KEY, officialName); + if (!authNameFromAlias.empty()) { + auto identifiers = ArrayOfBaseObject::create(); + identifiers->add(Identifier::create( + codeFromAlias, + PropertyMap() + .set(Identifier::CODESPACE_KEY, authNameFromAlias) + .set(Identifier::AUTHORITY_KEY, + authNameFromAlias))); + properties.set(IdentifiedObject::IDENTIFIERS_KEY, + identifiers); + } + } } Angle angle(angleValue, unit); - return PrimeMeridian::create(buildProperties(node), angle); + return PrimeMeridian::create(properties, angle); } catch (const std::exception &e) { throw buildRethrow(__FUNCTION__, e); } @@ -2737,6 +2803,9 @@ WKTParser::Private::buildGeodeticCRS(const WKTNodeNNPtr &node) { throw ParsingException("Missing DATUM or ENSEMBLE node"); } + // Do that now so that esriStyle_ can be set before buildPrimeMeridian() + auto props = buildProperties(node); + auto &dynamicNode = nodeP->lookForChild(WKTConstants::DYNAMIC); auto &csNode = nodeP->lookForChild(WKTConstants::CS_); @@ -2774,7 +2843,6 @@ WKTParser::Private::buildGeodeticCRS(const WKTNodeNNPtr &node) { angularUnit = primeMeridian->longitude().unit(); } - auto props = buildProperties(node); addExtensionProj4ToProp(nodeP, props); // No explicit AXIS node ? (WKT1) -- cgit v1.2.3 From f5b4060847bf780c12b399b98e06ebc56e3ae8e3 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 27 Nov 2020 00:39:49 +0100 Subject: formatting fixes --- src/filemanager.cpp | 8 ++++---- src/grids.cpp | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/filemanager.cpp b/src/filemanager.cpp index b3b074a2..b51205eb 100644 --- a/src/filemanager.cpp +++ b/src/filemanager.cpp @@ -1369,10 +1369,10 @@ static bool dontReadUserWritableDirectory() { return envVar != nullptr && envVar[0] != '\0'; } -static void * -pj_open_lib_internal(PJ_CONTEXT *ctx, const char *name, const char *mode, - void *(*open_file)(PJ_CONTEXT *, const char *, const char *), - char *out_full_filename, size_t out_full_filename_size) { +static void *pj_open_lib_internal( + PJ_CONTEXT *ctx, const char *name, const char *mode, + void *(*open_file)(PJ_CONTEXT *, const char *, const char *), + char *out_full_filename, size_t out_full_filename_size) { try { std::string fname; const char *sysname = nullptr; diff --git a/src/grids.cpp b/src/grids.cpp index 8bb865d8..871e21ed 100644 --- a/src/grids.cpp +++ b/src/grids.cpp @@ -2790,7 +2790,8 @@ ListOfGenericGrids pj_generic_grid_init(PJ *P, const char *gridkey) { } return {}; } - proj_context_errno_set(P->ctx, 0); // don't treat as a persistent error + proj_context_errno_set(P->ctx, + 0); // don't treat as a persistent error } else { grids.emplace_back(std::move(gridSet)); } @@ -3313,7 +3314,8 @@ ListOfVGrids pj_vgrid_init(PJ *P, const char *gridkey) { } return {}; } - proj_context_errno_set(P->ctx, 0); // don't treat as a persistent error + proj_context_errno_set(P->ctx, + 0); // don't treat as a persistent error } else { grids.emplace_back(std::move(gridSet)); } @@ -3442,4 +3444,3 @@ bool pj_bilinear_interpolation_three_samples( } NS_PROJ_END - -- cgit v1.2.3 From 4de6f0bd24051ed60d9c0a98dbba1da376457f12 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 28 Nov 2020 00:07:18 +0100 Subject: createObjectsFromName(): in exact match, make looking for 'ETRS89 / UTM zone 32N' return only the exact match --- src/iso19111/factory.cpp | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 03fd5267..7c9eac00 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -6155,6 +6155,8 @@ AuthorityFactory::createObjectsFromNameEx( auto sqlRes = d->run(sql, params); bool isFirst = true; bool firstIsDeprecated = false; + bool foundExactMatch = false; + std::size_t hashCodeFirstMatch = 0; for (const auto &row : sqlRes) { const auto &name = row[3]; if (approximateMatch) { @@ -6242,11 +6244,38 @@ AuthorityFactory::createObjectsFromNameEx( } throw std::runtime_error("Unsupported table_name"); }; - res.emplace_back(PairObjectName(getObject(table_name, code), name)); + const auto obj = getObject(table_name, code); + if (metadata::Identifier::canonicalizeName(obj->nameStr()) == + canonicalizedSearchedName) { + foundExactMatch = true; + } + + const auto objPtr = obj.get(); + if (res.empty()) { + hashCodeFirstMatch = typeid(*objPtr).hash_code(); + } else if (hashCodeFirstMatch != typeid(*objPtr).hash_code()) { + hashCodeFirstMatch = 0; + } + + res.emplace_back(PairObjectName(obj, name)); if (limitResultCount > 0 && res.size() == limitResultCount) { break; } } + + // If we found a name that is an exact match, and all objects have the + // same type, and we are not in approximate mode, only keep the objet(s) + // with the exact name match. + if (foundExactMatch && hashCodeFirstMatch != 0 && !approximateMatch) { + std::list resTmp; + for (const auto &pair : res) { + if (metadata::Identifier::canonicalizeName( + pair.first->nameStr()) == canonicalizedSearchedName) { + resTmp.emplace_back(pair); + } + } + res = std::move(resTmp); + } } auto sortLambda = [](const PairObjectName &a, const PairObjectName &b) { -- cgit v1.2.3 From 24c74a4d1cead8df41a7f22c8f28b1bf9e884de9 Mon Sep 17 00:00:00 2001 From: Houder <74594217+Houder@users.noreply.github.com> Date: Sat, 28 Nov 2020 13:45:06 +0100 Subject: Use same arguments to printf format string for both radians and degrees in output by cct (#2453) Currently the output of the cct utility is different between radians and degrees (as expected by cct), because of a bug in cct: $ printf "1 2\n" | cct -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad 1.0000000000 2.0000000000 0.0000 0.0000 $ printf "1 2\n" | cct -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=deg 1.0000 2.0000 0.0000 0.0000 The arguments to the printf format string are as follows: * radians: width 14, precision 10 * degrees: width 13, precision 4 (this is by mistake. bug!) After the suggested fix has been applied, output will be the same for both radians and degrees: $ printf "1 2\n" | cct -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad 1.0000000000 2.0000000000 0.0000 0.0000 $ printf "1 2\n" | cct -z 0 -t 0 +proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=deg 1.0000000000 2.0000000000 0.0000 0.0000 The cause of the bug is that cct does test if it "has radians to output", but "neglects" to test if it "has degrees to output", resulting in using different arguments to the printf format string in the latter case. The fix makes cct test if it "has either radians or degrees to output". --- src/apps/cct.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/apps/cct.cpp b/src/apps/cct.cpp index ebfa6a23..4f21f10a 100644 --- a/src/apps/cct.cpp +++ b/src/apps/cct.cpp @@ -458,9 +458,14 @@ int main(int argc, char **argv) { comment_delimiter = (comment && *comment) ? whitespace : blank_comment; /* Time to print the result */ - if (proj_angular_output (P, direction)) { - point.lpzt.lam = proj_todeg (point.lpzt.lam); - point.lpzt.phi = proj_todeg (point.lpzt.phi); + /* use same arguments to printf format string for both radians and + degrees; convert radians to degrees before printing */ + if (proj_angular_output (P, direction) || + proj_degree_output (P, direction)) { + if (proj_angular_output (P, direction)) { + point.lpzt.lam = proj_todeg (point.lpzt.lam); + point.lpzt.phi = proj_todeg (point.lpzt.phi); + } print (PJ_LOG_NONE, "%14.*f %14.*f %12.*f %12.4f%s%s", decimals_angles, point.xyzt.x, decimals_angles, point.xyzt.y, -- cgit v1.2.3 From 0b4c8b0a76c65d8b1146224bf314cad53e9f6607 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 28 Nov 2020 15:51:27 +0100 Subject: cs2cs: add --area and --bbox options to restrict candidate coordinate operations (fixes #2423) --- src/apps/cs2cs.cpp | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 150 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp index 12e045bb..dd65baf4 100644 --- a/src/apps/cs2cs.cpp +++ b/src/apps/cs2cs.cpp @@ -36,8 +36,13 @@ #include #include +#include #include +#include +#include +#include + #include // PROJ include order is sensitive @@ -70,12 +75,18 @@ static const char *oform = static char oform_buffer[16]; /* buffer for oform when using -d */ static const char *oterr = "*\t*"; /* output line for unprojectable input */ static const char *usage = - "%s\nusage: %s [-dDeEfIlrstvwW [args]] [+opt[=arg] ...]\n" - " [+to +opt[=arg] ...] [file ...]\n"; + "%s\nusage: %s [-dDeEfIlrstvwW [args]]\n" + " [[--area name_or_code] | [--bbox west_long,south_lat,east_long,north_lat]]\n" + " [+opt[=arg] ...] [+to +opt[=arg] ...] [file ...]\n"; static double (*informat)(const char *, char **); /* input data deformatter function */ +using namespace NS_PROJ::io; +using namespace NS_PROJ::metadata; +using namespace NS_PROJ::util; +using namespace NS_PROJ::internal; + /************************************************************************/ /* process() */ /* */ @@ -359,9 +370,47 @@ int main(int argc, char **argv) { } } + ExtentPtr bboxFilter; + std::string area; + /* process run line arguments */ while (--argc > 0) { /* collect run line arguments */ - if (**++argv == '-') { + ++argv; + if (strcmp(*argv, "--area") == 0 ) { + ++argv; + --argc; + if( argc == 0 ) { + emess(1, "missing argument for --area"); + std::exit(1); + } + area = *argv; + } + else if (strcmp(*argv, "--bbox") == 0) { + ++argv; + --argc; + if( argc == 0 ) { + emess(1, "missing argument for --bbox"); + std::exit(1); + } + auto bboxStr(*argv); + auto bbox(split(bboxStr, ',')); + if (bbox.size() != 4) { + std::cerr << "Incorrect number of values for option --bbox: " + << bboxStr << std::endl; + std::exit(1); + } + try { + bboxFilter = Extent::createFromBBOX( + c_locale_stod(bbox[0]), c_locale_stod(bbox[1]), + c_locale_stod(bbox[2]), c_locale_stod(bbox[3])) + .as_nullable(); + } catch (const std::exception &e) { + std::cerr << "Invalid value for option --bbox: " << bboxStr + << ", " << e.what() << std::endl; + std::exit(1); + } + } + else if (**argv == '-') { for (arg = *argv;;) { switch (*++arg) { case '\0': /* position of "stdin" */ @@ -536,6 +585,102 @@ int main(int argc, char **argv) { } } + if (bboxFilter && !area.empty()) { + std::cerr << "ERROR: --bbox and --area are exclusive" << std::endl; + std::exit(1); + } + + PJ_AREA* pj_area = nullptr; + if (!area.empty()) { + + DatabaseContextPtr dbContext; + try { + dbContext = + DatabaseContext::create().as_nullable(); + } catch (const std::exception &e) { + std::cerr << "ERROR: Cannot create database connection: " + << e.what() << std::endl; + std::exit(1); + } + + // Process area of use + try { + if (area.find(' ') == std::string::npos && + area.find(':') != std::string::npos) { + auto tokens = split(area, ':'); + if (tokens.size() == 2) { + const std::string &areaAuth = tokens[0]; + const std::string &areaCode = tokens[1]; + bboxFilter = AuthorityFactory::create( + NN_NO_CHECK(dbContext), areaAuth) + ->createExtent(areaCode) + .as_nullable(); + } + } + if (!bboxFilter) { + auto authFactory = AuthorityFactory::create( + NN_NO_CHECK(dbContext), std::string()); + auto res = authFactory->listAreaOfUseFromName(area, false); + if (res.size() == 1) { + bboxFilter = + AuthorityFactory::create(NN_NO_CHECK(dbContext), + res.front().first) + ->createExtent(res.front().second) + .as_nullable(); + } else { + res = authFactory->listAreaOfUseFromName(area, true); + if (res.size() == 1) { + bboxFilter = + AuthorityFactory::create(NN_NO_CHECK(dbContext), + res.front().first) + ->createExtent(res.front().second) + .as_nullable(); + } else if (res.empty()) { + std::cerr << "No area of use matching provided name" + << std::endl; + std::exit(1); + } else { + std::cerr << "Several candidates area of use " + "matching provided name :" + << std::endl; + for (const auto &candidate : res) { + auto obj = + AuthorityFactory::create( + NN_NO_CHECK(dbContext), candidate.first) + ->createExtent(candidate.second); + std::cerr << " " << candidate.first << ":" + << candidate.second << " : " + << *obj->description() << std::endl; + } + std::exit(1); + } + } + } + } catch (const std::exception &e) { + std::cerr << "Area of use retrieval failed: " << e.what() + << std::endl; + std::exit(1); + } + } + + if (bboxFilter) { + auto geogElts = bboxFilter->geographicElements(); + if (geogElts.size() == 1) + { + auto bbox = std::dynamic_pointer_cast( + geogElts[0].as_nullable()); + if (bbox) + { + pj_area = proj_area_create(); + proj_area_set_bbox(pj_area, + bbox->westBoundLongitude(), + bbox->southBoundLatitude(), + bbox->eastBoundLongitude(), + bbox->northBoundLatitude()); + } + } + } + /* * If the user has requested inverse, then just reverse the * coordinate systems. @@ -617,10 +762,11 @@ int main(int argc, char **argv) { } transformation = proj_create_crs_to_crs_from_pj(nullptr, src, dst, - nullptr, nullptr); + pj_area, nullptr); proj_destroy(src); proj_destroy(dst); + proj_area_destroy(pj_area); if (!transformation) { emess(3, "cannot initialize transformation\ncause: %s", -- cgit v1.2.3 From ebe3425bf66287e004958eb53976d3837f88b9e1 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 28 Nov 2020 15:57:17 +0100 Subject: proj_create_crs_to_crs_from_pj(): do not use PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION if area is specified --- src/4D_api.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/4D_api.cpp b/src/4D_api.cpp index 15bc73c8..9231a7ed 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -1287,9 +1287,11 @@ PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, cons area->east_lon_degree, area->north_lat_degree); } + else { + proj_operation_factory_context_set_spatial_criterion( + ctx, operation_ctx, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION); + } - proj_operation_factory_context_set_spatial_criterion( - ctx, operation_ctx, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION); proj_operation_factory_context_set_grid_availability_use( ctx, operation_ctx, proj_context_is_network_enabled(ctx) ? -- cgit v1.2.3 From c6dda7637c0c49ece9216395caffa2bbd6184a92 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 28 Nov 2020 20:02:15 +0100 Subject: WKT1 import: better deal with apps.epsg.org output w.r.t datum ensemble names --- src/iso19111/io.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 52d46d27..125105ec 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -2163,9 +2163,15 @@ GeodeticReferenceFrameNNPtr WKTParser::Private::buildGeodeticReferenceFrame( return false; }; - if (name == "WGS_1984") { + // Remap GDAL WGS_1984 to EPSG v9 "World Geodetic System 1984" official + // name. + // Also remap EPSG v10 datum ensemble names to non-ensemble EPSG v9 + if (name == "WGS_1984" || name == "World Geodetic System 1984 ensemble") { properties.set(IdentifiedObject::NAME_KEY, GeodeticReferenceFrame::EPSG_6326->nameStr()); + } else if (name == "European Terrestrial Reference System 1989 ensemble") { + properties.set(IdentifiedObject::NAME_KEY, + "European Terrestrial Reference System 1989"); } else if (starts_with(name, "D_")) { esriStyle_ = true; const char *tableNameForAlias = nullptr; -- cgit v1.2.3 From 87270ae6f1840872d5f49c70258941197b0ce809 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 28 Nov 2020 23:39:33 +0100 Subject: createOperations(): get a '+proj=noop' instead of '+proj=affine +s33=-1' when attempting (non-sensical) EPSG:3855 to EPSG:4326 --- src/iso19111/coordinateoperation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 0f1c680b..5ef32d31 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -14837,7 +14837,7 @@ void CoordinateOperationFactory::Private::createOperationsVertToGeogBallpark( double convDst = 1.0; const auto &geogAxis = geogDst->coordinateSystem()->axisList(); bool dstIsUp = true; - bool dstIsDown = true; + bool dstIsDown = false; if (geogAxis.size() == 3) { const auto &dstAxis = geogAxis[2]; convDst = dstAxis->unit().conversionToSI(); -- cgit v1.2.3 From bc0c9f3e96dc4a9829f1f3d1e1307b4dd5dd10de Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 29 Nov 2020 14:10:15 +0100 Subject: Inverse tmerc spherical: fix wrong sign of latitude when lat_0 is used (fixes #2468) Corrected formula given by @evanmiller --- src/projections/tmerc.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/projections/tmerc.cpp b/src/projections/tmerc.cpp index 8cae9968..2d13b064 100644 --- a/src/projections/tmerc.cpp +++ b/src/projections/tmerc.cpp @@ -203,11 +203,13 @@ static PJ_LP approx_s_inv (PJ_XY xy, PJ *P) { return proj_coord_error().lp; } g = .5 * (h - 1. / h); - h = cos (P->phi0 + xy.y / Q->esp); + /* D, as in equation 8-8 of USGS "Map Projections - A Working Manual" */ + const double D = P->phi0 + xy.y / Q->esp; + h = cos (D); lp.phi = 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.phi+P->phi0 < 0.0) lp.phi = -lp.phi; + lp.phi = copysign(lp.phi, D); lp.lam = (g != 0.0 || h != 0.0) ? atan2 (g, h) : 0.; return lp; -- cgit v1.2.3 From 284feecd27f3fd43569d3d37d62ae7b0153c20ce Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 29 Nov 2020 20:53:21 +0100 Subject: Spherical tmerc forward: do not restrict to [-90,90] longitude range The restriction was a copy&paste from the Evenden/Snyder approximate ellipsoidal implementation, but the spherical one is exact, so this restriction isn't needed. Also tune a bit the handling of lat=0, |lon| > 90 --- src/projections/tmerc.cpp | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/projections/tmerc.cpp b/src/projections/tmerc.cpp index 2d13b064..8f897061 100644 --- a/src/projections/tmerc.cpp +++ b/src/projections/tmerc.cpp @@ -115,25 +115,11 @@ static PJ_XY approx_e_fwd (PJ_LP lp, PJ *P) return (xy); } -static PJ_XY approx_s_fwd (PJ_LP lp, PJ *P) { +static PJ_XY tmerc_spherical_fwd (PJ_LP lp, PJ *P) { PJ_XY xy = {0.0,0.0}; double b, cosphi; const auto *Q = &(static_cast(P->opaque)->approx); - /* - * Fail if our longitude is more than 90 degrees from the - * central meridian since the results are essentially garbage. - * Is error -20 really an appropriate return value? - * - * http://trac.osgeo.org/proj/ticket/5 - */ - if( lp.lam < -M_HALFPI || lp.lam > M_HALFPI ) { - xy.x = HUGE_VAL; - xy.y = HUGE_VAL; - proj_context_errno_set( P->ctx, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT ); - return xy; - } - cosphi = cos(lp.phi); b = cosphi * sin (lp.lam); if (fabs (fabs (b) - 1.) <= EPS10) { @@ -145,7 +131,12 @@ static PJ_XY approx_s_fwd (PJ_LP lp, PJ *P) { xy.y = cosphi * cos (lp.lam) / sqrt (1. - b * b); b = fabs ( xy.y ); - if (b >= 1.) { + if (cosphi == 1 && (lp.lam < -M_HALFPI || lp.lam > M_HALFPI) ) { + /* Helps to be able to roundtrip |longitudes| > 90 at lat=0 */ + /* We could also map to -M_PI ... */ + xy.y = M_PI; + } + else if (b >= 1.) { if ((b - 1.) > EPS10) { proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION); return xy; @@ -192,7 +183,7 @@ static PJ_LP approx_e_inv (PJ_XY xy, PJ *P) { return lp; } -static PJ_LP approx_s_inv (PJ_XY xy, PJ *P) { +static PJ_LP tmerc_spherical_inv (PJ_XY xy, PJ *P) { PJ_LP lp = {0.0, 0.0}; double h, g; const auto *Q = &(static_cast(P->opaque)->approx); @@ -611,8 +602,8 @@ static PJ *setup(PJ *P, TMercAlgo eAlg) { return nullptr; if( P->es == 0 ) { - P->inv = approx_s_inv; - P->fwd = approx_s_fwd; + P->inv = tmerc_spherical_inv; + P->fwd = tmerc_spherical_fwd; } else { -- cgit v1.2.3 From ee534a70ef35ba34f773d92ce336108e8d90b6bd Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 30 Nov 2020 00:31:21 +0100 Subject: pj_datum_set(): make code more obvious to humans and analyzers --- src/datum_set.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/datum_set.cpp b/src/datum_set.cpp index 398d85cd..3f612633 100644 --- a/src/datum_set.cpp +++ b/src/datum_set.cpp @@ -84,25 +84,27 @@ int pj_datum_set(PJ_CONTEXT *ctx, paralist *pl, PJ *projdef) sizeof(entry) - 1 - strlen(entry) ); entry[ sizeof(entry) - 1 ] = '\0'; - curr = curr->next = pj_mkparam(entry); - if (nullptr == curr) + auto param = pj_mkparam(entry); + if (nullptr == param) { proj_context_errno_set(ctx, ENOMEM); return 1; } + curr->next = param; + curr = param; } if( pj_datums[i].defn && strlen(pj_datums[i].defn) > 0 ) { - curr = curr->next = pj_mkparam(pj_datums[i].defn); - if (nullptr == curr) + auto param = pj_mkparam(pj_datums[i].defn); + if (nullptr == param) { proj_context_errno_set(ctx, ENOMEM); return 1; } + curr->next = param; + /* curr = param; */ } - - (void)curr; /* make clang static analyzer happy */ } /* -------------------------------------------------------------------- */ -- cgit v1.2.3 From f4dc79075c19706dda6e3253c2f224e9df468291 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 30 Nov 2020 01:35:59 +0100 Subject: API cleanup: unexport number of internal symbols, and remove/replace a few unused ones --- src/Makefile.am | 4 +- src/apps/proj.cpp | 18 +++++--- src/init.cpp | 97 --------------------------------------- src/proj_internal.h | 32 ++++++------- src/projections/ob_tran.cpp | 9 ++-- src/tests/test228.cpp | 109 -------------------------------------------- 6 files changed, 31 insertions(+), 238 deletions(-) delete mode 100644 src/tests/test228.cpp (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 4f3db3ed..1d772207 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ AM_CFLAGS = @C_WFLAGS@ -EXTRA_PROGRAMS = multistresstest test228 +EXTRA_PROGRAMS = multistresstest TESTS = geodtest check_PROGRAMS = geodtest @@ -36,7 +36,6 @@ bin_PROGRAMS = proj geod cs2cs gie cct projinfo $(PROJSYNC_BIN) gie_SOURCES = apps/gie.cpp apps/proj_strtod.cpp apps/proj_strtod.h apps/optargpm.h multistresstest_SOURCES = tests/multistresstest.cpp -test228_SOURCES = tests/test228.cpp geodtest_SOURCES = tests/geodtest.cpp cct_LDADD = libproj.la @@ -47,7 +46,6 @@ projinfo_LDADD = libproj.la gie_LDADD = libproj.la multistresstest_LDADD = libproj.la @THREAD_LIB@ -test228_LDADD = libproj.la @THREAD_LIB@ geodtest_LDADD = libproj.la lib_LTLIBRARIES = libproj.la diff --git a/src/apps/proj.cpp b/src/apps/proj.cpp index a5c917f6..0108cb74 100644 --- a/src/apps/proj.cpp +++ b/src/apps/proj.cpp @@ -9,6 +9,8 @@ #include "emess.h" #include "utils.h" +#include + #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__WIN32__) # include # include @@ -292,10 +294,10 @@ static void vprocess(FILE *fid) { int main(int argc, char **argv) { char *arg; - char *pargv[MAX_PARGS] = {}; + std::vector argvVector; char **eargv = argv; FILE *fid; - int pargc = 0, eargc = 0, mon = 0; + int eargc = 0, mon = 0; if ( (emess_dat.Prog_name = strrchr(*argv,DIR_CHAR)) != nullptr) ++emess_dat.Prog_name; @@ -450,10 +452,7 @@ int main(int argc, char **argv) { } break; } else if (**argv == '+') { /* + argument */ - if (pargc < MAX_PARGS) - pargv[pargc++] = *argv + 1; - else - emess(1,"overflowed + argument table"); + argvVector.push_back(*argv + 1); } else /* assumed to be input file name(s) */ eargv[eargc++] = *argv; } @@ -473,7 +472,12 @@ int main(int argc, char **argv) { postscale = 0; fscale = 1./fscale; } - if (!(Proj = pj_init(pargc, pargv))) + proj_context_use_proj4_init_rules(nullptr, true); + + // proj historically ignores any datum shift specifier, like nadgrids, towgs84, etc + argvVector.push_back(const_cast("break_cs2cs_recursion")); + + if (!(Proj = proj_create_argv(nullptr, static_cast(argvVector.size()), argvVector.data()))) emess(3,"projection initialization failure\ncause: %s", proj_errno_string(proj_context_errno(nullptr))); diff --git a/src/init.cpp b/src/init.cpp index 7b614c5f..1e89402d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -399,90 +399,6 @@ paralist *pj_expand_init(PJ_CONTEXT *ctx, paralist *init) { } -/************************************************************************/ -/* pj_init_plus() */ -/* */ -/* Same as pj_init() except it takes one argument string with */ -/* individual arguments preceded by '+', such as "+proj=utm */ -/* +zone=11 +ellps=WGS84". */ -/************************************************************************/ - -PJ * -pj_init_plus( const char *definition ) - -{ - return pj_init_plus_ctx( pj_get_default_ctx(), definition ); -} - -PJ * -pj_init_plus_ctx( PJ_CONTEXT *ctx, const char *definition ) -{ -#define MAX_ARG 200 - char *argv[MAX_ARG]; - char *defn_copy; - int argc = 0, i, blank_count = 0; - PJ *result = nullptr; - - /* make a copy that we can manipulate */ - defn_copy = (char *) malloc( strlen(definition)+1 ); - if (!defn_copy) - return nullptr; - strcpy( defn_copy, definition ); - - /* split into arguments based on '+' and trim white space */ - - for( i = 0; defn_copy[i] != '\0'; i++ ) - { - switch( defn_copy[i] ) - { - case '+': - if( i == 0 || defn_copy[i-1] == '\0' || blank_count > 0 ) - { - /* trim trailing spaces from the previous param */ - if( blank_count > 0 ) - { - defn_copy[i - blank_count] = '\0'; - blank_count = 0; - } - - if( argc+1 == MAX_ARG ) - { - free( defn_copy ); - proj_context_errno_set( ctx, PJD_ERR_UNPARSEABLE_CS_DEF ); - return nullptr; - } - - argv[argc++] = defn_copy + i + 1; - } - break; - - case ' ': - case '\t': - case '\n': - /* trim leading spaces from the current param */ - if( i == 0 || defn_copy[i-1] == '\0' || argc == 0 || argv[argc-1] == defn_copy + i ) - defn_copy[i] = '\0'; - else - blank_count++; - break; - - default: - /* reset blank_count */ - blank_count = 0; - } - } - /* trim trailing spaces from the last param */ - defn_copy[i - blank_count] = '\0'; - - /* perform actual initialization */ - result = pj_init_ctx( ctx, argc, argv ); - - free( defn_copy ); - return result; -} - - - /************************************************************************/ /* pj_init() */ /* */ @@ -492,11 +408,6 @@ pj_init_plus_ctx( PJ_CONTEXT *ctx, const char *definition ) /* large enough to hold projection specific parameters. */ /************************************************************************/ -PJ * -pj_init(int argc, char **argv) { - return pj_init_ctx( pj_get_default_ctx(), argc, argv ); -} - static PJ_CONSTRUCTOR locate_constructor (const char *name) { int i; @@ -510,14 +421,6 @@ static PJ_CONSTRUCTOR locate_constructor (const char *name) { } -PJ * -pj_init_ctx(PJ_CONTEXT *ctx, int argc, char **argv) { - /* Legacy interface: allow init=epsg:XXXX syntax by default */ - int allow_init_epsg = proj_context_get_use_proj4_init_rules(ctx, TRUE); - return pj_init_ctx_with_allow_init_epsg(ctx, argc, argv, allow_init_epsg); -} - - PJ * pj_init_ctx_with_allow_init_epsg(PJ_CONTEXT *ctx, int argc, char **argv, int allow_init_epsg) { const char *s; diff --git a/src/proj_internal.h b/src/proj_internal.h index 234ff80e..32aaa1ec 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -934,35 +934,31 @@ extern char const PROJ_DLL pj_release[]; /* global release id string */ /* procedure prototypes */ PJ_CONTEXT PROJ_DLL *pj_get_default_ctx(void); -PJ_CONTEXT PROJ_DLL *pj_get_ctx( PJ *); +PJ_CONTEXT *pj_get_ctx( PJ *); PJ_XY PROJ_DLL pj_fwd(PJ_LP, PJ *); PJ_LP PROJ_DLL pj_inv(PJ_XY, PJ *); -PJ_XYZ PROJ_DLL pj_fwd3d(PJ_LPZ, PJ *); -PJ_LPZ PROJ_DLL pj_inv3d(PJ_XYZ, PJ *); +PJ_XYZ pj_fwd3d(PJ_LPZ, PJ *); +PJ_LPZ pj_inv3d(PJ_XYZ, PJ *); -void PROJ_DLL pj_clear_initcache(void); -void PROJ_DLL pj_pr_list(PJ *); -PJ PROJ_DLL *pj_init(int, char **); -PJ PROJ_DLL *pj_init_plus(const char *); -PJ PROJ_DLL *pj_init_ctx( PJ_CONTEXT *, int, char ** ); -PJ PROJ_DLL *pj_init_plus_ctx( PJ_CONTEXT *, const char * ); -char PROJ_DLL *pj_get_def(PJ *, int); -int PROJ_DLL pj_has_inverse(PJ *); +void pj_clear_initcache(void); +void PROJ_DLL pj_pr_list(PJ *); /* used by proj.cpp */ +char *pj_get_def(PJ *, int); +int pj_has_inverse(PJ *); -char PROJ_DLL *pj_strdup(const char *str); +char *pj_strdup(const char *str); const char PROJ_DLL *pj_get_release(void); -void PROJ_DLL pj_acquire_lock(void); -void PROJ_DLL pj_release_lock(void); -void PROJ_DLL pj_cleanup_lock(void); +void pj_acquire_lock(void); +void pj_release_lock(void); +void pj_cleanup_lock(void); -void PROJ_DLL pj_log( PJ_CONTEXT * ctx, int level, const char *fmt, ... ); -void PROJ_DLL pj_stderr_logger( void *, int, const char * ); +void pj_log( PJ_CONTEXT * ctx, int level, const char *fmt, ... ); +void pj_stderr_logger( void *, int, const char * ); -int PROJ_DLL pj_find_file(PJ_CONTEXT * ctx, const char *short_filename, +int pj_find_file(PJ_CONTEXT * ctx, const char *short_filename, char* out_full_filename, size_t out_full_filename_size); diff --git a/src/projections/ob_tran.cpp b/src/projections/ob_tran.cpp index 4990ab2a..86798e0a 100644 --- a/src/projections/ob_tran.cpp +++ b/src/projections/ob_tran.cpp @@ -141,14 +141,15 @@ static ARGS ob_tran_target_params (paralist *params) { if (argc < 2) return args; - /* all args except the proj_ob_tran */ + /* all args except the proj=ob_tran */ args.argv = static_cast(calloc (argc - 1, sizeof (char *))); if (nullptr==args.argv) return args; - /* Copy all args *except* the proj=ob_tran arg to the argv array */ + /* Copy all args *except* the proj=ob_tran or inv arg to the argv array */ for (i = 0; params != nullptr; params = params->next) { - if (0==strcmp (params->param, "proj=ob_tran")) + if (0==strcmp (params->param, "proj=ob_tran") || + 0==strcmp (params->param, "inv") ) continue; args.argv[i++] = params->param; } @@ -194,7 +195,7 @@ PJ *PROJECTION(ob_tran) { if (args.argv == nullptr ) { return destructor(P, PJD_ERR_FAILED_TO_FIND_PROJ); } - R = pj_init_ctx (pj_get_ctx(P), args.argc, args.argv); + R = proj_create_argv (P->ctx, args.argc, args.argv); free (args.argv); if (nullptr==R) diff --git a/src/tests/test228.cpp b/src/tests/test228.cpp deleted file mode 100644 index ae2eb9cc..00000000 --- a/src/tests/test228.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/****************************************************************************** - * - * Project: PROJ - * Purpose: Test - * Author: Even Rouault - * - ****************************************************************************** - * Copyright (c) 2014, Even Rouault - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - ****************************************************************************/ - -#include "proj_internal.h" -#include /* for printf declaration */ - - -#ifdef _WIN32 - -int main(int argc, char* argv[]) -{ - printf("Test not yet ported on Win32\n"); - return 0; -} - -#else - -#include -#include -#include -#include - -static volatile int run = 0; -static volatile int started = 0; - -static void* thread_main(void* unused) -{ - PJ_CONTEXT *p_proj_ctxt; - PJ *p_WGS84_proj; - PJ * p_OSGB36_proj; - (void)unused; - - __sync_add_and_fetch(&started, 1); - while(run == 0); - - p_proj_ctxt=pj_ctx_alloc(); - p_WGS84_proj=pj_init_plus_ctx(p_proj_ctxt,"+proj=longlat " - "+ellps=WGS84 +datum=WGS84"); - p_OSGB36_proj=pj_init_plus_ctx(p_proj_ctxt, - "+proj=longlat +ellps=airy +datum=OSGB36 +nadgrids=OSTN15_NTv2_OSGBtoETRS.gsb"); - - while(run) - { - double x, y; - int proj_ret; - - x = -5.2*DEG_TO_RAD; - y = 50*DEG_TO_RAD; - proj_ret = pj_transform(p_WGS84_proj, - p_OSGB36_proj, 1, 1, &x, &y, nullptr ); - x *= RAD_TO_DEG; - y *= RAD_TO_DEG; - /*printf("%.18f %.18f\n", x, y); */ - assert(proj_ret == 0); - assert(fabs(x - -5.198965207267856492) < 1e-15); - assert(fabs(y - 49.999396074140378232) < 1e-15); - } - - pj_free (p_OSGB36_proj); - pj_free (p_WGS84_proj); - return nullptr; -} - -int main() -{ - int i; - - pthread_t tid1, tid2; - pthread_attr_t attr1, attr2; - - pthread_attr_init(&attr1); - pthread_attr_init(&attr2); - - pthread_create(&tid1, &attr1, thread_main, nullptr); - pthread_create(&tid2, &attr2, thread_main, nullptr); - while(started != 2); - run = 1; - for(i=0;i<2;i++) - sleep(1); - run = 0; - return 0; -} - -#endif /* _WIN32 */ -- cgit v1.2.3 From eef73e3eca2959768563d2dbb95a591c68b1d807 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 30 Nov 2020 14:00:46 +0100 Subject: Database: add metadata with the version number of the database layout and check it in the code This is aimed at detecting running a PROJ version against a proj.db that is not meant to work with it. This happens sometimes in complex setups mixing PROJ versions. Hopefully this will help spotting the issue earlier. --- src/iso19111/factory.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'src') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 7c9eac00..2a03fd4e 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -93,6 +93,12 @@ namespace io { #define GEOG_3D_SINGLE_QUOTED "'geographic 3D'" #define GEOCENTRIC_SINGLE_QUOTED "'geocentric'" +// See data/sql/metadata.sql for the semantics of those constants +constexpr int DATABASE_LAYOUT_VERSION_MAJOR = 1; +// If the code depends on the new additions, then DATABASE_LAYOUT_VERSION_MINOR +// must be incremented. +constexpr int DATABASE_LAYOUT_VERSION_MINOR = 0; + // --------------------------------------------------------------------------- struct SQLValues { @@ -277,6 +283,8 @@ struct DatabaseContext::Private { lru11::Cache> cacheAliasNames_{ CACHE_SIZE}; + void checkDatabaseLayout(); + static void insertIntoCache(LRUCacheOfObjects &cache, const std::string &code, const util::BaseObjectPtr &obj); @@ -571,6 +579,61 @@ void DatabaseContext::Private::open(const std::string &databasePath, // --------------------------------------------------------------------------- +void DatabaseContext::Private::checkDatabaseLayout() { + auto res = run("SELECT key, value FROM metadata WHERE key IN " + "('DATABASE.LAYOUT.VERSION.MAJOR', " + "'DATABASE.LAYOUT.VERSION.MINOR')"); + if (res.size() != 2) { + // The database layout of PROJ 7.2 that shipped with EPSG v10.003 is + // at the time of writing still compatible of the one we support. + static_assert( + // cppcheck-suppress knownConditionTrueFalse + DATABASE_LAYOUT_VERSION_MAJOR == 1 && + // cppcheck-suppress knownConditionTrueFalse + DATABASE_LAYOUT_VERSION_MINOR == 0, + "remove that assertion and below lines next time we upgrade " + "database structure"); + res = run("SELECT 1 FROM metadata WHERE key = 'EPSG.VERSION' AND " + "value = 'v10.003'"); + if (!res.empty()) { + return; + } + + throw FactoryException( + databasePath_ + + " lacks DATABASE.LAYOUT.VERSION.MAJOR / " + "DATABASE.LAYOUT.VERSION.MINOR " + "metadata. It comes from another PROJ installation."); + } + int nMajor = 0; + int nMinor = 0; + for (const auto &row : res) { + if (row[0] == "DATABASE.LAYOUT.VERSION.MAJOR") { + nMajor = atoi(row[1].c_str()); + } else if (row[0] == "DATABASE.LAYOUT.VERSION.MINOR") { + nMinor = atoi(row[1].c_str()); + } + } + if (nMajor != DATABASE_LAYOUT_VERSION_MAJOR) { + throw FactoryException(databasePath_ + + " contains DATABASE.LAYOUT.VERSION.MAJOR = " + + toString(nMajor) + " whereas " + + toString(DATABASE_LAYOUT_VERSION_MAJOR) + + " is expected. " + "It comes from another PROJ installation."); + } + if (nMinor < DATABASE_LAYOUT_VERSION_MINOR) { + throw FactoryException(databasePath_ + + " contains DATABASE.LAYOUT.VERSION.MINOR = " + + toString(nMinor) + " whereas a number >= " + + toString(DATABASE_LAYOUT_VERSION_MINOR) + + " is expected. " + "It comes from another PROJ installation."); + } +} + +// --------------------------------------------------------------------------- + void DatabaseContext::Private::setHandle(sqlite3 *sqlite_handle) { assert(sqlite_handle); @@ -888,6 +951,7 @@ DatabaseContext::create(const std::string &databasePath, if (!auxiliaryDatabasePaths.empty()) { dbCtx->getPrivate()->attachExtraDatabases(auxiliaryDatabasePaths); } + dbCtx->getPrivate()->checkDatabaseLayout(); return dbCtx; } -- cgit v1.2.3 From ebe00831b7d6de3aae01ddd5f3074e53ac6d981e Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 2 Dec 2020 15:22:48 +0100 Subject: fix build --- src/conversions/topocentric.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/conversions/topocentric.cpp b/src/conversions/topocentric.cpp index 214f8221..f6f328ad 100644 --- a/src/conversions/topocentric.cpp +++ b/src/conversions/topocentric.cpp @@ -76,7 +76,7 @@ static PJ_COORD topocentric_inv(PJ_COORD in, PJ * P) /*********************************************************************/ PJ *CONVERSION(topocentric,1) { /*********************************************************************/ - struct pj_opaque *Q = static_cast(pj_calloc (1, sizeof (struct pj_opaque))); + struct pj_opaque *Q = static_cast(calloc (1, sizeof (struct pj_opaque))); if (nullptr==Q) return pj_default_destructor (P, ENOMEM); P->opaque = static_cast(Q); -- cgit v1.2.3 From 18ab7ef2e357e0c01464848a6911e754ebca471f Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 2 Dec 2020 17:12:54 +0100 Subject: cs2cs / proj_create_crs_to_crs_from_pj(): add a --authority switch to control where coordinate operations are looked for (fixes #2442) --- src/4D_api.cpp | 29 +++++++++++++++++++++++++++-- src/apps/cs2cs.cpp | 20 +++++++++++++++++++- 2 files changed, 46 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/4D_api.cpp b/src/4D_api.cpp index 9231a7ed..d6eb901d 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -1260,8 +1260,20 @@ std::vector pj_create_prepared_operations(PJ_CONTEXT *ctx, } } +// --------------------------------------------------------------------------- + +//! @cond Doxygen_Suppress +static const char *getOptionValue(const char *option, + const char *keyWithEqual) noexcept { + if (ci_starts_with(option, keyWithEqual)) { + return option + strlen(keyWithEqual); + } + return nullptr; +} +//! @endcond + /*****************************************************************************/ -PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, const PJ *target_crs, PJ_AREA *area, const char* const *) { +PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, const PJ *target_crs, PJ_AREA *area, const char* const * options) { /****************************************************************************** Create a transformation pipeline between two known coordinate reference systems. @@ -1273,7 +1285,20 @@ PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, cons ctx = pj_get_default_ctx(); } - auto operation_ctx = proj_create_operation_factory_context(ctx, nullptr); + const char* authority = nullptr; + for (auto iter = options; iter && iter[0]; ++iter) { + const char *value; + if ((value = getOptionValue(*iter, "AUTHORITY="))) { + authority = value; + } else { + std::string msg("Unknown option :"); + msg += *iter; + ctx->logger(ctx->logger_app_data, PJ_LOG_ERROR, msg.c_str()); + return nullptr; + } + } + + auto operation_ctx = proj_create_operation_factory_context(ctx, authority); if( !operation_ctx ) { return nullptr; } diff --git a/src/apps/cs2cs.cpp b/src/apps/cs2cs.cpp index dd65baf4..409a5ef3 100644 --- a/src/apps/cs2cs.cpp +++ b/src/apps/cs2cs.cpp @@ -77,6 +77,7 @@ static const char *oterr = "*\t*"; /* output line for unprojectable input */ static const char *usage = "%s\nusage: %s [-dDeEfIlrstvwW [args]]\n" " [[--area name_or_code] | [--bbox west_long,south_lat,east_long,north_lat]]\n" + " [--authority {name}]\n" " [+opt[=arg] ...] [+to +opt[=arg] ...] [file ...]\n"; static double (*informat)(const char *, @@ -372,6 +373,7 @@ int main(int argc, char **argv) { ExtentPtr bboxFilter; std::string area; + const char* authority = nullptr; /* process run line arguments */ while (--argc > 0) { /* collect run line arguments */ @@ -410,6 +412,15 @@ int main(int argc, char **argv) { std::exit(1); } } + else if (strcmp(*argv, "--authority") == 0 ) { + ++argv; + --argc; + if( argc == 0 ) { + emess(1, "missing argument for --authority"); + std::exit(1); + } + authority = *argv; + } else if (**argv == '-') { for (arg = *argv;;) { switch (*++arg) { @@ -761,8 +772,15 @@ int main(int argc, char **argv) { } } + std::string authorityOption; /* keep this variable in this outer scope ! */ + const char* options[2] = { nullptr, nullptr }; + if( authority ) { + authorityOption = "AUTHORITY="; + authorityOption += authority; + options[0] = authorityOption.data(); + } transformation = proj_create_crs_to_crs_from_pj(nullptr, src, dst, - pj_area, nullptr); + pj_area, options); proj_destroy(src); proj_destroy(dst); -- cgit v1.2.3