[GRASS-SVN] r71594 - grass/trunk/vector/v.in.ogr

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Oct 25 11:33:30 PDT 2017


Author: mmetz
Date: 2017-10-25 11:33:30 -0700 (Wed, 25 Oct 2017)
New Revision: 71594

Modified:
   grass/trunk/vector/v.in.ogr/main.c
   grass/trunk/vector/v.in.ogr/proj.c
Log:
v.in.ogr: bug fixes for location creation and error reporting

Modified: grass/trunk/vector/v.in.ogr/main.c
===================================================================
--- grass/trunk/vector/v.in.ogr/main.c	2017-10-25 09:00:34 UTC (rev 71593)
+++ grass/trunk/vector/v.in.ogr/main.c	2017-10-25 18:33:30 UTC (rev 71594)
@@ -152,6 +152,7 @@
     double area_size;
     int use_tmp_vect;
     int ncentr, n_overlaps;
+    int failed_centr, err_boundaries, err_centr_out, err_centr_dupl;
     struct bound_box box;
 
     xmin = ymin = 1.0;
@@ -617,6 +618,7 @@
     cellhd.ew_res3 = 1.;
     cellhd.tb_res = 1.;
 
+    /* check projection match */
     check_projection(&cellhd, Ogr_ds, layers[0], param.geom->answer,
 		     param.outloc->answer,
                      flag.no_import->answer, flag.over->answer,
@@ -830,6 +832,7 @@
     Vect_hist_command(&Map);
 
     ncentr = n_overlaps = n_polygons = 0;
+    failed_centr = 0;
 
     G_begin_polygon_area_calculations();	/* Used in geom() and centroid() */
 
@@ -1407,6 +1410,7 @@
 	    Centr[centr].cats = Vect_new_cats_struct();
 	    ret = Vect_get_point_in_area(&Tmp, centr, &x, &y);
 	    if (ret < 0) {
+		failed_centr++;
 		G_warning(_("Unable to calculate area centroid"));
 		continue;
 	    }
@@ -1577,94 +1581,175 @@
 	Vect_topo_check(&Map, NULL);
 #endif
 
-    if (n_polygons && nlayers == 1) {
-	/* test for topological errors */
-	/* this test is not perfect:
-	 * small gaps (areas without centroid) are not detected
-	 * small gaps may also be true gaps */
-	ncentr = Vect_get_num_primitives(&Map, GV_CENTROID);
-	if (ncentr != n_polygons || n_overlaps) {
-	    double min_snap, max_snap;
-	    int exp;
+    /* fast topology check */
+    err_boundaries = err_centr_out = err_centr_dupl = 0;
+    if (Vect_get_num_primitives(&Map, GV_BOUNDARY) > 0) {
+	int line, nlines, ltype;
 
-	    Vect_get_map_box(&Map, &box);
+	nlines = Vect_get_num_lines(&Map);
+	for (line = 1; line <= nlines; line++) {
+	    if (!Vect_line_alive(&Map, line))
+		continue;
 	    
-	    if (abs(box.E) > abs(box.W))
-		xmax = abs(box.E);
-	    else
-		xmax = abs(box.W);
-	    if (abs(box.N) > abs(box.S))
-		ymax = abs(box.N);
-	    else
-		ymax = abs(box.S);
+	    ltype = Vect_get_line_type(&Map, line);
+	    if (ltype == GV_BOUNDARY) {
+		int left, right;
 
-	    if (xmax < ymax)
-		xmax = ymax;
+		left = right = 0;
+		Vect_get_line_areas(&Map, line, &left, &right);
 
-	    /* double precision ULP */
-	    min_snap = frexp(xmax, &exp);
-	    exp -= 52;
-	    min_snap = ldexp(min_snap, exp);
-	    /* human readable */
-	    min_snap = log10(min_snap);
-	    if (min_snap < 0)
-		min_snap = (int)min_snap;
-	    else
-		min_snap = (int)min_snap + 1;
-	    min_snap = pow(10, min_snap);
+		if (left == 0 || right == 0) {
+		    err_boundaries++;
+		}
+	    }
+	    else if (ltype == GV_CENTROID) {
+		int area;
+		
+		area = 0;
+		
+		area = Vect_get_centroid_area(&Map, line);
 
-	    /* single precision ULP */
-	    max_snap = frexp(xmax, &exp);
-	    exp -= 23;
-	    max_snap = ldexp(max_snap, exp);
-	    /* human readable */
-	    max_snap = log10(max_snap);
-	    if (max_snap < 0)
-		max_snap = (int)max_snap;
+		if (area == 0)
+		    err_centr_out++;
+		else if (area < 0)
+		    err_centr_dupl++;
+	    }
+	}
+    }
+
+    /* test for topological errors */
+    /* this test is not perfect:
+     * small gaps (areas without centroid) are not detected
+     * small gaps may also be true gaps */
+    ncentr = Vect_get_num_primitives(&Map, GV_CENTROID);
+    if (failed_centr || err_boundaries || err_centr_out || err_centr_dupl
+        || ncentr != n_polygons || n_overlaps) {
+
+	double min_snap, max_snap;
+	int exp;
+
+	Vect_get_map_box(&Map, &box);
+	
+	if (abs(box.E) > abs(box.W))
+	    xmax = abs(box.E);
+	else
+	    xmax = abs(box.W);
+	if (abs(box.N) > abs(box.S))
+	    ymax = abs(box.N);
+	else
+	    ymax = abs(box.S);
+
+	if (xmax < ymax)
+	    xmax = ymax;
+
+	/* double precision ULP */
+	min_snap = frexp(xmax, &exp);
+	exp -= 52;
+	min_snap = ldexp(min_snap, exp);
+	/* human readable */
+	min_snap = log10(min_snap);
+	if (min_snap < 0)
+	    min_snap = (int)min_snap;
+	else
+	    min_snap = (int)min_snap + 1;
+	min_snap = pow(10, min_snap);
+
+	/* single precision ULP */
+	max_snap = frexp(xmax, &exp);
+	exp -= 23;
+	max_snap = ldexp(max_snap, exp);
+	/* human readable */
+	max_snap = log10(max_snap);
+	if (max_snap < 0)
+	    max_snap = (int)max_snap;
+	else
+	    max_snap = (int)max_snap + 1;
+	max_snap = pow(10, max_snap);
+
+	/* topological errors are
+	 * - areas too small / too thin to calculate a centroid
+	 * - incorrect boundaries
+	 * - duplicate area centroids
+	 * - centroids outside any area
+	 * 
+	 * overlapping polygons are topological problems only
+	 * if input polygons are not supposed to overlap
+	 */
+
+	G_important_message("%s", separator);
+	/* topological errors */
+	if (failed_centr || err_boundaries || err_centr_out || err_centr_dupl) {
+	    G_warning(_("The output contains topological errors:"));
+	    if (failed_centr)
+		G_warning(_("Unable to calculate a centroid for %d areas"), failed_centr);
+	    if (err_boundaries)
+		G_warning(_("Number of incorrect boundaries: %d"),
+			  err_boundaries);
+	    if (err_centr_out)
+		G_warning(_("Number of centroids outside area: %d"),
+			  err_centr_out);
+	    if (err_centr_dupl)
+		G_warning(_("Number of duplicate centroids: %d"),
+			  err_centr_dupl);
+	    
+	    G_important_message(_("The input could be cleaned by snapping vertices to each other."));
+
+	    if (snap < max_snap) {
+		G_important_message(_("Estimated range of snapping threshold: [%g, %g]"), min_snap, max_snap);
+	    }
+
+	    if (snap < min_snap) {
+		G_important_message(_("Try to import again, snapping with at least %g: 'snap=%g'"), min_snap, min_snap);
+	    }
+	    else if (snap < max_snap) {
+		min_snap = snap * 10;
+		G_important_message(_("Try to import again, snapping with %g: 'snap=%g'"), min_snap, min_snap);
+	    }
 	    else
-		max_snap = (int)max_snap + 1;
-	    max_snap = pow(10, max_snap);
-
-	    G_important_message("%s", separator);
+		/* assume manual cleaning is required */
+		G_important_message(_("Manual cleaning may be needed."));
+	}
+	/* overlapping polygons */
+	else if (n_overlaps) {
 	    if (n_overlaps) {
 		G_important_message(_("Some input polygons are overlapping each other."));
 		G_important_message(_("If overlapping is not desired, the data need to be cleaned."));
+		G_important_message(_("The input could be cleaned by snapping vertices to each other."));
+	    }
 
-		if (snap < max_snap) {
-		    G_important_message(_("The input could be cleaned by snapping vertices to each other."));
-		    G_important_message(_("Estimated range of snapping threshold: [%g, %g]"), min_snap, max_snap);
-		}
+	    if (snap < max_snap) {
+		G_important_message(_("Estimated range of snapping threshold: [%g, %g]"), min_snap, max_snap);
+	    }
 
-		if (snap < min_snap) {
-		    G_important_message(_("Try to import again, snapping with at least %g: 'snap=%g'"), min_snap, min_snap);
-		}
-		else if (snap < max_snap) {
-		    min_snap = snap * 10;
-		    G_important_message(_("Try to import again, snapping with %g: 'snap=%g'"), min_snap, min_snap);
-		}
-		else
-		    /* assume manual cleaning is required */
-		    G_important_message(_("Manual cleaning may be needed."));
+	    if (snap < min_snap) {
+		G_important_message(_("Try to import again, snapping with at least %g: 'snap=%g'"), min_snap, min_snap);
 	    }
+	    else if (snap < max_snap) {
+		min_snap = snap * 10;
+		G_important_message(_("Try to import again, snapping with %g: 'snap=%g'"), min_snap, min_snap);
+	    }
+	    else
+		/* assume manual cleaning is required */
+		G_important_message(_("Manual cleaning may be needed."));
+	}
+	/* number of centroids does not match number of input polygons */
+	else if (ncentr != n_polygons) {
+	    if (ncentr < n_polygons) {
+		G_important_message(_("%d input polygons got lost during import."), n_polygons - ncentr);
+	    }
+	    if (ncentr > n_polygons) {
+		G_important_message(_("%d additional areas where created during import."), ncentr - n_polygons);
+	    }
+	    if (snap > 0) {
+		G_important_message(_("The snapping threshold %g might be too large."), snap);
+		G_important_message(_("Estimated range of snapping threshold: [%g, %g]"), min_snap, max_snap);
+		/* assume manual cleaning is required */
+		G_important_message(_("Try to reduce the snapping threshold or clean the output manually."));
+	    }
 	    else {
-		if (ncentr < n_polygons) {
-		    G_important_message(_("%d input polygons got lost during import."), n_polygons - ncentr);
-		}
-		if (ncentr > n_polygons) {
-		    G_important_message(_("%d additional areas where created during import."), ncentr - n_polygons);
-		}
-		if (snap > 0) {
-		    G_important_message(_("The snapping threshold %g might be too large."), snap);
-		    G_important_message(_("Estimated range of snapping threshold: [%g, %g]"), min_snap, max_snap);
-		    /* assume manual cleaning is required */
-		    G_important_message(_("Manual cleaning may be needed."));
-		}
-		else {
-		    G_important_message(_("The input could be cleaned by snapping vertices to each other."));
-		    G_important_message(_("Estimated range of snapping threshold: [%g, %g]"), min_snap, max_snap);
-		}
+		G_important_message(_("The input could be cleaned by snapping vertices to each other."));
+		G_important_message(_("Estimated range of snapping threshold: [%g, %g]"), min_snap, max_snap);
 	    }
-
 	}
     }
 

Modified: grass/trunk/vector/v.in.ogr/proj.c
===================================================================
--- grass/trunk/vector/v.in.ogr/proj.c	2017-10-25 09:00:34 UTC (rev 71593)
+++ grass/trunk/vector/v.in.ogr/proj.c	2017-10-25 18:33:30 UTC (rev 71594)
@@ -19,7 +19,6 @@
     Ogr_projection = NULL;
     *proj_info = NULL;
     *proj_units = NULL;
-    G_get_window(cellhd);
 
     /* Fetch input layer projection in GRASS form. */
 #if GDAL_VERSION_NUM >= 1110000
@@ -133,6 +132,7 @@
     proj_info1 = proj_units1 = NULL;
     proj_info2 = proj_units2 = NULL;
 
+    G_get_window(&cellhd1);
     layer = 0;
     do {
 	/* Get first SRS */
@@ -172,6 +172,7 @@
     for (layer = 1; layer < nlayers; layer++) {
 	/* Get SRS of other layer(s) */
 	Ogr_layer = ds_getlayerbyindex(Ogr_ds, layers[layer]);
+	G_get_window(&cellhd2);
 	if (get_layer_proj(Ogr_layer, &cellhd2, &proj_info2, &proj_units2,
 			   geom_col, 0) != 0) {
 	    G_free_key_value(proj_info1);
@@ -340,6 +341,30 @@
 			sprintf(error_msg + strlen(error_msg), "%s: %s\n",
 				proj_info->key[i_value],
 				proj_info->value[i_value]);
+		}
+		else {
+		    strcat(error_msg, _("Dataset PROJ_INFO is:\n"));
+		    if (cellhd->proj == PROJECTION_XY)
+			sprintf(error_msg + strlen(error_msg),
+				"Dataset proj = %d (unreferenced/unknown)\n",
+				cellhd->proj);
+		    else if (cellhd->proj == PROJECTION_LL)
+			sprintf(error_msg + strlen(error_msg),
+				"Dataset proj = %d (lat/long)\n",
+				cellhd->proj);
+		    else if (cellhd->proj == PROJECTION_UTM)
+			sprintf(error_msg + strlen(error_msg),
+				"Dataset proj = %d (UTM), zone = %d\n",
+				cellhd->proj, cellhd->zone);
+		    else
+			sprintf(error_msg + strlen(error_msg),
+				"Dataset proj = %d (unknown), zone = %d\n",
+				cellhd->proj, cellhd->zone);
+		}
+		if (loc_wind.proj != cellhd->proj) {
+		    strcat(error_msg, "\nERROR: proj\n");
+		}
+		else {
 		    strcat(error_msg, "\nERROR: ");
 		    switch (err) {
 		    case -1:
@@ -377,25 +402,6 @@
 			break;
 		    }
 		}
-		else {
-		    strcat(error_msg, _("Dataset PROJ_INFO is:\n"));
-		    if (cellhd->proj == PROJECTION_XY)
-			sprintf(error_msg + strlen(error_msg),
-				"Dataset proj = %d (unreferenced/unknown)\n",
-				cellhd->proj);
-		    else if (cellhd->proj == PROJECTION_LL)
-			sprintf(error_msg + strlen(error_msg),
-				"Dataset proj = %d (lat/long)\n",
-				cellhd->proj);
-		    else if (cellhd->proj == PROJECTION_UTM)
-			sprintf(error_msg + strlen(error_msg),
-				"Dataset proj = %d (UTM), zone = %d\n",
-				cellhd->proj, cellhd->zone);
-		    else
-			sprintf(error_msg + strlen(error_msg),
-				"Dataset proj = %d (unknown), zone = %d\n",
-				cellhd->proj, cellhd->zone);
-		}
 	    }
 	    else {
 		/* error in proj_units */
@@ -426,11 +432,12 @@
 		    "the 'location' parameter.\n"));
 
 	    if (check_only)
-		msg_fn = G_message;
+		msg_fn = G_warning;
 	    else
 		msg_fn = G_fatal_error;
 	    msg_fn(error_msg);
 	    if (check_only) {
+		ds_close(hDS);
 		exit(EXIT_FAILURE);
 	    }
 	}



More information about the grass-commit mailing list