GRASS Programmer's Manual 6.4.1(2011)
histogram.c
Go to the documentation of this file.
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 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines