GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
break.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/vedit/break.c
3
4 \brief Vedit library - split, break, connect lines
5
6 (C) 2007-2008 by the GRASS Development Team
7
8 This program is free software under the GNU General Public License
9 (>=v2). Read the file COPYING that comes with GRASS for details.
10
11 \author Martin Landa <landa.martin gmail.com>
12 */
13
14#include <math.h>
15#include <grass/vedit.h>
16
17static int connect_lines(struct Map_info *, int, int, int, double,
18 struct ilist *);
19
20/*!
21 \brief Split selected lines on given position
22
23 \param Map pointer to Map_info
24 \param List list of selected lines
25 \param coord points location
26 \param thresh threshold
27 \param[out] List_updated list of rewritten features (or NULL)
28
29 \return number of modified lines
30 \return -1 on error
31 */
33 struct line_pnts *coord, double thresh,
34 struct ilist *List_updated)
35{
36 int i, j, l;
37 int type, line, seg, newline;
39 double px, py, spdist, lpdist, dist;
40 double *x, *y, *z;
41
42 struct line_pnts *Points, *Points2;
43 struct line_cats *Cats;
44
46
47 Points = Vect_new_line_struct();
50
51 for (i = 0; i < List->n_values; i++) {
52 line = List->value[i];
53
54 if (!Vect_line_alive(Map, line))
55 continue;
56
57 type = Vect_read_line(Map, Points, Cats, line);
58
59 if (!(type & GV_LINES))
60 continue;
61
62 x = Points->x;
63 y = Points->y;
64 z = Points->z;
65
66 for (j = 0; j < coord->n_points; j++) {
67 seg = Vect_line_distance(Points, coord->x[j], coord->y[j],
68 coord->z[j], WITHOUT_Z, &px, &py, NULL,
69 &dist, &spdist, &lpdist);
70
71 if (dist > thresh) {
72 continue;
73 }
74
75 G_debug(3,
76 "Vedit_split_lines(): line=%d, x=%f, y=%f, px=%f, py=%f, "
77 "seg=%d, "
78 "dist=%f, spdist=%f, lpdist=%f",
79 line, coord->x[j], coord->y[j], px, py, seg, dist, spdist,
80 lpdist);
81
83 continue;
84
85 G_debug(3, "Vedit_split_lines(): line=%d", line);
86
87 /* copy first line part */
89 for (l = 0; l < seg; l++) {
90 Vect_append_point(Points2, x[l], y[l], z[l]);
91 }
92
93 /* add last vertex */
95
96 /* rewrite the line */
97 if (j == 0)
98 newline = Vect_rewrite_line(Map, line, type, Points2, Cats);
99 else
101 if (newline < 0) {
102 nlines_modified = -1;
103 goto free_exit;
104 }
105 if (List_updated)
108
109 /* add given vertex */
111
112 /* copy second line part */
113 for (l = seg; l < Points->n_points; l++) {
114 Vect_append_point(Points2, x[l], y[l], z[l]);
115 }
116
117 /* rewrite the line */
119 if (newline < 0) {
120 nlines_modified = -1;
121 goto free_exit;
122 }
123 if (List_updated)
125
127 } /* for each bounding box */
128 } /* for each selected line */
129
134
135 return nlines_modified;
136}
137
138/*!
139 \brief Connect lines in given threshold
140
141 \code
142 \ \
143 id1 \ -> \
144 \
145 id2 --------- -----+---
146 \endcode
147
148 If two lines are selected and <i>thresh</i> is -1, no limit is
149 applied.
150
151 \param Map pointer to Map_info
152 \param List list of selected lines
153 \param thresh threshold value
154
155 \return number of modified lines
156 \return -1 on error
157 */
158int Vedit_connect_lines(struct Map_info *Map, struct ilist *List, double thresh)
159{
161 int i, j, node[2], n_nodes;
162 int line, found;
163 double x, y, z;
164
165 struct ilist *List_exclude, *List_found;
166
167 nlines_modified = 0;
168
171
172 n_nodes = 2;
173
174 /* collect lines to be modified */
175 for (i = 0; i < List->n_values; i++) {
176 line = List->value[i];
177
178 if (!Vect_line_alive(Map, line))
179 continue;
180
181 if (Vect_get_line_type(Map, line) & GV_POINTS)
182 continue;
183
184 node[0] = node[1] = -1;
185 Vect_get_line_nodes(Map, line, &(node[0]), &(node[1]));
186 if (node[0] < 0 || node[1] < 0)
187 continue;
188
189 connected = 0;
192 for (j = 0; j < n_nodes && !connected; j++) {
193 /* for each line node find lines in threshold */
194 Vect_get_node_coor(Map, node[j], &x, &y, &z);
195
196 do {
197 /* find first nearest line */
198 found =
201
202 if (found > 0 && Vect_line_alive(Map, found)) {
203 /* try to connect lines (given node) */
204 G_debug(3, "Vedit_connect_lines(): lines=%d,%d", line,
205 found);
206 if (connect_lines(Map, !j, line, found, thresh, List)) {
207 G_debug(
208 3,
209 "Vedit_connect_lines(): lines=%d,%d -> connected",
210 line, found);
211 nlines_modified += 2;
212 connected = 1;
213 }
214 }
215
217 } while (List_found->n_values > 0 && !connected);
218 }
219 }
220
223
224 return nlines_modified;
225}
226
227int connect_lines(struct Map_info *Map, int first, int line_from, int line_to,
228 double thresh, struct ilist *List UNUSED)
229{
230 int line_new;
231 int type_from, type_to;
232 int n_points, seg, is;
233 double x, y, px, py, x1, y1;
234 double dist, spdist, lpdist, length, dist_p;
235 double angle_t, angle_f, angle;
236
238 struct line_cats *Cats_from, *Cats_to;
239
245
248
249 line_new = 0;
250 if (!(type_from & GV_LINES) || !(type_to & GV_LINES))
251 line_new = -1;
252
253 if (line_new > -1) {
254 n_points = Points_from->n_points - 1;
255
256 if (first) {
257 x = Points_from->x[0];
258 y = Points_from->y[0];
259 }
260 else {
261 x = Points_from->x[n_points];
262 y = Points_from->y[n_points];
263 }
264 seg = Vect_line_distance(Points_to, x, y, 0.0, WITHOUT_Z, &px, &py,
265 NULL, &dist, &spdist, &lpdist);
266
267 if (seg > 0 && dist > 0.0 && (thresh < 0. || dist <= thresh)) {
268 /* lines in threshold */
269 if (first)
270 length = 0;
271 else
273
275 &angle_f, NULL) > 0) {
277 &angle_t, NULL) > 0) {
279 dist_p = fabs(dist / sin(angle));
280
281 if (first) {
282 if (angle_f < 0)
283 angle_f -= M_PI;
284 else
285 angle_f += M_PI;
286 }
287
288 x1 = x + dist_p * cos(angle_f);
289 y1 = y + dist_p * sin(angle_f);
290
291 length = Vect_line_length(Points_to);
292 Vect_line_insert_point(Points_to, seg, x1, y1, 0.);
293 if (fabs(Vect_line_length(Points_to) - length) <
294 length * 1e-3) {
295 /* lines connected -> split line_to */
296 /* update line_from */
297 if (first) {
298 Points_from->x[0] = x1;
299 Points_from->y[0] = y1;
300 }
301 else {
302 Points_from->x[n_points] = x1;
303 Points_from->y[n_points] = y1;
304 }
305
308 /* Vect_list_append(List, line_new); */
309
310 /* update line_to -- first part */
312 for (is = 0; is < seg; is++) {
314 Points_to->y[is],
315 Points_to->z[is]);
316 }
317 Vect_append_point(Points_final, x1, y1, 0.0);
320 /* Vect_list_append(List, line_new); */
321
322 /* write second part */
324 Vect_append_point(Points_final, x1, y1, 0.0);
325 for (is = seg; is < Points_to->n_points; is++) {
327 Points_to->y[is],
328 Points_to->z[is]);
329 }
330
331 /* rewrite first part */
333 Cats_to);
334 /* Vect_list_append(List, line_new); */
335 }
336 }
337 }
338 }
339 }
340
346
347 return line_new > 0 ? 1 : 0;
348}
int Vedit_connect_lines(struct Map_info *Map, struct ilist *List, double thresh)
Connect lines in given threshold.
Definition break.c:158
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:32
#define NULL
Definition ccmath.h:32
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
off_t Vect_rewrite_line(struct Map_info *, off_t, int, const struct line_pnts *, const struct line_cats *)
Rewrites existing feature (topological level required)
int Vect_get_line_nodes(struct Map_info *, int, int *, int *)
Get line nodes.
Definition level_two.c:304
int Vect_get_node_coor(struct Map_info *, int, double *, double *, double *)
Get node coordinates.
Definition level_two.c:274
double Vect_line_length(const struct line_pnts *)
Calculate line length, 3D-length in case of 3D vector line.
Definition line.c:575
int Vect_point_on_line(const struct line_pnts *, double, double *, double *, double *, double *, double *)
Find point on line in the specified distance.
Definition line.c:413
int Vect_get_line_type(struct Map_info *, int)
Get line type.
Definition level_two.c:254
int Vect_find_line_list(struct Map_info *, double, double, double, int, double, int, const struct ilist *, struct ilist *)
Find the nearest line(s).
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_read_line(struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
int Vect_line_distance(const struct line_pnts *, double, double, double, int, double *, double *, double *, double *, double *, double *)
Calculate distance of point to line.
Definition line.c:648
int Vect_line_alive(struct Map_info *, int)
Check if feature is alive or dead (topological level required)
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
int Vect_line_insert_point(struct line_pnts *, int, double, double, double)
Insert new point at index position and move all old points at that position and above up.
Definition line.c:176
off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes a new feature.
void Vect_reset_line(struct line_pnts *)
Reset line.
Definition line.c:129
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition line.c:45
int Vect_reset_list(struct ilist *)
Reset ilist structure.
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
Definition line.c:148
#define GV_LINES
#define WITHOUT_Z
2D/3D vector data
#define GV_POINTS
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition gis.h:46
#define M_PI
Definition gis.h:157
double l
Definition r_raster.c:39
Vector map info.
List of integers.
Definition gis.h:715
Feature category info.
Feature geometry info - coordinates.
double * y
Array of Y coordinates.
double * x
Array of X coordinates.
int n_points
Number of points.
double * z
Array of Z coordinates.
#define x