#include #include #include #include #include #include "gis.h" #include "options.h" #include "dhist.h" static char * mk_command (const char *fmt, int nargs, ...) { /* asprintf() would solve this problem better */ size_t len = strlen(fmt) + 1; char *cmd; va_list ap, copy; va_start (ap, nargs); va_copy (copy, ap); while (nargs--) { cmd = va_arg (ap, char *); len += strlen (cmd); } cmd = G_malloc (len); vsprintf (cmd, fmt, copy); va_end (ap); va_end (copy); return cmd; } int get_stats( char *mapname, char *mapset, struct stat_list *dist_stats, /* linked list of stats */ int quiet) { char buf[1024]; /* input buffer for reading stats */ int done = 0; char *tempfile; /* temp file name */ char *fullname; char *cmd; FILE *fd; /* temp file pointer */ long int cat; /* a category value */ long int stat; /* a category stat value */ struct stat_node *ptr = NULL; int first; /* write stats to a temp file */ tempfile = G_tempfile(); fullname = G_fully_qualified_name(mapname,mapset); is_fp = G_raster_map_is_fp(mapname,mapset); if(is_fp) { if(cat_ranges) { if(G_read_raster_cats(mapname, mapset, &cats) < 0) G_fatal_error("Can't read category file"); if(G_number_of_raster_cats(&cats) <=0) { G_warning("There are no labeled cats, using nsteps argument"); cat_ranges = 0; } } if(G_read_fp_range (map_name, mapset, &fp_range) <= 0) G_fatal_error("Can't read frange file"); } if(cat_ranges) { cmd = mk_command ("r.stats -Cr%s%s '%s' > '%s'\n", 4, type==COUNT?"c":"a", quiet?"q":"", fullname, tempfile); } else { sprintf (buf, "%d", nsteps); cmd = mk_command ("r.stats -r%s%s '%s' nsteps=%s > '%s'\n", 5, type==COUNT?"c":"a", quiet?"q":"", fullname, buf, tempfile); } if(system(cmd)) G_fatal_error ("%s: ERROR running r.stats", G_program_name()); /* open temp file and read the stats into a linked list */ fd = fopen(tempfile,"r"); if (fd == NULL) { perror ("opening r.stats output file"); G_fatal_error ("unable to continue."); } dist_stats->ptr = NULL; dist_stats->count = 0; dist_stats->sumstat = 0; first=1; while (!done) { if (fgets(buf,sizeof(buf),fd) != NULL) { /* WARNING!!!!!! * this will be very wrong if type!=COUNT * since the stat prodcued by r.stats will be a floating point value * possibly less than 1 (shapiro) */ if (sscanf(buf,"* %ld", &stat) == 1) { dist_stats->null_stat = stat; if (stat>dist_stats->maxstat && nodata) dist_stats->maxstat = stat; if (statminstat && nodata) dist_stats->minstat = stat; if(nodata) dist_stats->sumstat += stat; } else if (sscanf(buf,"%ld %ld",&cat,&stat) == 2) { /* count stats */ dist_stats->count++; /* sum stats */ dist_stats->sumstat += stat; /* a max or a min stat? */ if (first) { dist_stats->maxstat = stat; dist_stats->minstat = stat; dist_stats->maxcat = cat; dist_stats->mincat = cat; first=0; } if (stat>dist_stats->maxstat) dist_stats->maxstat = stat; if (statminstat) dist_stats->minstat = stat; /* a max or a min cat? */ if (cat>dist_stats->maxcat) dist_stats->maxcat = cat; if (catmincat) dist_stats->mincat = cat; /* put it in the list */ if (dist_stats->ptr == NULL) { /* first in list */ dist_stats->ptr=(struct stat_node *) G_malloc(sizeof(struct stat_node)); dist_stats->ptr->cat = cat; dist_stats->ptr->stat = stat; dist_stats->ptr->next = NULL; ptr = dist_stats->ptr; } else { ptr->next=(struct stat_node *) G_malloc(sizeof(struct stat_node)); ptr->next->cat = cat; ptr->next->stat = stat; ptr->next->next = NULL; /* mod: shapiro */ ptr = ptr->next; } } } else done = 1; } fclose (fd); unlink (tempfile); return 0; }