GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-d6dec75dd4
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 
196  return (nremoved);
197 }
198 
199 /* much faster version */
200 int Vect_remove_small_areas_nat(struct Map_info *Map, double thresh,
201  struct Map_info *Err, double *removed_area)
202 {
203  int area, nareas;
204  int nremoved = 0;
205  struct ilist *List;
206  struct ilist *AList;
207  struct ilist *BList;
208  struct ilist *NList;
209  struct ilist *IList;
210  struct line_pnts *Points;
211  struct line_cats *Cats;
212  double size_removed = 0.0;
213  int dissolve_neighbour;
214  int line, left, right, neighbour;
215  int nisles, nnisles;
216 
217  List = Vect_new_list();
218  AList = Vect_new_list();
219  BList = Vect_new_list();
220  NList = Vect_new_list();
221  IList = Vect_new_list();
222  Points = Vect_new_line_struct();
223  Cats = Vect_new_cats_struct();
224 
225  nareas = Vect_get_num_areas(Map);
226  for (area = 1; area <= nareas; area++) {
227  int i, j, centroid, ncentroid;
228  double length, l, size;
229  int outer_area = -1;
230  int narea, same_atype = 0;
231 
232  G_percent(area, nareas, 1);
233  G_debug(3, "area = %d", area);
234  if (!Vect_area_alive(Map, area))
235  continue;
236 
237  size = Vect_get_area_area(Map, area);
238  if (size > thresh)
239  continue;
240  size_removed += size;
241 
242  /* The area is smaller than the limit -> remove */
243 
244  /* Remove centroid */
245  centroid = Vect_get_area_centroid(Map, area);
246  if (centroid > 0) {
247  if (Err) {
248  Vect_read_line(Map, Points, Cats, centroid);
249  Vect_write_line(Err, GV_CENTROID, Points, Cats);
250  }
251  Vect_delete_line(Map, centroid);
252  }
253 
254  /* Find the adjacent area with which the longest boundary is shared */
255 
256  Vect_get_area_boundaries(Map, area, List);
257 
258  /* Create a list of neighbour areas */
259  Vect_reset_list(AList);
260  for (i = 0; i < List->n_values; i++) {
261 
262  line = List->value[i];
263 
264  if (!Vect_line_alive(Map, abs(line))) /* Should not happen */
265  G_fatal_error(_("Area is composed of dead boundary"));
266 
267  Vect_get_line_areas(Map, abs(line), &left, &right);
268  if (line > 0)
269  neighbour = left;
270  else
271  neighbour = right;
272 
273  G_debug(4, " line = %d left = %d right = %d neighbour = %d", line,
274  left, right, neighbour);
275 
276  ncentroid = 0;
277  if (neighbour > 0) {
278  ncentroid = Vect_get_area_centroid(Map, neighbour);
279  }
280  if (neighbour < 0) {
281  narea = Vect_get_isle_area(Map, -neighbour);
282  if (narea > 0)
283  ncentroid = Vect_get_area_centroid(Map, narea);
284  }
285  if ((centroid != 0) + (ncentroid != 0) != 1)
286  same_atype = 1;
287 
288  Vect_list_append(AList, neighbour); /* this checks for duplicity */
289  }
290  G_debug(3, "num neighbours = %d", AList->n_values);
291 
292  if (AList->n_values == 1)
293  same_atype = 0;
294 
295  /* Go through the list of neighbours and find the one with the longest
296  * boundary */
297  dissolve_neighbour = 0;
298  length = -1.0;
299  for (i = 0; i < AList->n_values; i++) {
300  int neighbour1;
301 
302  l = 0.0;
303  neighbour1 = AList->value[i];
304  G_debug(4, " neighbour1 = %d", neighbour1);
305 
306  if (same_atype) {
307  ncentroid = 0;
308  if (neighbour1 > 0) {
309  ncentroid = Vect_get_area_centroid(Map, neighbour1);
310  }
311  if (neighbour1 < 0) {
312  narea = Vect_get_isle_area(Map, -neighbour1);
313  if (narea > 0)
314  ncentroid = Vect_get_area_centroid(Map, narea);
315  }
316  if ((centroid != 0) + (ncentroid != 0) == 1)
317  continue;
318  }
319 
320  for (j = 0; j < List->n_values; j++) {
321  int neighbour2;
322 
323  line = List->value[j];
324  Vect_get_line_areas(Map, abs(line), &left, &right);
325  if (line > 0)
326  neighbour2 = left;
327  else
328  neighbour2 = right;
329 
330  if (neighbour2 == neighbour1) {
331  Vect_read_line(Map, Points, NULL, abs(line));
332  l += Vect_line_length(Points);
333  }
334  }
335  if (l > length) {
336  length = l;
337  dissolve_neighbour = neighbour1;
338  }
339  }
340 
341  G_debug(3, "dissolve_neighbour = %d", dissolve_neighbour);
342 
343  if (dissolve_neighbour == 0) {
344  G_fatal_error("could not find neighbour to dissolve");
345  }
346 
347  /* Make list of boundaries to be removed */
348  Vect_reset_list(AList);
349  Vect_reset_list(BList);
350  for (i = 0; i < List->n_values; i++) {
351 
352  line = List->value[i];
353  Vect_get_line_areas(Map, abs(line), &left, &right);
354  if (line > 0)
355  neighbour = left;
356  else
357  neighbour = right;
358 
359  G_debug(3, " neighbour = %d", neighbour);
360 
361  if (neighbour == dissolve_neighbour) {
362  Vect_list_append(AList, abs(line));
363  }
364  else
365  Vect_list_append(BList, line);
366  }
367  G_debug(3, "remove %d of %d boundaries", AList->n_values,
368  List->n_values);
369 
370  /* Get isles inside area */
371  Vect_reset_list(IList);
372  if ((nisles = Vect_get_area_num_isles(Map, area)) > 0) {
373  for (i = 0; i < nisles; i++) {
374  Vect_list_append(IList, Vect_get_area_isle(Map, area, i));
375  }
376  }
377 
378  /* Remove boundaries */
379  for (i = 0; i < AList->n_values; i++) {
380  int ret;
381 
382  line = AList->value[i];
383 
384  if (Err) {
385  Vect_read_line(Map, Points, Cats, line);
386  Vect_write_line(Err, GV_BOUNDARY, Points, Cats);
387  }
388  /* Vect_delete_line(Map, line); */
389 
390  /* delete the line from coor */
391  ret = V1_delete_line_nat(Map, Map->plus.Line[line]->offset);
392 
393  if (ret == -1) {
394  G_fatal_error(_("Could not delete line from coor"));
395  }
396  }
397 
398  /* update topo */
399  if (dissolve_neighbour > 0) {
400 
401  G_debug(3, "dissolve with neighbour area");
402 
403  /* get neighbour centroid */
404  centroid = Vect_get_area_centroid(Map, dissolve_neighbour);
405  /* get neighbour isles */
406  if ((nnisles = Vect_get_area_num_isles(Map, dissolve_neighbour)) >
407  0) {
408  for (i = 0; i < nnisles; i++) {
410  IList, Vect_get_area_isle(Map, dissolve_neighbour, i));
411  }
412  }
413 
414  /* get neighbour boundaries */
415  Vect_get_area_boundaries(Map, dissolve_neighbour, NList);
416 
417  /* delete area from topo */
418  dig_del_area(&(Map->plus), area);
419  /* delete neighbour area from topo */
420  dig_del_area(&(Map->plus), dissolve_neighbour);
421  /* delete boundaries from topo */
422  for (i = 0; i < AList->n_values; i++) {
423  struct P_topo_b *topo;
424  struct P_node *Node;
425 
426  line = AList->value[i];
427  topo = (struct P_topo_b *)Map->plus.Line[line]->topo;
428  Node = Map->plus.Node[topo->N1];
429  dig_del_line(&(Map->plus), line, Node->x, Node->y, Node->z);
430  }
431  /* build new area from leftover boundaries of deleted area */
432  for (i = 0; i < BList->n_values; i++) {
433  struct P_topo_b *topo;
434  int new_isle;
435 
436  line = BList->value[i];
437  topo = Map->plus.Line[abs(line)]->topo;
438 
439  if (topo->left == 0 || topo->right == 0) {
440  new_isle = Vect_build_line_area(
441  Map, abs(line), (line > 0 ? GV_RIGHT : GV_LEFT));
442  if (new_isle > 0) {
443  if (outer_area > 0)
444  G_fatal_error("dissolve_neighbour > 0, new area "
445  "has already been created");
446  outer_area = new_isle;
447  /* reattach centroid */
448  Map->plus.Area[outer_area]->centroid = centroid;
449  if (centroid > 0) {
450  struct P_topo_c *ctopo =
451  Map->plus.Line[centroid]->topo;
452 
453  ctopo->area = outer_area;
454  }
455  }
456  else if (new_isle < 0) {
457  /* leftover boundary creates a new isle */
458  Vect_list_append(IList, -new_isle);
459  }
460  else {
461  /* neither area nor isle, should not happen */
462  G_fatal_error(_("dissolve_neighbour > 0, failed to "
463  "build new area"));
464  }
465  }
466  /* check */
467  if (topo->left == 0 || topo->right == 0)
469  _("Dissolve with neighbour area: corrupt topology"));
470  }
471  /* build new area from neighbour's boundaries */
472  for (i = 0; i < NList->n_values; i++) {
473  struct P_topo_b *topo;
474 
475  line = NList->value[i];
476  if (!Vect_line_alive(Map, abs(line)))
477  continue;
478 
479  topo = Map->plus.Line[abs(line)]->topo;
480 
481  if (topo->left == 0 || topo->right == 0) {
482  int new_isle;
483 
484  new_isle = Vect_build_line_area(
485  Map, abs(line), (line > 0 ? GV_RIGHT : GV_LEFT));
486  if (new_isle > 0) {
487  if (outer_area > 0)
488  G_fatal_error("dissolve_neighbour > 0, new area "
489  "has already been created");
490  outer_area = new_isle;
491  /* reattach centroid */
492  Map->plus.Area[outer_area]->centroid = centroid;
493  if (centroid > 0) {
494  struct P_topo_c *ctopo =
495  Map->plus.Line[centroid]->topo;
496 
497  ctopo->area = outer_area;
498  }
499  }
500  else if (new_isle < 0) {
501  /* Neigbour's boundary creates a new isle */
502  Vect_list_append(IList, -new_isle);
503  }
504  else {
505  /* neither area nor isle, should not happen */
506  G_fatal_error(_("Failed to build new area"));
507  }
508  }
509  if (topo->left == 0 || topo->right == 0)
511  _("Dissolve with neighbour area: corrupt topology"));
512  }
513  }
514  /* dissolve with outer isle */
515  else if (dissolve_neighbour < 0) {
516 
517  G_debug(3, "dissolve with outer isle");
518 
519  outer_area = Vect_get_isle_area(Map, -dissolve_neighbour);
520 
521  /* get isle boundaries */
522  Vect_get_isle_boundaries(Map, -dissolve_neighbour, NList);
523 
524  /* delete area from topo */
525  dig_del_area(&(Map->plus), area);
526  /* delete isle from topo */
527  dig_del_isle(&(Map->plus), -dissolve_neighbour);
528  /* delete boundaries from topo */
529  for (i = 0; i < AList->n_values; i++) {
530  struct P_topo_b *topo;
531  struct P_node *Node;
532 
533  line = AList->value[i];
534  topo = (struct P_topo_b *)Map->plus.Line[line]->topo;
535  Node = Map->plus.Node[topo->N1];
536  dig_del_line(&(Map->plus), line, Node->x, Node->y, Node->z);
537  }
538  /* build new isle(s) from leftover boundaries */
539  for (i = 0; i < BList->n_values; i++) {
540  struct P_topo_b *topo;
541 
542  line = BList->value[i];
543  topo = Map->plus.Line[abs(line)]->topo;
544 
545  if (topo->left == 0 || topo->right == 0) {
546  int new_isle;
547 
548  new_isle = Vect_build_line_area(
549  Map, abs(line), (line > 0 ? GV_RIGHT : GV_LEFT));
550  if (new_isle < 0) {
551  Vect_list_append(IList, -new_isle);
552  }
553  else {
554  /* area or nothing should not happen */
555  G_fatal_error(_("Failed to build new isle"));
556  }
557  }
558  /* check */
559  if (topo->left == 0 || topo->right == 0)
561  _("Dissolve with outer isle: corrupt topology"));
562  }
563 
564  /* build new isle(s) from old isle's boundaries */
565  for (i = 0; i < NList->n_values; i++) {
566  struct P_topo_b *topo;
567 
568  line = NList->value[i];
569  if (!Vect_line_alive(Map, abs(line)))
570  continue;
571 
572  topo = Map->plus.Line[abs(line)]->topo;
573 
574  if (topo->left == 0 || topo->right == 0) {
575  int new_isle;
576 
577  new_isle = Vect_build_line_area(
578  Map, abs(line), (line > 0 ? GV_RIGHT : GV_LEFT));
579  if (new_isle < 0) {
580  Vect_list_append(IList, -new_isle);
581  }
582  else {
583  /* area or nothing should not happen */
584  G_fatal_error(_("Failed to build new isle"));
585  }
586  }
587  /* check */
588  if (topo->left == 0 || topo->right == 0)
590  _("Dissolve with outer isle: corrupt topology"));
591  }
592  }
593 
594  if (dissolve_neighbour > 0 && outer_area <= 0) {
595  G_fatal_error(_("Area merging failed"));
596  }
597 
598  /* attach all isles to outer or new area */
599  if (outer_area >= 0) {
600  for (i = 0; i < IList->n_values; i++) {
601  if (!Map->plus.Isle[IList->value[i]])
602  continue;
603  Map->plus.Isle[IList->value[i]]->area = outer_area;
604  if (outer_area > 0)
605  dig_area_add_isle(&(Map->plus), outer_area,
606  IList->value[i]);
607  }
608  }
609 
610  nremoved++;
611  nareas = Vect_get_num_areas(Map);
612  }
613 
614  if (removed_area)
615  *removed_area = size_removed;
616 
617  G_message(_("%d areas of total size %g removed"), nremoved, size_removed);
618 
619  Vect_destroy_list(List);
620  Vect_destroy_list(AList);
621  Vect_destroy_list(BList);
622  Vect_destroy_list(NList);
623  Vect_destroy_list(IList);
624  Vect_destroy_line_struct(Points);
626 
627  return (nremoved);
628 }
#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:200
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