GRASS 8 Programmer's Manual 8.6.0dev(2026)-f6f2c534ea
Loading...
Searching...
No Matches
histogram.c
Go to the documentation of this file.
1#include <stdlib.h>
2
3#include <grass/gis.h>
4#include <grass/raster.h>
5#include <grass/glocale.h>
6
7#define LIST struct Histogram_list
8
9static FILE *fopen_histogram_new(const char *);
10static int cmp(const void *, const void *);
11static int cmp_count(const void *, const void *);
12
13/*!
14 * \brief initializes the histogram structure
15 *
16 * initializes the histogram structure for calls to Rast_set_histogram()
17 * and Rast_add_histogram()
18 * \param histogram
19 * \return
20 */
22{
23 histogram->num = 0;
24 histogram->list = NULL;
25}
26
27/*!
28 * \brief read the histogram information
29 *
30 * Reads the histogram information associated with map layer "map"
31 * in mapset "mapset" into the structure "histogram".
32 *
33 * note: a warning message is printed if the file is missing or incorrect
34 * \param name: name of map
35 * \param mapset: mapset that map belongs to
36 * \param histogram: struct for histogram
37 * \return 1 if successful,
38 * 0 if no histogram file,
39 */
40int Rast_read_histogram(const char *name, const char *mapset,
41 struct Histogram *histogram)
42{
43 FILE *fd = NULL;
44 long cat;
45 long count;
46 char buf[200];
47
49
50 if (!G_find_file2_misc("cell_misc", "histogram", name, mapset)) {
51 G_warning(_("Histogram for [%s in %s] missing (run r.support)"), name,
52 mapset);
53 return 0;
54 }
55
56 fd = G_fopen_old_misc("cell_misc", "histogram", name, mapset);
57 if (!fd)
58 G_fatal_error(_("Can't read histogram for [%s in %s]"), name, mapset);
59
60 while (fgets(buf, sizeof buf, fd)) {
61 if (sscanf(buf, "%ld:%ld", &cat, &count) != 2)
62 G_fatal_error(_("Invalid histogram file for [%s in %s]"), name,
63 mapset);
65 }
66 fclose(fd);
67
68 if (histogram->num == 0)
69 G_fatal_error(_("Invalid histogram file for [%s in %s]"), name, mapset);
70
72
73 return 1;
74}
75
76/*!
77 * \brief Writes the histogram information
78 *
79 * Writes the histogram information associated with map layer "name"
80 * \param name: name of map
81 * \param histogram: struct for histogram
82 * \return void
83 */
84void Rast_write_histogram(const char *name, const struct Histogram *histogram)
85{
86 FILE *fp;
87 int n;
88 LIST *list;
89
90 fp = fopen_histogram_new(name);
91
92 list = histogram->list;
93 for (n = 0; n < histogram->num; n++) {
94 if (list[n].count)
95 fprintf(fp, "%ld:%ld\n", (long)list[n].cat, list[n].count);
96 }
97
98 fclose(fp);
99}
100
101/*!
102 * \brief Writes the histogram based on cell statistics to file
103 *
104 * \param name: name of map
105 * \param statf: cell statistics
106 * \return void
107 */
108void Rast_write_histogram_cs(const char *name, struct Cell_stats *statf)
109{
110 FILE *fp;
111 CELL cat;
112 long count;
113
114 fp = fopen_histogram_new(name);
115
117 while (Rast_next_cell_stat(&cat, &count, statf)) {
118 if (count > 0)
119 fprintf(fp, "%ld:%ld\n", (long)cat, count);
120 }
121
122 fclose(fp);
123}
124
125/*!
126 * \brief Creates histogram based on cell statistics
127 *
128 * \param statf: cell statistics
129 * \param histogram: raster histogram
130 * \return
131 */
133 struct Histogram *histogram)
134{
135 CELL cat;
136 long count;
137
140 while (Rast_next_cell_stat(&cat, &count, statf))
142
144}
145
146/*!
147 * \brief Sorts the histogram in ascending order by counts then category
148 *
149 * Sorts the histogram in ascending order by counts then category.
150 * No combining is done.
151 * \param histogram: struct for histogram
152 * \return 1 if successful,
153 * -1 on fail
154 */
156{
157 return histogram->num;
158}
159
160/*!
161 * \brief Returns cat for the nth element in the histogram
162 *
163 * Returns cat for the nth element in the histogram
164 * \param n: The nth element in the histogram to get the cat for
165 * \param histogram: struct for histogram
166 * \return CELL
167 */
169{
170 if (n < 0 || n >= histogram->num)
171 return 0;
172
173 return histogram->list[n].cat;
174}
175
176/*!
177 * \brief Returns count for the nth element in the histogram
178 *
179 * Returns count for the nth element in the histogram
180 * \param n: nth element
181 * \param histogram: struct for histogram
182 * \return count
183 */
185{
186 if (n < 0 || n >= histogram->num)
187 return 0;
188
189 return histogram->list[n].count;
190}
191
192/*!
193 * \brief Frees memory allocated for the histogram
194 *
195 * frees the memory allocated for the histogram
196 * \param histogram: struct for histogram
197 * \return
198 */
200{
201 if (histogram->num > 0)
202 G_free(histogram->list);
203 histogram->num = 0;
204 histogram->list = NULL;
205}
206
207/*!
208 * \brief Sorts the histogram
209 *
210 * Sorts the histogram in ascending order by category,
211 * combining (by adding) elements that have the same category.
212 * \param histogram: struct for histogram
213 * \return 0 if successful,
214 * 1 on fail
215 */
217{
218 int a, b, n;
219 LIST *list;
220
221 /* if histogram only has 1 entry, nothing to do */
222 if ((n = histogram->num) <= 1)
223 return 1;
224
225 list = histogram->list;
226
227 /* quick check to see if sorting needed */
228 for (a = 1; a < n; a++)
229 if (list[a - 1].cat >= list[a].cat)
230 break;
231 if (a >= n)
232 return 1;
233
234 /* sort */
235 qsort(list, n, sizeof(LIST), &cmp);
236
237 /* sum duplicate entries */
238 for (a = 0, b = 1; b < n; b++) {
239 if (list[a].cat != list[b].cat) {
240 a++;
241 list[a].count = list[b].count;
242 list[a].cat = list[b].cat;
243 }
244 else {
245 list[a].count += list[b].count;
246 }
247 }
248 histogram->num = a + 1;
249
250 return 0;
251}
252
253static int cmp(const void *aa, const void *bb)
254{
255 const LIST *a = aa, *b = bb;
256
257 if (a->cat < b->cat)
258 return -1;
259
260 if (a->cat > b->cat)
261 return 1;
262
263 return 0;
264}
265
266/*!
267 * \brief Sorts the histogram by counts
268 *
269 * Sorts the histogram in ascending order by counts then category.
270 * No combining is done.
271 * \param histogram: struct for histogram
272 * \return 0 if successful,
273 * 1 on fail
274 */
276{
277 int n;
278 LIST *list;
279
280 /* if histogram only has 1 entry, nothing to do */
281 if ((n = histogram->num) <= 1)
282 return 1;
283
284 list = histogram->list;
285
286 /* sort */
287 qsort(list, n, sizeof(LIST), &cmp_count);
288
289 return 0;
290}
291
292static int cmp_count(const void *aa, const void *bb)
293{
294 const LIST *a = aa, *b = bb;
295
296 if (a->count < b->count)
297 return -1;
298
299 if (a->count > b->count)
300 return 1;
301
302 if (a->cat < b->cat)
303 return -1;
304
305 if (a->cat > b->cat)
306 return 1;
307
308 return 0;
309}
310
311static FILE *fopen_histogram_new(const char *name)
312{
313 FILE *fp;
314
315 fp = G_fopen_new_misc("cell_misc", "histogram", name);
316 if (!fp)
317 G_fatal_error(_("Unable to create histogram file for <%s>"), name);
318
319 return fp;
320}
321
322/*!
323 * \brief Removes the histogram
324 *
325 * Removes the histogram information associated with map layer "name"
326 * \param name: name of map
327 * \return
328 */
330{
331 G_remove_misc("cell_misc", "histogram", name);
332}
333
334/*!
335 * \brief adds count to the histogram value for cat
336 *
337 * adds count to the histogram value for cat
338 * \param cat: category
339 * \param count
340 * \param histogram: struct for histogram
341 * \return 0 if successful,
342 * 1 on fail
343 */
344int Rast_add_histogram(CELL cat, long count, struct Histogram *histogram)
345{
346 int i;
347
348 for (i = 0; i < histogram->num; i++) {
349 if (histogram->list[i].cat == cat) {
350 histogram->list[i].count += count;
351 return 1;
352 }
353 }
355
356 return 0;
357}
358
359/*!
360 * \brief sets the histogram value for cat to count
361 *
362 * sets the histogram value for cat to count
363 * \param cat: category
364 * \param count
365 * \param histogram: struct for histogram
366 * \return 0 if successful,
367 * 1 on fail
368 */
369int Rast_set_histogram(CELL cat, long count, struct Histogram *histogram)
370{
371 int i;
372
373 for (i = 0; i < histogram->num; i++) {
374 if (histogram->list[i].cat == cat) {
375 histogram->list[i].count = count;
376 return 1;
377 }
378 }
380
381 return 0;
382}
383
384/*!
385 * \brief Extends histogram struct to accommodate a new value
386 *
387 * \param cat: category
388 * \param count
389 * \param histogram: struct for histogram
390 * \return
391 */
392void Rast_extend_histogram(CELL cat, long count, struct Histogram *histogram)
393{
394 histogram->num++;
395 histogram->list =
396 (LIST *)G_realloc(histogram->list, histogram->num * sizeof(LIST));
397 histogram->list[histogram->num - 1].cat = cat;
398 histogram->list[histogram->num - 1].count = count;
399}
400
401/*!
402 * \brief Zero out histogram struct
403 *
404 * \param histogram: struct for histogram
405 * \return
406 */
408{
409 int i;
410
411 for (i = 0; i < histogram->num; i++)
412 histogram->list[i].count = 0;
413}
#define NULL
Definition ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:147
#define G_realloc(p, n)
Definition defs/gis.h:141
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
int G_remove_misc(const char *, const char *, const char *)
Remove a database misc file.
Definition remove.c:64
const char * G_find_file2_misc(const char *, const char *, const char *, const char *)
Searches for a misc file from the mapset search list or in a specified mapset. (look but don't touch)
Definition find_file.c:257
FILE * G_fopen_old_misc(const char *, const char *, const char *, const char *)
open a database misc file for reading
Definition open_misc.c:210
FILE * G_fopen_new_misc(const char *, const char *, const char *)
open a new database misc file
Definition open_misc.c:183
int Rast_rewind_cell_stats(struct Cell_stats *)
Reset/rewind cell stats.
Definition cell_stats.c:248
int Rast_next_cell_stat(CELL *, long *, struct Cell_stats *)
Retrieve sorted cell stats.
Definition cell_stats.c:312
int CELL
Definition gis.h:634
#define _(str)
Definition glocale.h:10
int Rast_get_histogram_num(const struct Histogram *histogram)
Sorts the histogram in ascending order by counts then category.
Definition histogram.c:155
void Rast_write_histogram(const char *name, const struct Histogram *histogram)
Writes the histogram information.
Definition histogram.c:84
int Rast_read_histogram(const char *name, const char *mapset, struct Histogram *histogram)
read the histogram information
Definition histogram.c:40
void Rast_free_histogram(struct Histogram *histogram)
Frees memory allocated for the histogram.
Definition histogram.c:199
int Rast_add_histogram(CELL cat, long count, struct Histogram *histogram)
adds count to the histogram value for cat
Definition histogram.c:344
int Rast_sort_histogram(struct Histogram *histogram)
Sorts the histogram.
Definition histogram.c:216
void Rast_extend_histogram(CELL cat, long count, struct Histogram *histogram)
Extends histogram struct to accommodate a new value.
Definition histogram.c:392
void Rast_write_histogram_cs(const char *name, struct Cell_stats *statf)
Writes the histogram based on cell statistics to file.
Definition histogram.c:108
long Rast_get_histogram_count(int n, const struct Histogram *histogram)
Returns count for the nth element in the histogram.
Definition histogram.c:184
int Rast_sort_histogram_by_count(struct Histogram *histogram)
Sorts the histogram by counts.
Definition histogram.c:275
void Rast_make_histogram_cs(struct Cell_stats *statf, struct Histogram *histogram)
Creates histogram based on cell statistics.
Definition histogram.c:132
int Rast_set_histogram(CELL cat, long count, struct Histogram *histogram)
sets the histogram value for cat to count
Definition histogram.c:369
CELL Rast_get_histogram_cat(int n, const struct Histogram *histogram)
Returns cat for the nth element in the histogram.
Definition histogram.c:168
void Rast_zero_histogram(struct Histogram *histogram)
Zero out histogram struct.
Definition histogram.c:407
void Rast_init_histogram(struct Histogram *histogram)
initializes the histogram structure
Definition histogram.c:21
void Rast_remove_histogram(const char *name)
Removes the histogram.
Definition histogram.c:329
#define LIST
Definition histogram.c:7
int count
const char * name
Definition named_colr.c:6
double b
Definition r_raster.c:39
Definition manage.h:4