Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Horisontal and vertical gridshift drivers #492

Merged
merged 5 commits into from
Mar 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ libproj_la_SOURCES = \
jniproj.c pj_mutex.c pj_initcache.c pj_apply_vgridshift.c geodesic.c \
pj_strtod.c \
\
pj_obs_api.c PJ_cart.c PJ_pipeline.c PJ_horner.c PJ_helmert.c
pj_obs_api.c PJ_cart.c PJ_pipeline.c PJ_horner.c PJ_helmert.c \
PJ_vgridshift.c PJ_hgridshift.c

install-exec-local:
rm -f $(DESTDIR)$(bindir)/invproj$(EXEEXT)
Expand Down
145 changes: 145 additions & 0 deletions src/PJ_hgridshift.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#define PJ_LIB__
#include <proj.h>
#include <projects.h>

PROJ_HEAD(hgridshift, "Horizontal grid shift");

static void *freeup_msg (PJ *P, int errlev) {
if (0==P)
return 0;

if (0!=P->ctx)
pj_ctx_set_errno (P->ctx, errlev);

return pj_dealloc(P);
}


static void freeup (PJ *P) {
freeup_msg (P, 0);
return;
}


static XYZ forward_3d(LPZ lpz, PJ *P) {
PJ_TRIPLET point;
point.lpz = lpz;

if (P->gridlist != NULL) {
/* Only try the gridshift if at least one grid is loaded,
* otherwise just pass the coordinate through unchanged. */
pj_apply_gridshift_3( P->ctx, P->gridlist,
P->gridlist_count, 1, 1, 0,
&point.xyz.x, &point.xyz.y, &point.xyz.z );
}

return point.xyz;
}


static LPZ reverse_3d(XYZ xyz, PJ *P) {
PJ_TRIPLET point;
point.xyz = xyz;

if (P->gridlist != NULL) {
/* Only try the gridshift if at least one grid is loaded,
* otherwise just pass the coordinate through unchanged. */
pj_apply_gridshift_3( P->ctx, P->gridlist,
P->gridlist_count, 0, 1, 0,
&point.xyz.x, &point.xyz.y, &point.xyz.z );
}

return point.lpz;
}


static PJ_OBS forward_obs(PJ_OBS obs, PJ *P) {
PJ_OBS point;
point.coo.xyz = forward_3d (obs.coo.lpz, P);
return point;
}


static PJ_OBS reverse_obs(PJ_OBS obs, PJ *P) {
PJ_OBS point;
point.coo.lpz = reverse_3d (obs.coo.xyz, P);
return point;
}


PJ *PROJECTION(hgridshift) {

if (!pj_param(P->ctx, P->params, "tgrids").i) {
pj_log_error(P, "hgridshift: +grids parameter missing.");
return freeup_msg(P, -1);
}

/* Build gridlist. P->gridlist can be empty if +grids only ask for optional grids. */
P->gridlist = pj_gridlist_from_nadgrids( P->ctx, pj_param(P->ctx, P->params, "sgrids").s,
&(P->gridlist_count) );

/* Was gridlist compiled properly? */
if ( pj_ctx_get_errno(P->ctx) ) {
pj_log_error(P, "hgridshift: could not find required grid(s).");
return freeup_msg(P, -38);
}

P->fwdobs = forward_obs;
P->invobs = reverse_obs;
P->fwd3d = forward_3d;
P->inv3d = reverse_3d;
P->fwd = 0;
P->inv = 0;

P->left = PJ_IO_UNITS_RADIANS;
P->right = PJ_IO_UNITS_RADIANS;

return P;
}


#ifndef PJ_SELFTEST
/* selftest stub */
int pj_hgridshift_selftest (void) {return 0;}
#else
int pj_hgridshift_selftest (void) {
PJ *P;
PJ_OBS expect, a, b;
double dist;

/* fail on purpose: +grids parameter is mandatory*/
P = pj_create("+proj=hgridshift");
if (0!=P)
return 99;

/* fail on purpose: open non-existing grid */
P = pj_create("+proj=hgridshift +grids=nonexistinggrid.gsb");
if (0!=P)
return 999;


/* Failure most likely means the grid is missing */
P = pj_create ("+proj=hgridshift +grids=nzgd2kgrid0005.gsb +ellps=GRS80");
if (0==P)
return 10;

a = pj_obs_null;
a.coo.lpz.lam = TORAD(173);
a.coo.lpz.phi = TORAD(-45);

dist = pj_roundtrip (P, PJ_FWD, 1, a);
if (dist > 0.00000001)
return 1;

expect.coo.lpz.lam = TORAD(172.999892181021551);
expect.coo.lpz.phi = TORAD(-45.001620431954613);
b = pj_trans(P, PJ_FWD, a);
if (pj_xy_dist(expect.coo.xy, b.coo.xy) > 1e-4)
return 2;


pj_free(P);

return 0;
}
#endif
147 changes: 147 additions & 0 deletions src/PJ_vgridshift.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
#define PJ_LIB__
#include <proj.h>
#include <projects.h>

PROJ_HEAD(vgridshift, "Vertical grid shift");

static void *freeup_msg (PJ *P, int errlev) {
if (0==P)
return 0;

if (0!=P->ctx)
pj_ctx_set_errno (P->ctx, errlev);

return pj_dealloc(P);
}


static void freeup (PJ *P) {
freeup_msg (P, 0);
return;
}


static XYZ forward_3d(LPZ lpz, PJ *P) {
PJ_TRIPLET point;
point.lpz = lpz;

if (P->gridlist != NULL) {
/* Only try the gridshift if at least one grid is loaded,
* otherwise just pass the coordinate through unchanged. */
pj_apply_vgridshift( P, "sgrids",
&(P->vgridlist_geoid),
&(P->vgridlist_geoid_count),
1, 1, 0,
&point.xyz.x, &point.xyz.y, &point.xyz.z );
}

return point.xyz;
}


static LPZ reverse_3d(XYZ xyz, PJ *P) {
PJ_TRIPLET point;
point.xyz = xyz;

if (P->gridlist != NULL) {
/* Only try the gridshift if at least one grid is loaded,
* otherwise just pass the coordinate through unchanged. */
pj_apply_vgridshift( P, "sgrids",
&(P->vgridlist_geoid),
&(P->vgridlist_geoid_count),
0, 1, 0,
&point.xyz.x, &point.xyz.y, &point.xyz.z );
}

return point.lpz;
}


static PJ_OBS forward_obs(PJ_OBS obs, PJ *P) {
PJ_OBS point;
point.coo.xyz = forward_3d (obs.coo.lpz, P);
return point;
}

static PJ_OBS reverse_obs(PJ_OBS obs, PJ *P) {
PJ_OBS point;
point.coo.lpz = reverse_3d (obs.coo.xyz, P);
return point;
}


PJ *PROJECTION(vgridshift) {

if (!pj_param(P->ctx, P->params, "tgrids").i) {
pj_log_error(P, "vgridshift: +grids parameter missing.");
return freeup_msg(P, -1);
}

/* Build gridlist. P->gridlist can be empty if +grids only ask for optional grids. */
P->gridlist = pj_gridlist_from_nadgrids( P->ctx, pj_param(P->ctx, P->params, "sgrids").s,
&(P->gridlist_count) );

/* Was gridlist compiled properly? */
if ( pj_ctx_get_errno(P->ctx) ) {
pj_log_error(P, "vgridshift: could not find required grid(s).");
return freeup_msg(P, -38);
}

P->fwdobs = forward_obs;
P->invobs = reverse_obs;
P->fwd3d = forward_3d;
P->inv3d = reverse_3d;
P->fwd = 0;
P->inv = 0;

P->left = PJ_IO_UNITS_RADIANS;
P->right = PJ_IO_UNITS_RADIANS;

return P;
}


#ifndef PJ_SELFTEST
/* selftest stub */
int pj_vgridshift_selftest (void) {return 0;}
#else
int pj_vgridshift_selftest (void) {
PJ *P;
PJ_OBS expect, a, b;
double dist;

/* fail on purpose: +grids parameter it mandatory*/
P = pj_create("+proj=vgridshift");
if (0!=P)
return 99;

/* fail on purpose: open non-existing grid */
P = pj_create("+proj=vgridshift +grids=nonexistinggrid.gtx");
if (0!=P)
return 999;

/* Failure most likely means the grid is missing */
P = pj_create ("+proj=vgridshift +grids=egm96_15.gtx +ellps=GRS80");
if (0==P)
return 10;

a = pj_obs_null;
a.coo.lpz.lam = TORAD(12.5);
a.coo.lpz.phi = TORAD(55.5);

dist = pj_roundtrip (P, PJ_FWD, 1, a);
if (dist > 0.00000001)
return 1;

expect = a;
expect.coo.lpz.z = -36.021305084228515625;
b = pj_trans(P, PJ_FWD, a);
if (pj_xyz_dist(expect.coo.xyz, b.coo.xyz) > 1e-10)
return 2;


pj_free(P);

return 0;
}
#endif
2 changes: 2 additions & 0 deletions src/lib_proj.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ SET(SRC_LIBPROJ_PJ
PJ_hammer.c
PJ_hatano.c
PJ_helmert.c
PJ_hgridshift.c
PJ_horner.c
PJ_igh.c
PJ_isea.c
Expand Down Expand Up @@ -139,6 +140,7 @@ SET(SRC_LIBPROJ_PJ
PJ_vandg.c
PJ_vandg2.c
PJ_vandg4.c
PJ_vgridshift.c
PJ_wag2.c
PJ_wag3.c
PJ_wag7.c
Expand Down
3 changes: 2 additions & 1 deletion src/makefile.vc
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ support = \
pj_strtod.obj pj_run_selftests.obj pj_generic_selftest.obj

pipeline = \
pj_obs_api.obj PJ_cart.obj PJ_pipeline.obj PJ_horner.obj PJ_helmert.obj
pj_obs_api.obj PJ_cart.obj PJ_pipeline.obj PJ_horner.obj PJ_helmert.obj \
PJ_vgridshift.obj PJ_hgridshift.obj

geodesic = geodesic.obj

Expand Down
2 changes: 2 additions & 0 deletions src/pj_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ PROJ_HEAD(hatano, "Hatano Asymmetrical Equal Area")
PROJ_HEAD(healpix, "HEALPix")
PROJ_HEAD(rhealpix, "rHEALPix")
PROJ_HEAD(helmert, "3- and 7-parameter Helmert shift")
PROJ_HEAD(hgridshift, "Horizontal grid shift")
PROJ_HEAD(horner, "Horner polynomial evaluation")
PROJ_HEAD(igh, "Interrupted Goode Homolosine")
PROJ_HEAD(imw_p, "International Map of the World Polyconic")
Expand Down Expand Up @@ -141,6 +142,7 @@ PROJ_HEAD(vandg2, "van der Grinten II")
PROJ_HEAD(vandg3, "van der Grinten III")
PROJ_HEAD(vandg4, "van der Grinten IV")
PROJ_HEAD(vitk1, "Vitkovsky I")
PROJ_HEAD(vgridshift, "Vertical grid shift")
PROJ_HEAD(wag1, "Wagner I (Kavraisky VI)")
PROJ_HEAD(wag2, "Wagner II")
PROJ_HEAD(wag3, "Wagner III")
Expand Down