[GRASS-SVN] r55276 - grass/trunk/raster/r.cross
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Mar 1 13:01:50 PST 2013
Author: glynn
Date: 2013-03-01 13:01:50 -0800 (Fri, 01 Mar 2013)
New Revision: 55276
Removed:
grass/trunk/raster/r.cross/tree.c
Modified:
grass/trunk/raster/r.cross/Makefile
grass/trunk/raster/r.cross/cross.c
grass/trunk/raster/r.cross/glob.h
grass/trunk/raster/r.cross/local_proto.h
grass/trunk/raster/r.cross/main.c
grass/trunk/raster/r.cross/renumber.c
Log:
Fix handling of null values
Use btree library instead of inlined version
Modified: grass/trunk/raster/r.cross/Makefile
===================================================================
--- grass/trunk/raster/r.cross/Makefile 2013-03-01 20:45:54 UTC (rev 55275)
+++ grass/trunk/raster/r.cross/Makefile 2013-03-01 21:01:50 UTC (rev 55276)
@@ -2,8 +2,8 @@
PGM = r.cross
-LIBES = $(RASTERLIB) $(GISLIB)
-DEPENDENCIES = $(RASTERDEP) $(GISDEP)
+LIBES = $(RASTERLIB) $(GISLIB) $(BTREELIB)
+DEPENDENCIES = $(RASTERDEP) $(GISDEP) $(BTREEDEP)
include $(MODULE_TOPDIR)/include/Make/Module.make
Modified: grass/trunk/raster/r.cross/cross.c
===================================================================
--- grass/trunk/raster/r.cross/cross.c 2013-03-01 20:45:54 UTC (rev 55275)
+++ grass/trunk/raster/r.cross/cross.c 2013-03-01 21:01:50 UTC (rev 55276)
@@ -17,24 +17,39 @@
***************************************************************************/
#include <stdlib.h>
+#include <grass/glocale.h>
+#include <grass/raster.h>
+#include <grass/btree.h>
#include "glob.h"
#include "local_proto.h"
-#include <grass/raster.h>
-#include <grass/glocale.h>
+static int compare(const void *aa, const void *bb)
+{
+ const CELL *a = aa;
+ const CELL *b = bb;
+ int i;
+ for (i = 0; i < nfiles; i++) {
+ if (a[i] > b[i])
+ return 1;
+ if (a[i] < b[i])
+ return -1;
+ }
+
+ return 0;
+}
+
CELL cross(int fd[], int non_zero, int primary, int outfd)
{
+ BTREE btree;
CELL *cell[NFILES];
- CELL *result_cell, *rp;
- CELL cat[NFILES], cat0, cat1;
- register int i;
+ CELL *result_cell;
+ CELL cat[NFILES];
+ int row, col, i;
int zero;
- int row, col;
- register int p, q;
- int dir;
- NODE *pnode, *new_node;
CELL result;
+ int keysize = nfiles * sizeof(CELL);
+ void *ptr;
/* allocate i/o buffers for each raster map */
@@ -44,12 +59,9 @@
/* initialize the reclass table */
result = 0;
- for (i = 0; i < nfiles; i++)
- cat[i] = 0;
- store_reclass(result, primary, cat);
/* here we go */
- plant_tree();
+ btree_create(&btree, compare, 1);
G_message(_("%s: STEP 1 ... "), G_program_name());
for (row = 0; row < nrows; row++) {
G_percent(row, nrows, 5);
@@ -65,7 +77,8 @@
for (col = 0; col < ncols; col++) {
zero = 1;
for (i = 0; i < nfiles; i++) {
- if (cat[i] = cell[i][col])
+ cat[i] = cell[i][col];
+ if (!Rast_is_c_null_value(&cat[i]))
zero = 0;
else if (non_zero) {
zero = 1;
@@ -73,101 +86,18 @@
}
}
if (zero) {
- result_cell[col] = 0;
+ Rast_set_c_null_value(&result_cell[col], 1);
continue;
}
/* search for this value in the tree */
- cat0 = cat[0];
- cat1 = cat0 - NCATS;
- q = 1;
- while (q > 0) {
- register CELL *t, *c;
- register CELL diff;
-
- pnode = &tree[p = q];
- t = pnode->cat;
-
- /* search the tree */
- dir = FOUND;
- if (*t > cat0)
- dir = LEFT;
- else if (*t++ <= cat1)
- dir = RIGHT;
- else {
- c = cat + 1;
- for (i = 1; i < nfiles; i++)
- if ((diff = (*t++ - *c++)) > 0) {
- dir = LEFT;
- break;
- }
- else if (diff < 0) {
- dir = RIGHT;
- break;
- }
- }
- switch (dir) {
- case FOUND:
- rp = &pnode->result[cat0 - pnode->cat[0]];
- if (*rp == 0) {
- *rp = ++result;
- store_reclass(result, primary, cat);
- }
- result_cell[col] = *rp;
- q = 0;
- break;
- case LEFT:
- q = pnode->left;
- break;
- case RIGHT:
- q = pnode->right;
- break;
- }
- }
- if (dir == FOUND)
- continue;
-
- /* add a new node to the tree and put this value into it */
- N++;
- /* grow the tree? */
- if (N >= tlen) {
- tree =
- (NODE *) G_realloc(tree, sizeof(NODE) * (tlen += INCR));
- pnode = &tree[p]; /* realloc moves tree, must reassign pnode */
- }
-
- new_node = &tree[N];
- new_node->cat = (CELL *) G_calloc(nfiles, sizeof(CELL));
- new_node->result = (CELL *) G_calloc(NCATS, sizeof(CELL));
-
- if (cat0 < 0)
- cat0 = -((-cat0) >> SHIFT) - 1;
- else
- cat0 = cat0 >> SHIFT;
-
- if (cat0 < 0)
- cat0 = -((-cat0) << SHIFT) + 1;
- else
- cat0 = cat0 << SHIFT;
- new_node->cat[0] = cat0;
-
- for (i = 1; i < nfiles; i++)
- new_node->cat[i] = cat[i];
-
- for (i = 0; i < NCATS; i++)
- new_node->result[i] = 0;
- result_cell[col] = new_node->result[cat[0] - cat0] = ++result;
- store_reclass(result, primary, cat);
-
- new_node->left = 0;
-
- if (dir == LEFT) {
- new_node->right = -p; /* create thread */
- pnode->left = N; /* insert left */
- }
+ if (btree_find(&btree, cat, &ptr))
+ result_cell[col] = *(CELL*)ptr;
else {
- new_node->right = pnode->right; /* copy right link/thread */
- pnode->right = N; /* add right */
+ btree_update(&btree, cat, keysize, &result, sizeof(CELL));
+ store_reclass(result, primary, cat);
+ result_cell[col] = result;
+ result++;
}
}
Rast_put_row(outfd, result_cell, CELL_TYPE);
@@ -175,8 +105,8 @@
G_percent(nrows, nrows, 5);
/* free some memory */
- uproot_tree();
+ btree_free(&btree);
for (i = 0; i < nfiles; i++)
G_free(cell[i]);
- return result;
+ return result - 1;
}
Modified: grass/trunk/raster/r.cross/glob.h
===================================================================
--- grass/trunk/raster/r.cross/glob.h 2013-03-01 20:45:54 UTC (rev 55275)
+++ grass/trunk/raster/r.cross/glob.h 2013-03-01 21:01:50 UTC (rev 55276)
@@ -23,35 +23,16 @@
#include <grass/raster.h>
#define NFILES 30 /* maximum number of layers */
-#define SHIFT 6 /* 2^SHIFT cats per node */
-#define INCR 16
-#define FOUND 0
-#define LEFT 1
-#define RIGHT 2
-
extern int nfiles;
extern int nrows;
extern int ncols;
-extern int NCATS;
extern const char *names[NFILES];
extern struct Categories labels[NFILES];
typedef struct
{
CELL *cat;
- CELL *result;
- int left;
- int right;
-} NODE;
-
-extern NODE *tree; /* tree of values */
-extern int tlen; /* allocate tree size */
-extern int N; /* number of actual nodes in tree */
-
-typedef struct
-{
- CELL *cat;
CELL result;
} RECLASS;
Modified: grass/trunk/raster/r.cross/local_proto.h
===================================================================
--- grass/trunk/raster/r.cross/local_proto.h 2013-03-01 20:45:54 UTC (rev 55275)
+++ grass/trunk/raster/r.cross/local_proto.h 2013-03-01 21:01:50 UTC (rev 55276)
@@ -34,11 +34,4 @@
/* store.c */
int store_reclass(CELL, int, CELL *);
-/* tree.c */
-int plant_tree(void);
-int first_node(CELL **, CELL **);
-int next_node(int, CELL **, CELL **);
-CELL index_cat(register CELL);
-int uproot_tree(void);
-
#endif /* __R_CROSS_LOCAL_PROTO_H__ */
Modified: grass/trunk/raster/r.cross/main.c
===================================================================
--- grass/trunk/raster/r.cross/main.c 2013-03-01 20:45:54 UTC (rev 55275)
+++ grass/trunk/raster/r.cross/main.c 2013-03-01 21:01:50 UTC (rev 55276)
@@ -27,12 +27,8 @@
int nfiles;
int nrows;
int ncols;
-int NCATS = 1 << SHIFT;
const char *names[NFILES];
struct Categories labels[NFILES];
-NODE *tree; /* tree of values */
-int tlen; /* allocate tree size */
-int N; /* number of actual nodes in tree */
RECLASS *reclass;
CELL *table;
Modified: grass/trunk/raster/r.cross/renumber.c
===================================================================
--- grass/trunk/raster/r.cross/renumber.c 2013-03-01 20:45:54 UTC (rev 55275)
+++ grass/trunk/raster/r.cross/renumber.c 2013-03-01 21:01:50 UTC (rev 55276)
@@ -36,7 +36,8 @@
Rast_get_c_row(in, c = cell, row);
col = ncols;
while (col-- > 0) {
- *c = table[*c];
+ if (!Rast_is_c_null_value(c))
+ *c = table[*c];
c++;
}
Rast_put_row(out, cell, CELL_TYPE);
Deleted: grass/trunk/raster/r.cross/tree.c
===================================================================
--- grass/trunk/raster/r.cross/tree.c 2013-03-01 20:45:54 UTC (rev 55275)
+++ grass/trunk/raster/r.cross/tree.c 2013-03-01 21:01:50 UTC (rev 55276)
@@ -1,122 +0,0 @@
-
-/****************************************************************************
- *
- * MODULE: r.cross
- *
- * AUTHOR(S): Michael Shapiro - CERL
- *
- * PURPOSE: Creates a cross product of the category values from
- * multiple raster map layers.
- *
- * 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 "glob.h"
-
-
-int plant_tree(void)
-{
- register CELL *cat;
- register CELL *result;
- register int i;
-
- NODE *node;
-
- tree = (NODE *) G_calloc(tlen = INCR, sizeof(NODE));
- node = &tree[N = 1];
-
- cat = node->cat = (CELL *) G_calloc(nfiles, sizeof(CELL));
- result = node->result = (CELL *) G_calloc(NCATS, sizeof(CELL));
-
- i = nfiles;
- while (i--)
- *cat++ = 0;
- i = NCATS;
- while (i--)
- *result++ = 0;
- node->left = 0;
- node->right = 0;
-
- return 0;
-}
-
-int first_node(CELL ** cat, CELL ** result)
-{
- register int p, q;
-
- /* start at root and go all the way to the left */
- p = 1;
- while ((q = tree[p].left))
- p = q;
- *cat = tree[p].cat;
- *result = tree[p].result;
- return p;
-}
-
-int next_node(int p, CELL ** cat, CELL ** result)
-{
- register int q;
-
- /* go to the right */
- p = tree[p].right;
-
- if (p == 0) /* no more */
- return 0;
-
- if (p < 0) { /* thread. stop here */
- p = -p;
- *cat = tree[p].cat;
- *result = tree[p].result;
- return p;
- }
-
- while ((q = tree[p].left)) /* now go all the way left */
- p = q;
-
- *cat = tree[p].cat;
- *result = tree[p].result;
- return p;
-}
-
-CELL index_cat(register CELL cat)
-{
- register CELL idx;
-
- /*
- if (cat < 0)
- idx = -(-cat/NCATS) - 1;
- else
- idx = cat/NCATS;
-
- if ((idx *= NCATS) < 0) idx++;
- */
- if (cat < 0)
- idx = -((-cat) >> SHIFT) - 1;
- else
- idx = cat >> SHIFT;
-
- if (idx < 0)
- idx = -((-idx) << SHIFT) + 1;
- else
- idx = idx << SHIFT;
-
- return idx;
-}
-
-int uproot_tree(void)
-{
- int i;
-
- for (i = 1; i <= N; i++) {
- G_free(tree[i].cat);
- G_free(tree[i].result);
- }
- G_free(tree);
-
- return 0;
-}
More information about the grass-commit
mailing list