GRASS GIS 8 Programmer's Manual  8.5.0dev(2025)-f22b1278f8
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 
41 int Vect_remove_small_areas(struct Map_info *Map, double thresh,
42  struct Map_info *Err, double *removed_area)
43 {
44 
45  if (Map->format == GV_FORMAT_NATIVE)
46  return Vect_remove_small_areas_nat(Map, thresh, Err, removed_area);
47  else
48  return Vect_remove_small_areas_ext(Map, thresh, Err, removed_area);
49 }
50 
51 int Vect_remove_small_areas_ext(struct Map_info *Map, double thresh,
52  struct Map_info *Err, double *removed_area)
53 {
54  int area, nareas;
55  int nremoved = 0;
56  struct ilist *List;
57  struct ilist *AList;
58  struct line_pnts *Points;
59  struct line_cats *Cats;
60  double size_removed = 0.0;
61 
62  List = Vect_new_list();
63  AList = Vect_new_list();
64  Points = Vect_new_line_struct();
65  Cats = Vect_new_cats_struct();
66 
67  nareas = Vect_get_num_areas(Map);
68  for (area = 1; area <= nareas; area++) {
69  int i, j, centroid, dissolve_neighbour;
70  double length, size;
71 
72  G_percent(area, nareas, 1);
73  G_debug(3, "area = %d", area);
74  if (!Vect_area_alive(Map, area))
75  continue;
76 
77  size = Vect_get_area_area(Map, area);
78  if (size > thresh)
79  continue;
80  size_removed += size;
81 
82  /* The area is smaller than the limit -> remove */
83 
84  /* Remove centroid */
85  centroid = Vect_get_area_centroid(Map, area);
86  if (centroid > 0) {
87  if (Err) {
88  Vect_read_line(Map, Points, Cats, centroid);
89  Vect_write_line(Err, GV_CENTROID, Points, Cats);
90  }
91  Vect_delete_line(Map, centroid);
92  }
93 
94  /* Find the adjacent area with which the longest boundary is shared */
95 
96  Vect_get_area_boundaries(Map, area, List);
97 
98  /* Create a list of neighbour areas */
99  Vect_reset_list(AList);
100  for (i = 0; i < List->n_values; i++) {
101  int line, left, right, neighbour;
102 
103  line = List->value[i];
104 
105  if (!Vect_line_alive(Map, abs(line))) /* Should not happen */
106  G_fatal_error(_("Area is composed of dead boundary"));
107 
108  Vect_get_line_areas(Map, abs(line), &left, &right);
109  if (line > 0)
110  neighbour = left;
111  else
112  neighbour = right;
113 
114  G_debug(4, " line = %d left = %d right = %d neighbour = %d", line,
115  left, right, neighbour);
116 
117  Vect_list_append(AList, neighbour); /* this checks for duplicity */
118  }
119  G_debug(3, "num neighbours = %d", AList->n_values);
120 
121  /* Go through the list of neighbours and find that with the longest
122  * boundary */
123  dissolve_neighbour = 0;
124  length = -1.0;
125  for (i = 0; i < AList->n_values; i++) {
126  int neighbour1;
127  double l = 0.0;
128 
129  neighbour1 = AList->value[i];
130  G_debug(4, " neighbour1 = %d", neighbour1);
131 
132  for (j = 0; j < List->n_values; j++) {
133  int line, left, right, neighbour2;
134 
135  line = List->value[j];
136  Vect_get_line_areas(Map, abs(line), &left, &right);
137  if (line > 0)
138  neighbour2 = left;
139  else
140  neighbour2 = right;
141 
142  if (neighbour2 == neighbour1) {
143  Vect_read_line(Map, Points, NULL, abs(line));
144  l += Vect_line_length(Points);
145  }
146  }
147  if (l > length) {
148  length = l;
149  dissolve_neighbour = neighbour1;
150  }
151  }
152 
153  G_debug(3, "dissolve_neighbour = %d", dissolve_neighbour);
154 
155  /* Make list of boundaries to be removed */
156  Vect_reset_list(AList);
157  for (i = 0; i < List->n_values; i++) {
158  int line, left, right, neighbour;
159 
160  line = List->value[i];
161  Vect_get_line_areas(Map, abs(line), &left, &right);
162  if (line > 0)
163  neighbour = left;
164  else
165  neighbour = right;
166 
167  G_debug(3, " neighbour = %d", neighbour);
168 
169  if (neighbour == dissolve_neighbour) {
170  Vect_list_append(AList, abs(line));
171  }
172  }
173 
174  /* Remove boundaries */
175  for (i = 0; i < AList->n_values; i++) {
176  int line;
177 
178  line = AList->value[i];
179 
180  if (Err) {
181  Vect_read_line(Map, Points, Cats, line);
182  Vect_write_line(Err, GV_BOUNDARY, Points, Cats);
183  }
184  Vect_delete_line(Map, line);
185  }
186 
187  nremoved++;
188  nareas = Vect_get_num_areas(Map);
189  }
190 
191  if (removed_area)
192  *removed_area = size_removed;
193 
194  G_message(_("%d areas of total size %g removed"), nremoved, size_removed);
195  Vect_destroy_list(AList);
196  Vect_destroy_list(List);
197  Vect_destroy_line_struct(Points);
199 
200  return (nremoved);
201 }
202 
203 /* much faster version */
204 int Vect_remove_small_areas_nat(struct Map_info *Map, double thresh,
205  struct Map_info *Err, double *removed_area)
206 {
207  int area, nareas;
208  int nremoved = 0;
209  struct ilist *List;
210  struct ilist *AList;
211  struct ilist *BList;
212  struct ilist *NList;
213  struct ilist *IList;
214  struct line_pnts *Points;
215  struct line_cats *Cats;
216  double size_removed = 0.0;
217  int dissolve_neighbour;
218  int line, left, right, neighbour;
219  int nisles, nnisles;
220 
221  List = Vect_new_list();
222  AList = Vect_new_list();
223  BList = Vect_new_list();
224  NList = Vect_new_list();
225  IList = Vect_new_list();
226  Points = Vect_new_line_struct();
227  Cats = Vect_new_cats_struct();
228 
229  nareas = Vect_get_num_areas(Map);
230  for (area = 1; area <= nareas; area++) {
231  int i, j, centroid, ncentroid;
232  double length, l, size;
233  int outer_area = -1;
234  int narea, same_atype = 0;
235 
236  G_percent(area, nareas, 1);
237  G_debug(3, "area = %d", area);
238  if (!Vect_area_alive(Map, area))
239  continue;
240 
241  size = Vect_get_area_area(Map, area);
242  if (size > thresh)
243  continue;
244  size_removed += size;
245 
246  /* The area is smaller than the limit -> remove */
247 
248  /* Remove centroid */
249  centroid = Vect_get_area_centroid(Map, area);
250  if (centroid > 0) {
251  if (Err) {
252  Vect_read_line(Map, Points, Cats, centroid);
253  Vect_write_line(Err, GV_CENTROID, Points, Cats);
254  }
255  Vect_delete_line(Map, centroid);
256  }
257 
258  /* Find the adjacent area with which the longest boundary is shared */
259 
260  Vect_get_area_boundaries(Map, area, List);
261 
262  /* Create a list of neighbour areas */
263  Vect_reset_list(AList);
264  for (i = 0; i < List->n_values; i++) {
265 
266  line = List->value[i];
267 
268  if (!Vect_line_alive(Map, abs(line))) /* Should not happen */
269  G_fatal_error(_("Area is composed of dead boundary"));
270 
271  Vect_get_line_areas(Map, abs(line), &left, &right);
272  if (line > 0)
273  neighbour = left;
274  else
275  neighbour = right;
276 
277  G_debug(4, " line = %d left = %d right = %d neighbour = %d", line,
278  left, right, neighbour);
279 
280  ncentroid = 0;
281  if (neighbour > 0) {
282  ncentroid = Vect_get_area_centroid(Map, neighbour);
283  }
284  if (neighbour < 0) {
285  narea = Vect_get_isle_area(Map, -neighbour);
286  if (narea > 0)
287  ncentroid = Vect_get_area_centroid(Map, narea);
288  }
289  if ((centroid != 0) + (ncentroid != 0) != 1)
290  same_atype = 1;
291 
292  Vect_list_append(AList, neighbour); /* this checks for duplicity */
293  }
294  G_debug(3, "num neighbours = %d", AList->n_values);
295 
296  if (AList->n_values == 1)
297  same_atype = 0;
298 
299  /* Go through the list of neighbours and find the one with the longest
300  * boundary */
301  dissolve_neighbour = 0;
302  length = -1.0;
303  for (i = 0; i < AList->n_values; i++) {
304  int neighbour1;
305 
306  l = 0.0;
307  neighbour1 = AList->value[i];
308  G_debug(4, " neighbour1 = %d", neighbour1);
309 
310  if (same_atype) {
311  ncentroid = 0;
312  if (neighbour1 > 0) {
313  ncentroid = Vect_get_area_centroid(Map, neighbour1);
314  }
315  if (neighbour1 < 0) {
316  narea = Vect_get_isle_area(Map, -neighbour1);
317  if (narea > 0)
318  ncentroid = Vect_get_area_centroid(Map, narea);
319  }
320  if ((centroid != 0) + (ncentroid != 0) == 1)
321  continue;
322  }
323 
324  for (j = 0; j < List->n_values; j++) {
325  int neighbour2;
326 
327  line = List->value[j];
328  Vect_get_line_areas(Map, abs(line), &left, &right);
329  if (line > 0)
330  neighbour2 = left;
331  else
332  neighbour2 = right;
333 
334  if (neighbour2 == neighbour1) {
335  Vect_read_line(Map, Points, NULL, abs(line));
336  l += Vect_line_length(Points);
337  }
338  }
339  if (l > length) {
340  length = l;
341  dissolve_neighbour = neighbour1;
342  }
343  }
344 
345  G_debug(3, "dissolve_neighbour = %d", dissolve_neighbour);
346 
347  if (dissolve_neighbour == 0) {
348  G_fatal_error("could not find neighbour to dissolve");
349  }
350 
351  /* Make list of boundaries to be removed */
352  Vect_reset_list(AList);
353  Vect_reset_list(BList);
354  for (i = 0; i < List->n_values; i++) {
355 
356  line = List->value[i];
357  Vect_get_line_areas(Map, abs(line), &left, &right);
358  if (line > 0)
359  neighbour = left;
360  else
361  neighbour = right;
362 
363  G_debug(3, " neighbour = %d", neighbour);
364 
365  if (neighbour == dissolve_neighbour) {
366  Vect_list_append(AList, abs(line));
367  }
368  else
369  Vect_list_append(BList, line);
370  }
371  G_debug(3, "remove %d of %d boundaries", AList->n_values,
372  List->n_values);
373 
374  /* Get isles inside area */
375  Vect_reset_list(IList);
376  if ((nisles = Vect_get_area_num_isles(Map, area)) > 0) {
377  for (i = 0; i < nisles; i++) {
378  Vect_list_append(IList, Vect_get_area_isle(Map, area, i));
379  }
380  }
381 
382  /* Remove boundaries */
383  for (i = 0; i < AList->n_values; i++) {
384  int ret;
385 
386  line = AList->value[i];
387 
388  if (Err) {
389  Vect_read_line(Map, Points, Cats, line);
390  Vect_write_line(Err, GV_BOUNDARY, Points, Cats);
391  }
392  /* Vect_delete_line(Map, line); */
393 
394  /* delete the line from coor */
395  ret = V1_delete_line_nat(Map, Map->plus.Line[line]->offset);
396 
397  if (ret == -1) {
398  G_fatal_error(_("Could not delete line from coor"));
399  }
400  }
401 
402  /* update topo */
403  if (dissolve_neighbour > 0) {
404 
405  G_debug(3, "dissolve with neighbour area");
406 
407  /* get neighbour centroid */
408  centroid = Vect_get_area_centroid(Map, dissolve_neighbour);
409  /* get neighbour isles */
410  if ((nnisles = Vect_get_area_num_isles(Map, dissolve_neighbour)) >
411  0) {
412  for (i = 0; i < nnisles; i++) {
414  IList, Vect_get_area_isle(Map, dissolve_neighbour, i));
415  }
416  }
417 
418  /* get neighbour boundaries */
419  Vect_get_area_boundaries(Map, dissolve_neighbour, NList);
420 
421  /* delete area from topo */
422  dig_del_area(&(Map->plus), area);
423  /* delete neighbour area from topo */
424  dig_del_area(&(Map->plus), dissolve_neighbour);
425  /* delete boundaries from topo */
426  for (i = 0; i < AList->n_values; i++) {
427  struct P_topo_b *topo;
428  struct P_node *Node;
429 
430  line = AList->value[i];
431  topo = (struct P_topo_b *)Map->plus.Line[line]->topo;
432  Node = Map->plus.Node[topo->N1];
433  dig_del_line(&(Map->plus), line, Node->x, Node->y, Node->z);
434  }
435  /* build new area from leftover boundaries of deleted area */
436  for (i = 0; i < BList->n_values; i++) {
437  struct P_topo_b *topo;
438  int new_isle;
439 
440  line = BList->value[i];
441  topo = Map->plus.Line[abs(line)]->topo;
442 
443  if (topo->left == 0 || topo->right == 0) {
444  new_isle = Vect_build_line_area(
445  Map, abs(line), (line > 0 ? GV_RIGHT : GV_LEFT));
446  if (new_isle > 0) {
447  if (outer_area > 0)
448  G_fatal_error("dissolve_neighbour > 0, new area "
449  "has already been created");
450  outer_area = new_isle;
451  /* reattach centroid */
452  Map->plus.Area[outer_area]->centroid = centroid;
453  if (centroid > 0) {
454  struct P_topo_c *ctopo =
455  Map->plus.Line[centroid]->topo;
456 
457  ctopo->area = outer_area;
458  }
459  }
460  else if (new_isle < 0) {
461  /* leftover boundary creates a new isle */
462  Vect_list_append(IList, -new_isle);
463  }
464  else {
465  /* neither area nor isle, should not happen */
466  G_fatal_error(_("dissolve_neighbour > 0, failed to "
467  "build new area"));
468  }
469  }
470  /* check */
471  if (topo->left == 0 || topo->right == 0)
473  _("Dissolve with neighbour area: corrupt topology"));
474  }
475  /* build new area from neighbour's boundaries */
476  for (i = 0; i < NList->n_values; i++) {
477  struct P_topo_b *topo;
478 
479  line = NList->value[i];
480  if (!Vect_line_alive(Map, abs(line)))
481  continue;
482 
483  topo = Map->plus.Line[abs(line)]->topo;
484 
485  if (topo->left == 0 || topo->right == 0) {
486  int new_isle;
487 
488  new_isle = Vect_build_line_area(
489  Map, abs(line), (line > 0 ? GV_RIGHT : GV_LEFT));
490  if (new_isle > 0) {
491  if (outer_area > 0)
492  G_fatal_error("dissolve_neighbour > 0, new area "
493  "has already been created");
494  outer_area = new_isle;
495  /* reattach centroid */
496  Map->plus.Area[outer_area]->centroid = centroid;
497  if (centroid > 0) {
498  struct P_topo_c *ctopo =
499  Map->plus.Line[centroid]->topo;
500 
501  ctopo->area = outer_area;
502  }
503  }
504  else if (new_isle < 0) {
505  /* Neigbour's boundary creates a new isle */
506  Vect_list_append(IList, -new_isle);
507  }
508  else {
509  /* neither area nor isle, should not happen */
510  G_fatal_error(_("Failed to build new area"));
511  }
512  }
513  if (topo->left == 0 || topo->right == 0)
515  _("Dissolve with neighbour area: corrupt topology"));
516  }
517  }
518  /* dissolve with outer isle */
519  else if (dissolve_neighbour < 0) {
520 
521  G_debug(3, "dissolve with outer isle");
522 
523  outer_area = Vect_get_isle_area(Map, -dissolve_neighbour);
524 
525  /* get isle boundaries */
526  Vect_get_isle_boundaries(Map, -dissolve_neighbour, NList);
527 
528  /* delete area from topo */
529  dig_del_area(&(Map->plus), area);
530  /* delete isle from topo */
531  dig_del_isle(&(Map->plus), -dissolve_neighbour);
532  /* delete boundaries from topo */
533  for (i = 0; i < AList->n_values; i++) {
534  struct P_topo_b *topo;
535  struct P_node *Node;
536 
537  line = AList->value[i];
538  topo = (struct P_topo_b *)Map->plus.Line[line]->topo;
539  Node = Map->plus.Node[topo->N1];
540  dig_del_line(&(Map->plus), line, Node->x, Node->y, Node->z);
541  }
542  /* build new isle(s) from leftover boundaries */
543  for (i = 0; i < BList->n_values; i++) {
544  struct P_topo_b *topo;
545 
546  line = BList->value[i];
547  topo = Map->plus.Line[abs(line)]->topo;
548 
549  if (topo->left == 0 || topo->right == 0) {
550  int new_isle;
551 
552  new_isle = Vect_build_line_area(
553  Map, abs(line), (line > 0 ? GV_RIGHT : GV_LEFT));
554  if (new_isle < 0) {
555  Vect_list_append(IList, -new_isle);
556  }
557  else {
558  /* area or nothing should not happen */
559  G_fatal_error(_("Failed to build new isle"));
560  }
561  }
562  /* check */
563  if (topo->left == 0 || topo->right == 0)
565  _("Dissolve with outer isle: corrupt topology"));
566  }
567 
568  /* build new isle(s) from old isle's boundaries */
569  for (i = 0; i < NList->n_values; i++) {
570  struct P_topo_b *topo;
571 
572  line = NList->value[i];
573  if (!Vect_line_alive(Map, abs(line)))
574  continue;
575 
576  topo = Map->plus.Line[abs(line)]->topo;
577 
578  if (topo->left == 0 || topo->right == 0) {
579  int new_isle;
580 
581  new_isle = Vect_build_line_area(
582  Map, abs(line), (line > 0 ? GV_RIGHT : GV_LEFT));
583  if (new_isle < 0) {
584  Vect_list_append(IList, -new_isle);
585  }
586  else {
587  /* area or nothing should not happen */
588  G_fatal_error(_("Failed to build new isle"));
589  }
590  }
591  /* check */
592  if (topo->left == 0 || topo->right == 0)
594  _("Dissolve with outer isle: corrupt topology"));
595  }
596  }
597 
598  if (dissolve_neighbour > 0 && outer_area <= 0) {
599  G_fatal_error(_("Area merging failed"));
600  }
601 
602  /* attach all isles to outer or new area */
603  if (outer_area >= 0) {
604  for (i = 0; i < IList->n_values; i++) {
605  if (!Map->plus.Isle[IList->value[i]])
606  continue;
607  Map->plus.Isle[IList->value[i]]->area = outer_area;
608  if (outer_area > 0)
609  dig_area_add_isle(&(Map->plus), outer_area,
610  IList->value[i]);
611  }
612  }
613 
614  nremoved++;
615  nareas = Vect_get_num_areas(Map);
616  }
617 
618  if (removed_area)
619  *removed_area = size_removed;
620 
621  G_message(_("%d areas of total size %g removed"), nremoved, size_removed);
622 
623  Vect_destroy_list(List);
624  Vect_destroy_list(AList);
625  Vect_destroy_list(BList);
626  Vect_destroy_list(NList);
627  Vect_destroy_list(IList);
628  Vect_destroy_line_struct(Points);
630 
631  return (nremoved);
632 }
#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:346
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:216
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:204
int Vect_remove_small_areas_ext(struct Map_info *, double, struct Map_info *, double *)
Definition: remove_areas.c:51
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:41
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:709
int n_values
Number of values in the list.
Definition: gis.h:717
int * value
Array of values.
Definition: gis.h:713
Feature category info.
Definition: dig_structs.h:1677
Feature geometry info - coordinates.
Definition: dig_structs.h:1651