[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