1 #include <stdlib.h>
2 #include <grass/gis.h>
3 #include <grass/vector.h>
4 #include <grass/glocale.h>
5 #include "proto.h"
6 
report(struct Map_info * In,int afield,int nfield,int action)7 int report(struct Map_info *In, int afield, int nfield, int action)
8 {
9     int i, j, line, nlines, ltype, node, nnodes;
10     int cat_line, cat_node[2];
11 
12     struct line_cats *Cats, *Cats2;
13     struct line_pnts *Points;
14     struct bound_box box;
15 
16     double x, y, z;
17 
18     Cats = Vect_new_cats_struct();
19     Cats2 = Vect_new_cats_struct();
20     Points = Vect_new_line_struct();
21 
22     nlines = Vect_get_num_lines(In);
23 
24     if (action == TOOL_REPORT) {
25 	struct boxlist *List;
26 
27 	List = Vect_new_boxlist(0);
28 
29 	/* For all lines find categories for points on nodes */
30 	for (i = 1; i <= nlines; i++) {
31 	    ltype = Vect_read_line(In, NULL, Cats, i);
32 	    if (!(ltype & GV_LINES))
33 		continue;
34 
35 	    cat_line = 0;
36 	    if (!Vect_cat_get(Cats, afield, &cat_line))
37 		G_warning(_("Line %d has no category"), i);
38 
39 	    cat_node[0] = cat_node[1] = -1;
40 	    for (j = 0; j < 2; j++) {
41 		if (j == 0)
42 		    Vect_get_line_nodes(In, i, &node, NULL);
43 		else
44 		    Vect_get_line_nodes(In, i, NULL, &node);
45 
46 		Vect_get_node_coor(In, node, &x, &y, &z);
47 
48 		box.E = box.W = x;
49 		box.N = box.S = y;
50 		box.T = box.B = z;
51 		Vect_select_lines_by_box(In, &box, GV_POINT, List);
52 
53 		nnodes = List->n_values;
54 		if (nnodes > 0) {
55 		    line = List->id[nnodes - 1]; /* last in list */
56 		    Vect_read_line(In, NULL, Cats, line);
57 		    Vect_cat_get(Cats, nfield, &(cat_node[j]));
58 		}
59 
60 		if (nnodes == 0) {
61 		    /* this is ok, not every node needs to be
62 		     * represented by a point */
63 		    G_debug(4, "No point here: %g %g %.g line category: %d",
64 			      x, y, z, cat_line);
65 		}
66 		else if (nnodes > 1)
67 		    G_warning(_("%d points found: %g %g %g line category: %d"),
68 			      nnodes, x, y, z, cat_line);
69 	    }
70 	    fprintf(stdout, "%d %d %d\n", cat_line, cat_node[0], cat_node[1]);
71 	}
72     }
73     else {			/* node report */
74 	int elem, nelem, type, k, l;
75 	struct ilist *List;
76 
77 	List = Vect_new_list();
78 
79 
80 	for (i = 1; i <= nlines; i++) {
81 
82 	    if (Vect_get_line_type(In, i) != GV_POINT)
83 		continue;
84 
85 	    Vect_read_line(In, Points, Cats, i);
86 
87 	    box.E = box.W = Points->x[0];
88 	    box.N = box.S = Points->y[0];
89 	    box.T = box.B = Points->z[0];
90 
91 	    nnodes = Vect_select_nodes_by_box(In, &box, List);
92 
93 	    if (nnodes > 1) {
94 		G_warning(_("Duplicate nodes at x=%g y=%g z=%g "),
95 			  Points->x[0], Points->y[0], Points->z[0]);
96 	    }
97 	    if (nnodes > 0) {
98 		node = List->value[0];
99 		nelem = Vect_get_node_n_lines(In, node);
100 
101 		/* Loop through all cats of point */
102 		for (j = 0; j < Cats->n_cats; j++) {
103 		    if (Cats->field[j] == nfield) {
104 			int count = 0;
105 
106 			fprintf(stdout, "%d ", Cats->cat[j]);
107 
108 			/* Loop through all lines */
109 			for (k = 0; k < nelem; k++) {
110 			    elem = abs(Vect_get_node_line(In, node, k));
111 			    type = Vect_read_line(In, NULL, Cats2, elem);
112 			    if (!(type & GV_LINES))
113 				continue;
114 
115 			    /* Loop through all cats of line */
116 			    for (l = 0; l < Cats2->n_cats; l++) {
117 				if (Cats2->field[l] == afield) {
118 				    if (count > 0)
119 					fprintf(stdout, ",");
120 
121 				    fprintf(stdout, "%d", Cats2->cat[l]);
122 				    count++;
123 				}
124 			    }
125 			}
126 			fprintf(stdout, "\n");
127 		    }
128 		}
129 	    }
130 	}
131     }
132 
133     return 0;
134 }
135