~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to vector/v.digit/vertex.c

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <stdio.h>
2
 
#include <unistd.h>
3
 
#include <math.h>
4
 
#include <grass/gis.h>
5
 
#include <grass/Vect.h>
6
 
#include <grass/dbmi.h>
7
 
#include <grass/raster.h>
8
 
#include <grass/display.h>
9
 
#include <grass/colors.h>
10
 
#include <grass/form.h>
11
 
#include <grass/glocale.h>
12
 
#include "global.h"
13
 
#include "proto.h"
14
 
 
15
 
/* Split line */
16
 
struct split_line
17
 
{
18
 
    struct line_pnts *Points, *NPoints;
19
 
    struct line_cats *Cats;
20
 
    int last_line, last_seg;
21
 
    double thresh;
22
 
    double xo, yo;
23
 
};
24
 
 
25
 
int split_line_begin(void *closure)
26
 
{
27
 
    struct split_line *sl = closure;
28
 
 
29
 
    G_debug(2, "split_line()");
30
 
 
31
 
    sl->Points = Vect_new_line_struct();
32
 
    sl->NPoints = Vect_new_line_struct();
33
 
    sl->Cats = Vect_new_cats_struct();
34
 
 
35
 
    i_prompt(_("Split line:"));
36
 
    i_prompt_buttons(_("Select"), "", _("Quit tool"));
37
 
 
38
 
    sl->thresh = get_thresh();
39
 
    G_debug(2, "thresh = %f", sl->thresh);
40
 
 
41
 
    sl->last_line = 0;
42
 
    sl->last_seg = 0;
43
 
 
44
 
    set_mode(MOUSE_POINT);
45
 
 
46
 
    return 0;
47
 
}
48
 
 
49
 
int split_line_update(void *closure, int sxn, int syn, int button)
50
 
{
51
 
    struct split_line *sl = closure;
52
 
    double x = D_d_to_u_col(sxn);
53
 
    double y = D_d_to_u_row(syn);
54
 
 
55
 
    if (sl->last_line == 0) {
56
 
        i_prompt_buttons(_("Select"), "", _("Quit tool"));
57
 
    }
58
 
 
59
 
    if (sl->last_line > 0) {
60
 
        display_line(sl->last_line, SYMB_DEFAULT, 1);
61
 
    }
62
 
 
63
 
    G_debug(3, "button = %d x = %d = %f y = %d = %f", button, sxn, x, syn, y);
64
 
 
65
 
    if (button == 3)
66
 
        return 1;
67
 
 
68
 
    if (button == 1) {          /* Select / split */
69
 
        int line;
70
 
 
71
 
        if (sl->last_line > 0) {        /* Line is already selected -> split */
72
 
            int node1, node2, type, np, i;
73
 
 
74
 
            display_line(sl->last_line, SYMB_BACKGROUND, 1);
75
 
            Vect_get_line_nodes(&Map, sl->last_line, &node1, &node2);
76
 
            display_node(node1, SYMB_BACKGROUND, 1);
77
 
            display_node(node2, SYMB_BACKGROUND, 1);
78
 
            symb_set_driver_color(SYMB_BACKGROUND);
79
 
            display_icon(sl->xo, sl->yo, G_ICON_CROSS, 0, 10, 1);
80
 
 
81
 
            /* Read and delete old */
82
 
            type = Vect_read_line(&Map, sl->Points, sl->Cats, sl->last_line);
83
 
            Vect_delete_line(&Map, sl->last_line);
84
 
            updated_lines_and_nodes_erase_refresh_display();
85
 
            np = sl->Points->n_points;
86
 
 
87
 
            /* First part */
88
 
            Vect_reset_line(sl->NPoints);
89
 
            for (i = 0; i < sl->last_seg; i++) {
90
 
                Vect_append_point(sl->NPoints, sl->Points->x[i],
91
 
                                  sl->Points->y[i], sl->Points->z[i]);
92
 
            }
93
 
            Vect_append_point(sl->NPoints, sl->xo, sl->yo, 0);
94
 
            Vect_write_line(&Map, type, sl->NPoints, sl->Cats);
95
 
            updated_lines_and_nodes_erase_refresh_display();
96
 
 
97
 
            /* Second part */
98
 
            Vect_reset_line(sl->NPoints);
99
 
            Vect_append_point(sl->NPoints, sl->xo, sl->yo, 0);
100
 
            for (i = sl->last_seg; i < np; i++) {
101
 
                Vect_append_point(sl->NPoints, sl->Points->x[i],
102
 
                                  sl->Points->y[i], sl->Points->z[i]);
103
 
            }
104
 
            Vect_write_line(&Map, type, sl->NPoints, sl->Cats);
105
 
            updated_lines_and_nodes_erase_refresh_display();
106
 
 
107
 
            sl->last_line = 0;
108
 
        }
109
 
 
110
 
        /* Select vertex */
111
 
        line =
112
 
            Vect_find_line(&Map, x, y, 0, GV_LINE | GV_BOUNDARY, sl->thresh,
113
 
                           0, 0);
114
 
        G_debug(2, "line found = %d", line);
115
 
 
116
 
        /* Display new selected line if any */
117
 
        if (line > 0) {
118
 
            int seg;
119
 
 
120
 
            /* Find the nearest vertex on the line */
121
 
            Vect_read_line(&Map, sl->Points, NULL, line);
122
 
            seg =
123
 
                Vect_line_distance(sl->Points, x, y, 0, 0, &sl->xo, &sl->yo,
124
 
                                   NULL, NULL, NULL, NULL);
125
 
 
126
 
            display_line(line, SYMB_HIGHLIGHT, 1);
127
 
            symb_set_driver_color(SYMB_HIGHLIGHT);
128
 
            display_icon(sl->xo, sl->yo, G_ICON_CROSS, 0, 10, 1);
129
 
 
130
 
            i_prompt_buttons(_("Confirm and select next"), _("Unselect"),
131
 
                             _("Quit tool"));
132
 
            sl->last_line = line;
133
 
            sl->last_seg = seg;
134
 
        }
135
 
    }
136
 
    if (button == 2) {          /* Unselect */
137
 
        if (sl->last_line > 0) {
138
 
            symb_set_driver_color(SYMB_BACKGROUND);
139
 
            display_icon(sl->xo, sl->yo, G_ICON_CROSS, 0, 10, 1);
140
 
            sl->last_line = 0;
141
 
        }
142
 
    }
143
 
 
144
 
    return 0;
145
 
}
146
 
 
147
 
int split_line_end(void *closure)
148
 
{
149
 
    struct split_line *sl = closure;
150
 
 
151
 
    if (sl->last_line == 0) {
152
 
        i_prompt_buttons(_("Select"), "", _("Quit tool"));
153
 
    }
154
 
 
155
 
    if (sl->last_line > 0) {
156
 
        display_line(sl->last_line, SYMB_DEFAULT, 1);
157
 
    }
158
 
 
159
 
    if (sl->last_line > 0) {
160
 
        symb_set_driver_color(SYMB_BACKGROUND);
161
 
        display_icon(sl->xo, sl->yo, G_ICON_CROSS, 0, 10, 1);
162
 
    }
163
 
 
164
 
    i_prompt("");
165
 
    i_prompt_buttons("", "", "");
166
 
    i_coor(COOR_NULL, COOR_NULL);
167
 
 
168
 
    G_debug(3, "split_line(): End");
169
 
 
170
 
    return 1;
171
 
}
172
 
 
173
 
void split_line(void)
174
 
{
175
 
    static struct split_line sl;
176
 
 
177
 
    set_tool(split_line_begin, split_line_update, split_line_end, &sl);
178
 
}
179
 
 
180
 
/* Remove line vertex */
181
 
struct rm_vertex
182
 
{
183
 
    struct line_pnts *Points;
184
 
    struct line_cats *Cats;
185
 
    int last_line, last_seg;
186
 
    double thresh;
187
 
    double xo, yo;
188
 
};
189
 
 
190
 
int rm_vertex_begin(void *closure)
191
 
{
192
 
    struct rm_vertex *rv = closure;
193
 
 
194
 
    G_debug(2, "remove_vertex()");
195
 
 
196
 
    rv->Points = Vect_new_line_struct();
197
 
    rv->Cats = Vect_new_cats_struct();
198
 
 
199
 
    i_prompt(_("Remove vertex:"));
200
 
    i_prompt_buttons(_("Select vertex"), "", _("Quit tool"));
201
 
 
202
 
    rv->thresh = get_thresh();
203
 
    G_debug(2, "thresh = %f", rv->thresh);
204
 
 
205
 
    rv->last_line = 0;
206
 
    rv->last_seg = 0;
207
 
 
208
 
    set_mode(MOUSE_POINT);
209
 
 
210
 
    return 0;
211
 
}
212
 
 
213
 
int rm_vertex_update(void *closure, int sxn, int syn, int button)
214
 
{
215
 
    struct rm_vertex *rv = closure;
216
 
    double x = D_d_to_u_col(sxn);
217
 
    double y = D_d_to_u_row(syn);
218
 
 
219
 
    if (rv->last_line == 0) {
220
 
        i_prompt_buttons(_("Select vertex"), "", _("Quit tool"));
221
 
    }
222
 
 
223
 
    if (rv->last_line > 0) {
224
 
        display_line(rv->last_line, SYMB_DEFAULT, 1);
225
 
    }
226
 
 
227
 
    G_debug(3, "button = %d x = %d = %f y = %d = %f", button, sxn, x, syn, y);
228
 
 
229
 
    if (button == 3)
230
 
        return 1;
231
 
 
232
 
    if (button == 1) {          /* Select / new location */
233
 
        int line;
234
 
 
235
 
        if (rv->last_line > 0) {        /* Line is already selected */
236
 
            int node1, node2, type, np, i;
237
 
 
238
 
            display_line(rv->last_line, SYMB_BACKGROUND, 1);
239
 
            Vect_get_line_nodes(&Map, rv->last_line, &node1, &node2);
240
 
            display_node(node1, SYMB_BACKGROUND, 1);
241
 
            display_node(node2, SYMB_BACKGROUND, 1);
242
 
            symb_set_driver_color(SYMB_BACKGROUND);
243
 
            display_icon(rv->xo, rv->yo, G_ICON_BOX, 0, 10, 1);
244
 
 
245
 
            type = Vect_read_line(&Map, rv->Points, rv->Cats, rv->last_line);
246
 
            np = rv->Points->n_points;
247
 
            
248
 
            /* Lines should have at least two vertices (start and end node). */
249
 
            if (np < 3 && Vect_line_alive(&Map, rv->last_line)) {
250
 
                Vect_delete_line(&Map, rv->last_line);
251
 
                for (i = 0; i < rv->Cats->n_cats; i++) {
252
 
                    check_record(rv->Cats->field[i], rv->Cats->cat[i]);
253
 
                }
254
 
            } else {
255
 
                for (i = rv->last_seg; i < np - 1; i++) {
256
 
                    rv->Points->x[i] = rv->Points->x[i + 1];
257
 
                    rv->Points->y[i] = rv->Points->y[i + 1];
258
 
                    rv->Points->z[i] = rv->Points->z[i + 1];
259
 
                }
260
 
                rv->Points->n_points--;
261
 
                Vect_rewrite_line(&Map, rv->last_line, type, rv->Points,
262
 
                              rv->Cats);
263
 
            }
264
 
            updated_lines_and_nodes_erase_refresh_display();
265
 
            rv->last_line = 0;
266
 
        }
267
 
 
268
 
        /* Select vertex */
269
 
        line =
270
 
            Vect_find_line(&Map, x, y, 0, GV_LINE | GV_BOUNDARY, rv->thresh,
271
 
                           0, 0);
272
 
        G_debug(2, "line found = %d", line);
273
 
 
274
 
        /* Display new selected line if any */
275
 
        if (line > 0) {
276
 
            int seg;
277
 
            double dist;
278
 
 
279
 
            /* Find the nearest vertex on the line */
280
 
            Vect_read_line(&Map, rv->Points, NULL, line);
281
 
            seg =
282
 
                Vect_line_distance(rv->Points, x, y, 0, 0, &rv->xo, &rv->yo,
283
 
                                   NULL, NULL, NULL, NULL);
284
 
 
285
 
            dist =
286
 
                Vect_points_distance(rv->xo, rv->yo, 0,
287
 
                                     rv->Points->x[seg - 1],
288
 
                                     rv->Points->y[seg - 1], 0, 0);
289
 
 
290
 
            if (dist <
291
 
                Vect_points_distance(rv->xo, rv->yo, 0, rv->Points->x[seg],
292
 
                                     rv->Points->y[seg], 0, 0)) {
293
 
                seg -= 1;
294
 
            }
295
 
 
296
 
            rv->xo = rv->Points->x[seg];
297
 
            rv->yo = rv->Points->y[seg];
298
 
 
299
 
            display_line(line, SYMB_HIGHLIGHT, 1);
300
 
            symb_set_driver_color(SYMB_HIGHLIGHT);
301
 
            display_icon(rv->xo, rv->yo, G_ICON_BOX, 0, 10, 1);
302
 
 
303
 
            i_prompt_buttons(_("Confirm and select next"), _("Unselect"),
304
 
                             _("Quit tool"));
305
 
            rv->last_line = line;
306
 
            rv->last_seg = seg;
307
 
        }
308
 
    }
309
 
    if (button == 2) {          /* Unselect */
310
 
        if (rv->last_line > 0) {
311
 
            symb_set_driver_color(SYMB_BACKGROUND);
312
 
            display_icon(rv->xo, rv->yo, G_ICON_BOX, 0, 10, 1);
313
 
            rv->last_line = 0;
314
 
        }
315
 
    }
316
 
 
317
 
    return 0;
318
 
}
319
 
 
320
 
int rm_vertex_end(void *closure)
321
 
{
322
 
    struct rm_vertex *rv = closure;
323
 
 
324
 
    if (rv->last_line == 0) {
325
 
        i_prompt_buttons(_("Select vertex"), "", _("Quit tool"));
326
 
    }
327
 
 
328
 
    if (rv->last_line > 0) {
329
 
        display_line(rv->last_line, SYMB_DEFAULT, 1);
330
 
    }
331
 
 
332
 
    if (rv->last_line > 0) {
333
 
        symb_set_driver_color(SYMB_BACKGROUND);
334
 
        display_icon(rv->xo, rv->yo, G_ICON_BOX, 0, 10, 1);
335
 
    }
336
 
 
337
 
    i_prompt("");
338
 
    i_prompt_buttons("", "", "");
339
 
    i_coor(COOR_NULL, COOR_NULL);
340
 
 
341
 
    G_debug(3, "remove_vertex(): End");
342
 
 
343
 
    return 1;
344
 
}
345
 
 
346
 
void rm_vertex(void)
347
 
{
348
 
    static struct rm_vertex rv;
349
 
 
350
 
    set_tool(rm_vertex_begin, rm_vertex_update, rm_vertex_end, &rv);
351
 
}
352
 
 
353
 
/* Add new vertex to line */
354
 
struct add_vertex
355
 
{
356
 
    struct line_pnts *Points;
357
 
    struct line_cats *Cats;
358
 
    int last_line, last_seg;
359
 
    int do_snap;
360
 
    double thresh;
361
 
};
362
 
 
363
 
int add_vertex_begin(void *closure)
364
 
{
365
 
    struct add_vertex *av = closure;
366
 
 
367
 
    G_debug(2, "add_vertex()");
368
 
 
369
 
    av->Points = Vect_new_line_struct();
370
 
    av->Cats = Vect_new_cats_struct();
371
 
 
372
 
    i_prompt(_("Add vertex:"));
373
 
    i_prompt_buttons(_("Select"), "", _("Quit tool"));
374
 
 
375
 
    av->thresh = get_thresh();
376
 
    G_debug(2, "thresh = %f", av->thresh);
377
 
 
378
 
    av->last_line = 0;
379
 
    av->last_seg = 0;
380
 
    av->do_snap = 0;
381
 
 
382
 
    set_mode(MOUSE_POINT);
383
 
 
384
 
    return 0;
385
 
}
386
 
 
387
 
int add_vertex_update(void *closure, int sxn, int syn, int button)
388
 
{
389
 
    struct add_vertex *av = closure;
390
 
    double x = D_d_to_u_col(sxn);
391
 
    double y = D_d_to_u_row(syn);
392
 
 
393
 
    G_debug(3, "button = %d x = %d = %f y = %d = %f", button, sxn, x, syn, y);
394
 
 
395
 
    if (button == 3)
396
 
        return 1;
397
 
 
398
 
    if (av->last_line > 0) {
399
 
        display_line(av->last_line, SYMB_DEFAULT, 1);
400
 
    }
401
 
 
402
 
    if (button == 1) {          /* Select line segment */
403
 
        if (av->last_line == 0) {       /* Select line */
404
 
            int line = Vect_find_line(&Map, x, y, 0, GV_LINE | GV_BOUNDARY,
405
 
                                      av->thresh, 0, 0);
406
 
 
407
 
            G_debug(2, "line found = %d", line);
408
 
 
409
 
            /* Display new selected line if any */
410
 
            if (line > 0) {
411
 
                int seg, len;
412
 
                double xo, yo, px, py;
413
 
                double dist;
414
 
 
415
 
                display_line(line, SYMB_HIGHLIGHT, 1);
416
 
 
417
 
                /* Find the nearest vertex on the line */
418
 
                Vect_read_line(&Map, av->Points, NULL, line);
419
 
                seg =
420
 
                    Vect_line_distance(av->Points, x, y, 0, 0, &px, &py, NULL,
421
 
                                       NULL, NULL, NULL);
422
 
 
423
 
                G_debug(3, "seg = %d", seg);
424
 
 
425
 
                xo = (av->Points->x[seg - 1] + av->Points->x[seg]) / 2;
426
 
                yo = (av->Points->y[seg - 1] + av->Points->y[seg]) / 2;
427
 
 
428
 
                /* If close to first or last point insert before / after the line. 
429
 
                 * 'close' is here < 1/4 of segment length */
430
 
                av->do_snap = 0;
431
 
                if (seg == 1) {
432
 
                    dist =
433
 
                        Vect_points_distance(px, py, 0, av->Points->x[0],
434
 
                                             av->Points->y[0], 0, 0);
435
 
                    len =
436
 
                        Vect_points_distance(av->Points->x[0],
437
 
                                             av->Points->y[0], 0,
438
 
                                             av->Points->x[1],
439
 
                                             av->Points->y[1], 0, 0);
440
 
 
441
 
                    if (dist < len / 4) {
442
 
                        seg = 0;
443
 
                        xo = av->Points->x[0];
444
 
                        yo = av->Points->y[0];
445
 
                        av->do_snap = 1;
446
 
                    }
447
 
                }
448
 
 
449
 
                if (seg == av->Points->n_points - 1) {
450
 
                    int np = av->Points->n_points;
451
 
                    double dist =
452
 
                        Vect_points_distance(px, py, 0, av->Points->x[np - 1],
453
 
                                             av->Points->y[np - 1], 0, 0);
454
 
                    int len = Vect_points_distance(av->Points->x[np - 2],
455
 
                                                   av->Points->y[np - 2], 0,
456
 
                                                   av->Points->x[np - 1],
457
 
                                                   av->Points->y[np - 1], 0,
458
 
                                                   0);
459
 
 
460
 
                    if (dist < len / 4) {
461
 
                        seg++;
462
 
                        xo = av->Points->x[np - 1];
463
 
                        yo = av->Points->y[np - 1];
464
 
                        av->do_snap = 1;
465
 
                    }
466
 
                }
467
 
                G_debug(3, "seg 2 = %d", seg);
468
 
 
469
 
                set_location(D_u_to_d_col(xo), D_u_to_d_row(yo));
470
 
 
471
 
                i_prompt_buttons(_("New vertex"), _("Unselect"), _("Quit tool"));
472
 
                av->last_line = line;
473
 
                av->last_seg = seg;
474
 
            }
475
 
        }
476
 
        else {                  /* Line is already selected -> new vertex */
477
 
            int node1, node2, type, np, i;
478
 
 
479
 
            if (av->do_snap) {
480
 
                snap(&x, &y);
481
 
            }
482
 
            display_line(av->last_line, SYMB_BACKGROUND, 1);
483
 
            Vect_get_line_nodes(&Map, av->last_line, &node1, &node2);
484
 
            display_node(node1, SYMB_BACKGROUND, 1);
485
 
            display_node(node2, SYMB_BACKGROUND, 1);
486
 
 
487
 
            type = Vect_read_line(&Map, av->Points, av->Cats, av->last_line);
488
 
            np = av->Points->n_points;
489
 
            /* insert vertex */
490
 
            Vect_append_point(av->Points, 0, 0, 0);
491
 
            for (i = np; i > av->last_seg; i--) {
492
 
                av->Points->x[i] = av->Points->x[i - 1];
493
 
                av->Points->y[i] = av->Points->y[i - 1];
494
 
                av->Points->z[i] = av->Points->z[i - 1];
495
 
            }
496
 
 
497
 
            av->Points->x[av->last_seg] = x;
498
 
            av->Points->y[av->last_seg] = y;
499
 
            av->Points->z[av->last_seg] = 0;
500
 
 
501
 
            Vect_rewrite_line(&Map, av->last_line, type, av->Points,
502
 
                              av->Cats);
503
 
            updated_lines_and_nodes_erase_refresh_display();
504
 
            av->last_line = 0;
505
 
        }
506
 
 
507
 
    }
508
 
 
509
 
    if (button == 2) {          /* Unselect */
510
 
        if (av->last_line > 0) {
511
 
            av->last_line = 0;
512
 
        }
513
 
    }
514
 
 
515
 
    if (av->last_line == 0) {
516
 
        i_prompt_buttons(_("Select"), "", _("Quit tool"));
517
 
        set_mode(MOUSE_POINT);
518
 
    }
519
 
    else
520
 
        set_mode(MOUSE_LINE);
521
 
 
522
 
    return 0;
523
 
}
524
 
 
525
 
int add_vertex_end(void *closure)
526
 
{
527
 
    struct add_vertex *av = closure;
528
 
 
529
 
    if (av->last_line > 0) {
530
 
        display_line(av->last_line, SYMB_DEFAULT, 1);
531
 
    }
532
 
 
533
 
    i_prompt("");
534
 
    i_prompt_buttons("", "", "");
535
 
    i_coor(COOR_NULL, COOR_NULL);
536
 
 
537
 
    G_debug(3, "add_vertex(): End");
538
 
 
539
 
    return 1;
540
 
}
541
 
 
542
 
void add_vertex(void)
543
 
{
544
 
    static struct add_vertex av;
545
 
 
546
 
    set_tool(add_vertex_begin, add_vertex_update, add_vertex_end, &av);
547
 
}
548
 
 
549
 
/* Move vertex */
550
 
 
551
 
struct move_vertex
552
 
{
553
 
    struct line_pnts *Points;
554
 
    struct line_cats *Cats;
555
 
    int last_line, last_seg;
556
 
    double thresh;
557
 
    double xo, yo;
558
 
};
559
 
 
560
 
int move_vertex_begin(void *closure)
561
 
{
562
 
    struct move_vertex *mv = closure;
563
 
 
564
 
    G_debug(2, "move_vertex()");
565
 
 
566
 
    mv->Points = Vect_new_line_struct();
567
 
    mv->Cats = Vect_new_cats_struct();
568
 
 
569
 
    i_prompt(_("Move vertex:"));
570
 
    i_prompt_buttons(_("Select"), "", _("Quit tool"));
571
 
 
572
 
    mv->thresh = get_thresh();
573
 
    G_debug(2, "thresh = %f", mv->thresh);
574
 
 
575
 
    mv->last_line = 0;
576
 
    mv->last_seg = 0;
577
 
 
578
 
    set_mode(MOUSE_POINT);
579
 
 
580
 
    return 0;
581
 
}
582
 
 
583
 
int move_vertex_update(void *closure, int sxn, int syn, int button)
584
 
{
585
 
    struct move_vertex *mv = closure;
586
 
    double x = D_d_to_u_col(sxn);
587
 
    double y = D_d_to_u_row(syn);
588
 
 
589
 
    G_debug(3, "button = %d x = %d = %f y = %d = %f", button, sxn, x, syn, y);
590
 
 
591
 
    if (mv->last_line > 0) {
592
 
        display_line(mv->last_line, SYMB_DEFAULT, 1);
593
 
    }
594
 
 
595
 
    if (button == 3)
596
 
        return 1;
597
 
 
598
 
    if (button == 1) {          /* Select / new location */
599
 
        if (mv->last_line == 0) {       /* Select line */
600
 
            int line = Vect_find_line(&Map, x, y, 0, GV_POINT | GV_LINE | GV_BOUNDARY,
601
 
                                      mv->thresh, 0, 0);
602
 
 
603
 
            G_debug(2, "line found = %d", line);
604
 
 
605
 
            /* Display new selected line if any */
606
 
            if (line > 0) {
607
 
                int seg;
608
 
                double xo, yo, dist;
609
 
 
610
 
                display_line(line, SYMB_HIGHLIGHT, 1);
611
 
 
612
 
                /* Find the nearest vertex on the line */
613
 
                Vect_read_line(&Map, mv->Points, NULL, line);
614
 
                seg =
615
 
                    Vect_line_distance(mv->Points, x, y, 0, 0, &xo, &yo, NULL,
616
 
                                       NULL, NULL, NULL);
617
 
 
618
 
                dist =
619
 
                    Vect_points_distance(xo, yo, 0, mv->Points->x[seg - 1],
620
 
                                         mv->Points->y[seg - 1], 0, 0);
621
 
 
622
 
                if (dist <
623
 
                    Vect_points_distance(xo, yo, 0, mv->Points->x[seg],
624
 
                                         mv->Points->y[seg], 0, 0)) {
625
 
                    seg -= 1;
626
 
                }
627
 
 
628
 
                mv->xo = mv->Points->x[seg];
629
 
                mv->yo = mv->Points->y[seg];
630
 
                set_location(D_u_to_d_col(mv->xo), D_u_to_d_row(mv->yo));
631
 
 
632
 
 
633
 
                i_prompt_buttons(_("New location"), _("Unselect"), _("Quit tool"));
634
 
                mv->last_line = line;
635
 
                mv->last_seg = seg;
636
 
            }
637
 
        }
638
 
        else {                  /* Line is already selected */
639
 
            int type, node1, node2;
640
 
 
641
 
            if (mv->last_seg == 0 || mv->last_seg == mv->Points->n_points - 1) {
642
 
                snap(&x, &y);
643
 
            }
644
 
            display_line(mv->last_line, SYMB_BACKGROUND, 1);
645
 
            Vect_get_line_nodes(&Map, mv->last_line, &node1, &node2);
646
 
            display_node(node1, SYMB_BACKGROUND, 1);
647
 
            display_node(node2, SYMB_BACKGROUND, 1);
648
 
 
649
 
            type = Vect_read_line(&Map, mv->Points, mv->Cats, mv->last_line);
650
 
            mv->Points->x[mv->last_seg] =
651
 
                mv->Points->x[mv->last_seg] + x - mv->xo;
652
 
            mv->Points->y[mv->last_seg] =
653
 
                mv->Points->y[mv->last_seg] + y - mv->yo;
654
 
            Vect_rewrite_line(&Map, mv->last_line, type, mv->Points,
655
 
                              mv->Cats);
656
 
            updated_lines_and_nodes_erase_refresh_display();
657
 
            mv->last_line = 0;
658
 
        }
659
 
 
660
 
    }
661
 
    if (button == 2) {          /* Unselect */
662
 
        if (mv->last_line > 0) {
663
 
            mv->last_line = 0;
664
 
        }
665
 
    }
666
 
 
667
 
 
668
 
    if (mv->last_line == 0) {
669
 
        i_prompt_buttons(_("Select"), "", _("Quit tool"));
670
 
        set_mode(MOUSE_POINT);
671
 
    }
672
 
    else
673
 
        set_mode(MOUSE_LINE);
674
 
 
675
 
    return 0;
676
 
}
677
 
 
678
 
int move_vertex_end(void *closure)
679
 
{
680
 
    struct move_vertex *mv = closure;
681
 
 
682
 
    if (mv->last_line > 0) {
683
 
        display_line(mv->last_line, SYMB_DEFAULT, 1);
684
 
    }
685
 
 
686
 
    i_prompt("");
687
 
    i_prompt_buttons("", "", "");
688
 
    i_coor(COOR_NULL, COOR_NULL);
689
 
 
690
 
    G_debug(3, "move_vertex(): End");
691
 
 
692
 
    return 1;
693
 
}
694
 
 
695
 
void move_vertex(void)
696
 
{
697
 
    static struct move_vertex mv;
698
 
 
699
 
    set_tool(move_vertex_begin, move_vertex_update, move_vertex_end, &mv);
700
 
}