21 #include <grass/gis.h>
22 #include <grass/Vect.h>
23 #include <grass/glocale.h>
26 static int sort_new(
const void *pa,
const void *pb);
81 double thresh,
struct Map_info *Err)
83 struct line_pnts *Points, *NPoints;
84 struct line_cats *Cats;
85 int line, ltype, line_idx;
90 int nanchors, ntosnap;
91 int nsnapped, ncreated;
92 int apoints, npoints, nvertices;
101 if (List_lines->n_values < 1)
110 thresh2 = thresh * thresh;
118 for (line_idx = 0; line_idx < List_lines->n_values; line_idx++) {
121 G_percent(line_idx, List_lines->n_values, 2);
123 line = List_lines->value[line_idx];
131 for (v = 0; v < Points->n_points; v++) {
132 G_debug(3,
" vertex v = %d", v);
146 G_debug(3,
"List : nvalues = %d", List->n_values);
148 if (List->n_values == 0) {
151 if ((point - 1) == apoints) {
154 (
XPNT *) G_realloc(XPnts,
155 (apoints + 1) *
sizeof(
XPNT));
157 XPnts[point].
x = Points->x[v];
158 XPnts[point].
y = Points->y[v];
164 G_percent(line_idx, List_lines->n_values, 2);
170 nanchors = ntosnap = 0;
171 for (point = 1; point <= npoints; point++) {
176 G_debug(3,
" point = %d", point);
178 if (XPnts[point].anchor >= 0)
185 rect.
boundary[0] = XPnts[point].
x - thresh;
186 rect.
boundary[3] = XPnts[point].
x + thresh;
187 rect.
boundary[1] = XPnts[point].
y - thresh;
188 rect.
boundary[4] = XPnts[point].
y + thresh;
194 G_debug(4,
" %d points in threshold box", List->n_values);
196 for (i = 0; i < List->n_values; i++) {
198 double dx, dy, dist2;
200 pointb = List->value[i];
204 dx = XPnts[pointb].
x - XPnts[point].
x;
205 dy = XPnts[pointb].
y - XPnts[point].
y;
206 dist2 = dx * dx + dy * dy;
212 if (XPnts[pointb].anchor == -1) {
213 XPnts[pointb].
anchor = point;
216 else if (XPnts[pointb].anchor > 0) {
219 dx = XPnts[XPnts[pointb].
anchor].
x - XPnts[pointb].
x;
220 dy = XPnts[XPnts[pointb].
anchor].
y - XPnts[pointb].
y;
221 dist2_a = dx * dx + dy * dy;
224 if (dist2 < dist2_a) {
225 XPnts[pointb].
anchor = point;
235 nsnapped = ncreated = 0;
237 for (line_idx = 0; line_idx < List_lines->n_values; line_idx++) {
238 int v, spoint, anchor;
241 G_percent(line_idx, List_lines->n_values, 2);
243 line = List_lines->value[line_idx];
251 if (Points->n_points >= aindex) {
252 aindex = Points->n_points;
253 Index = (
int *)G_realloc(Index, aindex *
sizeof(
int));
257 for (v = 0; v < Points->n_points; v++) {
271 spoint = List->value[0];
272 anchor = XPnts[spoint].
anchor;
275 Points->x[v] = XPnts[anchor].
x;
276 Points->y[v] = XPnts[anchor].
y;
290 for (v = 0; v < Points->n_points - 1; v++) {
292 double x1, x2, y1, y2, xmin, xmax, ymin, ymax;
294 G_debug(3,
" segment = %d end anchors : %d %d", v, Index[v],
298 x2 = Points->x[v + 1];
300 y2 = Points->y[v + 1];
334 G_debug(3,
" %d points in box", List->n_values);
338 for (i = 0; i < List->n_values; i++) {
341 spoint = List->value[i];
342 G_debug(4,
" spoint = %d anchor = %d", spoint,
343 XPnts[spoint].anchor);
345 if (spoint == Index[v] || spoint == Index[v + 1])
347 if (XPnts[spoint].anchor > 0)
353 XPnts[spoint].y, 0, x1, y1, 0,
357 G_debug(4,
" distance = %lf", sqrt(dist2));
359 if (dist2 <= thresh2) {
360 G_debug(4,
" anchor in thresh, along = %lf", along);
364 New = (
NEW *) G_realloc(New, anew *
sizeof(
NEW));
366 New[nnew].
anchor = spoint;
367 New[nnew].
along = along;
371 G_debug(3,
" nnew = %d", nnew);
375 qsort(New,
sizeof(
char) * nnew,
sizeof(
NEW), sort_new);
377 for (i = 0; i < nnew; i++) {
389 v = Points->n_points - 1;
394 if (NPoints->n_points > 1 || ltype &
GV_LINES) {
405 G_percent(line_idx, List_lines->n_values, 2);
417 static int sort_new(
const void *pa,
const void *pb)
443 struct Map_info *Err)
445 int line, nlines, ltype;
453 for (line = 1; line <= nlines; line++) {