GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
histogram.c
Go to the documentation of this file.
1 #include <grass/gis.h>
2 #include <grass/glocale.h>
3 #include <stdlib.h>
4 
5 
6 #define LIST struct Histogram_list
7 
8 static FILE *fopen_histogram_new(const char *);
9 static int cmp(const void *, const void *);
10 static int cmp_count(const void *, const void *);
11 
12 
22 int G_init_histogram(struct Histogram *histogram)
23 {
24  histogram->num = 0;
25  histogram->list = NULL;
26 
27  return 0;
28 }
29 
30 
46 int G_read_histogram(const char *name, const char *mapset,
47  struct Histogram *histogram)
48 {
49  FILE *fd = NULL;
50  long cat;
51  long count;
52  char buf[200];
53 
54  G_init_histogram(histogram);
55 
56  if (G_find_file2_misc("cell_misc", "histogram", name, mapset) == NULL) {
57  G_warning(_("Histogram for [%s in %s] missing (run r.support)"), name,
58  mapset);
59 
60  return 0;
61  }
62 
63  fd = G_fopen_old_misc("cell_misc", "histogram", name, mapset);
64  if (!fd) {
65  G_warning(_("Can't read histogram for [%s in %s]"), name, mapset);
66 
67  return -1;
68  }
69 
70  while (fgets(buf, sizeof buf, fd)) {
71  if (sscanf(buf, "%ld:%ld", &cat, &count) != 2) {
72  G_free_histogram(histogram);
73  fclose(fd);
74  G_warning(_("Invalid histogram file for [%s in %s]"), name,
75  mapset);
76 
77  return -1;
78  }
79  G_extend_histogram((CELL) cat, count, histogram);
80  }
81  fclose(fd);
82 
83  if (histogram->num == 0) {
84  G_warning(_("Invalid histogram file for [%s in %s]"), name, mapset);
85 
86  return -1;
87  }
88 
89  G_sort_histogram(histogram);
90 
91  return 1;
92 }
93 
94 
105 int G_write_histogram(const char *name, const struct Histogram *histogram)
106 {
107  FILE *fd;
108  int n;
109  LIST *list;
110 
111  fd = fopen_histogram_new(name);
112  if (fd == NULL)
113  return -1;
114 
115  list = histogram->list;
116  for (n = 0; n < histogram->num; n++) {
117  if (list[n].count)
118  fprintf(fd, "%ld:%ld\n", (long)list[n].cat, list[n].count);
119  }
120  fclose(fd);
121 
122  return 1;
123 }
124 
125 
135 int G_write_histogram_cs(const char *name, struct Cell_stats *statf)
136 {
137  FILE *fd;
138  CELL cat;
139  long count;
140 
141  fd = fopen_histogram_new(name);
142  if (fd == NULL)
143  return -1;
144 
145  G_rewind_cell_stats(statf);
146  while (G_next_cell_stat(&cat, &count, statf)) {
147  if (count > 0)
148  fprintf(fd, "%ld:%ld\n", (long)cat, count);
149  }
150  fclose(fd);
151 
152  return 1;
153 }
154 
155 
163 int G_make_histogram_cs(struct Cell_stats *statf, struct Histogram *histogram)
164 {
165  CELL cat;
166  long count;
167 
168  G_init_histogram(histogram);
169  G_rewind_cell_stats(statf);
170  while (G_next_cell_stat(&cat, &count, statf))
171  G_add_histogram(cat, count, histogram);
172 
173  G_sort_histogram(histogram);
174 
175  return 0;
176 }
177 
178 
188 int G_get_histogram_num(const struct Histogram *histogram)
189 {
190  return histogram->num;
191 }
192 
193 
201 CELL G_get_histogram_cat(int n, const struct Histogram * histogram)
202 {
203  if (n < 0 || n >= histogram->num)
204  return 0;
205 
206  return histogram->list[n].cat;
207 }
208 
209 
218 long G_get_histogram_count(int n, const struct Histogram *histogram)
219 {
220  if (n < 0 || n >= histogram->num)
221  return 0;
222 
223  return histogram->list[n].count;
224 }
225 
226 
234 int G_free_histogram(struct Histogram *histogram)
235 {
236  if (histogram->num > 0)
237  G_free(histogram->list);
238  histogram->num = 0;
239  histogram->list = NULL;
240 
241  return 1;
242 }
243 
253 int G_sort_histogram(struct Histogram *histogram)
254 {
255  int a, b, n;
256  LIST *list;
257 
258  /* if histogram only has 1 entry, nothing to do */
259  if ((n = histogram->num) <= 1)
260  return 1;
261 
262  list = histogram->list;
263 
264  /* quick check to see if sorting needed */
265  for (a = 1; a < n; a++)
266  if (list[a - 1].cat >= list[a].cat)
267  break;
268  if (a >= n)
269  return 1;
270 
271  /* sort */
272  qsort(list, n, sizeof(LIST), &cmp);
273 
274  /* sum duplicate entries */
275  for (a = 0, b = 1; b < n; b++) {
276  if (list[a].cat != list[b].cat) {
277  a++;
278  list[a].count = list[b].count;
279  list[a].cat = list[b].cat;
280  }
281  else {
282  list[a].count += list[b].count;
283  }
284  }
285  histogram->num = a + 1;
286 
287  return 0;
288 }
289 
290 
291 static int cmp(const void *aa, const void *bb)
292 {
293  const LIST *a = aa, *b = bb;
294 
295  if (a->cat < b->cat)
296  return -1;
297 
298  if (a->cat > b->cat)
299  return 1;
300 
301  return 0;
302 }
303 
313 int G_sort_histogram_by_count(struct Histogram *histogram)
314 {
315  int n;
316  LIST *list;
317 
318  /* if histogram only has 1 entry, nothing to do */
319  if ((n = histogram->num) <= 1)
320  return 1;
321 
322  list = histogram->list;
323 
324  /* sort */
325  qsort(list, n, sizeof(LIST), &cmp_count);
326 
327  return 0;
328 }
329 
330 
331 static int cmp_count(const void *aa, const void *bb)
332 {
333  const LIST *a = aa, *b = bb;
334 
335  if (a->count < b->count)
336  return -1;
337 
338  if (a->count > b->count)
339  return 1;
340 
341  if (a->cat < b->cat)
342  return -1;
343 
344  if (a->cat > b->cat)
345  return 1;
346 
347  return 0;
348 }
349 
350 static FILE *fopen_histogram_new(const char *name)
351 {
352  FILE *fd;
353 
354  fd = G_fopen_new_misc("cell_misc", "histogram", name);
355  if (fd == NULL)
356  G_warning(_("can't create histogram for [%s in %s]"), name,
357  G_mapset());
358 
359  return fd;
360 }
361 
362 
371 int G_remove_histogram(const char *name)
372 {
373  G_remove_misc("cell_misc", "histogram", name);
374 
375  return 0;
376 }
377 
378 
389 int G_add_histogram(CELL cat, long count, struct Histogram *histogram)
390 {
391  int i;
392 
393  for (i = 0; i < histogram->num; i++) {
394  if (histogram->list[i].cat == cat) {
395  histogram->list[i].count += count;
396  return 1;
397  }
398  }
399  G_extend_histogram(cat, count, histogram);
400 
401  return 0;
402 }
403 
404 
415 int G_set_histogram(CELL cat, long count, struct Histogram *histogram)
416 {
417  int i;
418 
419  for (i = 0; i < histogram->num; i++) {
420  if (histogram->list[i].cat == cat) {
421  histogram->list[i].count = count;
422  return 1;
423  }
424  }
425  G_extend_histogram(cat, count, histogram);
426 
427  return 0;
428 }
429 
430 
439 int G_extend_histogram(CELL cat, long count, struct Histogram *histogram)
440 {
441  histogram->num++;
442  histogram->list =
443  (LIST *) G_realloc((char *)histogram->list,
444  histogram->num * sizeof(LIST));
445  histogram->list[histogram->num - 1].cat = cat;
446  histogram->list[histogram->num - 1].count = count;
447 
448  return 0;
449 }
450 
451 
458 int G_zero_histogram(struct Histogram *histogram)
459 {
460  int i;
461 
462  for (i = 0; i < histogram->num; i++)
463  histogram->list[i].count = 0;
464 
465  return 0;
466 }
char * G_mapset(void)
current mapset name
Definition: mapset.c:31
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
float b
Definition: named_colr.c:8
int G_read_histogram(const char *name, const char *mapset, struct Histogram *histogram)
read the histogram information
Definition: histogram.c:46
int G_get_histogram_num(const struct Histogram *histogram)
Sorts the histogram in ascending order by counts then category.
Definition: histogram.c:188
FILE * fd
Definition: g3dcolor.c:368
string name
Definition: render.py:1314
int G_zero_histogram(struct Histogram *histogram)
Zero out histogram struct.
Definition: histogram.c:458
Definition: pad.h:5
int G_set_histogram(CELL cat, long count, struct Histogram *histogram)
sets the histogram value for cat to count
Definition: histogram.c:415
char * G_find_file2_misc(const char *dir, const char *element, const char *name, const char *mapset)
Definition: find_file.c:196
int count
FILE * G_fopen_old_misc(const char *dir, const char *element, const char *name, const char *mapset)
open a database file for reading
Definition: open_misc.c:200
int G_write_histogram_cs(const char *name, struct Cell_stats *statf)
Writes the histogram based on cell statistics to file.
Definition: histogram.c:135
int G_free_histogram(struct Histogram *histogram)
Frees memory allocated for the histogram.
Definition: histogram.c:234
CELL G_get_histogram_cat(int n, const struct Histogram *histogram)
Returns cat for the nth element in the histogram.
Definition: histogram.c:201
int G_next_cell_stat(CELL *cat, long *count, struct Cell_stats *s)
retrieve sorted cell stats
Definition: cell_stats.c:338
#define LIST
Definition: globals.h:74
int G_remove_histogram(const char *name)
Removes the histogram.
Definition: histogram.c:371
int G_init_histogram(struct Histogram *histogram)
initializes the histogram structure
Definition: histogram.c:22
int G_add_histogram(CELL cat, long count, struct Histogram *histogram)
adds count to the histogram value for cat
Definition: histogram.c:389
int G_sort_histogram_by_count(struct Histogram *histogram)
Sorts the histogram by counts.
Definition: histogram.c:313
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
int G_sort_histogram(struct Histogram *histogram)
Sorts the histogram.
Definition: histogram.c:253
int G_extend_histogram(CELL cat, long count, struct Histogram *histogram)
Extends histogram struct to accomodate a new value.
Definition: histogram.c:439
return NULL
Definition: dbfopen.c:1394
int G_rewind_cell_stats(struct Cell_stats *s)
reset/rewind cell stats
Definition: cell_stats.c:265
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
fclose(fd)
FILE * G_fopen_new_misc(const char *dir, const char *element, const char *name)
open a new database file
Definition: open_misc.c:172
long G_get_histogram_count(int n, const struct Histogram *histogram)
Returns count for the nth element in the histogram.
Definition: histogram.c:218
CELL cat
Definition: g3dcats.c:90
int G_remove_misc(const char *dir, const char *element, const char *name)
Remove a database misc file.
Definition: remove.c:67
int G_write_histogram(const char *name, const struct Histogram *histogram)
Writes the histogram information.
Definition: histogram.c:105
int G_make_histogram_cs(struct Cell_stats *statf, struct Histogram *histogram)
Creates histogram based on cell statistics.
Definition: histogram.c:163
int n
Definition: dataquad.c:291