[GRASS-SVN] r59021 - grass/trunk/raster/r.li/r.li.patchnum

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Feb 13 03:31:59 PST 2014


Author: mmetz
Date: 2014-02-13 03:31:59 -0800 (Thu, 13 Feb 2014)
New Revision: 59021

Modified:
   grass/trunk/raster/r.li/r.li.patchnum/main.c
Log:
r.li.patchnum: fix number of patches

Modified: grass/trunk/raster/r.li/r.li.patchnum/main.c
===================================================================
--- grass/trunk/raster/r.li/r.li.patchnum/main.c	2014-02-13 10:26:41 UTC (rev 59020)
+++ grass/trunk/raster/r.li/r.li.patchnum/main.c	2014-02-13 11:31:59 UTC (rev 59021)
@@ -59,26 +59,39 @@
 
 int patch_number(int fd, char **par, struct area_entry *ad, double *result)
 {
-    CELL *buf, *sup;
-    int count = 0, i, j, connected = 0, complete_line = 1, other_above = 0;
+    CELL *buf, *sup, *cnull;
+    CELL pid, old_pid, *pid_curr, *pid_sup, *ctmp;
+    int count, i, j, k, connected, other_above;
     struct Cell_head hd;
-    CELL complete_value;
-    int mask_fd = -1, *mask_buf, *mask_sup, null_count = 0;
+    int mask_fd, *mask_buf, null_count;
 
-    Rast_set_c_null_value(&complete_value, 1);
     Rast_get_cellhd(ad->raster, "", &hd);
 
-    sup = Rast_allocate_c_buf();
+    cnull = Rast_allocate_c_buf();
+    Rast_set_c_null_value(cnull, Rast_window_cols());
+    sup = cnull;
 
+    /* initialize patch ids */
+    pid_curr = Rast_allocate_c_buf();
+    Rast_set_c_null_value(pid_curr, Rast_window_cols());
+    pid_sup = Rast_allocate_c_buf();
+    Rast_set_c_null_value(pid_sup, Rast_window_cols());
+
     /* open mask if needed */
+    mask_fd = -1;
+    mask_buf = NULL;
+    null_count = 0;
     if (ad->mask == 1) {
 	if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
 	    return 0;
-	mask_buf = malloc(ad->cl * sizeof(int));
-	mask_sup = malloc(ad->cl * sizeof(int));
+	mask_buf = G_malloc(ad->cl * sizeof(int));
     }
 
-    /*calculate number of patch */
+    /* calculate number of patches */
+    count = 0;
+    connected = 0;
+    other_above = 0;
+    pid = 0;
 
     for (i = 0; i < ad->rl; i++) {
 	buf = RLI_get_cell_raster_row(fd, i + ad->y, ad);
@@ -87,95 +100,93 @@
 	}
 	/* mask values */
 	if (ad->mask == 1) {
-	    int k;
-
-	    if (i > 0) {
-		int *tmp;
-
-		tmp = mask_sup;
-		mask_buf = mask_sup;
-	    }
 	    if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
 		return 0;
 	    for (k = 0; k < ad->cl; k++) {
 		if (mask_buf[k] == 0) {
-		    Rast_set_c_null_value(mask_buf + k, 1);
+		    Rast_set_c_null_value(&buf[k + ad->x], 1);
 		    null_count++;
 		}
 	    }
-
 	}
+	
+	ctmp = pid_sup;
+	pid_sup = pid_curr;
+	pid_curr = ctmp;
+	Rast_set_c_null_value(pid_curr, Rast_window_cols());
 
+	connected = 0;
+	other_above = 1;
+	for (j = 0; j < ad->cl; j++) {
+	    
+	    if (Rast_is_null_value(&(buf[j + ad->x]), CELL_TYPE)) {
+		connected = 0;
+		other_above = 1;
+		continue;
+	    }
 
-	if (complete_line) {
-	    if (!Rast_is_null_value(&(buf[ad->x]), CELL_TYPE) &&
-		buf[ad->x] != complete_value)
-		count++;
-
-	    for (j = 0; j < ad->cl - 1; j++) {
-
-		if (buf[j + ad->x] != buf[j + 1 + ad->x]) {
-		    complete_line = 0;
-		    if (!Rast_is_null_value(&(buf[j + 1 + ad->x]), CELL_TYPE)
-			&& buf[j + 1 + ad->x] != complete_value)
-			count++;
+	    if (sup[j + ad->x] == buf[j + ad->x]) {
+		
+		if (!connected) {
+		    pid_curr[j + ad->x] = pid_sup[j + ad->x];
 		}
-
-	    }
-	    if (complete_line) {
-		complete_value = buf[ad->x];
-	    }
-	}
-	else {
-	    complete_line = 1;
-	    connected = 0;
-	    other_above = 0;
-	    for (j = 0; j < ad->cl; j++) {
-		if (sup[j + ad->x] == buf[j + ad->x]) {
-		    connected = 1;
-		    if (other_above) {
-			other_above = 0;
+		
+		if (pid_curr[j + ad->x] != pid_sup[j + ad->x]) {
+		    if (connected) {
 			count--;
 		    }
-		}
-		else {
-		    if (connected &&
-			!Rast_is_null_value(&(buf[j + ad->x]), CELL_TYPE))
-			other_above = 1;
-		}
-		if (j < ad->cl - 1 && buf[j + ad->x] != buf[j + 1 + ad->x]) {
-		    complete_line = 0;
-		    if (!connected &&
-			!Rast_is_null_value(&(buf[j + ad->x]), CELL_TYPE)) {
-
-			count++;
-			connected = 0;
-			other_above = 0;
+		    if (other_above) {
+			pid_curr[j + ad->x] = pid_sup[j + ad->x];
+			for (k = j + ad->x - 1; k >= ad->x; k--) {
+			    if (buf[k] != buf[j + ad->x])
+				break;
+			    pid_curr[k] = pid_sup[j + ad->x];
+			}
 		    }
 		    else {
-			connected = 0;
-			other_above = 0;
+			old_pid = pid_sup[j + ad->x];
+			pid_sup[j + ad->x] = pid_curr[j + ad->x];
+			
+			for (k = j + 1; k < ad->cl; k++) {
+			    if (pid_sup[k + ad->x] == old_pid) {
+				pid_sup[k + ad->x] = pid_curr[j + ad->x];
+			    }
+			}
 		    }
 		}
+
+		other_above = 0;
+		connected = 1;
 	    }
-	    if (!connected &&
-		sup[ad->cl - 1 + ad->x] != buf[ad->cl - 1 + ad->x]) {
-		if (!Rast_is_null_value
-		    (&(buf[ad->cl - 1 + ad->x]), CELL_TYPE)) {
-		    count++;
-		    complete_line = 0;
+
+	    if (!connected) {
+		count++;
+		pid++;
+		pid_curr[j + ad->x] = pid;
+	    }
+
+	    if (j < ad->cl - 1) {
+		if (buf[j + ad->x] == buf[j + 1 + ad->x]) {
+		    
+		    connected = 1;
+		    pid_curr[j + 1 + ad->x] = pid_curr[j + ad->x];
 		}
+		else {
+		    other_above = 1;
+		    connected = 0;
+		}
 	    }
-
-	    if (complete_line)
-		complete_value = buf[ad->x];
-
 	}
-
     }
 
     *result = count;
 
-    G_free(sup);
+    if (ad->mask == 1) {
+	G_free(mask_buf);
+    }
+    G_free(cnull);
+    G_free(pid_curr);
+    G_free(pid_sup);
+
     return RLI_OK;
 }



More information about the grass-commit mailing list