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 #define LIST struct Histogram_list
00006 
00007 static FILE *fopen_histogram_new(char *);
00008 static int cmp(const void *, const void *);
00009 static int cmp_count (const void *, const void *);
00010 
00020 int G_init_histogram (
00021     struct Histogram *histogram)
00022 {
00023     histogram->num = 0;
00024     histogram->list = NULL;
00025 
00026     return 0;
00027 }
00028 
00044 int G_read_histogram (
00045     char *name,char *mapset,
00046     struct Histogram *histogram)
00047 {
00048     FILE *fd;
00049     long cat;
00050     long count;
00051     char buf[200];
00052 
00053     fd = NULL;
00054 
00055     G_init_histogram (histogram);
00056 
00057     sprintf (buf,"cell_misc/%s", name);
00058     if (G_find_file (buf, "histogram", mapset) == NULL)
00059     {
00060         sprintf (buf, _("Histogram for [%s in %s] missing (run r.support)"), name, mapset);
00061         G_warning (buf);
00062         return 0;
00063     }
00064     fd = G_fopen_old (buf, "histogram", mapset);
00065     if (!fd)
00066     {
00067         sprintf (buf, _("Can't read histogram for [%s in %s]"), name, mapset);
00068         G_warning (buf);
00069         return -1;
00070     }
00071 
00072     while (fgets (buf, sizeof buf, fd))
00073     {
00074         if (sscanf (buf, "%ld:%ld", &cat, &count) != 2)
00075         {
00076             G_free_histogram (histogram);
00077             fclose (fd);
00078             sprintf (buf,_("Invalid histogram file for [%s in %s]"), name, mapset);
00079             G_warning (buf);
00080             return -1;
00081         }
00082         G_extend_histogram ((CELL)cat, count, histogram);
00083     }
00084     fclose (fd);
00085     if (histogram->num == 0)
00086     {
00087         sprintf (buf,_("Invalid histogram file for [%s in %s]"), name, mapset);
00088         G_warning (buf);
00089         return -1;
00090     }
00091 
00092     G_sort_histogram  (histogram);
00093     return 1;
00094 }
00095 
00106 int G_write_histogram (
00107     char *name,
00108     struct Histogram *histogram)
00109 {
00110     FILE *fd;
00111     int n;
00112     LIST *list;
00113 
00114     fd = fopen_histogram_new (name);
00115     if (fd == NULL)
00116         return -1;
00117 
00118     list = histogram->list;
00119     for (n = 0; n < histogram->num; n++)
00120     {
00121         if (list[n].count)
00122             fprintf (fd, "%ld:%ld\n", (long)list[n].cat, list[n].count);
00123     }
00124     fclose (fd);
00125     return 1;
00126 }
00127 
00136 int G_write_histogram_cs (
00137     char *name,
00138     struct Cell_stats *statf)
00139 {
00140     FILE *fd;
00141     CELL cat;
00142     long count;
00143 
00144     fd = fopen_histogram_new (name);
00145     if (fd == NULL)
00146         return -1;
00147     G_rewind_cell_stats (statf);
00148     while (G_next_cell_stat (&cat, &count, statf))
00149     {
00150         if (count > 0)
00151             fprintf (fd, "%ld:%ld\n", (long)cat, count);
00152     }
00153     fclose (fd);
00154     return 1;
00155 }
00156 
00163 int G_make_histogram_cs (
00164     struct Cell_stats *statf,
00165     struct Histogram *histogram)
00166 {
00167     CELL cat;
00168     long count;
00169 
00170     G_init_histogram (histogram);
00171     G_rewind_cell_stats (statf);
00172     while (G_next_cell_stat (&cat, &count, statf))
00173         G_add_histogram (cat, count, histogram);
00174     G_sort_histogram (histogram);
00175 
00176     return 0;
00177 }
00178 
00188 int G_get_histogram_num (struct Histogram *histogram)
00189 {
00190     return histogram->num;
00191 }
00192 
00200 CELL G_get_histogram_cat (int n, struct Histogram *histogram)
00201 {
00202     if (n < 0 || n >= histogram->num)
00203         return 0;
00204     return histogram->list[n].cat;
00205 }
00206 
00215 long G_get_histogram_count (int n, struct Histogram *histogram)
00216 {
00217     if (n < 0 || n >= histogram->num)
00218         return 0;
00219     return histogram->list[n].count;
00220 }
00221 
00229 int G_free_histogram ( struct Histogram *histogram)
00230 {
00231     if (histogram->num > 0)
00232         G_free (histogram->list);
00233     histogram->num = 0;
00234     histogram->list = NULL;
00235     return 1;
00236 }
00237 
00247 int G_sort_histogram ( struct Histogram *histogram)
00248 {
00249     int a,b,n;
00250     LIST *list;
00251 
00252 /* if histogram only has 1 entry, nothing to do */
00253     if ((n = histogram->num) <= 1) return 1;
00254 
00255     list=histogram->list;
00256 
00257 /* quick check to see if sorting needed */
00258     for (a = 1; a < n; a++)
00259         if (list[a-1].cat >= list[a].cat)
00260             break;
00261     if (a >= n) return 1;
00262 
00263 /* sort */
00264     qsort (list, n, sizeof(LIST), &cmp);
00265 
00266 /* sum duplicate entries */
00267     for (a = 0, b = 1; b < n; b++)
00268         if (list[a].cat != list[b].cat)
00269         {
00270             a++;
00271             list[a].count = list[b].count;
00272             list[a].cat   = list[b].cat;
00273         }
00274         else
00275         {
00276             list[a].count += list[b].count;
00277         }
00278     histogram->num = a + 1;
00279 
00280     return 0;
00281 }
00282 
00283 static int cmp(const void *aa, const void *bb)
00284 {
00285     const LIST *a = aa, *b = bb;
00286     if (a->cat < b->cat)
00287         return -1;
00288     if (a->cat > b->cat)
00289         return 1;
00290     return 0;
00291 }
00292 
00302 int G_sort_histogram_by_count ( struct Histogram *histogram)
00303 {
00304     int n;
00305     LIST *list;
00306 
00307 /* if histogram only has 1 entry, nothing to do */
00308     if ((n = histogram->num) <= 1) return 1;
00309 
00310     list=histogram->list;
00311 
00312 /* sort */
00313     qsort (list, n, sizeof(LIST), &cmp_count);
00314 
00315     return 0;
00316 }
00317 
00318 static int cmp_count(const void *aa, const void *bb)
00319 {
00320     const LIST *a = aa, *b = bb;
00321     if(a->count < b->count)
00322         return -1;
00323     if(a->count > b->count)
00324         return 1;
00325     if(a->cat < b->cat)
00326         return -1;
00327     if(a->cat > b->cat)
00328         return 1;
00329     return 0;
00330 }
00331 
00332 static FILE *fopen_histogram_new ( char *name)
00333 {
00334     char buf[100];
00335     FILE *fd;
00336 
00337     sprintf (buf,"cell_misc/%s", name);
00338     fd = G_fopen_new (buf, "histogram");
00339     if (fd == NULL)
00340     {
00341         sprintf (buf,_("can't create histogram for [%s in %s]"), name, G_mapset());
00342         G_warning (buf);
00343     }
00344     return fd;
00345 }
00346 
00355 int G_remove_histogram (char *name)
00356 
00357 {
00358     char buf[100];
00359     sprintf (buf,"cell_misc/%s", name);
00360     G_remove(buf, "histogram");
00361 
00362     return 0;
00363 }
00364 
00375 int G_add_histogram (
00376     CELL cat,
00377     long count,
00378     struct Histogram *histogram)
00379 {
00380     int i;
00381 
00382     for (i = 0 ; i < histogram->num; i++)
00383         if (histogram->list[i].cat == cat)
00384         {
00385             histogram->list[i].count += count;
00386             return 1;
00387         }
00388 
00389     G_extend_histogram (cat, count, histogram);
00390 
00391     return 0;
00392 }
00393 
00404 int G_set_histogram (
00405     CELL cat,
00406     long count,
00407     struct Histogram *histogram)
00408 {
00409     int i;
00410 
00411     for (i = 0 ; i < histogram->num; i++)
00412         if (histogram->list[i].cat == cat)
00413         {
00414             histogram->list[i].count = count;
00415             return 1;
00416         }
00417 
00418     G_extend_histogram (cat, count, histogram);
00419 
00420     return 0;
00421 }
00422 
00431 int G_extend_histogram (
00432     CELL cat,
00433     long count,
00434     struct Histogram *histogram)
00435 {
00436     histogram->num++;
00437     histogram->list =
00438         (LIST *) G_realloc ((char *) histogram->list, histogram->num*sizeof (LIST));
00439     histogram->list[histogram->num-1].cat = cat;
00440     histogram->list[histogram->num-1].count = count;
00441 
00442     return 0;
00443 }
00444 
00451 int G_zero_histogram ( struct Histogram *histogram)
00452 {
00453     int i;
00454 
00455     for (i = 0; i < histogram->num; i++)
00456         histogram->list[i].count = 0;
00457 
00458     return 0;
00459 }

Generated on Wed Dec 19 14:59:06 2007 for GRASS by  doxygen 1.5.4