aboutsummaryrefslogtreecommitdiff
path: root/src/PJ_aea.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/PJ_aea.c')
-rw-r--r--src/PJ_aea.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/PJ_aea.c b/src/PJ_aea.c
new file mode 100644
index 00000000..6ad5e9f0
--- /dev/null
+++ b/src/PJ_aea.c
@@ -0,0 +1,131 @@
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_aea.c 4.2 94/03/18 GIE REL";
+#endif
+# define EPS10 1.e-10
+# define TOL7 1.e-7
+#define PROJ_PARMS__ \
+ double ec; \
+ double n; \
+ double c; \
+ double dd; \
+ double n2; \
+ double rho0; \
+ double rho; \
+ double phi1; \
+ double phi2; \
+ double *en; \
+ int ellips;
+#define PJ_LIB__
+# include <projects.h>
+PROJ_HEAD(aea, "Albers Equal Area")
+ "\n\tConic Sph&Ell\n\tlat_1= lat_2=";
+PROJ_HEAD(leac, "Lambert Equal Area Conic")
+ "\n\tConic, Sph&Ell\n\tlat_1= south";
+/* determine latitude angle phi-1 */
+# define N_ITER 15
+# define EPSILON 1.0e-7
+# define TOL 1.0e-10
+ static double
+phi1_(double qs, double Te, double Tone_es) {
+ int i;
+ double Phi, sinpi, cospi, con, com, dphi;
+
+ Phi = asin (.5 * qs);
+ if (Te < EPSILON)
+ return( Phi );
+ i = N_ITER;
+ do {
+ sinpi = sin (Phi);
+ cospi = cos (Phi);
+ con = Te * sinpi;
+ com = 1. - con * con;
+ dphi = .5 * com * com / cospi * (qs / Tone_es -
+ sinpi / com + .5 / Te * log ((1. - con) /
+ (1. + con)));
+ Phi += dphi;
+ } while (fabs(dphi) > TOL && --i);
+ return( i ? Phi : HUGE_VAL );
+}
+FORWARD(e_forward); /* ellipsoid & spheroid */
+ if ((P->rho = P->c - (P->ellips ? P->n * pj_qsfn(sin(lp.phi),
+ P->e, P->one_es) : P->n2 * sin(lp.phi))) < 0.) F_ERROR
+ P->rho = P->dd * sqrt(P->rho);
+ xy.x = P->rho * sin( lp.lam *= P->n );
+ xy.y = P->rho0 - P->rho * cos(lp.lam);
+ return (xy);
+}
+INVERSE(e_inverse) /* ellipsoid & spheroid */;
+ if (P->rho = hypot(xy.x, xy.y = P->rho0 - xy.y)) {
+ if (P->n < 0.) {
+ P->rho = -P->rho;
+ xy.x = -xy.x;
+ xy.y = -xy.y;
+ }
+ lp.phi = P->rho / P->dd;
+ if (P->ellips) {
+ lp.phi = (P->c - lp.phi * lp.phi) / P->n;
+ if (fabs(P->ec - fabs(lp.phi)) > TOL7) {
+ if ((lp.phi = phi1_(lp.phi, P->e, P->one_es)) == HUGE_VAL)
+ I_ERROR
+ } else
+ lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
+ } else if (fabs(lp.phi = (P->c - lp.phi * lp.phi) / P->n2) <= 1.)
+ lp.phi = asin(lp.phi);
+ else
+ lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
+ lp.lam = atan2(xy.x, xy.y) / P->n;
+ } else {
+ lp.lam = 0.;
+ lp.phi = P->n > 0. ? HALFPI : - HALFPI;
+ }
+ return (lp);
+}
+FREEUP; if (P) { if (P->en) pj_dalloc(P->en); pj_dalloc(P); } }
+ static PJ *
+setup(PJ *P) {
+ double cosphi, sinphi;
+ int secant;
+
+ if (fabs(P->phi1 + P->phi2) < EPS10) E_ERROR(-21);
+ P->n = sinphi = sin(P->phi1);
+ cosphi = cos(P->phi1);
+ secant = fabs(P->phi1 - P->phi2) >= EPS10;
+ if (P->ellips = P->es > 0.) {
+ double ml1, m1;
+
+ if (!(P->en = pj_enfn(P->es))) E_ERROR_0;
+ m1 = pj_msfn(sinphi, cosphi, P->es);
+ ml1 = pj_qsfn(sinphi, P->e, P->one_es);
+ if (secant) { /* secant cone */
+ double ml2, m2;
+
+ sinphi = sin(P->phi2);
+ cosphi = cos(P->phi2);
+ m2 = pj_msfn(sinphi, cosphi, P->es);
+ ml2 = pj_qsfn(sinphi, P->e, P->one_es);
+ P->n = (m1 * m1 - m2 * m2) / (ml2 - ml1);
+ }
+ P->ec = 1. - .5 * P->one_es * log((1. - P->e) /
+ (1. + P->e)) / P->e;
+ P->c = m1 * m1 + P->n * ml1;
+ P->dd = 1. / P->n;
+ P->rho0 = P->dd * sqrt(P->c - P->n * pj_qsfn(sin(P->phi0),
+ P->e, P->one_es));
+ } else {
+ if (secant) P->n = .5 * (P->n + sin(P->phi2));
+ P->n2 = P->n + P->n;
+ P->c = cosphi * cosphi + P->n2 * sinphi;
+ P->dd = 1. / P->n;
+ P->rho0 = P->dd * sqrt(P->c - P->n2 * sin(P->phi0));
+ }
+ P->inv = e_inverse; P->fwd = e_forward;
+ return P;
+}
+ENTRY0(aea)
+ P->phi1 = pj_param(P->params, "rlat_1").f;
+ P->phi2 = pj_param(P->params, "rlat_2").f;
+ENDENTRY(setup(P))
+ENTRY0(leac)
+ P->phi2 = pj_param(P->params, "rlat_1").f;
+ P->phi1 = pj_param(P->params, "bsouth").i ? - HALFPI: HALFPI;
+ENDENTRY(setup(P))