aboutsummaryrefslogtreecommitdiff
path: root/src/transformations/hgridshift.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-01-22 18:31:26 +0100
committerGitHub <noreply@github.com>2020-01-22 18:31:26 +0100
commitdb31b6dfa9c8fe37d5706d95ce81012b8db3c3b9 (patch)
treedc592c2b56f8af476c42a51f5dbc6ee04fabc280 /src/transformations/hgridshift.cpp
parent1ad703a58ce1867fe2ede96ebced1bdec9c63d65 (diff)
downloadPROJ-db31b6dfa9c8fe37d5706d95ce81012b8db3c3b9.tar.gz
PROJ-db31b6dfa9c8fe37d5706d95ce81012b8db3c3b9.zip
Merge RFC4 (#1865)
This commit is the result of the squashing of rfc4_dev branch in a single commit. It implements mostly RFC 4 related work. * Grid handling: - remove obsolete and presumably unfinished implementation of grid catalog functionality - all grid functionality is in grids.cpp/.hpp - vertical and horizontal grid shift: rework to no longer load whole grid into memory - remove hgrids and vgrids member from PJ structure, and store them in hgridshift/vgridshift/deformation structures - build systems: add optional libtiff dependency. Must be explicitly disabled if not desired - add support for horizontal and vertical grids in GeoTIFF, if libtiff is available - add GenericShiftGridSet and GenericShiftGrid classes, relying on TIFF grids, that can be used for generic purpose grid-based adjustment - add a +proj=xyzgridshift method to perform geocentric translation by grid. Used for French NTF to RGF93 transformation using gr3df97a.tif grid - deformation: add support for +grids= for GeoTIFF grids - horizontal grid shift: fix failures on points slightly outside a subgrid (fixes #209) * File management: - add a filemanager.cpp/.hpp to deal with file related work - test for legacy proj_api.h fileapi - proj.h: add proj_context_set_fileapi() and proj_context_set_sqlite3_vfs_name() (fixes #866) - add capability to read resource files from the user writable directory * Network access: - build systems: add optional curl dependency - add a curl-based default implementation for network related functionality - proj.h: add C API to control network functionality, and optionaly provide network callbacks - add data/proj.ini with default settings - add a SQLite3 local cache of downloaded chunks - add proj_is_download_needed() and proj_download_file() * Use Win32 Unicode APIs and expect all strings to be UTF-8 (fixes #1765) For backward compatibility, if PROJ_LIB content is found to be not UTF-8 or pointing to a non existing directory, then an attempt at interpretating it in the ANSI page encoding is done. proj_context_set_search_paths() now assumes strings to be in UTF-8, and functions returning paths will also return values in UTF-8.
Diffstat (limited to 'src/transformations/hgridshift.cpp')
-rw-r--r--src/transformations/hgridshift.cpp89
1 files changed, 67 insertions, 22 deletions
diff --git a/src/transformations/hgridshift.cpp b/src/transformations/hgridshift.cpp
index 90633939..122a7ab2 100644
--- a/src/transformations/hgridshift.cpp
+++ b/src/transformations/hgridshift.cpp
@@ -6,24 +6,38 @@
#include <time.h>
#include "proj_internal.h"
+#include "grids.hpp"
PROJ_HEAD(hgridshift, "Horizontal grid shift");
+using namespace NS_PROJ;
+
namespace { // anonymous namespace
-struct pj_opaque_hgridshift {
- double t_final;
- double t_epoch;
+struct hgridshiftData {
+ double t_final = 0;
+ double t_epoch = 0;
+ ListOfHGrids grids{};
+ bool defer_grid_opening = false;
};
} // anonymous namespace
static PJ_XYZ forward_3d(PJ_LPZ lpz, PJ *P) {
+ auto Q = static_cast<hgridshiftData*>(P->opaque);
PJ_COORD point = {{0,0,0,0}};
point.lpz = lpz;
- if (P->gridlist != nullptr) {
+ if ( Q->defer_grid_opening ) {
+ Q->defer_grid_opening = false;
+ Q->grids = pj_hgrid_init(P, "grids");
+ if ( proj_errno(P) ) {
+ return proj_coord_error().xyz;
+ }
+ }
+
+ if (!Q->grids.empty()) {
/* Only try the gridshift if at least one grid is loaded,
* otherwise just pass the coordinate through unchanged. */
- point.lp = proj_hgrid_apply(P, point.lp, PJ_FWD);
+ point.lp = pj_hgrid_apply(P->ctx, Q->grids, point.lp, PJ_FWD);
}
return point.xyz;
@@ -31,20 +45,29 @@ static PJ_XYZ forward_3d(PJ_LPZ lpz, PJ *P) {
static PJ_LPZ reverse_3d(PJ_XYZ xyz, PJ *P) {
+ auto Q = static_cast<hgridshiftData*>(P->opaque);
PJ_COORD point = {{0,0,0,0}};
point.xyz = xyz;
- if (P->gridlist != nullptr) {
+ if ( Q->defer_grid_opening ) {
+ Q->defer_grid_opening = false;
+ Q->grids = pj_hgrid_init(P, "grids");
+ if ( proj_errno(P) ) {
+ return proj_coord_error().lpz;
+ }
+ }
+
+ if (!Q->grids.empty()) {
/* Only try the gridshift if at least one grid is loaded,
* otherwise just pass the coordinate through unchanged. */
- point.lp = proj_hgrid_apply(P, point.lp, PJ_INV);
+ point.lp = pj_hgrid_apply(P->ctx, Q->grids, point.lp, PJ_INV);
}
return point.lpz;
}
static PJ_COORD forward_4d(PJ_COORD obs, PJ *P) {
- struct pj_opaque_hgridshift *Q = (struct pj_opaque_hgridshift *) P->opaque;
+ struct hgridshiftData *Q = (struct hgridshiftData *) P->opaque;
PJ_COORD point = obs;
/* If transformation is not time restricted, we always call it */
@@ -62,7 +85,7 @@ static PJ_COORD forward_4d(PJ_COORD obs, PJ *P) {
}
static PJ_COORD reverse_4d(PJ_COORD obs, PJ *P) {
- struct pj_opaque_hgridshift *Q = (struct pj_opaque_hgridshift *) P->opaque;
+ struct hgridshiftData *Q = (struct hgridshiftData *) P->opaque;
PJ_COORD point = obs;
/* If transformation is not time restricted, we always call it */
@@ -78,12 +101,29 @@ static PJ_COORD reverse_4d(PJ_COORD obs, PJ *P) {
return point;
}
+static PJ *destructor (PJ *P, int errlev) {
+ if (nullptr==P)
+ return nullptr;
+
+ delete static_cast<struct hgridshiftData*>(P->opaque);
+ P->opaque = nullptr;
+
+ return pj_default_destructor(P, errlev);
+}
+
+static void reassign_context( PJ* P, PJ_CONTEXT* ctx )
+{
+ auto Q = (struct hgridshiftData *) P->opaque;
+ for( auto& grid: Q->grids ) {
+ grid->reassign_context(ctx);
+ }
+}
PJ *TRANSFORMATION(hgridshift,0) {
- struct pj_opaque_hgridshift *Q = static_cast<struct pj_opaque_hgridshift*>(pj_calloc (1, sizeof (struct pj_opaque_hgridshift)));
- if (nullptr==Q)
- return pj_default_destructor (P, ENOMEM);
+ auto Q = new hgridshiftData;
P->opaque = (void *) Q;
+ P->destructor = destructor;
+ P->reassign_context = reassign_context;
P->fwd4d = forward_4d;
P->inv4d = reverse_4d;
@@ -97,12 +137,12 @@ PJ *TRANSFORMATION(hgridshift,0) {
if (0==pj_param(P->ctx, P->params, "tgrids").i) {
proj_log_error(P, "hgridshift: +grids parameter missing.");
- return pj_default_destructor (P, PJD_ERR_NO_ARGS);
+ return destructor (P, PJD_ERR_NO_ARGS);
}
- /* TODO: Refactor into shared function that can be used */
- /* by both vgridshift and hgridshift */
- if (pj_param(P->ctx, P->params, "tt_final").i) {
+ /* TODO: Refactor into shared function that can be used */
+ /* by both vgridshift and hgridshift */
+ 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" */
@@ -117,16 +157,21 @@ PJ *TRANSFORMATION(hgridshift,0) {
}
}
- if (pj_param(P->ctx, P->params, "tt_epoch").i)
+ 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? */
- if ( proj_errno(P) ) {
- proj_log_error(P, "hgridshift: could not find required grid(s).");
- return pj_default_destructor(P, PJD_ERR_FAILED_TO_LOAD_GRID);
+ if( P->ctx->defer_grid_opening ) {
+ Q->defer_grid_opening = true;
}
+ else {
+ Q->grids = pj_hgrid_init(P, "grids");
+ /* Was gridlist compiled properly? */
+ if ( proj_errno(P) ) {
+ proj_log_error(P, "hgridshift: could not find required grid(s).");
+ return destructor(P, PJD_ERR_FAILED_TO_LOAD_GRID);
+ }
+ }
return P;
}