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
Temporal gridshifting #1015
Temporal gridshifting #1015
Changes from 3 commits
9d7db9d
29c2b56
ca453c1
3029de1
1e03829
d5f6453
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,20 @@ | ||
#define PJ_LIB__ | ||
|
||
#include <errno.h> | ||
#include <string.h> | ||
#include <stddef.h> | ||
#include <time.h> | ||
|
||
#include "proj_internal.h" | ||
#include "projects.h" | ||
|
||
PROJ_HEAD(hgridshift, "Horizontal grid shift"); | ||
|
||
struct pj_opaque_hgridshift { | ||
double t_final; | ||
double t_epoch; | ||
}; | ||
|
||
static XYZ forward_3d(LPZ lpz, PJ *P) { | ||
PJ_COORD point = {{0,0,0,0}}; | ||
point.lpz = lpz; | ||
|
@@ -34,21 +42,36 @@ static LPZ reverse_3d(XYZ xyz, PJ *P) { | |
return point.lpz; | ||
} | ||
|
||
|
||
static PJ_COORD forward_4d (PJ_COORD obs, PJ *P) { | ||
obs.xyz = forward_3d (obs.lpz, P); | ||
return obs; | ||
static PJ_COORD forward_4d(PJ_COORD obs, PJ *P) { | ||
struct pj_opaque_hgridshift *Q = (struct pj_opaque_hgridshift *) P->opaque; | ||
PJ_COORD point = obs; | ||
if (Q->t_final != 0.0 && Q->t_epoch != 0.0) { | ||
if (obs.lpzt.t < Q->t_epoch && Q->t_final > Q->t_epoch) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't that be be <= and >= ? Or so if t_final and t_epoch are specified, we apply the grid shift only if the observation time is below the epoch, and the epoch below the final epoch. That doesn't immediately seem obvious to me. Should probably be explained in the .rst files There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have just updated the .rst files. Do they cover the topic better now? From a physical point of view I would say that the case where A similar point can be made for the second part of the condition, but I think from a practical point of view it make sense to change it to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes the docs make things really clear (sorry I started looking at the code before reading your PR general comment where you mentioned that would be later detailed :-) ) |
||
point.xyz = forward_3d (obs.lpz, P); | ||
} else { | ||
point.xyz = forward_3d (obs.lpz, P); | ||
} | ||
return point; | ||
} | ||
|
||
|
||
static PJ_COORD reverse_4d (PJ_COORD obs, PJ *P) { | ||
obs.lpz = reverse_3d (obs.xyz, P); | ||
return obs; | ||
static PJ_COORD reverse_4d(PJ_COORD obs, PJ *P) { | ||
struct pj_opaque_hgridshift *Q = (struct pj_opaque_hgridshift *) P->opaque; | ||
PJ_COORD point = obs; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the code below (and the similar in the forward_4d case) will be more readable if the conditionals are inverted, so the if/if/else-branches can be decoupled:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good suggestion. Updated the code. |
||
if (Q->t_final != 0.0 && Q->t_epoch != 0.0) { | ||
if (obs.lpzt.t < Q->t_epoch && Q->t_final > Q->t_epoch) | ||
point.lpz = reverse_3d (obs.xyz, P); | ||
} else { | ||
point.lpz = reverse_3d (obs.xyz, P); | ||
} | ||
return point; | ||
} | ||
|
||
|
||
|
||
PJ *TRANSFORMATION(hgridshift,0) { | ||
struct pj_opaque_hgridshift *Q = pj_calloc (1, sizeof (struct pj_opaque_hgridshift)); | ||
if (0==Q) | ||
return pj_default_destructor (P, ENOMEM); | ||
P->opaque = (void *) Q; | ||
|
||
P->fwd4d = forward_4d; | ||
P->inv4d = reverse_4d; | ||
|
@@ -65,6 +88,24 @@ PJ *TRANSFORMATION(hgridshift,0) { | |
return pj_default_destructor (P, PJD_ERR_NO_ARGS); | ||
} | ||
|
||
if (pj_param(P->ctx, P->params, "tt_final").i) { | ||
Q->t_final = pj_param (P->ctx, P->params, "dt_final").f; | ||
if (Q->t_final == 0) { | ||
/* a number wasn't passed to +t_final, let's see if it was "now" */ | ||
/* and set the time accordingly. */ | ||
if (!strcmp("now", pj_param(P->ctx, P->params, "st_final").s)) { | ||
time_t now; | ||
struct tm *date; | ||
time(&now); | ||
date = localtime(&now); | ||
Q->t_final = 1900.0 + date->tm_year + date->tm_yday/365.0; | ||
} | ||
} | ||
} | ||
|
||
if (pj_param(P->ctx, P->params, "tt_epoch").i) | ||
Q->t_epoch = pj_param (P->ctx, P->params, "dt_epoch").f; | ||
|
||
|
||
proj_hgrid_init(P, "grids"); | ||
/* Was gridlist compiled properly? */ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,19 @@ | ||
#define PJ_LIB__ | ||
|
||
#include <errno.h> | ||
#include <stddef.h> | ||
#include <string.h> | ||
#include <time.h> | ||
|
||
#include "proj_internal.h" | ||
#include "projects.h" | ||
|
||
PROJ_HEAD(vgridshift, "Vertical grid shift"); | ||
|
||
struct pj_opaque_vgridshift { | ||
double t_final; | ||
double t_epoch; | ||
}; | ||
|
||
static XYZ forward_3d(LPZ lpz, PJ *P) { | ||
PJ_COORD point = {{0,0,0,0}}; | ||
|
@@ -37,25 +44,60 @@ static LPZ reverse_3d(XYZ xyz, PJ *P) { | |
|
||
|
||
static PJ_COORD forward_4d(PJ_COORD obs, PJ *P) { | ||
PJ_COORD point = {{0,0,0,0}}; | ||
point.xyz = forward_3d (obs.lpz, P); | ||
struct pj_opaque_vgridshift *Q = (struct pj_opaque_vgridshift *) P->opaque; | ||
PJ_COORD point = obs; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cf. comment in PJ_hgridshift.c regarding inverted conditionals |
||
if (Q->t_final != 0.0 && Q->t_epoch != 0.0) { | ||
if (obs.lpzt.t < Q->t_epoch && Q->t_final > Q->t_epoch) | ||
point.xyz = forward_3d (obs.lpz, P); | ||
} else { | ||
point.xyz = forward_3d (obs.lpz, P); | ||
} | ||
return point; | ||
} | ||
|
||
static PJ_COORD reverse_4d(PJ_COORD obs, PJ *P) { | ||
PJ_COORD point; | ||
point.lpz = reverse_3d (obs.xyz, P); | ||
struct pj_opaque_vgridshift *Q = (struct pj_opaque_vgridshift *) P->opaque; | ||
PJ_COORD point = obs; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cf. comment in PJ_hgridshift.c regarding inverted conditionals |
||
if (Q->t_final != 0.0 && Q->t_epoch != 0.0) { | ||
if (obs.lpzt.t < Q->t_epoch && Q->t_final > Q->t_epoch) | ||
point.lpz = reverse_3d (obs.xyz, P); | ||
} else { | ||
point.lpz = reverse_3d (obs.xyz, P); | ||
} | ||
return point; | ||
} | ||
|
||
|
||
PJ *TRANSFORMATION(vgridshift,0) { | ||
struct pj_opaque_vgridshift *Q = pj_calloc (1, sizeof (struct pj_opaque_vgridshift)); | ||
if (0==Q) | ||
return pj_default_destructor (P, ENOMEM); | ||
P->opaque = (void *) Q; | ||
|
||
if (!pj_param(P->ctx, P->params, "tgrids").i) { | ||
proj_log_error(P, "vgridshift: +grids parameter missing."); | ||
return pj_default_destructor(P, PJD_ERR_NO_ARGS); | ||
} | ||
|
||
if (pj_param(P->ctx, P->params, "tt_final").i) { | ||
Q->t_final = pj_param (P->ctx, P->params, "dt_final").f; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should likely have a pj_eval_param_time(const char*) function to do the below processing, since it is repeated above. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Good point. I intend to add similar functionality to
When can There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We'd need a configure / cmake check to test for its availability. Or alternatively "port" GDAL's https://github.com/OSGeo/gdal/blob/master/gdal/port/cpl_time.cpp#L64 which as indicated in the file header comes from public domain code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is a bit out of scope for this PR. How big a risk is it to include the code as it is now? localtime() is only called once during creation of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The risk is probably low. A TODO in the code + issue to remember should be good enough There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Created #1016 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can probably significantly reduce (but not eliminate) the risk by saying:
Essentially doing a copy of the the |
||
if (Q->t_final == 0) { | ||
/* a number wasn't passed to +t_final, let's see if it was "now" */ | ||
/* and set the time accordingly. */ | ||
if (!strcmp("now", pj_param(P->ctx, P->params, "st_final").s)) { | ||
time_t now; | ||
struct tm *date; | ||
time(&now); | ||
date = localtime(&now); | ||
Q->t_final = 1900.0 + date->tm_year + date->tm_yday/365.0; | ||
} | ||
} | ||
} | ||
|
||
if (pj_param(P->ctx, P->params, "tt_epoch").i) | ||
Q->t_epoch = pj_param (P->ctx, P->params, "dt_epoch").f; | ||
|
||
|
||
/* Build gridlist. P->vgridlist_geoid can be empty if +grids only ask for optional grids. */ | ||
proj_vgrid_init(P, "grids"); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hgridshift.rst should also be similarly updated