GRASS 8 Programmer's Manual 8.6.0dev(2026)-8843f13794
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 SPDX-FileCopyrightText: 2007-2008 GRASS Development Team
7 SPDX-License-Identifier: GPL-2.0-or-later
8
9 \author Martin Landa <landa.martin gmail.com>
10 */
11
12#include <grass/vedit.h>
13
14/*!
15 \brief Snap given point to the nearest primitive
16
17 \param Map pointer to Map_info
18 \param line line to be excluded (point on line)
19 \param x,y,z point on line to be snapped
20 \param thresh snapping threshold (>0)
21 \param vertex snap also to vertex (non-zero)
22
23 \return 1 snapped
24 \return 0 not snapped
25 */
26int Vedit_snap_point(struct Map_info *Map, int line, double *x, double *y,
27 double *z, double thresh, int vertex)
28{
29 struct line_pnts *Points;
30
31 int i, snapped;
33 double dist, mindist;
34
35 snapped = 0;
36 mindist_idx = -1;
38
39 Points = Vect_new_line_struct();
40
41 line2snap = Vect_find_line(Map, *x, *y, *z, -1, thresh, WITHOUT_Z, line);
42
43 if (line2snap > 0) {
45
48 return snapped;
49 }
50
51 for (i = 0; i < Points->n_points; i++) {
52 if (i > 0 && i < Points->n_points - 1)
53 if (!vertex)
54 continue;
55 dist = Vect_points_distance(*x, *y, *z, Points->x[i], Points->y[i],
56 Points->z[i], WITHOUT_Z);
57
58 if (mindist >= dist) {
59 mindist = dist;
60 mindist_idx = i;
61 }
62 }
63
64 if (mindist_idx > -1) {
65 *x = Points->x[mindist_idx];
66 *y = Points->y[mindist_idx];
67 *z = Points->z[mindist_idx];
68 snapped = 1;
69 }
70 }
71
72 G_debug(3, "Vedit_snap_point(): map=%s, line2snap=%d, snapped=%d",
74
76
77 return snapped;
78}
79
80/*!
81 \brief Snap selected primitive to its nearest primitive
82
83 \param Map pointer to Map_info
84 \param BgMap,nbgmaps list of background maps used for snapping
85 \param line line id to be snapped (if already written, otherwise -1)
86 \param Points line geometry
87 \param layer layer number
88 \param thresh threshold value used for snapping (>0)
89 \param to_vertex allow snapping also to vertex
90
91 \return 1 line snapped
92 \return 0 line not snapped
93 \return -1 line is dead (if 'line' is > 0)
94 */
95int Vedit_snap_line(struct Map_info *Map, struct Map_info **BgMap, int nbgmaps,
96 int line, struct line_pnts *Points, double thresh,
97 int to_vertex)
98{
99 int i, npoints, node, rewrite;
100 double *x, *y, *z;
101
102 struct line_cats *Cats;
103
104 G_debug(3, "Vedit_snap_line(): thresh=%g, to_vertex=%d", thresh, to_vertex);
105
106 if (line > 0 && !Vect_line_alive(Map, line))
107 return -1;
108
110
111 npoints = Points->n_points;
112 x = Points->x;
113 y = Points->y;
114 z = Points->z;
115
116 rewrite = 0;
117 for (node = 0; node < npoints; node++) {
118 if ((node > 0 && node < npoints - 1) && !to_vertex)
119 continue;
120
121 if (Vedit_snap_point(Map, line, &x[node], &y[node], &z[node], thresh,
122 to_vertex)) {
123 rewrite = 1;
124 }
125 else {
126 /* check also background maps */
127 for (i = 0; i < nbgmaps; i++) {
128 if (Vedit_snap_point(BgMap[i], -1, &x[node], &y[node], &z[node],
129 thresh, to_vertex)) {
130 rewrite = 1;
131 break; /* snapped, don't continue */
132 }
133 }
134 }
135 } /* for each line vertex */
136
137 /* close boundaries or lines */
138 if (!rewrite &&
139 Vect_points_distance(x[0], y[0], z[0], x[npoints - 1], y[npoints - 1],
140 z[npoints - 1], WITHOUT_Z) <= thresh) {
141 x[npoints - 1] = x[0];
142 y[npoints - 1] = y[0];
143 z[npoints - 1] = z[0];
144
145 rewrite = 1;
146 }
147
148 G_debug(3, "Vedit_snap_line(): line=%d, snapped=%d", line, rewrite);
149
151
152 return rewrite;
153}
154
155/*!
156 \brief Snap lines/boundaries
157
158 \param Map pointer to Map_info
159 \param BgMap,nbgmaps list of background maps used for snapping
160 \param List list of lines to be snapped
161 \param layer layer number
162 \param thresh threshold value used for snapping (>0)
163 \param to_vertex allow snapping also to vertex
164
165 \return number of snapped lines
166 \return -1 on error
167 */
169 struct ilist *List, double thresh, int to_vertex)
170{
171 int i, line, type;
172 int nlines_modified = 0;
173
174 struct line_pnts *Points;
175 struct line_cats *Cats;
176
177 Points = Vect_new_line_struct();
179
180 for (i = 0; i < List->n_values; i++) {
181 line = List->value[i];
182 type = Vect_read_line(Map, Points, Cats, line);
183
184 if (!(type & (GV_POINT | GV_LINES))) {
185 continue;
186 }
187
188 if (Vedit_snap_line(Map, BgMap, nbgmaps, line, Points, thresh,
189 to_vertex) == 1) {
190 if (Vect_rewrite_line(Map, line, type, Points, Cats) < 0) {
191 nlines_modified = -1;
192 goto free_exit;
193 }
194
196 }
197 }
198
202
203 return nlines_modified;
204}
#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:75
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:864
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:43
#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:712
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:26
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:168
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:95
#define x