From 092c6d61b8fd7a22818492e39eb85e187b9ab0f5 Mon Sep 17 00:00:00 2001 From: Markus Metz Date: Wed, 6 May 2026 18:57:35 +0200 Subject: [PATCH 1/7] v.overlay: add option to remove small areas --- vector/v.overlay/area_area.c | 19 ++++++++++++++----- vector/v.overlay/local.h | 2 +- vector/v.overlay/main.c | 16 ++++++++++++---- vector/v.overlay/v.overlay.html | 10 +++++++++- vector/v.overlay/v.overlay.md | 12 ++++++++++-- 5 files changed, 46 insertions(+), 13 deletions(-) diff --git a/vector/v.overlay/area_area.c b/vector/v.overlay/area_area.c index e8ae6fb3ed5..b98f249fadb 100644 --- a/vector/v.overlay/area_area.c +++ b/vector/v.overlay/area_area.c @@ -26,7 +26,7 @@ static int cmp_int(const void *a, const void *b) int area_area(struct Map_info *In, int *field, struct Map_info *Tmp, struct Map_info *Out, struct field_info *Fi, dbDriver *driver, int operator, int *ofield, ATTRIBUTES *attr, struct ilist *BList, - double snap) + double snap, double area_minsize) { int ret, input, line, nlines, area, nareas; int in_centr, out_cat; @@ -172,10 +172,19 @@ int area_area(struct Map_info *In, int *field, struct Map_info *Tmp, Vect_remove_bridges(Tmp, NULL, NULL, NULL); } - G_set_verbose(0); - Vect_build_partial(Tmp, GV_BUILD_NONE); - Vect_build_partial(Tmp, GV_BUILD_BASE); - G_set_verbose(verbose); + if (area_minsize > 0) { + Vect_build_partial(Tmp, GV_BUILD_CENTROIDS); + G_message(_("Removing areas smaller than %g sqm..."), area_minsize); + Vect_remove_small_areas(Tmp, area_minsize, NULL, NULL); + Vect_build_partial(Tmp, GV_BUILD_BASE); + } + else { + G_set_verbose(0); + Vect_build_partial(Tmp, GV_BUILD_NONE); + Vect_build_partial(Tmp, GV_BUILD_BASE); + G_set_verbose(verbose); + } + G_message(_("Merging lines...")); Vect_merge_lines(Tmp, GV_BOUNDARY, NULL, NULL); diff --git a/vector/v.overlay/local.h b/vector/v.overlay/local.h index 5909cb540e7..73d99faa28f 100644 --- a/vector/v.overlay/local.h +++ b/vector/v.overlay/local.h @@ -29,7 +29,7 @@ ATTR *find_attr(ATTRIBUTES *attributes, int cat); int area_area(struct Map_info *In, int *field, struct Map_info *Tmp, struct Map_info *Out, struct field_info *Fi, dbDriver *driver, int operator, int * ofield, ATTRIBUTES *attr, struct ilist *BList, - double snap_thresh); + double snap_thresh, double area_minsize); int line_area(struct Map_info *In, int *field, struct Map_info *Tmp, struct Map_info *Out, struct field_info *Fi, dbDriver *driver, int operator, int * ofield, ATTRIBUTES *attr, diff --git a/vector/v.overlay/main.c b/vector/v.overlay/main.c index 8a22730f151..ae9730027e5 100644 --- a/vector/v.overlay/main.c +++ b/vector/v.overlay/main.c @@ -10,7 +10,7 @@ * OGR support by Martin Landa * Markus Metz * PURPOSE: - * COPYRIGHT: (C) 2003-2016 by the GRASS Development Team + * COPYRIGHT: (C) 2003-2026 by the GRASS Development Team * * This program is free software under the GNU General * Public License (>=v2). Read the file COPYING that @@ -36,10 +36,10 @@ int main(int argc, char *argv[]) { int i, j, input, line, nlines, operator; int type[2], field[2], ofield[3]; - double snap_thresh; + double snap_thresh, area_minsize; struct GModule *module; struct Option *in_opt[2], *out_opt, *type_opt[2], *field_opt[2], - *ofield_opt, *operator_opt, *snap_opt; + *ofield_opt, *operator_opt, *snap_opt, *minsize_opt; struct Flag *table_flag; struct Map_info In[2], Out, Tmp; struct line_pnts *Points, *Points2; @@ -142,6 +142,13 @@ int main(int argc, char *argv[]) snap_opt->type = TYPE_DOUBLE; snap_opt->answer = "1e-8"; + minsize_opt = G_define_option(); + minsize_opt->key = "minsize"; + minsize_opt->label = _("Minimum size of areas to keep in square meters"); + minsize_opt->description = _("Enable with minsize > 0"); + minsize_opt->type = TYPE_DOUBLE; + minsize_opt->answer = "0"; + table_flag = G_define_standard_flag(G_FLG_V_TABLE); table_flag->guisection = _("Attributes"); @@ -220,6 +227,7 @@ int main(int argc, char *argv[]) operator_opt->answer); snap_thresh = atof(snap_opt->answer); + area_minsize = atof(minsize_opt->answer); Points = Vect_new_line_struct(); Points2 = Vect_new_line_struct(); @@ -635,7 +643,7 @@ int main(int argc, char *argv[]) /* AREA x AREA */ if (type[0] == GV_AREA) { area_area(In, field, &Tmp, &Out, Fi, driver, operator, ofield, attr, - BList, snap_thresh); + BList, snap_thresh, area_minsize); } else { /* LINE x AREA */ line_area(In, field, &Tmp, &Out, Fi, driver, operator, ofield, attr, diff --git a/vector/v.overlay/v.overlay.html b/vector/v.overlay/v.overlay.html index 7069ad58b23..90ceebb36ae 100644 --- a/vector/v.overlay/v.overlay.html +++ b/vector/v.overlay/v.overlay.html @@ -55,8 +55,16 @@

NOTES

the output layer with the third number.

-If atype=auto is given than v.overlay determines +If atype=auto is given then v.overlay determines the feature type for ainput from the first found feature. +

+When overlaying two vectors with areas, very small areas can occur in the +output. This can happen when e.g. one vector is a slightly modified +version of the other vector (buffered or simplified). These very small +areas can be removed by setting minsize to some value larger 0. +The value is interpreted as square meters. In order to remove only noise +from slightly mismatching boundaries, the value of minsize should be +small, e.g. in the range 0.0001 to 1.