GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
vedit/snap.c
Go to the documentation of this file.
1/*!
2 \file lib/vector/vedit/snap.c
3
4 \brief Vedit library - snapping
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 <grass/vedit.h>
15
16/*!
17 \brief Snap given point to the nearest primitive
18
19 \param Map pointer to Map_info
20 \param line line to be excluded (point on line)
21 \param x,y,z point on line to be snapped
22 \param thresh snapping threshold (>0)
23 \param vertex snap also to vertex (non-zero)
24
25 \return 1 snapped
26 \return 0 not snapped
27 */
28int Vedit_snap_point(struct Map_info *Map, int line, double *x, double *y,
29 double *z, double thresh, int vertex)
30{
31 struct line_pnts *Points;
32
33 int i, snapped;
35 double dist, mindist;
36
37 snapped = 0;
38 mindist_idx = -1;
40
41 Points = Vect_new_line_struct();
42
43 line2snap = Vect_find_line(Map, *x, *y, *z, -1, thresh, WITHOUT_Z, line);
44
45 if (line2snap > 0) {
47
50 return snapped;
51 }
52
53 for (i = 0; i < Points->n_points; i++) {
54 if (i > 0 && i < Points->n_points - 1)
55 if (!vertex)
56 continue;
57 dist = Vect_points_distance(*x, *y, *z, Points->x[i], Points->y[i],
58 Points->z[i], WITHOUT_Z);
59
60 if (mindist >= dist) {
61 mindist = dist;
62 mindist_idx = i;
63 }
64 }
65
66 if (mindist_idx > -1) {
67 *x = Points->x[mindist_idx];
68 *y = Points->y[mindist_idx];
69 *z = Points->z[mindist_idx];
70 snapped = 1;
71 }
72 }
73
74 G_debug(3, "Vedit_snap_point(): map=%s, line2snap=%d, snapped=%d",
76
78
79 return snapped;
80}
81
82/*!
83 \brief Snap selected primitive to its nearest primitive
84
85 \param Map pointer to Map_info
86 \param BgMap,nbgmaps list of background maps used for snapping
87 \param line line id to be snapped (if already written, otherwise -1)
88 \param Points line geometry
89 \param layer layer number
90 \param thresh threshold value used for snapping (>0)
91 \param to_vertex allow snapping also to vertex
92
93 \return 1 line snapped
94 \return 0 line not snapped
95 \return -1 line is dead (if 'line' is > 0)
96 */
97int Vedit_snap_line(struct Map_info *Map, struct Map_info **BgMap, int nbgmaps,
98 int line, struct line_pnts *Points, double thresh,
99 int to_vertex)
100{
101 int i, npoints, node, rewrite;
102 double *x, *y, *z;
103
104 struct line_cats *Cats;
105
106 G_debug(3, "Vedit_snap_line(): thresh=%g, to_vertex=%d", thresh, to_vertex);
107
108 if (line > 0 && !Vect_line_alive(Map, line))
109 return -1;
110
112
113 npoints = Points->n_points;
114 x = Points->x;
115 y = Points->y;
116 z = Points->z;
117
118 rewrite = 0;
119 for (node = 0; node < npoints; node++) {
120 if ((node > 0 && node < npoints - 1) && !to_vertex)
121 continue;
122
123 if (Vedit_snap_point(Map, line, &x[node], &y[node], &z[node], thresh,
124 to_vertex)) {
125 rewrite = 1;
126 }
127 else {
128 /* check also background maps */
129 for (i = 0; i < nbgmaps; i++) {
130 if (Vedit_snap_point(BgMap[i], -1, &x[node], &y[node], &z[node],
131 thresh, to_vertex)) {
132 rewrite = 1;
133 break; /* snapped, don't continue */
134 }
135 }
136 }
137 } /* for each line vertex */
138
139 /* close boundaries or lines */
140 if (!rewrite &&
141 Vect_points_distance(x[0], y[0], z[0], x[npoints - 1], y[npoints - 1],
142 z[npoints - 1], WITHOUT_Z) <= thresh) {
143 x[npoints - 1] = x[0];
144 y[npoints - 1] = y[0];
145 z[npoints - 1] = z[0];
146
147 rewrite = 1;
148 }
149
150 G_debug(3, "Vedit_snap_line(): line=%d, snapped=%d", line, rewrite);
151
153
154 return rewrite;
155}
156
157/*!
158 \brief Snap lines/boundaries
159
160 \param Map pointer to Map_info
161 \param BgMap,nbgmaps list of background maps used for snapping
162 \param List list of lines to be snapped
163 \param layer layer number
164 \param thresh threshold value used for snapping (>0)
165 \param to_vertex allow snapping also to vertex
166
167 \return number of snapped lines
168 \return -1 on error
169 */
171 struct ilist *List, double thresh, int to_vertex)
172{
173 int i, line, type;
174 int nlines_modified = 0;
175
176 struct line_pnts *Points;
177 struct line_cats *Cats;
178
179 Points = Vect_new_line_struct();
181
182 for (i = 0; i < List->n_values; i++) {
183 line = List->value[i];
184 type = Vect_read_line(Map, Points, Cats, line);
185
186 if (!(type & (GV_POINT | GV_LINES))) {
187 continue;
188 }
189
190 if (Vedit_snap_line(Map, BgMap, nbgmaps, line, Points, thresh,
191 to_vertex) == 1) {
192 if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) {
193 nlines_modified = -1;
194 goto free_exit;
195 }
196
198 }
199 }
200
204
205 return nlines_modified;
206}
#define NULL
Definition ccmath.h:32
AMI_err name(char **stream_name)
Definition ami_stream.h:426
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_find_line(struct Map_info *, double, double, double, int, double, int, int)
Find the nearest line.
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.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
Definition line.c:45
#define GV_POINT
Feature types used in memory on run time (may change)
#define GV_LINES
#define WITHOUT_Z
2D/3D vector data
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.
Definition path.h:10
int Vedit_snap_point(struct Map_info *Map, int line, double *x, double *y, double *z, double thresh, int vertex)
Snap given point to the nearest primitive.
Definition vedit/snap.c:28
int Vedit_snap_lines(struct Map_info *Map, struct Map_info **BgMap, int nbgmaps, struct ilist *List, double thresh, int to_vertex)
Snap lines/boundaries.
Definition vedit/snap.c:170
int Vedit_snap_line(struct Map_info *Map, struct Map_info **BgMap, int nbgmaps, int line, struct line_pnts *Points, double thresh, int to_vertex)
Snap selected primitive to its nearest primitive.
Definition vedit/snap.c:97
#define x