[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