[GRASS-SVN] r72480 - in grass/trunk: include lib/proj
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Mar 21 13:41:55 PDT 2018
Author: mmetz
Date: 2018-03-21 13:41:55 -0700 (Wed, 21 Mar 2018)
New Revision: 72480
Modified:
grass/trunk/include/gprojects.h
grass/trunk/lib/proj/convert.c
grass/trunk/lib/proj/do_proj.c
grass/trunk/lib/proj/get_proj.c
Log:
libproj: remove hacks for PROJ 5+ API
Modified: grass/trunk/include/gprojects.h
===================================================================
--- grass/trunk/include/gprojects.h 2018-03-21 20:18:38 UTC (rev 72479)
+++ grass/trunk/include/gprojects.h 2018-03-21 20:41:55 UTC (rev 72480)
@@ -49,7 +49,8 @@
#endif
double meters;
int zone;
- char proj[256];
+ char proj[100];
+ char *def;
};
struct gpj_datum
@@ -85,6 +86,9 @@
from upstream; pending better solution. see:
http://trac.osgeo.org/proj/ticket/98 */
+/* In PROJ 5, the 'struct FACTORS' is back in as 'struct P5_FACTORS',
+ * and old 'struct LP' is now back in as 'PJ_UV' */
+
typedef struct { double u, v; } LP;
struct DERIVS {
Modified: grass/trunk/lib/proj/convert.c
===================================================================
--- grass/trunk/lib/proj/convert.c 2018-03-21 20:18:38 UTC (rev 72479)
+++ grass/trunk/lib/proj/convert.c 2018-03-21 20:41:55 UTC (rev 72480)
@@ -33,14 +33,6 @@
static void DatumNameMassage(char **);
#endif
-/* TODO: remove hack for PROJ 5+ */
-#ifdef HAVE_PROJ_H
-char *pj_get_def(PJ *, int);
-void pj_dalloc(void *);
-void pj_free(PJ *);
-#endif
-
-
/* from proj-5.0.0/src/pj_units.c */
struct gpj_units {
char *id; /* units keyword */
@@ -205,7 +197,7 @@
/* fetch the PROJ definition */
/* TODO: get the PROJ definition as used by pj_get_kv() */
- if ((proj4 = pj_get_def(pjinfo.pj, 0)) == NULL) {
+ if ((proj4 = pjinfo.def) == NULL) {
G_warning(_("Unable get PROJ.4-style parameter string"));
return NULL;
}
@@ -221,7 +213,6 @@
G_asprintf(&proj4mod, "%s +to_meter=%s", proj4, unfact);
else
proj4mod = G_store(proj4);
- pj_dalloc(proj4);
/* create GDAL OSR from proj string */
if ((errcode = OSRImportFromProj4(hSRS, proj4mod)) != OGRERR_NONE) {
Modified: grass/trunk/lib/proj/do_proj.c
===================================================================
--- grass/trunk/lib/proj/do_proj.c 2018-03-21 20:18:38 UTC (rev 72479)
+++ grass/trunk/lib/proj/do_proj.c 2018-03-21 20:41:55 UTC (rev 72480)
@@ -43,34 +43,46 @@
static double METERS_in = 1.0, METERS_out = 1.0;
-/* TODO: remove hack for PROJ 5+ */
-#ifdef HAVE_PROJ_H
-char *pj_get_def(PJ *, int);
-void pj_dalloc(void *);
-void pj_free(PJ *);
-
/* TODO: add to gprojects.h */
-/* Create a PROJ transformation object */
+/* Create a PROJ transformation object
+ * to transform coordinates from an input SRS to an output SRS */
+/* PROJ 5+:
+ * info_in, info_trans must not be null
+ * if info_out is null, assume info_out to be ll equivalent of info_in
+ * create info_trans from info_in to info_out
+ * NOTE: this is against the logic of PROJ 5 which by default
+ * converts from ll to a given SRS
+ * thus PROJ 5+ itself uses an inverse transformation in the
+ * first step of the pipeline for proj_create_crs_to_crs()
+ * PROJ 4:
+ * info_in, info_out must not be null
+ * do nothing
+ */
int GPJ_prepare_pjinfo(const struct pj_info *info_in,
const struct pj_info *info_out,
- struct pj_info *info_new)
+ struct pj_info *info_trans)
{
- char *projdef, *projdefin, *projdefout;
+ if (info_in == NULL)
+ G_fatal_error(_("Input coordinate system is NULL"));
- projdefin = pj_get_def(info_in->pj, 1);
- projdefout = pj_get_def(info_out->pj, 1);
- projdef = NULL;
- G_asprintf(&projdef, "+proj=pipeline +step %s +inv +step %s", projdefin, projdefout);
- info_new->pj = proj_create(PJ_DEFAULT_CTX, projdef);
- if (info_new->pj == NULL)
- G_fatal_error(_("proj_create() failed"));
- pj_dalloc(projdefin);
- pj_dalloc(projdefout);
- G_free(projdef);
+#ifdef HAVE_PROJ_H
+ if (info_trans == NULL)
+ G_fatal_error(_("Transformation object for PROJ is NULL"));
+ G_asprintf(&(info_trans->def), "+proj=pipeline +step %s +inv +step %s",
+ info_in->def, info_out->def);
+ info_trans->pj = proj_create(PJ_DEFAULT_CTX, info_trans->def);
+ if (info_trans->pj == NULL)
+ G_fatal_error(_("proj_create() failed for '%s'"), info_trans->def);
+
return 1;
+#else
+ if (info_out == NULL)
+ G_fatal_error(_("Output coordinate system is NULL"));
+
+ return 1;
+#endif
}
-#endif
/* TODO: rename pj_ to GPJ_ to avoid symbol clash with PROJ lib */
Modified: grass/trunk/lib/proj/get_proj.c
===================================================================
--- grass/trunk/lib/proj/get_proj.c 2018-03-21 20:18:38 UTC (rev 72479)
+++ grass/trunk/lib/proj/get_proj.c 2018-03-21 20:41:55 UTC (rev 72480)
@@ -33,13 +33,6 @@
static char *opt_in[MAX_PARGS];
static int nopt;
-/* TODO: remove hack for PROJ 5+ */
-#ifdef HAVE_PROJ_H
-char *pj_get_def(PJ *, int);
-void pj_dalloc(void *);
-void pj_free(PJ *);
-#endif
-
/* TODO: rename pj_ to GPJ_ to avoid symbol clash with PROJ lib */
/**
@@ -61,7 +54,7 @@
* 2 if "default" 3-parameter datum shift values from datum.table
* were used
* 3 if an unrecognised datum name was passed on to PROJ.4 (and
- * initialization was successful
+ * initialization was successful)
* 1 otherwise
**/
@@ -73,6 +66,7 @@
double a, es, rf;
int returnval = 1;
char buffa[300], factbuff[50];
+ int deflen;
char proj_in[250], *datum, *params;
#ifdef HAVE_PROJ_H
PJ *pj;
@@ -85,6 +79,7 @@
info->zone = 0;
info->meters = 1.0;
info->proj[0] = '\0';
+ info->def = NULL;
str = G_find_key_value("meters", in_units_keys);
if (str != NULL) {
@@ -267,8 +262,21 @@
info->pj = pj;
+ deflen = 0;
for (i = 0; i < nopt; i++)
+ deflen += strlen(opt_in[i]) + 2;
+
+ info->def = G_malloc(deflen + 1);
+
+ sprintf(buffa, "+%s ", opt_in[0]);
+ strcpy(info->def, buffa);
+ G_free(opt_in[0]);
+
+ for (i = 0; i < nopt; i++) {
+ sprintf(buffa, "+%s ", opt_in[0]);
+ strcat(info->def, buffa);
G_free(opt_in[i]);
+ }
return returnval;
}
@@ -283,11 +291,31 @@
return;
}
+/**
+ * \brief Create a pj_info struct Co-ordinate System definition from a
+ * string with a sequence of key=value pairs
+ *
+ * This function takes a GRASS- or PROJ style co-ordinate system definition
+ * and processes it to create a pj_info representation for use in
+ * re-projecting with pj_do_proj(). In addition to the parameters passed
+ * to it it may also make reference to the system ellipse.table and
+ * datum.table files if necessary.
+ *
+ * \param info Pointer to a pj_info struct (which must already exist) into
+ * which the co-ordinate system definition will be placed
+ * \param str input string with projection definition
+ * \param in_units_keys PROJ_UNITS-style key-value pairs
+ *
+ * \return -1 on error (unable to initialise PROJ.4)
+ * 1 on success
+ **/
+
int pj_get_string(struct pj_info *info, char *str)
{
char *s;
int i, nsize;
char zonebuff[50], buffa[300];
+ int deflen;
#ifdef HAVE_PROJ_H
PJ *pj;
PJ_CONTEXT *pjc;
@@ -298,6 +326,7 @@
info->zone = 0;
info->proj[0] = '\0';
info->meters = 1.0;
+ info->def = NULL;
nopt = 0;
@@ -369,12 +398,29 @@
#endif
info->pj = pj;
+ deflen = 0;
for (i = 0; i < nopt; i++)
+ deflen += strlen(opt_in[i]) + 2;
+
+ info->def = G_malloc(deflen + 1);
+
+ sprintf(buffa, "+%s ", opt_in[0]);
+ strcpy(info->def, buffa);
+ G_free(opt_in[0]);
+
+ for (i = 0; i < nopt; i++) {
+ sprintf(buffa, "+%s ", opt_in[0]);
+ strcat(info->def, buffa);
G_free(opt_in[i]);
+ }
return 1;
}
+#ifndef HAVE_PROJ_H
+/* GPJ_get_equivalent_latlong(): only available with PROJ 4 API
+ * with the new PROJ 5+ API, use pjold directly with PJ_FWD/PJ_INV transformation
+*/
/**
* \brief Define a latitude / longitude co-ordinate system with the same
* ellipsoid and datum parameters as an existing projected system
@@ -393,19 +439,22 @@
int GPJ_get_equivalent_latlong(struct pj_info *pjnew, struct pj_info *pjold)
{
-#ifdef HAVE_PROJ_H
- G_fatal_error(_("GPJ_get_equivalent_latlong(): with the new PROJ 5+ API "
- "use the old pj directly with PJ_FWD/PJ_INV transformation"));
-#else
+ char *deftmp;
+
pjnew->meters = 1.;
pjnew->zone = 0;
+ pjnew->def = NULL;
sprintf(pjnew->proj, "ll");
if ((pjnew->pj = pj_latlong_from_proj(pjold->pj)) == NULL)
return -1;
- else
- return 1;
+
+ deftmp = pj_get_def(pjnew->pj, 1);
+ pjnew->def = G_store(deftmp);
+ pj_dalloc(deftmp);
+
+ return 1;
+}
#endif
-}
/* set_proj_lib()
* 'finder function' for use with PROJ.4 pj_set_finder() function */
@@ -445,11 +494,10 @@
char *str;
if (iproj) {
- str = pj_get_def(iproj->pj, 1);
+ str = iproj->def;
if (str != NULL) {
fprintf(stderr, "%s: %s\n", _("Input Projection Parameters"),
str);
- pj_dalloc(str);
fprintf(stderr, "%s: %.16g\n", _("Input Unit Factor"),
iproj->meters);
}
@@ -458,11 +506,10 @@
}
if (oproj) {
- str = pj_get_def(oproj->pj, 1);
+ str = oproj->def;
if (str != NULL) {
fprintf(stderr, "%s: %s\n", _("Output Projection Parameters"),
str);
- pj_dalloc(str);
fprintf(stderr, "%s: %.16g\n", _("Output Unit Factor"),
oproj->meters);
}
More information about the grass-commit
mailing list