GRASS Programmer's Manual  6.4.3(2013)-r
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties 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  for (l = 0; l < seg; l++) {
88  Vect_append_point(Points2, x[l], y[l], z[l]);
89  }
90 
91  /* add last vertex */
92  Vect_append_point(Points2, px, py, 0.0);
93 
94  /* rewrite the line */
95  newline = Vect_rewrite_line(Map, line, type, Points2, Cats);
96  if (newline < 0) {
97  return -1;
98  }
99  if (List_updated)
100  Vect_list_append(List_updated, newline);
101  Vect_reset_line(Points2);
102 
103  /* add given vertex */
104  Vect_append_point(Points2, px, py, 0.0);
105 
106  /* copy second line part */
107  for (l = seg; l < Points->n_points; l++) {
108  Vect_append_point(Points2, x[l], y[l], z[l]);
109  }
110 
111  /* rewrite the line */
112  newline = Vect_write_line(Map, type, Points2, Cats);
113  if (newline < 0) {
114  return -1;
115  }
116  if (List_updated)
117  Vect_list_append(List_updated, newline);
118 
119  nlines_modified++;
120  } /* for each bounding box */
121  } /* for each selected line */
122 
123  Vect_destroy_line_struct(Points);
124  Vect_destroy_line_struct(Points2);
126  Vect_destroy_list(List_in_box);
127 
128  return nlines_modified;
129 }
130 
151 int Vedit_connect_lines(struct Map_info *Map, struct ilist *List,
152  double thresh)
153 {
154  int nlines_modified, connected;
155  int i, j, node[2], n_nodes;
156  int line, found;
157  double x, y, z;
158 
159  struct ilist *List_exclude, *List_found;
160 
161  nlines_modified = 0;
162 
163  List_exclude = Vect_new_list();
164  List_found = Vect_new_list();
165 
166  n_nodes = 2;
167 
168  /* collect lines to be modified */
169  for (i = 0; i < List->n_values; i++) {
170  line = List->value[i];
171 
172  if (!Vect_line_alive(Map, line))
173  continue;
174 
175  node[0] = node[1] = -1;
176  Vect_get_line_nodes(Map, line, &(node[0]), &(node[1]));
177  if (node[0] < 0 || node[1] < 0)
178  continue;
179 
180  connected = 0;
181  Vect_reset_list(List_exclude);
182  Vect_list_append(List_exclude, line);
183  for (j = 0; j < n_nodes && !connected; j++) {
184  /* for each line node find lines in threshold */
185  Vect_get_node_coor(Map, node[j], &x, &y, &z);
186 
187  do {
188  /* find first nearest line */
189  found = Vect_find_line_list(Map, x, y, z,
190  GV_LINES, thresh, WITHOUT_Z,
191  List_exclude, List_found);
192 
193  if (found > 0 && Vect_line_alive(Map, found)) {
194  /* try to connect lines (given node) */
195  G_debug(3, "Vedit_connect_lines(): lines=%d,%d", line, found);
196  if (connect_lines(Map, !j, line, found, thresh, List)) {
197  G_debug(3, "Vedit_connect_lines(): lines=%d,%d -> connected",
198  line, found);
199  nlines_modified += 2;
200  connected = 1;
201  }
202  }
203 
204  Vect_list_append(List_exclude, found);
205  } while(List_found->n_values > 0 && !connected);
206  }
207  }
208 
209  Vect_destroy_list(List_exclude);
210  Vect_destroy_list(List_found);
211 
212  return nlines_modified;
213 }
214 
215 int connect_lines(struct Map_info *Map, int first, int line_from, int line_to,
216  double thresh, struct ilist *List)
217 {
218  int line_new;
219  int type_from, type_to;
220  int n_points, seg, is;
221  double x, y, px, py, x1, y1;
222  double dist, spdist, lpdist, length, dist_p;
223  double angle_t, angle_f, angle;
224 
225  struct line_pnts *Points_from, *Points_to, *Points_final;
226  struct line_cats *Cats_from, *Cats_to;
227 
228  Points_from = Vect_new_line_struct();
229  Points_to = Vect_new_line_struct();
230  Points_final = Vect_new_line_struct();
231  Cats_from = Vect_new_cats_struct();
232  Cats_to = Vect_new_cats_struct();
233 
234  type_from = Vect_read_line(Map, Points_from, Cats_from, line_from);
235  type_to = Vect_read_line(Map, Points_to, Cats_to, line_to);
236 
237  line_new = 0;
238  if (!(type_from & GV_LINES) || !(type_to & GV_LINES))
239  line_new = -1;
240 
241  if (line_new > -1) {
242  if (first) {
243  x = Points_from->x[0];
244  y = Points_from->y[0];
245  }
246  else {
247  n_points = Points_from->n_points - 1;
248  x = Points_from->x[n_points];
249  y = Points_from->y[n_points];
250  }
251  seg = Vect_line_distance(Points_to, x, y, 0.0, WITHOUT_Z,
252  &px, &py, NULL, &dist, &spdist, &lpdist);
253 
254  if (seg > 0 && dist > 0.0 && (thresh < 0. || dist <= thresh)) {
255  /* lines in threshold */
256  if (first)
257  length = 0;
258  else
259  length = Vect_line_length(Points_from);
260 
261  if (Vect_point_on_line(Points_from, length,
262  NULL, NULL, NULL, &angle_f, NULL) > 0) {
263  if (Vect_point_on_line(Points_to, lpdist,
264  NULL, NULL, NULL, &angle_t,
265  NULL) > 0) {
266  angle = angle_t - angle_f;
267  dist_p = fabs(dist / sin(angle));
268 
269  if (first) {
270  if (angle_f < 0)
271  angle_f -= M_PI;
272  else
273  angle_f += M_PI;
274  }
275 
276  x1 = x + dist_p * cos(angle_f);
277  y1 = y + dist_p * sin(angle_f);
278 
279  length = Vect_line_length(Points_to);
280  Vect_line_insert_point(Points_to, seg, x1, y1, 0.);
281  if (fabs(Vect_line_length(Points_to) - length) < length * 1e-3) {
282  /* lines connected -> split line_to */
283  /* update line_from */
284  if (first) {
285  Points_from->x[0] = x1;
286  Points_from->y[0] = y1;
287  }
288  else {
289  Points_from->x[n_points] = x1;
290  Points_from->y[n_points] = y1;
291  }
292 
293  line_new = Vect_rewrite_line(Map, line_from, type_from,
294  Points_from, Cats_from);
295  /* Vect_list_append(List, line_new); */
296 
297  /* update line_to -- first part */
298  Vect_reset_line(Points_final);
299  for (is = 0; is < seg; is++) {
300  Vect_append_point(Points_final, Points_to->x[is],
301  Points_to->y[is],
302  Points_to->z[is]);
303  }
304  Vect_append_point(Points_final, x1, y1, 0.0);
305  line_new = Vect_rewrite_line(Map, line_to, type_to,
306  Points_final, Cats_to);
307  /* Vect_list_append(List, line_new); */
308 
309  /* write second part */
310  Vect_reset_line(Points_final);
311  Vect_append_point(Points_final, x1, y1, 0.0);
312  for (is = seg; is < Points_to->n_points; is++) {
313  Vect_append_point(Points_final, Points_to->x[is],
314  Points_to->y[is],
315  Points_to->z[is]);
316  }
317 
318  /* rewrite first part */
319  line_new = Vect_write_line(Map, type_to,
320  Points_final, Cats_to);
321  /* Vect_list_append(List, line_new); */
322  }
323  }
324  }
325  }
326  }
327 
328  Vect_destroy_line_struct(Points_from);
329  Vect_destroy_line_struct(Points_to);
330  Vect_destroy_line_struct(Points_final);
331  Vect_destroy_cats_struct(Cats_from);
332  Vect_destroy_cats_struct(Cats_to);
333 
334  return line_new > 0 ? 1 : 0;
335 }
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:230
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:1301
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:151
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:206
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.