123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- /****************************************************************************
- *
- * MODULE: r.describe
- *
- * AUTHOR(S): Michael Shapiro - CERL
- *
- * PURPOSE: Prints terse list of category values found in a raster
- * map layer.
- *
- * COPYRIGHT: (C) 2006 by the GRASS Development Team
- *
- * This program is free software under the GNU General Public
- * License (>=v2). Read the file COPYING that comes with GRASS
- * for details.
- *
- ***************************************************************************/
- #include <grass/gis.h>
- #include <grass/raster.h>
- #define INCR 10
- #define NCATS 100
- typedef struct
- {
- int idx;
- char cat[NCATS];
- int left;
- int right;
- } NODE;
- static NODE *tree = 0; /* tree of values */
- static int tlen; /* allocated tree size */
- static int N; /* number of actual nodes in tree */
- int plant_tree(void)
- {
- N = 0;
- if (!tree) {
- tlen = INCR;
- tree = (NODE *) G_malloc(tlen * sizeof(NODE));
- }
- return 0;
- }
- int add_node_to_tree(register CELL cat)
- {
- register int p, q;
- int idx, offset;
- if (cat < 0) {
- idx = -(-cat / NCATS) - 1;
- offset = cat - idx * NCATS - 1;
- }
- else {
- idx = cat / NCATS;
- offset = cat - idx * NCATS;
- }
- if (offset < 0 || offset >= NCATS)
- G_warning("cat %ld got offset %d - shouldn't happen", (long)cat,
- offset);
- /* first node is special case */
- if (N == 0) {
- N = 1;
- G_zero(tree[N].cat, sizeof(tree[N].cat));
- tree[N].idx = idx;
- tree[N].cat[offset] = 1;
- tree[N].left = 0;
- tree[N].right = 0;
- return 0;
- }
- q = 1;
- while (q > 0) {
- p = q;
- if (tree[q].idx == idx) {
- tree[q].cat[offset] = 1;
- return 0; /* found */
- }
- if (tree[q].idx > idx)
- q = tree[q].left; /* go left */
- else
- q = tree[q].right; /* go right */
- }
- /* new node */
- N++;
- /* grow the tree? */
- if (N >= tlen)
- tree = (NODE *) G_realloc(tree, sizeof(NODE) * (tlen += INCR));
- /* add node to tree */
- G_zero(tree[N].cat, sizeof(tree[N].cat));
- tree[N].idx = idx;
- tree[N].cat[offset] = 1;
- tree[N].left = 0;
- if (tree[p].idx > idx) {
- tree[N].right = -p; /* create thread */
- tree[p].left = N; /* insert left */
- }
- else {
- tree[N].right = tree[p].right; /* copy right link/thread */
- tree[p].right = N; /* add right */
- }
- return 0;
- }
- static int curp;
- #ifdef COMMENT_OUT
- static int curoffset;
- #endif
- int first_node(void)
- {
- int q;
- /* start at root and go all the way to the left */
- curp = 1;
- while ((q = tree[curp].left))
- curp = q;
- return 0;
- }
- int next_node(void)
- {
- int q;
- /* go to the right */
- curp = tree[curp].right;
- if (curp == 0) /* no more */
- return 0;
- if (curp < 0) { /* thread. stop here */
- curp = -curp;
- return 1;
- }
- while ((q = tree[curp].left)) /* now go all the way left */
- curp = q;
- return 1;
- }
- #ifdef COMMENT_OUT
- int first_cat(CELL * cat)
- {
- first_node();
- curoffset = -1;
- return next_cat(cat);
- }
- int next_cat(CELL * cat)
- {
- int idx;
- for (;;) {
- curoffset++;
- if (curoffset >= NCATS) {
- if (!next_node())
- return 0;
- curoffset = -1;
- continue;
- }
- if (tree[curp].cat[curoffset]) {
- idx = tree[curp].idx;
- if (idx < 0)
- *cat = idx * NCATS + curoffset + 1;
- else
- *cat = idx * NCATS + curoffset;
- return 1;
- }
- }
- return 0;
- }
- #endif
|