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
00253 if ((n = histogram->num) <= 1) return 1;
00254
00255 list=histogram->list;
00256
00257
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
00264 qsort (list, n, sizeof(LIST), &cmp);
00265
00266
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
00308 if ((n = histogram->num) <= 1) return 1;
00309
00310 list=histogram->list;
00311
00312
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 }