GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
vertex.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/vedit/vertex.c
3
4 \brief Vedit library - vertex manipulation
5
6 (C) 2006-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 Jachym Cepicky <jachym.cepicky gmail.com>
12 \author Martin Landa <landa.martin gmail.com>
13 */
14
15#include <grass/vedit.h>
16
17/*!
18 \brief Move all vertices in bounding box(es)
19
20 \param Map pointer to Map_info
21 \param BgMap, nbgmaps list of background vector maps for snapping
22 \param List list of selected lines
23 \param coord points location
24 \param thresh_coords threshold value for selecting lines
25 \param thresh_snap threshold value used for snapping
26 \param move_x,move_y,move_z direction (move_z is used when map is 3D)
27 \param move_first move only first vertex found in the bounding box
28 \param snap snapping mode (see vedit.h)
29
30 \return number of moved vertices
31 \return -1 on error
32 */
34 int nbgmaps, struct ilist *List, struct line_pnts *coord,
35 double thresh_coords, double thresh_snap, double move_x,
36 double move_y, double move_z, int move_first, int snap)
37{
39
40 int i, j, k;
41 int line, type, rewrite;
42 int npoints;
43 double east, north, dist;
44 double *x, *y, *z;
45 char *moved;
46
47 struct line_pnts *Points;
48 struct line_cats *Cats;
49
51 moved = NULL;
52
53 Points = Vect_new_line_struct();
55
56 for (i = 0; i < List->n_values; i++) {
57 line = List->value[i];
58
59 if (!Vect_line_alive(Map, line))
60 continue;
61
62 type = Vect_read_line(Map, Points, Cats, line);
63
64 if (!(type & GV_LINES))
65 continue;
66
67 npoints = Points->n_points;
68 x = Points->x;
69 y = Points->y;
70 z = Points->z;
71
72 /* vertex moved
73 0 not moved
74 1 moved
75 2 moved and snapped
76 */
77 moved =
78 (char *)G_realloc((void *)moved, Points->n_points * sizeof(char));
79 G_zero((void *)moved, Points->n_points * sizeof(char));
80
81 rewrite = 0;
82 for (j = 0; j < coord->n_points; j++) {
83 east = coord->x[j];
84 north = coord->y[j];
85
86 /* move all vertices in the bounding box */
87 for (k = 0; k < Points->n_points; k++) {
88 if (moved[k] == 0) {
89 dist = Vect_points_distance(east, north, 0.0, x[k], y[k],
90 z[k], WITHOUT_Z);
91 if (dist <= thresh_coords) {
92 G_debug(3,
93 "Vedit_move_vertex(): line=%d; x=%f, y=%f -> "
94 "x=%f, y=%f",
95 line, x[k], y[k], x[k] + move_x, y[k] + move_y);
96 x[k] += move_x;
97 y[k] += move_y;
98 if (Vect_is_3d(Map))
99 z[k] += move_z;
100
101 moved[k] = 1;
102
103 G_debug(3, "Vedit_move_vertex(): line=%d, point=%d",
104 line, k);
105
106 if (snap != NO_SNAP) {
108 Map, line, &x[k], &y[k], &z[k], thresh_snap,
109 (snap == SNAPVERTEX) ? 1 : 0) == 0) {
110 /* check also background maps */
111 int bgi;
112
113 for (bgi = 0; bgi < nbgmaps; bgi++) {
115 BgMap[bgi], -1, &x[k], &y[k], &z[k],
117 (snap == SNAPVERTEX) ? 1 : 0))
118 moved[k] = 2;
119 break; /* snapped, don't continue */
120 }
121 }
122 else {
123 moved[k] = 2;
124 }
125 }
126
127 rewrite = 1;
129
130 if (move_first)
131 break;
132 }
133 }
134 } /* for each line vertex */
135
136 /* close line or boundary */
137 if ((type & GV_LINES) &&
138 Vect_points_distance(x[0], y[0], z[0], x[npoints - 1],
139 y[npoints - 1], z[npoints - 1],
141
142 if (moved[0] == 1) { /* first node moved */
143 x[0] = x[npoints - 1];
144 y[0] = y[npoints - 1];
145 if (Vect_is_3d(Map))
146 z[0] = z[npoints - 1];
147 }
148 else if (moved[npoints - 1] == 1) { /* last node moved */
149 x[npoints - 1] = x[0];
150 y[npoints - 1] = y[0];
151 if (Vect_is_3d(Map))
152 z[npoints - 1] = z[0];
153 }
154 }
155 } /* for each coord */
156
157 if (rewrite) {
158 if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) {
159 nvertices_moved = -1;
160 goto free_exit;
161 }
162 }
163 } /* for each selected line */
164
166 /* destroy structures */
169 G_free(moved);
170
171 return nvertices_moved;
172}
173
174/*!
175 \brief Add new vertex to line
176
177 Shape of line is not changed.
178
179 \todo 3D
180
181 \param Map pointer to Map_info
182 \param List list of lines
183 \param coord points location
184 \param thresh find line in given threshold
185
186 \return number of add vertices
187 \return -1 on error
188 */
190 struct line_pnts *coord, double thresh)
191{
192 int i, j;
193 int type, line, seg;
195 double east, north, dist;
196 double *x, *y, *z;
197 double px, py;
198
199 struct line_pnts *Points;
200 struct line_cats *Cats;
201
202 nvertices_added = 0;
203 Points = Vect_new_line_struct();
205
206 for (i = 0; i < List->n_values; i++) {
207 line = List->value[i];
208
209 if (!Vect_line_alive(Map, line))
210 continue;
211
212 type = Vect_read_line(Map, Points, Cats, line);
213
214 if (!(type & GV_LINES))
215 continue;
216
217 G_debug(3, "Vedit_add_vertex(): line = %d, thresh = %f", line, thresh);
218
219 x = Points->x;
220 y = Points->y;
221 z = Points->z;
222 rewrite = FALSE;
223 for (j = 0; j < coord->n_points; j++) {
224 east = coord->x[j];
225 north = coord->y[j];
226
227 seg = Vect_line_distance(Points, east, north, 0.0, /* standpoint */
228 WITHOUT_Z, &px, &py,
229 NULL, /* point on line */
230 &dist, /* distance to line */
231 NULL, NULL);
232
233 if (dist <= thresh &&
234 Vect_points_distance(px, py, 0.0, x[seg], y[seg], z[seg],
235 WITHOUT_Z) > 0 &&
236 Vect_points_distance(px, py, 0.0, x[seg - 1], y[seg - 1],
237 z[seg - 1], WITHOUT_Z) > 0) {
238 /* add new vertex */
239 Vect_line_insert_point(Points, seg, px, py, 0.0);
240 G_debug(3, "Vedit_add_vertex(): line=%d; x=%f, y=%f, index=%d",
241 line, px, py, seg);
242 rewrite = TRUE;
244 }
245 } /* for each point */
246
247 /* rewrite the line */
248 if (rewrite) {
249 Vect_line_prune(Points);
250 if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) {
251 return -1;
252 }
253 }
254 } /* for each line */
255
256 /* destroy structures */
259
260 return nvertices_added;
261}
262
263/*!
264 \brief Remove vertex from line
265
266 \todo 3D
267
268 \param Map pointer to Map_info
269 \param List list of selected lines
270 \param coord points location
271 \param thresh threshold value to find a line
272
273 \return number of removed vertices
274 \return -1 on error
275 */
277 struct line_pnts *coord, double thresh)
278{
279 int i, j, k;
280 int type, line;
282 double east, north;
283 double dist;
284 double *x, *y, *z;
285
286 struct line_pnts *Points;
287 struct line_cats *Cats;
288
290
291 Points = Vect_new_line_struct();
293
294 for (i = 0; i < List->n_values; i++) {
295 line = List->value[i];
296
297 if (!Vect_line_alive(Map, line))
298 continue;
299
300 type = Vect_read_line(Map, Points, Cats, line);
301
302 if (!(type & GV_LINES))
303 continue;
304
305 x = Points->x;
306 y = Points->y;
307 z = Points->z;
308 rewrite = 0;
309 for (j = 0; j < coord->n_points; j++) {
310 east = coord->x[j];
311 north = coord->y[j];
312
313 for (k = 0; k < Points->n_points; k++) {
314 dist = Vect_points_distance(east, north, 0.0, x[k], y[k], z[k],
315 WITHOUT_Z);
316 if (dist <= thresh) {
317 /* remove vertex */
318 Vect_line_delete_point(Points, k);
319 G_debug(
320 3,
321 "Vedit_remove_vertex(): line=%d; x=%f, y=%f, index=%d",
322 line, x[k], y[k], k);
323 k--;
325 rewrite = 1;
326 }
327 } /* for each point */
328 } /* for each bounding box */
329
330 if (rewrite) {
331 /* rewrite the line */
332 if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) {
333 return -1;
334 }
335
337 }
338 } /* for each line */
339
340 /* destroy structures */
343
344 return nvertices_removed;
345}
#define NULL
Definition ccmath.h:32
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
Definition gis/zero.c:23
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:147
#define G_realloc(p, n)
Definition defs/gis.h:141
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)
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
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
double Vect_points_distance(double, double, double, double, double, double, int)
Calculate distance of 2 points.
Definition line.c:866
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.
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
int Vect_line_delete_point(struct line_pnts *, int)
Delete point at given index and move all points above down.
Definition line.c:210
int Vect_line_prune(struct line_pnts *)
Remove duplicate points, i.e. zero length segments.
Definition line.c:279
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition line.c:45
int Vect_is_3d(struct Map_info *)
Check if vector map is 3D.
int Vedit_snap_point(struct Map_info *, int, double *, double *, double *, double, int)
Snap given point to the nearest primitive.
Definition vedit/snap.c:28
#define GV_LINES
#define WITHOUT_Z
2D/3D vector data
#define TRUE
Definition gis.h:78
#define FALSE
Definition gis.h:82
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 NO_SNAP
Definition vedit.h:7
#define SNAPVERTEX
Definition vedit.h:9
int Vedit_move_vertex(struct Map_info *Map, struct Map_info **BgMap, int nbgmaps, struct ilist *List, struct line_pnts *coord, double thresh_coords, double thresh_snap, double move_x, double move_y, double move_z, int move_first, int snap)
Move all vertices in bounding box(es)
Definition vertex.c:33
int Vedit_add_vertex(struct Map_info *Map, struct ilist *List, struct line_pnts *coord, double thresh)
Add new vertex to line.
Definition vertex.c:189
int Vedit_remove_vertex(struct Map_info *Map, struct ilist *List, struct line_pnts *coord, double thresh)
Remove vertex from line.
Definition vertex.c:276
#define x