GRASS 8 Programmer's Manual  8.5.0dev(2025)-c070206eb1
remove_areas.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/remove_areas.c
3 
4  \brief Vector library - clean geometry (remove small areas)
5 
6  Higher level functions for reading/writing/manipulating vectors.
7 
8  (C) 2001-2009 by the GRASS Development Team
9 
10  This program is free software under the GNU General Public License
11  (>=v2). Read the file COPYING that comes with GRASS for details.
12 
13  \author Radim Blazek, Markus Metz
14  */
15 
16 #include <stdlib.h>
17 #include <grass/vector.h>
18 #include <grass/glocale.h>
19 
20 int Vect_remove_small_areas_nat(struct Map_info *, double, struct Map_info *,
21  double *);
22 
23 int Vect_remove_small_areas_ext(struct Map_info *, double, struct Map_info *,
24  double *);
25 
26 /*!
27  \brief Remove small areas from the map map.
28 
29  Centroid of the area and the longest boundary with adjacent area is
30  removed. Map topology must be built GV_BUILD_CENTROIDS.
31 
32  \param[in,out] Map vector map
33  \param thresh maximum area size for removed areas
34  \param[out] Err vector map where removed lines and centroids are written
35  \param removed_area pointer to where total size of removed area is stored or
36  NULL
37 
38  \return number of removed areas
39  */
40 int Vect_remove_small_areas(struct Map_info *Map, double thresh,
41  struct Map_info *Err, double *removed_area)
42 {
43 
44  if (Map->format == GV_FORMAT_NATIVE)
45  return Vect_remove_small_areas_nat(Map, thresh, Err, removed_area);
46  else
47  return Vect_remove_small_areas_ext(Map, thresh, Err, removed_area);
48 }
49 
50 int Vect_remove_small_areas_ext(struct Map_info *Map, double thresh,
51  struct Map_info *Err, double *removed_area)
52 {
53  int area, nareas;
54  int nremoved = 0;
55  struct ilist *List;
56  struct ilist *AList;
57  struct line_pnts *Points;
58  struct line_cats *Cats;
59  double size_removed = 0.0;
60 
61  List = Vect_new_list();
62  AList = Vect_new_list();
63  Points = Vect_new_line_struct();
64  Cats = Vect_new_cats_struct();
65 
66  nareas = Vect_get_num_areas(Map);
67  for (area = 1; area <= nareas; area++) {
68  int i, j, centroid, dissolve_neighbour;
69  double length, size;
70 
71  G_percent(area, nareas, 1);
72  G_debug(3, "area = %d", area);
73  if (!Vect_area_alive(Map, area))
74  continue;
75 
76  size = Vect_get_area_area(Map, area);
77  if (size > thresh)
78  continue;
79  size_removed += size;
80 
81  /* The area is smaller than the limit -> remove */
82 
83  /* Remove centroid */
84  centroid = Vect_get_area_centroid(Map, area);
85  if (centroid > 0) {
86  if (Err) {
87  Vect_read_line(Map, Points, Cats, centroid);
88  Vect_write_line(Err, GV_CENTROID, Points, Cats);
89  }
90  Vect_delete_line(Map, centroid);
91  }
92 
93  /* Find the adjacent area with which the longest boundary is shared */
94 
95  Vect_get_area_boundaries(Map, area, List);
96 
97  /* Create a list of neighbour areas */
98  Vect_reset_list(AList);
99  for (i = 0; i < List->n_values; i++) {
100  int line, left, right, neighbour;
101 
102  line = List->value[i];
103 
104  if (!Vect_line_alive(Map, abs(line))) /* Should not happen */
105  G_fatal_error(_("Area is composed of dead boundary"));
106 
107  Vect_get_line_areas(Map, abs(line), &left, &right);
108  if (line > 0)
109  neighbour = left;
110  else
111  neighbour = right;
112 
113  G_debug(4, " line = %d left = %d right = %d neighbour = %d", line,
114  left, right, neighbour);
115 
116  Vect_list_append(AList, neighbour); /* this checks for duplicity */
117  }
118  G_debug(3, "num neighbours = %d", AList->n_values);
119 
120  /* Go through the list of neighbours and find that with the longest
121  * boundary */
122  dissolve_neighbour = 0;
123  length = -1.0;
124  for (i = 0; i < AList->n_values; i++) {
125  int neighbour1;
126  double l = 0.0;
127 
128  neighbour1 = AList->value[i];
129  G_debug(4, " neighbour1 = %d", neighbour1);
130 
131  for (j = 0; j < List->n_values; j++) {
132  int line, left, right, neighbour2;
133 
134  line = List->value[j];
135  Vect_get_line_areas(Map, abs(line), &left, &right);
136  if (line > 0)
137  neighbour2 = left;
138  else
139  neighbour2 = right;
140 
141  if (neighbour2 == neighbour1) {
142  Vect_read_line(Map, Points, NULL, abs(line));
143  l += Vect_line_length(Points);
144  }
145  }
146  if (l > length) {
147  length = l;
148  dissolve_neighbour = neighbour1;
149  }
150  }
151 
152  G_debug(3, "dissolve_neighbour = %d", dissolve_neighbour);
153 
154  /* Make list of boundaries to be removed */
155  Vect_reset_list(AList);
156  for (i = 0; i < List->n_values; i++) {
157  int line, left, right, neighbour;
158 
159  line = List->value[i];
160  Vect_get_line_areas(Map, abs(line), &left, &right);
161  if (line > 0)
162  neighbour = left;
163  else
164  neighbour = right;
165 
166  G_debug(3, " neighbour = %d", neighbour);
167 
168  if (neighbour == dissolve_neighbour) {
169  Vect_list_append(AList, abs(line));
170  }
171  }
172 
173  /* Remove boundaries */
174  for (i = 0; i < AList->n_values; i++) {
175  int line;
176 
177  line = AList->value[i];
178 
179  if (Err) {
180  Vect_read_line(Map, Points, Cats, line);
181  Vect_write_line(Err, GV_BOUNDARY, Points, Cats);
182  }
183  Vect_delete_line(Map, line);
184  }
185 
186  nremoved++;
187  nareas = Vect_get_num_areas(Map);
188  }
189 
190  if (removed_area)
191  *removed_area = size_removed;
192 
193  G_message(_("%d areas of total size %g removed"), nremoved, size_removed);
194  Vect_destroy_list(AList);
195  Vect_destroy_list(List);
196  Vect_destroy_line_struct(Points);
198 
199  return (nremoved);
200 }
201 
202 /* much faster version */
203 int Vect_remove_small_areas_nat(struct Map_info *Map, double thresh,
204  struct Map_info *Err, double *removed_area)
205 {
206  int area, nareas;
207  int nremoved = 0;
208  struct ilist *List;
209  struct ilist *AList;
210  struct ilist *BList;
211  struct ilist *NList;
212  struct ilist *IList;
213  struct line_pnts *Points;
214  struct line_cats *Cats;
215  double size_removed = 0.0;
216  int dissolve_neighbour;
217  int line, left, right, neighbour;
218  int nisles, nnisles;
219 
220  List = Vect_new_list();
221  AList = Vect_new_list();
222  BList = Vect_new_list();
223  NList = Vect_new_list();
224  IList = Vect_new_list();
225  Points = Vect_new_line_struct();
226  Cats = Vect_new_cats_struct();
227 
228  nareas = Vect_get_num_areas(Map);
229  for (area = 1; area <= nareas; area++) {
230  int i, j, centroid, ncentroid;
231  double length, l, size;
232  int outer_area = -1;
233  int narea, same_atype = 0;
234 
235  G_percent(area, nareas, 1);
236  G_debug(3, "area = %d", area);
237  if (!Vect_area_alive(Map, area))
238  continue;
239 
240  size = Vect_get_area_area(Map, area);
241  if (size > thresh)
242  continue;
243  size_removed += size;
244 
245  /* The area is smaller than the limit -> remove */
246 
247  /* Remove centroid */
248  centroid = Vect_get_area_centroid(Map, area);
249  if (centroid > 0) {
250  if (Err) {
251  Vect_read_line(Map, Points, Cats, centroid);
252  Vect_write_line(Err, GV_CENTROID, Points, Cats);
253  }
254  Vect_delete_line(Map, centroid);
255  }
256 
257  /* Find the adjacent area with which the longest boundary is shared */
258 
259  Vect_get_area_boundaries(Map, area, List);
260 
261  /* Create a list of neighbour areas */
262  Vect_reset_list(AList);
263  for (i = 0; i < List->n_values; i++) {
264 
265  line = List->value[i];
266 
267  if (!Vect_line_alive(Map, abs(line))) /* Should not happen */
268  G_fatal_error(_("Area is composed of dead boundary"));
269 
270  Vect_get_line_areas(Map, abs(line), &left, &right);
271  if (line > 0)
272  neighbour = left;
273  else
274  neighbour = right;
275 
276  G_debug(4, " line = %d left = %d right = %d neighbour = %d", line,
277  left, right, neighbour);
278 
279  ncentroid = 0;
280  if (neighbour > 0) {
281  ncentroid = Vect_get_area_centroid(Map, neighbour);
282  }
283  if (neighbour < 0) {
284  narea = Vect_get_isle_area(Map, -neighbour);
285  if (narea > 0)
286  ncentroid = Vect_get_area_centroid(Map, narea);
287  }
288  if ((centroid != 0) + (ncentroid != 0) != 1)
289  same_atype = 1;
290 
291  Vect_list_append(AList, neighbour); /* this checks for duplicity */
292  }
293  G_debug(3, "num neighbours = %d", AList->n_values);
294 
295  if (AList->n_values == 1)
296  same_atype = 0;
297 
298  /* Go through the list of neighbours and find the one with the longest
299  * boundary */
300  dissolve_neighbour = 0;
301  length = -1.0;
302  for (i = 0; i < AList->n_values; i++) {
303  int neighbour1;
304 
305  l = 0.0;
306  neighbour1 = AList->value[i];
307  G_debug(4, " neighbour1 = %d", neighbour1);
308 
309  if (same_atype) {
310  ncentroid = 0;
311  if (neighbour1 > 0) {
312  ncentroid = Vect_get_area_centroid(Map, neighbour1);
313  }
314  if (neighbour1 < 0) {
315  narea = Vect_get_isle_area(Map, -neighbour1);
316  if (narea > 0)
317  ncentroid = Vect_get_area_centroid(Map, narea);
318  }
319  if ((centroid != 0) + (ncentroid != 0) == 1)
320  continue;
321  }
322 
323  for (j = 0; j < List->n_values; j++) {
324  int neighbour2;
325 
326  line = List->value[j];
327  Vect_get_line_areas(Map, abs(line), &left, &right);
328  if (line > 0)
329  neighbour2 = left;
330  else
331  neighbour2 = right;
332 
333  if (neighbour2 == neighbour1) {
334  Vect_read_line(Map, Points, NULL, abs(line));
335  l += Vect_line_length(Points);
336  }
337  }
338  if (l > length) {
339  length = l;
340  dissolve_neighbour = neighbour1;
341  }
342  }
343 
344  G_debug(3, "dissolve_neighbour = %d", dissolve_neighbour);
345 
346  if (dissolve_neighbour == 0) {
347  G_fatal_error("could not find neighbour to dissolve");
348  }
349 
350  /* Make list of boundaries to be removed */
351  Vect_reset_list(AList);
352  Vect_reset_list(BList);
353  for (i = 0; i < List->n_values; i++) {
354 
355  line = List->value[i];
356  Vect_get_line_areas(Map, abs(line), &left, &right);
357  if (line > 0)
358  neighbour = left;
359  else
360  neighbour = right;
361 
362  G_debug(3, " neighbour = %d", neighbour);
363 
364  if (neighbour == dissolve_neighbour) {
365  Vect_list_append(AList, abs(line));
366  }
367  else
368  Vect_list_append(BList, line);
369  }
370  G_debug(3, "remove %d of %d boundaries", AList->n_values,
371  List->n_values);
372 
373  /* Get isles inside area */
374  Vect_reset_list(IList);
375  if ((nisles = Vect_get_area_num_isles(Map, area)) > 0) {
376  for (i = 0; i < nisles; i++) {
377  Vect_list_append(IList, Vect_get_area_isle(Map, area, i));
378  }
379  }
380 
381  /* Remove boundaries */
382  for (i = 0; i < AList->n_values; i++) {
383  int ret;
384 
385  line = AList->value[i];
386 
387  if (Err) {
388  Vect_read_line(Map, Points, Cats, line);
389  Vect_write_line(Err, GV_BOUNDARY, Points, Cats);
390  }
391  /* Vect_delete_line(Map, line); */
392 
393  /* delete the line from coor */
394  ret = V1_delete_line_nat(Map, Map->plus.Line[line]->offset);
395 
396  if (ret == -1) {
397  G_fatal_error(_("Could not delete line from coor"));
398  }
399  }
400 
401  /* update topo */
402  if (dissolve_neighbour > 0) {
403 
404  G_debug(3, "dissolve with neighbour area");
405 
406  /* get neighbour centroid */
407  centroid = Vect_get_area_centroid(Map, dissolve_neighbour);
408  /* get neighbour isles */
409  if ((nnisles = Vect_get_area_num_isles(Map, dissolve_neighbour)) >
410  0) {
411  for (i = 0; i < nnisles; i++) {
413  IList, Vect_get_area_isle(Map, dissolve_neighbour, i));
414  }
415  }
416 
417  /* get neighbour boundaries */
418  Vect_get_area_boundaries(Map, dissolve_neighbour, NList);
419 
420  /* delete area from topo */
421  dig_del_area(&(Map->plus), area);
422  /* delete neighbour area from topo */
423  dig_del_area(&(Map->plus), dissolve_neighbour);
424  /* delete boundaries from topo */
425  for (i = 0; i < AList->n_values; i++) {
426  struct P_topo_b *topo;
427  struct P_node *Node;
428 
429  line = AList->value[i];
430  topo = (struct P_topo_b *)Map->plus.Line[line]->topo;
431  Node = Map->plus.Node[topo->N1];
432  dig_del_line(&(Map->plus), line, Node->x, Node->y, Node->z);
433  }
434  /* build new area from leftover boundaries of deleted area */
435  for (i = 0; i < BList->n_values; i++) {
436  struct P_topo_b *topo;
437  int new_isle;
438 
439  line = BList->value[i];
440  topo = Map->plus.Line[abs(line)]->topo;
441 
442  if (topo->left == 0 || topo->right == 0) {
443  new_isle = Vect_build_line_area(
444  Map, abs(line), (line > 0 ? GV_RIGHT : GV_LEFT));
445  if (new_isle > 0) {
446  if (outer_area > 0)
447  G_fatal_error("dissolve_neighbour > 0, new area "
448  "has already been created");
449  outer_area = new_isle;
450  /* reattach centroid */
451  Map->plus.Area[outer_area]->centroid = centroid;
452  if (centroid > 0) {
453  struct P_topo_c *ctopo =
454  Map->plus.Line[centroid]->topo;
455 
456  ctopo->area = outer_area;
457  }
458  }
459  else if (new_isle < 0) {
460  /* leftover boundary creates a new isle */
461  Vect_list_append(IList, -new_isle);
462  }
463  else {
464  /* neither area nor isle, should not happen */
465  G_fatal_error(_("dissolve_neighbour > 0, failed to "
466  "build new area"));
467  }
468  }
469  /* check */
470  if (topo->left == 0 || topo->right == 0)
472  _("Dissolve with neighbour area: corrupt topology"));
473  }
474  /* build new area from neighbour's boundaries */
475  for (i = 0; i < NList->n_values; i++) {
476  struct P_topo_b *topo;
477 
478  line = NList->value[i];
479  if (!Vect_line_alive(Map, abs(line)))
480  continue;
481 
482  topo = Map->plus.Line[abs(line)]->topo;
483 
484  if (topo->left == 0 || topo->right == 0) {
485  int new_isle;
486 
487  new_isle = Vect_build_line_area(
488  Map, abs(line), (line > 0 ? GV_RIGHT : GV_LEFT));
489  if (new_isle > 0) {
490  if (outer_area > 0)
491  G_fatal_error("dissolve_neighbour > 0, new area "
492  "has already been created");
493  outer_area = new_isle;
494  /* reattach centroid */
495  Map->plus.Area[outer_area]->centroid = centroid;
496  if (centroid > 0) {
497  struct P_topo_c *ctopo =
498  Map->plus.Line[centroid]->topo;
499 
500  ctopo->area = outer_area;
501  }
502  }
503  else if (new_isle < 0) {
504  /* Neigbour's boundary creates a new isle */
505  Vect_list_append(IList, -new_isle);
506  }
507  else {
508  /* neither area nor isle, should not happen */
509  G_fatal_error(_("Failed to build new area"));
510  }
511  }
512  if (topo->left == 0 || topo->right == 0)
514  _("Dissolve with neighbour area: corrupt topology"));
515  }
516  }
517  /* dissolve with outer isle */
518  else if (dissolve_neighbour < 0) {
519 
520  G_debug(3, "dissolve with outer isle");
521 
522  outer_area = Vect_get_isle_area(Map, -dissolve_neighbour);
523 
524  /* get isle boundaries */
525  Vect_get_isle_boundaries(Map, -dissolve_neighbour, NList);
526 
527  /* delete area from topo */
528  dig_del_area(&(Map->plus), area);
529  /* delete isle from topo */
530  dig_del_isle(&(Map->plus), -dissolve_neighbour);
531  /* delete boundaries from topo */
532  for (i = 0; i < AList->n_values; i++) {
533  struct P_topo_b *topo;
534  struct P_node *Node;
535 
536  line = AList->value[i];
537  topo = (struct P_topo_b *)Map->plus.Line[line]->topo;
538  Node = Map->plus.Node[topo->N1];
539  dig_del_line(&(Map->plus), line, Node->x, Node->y, Node->z);
540  }
541  /* build new isle(s) from leftover boundaries */
542  for (i = 0; i < BList->n_values; i++) {
543  struct P_topo_b *topo;
544 
545  line = BList->value[i];
546  topo = Map->plus.Line[abs(line)]->topo;
547 
548  if (topo->left == 0 || topo->right == 0) {
549  int new_isle;
550 
551  new_isle = Vect_build_line_area(
552  Map, abs(line), (line > 0 ? GV_RIGHT : GV_LEFT));
553  if (new_isle < 0) {
554  Vect_list_append(IList, -new_isle);
555  }
556  else {
557  /* area or nothing should not happen */
558  G_fatal_error(_("Failed to build new isle"));
559  }
560  }
561  /* check */
562  if (topo->left == 0 || topo->right == 0)
564  _("Dissolve with outer isle: corrupt topology"));
565  }
566 
567  /* build new isle(s) from old isle's boundaries */
568  for (i = 0; i < NList->n_values; i++) {
569  struct P_topo_b *topo;
570 
571  line = NList->value[i];
572  if (!Vect_line_alive(Map, abs(line)))
573  continue;
574 
575  topo = Map->plus.Line[abs(line)]->topo;
576 
577  if (topo->left == 0 || topo->right == 0) {
578  int new_isle;
579 
580  new_isle = Vect_build_line_area(
581  Map, abs(line), (line > 0 ? GV_RIGHT : GV_LEFT));
582  if (new_isle < 0) {
583  Vect_list_append(IList, -new_isle);
584  }
585  else {
586  /* area or nothing should not happen */
587  G_fatal_error(_("Failed to build new isle"));
588  }
589  }
590  /* check */
591  if (topo->left == 0 || topo->right == 0)
593  _("Dissolve with outer isle: corrupt topology"));
594  }
595  }
596 
597  if (dissolve_neighbour > 0 && outer_area <= 0) {
598  G_fatal_error(_("Area merging failed"));
599  }
600 
601  /* attach all isles to outer or new area */
602  if (outer_area >= 0) {
603  for (i = 0; i < IList->n_values; i++) {
604  if (!Map->plus.Isle[IList->value[i]])
605  continue;
606  Map->plus.Isle[IList->value[i]]->area = outer_area;
607  if (outer_area > 0)
608  dig_area_add_isle(&(Map->plus), outer_area,
609  IList->value[i]);
610  }
611  }
612 
613  nremoved++;
614  nareas = Vect_get_num_areas(Map);
615  }
616 
617  if (removed_area)
618  *removed_area = size_removed;
619 
620  G_message(_("%d areas of total size %g removed"), nremoved, size_removed);
621 
622  Vect_destroy_list(List);
623  Vect_destroy_list(AList);
624  Vect_destroy_list(BList);
625  Vect_destroy_list(NList);
626  Vect_destroy_list(IList);
627  Vect_destroy_line_struct(Points);
629 
630  return (nremoved);
631 }
#define NULL
Definition: ccmath.h:32
void G_percent(long, long, int)
Print percent complete messages.
Definition: percent.c:61
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_message(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
Definition: line.c:77
double Vect_line_length(const struct line_pnts *)
Calculate line length, 3D-length in case of 3D vector line.
Definition: line.c:575
plus_t Vect_get_num_areas(struct Map_info *)
Get number of areas in vector map.
Definition: level_two.c:87
int Vect_area_alive(struct Map_info *, int)
Check if area is alive or dead (topological level required)
int Vect_build_line_area(struct Map_info *, int, int)
Build area on given side of line (GV_LEFT or GV_RIGHT)
Definition: build.c:79
int Vect_get_area_boundaries(struct Map_info *, int, struct ilist *)
Creates list of boundaries for given area.
void Vect_destroy_list(struct ilist *)
Frees all memory associated with a struct ilist, including the struct itself.
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_list_append(struct ilist *, int)
Append new item to the end of list if not yet present.
int Vect_get_area_isle(struct Map_info *, int, int)
Returns isle id for area.
int Vect_read_line(struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
int Vect_get_area_num_isles(struct Map_info *, int)
Returns number of isles for given area.
int Vect_line_alive(struct Map_info *, int)
Check if feature is alive or dead (topological level required)
int Vect_get_isle_boundaries(struct Map_info *, int, struct ilist *)
Creates list of boundaries for given isle.
int Vect_delete_line(struct Map_info *, off_t)
Delete existing feature (topological level required)
off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes a new feature.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition: line.c:45
int Vect_get_area_centroid(struct Map_info *, int)
Returns centroid id for given area.
double Vect_get_area_area(struct Map_info *, int)
Returns area of area without areas of isles.
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
int V1_delete_line_nat(struct Map_info *, off_t)
Deletes feature at level 1 (internal use only)
Definition: write_nat.c:248
int Vect_get_line_areas(struct Map_info *, int, int *, int *)
Get area id on the left and right side of the boundary.
Definition: level_two.c:347
int Vect_reset_list(struct ilist *)
Reset ilist structure.
int Vect_get_isle_area(struct Map_info *, int)
Returns area id for isle.
#define GV_CENTROID
Definition: dig_defines.h:186
#define GV_BOUNDARY
Definition: dig_defines.h:185
#define GV_RIGHT
Definition: dig_defines.h:176
#define GV_LEFT
Boundary side indicator left/right.
Definition: dig_defines.h:175
#define GV_FORMAT_NATIVE
Geometry data formats supported by lib Don't change GV_FORMAT_* values, this order is hardcoded in li...
Definition: dig_defines.h:83
int dig_area_add_isle(struct Plus_head *, int, int)
Add isle to area if does not exist yet.
Definition: plus_area.c:265
int dig_del_line(struct Plus_head *, int, double, double, double)
Delete line from Plus_head structure.
Definition: plus_line.c:217
int dig_del_area(struct Plus_head *, int)
Delete area from Plus_head structure.
Definition: plus_area.c:365
int dig_del_isle(struct Plus_head *, int)
Delete island from Plus_head structure.
Definition: plus_area.c:781
#define _(str)
Definition: glocale.h:10
double l
Definition: r_raster.c:39
int Vect_remove_small_areas_nat(struct Map_info *, double, struct Map_info *, double *)
Definition: remove_areas.c:203
int Vect_remove_small_areas_ext(struct Map_info *, double, struct Map_info *, double *)
Definition: remove_areas.c:50
int Vect_remove_small_areas(struct Map_info *Map, double thresh, struct Map_info *Err, double *removed_area)
Remove small areas from the map map.
Definition: remove_areas.c:40
Vector map info.
Definition: dig_structs.h:1243
int format
Map format (native, ogr, postgis)
Definition: dig_structs.h:1255
struct Plus_head plus
Plus info (topology, version, ...)
Definition: dig_structs.h:1270
plus_t centroid
Number of first centroid within area.
Definition: dig_structs.h:1605
plus_t area
Area it exists w/in, if any.
Definition: dig_structs.h:1645
off_t offset
Offset in coor file for line.
Definition: dig_structs.h:1571
void * topo
Topology info.
Definition: dig_structs.h:1577
Topological feature - node.
Definition: dig_structs.h:1433
double x
X coordinate.
Definition: dig_structs.h:1437
double z
Z coordinate (used only for 3D data)
Definition: dig_structs.h:1445
double y
Y coordinate.
Definition: dig_structs.h:1441
Boundary topology.
Definition: dig_structs.h:1492
plus_t left
Area number to the left, negative for isle.
Definition: dig_structs.h:1504
plus_t N1
Start node.
Definition: dig_structs.h:1496
plus_t right
Area number to the right, negative for isle.
Definition: dig_structs.h:1508
Centroid topology.
Definition: dig_structs.h:1514
plus_t area
Area number, negative for duplicate centroid.
Definition: dig_structs.h:1518
struct P_line ** Line
Array of vector geometries.
Definition: dig_structs.h:871
struct P_area ** Area
Array of areas.
Definition: dig_structs.h:875
struct P_isle ** Isle
Array of isles.
Definition: dig_structs.h:879
struct P_node ** Node
Array of nodes.
Definition: dig_structs.h:867
List of integers.
Definition: gis.h:715
int n_values
Number of values in the list.
Definition: gis.h:723
int * value
Array of values.
Definition: gis.h:719
Feature category info.
Definition: dig_structs.h:1677
Feature geometry info - coordinates.
Definition: dig_structs.h:1651