[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