GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
break.c
Go to the documentation of this file.
1 
14 #include <math.h>
15 #include <grass/vedit.h>
16 
17 static int connect_lines(struct Map_info *, int, int, int,
18  double, struct ilist *);
19 
31 int Vedit_split_lines(struct Map_info *Map, struct ilist *List,
32  struct line_pnts *coord, double thresh,
33  struct ilist *List_updated)
34 {
35  int i, j, l;
36  int type, line, seg, newline;
37  int nlines_modified;
38  double px, py, spdist, lpdist, dist;
39  double *x, *y, *z;
40 
41  struct line_pnts *Points, *Points2;
42  struct line_cats *Cats;
43  struct ilist *List_in_box;
44 
45  nlines_modified = 0;
46 
47  Points = Vect_new_line_struct();
48  Points2 = Vect_new_line_struct();
49  Cats = Vect_new_cats_struct();
50  List_in_box = Vect_new_list();
51 
52  for (i = 0; i < List->n_values; i++) {
53  line = List->value[i];
54 
55  if (!Vect_line_alive(Map, line))
56  continue;
57 
58  type = Vect_read_line(Map, Points, Cats, line);
59 
60  if (!(type & GV_LINES))
61  continue;
62 
63  x = Points->x;
64  y = Points->y;
65  z = Points->z;
66 
67  for (j = 0; j < coord->n_points; j++) {
68  seg =
69  Vect_line_distance(Points, coord->x[j], coord->y[j],
70  coord->z[j], WITHOUT_Z, &px, &py, NULL,
71  &dist, &spdist, &lpdist);
72 
73  if (dist > thresh) {
74  continue;
75  }
76 
77  G_debug(3, "Vedit_split_lines(): line=%d, x=%f, y=%f, px=%f, py=%f, seg=%d, "
78  "dist=%f, spdist=%f, lpdist=%f", line, coord->x[j],
79  coord->y[j], px, py, seg, dist, spdist, lpdist);
80 
81  if (spdist <= 0.0 || spdist >= Vect_line_length(Points))
82  continue;
83 
84  G_debug(3, "Vedit_split_lines(): line=%d", line);
85 
86  /* copy first line part */
87  Vect_reset_line(Points2);
88  for (l = 0; l < seg; l++) {
89  Vect_append_point(Points2, x[l], y[l], z[l]);
90  }
91 
92  /* add last vertex */
93  Vect_append_point(Points2, px, py, 0.0);
94 
95  /* rewrite the line */
96  if (j == 0)
97  newline = Vect_rewrite_line(Map, line, type, Points2, Cats);
98  else
99  newline = Vect_write_line(Map, type, Points2, Cats);
100  if (newline < 0) {
101  return -1;
102  }
103  if (List_updated)
104  Vect_list_append(List_updated, newline);
105  Vect_reset_line(Points2);
106 
107  /* add given vertex */
108  Vect_append_point(Points2, px, py, 0.0);
109 
110  /* copy second line part */
111  for (l = seg; l < Points->n_points; l++) {
112  Vect_append_point(Points2, x[l], y[l], z[l]);
113  }
114 
115  /* rewrite the line */
116  newline = Vect_write_line(Map, type, Points2, Cats);
117  if (newline < 0) {
118  return -1;
119  }
120  if (List_updated)
121  Vect_list_append(List_updated, newline);
122 
123  nlines_modified++;
124  } /* for each bounding box */
125  } /* for each selected line */
126 
127  Vect_destroy_line_struct(Points);
128  Vect_destroy_line_struct(Points2);
130  Vect_destroy_list(List_in_box);
131 
132  return nlines_modified;
133 }
134 
155 int Vedit_connect_lines(struct Map_info *Map, struct ilist *List,
156  double thresh)
157 {
158  int nlines_modified, connected;
159  int i, j, node[2], n_nodes;
160  int line, found;
161  double x, y, z;
162 
163  struct ilist *List_exclude, *List_found;
164 
165  nlines_modified = 0;
166 
167  List_exclude = Vect_new_list();
168  List_found = Vect_new_list();
169 
170  n_nodes = 2;
171 
172  /* collect lines to be modified */
173  for (i = 0; i < List->n_values; i++) {
174  line = List->value[i];
175 
176  if (!Vect_line_alive(Map, line))
177  continue;
178 
179  node[0] = node[1] = -1;
180  Vect_get_line_nodes(Map, line, &(node[0]), &(node[1]));
181  if (node[0] < 0 || node[1] < 0)
182  continue;
183 
184  connected = 0;
185  Vect_reset_list(List_exclude);
186  Vect_list_append(List_exclude, line);
187  for (j = 0; j < n_nodes && !connected; j++) {
188  /* for each line node find lines in threshold */
189  Vect_get_node_coor(Map, node[j], &x, &y, &z);
190 
191  do {
192  /* find first nearest line */
193  found = Vect_find_line_list(Map, x, y, z,
194  GV_LINES, thresh, WITHOUT_Z,
195  List_exclude, List_found);
196 
197  if (found > 0 && Vect_line_alive(Map, found)) {
198  /* try to connect lines (given node) */
199  G_debug(3, "Vedit_connect_lines(): lines=%d,%d", line, found);
200  if (connect_lines(Map, !j, line, found, thresh, List)) {
201  G_debug(3, "Vedit_connect_lines(): lines=%d,%d -> connected",
202  line, found);
203  nlines_modified += 2;
204  connected = 1;
205  }
206  }
207 
208  Vect_list_append(List_exclude, found);
209  } while(List_found->n_values > 0 && !connected);
210  }
211  }
212 
213  Vect_destroy_list(List_exclude);
214  Vect_destroy_list(List_found);
215 
216  return nlines_modified;
217 }
218 
219 int connect_lines(struct Map_info *Map, int first, int line_from, int line_to,
220  double thresh, struct ilist *List)
221 {
222  int line_new;
223  int type_from, type_to;
224  int n_points, seg, is;
225  double x, y, px, py, x1, y1;
226  double dist, spdist, lpdist, length, dist_p;
227  double angle_t, angle_f, angle;
228 
229  struct line_pnts *Points_from, *Points_to, *Points_final;
230  struct line_cats *Cats_from, *Cats_to;
231 
232  Points_from = Vect_new_line_struct();
233  Points_to = Vect_new_line_struct();
234  Points_final = Vect_new_line_struct();
235  Cats_from = Vect_new_cats_struct();
236  Cats_to = Vect_new_cats_struct();
237 
238  type_from = Vect_read_line(Map, Points_from, Cats_from, line_from);
239  type_to = Vect_read_line(Map, Points_to, Cats_to, line_to);
240 
241  line_new = 0;
242  if (!(type_from & GV_LINES) || !(type_to & GV_LINES))
243  line_new = -1;
244 
245  if (line_new > -1) {
246  if (first) {
247  x = Points_from->x[0];
248  y = Points_from->y[0];
249  }
250  else {
251  n_points = Points_from->n_points - 1;
252  x = Points_from->x[n_points];
253  y = Points_from->y[n_points];
254  }
255  seg = Vect_line_distance(Points_to, x, y, 0.0, WITHOUT_Z,
256  &px, &py, NULL, &dist, &spdist, &lpdist);
257 
258  if (seg > 0 && dist > 0.0 && (thresh < 0. || dist <= thresh)) {
259  /* lines in threshold */
260  if (first)
261  length = 0;
262  else
263  length = Vect_line_length(Points_from);
264 
265  if (Vect_point_on_line(Points_from, length,
266  NULL, NULL, NULL, &angle_f, NULL) > 0) {
267  if (Vect_point_on_line(Points_to, lpdist,
268  NULL, NULL, NULL, &angle_t,
269  NULL) > 0) {
270  angle = angle_t - angle_f;
271  dist_p = fabs(dist / sin(angle));
272 
273  if (first) {
274  if (angle_f < 0)
275  angle_f -= M_PI;
276  else
277  angle_f += M_PI;
278  }
279 
280  x1 = x + dist_p * cos(angle_f);
281  y1 = y + dist_p * sin(angle_f);
282 
283  length = Vect_line_length(Points_to);
284  Vect_line_insert_point(Points_to, seg, x1, y1, 0.);
285  if (fabs(Vect_line_length(Points_to) - length) < length * 1e-3) {
286  /* lines connected -> split line_to */
287  /* update line_from */
288  if (first) {
289  Points_from->x[0] = x1;
290  Points_from->y[0] = y1;
291  }
292  else {
293  Points_from->x[n_points] = x1;
294  Points_from->y[n_points] = y1;
295  }
296 
297  line_new = Vect_rewrite_line(Map, line_from, type_from,
298  Points_from, Cats_from);
299  /* Vect_list_append(List, line_new); */
300 
301  /* update line_to -- first part */
302  Vect_reset_line(Points_final);
303  for (is = 0; is < seg; is++) {
304  Vect_append_point(Points_final, Points_to->x[is],
305  Points_to->y[is],
306  Points_to->z[is]);
307  }
308  Vect_append_point(Points_final, x1, y1, 0.0);
309  line_new = Vect_rewrite_line(Map, line_to, type_to,
310  Points_final, Cats_to);
311  /* Vect_list_append(List, line_new); */
312 
313  /* write second part */
314  Vect_reset_line(Points_final);
315  Vect_append_point(Points_final, x1, y1, 0.0);
316  for (is = seg; is < Points_to->n_points; is++) {
317  Vect_append_point(Points_final, Points_to->x[is],
318  Points_to->y[is],
319  Points_to->z[is]);
320  }
321 
322  /* rewrite first part */
323  line_new = Vect_write_line(Map, type_to,
324  Points_final, Cats_to);
325  /* Vect_list_append(List, line_new); */
326  }
327  }
328  }
329  }
330  }
331 
332  Vect_destroy_line_struct(Points_from);
333  Vect_destroy_line_struct(Points_to);
334  Vect_destroy_line_struct(Points_final);
335  Vect_destroy_cats_struct(Cats_from);
336  Vect_destroy_cats_struct(Cats_to);
337 
338  return line_new > 0 ? 1 : 0;
339 }
int Vect_destroy_list(struct ilist *list)
Frees all memory associated with a struct ilist, including the struct itself.
int l
Definition: dataquad.c:292
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_find_line_list(struct Map_info *map, double ux, double uy, double uz, int type, double maxdist, int with_z, struct ilist *exclude, struct ilist *found)
Find the nearest line(s).
int Vect_reset_line(struct line_pnts *Points)
Reset line.
Definition: line.c:148
int y
Definition: plot.c:34
int Vect_append_point(struct line_pnts *Points, double x, double y, double z)
Appends one point to the end of a line.
Definition: line.c:168
int Vect_line_insert_point(struct line_pnts *Points, int index, double x, double y, double z)
Insert new point at index position and move all old points at that position and above up...
Definition: line.c:194
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 Vect_point_on_line(struct line_pnts *Points, double distance, double *x, double *y, double *z, double *angle, double *slope)
Find point on line in the specified distance.
Definition: line.c:393
int GV_LINES
Definition: vdigit/main.py:24
int Vect_reset_list(struct ilist *list)
Reset ilist structure.
int Vect_destroy_cats_struct(struct line_cats *p)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_list_append(struct ilist *list, int val)
Append new item to the end of list if not yet present.
int first
Definition: form/open.c:25
int Vect_line_alive(struct Map_info *Map, int line)
Check if feature is alive or dead.
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 Vedit_connect_lines(struct Map_info *Map, struct ilist *List, double thresh)
Connect lines in given threshold.
Definition: break.c:155
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_node_coor(struct Map_info *map, int num, double *x, double *y, double *z)
Get node coordinates.
Definition: level_two.c:223
int Vect_line_distance(struct line_pnts *points, double ux, double uy, double uz, int with_z, double *px, double *py, double *pz, double *dist, double *spdist, double *lpdist)
calculate line distance.
Definition: line.c:631
int Vedit_split_lines(struct Map_info *Map, struct ilist *List, struct line_pnts *coord, double thresh, struct ilist *List_updated)
Split selected lines on given position.
Definition: break.c:31
int Vect_destroy_line_struct(struct line_pnts *p)
Frees all memory associated with a struct line_pnts, including the struct itself. ...
Definition: line.c:90
int Vect_read_line(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c, int line)
Read vector feature.