GRASS Programmer's Manual
6.4.2(2012)
|
00001 #include <grass/gis.h> 00002 #include <grass/glocale.h> 00003 #include <stdlib.h> 00004 00005 00006 #define LIST struct Histogram_list 00007 00008 static FILE *fopen_histogram_new(const char *); 00009 static int cmp(const void *, const void *); 00010 static int cmp_count(const void *, const void *); 00011 00012 00022 int G_init_histogram(struct Histogram *histogram) 00023 { 00024 histogram->num = 0; 00025 histogram->list = NULL; 00026 00027 return 0; 00028 } 00029 00030 00046 int G_read_histogram(const char *name, const char *mapset, 00047 struct Histogram *histogram) 00048 { 00049 FILE *fd = NULL; 00050 long cat; 00051 long count; 00052 char buf[200]; 00053 00054 G_init_histogram(histogram); 00055 00056 if (G_find_file2_misc("cell_misc", "histogram", name, mapset) == NULL) { 00057 G_warning(_("Histogram for [%s in %s] missing (run r.support)"), name, 00058 mapset); 00059 00060 return 0; 00061 } 00062 00063 fd = G_fopen_old_misc("cell_misc", "histogram", name, mapset); 00064 if (!fd) { 00065 G_warning(_("Can't read histogram for [%s in %s]"), name, mapset); 00066 00067 return -1; 00068 } 00069 00070 while (fgets(buf, sizeof buf, fd)) { 00071 if (sscanf(buf, "%ld:%ld", &cat, &count) != 2) { 00072 G_free_histogram(histogram); 00073 fclose(fd); 00074 G_warning(_("Invalid histogram file for [%s in %s]"), name, 00075 mapset); 00076 00077 return -1; 00078 } 00079 G_extend_histogram((CELL) cat, count, histogram); 00080 } 00081 fclose(fd); 00082 00083 if (histogram->num == 0) { 00084 G_warning(_("Invalid histogram file for [%s in %s]"), name, mapset); 00085 00086 return -1; 00087 } 00088 00089 G_sort_histogram(histogram); 00090 00091 return 1; 00092 } 00093 00094 00105 int G_write_histogram(const char *name, const struct Histogram *histogram) 00106 { 00107 FILE *fd; 00108 int n; 00109 LIST *list; 00110 00111 fd = fopen_histogram_new(name); 00112 if (fd == NULL) 00113 return -1; 00114 00115 list = histogram->list; 00116 for (n = 0; n < histogram->num; n++) { 00117 if (list[n].count) 00118 fprintf(fd, "%ld:%ld\n", (long)list[n].cat, list[n].count); 00119 } 00120 fclose(fd); 00121 00122 return 1; 00123 } 00124 00125 00135 int G_write_histogram_cs(const char *name, struct Cell_stats *statf) 00136 { 00137 FILE *fd; 00138 CELL cat; 00139 long count; 00140 00141 fd = fopen_histogram_new(name); 00142 if (fd == NULL) 00143 return -1; 00144 00145 G_rewind_cell_stats(statf); 00146 while (G_next_cell_stat(&cat, &count, statf)) { 00147 if (count > 0) 00148 fprintf(fd, "%ld:%ld\n", (long)cat, count); 00149 } 00150 fclose(fd); 00151 00152 return 1; 00153 } 00154 00155 00163 int G_make_histogram_cs(struct Cell_stats *statf, struct Histogram *histogram) 00164 { 00165 CELL cat; 00166 long count; 00167 00168 G_init_histogram(histogram); 00169 G_rewind_cell_stats(statf); 00170 while (G_next_cell_stat(&cat, &count, statf)) 00171 G_add_histogram(cat, count, histogram); 00172 00173 G_sort_histogram(histogram); 00174 00175 return 0; 00176 } 00177 00178 00188 int G_get_histogram_num(const struct Histogram *histogram) 00189 { 00190 return histogram->num; 00191 } 00192 00193 00201 CELL G_get_histogram_cat(int n, const struct Histogram * histogram) 00202 { 00203 if (n < 0 || n >= histogram->num) 00204 return 0; 00205 00206 return histogram->list[n].cat; 00207 } 00208 00209 00218 long G_get_histogram_count(int n, const struct Histogram *histogram) 00219 { 00220 if (n < 0 || n >= histogram->num) 00221 return 0; 00222 00223 return histogram->list[n].count; 00224 } 00225 00226 00234 int G_free_histogram(struct Histogram *histogram) 00235 { 00236 if (histogram->num > 0) 00237 G_free(histogram->list); 00238 histogram->num = 0; 00239 histogram->list = NULL; 00240 00241 return 1; 00242 } 00243 00253 int G_sort_histogram(struct Histogram *histogram) 00254 { 00255 int a, b, n; 00256 LIST *list; 00257 00258 /* if histogram only has 1 entry, nothing to do */ 00259 if ((n = histogram->num) <= 1) 00260 return 1; 00261 00262 list = histogram->list; 00263 00264 /* quick check to see if sorting needed */ 00265 for (a = 1; a < n; a++) 00266 if (list[a - 1].cat >= list[a].cat) 00267 break; 00268 if (a >= n) 00269 return 1; 00270 00271 /* sort */ 00272 qsort(list, n, sizeof(LIST), &cmp); 00273 00274 /* sum duplicate entries */ 00275 for (a = 0, b = 1; b < n; b++) { 00276 if (list[a].cat != list[b].cat) { 00277 a++; 00278 list[a].count = list[b].count; 00279 list[a].cat = list[b].cat; 00280 } 00281 else { 00282 list[a].count += list[b].count; 00283 } 00284 } 00285 histogram->num = a + 1; 00286 00287 return 0; 00288 } 00289 00290 00291 static int cmp(const void *aa, const void *bb) 00292 { 00293 const LIST *a = aa, *b = bb; 00294 00295 if (a->cat < b->cat) 00296 return -1; 00297 00298 if (a->cat > b->cat) 00299 return 1; 00300 00301 return 0; 00302 } 00303 00313 int G_sort_histogram_by_count(struct Histogram *histogram) 00314 { 00315 int n; 00316 LIST *list; 00317 00318 /* if histogram only has 1 entry, nothing to do */ 00319 if ((n = histogram->num) <= 1) 00320 return 1; 00321 00322 list = histogram->list; 00323 00324 /* sort */ 00325 qsort(list, n, sizeof(LIST), &cmp_count); 00326 00327 return 0; 00328 } 00329 00330 00331 static int cmp_count(const void *aa, const void *bb) 00332 { 00333 const LIST *a = aa, *b = bb; 00334 00335 if (a->count < b->count) 00336 return -1; 00337 00338 if (a->count > b->count) 00339 return 1; 00340 00341 if (a->cat < b->cat) 00342 return -1; 00343 00344 if (a->cat > b->cat) 00345 return 1; 00346 00347 return 0; 00348 } 00349 00350 static FILE *fopen_histogram_new(const char *name) 00351 { 00352 FILE *fd; 00353 00354 fd = G_fopen_new_misc("cell_misc", "histogram", name); 00355 if (fd == NULL) 00356 G_warning(_("can't create histogram for [%s in %s]"), name, 00357 G_mapset()); 00358 00359 return fd; 00360 } 00361 00362 00371 int G_remove_histogram(const char *name) 00372 { 00373 G_remove_misc("cell_misc", "histogram", name); 00374 00375 return 0; 00376 } 00377 00378 00389 int G_add_histogram(CELL cat, long count, struct Histogram *histogram) 00390 { 00391 int i; 00392 00393 for (i = 0; i < histogram->num; i++) { 00394 if (histogram->list[i].cat == cat) { 00395 histogram->list[i].count += count; 00396 return 1; 00397 } 00398 } 00399 G_extend_histogram(cat, count, histogram); 00400 00401 return 0; 00402 } 00403 00404 00415 int G_set_histogram(CELL cat, long count, struct Histogram *histogram) 00416 { 00417 int i; 00418 00419 for (i = 0; i < histogram->num; i++) { 00420 if (histogram->list[i].cat == cat) { 00421 histogram->list[i].count = count; 00422 return 1; 00423 } 00424 } 00425 G_extend_histogram(cat, count, histogram); 00426 00427 return 0; 00428 } 00429 00430 00439 int G_extend_histogram(CELL cat, long count, struct Histogram *histogram) 00440 { 00441 histogram->num++; 00442 histogram->list = 00443 (LIST *) G_realloc((char *)histogram->list, 00444 histogram->num * sizeof(LIST)); 00445 histogram->list[histogram->num - 1].cat = cat; 00446 histogram->list[histogram->num - 1].count = count; 00447 00448 return 0; 00449 } 00450 00451 00458 int G_zero_histogram(struct Histogram *histogram) 00459 { 00460 int i; 00461 00462 for (i = 0; i < histogram->num; i++) 00463 histogram->list[i].count = 0; 00464 00465 return 0; 00466 }