1 #include <math.h>
2 #include <grass/dbmi.h>
3 #include <grass/glocale.h>
4 #include "global.h"
5 
report(void)6 int report(void)
7 {
8     int i;
9     char left[20], right[20];
10 
11     if (!options.print && !(options.option == O_COUNT ||
12                             options.option == O_LENGTH ||
13                             options.option == O_AREA)) {
14         G_warning(_("No totals for selected option"));
15         return 0;
16     }
17 
18     switch (options.option) {
19     case O_CAT:
20 	if (G_verbose() > G_verbose_min())
21 	    fprintf(stdout, "cat\n");
22 	for (i = 0; i < vstat.rcat; i++)
23 	    fprintf(stdout, "%d\n", Values[i].cat);
24 	break;
25 
26     case O_COUNT:
27         if (options.print) {
28             if (G_verbose() > G_verbose_min())
29                 fprintf(stdout, "cat%scount\n", options.fs);
30             for (i = 0; i < vstat.rcat; i++)
31                 fprintf(stdout, "%d%s%d\n", Values[i].cat, options.fs, Values[i].count1);
32         }
33 	if (options.total) {
34 	    int sum = 0;
35 
36 	    for (i = 0; i < vstat.rcat; i++) {
37 		sum += Values[i].count1;
38 	    }
39 	    fprintf(stdout, "total count%s%d\n", options.fs, sum);
40 	}
41 	break;
42 
43     case O_AREA:
44         if (options.print) {
45             if (G_verbose() > G_verbose_min())
46                 fprintf(stdout, "cat%sarea\n", options.fs);
47             for (i = 0; i < vstat.rcat; i++)
48                 fprintf(stdout, "%d%s%.15g\n", Values[i].cat, options.fs, Values[i].d1);
49         }
50 	if (options.total) {
51 	    double sum = 0.0;
52 
53 	    for (i = 0; i < vstat.rcat; i++) {
54 		sum += Values[i].d1;
55 	    }
56 	    fprintf(stdout, "total area%s%.15g\n", options.fs, sum);
57 	}
58 	break;
59 
60     case O_COMPACT:
61 	/* perimeter / perimeter of equivalent circle
62 	 *   perimeter of equivalent circle: 2.0 * sqrt(M_PI * area) */
63 	if (G_verbose() > G_verbose_min())
64 	    fprintf(stdout, "cat%scompact\n", options.fs);
65 	for (i = 0; i < vstat.rcat; i++) {
66 	    Values[i].d1 = Values[i].d2 / (2.0 * sqrt(M_PI * Values[i].d1));
67 	    fprintf(stdout, "%d%s%.15g\n", Values[i].cat, options.fs, Values[i].d1);
68 	}
69 	break;
70 
71     case O_FD:
72 	/* 2.0 * log(perimeter) / log(area)
73 	 * this is neither
74 	 *   log(perimeter) / log(perimeter of equivalent circle)
75 	 *   perimeter of equivalent circle: 2 * sqrt(M_PI * area)
76 	 * nor
77 	 *   log(area of equivalent circle) / log(area)
78 	 *   area of equivalent circle: (perimeter / (2 * sqrt(M_PI))^2
79 	 *
80 	 * avoid division by zero:
81 	 * 2.0 * log(1 + perimeter) / log(1 + area) */
82 	if (G_verbose() > G_verbose_min())
83 	    fprintf(stdout, "cat%sfd\n", options.fs);
84 	for (i = 0; i < vstat.rcat; i++) {
85 	    if (Values[i].d1 == 1) /* log(1) == 0 */
86 		Values[i].d1 += 0.000001;
87 	    Values[i].d1 = 2.0 * log(Values[i].d2) / log(Values[i].d1);
88 	    fprintf(stdout, "%d%s%.15g\n", Values[i].cat, options.fs, Values[i].d1);
89 	}
90 	break;
91 
92     case O_PERIMETER:
93 	if (G_verbose() > G_verbose_min())
94 	    fprintf(stdout, "cat%sperimeter\n", options.fs);
95 	for (i = 0; i < vstat.rcat; i++)
96 	    fprintf(stdout, "%d%s%.15g\n", Values[i].cat, options.fs, Values[i].d1);
97 	break;
98 
99     case O_BBOX:
100 	if (G_verbose() > G_verbose_min())
101 	    fprintf(stdout, "cat%sN%sS%sE%sW\n", options.fs, options.fs, options.fs,options.fs);
102 	for (i = 0; i < vstat.rcat; i++) {
103 	    fprintf(stdout, "%d%s%.15g%s%.15g%s%.15g%s%.15g\n", Values[i].cat, options.fs,
104 	    Values[i].d1, options.fs, Values[i].d2, options.fs, Values[i].d3,
105 	    options.fs, Values[i].d4);
106 	}
107 	break;
108 
109     case O_LENGTH:
110         if (options.print) {
111             if (G_verbose() > G_verbose_min())
112                 fprintf(stdout, "cat%slength\n", options.fs);
113             for (i = 0; i < vstat.rcat; i++)
114                 fprintf(stdout, "%d%s%.15g\n", Values[i].cat, options.fs, Values[i].d1);
115         }
116 	if (options.total) {
117 	    double sum = 0.0;
118 
119 	    for (i = 0; i < vstat.rcat; i++) {
120 		sum += Values[i].d1;
121 	    }
122 	    fprintf(stdout, "total length%s%.15g\n", options.fs, sum);
123 	}
124 	break;
125     case O_SLOPE:
126 	if (G_verbose() > G_verbose_min())
127 	    fprintf(stdout, "cat%sslope\n", options.fs);
128 	for (i = 0; i < vstat.rcat; i++)
129 	    fprintf(stdout, "%d%s%.15g\n", Values[i].cat, options.fs, Values[i].d1);
130 
131 
132 	break;
133     case O_SINUOUS:
134 	if (G_verbose() > G_verbose_min())
135 	    fprintf(stdout, "cat%ssinuous\n", options.fs);
136 	for (i = 0; i < vstat.rcat; i++)
137 	    fprintf(stdout, "%d%s%.15g\n", Values[i].cat, options.fs, Values[i].d1);
138 	break;
139     case O_COOR:
140     case O_START:
141     case O_END:
142 	if (G_verbose() > G_verbose_min())
143 	    fprintf(stdout, "cat%sx%sy%sz\n", options.fs, options.fs, options.fs);
144 	for (i = 0; i < vstat.rcat; i++) {
145 	    if (Values[i].count1 == 1)
146 		fprintf(stdout, "%d%s%.15g%s%.15g%s%.15g\n", Values[i].cat, options.fs,
147 			Values[i].d1, options.fs, Values[i].d2, options.fs, Values[i].d3);
148 	}
149 	break;
150 
151     case O_SIDES:
152 	if (G_verbose() > G_verbose_min())
153 	    fprintf(stdout, "cat%sleft%sright\n", options.fs, options.fs);
154 	for (i = 0; i < vstat.rcat; i++) {
155 	    if (Values[i].count1 == 1) {
156 		if (Values[i].i1 >= 0)
157 		    sprintf(left, "%d", Values[i].i1);
158 		else
159 		    sprintf(left, "-1");	/* NULL, no area/cat */
160 	    }
161 	    else if (Values[i].count1 > 1) {
162 		sprintf(left, "-");
163 	    }
164 	    else {		/* Values[i].count1 == 0 */
165 		/* It can be OK if the category is assigned to an element
166 		   type which is not GV_BOUNDARY */
167 		/* -> TODO: print only if there is boundary with that cat */
168 		sprintf(left, "-");
169 	    }
170 
171 	    if (Values[i].count2 == 1) {
172 		if (Values[i].i2 >= 0)
173 		    sprintf(right, "%d", Values[i].i2);
174 		else
175 		    sprintf(right, "-1");	/* NULL, no area/cat */
176 	    }
177 	    else if (Values[i].count2 > 1) {
178 		sprintf(right, "-");
179 	    }
180 	    else {		/* Values[i].count1 == 0 */
181 		sprintf(right, "-");
182 	    }
183 
184 	    fprintf(stdout, "%d%s%s%s%s\n", Values[i].cat, options.fs, left, options.fs, right);
185 	}
186 	break;
187 
188     case O_QUERY:
189 	if (G_verbose() > G_verbose_min())
190 	    fprintf(stdout, "cat%squery\n", options.fs);
191 	for (i = 0; i < vstat.rcat; i++) {
192 	    if (Values[i].null) {
193 		fprintf(stdout, "%d|-\n", Values[i].cat);
194 	    }
195 	    else {
196 		switch (vstat.qtype) {
197 		case (DB_C_TYPE_INT):
198 		    fprintf(stdout, "%d%s%d\n", Values[i].cat, options.fs, Values[i].i1);
199 		    break;
200 		case (DB_C_TYPE_DOUBLE):
201 		    fprintf(stdout, "%d%s%15g\n", Values[i].cat, options.fs, Values[i].d1);
202 		    break;
203 		case (DB_C_TYPE_STRING):
204 		    fprintf(stdout, "%d%s%s\n", Values[i].cat, options.fs, Values[i].str1);
205 		    break;
206 		}
207 	    }
208 	}
209 	break;
210     case O_AZIMUTH:
211 	if (G_verbose() > G_verbose_min())
212 	    fprintf(stdout, "cat%sazimuth\n", options.fs);
213 	for (i = 0; i < vstat.rcat; i++)
214 		fprintf(stdout, "%d%s%.15g\n", Values[i].cat, options.fs, Values[i].d1);
215 	break;
216     }
217 
218     return 0;
219 }
220 
print_stat(void)221 int print_stat(void)
222 {
223     if (vstat.rcat > 0) {
224 	int rcat_report;
225 	if (find_cat(-1, 0) != -1)
226 	    rcat_report = vstat.rcat - 1;
227 	else
228 	    rcat_report = vstat.rcat;
229 
230 	G_message(_("%d categories read from vector map (layer %d)"),
231 		  rcat_report, options.field); /* don't report cat -1 */
232     }
233     if (vstat.select > 0)
234 	G_message(_("%d records selected from table (layer %d)"),
235 		  vstat.select, options.qfield);
236     if (vstat.exist > 0)
237 	G_message(_("%d categories read from vector map exist in selection from table"),
238 		  vstat.exist);
239     if (vstat.notexist > 0)
240 	G_message(_("%d categories read from vector map don't exist in selection from table"),
241 		  vstat.notexist);
242     G_message(_("%d records updated/inserted (layer %d)"),
243 	      vstat.update, options.field);
244     if (vstat.error > 0)
245 	G_message(_("%d update/insert errors (layer %d)"),
246 		  vstat.error, options.field);
247     if (vstat.dupl > 0)
248 	G_message(_("%d categories with more points (coordinates not loaded)"),
249 		  vstat.dupl);
250 
251     return 0;
252 }
253