GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
dangles.c
Go to the documentation of this file.
1 
20 #include <stdlib.h>
21 #include <grass/gis.h>
22 #include <grass/Vect.h>
23 #include <grass/glocale.h>
24 
25 #define REMOVE_DANGLE 0
26 #define CHTYPE_DANGLE 1
27 #define SELECT_DANGLE 2
28 
29 static void dangles(struct Map_info *, int, int, double,
30  struct Map_info *, struct ilist *);
31 
53 void
54 Vect_remove_dangles(struct Map_info *Map, int type, double maxlength,
55  struct Map_info *Err)
56 {
57  dangles(Map, type, REMOVE_DANGLE, maxlength, Err, NULL);
58 }
59 
79 void
80 Vect_chtype_dangles(struct Map_info *Map, double maxlength,
81  struct Map_info *Err)
82 {
83  dangles(Map, 0, CHTYPE_DANGLE, maxlength, Err, NULL);
84 }
85 
103 void
104 Vect_select_dangles(struct Map_info *Map, int type, double maxlength,
105  struct ilist *List)
106 {
107  dangles(Map, type, SELECT_DANGLE, maxlength, NULL, List);
108 }
109 
110 /*
111  Line is considered to be a dangle if on at least one end node is no
112  other line of given type(s). If a dangle is formed by more lines,
113  such string of lines is taken as one dangle and either deleted are
114  all parts or nothing. Optionally, if chtype is set to 1, only
115  GV_BOUNDARY are checked for dangles, and if dangle is found lines
116  are not deleted but rewritten with type GVLINE. Optionally deleted
117  dangles are written to error map. Input map must be opened on level
118  2 for update at least on GV_BUILD_BASE.
119 
120  Parameters:
121  Map input map where have to be deleted
122  type type of dangles
123  option dangle option (REMOVE_DANGLE, CHTYPE_DANGLE, SELECT_DANGLE)
124  maxlength maxlength of dangles or -1 for all dangles
125  Err vector map where deleted dangles are written or NULL
126  List_dangle list of feature (selected dangles) ids
127  */
128 static void dangles(struct Map_info *Map, int type, int option,
129  double maxlength, struct Map_info *Err,
130  struct ilist *List_dangle)
131 {
132  struct line_pnts *Points;
133  struct line_cats *Cats;
134  int i, line, ltype, next_line = 0, nnodelines;
135  int nnodes, node, node1, node2, next_node;
136  int lcount, tmp_next_line = 0;
137  double length;
138  int dangles_removed; /* number of removed dangles */
139  int lines_removed; /* number of lines removed */
140  struct ilist *List; /* List of lines in chain */
141  char *lmsg;
142 
143  next_line = tmp_next_line = 0;
144  dangles_removed = 0;
145  lines_removed = 0;
146 
147  type &= GV_LINES; /* to work only with lines and boundaries */
148 
149  if (option == CHTYPE_DANGLE) {
150  type = GV_BOUNDARY; /* process boundaries only */
151  lmsg = "changed lines";
152  }
153  else if (option == REMOVE_DANGLE) {
154  lmsg = "removed lines";
155  }
156  else {
157  lmsg = "selected lines";
158  }
159 
160  if (List_dangle)
161  Vect_reset_list(List_dangle);
162 
163  Points = Vect_new_line_struct();
164  Cats = Vect_new_cats_struct();
165  List = Vect_new_list();
166 
167  nnodes = Vect_get_num_nodes(Map);
168  G_debug(2, "nnodes = %d", nnodes);
169 
170  for (node = 1; node <= nnodes; node++) {
171  G_percent(node, nnodes, 1);
172  G_debug(3, "node = %d", node);
173  if (!Vect_node_alive(Map, node))
174  continue;
175 
176  nnodelines = Vect_get_node_n_lines(Map, node);
177 
178  lcount = 0; /* number of lines of given type */
179  for (i = 0; i < nnodelines; i++) {
180  line = Vect_get_node_line(Map, node, i);
181  G_debug(3, " node line %d = %d", i, line);
182 
183  ltype = Vect_read_line(Map, NULL, NULL, abs(line));
184 
185  if (ltype & type) {
186  lcount++;
187  next_line = line;
188  }
189  }
190 
191  Vect_reset_list(List);
192  if (lcount == 1) {
193  G_debug(3, " node %d is dangle -> follow the line %d", node,
194  next_line);
195 
196  while (next_line != 0) {
197  Vect_list_append(List, abs(next_line));
198 
199  /* Look at the next end of the line if just one another line of the type is connected */
200  Vect_get_line_nodes(Map, abs(next_line), &node1, &node2);
201  next_node = next_line > 0 ? node2 : node1;
202 
203  G_debug(3, " next_node = %d", next_node);
204 
205  nnodelines = Vect_get_node_n_lines(Map, next_node);
206 
207  lcount = 0; /* number of lines of given type (except current next_line) */
208  for (i = 0; i < nnodelines; i++) {
209  line = Vect_get_node_line(Map, next_node, i);
210  G_debug(3, " node line %d = %d", i, line);
211 
212  ltype = Vect_read_line(Map, NULL, NULL, abs(line));
213 
214  if (ltype & type && abs(line) != abs(next_line)) {
215  lcount++;
216  tmp_next_line = line;
217  }
218  }
219  if (lcount == 1)
220  next_line = tmp_next_line;
221  else
222  next_line = 0;
223 
224  }
225 
226  /* Length of the chain */
227  length = 0;
228  for (i = 0; i < List->n_values; i++) {
229  G_debug(3, " chain line %d = %d", i, List->value[i]);
230  ltype = Vect_read_line(Map, Points, NULL, List->value[i]);
231  length += Vect_line_length(Points);
232  }
233 
234  if (maxlength < 0 || length < maxlength) { /* delete the chain */
235  G_debug(3, " delete the chain (length=%g)", length);
236 
237  for (i = 0; i < List->n_values; i++) {
238  ltype = Vect_read_line(Map, Points, Cats, List->value[i]);
239 
240  /* Write to Err deleted dangle */
241  if (Err) {
242  Vect_write_line(Err, ltype, Points, Cats);
243  }
244 
245  if (option == REMOVE_DANGLE) {
246  Vect_delete_line(Map, List->value[i]);
247  }
248  else if (option == CHTYPE_DANGLE) {
249  G_debug(3, " rewrite line %d", List->value[i]);
250  Vect_rewrite_line(Map, List->value[i], GV_LINE,
251  Points, Cats);
252  }
253  else {
254  if (List_dangle) {
255  Vect_list_append(List_dangle, List->value[i]);
256  }
257  }
258  lines_removed++;
259  }
260  } /* delete the chain */
261 
262  dangles_removed++;
263  } /* lcount == 1 */
264  } /* node <= nnodes */
265 }
int Vect_get_node_line(struct Map_info *Map, int node, int line)
Get line id for node line index.
Definition: level_two.c:316
int Vect_get_line_nodes(struct Map_info *Map, int line, int *n1, int *n2)
Get line nodes.
Definition: level_two.c:247
struct line_pnts * Vect_new_line_struct()
Creates and initializes a struct line_pnts.
Definition: line.c:57
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
int Vect_node_alive(struct Map_info *Map, int node)
Check if node is alive or dead.
#define SELECT_DANGLE
Definition: dangles.c:27
void Vect_remove_dangles(struct Map_info *Map, int type, double maxlength, struct Map_info *Err)
Remove dangles from vector map.
Definition: dangles.c:54
void Vect_select_dangles(struct Map_info *Map, int type, double maxlength, struct ilist *List)
Select dangles from vector map.
Definition: dangles.c:104
int G_percent(long n, long d, int s)
Print percent complete messages.
Definition: percent.c:63
void Vect_chtype_dangles(struct Map_info *Map, double maxlength, struct Map_info *Err)
Change boundary dangles to lines.
Definition: dangles.c:80
int Vect_rewrite_line(struct Map_info *Map, int line, int type, struct line_pnts *points, struct line_cats *cats)
Rewrites feature info at the given offset.
int GV_LINES
Definition: vdigit/main.py:24
#define CHTYPE_DANGLE
Definition: dangles.c:26
int Vect_reset_list(struct ilist *list)
Reset ilist structure.
int Vect_list_append(struct ilist *list, int val)
Append new item to the end of list if not yet present.
struct line_cats * Vect_new_cats_struct()
Creates and initializes line_cats structure.
return NULL
Definition: dbfopen.c:1394
double Vect_line_length(struct line_pnts *Points)
Calculate line length, 3D-length in case of 3D vector line.
Definition: line.c:555
tuple Map
Definition: render.py:1310
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
int Vect_delete_line(struct Map_info *Map, int line)
Delete feature.
long Vect_write_line(struct Map_info *Map, int type, struct line_pnts *points, struct line_cats *cats)
Writes new feature to the end of file (table)
int Vect_get_num_nodes(struct Map_info *map)
Get number of nodes in vector map.
Definition: level_two.c:29
#define REMOVE_DANGLE
Definition: dangles.c:25
int Vect_read_line(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c, int line)
Read vector feature.
int Vect_get_node_n_lines(struct Map_info *Map, int node)
Get number of lines for node.
Definition: level_two.c:296