1 #include <stdlib.h>
2 #include <grass/gis.h>
3 #include <grass/vector.h>
4 #include <grass/glocale.h>
5 #include "proto.h"
6 
7 static int find_node(struct Map_info *, int, int);
8 
9 static void field2n(struct line_cats *, int);
10 
11 /**
12  * \brief Create network arcs (edge) based on given point vector map (nodes)
13  *
14  * \param file input file defining arcs
15  * \param Points input vector point map
16  * \param Out output vector map
17  * \param afield arcs layer
18  * \param nfield nodes layer
19  *
20  * \return number of new arcs
21  */
create_arcs(FILE * file,struct Map_info * Pnts,struct Map_info * Out,int afield,int nfield)22 int create_arcs(FILE * file, struct Map_info *Pnts,
23 		struct Map_info *Out, int afield, int nfield)
24 {
25     char buff[1024];
26     int lcat, fcat, tcat;
27     int node1, node2;
28     int narcs;
29 
30     struct line_pnts *points, *points2;
31     struct line_cats *cats;
32 
33     points = Vect_new_line_struct();
34     points2 = Vect_new_line_struct();
35     points = Vect_new_line_struct();
36     cats = Vect_new_cats_struct();
37 
38     narcs = 0;
39 
40     while (G_getl2(buff, sizeof(buff) - 1, file)) {
41 	if (sscanf(buff, "%d%d%d", &lcat, &fcat, &tcat) != 3)
42 	    G_fatal_error(_("Error reading file: '%s'"), buff);
43 
44 	node1 = find_node(Pnts, afield, fcat);
45 	node2 = find_node(Pnts, afield, tcat);
46 
47 	if (node1 < 1 || node2 < 1) {
48 	    G_warning(_("Skipping arc %d"), lcat);
49 	    continue;
50 	}
51 
52 	/* geometry */
53 	Vect_read_line(Pnts, points, cats, node1);
54 	field2n(cats, nfield);
55 	Vect_write_line(Out, GV_POINT, points, cats);
56 	Vect_read_line(Pnts, points2, cats, node2);
57 	field2n(cats, nfield);
58 	Vect_write_line(Out, GV_POINT, points2, cats);
59 	Vect_append_points(points, points2, GV_FORWARD);
60 
61 	/* category */
62 	Vect_reset_cats(cats);
63 	Vect_cat_set(cats, afield, lcat);
64 	Vect_write_line(Out, GV_LINE, points, cats);
65 
66 	narcs++;
67     }
68 
69     Vect_destroy_line_struct(points);
70     Vect_destroy_cats_struct(cats);
71 
72     return narcs;
73 }
74 
find_node(struct Map_info * Pnts,int field,int cat)75 int find_node(struct Map_info *Pnts, int field, int cat)
76 {
77     static struct ilist *list;
78 
79     if (!list)
80 	list = Vect_new_list();
81 
82     /* find start node */
83     Vect_cidx_find_all(Pnts, field, GV_POINT, cat, list);
84     if (list->n_values < 1) {
85 	G_warning(_("No point with category %d found"), cat);
86 	return 0;
87     }
88     if (list->n_values > 1) {
89 	G_warning(_("More points with category %d found"), cat);
90 	return 0;
91     }
92 
93     return list->value[0];
94 }
95 
field2n(struct line_cats * cats,int nfield)96 void field2n(struct line_cats *cats, int nfield)
97 {
98     int n;
99 
100     for (n = 0; n < cats->n_cats; n++) {
101 	cats->field[n] = nfield;
102     }
103 }
104