aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Evers <kristianevers@gmail.com>2018-06-26 15:34:37 +0200
committerGitHub <noreply@github.com>2018-06-26 15:34:37 +0200
commit3eb56dbe0f6c244ea31baf75306a4554af46b4c3 (patch)
tree79b9c8940326cf3db4dc5e7f823dca4ff668c369
parent540dd05de7fe3c69c81ce894cedb8ecd5e24107d (diff)
parent4e6b366e07960b19ae4c10b84c527bc2a7028337 (diff)
downloadPROJ-3eb56dbe0f6c244ea31baf75306a4554af46b4c3.tar.gz
PROJ-3eb56dbe0f6c244ea31baf75306a4554af46b4c3.zip
Merge pull request #1058 from kbevers/inverse-lagrange
Add inverse lagrange projection
-rw-r--r--src/PJ_lagrng.c45
-rw-r--r--test/gie/builtins.gie57
2 files changed, 86 insertions, 16 deletions
diff --git a/src/PJ_lagrng.c b/src/PJ_lagrng.c
index d2b53b09..3856fcdc 100644
--- a/src/PJ_lagrng.c
+++ b/src/PJ_lagrng.c
@@ -1,19 +1,21 @@
#define PJ_LIB__
-
#include <errno.h>
#include <math.h>
#include "proj.h"
#include "projects.h"
-PROJ_HEAD(lagrng, "Lagrange") "\n\tMisc Sph, no inv.\n\tW=";
+PROJ_HEAD(lagrng, "Lagrange") "\n\tMisc Sph\n\tW=";
#define TOL 1e-10
struct pj_opaque {
double a1;
+ double a2;
double hrw;
+ double hw;
double rw;
+ double w;
};
@@ -28,7 +30,9 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
} else {
lp.phi = sin(lp.phi);
v = Q->a1 * pow((1. + lp.phi)/(1. - lp.phi), Q->hrw);
- if ((c = 0.5 * (v + 1./v) + cos(lp.lam *= Q->rw)) < TOL) {
+ lp.lam *= Q->rw;
+ c = 0.5 * (v + 1./v) + cos(lp.lam);
+ if (c < TOL) {
proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
return xy;
}
@@ -39,6 +43,30 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
}
+static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */
+ LP lp = {0.0,0.0};
+ struct pj_opaque *Q = P->opaque;
+ double c, x2, y2p, y2m;
+
+ if (fabs(fabs(xy.y) - 2.) < TOL) {
+ lp.phi = xy.y < 0 ? -M_HALFPI : M_HALFPI;
+ lp.lam = 0;
+ } else {
+ x2 = xy.x * xy.x;
+ y2p = 2. + xy.y;
+ y2m = 2. - xy.y;
+ c = y2p * y2m - x2;
+ if (fabs(c) < TOL) {
+ proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
+ return lp;
+ }
+ lp.phi = 2. * atan(pow((y2p * y2p + x2) / (Q->a2 * (y2m * y2m + x2)), Q->hw)) - M_HALFPI;
+ lp.lam = Q->w * atan2(4. * xy.x, c);
+ }
+ return lp;
+}
+
+
PJ *PROJECTION(lagrng) {
double phi1;
struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque));
@@ -46,20 +74,23 @@ PJ *PROJECTION(lagrng) {
return pj_default_destructor (P, ENOMEM);
P->opaque = Q;
- Q->rw = pj_param(P->ctx, P->params, "dW").f;
- if (Q->rw <= 0)
+ Q->w = pj_param(P->ctx, P->params, "dW").f;
+ if (Q->w <= 0)
return pj_default_destructor(P, PJD_ERR_W_OR_M_ZERO_OR_LESS);
-
- Q->rw = 1. / Q->rw;
+ Q->hw = 0.5 * Q->w;
+ Q->rw = 1. / Q->w;
Q->hrw = 0.5 * Q->rw;
phi1 = sin(pj_param(P->ctx, P->params, "rlat_1").f);
if (fabs(fabs(phi1) - 1.) < TOL)
return pj_default_destructor(P, PJD_ERR_LAT_LARGER_THAN_90);
Q->a1 = pow((1. - phi1)/(1. + phi1), Q->hrw);
+ Q->a2 = Q->a1 * Q->a1;
P->es = 0.;
+ P->inv = s_inverse;
P->fwd = s_forward;
return P;
}
+
diff --git a/test/gie/builtins.gie b/test/gie/builtins.gie
index be491346..3e2059c1 100644
--- a/test/gie/builtins.gie
+++ b/test/gie/builtins.gie
@@ -2418,15 +2418,54 @@ Lagrange
-------------------------------------------------------------------------------
operation +proj=lagrng +a=6400000 +W=2 +lat_1=0.5 +lat_2=2
-------------------------------------------------------------------------------
-tolerance 0.1 mm
-accept 2 1
-expect 111703.375917226 27929.831908033
-accept 2 -1
-expect 111699.122088816 -83784.178013358
-accept -2 1
-expect -111703.375917226 27929.831908033
-accept -2 -1
-expect -111699.122088816 -83784.178013358
+tolerance 0.1 mm
+accept 2 1
+expect 111703.375917226 27929.831908033
+
+roundtrip 100
+accept 2 -1
+expect 111699.122088816 -83784.178013358
+roundtrip 100
+
+accept -2 1
+expect -111703.375917226 27929.831908033
+roundtrip 100
+
+accept -2 -1
+expect -111699.122088816 -83784.178013358
+roundtrip 100
+
+accept 0 90
+expect 0.0000 12800000.0
+roundtrip 100
+
+-------------------------------------------------------------------------------
+operation +proj=lagrng +R=1 +lat_1=56
+-------------------------------------------------------------------------------
+tolerance 1 cm
+accept 12 56
+expect 0.10 0.0
+
+-------------------------------------------------------------------------------
+operation +proj=lagrng +R=1 +W=-1
+-------------------------------------------------------------------------------
+expect failure errno w_or_m_zero_or_less
+
+-------------------------------------------------------------------------------
+operation +proj=lagrng +R=1 +lat_1=90.00001
+-------------------------------------------------------------------------------
+expect failure errno lat_larger_than_90
+
+-------------------------------------------------------------------------------
+operation +proj=lagrng +R=1 +W=0.5
+-------------------------------------------------------------------------------
+accept 90 0 0
+expect failure errno tolerance_condition
+
+direction inverse
+accept 2 0 0
+expect failure errno tolerance_condition
+
===============================================================================