aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjdugge <jdugge@users.noreply.github.com>2018-08-17 22:16:43 +0200
committerKristian Evers <kristianevers@gmail.com>2018-08-17 22:16:43 +0200
commit40036c19af8ae237a9b1565852340661bb1c66f8 (patch)
treed04658184f709815aa0543df86d8c07e2609dc66 /src
parentfe13c01125c57f1a2cd9256f78ee6233891fcec0 (diff)
downloadPROJ-40036c19af8ae237a9b1565852340661bb1c66f8.tar.gz
PROJ-40036c19af8ae237a9b1565852340661bb1c66f8.zip
Implementation of Equal Earth projection (#1090)
Implement the Equal Earth projection (closes #1085)
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/PJ_eqearth.c94
-rw-r--r--src/lib_proj.cmake1
-rw-r--r--src/makefile.vc3
-rw-r--r--src/pj_list.h1
5 files changed, 99 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 4e1db2e9..3040a403 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -78,6 +78,7 @@ libproj_la_SOURCES = \
pj_tsfn.c pj_units.c pj_ctx.c pj_log.c pj_zpoly1.c rtodms.c \
vector1.c pj_release.c pj_gauss.c \
PJ_healpix.c PJ_natearth.c PJ_natearth2.c PJ_calcofi.c pj_fileapi.c \
+ PJ_eqearth.c \
\
pj_gc_reader.c pj_gridcatalog.c \
nad_cvt.c nad_init.c nad_intr.c emess.c emess.h \
diff --git a/src/PJ_eqearth.c b/src/PJ_eqearth.c
new file mode 100644
index 00000000..2ca5ca20
--- /dev/null
+++ b/src/PJ_eqearth.c
@@ -0,0 +1,94 @@
+/*
+Equal Earth is a projection inspired by the Robinson projection, but unlike
+the Robinson projection retains the relative size of areas. The projection
+was designed in 2018 by Bojan Savric, Tom Patterson and Bernhard Jenny.
+
+Publication:
+Bojan Savric, Tom Patterson & Bernhard Jenny (2018). The Equal Earth map
+projection, International Journal of Geographical Information Science,
+DOI: 10.1080/13658816.2018.1504949
+
+Port to PROJ by Juernjakob Dugge, 16 August 2018
+*/
+#define PJ_LIB__
+
+#include <math.h>
+
+#include "projects.h"
+
+PROJ_HEAD(eqearth, "Equal Earth") "\n\tPCyl., Sph.";
+
+#define A1 1.340264
+#define A2 -0.081106
+#define A3 0.000893
+#define A4 0.003796
+#define M (sqrt(3) / 2.0)
+
+#define MAX_Y 1.3173627591574 /* 90° latitude on a sphere with radius 1 */
+#define EPS 1e-11
+#define MAX_ITER 12
+
+static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */
+ XY xy = {0.0,0.0};
+ double phi, phi2, phi6;
+ (void) P;
+
+ phi = asin(M * sin(lp.phi));
+ phi2 = phi * phi;
+ phi6 = phi2 * phi2 * phi2;
+
+ xy.x = lp.lam * cos(phi) / (M * (A1 + 3 * A2 * phi2 + phi6 * (7 * A3 + 9 * A4 * phi2)));
+ xy.y = phi * (A1 + A2 * phi2 + phi6 * (A3 + A4 * phi2));
+ return xy;
+}
+
+
+static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */
+ LP lp = {0.0,0.0};
+ double yc, tol, y2, y6, f, fder;
+ int i;
+ (void) P;
+
+ /* make sure y is inside valid range */
+ if (xy.y > MAX_Y) {
+ xy.y = MAX_Y;
+ } else if (xy.y < -MAX_Y) {
+ xy.y = -MAX_Y;
+ }
+
+ yc = xy.y;
+
+ for (i = MAX_ITER; i ; --i) { /* Newton-Raphson */
+ y2 = yc * yc;
+ y6 = y2 * y2 * y2;
+ f = yc * (A1 + A2 * y2 + y6 * (A3 + A4 * y2)) - xy.y;
+ fder = A1 + 3 * A2 * y2 + y6 * (7 * A3 + 9 * A4 * y2);
+ tol = f / fder;
+ yc -= tol;
+ if (fabs(tol) < EPS) {
+ break;
+ }
+ }
+
+ if( i == 0 ) {
+ pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT );
+ return lp;
+ }
+
+ y2 = yc * yc;
+ y6 = y2 * y2 * y2;
+
+ lp.lam = M * xy.x * (A1 + 3 * A2 * y2 + y6 * (7 * A3 + 9 * A4 * y2)) / cos(yc);
+ lp.phi = asin(sin(yc) / M);
+
+ return lp;
+}
+
+
+PJ *PROJECTION(eqearth) {
+ P->es = 0;
+ P->inv = s_inverse;
+ P->fwd = s_forward;
+
+ return P;
+}
diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake
index 249e8173..33f37bb0 100644
--- a/src/lib_proj.cmake
+++ b/src/lib_proj.cmake
@@ -67,6 +67,7 @@ SET(SRC_LIBPROJ_PJ
PJ_eck5.c
PJ_eqc.c
PJ_eqdc.c
+ PJ_eqearth.c
PJ_fahey.c
PJ_fouc_s.c
PJ_gall.c
diff --git a/src/makefile.vc b/src/makefile.vc
index ef39b084..d86649dd 100644
--- a/src/makefile.vc
+++ b/src/makefile.vc
@@ -38,7 +38,8 @@ pseudo = \
PJ_putp4p.obj PJ_putp5.obj PJ_putp6.obj PJ_robin.obj \
PJ_sts.obj PJ_urm5.obj PJ_urmfps.obj PJ_wag2.obj \
PJ_wag3.obj PJ_wink1.obj PJ_wink2.obj PJ_isea.obj \
- PJ_calcofi.obj PJ_natearth.obj PJ_natearth2.obj PJ_times.obj
+ PJ_calcofi.obj PJ_natearth.obj PJ_natearth2.obj PJ_times.obj \
+ PJ_eqearth.obj
support = \
aasincos.obj adjlon.obj bch2bps.obj bchgen.obj pj_gauss.obj \
diff --git a/src/pj_list.h b/src/pj_list.h
index 440f7972..0a8d9d1b 100644
--- a/src/pj_list.h
+++ b/src/pj_list.h
@@ -35,6 +35,7 @@ PROJ_HEAD(eck3, "Eckert III")
PROJ_HEAD(eck4, "Eckert IV")
PROJ_HEAD(eck5, "Eckert V")
PROJ_HEAD(eck6, "Eckert VI")
+PROJ_HEAD(eqearth, "Equal Earth")
PROJ_HEAD(eqc, "Equidistant Cylindrical (Plate Caree)")
PROJ_HEAD(eqdc, "Equidistant Conic")
PROJ_HEAD(euler, "Euler")