Browse Source

libproj: fix crs modification with PROJ6+ (#1007)

fix crs modification with PROJ6+ in lib/proj
fix usage of over switch in g.region and  [r|v].proj
Markus Metz 4 years ago
parent
commit
7bf60a0b2c
4 changed files with 53 additions and 30 deletions
  1. 4 1
      general/g.region/printwindow.c
  2. 39 25
      lib/proj/do_proj.c
  3. 5 2
      raster/r.proj/main.c
  4. 5 2
      vector/v.proj/main.c

+ 4 - 1
general/g.region/printwindow.c

@@ -555,7 +555,10 @@ void print_window(struct Cell_head *window, int print_flag, int flat_flag)
 	    if ((in_proj_info = G_get_projinfo()) == NULL)
 		G_fatal_error(_("Can't get projection info of current location"));
 	    /* do not wrap to -180, 180, otherwise east can be < west */
-	    G_set_key_value("+over", "defined", in_proj_info);
+	    /* TODO: for PROJ 6+, the +over switch must be added to the
+	     * transformation pipeline if authority:name or WKt are used 
+	     * as crs definition */
+	    G_set_key_value("over", "defined", in_proj_info);
 
 	    if ((in_unit_info = G_get_projunits()) == NULL)
 		G_fatal_error(_("Can't get projection units of current location"));

+ 39 - 25
lib/proj/do_proj.c

@@ -443,35 +443,41 @@ int GPJ_init_transform(const struct pj_info *info_in,
 	G_debug(1, "source proj string: %s", info_in->def);
 	G_debug(1, "source type: %s", get_pj_type_string(info_in->pj));
 	indefcrs = info_in->def;
-	source_crs = proj_get_source_crs(NULL, info_in->pj);
-	if (source_crs) {
-	    const char *projstr;
 
-	    projstr = proj_as_proj_string(NULL, source_crs, PJ_PROJ_5, NULL);
-	    if (projstr) {
-		indefcrs = G_store(projstr);
-		G_debug(1, "Input CRS definition converted from '%s' to '%s'",
-		        info_in->def, indefcrs);
+	if (proj_get_type(info_in->pj) == PJ_TYPE_BOUND_CRS) {
+	    source_crs = proj_get_source_crs(NULL, info_in->pj);
+	    if (source_crs) {
+		const char *projstr;
+
+		projstr = proj_as_proj_string(NULL, source_crs, PJ_PROJ_5, NULL);
+		if (projstr) {
+		    indefcrs = G_store(projstr);
+		    G_debug(1, "Input CRS definition converted from '%s' to '%s'",
+			    info_in->def, indefcrs);
+		}
+		proj_destroy(source_crs);
+		source_crs = NULL;
 	    }
-	    proj_destroy(source_crs);
-	    source_crs = NULL;
 	}
 
 	G_debug(1, "target proj string: %s", info_out->def);
 	G_debug(1, "target type: %s", get_pj_type_string(info_out->pj));
 	outdefcrs = info_out->def;
-	target_crs = proj_get_source_crs(NULL, info_out->pj);
-	if (target_crs) {
-	    const char *projstr;
 
-	    projstr = proj_as_proj_string(NULL, target_crs, PJ_PROJ_5, NULL);
-	    if (projstr) {
-		outdefcrs = G_store(projstr);
-		G_debug(1, "Output CRS definition converted from '%s' to '%s'",
-		        info_out->def, outdefcrs);
+	if (proj_get_type(info_in->pj) == PJ_TYPE_BOUND_CRS) {
+	    target_crs = proj_get_source_crs(NULL, info_out->pj);
+	    if (target_crs) {
+		const char *projstr;
+
+		projstr = proj_as_proj_string(NULL, target_crs, PJ_PROJ_5, NULL);
+		if (projstr) {
+		    outdefcrs = G_store(projstr);
+		    G_debug(1, "Output CRS definition converted from '%s' to '%s'",
+			    info_out->def, outdefcrs);
+		}
+		proj_destroy(target_crs);
+		target_crs = NULL;
 	    }
-	    proj_destroy(target_crs);
-	    target_crs = NULL;
 	}
 
 	/* PROJ6+: EPSG must be uppercase EPSG */
@@ -680,11 +686,18 @@ int GPJ_init_transform(const struct pj_info *info_in,
 			      info_trans->def);
 		}
 		else {
-		    proj_destroy(info_trans->pj);
-		    info_trans->pj = pj_norm;
-		    projstr = proj_as_proj_string(NULL, info_trans->pj,
-						    PJ_PROJ_5, NULL);
-		    info_trans->def = G_store(projstr);
+		    projstr = proj_as_proj_string(NULL, pj_norm,
+						  PJ_PROJ_5, NULL);
+		    if (projstr && *projstr) {
+			proj_destroy(info_trans->pj);
+			info_trans->pj = pj_norm;
+			info_trans->def = G_store(projstr);
+		    }
+		    else {
+			proj_destroy(pj_norm);
+			G_warning(_("No PROJ definition for normalized version of '%s'"),
+			      info_trans->def);
+		    }
 		}
 		if (op_count > 1) {
 		    G_important_message(_("Selected pipeline:"));
@@ -719,6 +732,7 @@ int GPJ_init_transform(const struct pj_info *info_in,
 		       indef, outdef);
 
 	    info_trans->pj = proj_create(PJ_DEFAULT_CTX, info_trans->def);
+	    G_debug(1, "proj_create() pipeline: %s", info_trans->def);
 	}
 
 	if (pj_area)

+ 5 - 2
raster/r.proj/main.c

@@ -317,9 +317,12 @@ int main(int argc, char **argv)
 	G_fatal_error(_("Unable to get projection info of input map"));
 
     /* apparently the +over switch must be set in the input projection,
-     * not the output latlon projection */
+     * not the output latlon projection
+     * TODO: for PROJ 6+, the +over switch must be added to the
+     * transformation pipeline if authority:name or WKt are used as
+     * crs definition */
     if (curr_proj == PROJECTION_LL)
-	G_set_key_value("+over", "defined", in_proj_info);
+	G_set_key_value("over", "defined", in_proj_info);
 
     if ((in_unit_info = G_get_projunits()) == NULL)
 	G_fatal_error(_("Unable to get projection units of input map"));

+ 5 - 2
vector/v.proj/main.c

@@ -231,9 +231,12 @@ int main(int argc, char *argv[])
 	    exit(EXIT_FAILURE);
 
 	/* apparently the +over switch must be set in the input projection,
-	 * not the output latlon projection */
+	 * not the output latlon projection
+	 * TODO: for PROJ 6+, the +over switch must be added to the
+	 * transformation pipeline if authority:name or WKt are used as
+	 * crs definition */
 	if (Out_proj == PROJECTION_LL && nowrap == 1)
-	    G_set_key_value("+over", "defined", in_proj_keys);
+	    G_set_key_value("over", "defined", in_proj_keys);
 
 	in_unit_keys = G_get_projunits();
 	if (in_unit_keys == NULL)