[GRASS-SVN] r59305 - in grass/branches/releasebranch_6_4/raster/r.li: . r.li.cwed r.li.daemon r.li.dominance r.li.edgedensity r.li.mpa r.li.mps r.li.padcv r.li.padrange r.li.padsd r.li.patchdensity r.li.patchnum r.li.pielou r.li.renyi r.li.richness r.li.shannon r.li.shape r.li.simpson
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon Mar 24 04:43:14 PDT 2014
Author: neteler
Date: 2014-03-24 04:43:14 -0700 (Mon, 24 Mar 2014)
New Revision: 59305
Added:
grass/branches/releasebranch_6_4/raster/r.li/r.li.cwed/weight.csv
Removed:
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/index.h
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/ipc.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/main.c.unused
Modified:
grass/branches/releasebranch_6_4/raster/r.li/TODO
grass/branches/releasebranch_6_4/raster/r.li/r.li.cwed/cwed.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.cwed/description.html
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/Makefile
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avl.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avl.h
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avlID.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avlID.h
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/daemon.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/daemon.h
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/description.html
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/ipc.h
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/list.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/list.h
grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/worker.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.dominance/dominance.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.edgedensity/edgedensity.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.mpa/mpa.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.mps/mps.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.padcv/padcv.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.padrange/padrange.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.padsd/padsd.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.patchdensity/main.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.patchnum/main.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.pielou/pielou.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.renyi/renyi.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.richness/richness.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.shannon/shannon.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.shape/main.c
grass/branches/releasebranch_6_4/raster/r.li/r.li.simpson/simpson.c
Log:
r.li.*: backport of rewrite in trunk (trac #1214)
Modified: grass/branches/releasebranch_6_4/raster/r.li/TODO
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/TODO 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/TODO 2014-03-24 11:43:14 UTC (rev 59305)
@@ -1,5 +1,54 @@
TODO list
+=========
+Brute-force testing
+-------------------
+# TODO: change to/add 3x3 example
+
+# 7x7 moving window test:
+# still Spearfish...
+
+# created as described in EXAMPLES, moving window r.li.setup/description.html:
+echo "SAMPLINGFRAME 0|0|1|1
+SAMPLEAREA -1|-1|0.015021459227467811|0.011058451816745656
+MOVINGWINDOW" > $HOME/.r.li/history/movwindow7
+
+export GRASS_OVERWRITE=1
+g.region rast=landcover.30m -p
+r.mapcalc "forests = if(landcover.30m >= 41 && landcover.30m <= 43,1,null())"
+
+MEASURE="dominance edgedensity mpa mps padcv padrange padsd patchdensity patchnum pielou richness shannon shape simpson"
+
+for mymeasure in $MEASURE ; do
+ r.li.${mymeasure} input=forests conf=movwindow7 out=forests_${mymeasure}_mov7
+ r.univar forests_${mymeasure}_mov7
+done
+
+# also alpha:
+r.li.renyi input=forests conf=movwindow7 out=forests_renyi_mov7_a06 alpha=0.6
+r.univar forests_renyi_mov7_a06
+
+echo "End of r.li tests"
+
+
+========================
+North Carolina tests
+
+echo "SAMPLINGFRAME 0|0|1|1
+SAMPLEAREA 0.0|0.0|1.0|1.0" > $HOME/.r.li/history/landsat_test
+
+g.region rast=lsat7_2002_40 -p
+r.li.shannon input=lsat7_2002_40 conf=landsat_test out=landsat_shannon
+--> Result written to ASCII file <$HOME/.r.li/output/landsat_shannon>
+
+
+
+===============================================================
+GRASS 6
+-------
+
+TODO: backport all GRASS 7 fixes
+
A few remaining things should be done soon:
- add relevant references
- use English variable names in C code
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.cwed/cwed.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.cwed/cwed.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.cwed/cwed.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -1,19 +1,26 @@
-/*
- * \brief calculates contrast weighted edge density index
+
+/****************************************************************************
*
- * \AUTHOR: Serena Pallecchi student of Computer Science University of Pisa (Italy)
- * Commission from Faunalia Pontedera (PI) www.faunalia.it
+ * MODULE: r.li.cwed
+ * AUTHOR(S): Serena Pallecchi student of Computer Science University of Pisa (Italy)
+ * Commission from Faunalia Pontedera (PI) www.faunalia.it
+ * Markus Metz
*
- * This program is free software under the GPL (>=v2)
- * Read the COPYING file that comes with GRASS for details.
- *
- */
+ * PURPOSE: calculates contrast weighted edge density index
+ * COPYRIGHT: (C) 2006-2014 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 <fcntl.h> /* for O_RDONLY usage */
+
#include <grass/gis.h>
#include <grass/glocale.h>
-#include <fcntl.h> /* for O_RDONLY usage */
-
#include "../r.li.daemon/defs.h"
#include "../r.li.daemon/daemon.h"
@@ -25,6 +32,7 @@
#define _PRES 1
#define _ERR -1
+rli_func contrastWeightedEdgeDensity;
int calculate(int fd, struct area_entry *ad, Coppie * cc, long totCoppie,
double *result);
int calculateD(int fd, struct area_entry *ad, Coppie * cc, long totCoppie,
@@ -80,12 +88,10 @@
double *result)
{
double indice = 0; /* the result */
- struct Cell_head hd;
int i = 0;
int file_fd = -1;
int l; /*number of read byte */
int ris = 0;
- char *mapset;
char *file;
char *strFile;
char row[NMAX]; /* to read the file */
@@ -146,14 +152,6 @@
return RLI_ERRORE;
}
- mapset = G_find_cell(ad->raster, "");
-
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1) {
- G_fatal_error("can't read raster header");
- return RLI_ERRORE;
- }
-
-
for (i = 0; i < totRow; i++) {
long num = 0;
char **b;
@@ -293,14 +291,16 @@
int i = 0, j;
int mask_fd = -1;
int masked = FALSE;
- int *mask_corr, *mask_sup;
+ int *mask_corr = NULL, *mask_sup = NULL, *mask_tmp;
- CELL *buf_corr, *buf_sup;
+ CELL *buf_corr, *buf_sup, *buf_null;
CELL prevCell, corrCell, supCell;
generic_cell c1;
generic_cell c2;
+ if (ad->rl < 2)
+ G_fatal_error(_("Row cache is too small"));
/* open mask if needed */
if (ad->mask == 1) {
@@ -314,32 +314,30 @@
G_fatal_error("malloc mask_corr failed");
return RLI_ERRORE;
}
-
mask_sup = G_malloc(ad->cl * sizeof(int));
if (mask_sup == NULL) {
- G_fatal_error("malloc mask_sup failed");
+ G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ for (j = 0; j < ad->cl; j++)
+ mask_corr[j] = 0;
masked = TRUE;
}
- buf_sup = G_allocate_cell_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
+ buf_null = G_allocate_cell_buf();
+ if (buf_null == NULL) {
+ G_fatal_error("malloc buf_null failed");
return RLI_ERRORE;
}
c1.t = CELL_TYPE;
c2.t = CELL_TYPE;
- buf_corr = G_allocate_cell_buf();
- if (buf_corr == NULL) {
- G_fatal_error("error malloc buf_corr");
- return RLI_ERRORE;
- }
+ /*the first time buf_sup is all null */
+ G_set_c_null_value(buf_null + ad->x, ad->cl);
+ buf_sup = buf_null;
- G_set_c_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
for (j = 0; j < ad->rl; j++) { /* for each row */
/* read row of raster */
buf_corr = RLI_get_cell_raster_row(fd, j + ad->y, ad);
@@ -348,6 +346,9 @@
}
/*read mask if needed */
if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_corr;
+ mask_corr = mask_tmp;
if (read(mask_fd, mask_corr, (ad->cl * sizeof(int))) < 0) {
G_fatal_error("reading mask_corr");
return RLI_ERRORE;
@@ -357,14 +358,20 @@
G_set_c_null_value(&prevCell, 1);
G_set_c_null_value(&corrCell, 1);
for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
- area++;
corrCell = buf_corr[i + ad->x];
- if (masked && mask_corr[i + ad->x] == 0) {
- area--;
+ if (masked && mask_corr[i] == 0) {
G_set_c_null_value(&corrCell, 1);
}
+ else {
+ /* total sample area */
+ area++;
+ }
+
if (!(G_is_null_value(&corrCell, CELL_TYPE))) {
supCell = buf_sup[i + ad->x];
+ if (masked && (mask_sup[i] == 0)) {
+ G_set_c_null_value(&supCell, 1);
+ }
/* calculate how many edges the cell has */
if (((!G_is_null_value(&prevCell, CELL_TYPE))) &&
@@ -391,11 +398,8 @@
return RLI_ERRORE;
}
}
- prevCell = buf_corr[i + ad->x];
+ prevCell = corrCell;
}
-
- if (masked)
- mask_sup = mask_corr;
}
/* calcolo dell'indice */
@@ -419,7 +423,8 @@
G_free(mask_sup);
}
- G_free(buf_sup);
+ G_free(buf_null);
+
return RLI_OK;
}
@@ -434,16 +439,17 @@
int i = 0, j;
int mask_fd = -1;
int masked = FALSE;
- int *mask_corr, *mask_sup;
+ int *mask_corr = NULL, *mask_sup = NULL, *mask_tmp;
- DCELL *buf_corr, *buf_sup;
+ DCELL *buf_corr, *buf_sup, *buf_null;
DCELL prevCell, corrCell, supCell;
generic_cell c1;
generic_cell c2;
+ if (ad->rl < 2)
+ G_fatal_error(_("Row cache is too small"));
-
/* open mask if needed */
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) {
@@ -456,29 +462,30 @@
G_fatal_error("malloc mask_corr failed");
return RLI_ERRORE;
}
-
mask_sup = G_malloc(ad->cl * sizeof(int));
if (mask_sup == NULL) {
- G_fatal_error("malloc mask_corr failed");
+ G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ for (j = 0; j < ad->cl; j++)
+ mask_corr[j] = 0;
masked = TRUE;
}
- buf_sup = G_allocate_d_raster_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
+ buf_null = G_allocate_d_raster_buf();
+ if (buf_null == NULL) {
+ G_fatal_error("malloc buf_null failed");
return RLI_ERRORE;
}
c1.t = DCELL_TYPE;
c2.t = DCELL_TYPE;
- buf_corr = G_allocate_d_raster_buf();
+ /*the first time buf_sup is all null */
+ G_set_d_null_value(buf_null + ad->x, ad->cl);
+ buf_sup = buf_null;
- G_set_d_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
-
for (j = 0; j < ad->rl; j++) { /* for each row */
/* read row of raster */
buf_corr = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
@@ -487,6 +494,9 @@
}
/*read mask if needed */
if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_corr;
+ mask_corr = mask_tmp;
if (read(mask_fd, mask_corr, (ad->cl * sizeof(int))) < 0) {
G_fatal_error("reading mask_corr");
return RLI_ERRORE;
@@ -495,15 +505,22 @@
G_set_d_null_value(&prevCell, 1);
G_set_d_null_value(&corrCell, 1);
for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
- area++;
corrCell = buf_corr[i + ad->x];
- if (masked && mask_corr[i + ad->x] == 0) {
+ if (masked && mask_corr[i] == 0) {
G_set_d_null_value(&corrCell, 1);
- area--;
}
+ else {
+ /* total sample area */
+ area++;
+ }
+
if (!(G_is_null_value(&corrCell, DCELL_TYPE))) {
supCell = buf_sup[i + ad->x];
- /* calculate how many edge the cell has */
+ if (masked && (mask_sup[i] == 0)) {
+ G_set_d_null_value(&supCell, 1);
+ }
+
+ /* calculate how many edges the cell has */
if (((!G_is_null_value(&prevCell, DCELL_TYPE))) &&
(corrCell != prevCell)) {
int r = 0;
@@ -528,11 +545,8 @@
}
}
- prevCell = buf_corr[i + ad->x];
+ prevCell = corrCell;
}
-
- if (masked)
- mask_sup = mask_corr;
}
/* calcolo dell'indice */
@@ -554,6 +568,9 @@
G_free(mask_corr);
G_free(mask_sup);
}
+
+ G_free(buf_null);
+
return RLI_OK;
}
@@ -569,16 +586,17 @@
int i = 0, j;
int mask_fd = -1;
int masked = FALSE;
- int *mask_corr, *mask_sup;
+ int *mask_corr = NULL, *mask_sup = NULL, *mask_tmp;
- FCELL *buf_corr, *buf_sup;
+ FCELL *buf_corr, *buf_sup, *buf_null;
FCELL prevCell, corrCell, supCell;
generic_cell c1;
generic_cell c2;
+ if (ad->rl < 2)
+ G_fatal_error(_("Row cache is too small"));
-
/* open mask if needed */
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) {
@@ -591,30 +609,27 @@
G_fatal_error("malloc mask_corr failed");
return RLI_ERRORE;
}
-
mask_sup = G_malloc(ad->cl * sizeof(int));
if (mask_sup == NULL) {
- G_fatal_error("malloc mask_sup failed");
+ G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ for (j = 0; j < ad->cl; j++)
+ mask_corr[j] = 0;
masked = TRUE;
}
/* allocate and inizialize buffers */
- buf_sup = G_allocate_f_raster_buf();
- if (buf_sup == NULL) {
+ buf_null = G_allocate_f_raster_buf();
+ if (buf_null == NULL) {
G_fatal_error("malloc buf_sup failed");
return RLI_ERRORE;
}
- G_set_f_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
+ /*the first time buf_sup is all null */
+ G_set_f_null_value(buf_null + ad->x, ad->cl);
+ buf_sup = buf_null;
- buf_corr = G_allocate_f_raster_buf();
- if (buf_corr == NULL) {
- G_fatal_error("malloc buf_corr failed");
- return RLI_ERRORE;
- }
-
c1.t = FCELL_TYPE;
c2.t = FCELL_TYPE;
@@ -627,6 +642,9 @@
}
/*read mask if needed */
if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_corr;
+ mask_corr = mask_tmp;
if (read(mask_fd, mask_corr, (ad->cl * sizeof(int))) < 0) {
G_fatal_error("reading mask_corr");
return RLI_ERRORE;
@@ -635,21 +653,28 @@
G_set_f_null_value(&prevCell, 1);
G_set_f_null_value(&corrCell, 1);
for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
- area++;
corrCell = buf_corr[i + ad->x];
- if (masked && mask_corr[i + ad->x] == 0) {
+ if (masked && mask_corr[i] == 0) {
G_set_f_null_value(&corrCell, 1);
- area--;
}
+ else {
+ /* total sample area */
+ area++;
+ }
+
if (!(G_is_null_value(&corrCell, FCELL_TYPE))) {
supCell = buf_sup[i + ad->x];
+ if (masked && (mask_sup[i] == 0)) {
+ G_set_f_null_value(&supCell, 1);
+ }
+ /* calculate how many edges the cell has */
if (((!G_is_null_value(&prevCell, FCELL_TYPE))) &&
(corrCell != prevCell)) {
int r = 0;
- c1.val.dc = corrCell;
- c2.val.dc = prevCell;
+ c1.val.fc = corrCell;
+ c2.val.fc = prevCell;
r = updateCoppia(cc, c1, c2, totCoppie);
if (r == RLI_ERRORE)
return RLI_ERRORE;
@@ -667,11 +692,8 @@
}
}
- prevCell = buf_corr[i + ad->x];
+ prevCell = corrCell;
}
-
- if (masked)
- mask_sup = mask_corr;
}
/* calcolo dell'indice */
@@ -693,6 +715,9 @@
G_free(mask_corr);
G_free(mask_sup);
}
+
+ G_free(buf_null);
+
return RLI_OK;
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.cwed/description.html
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.cwed/description.html 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.cwed/description.html 2014-03-24 11:43:14 UTC (rev 59305)
@@ -42,7 +42,7 @@
<em>my_conf</em> configuration file (previously defined with
<em>r.li.setup</em>) and saving results in <em>my_out</em>, run:
<div class="code"><pre>
-r.li.cwed map=my_map conf=my_conf path=my_file output=my_out \
+r.li.cwed map=my_map conf=my_conf output=my_out \
path=/path/to/weights.csv
</pre></div>
Added: grass/branches/releasebranch_6_4/raster/r.li/r.li.cwed/weight.csv
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.cwed/weight.csv (rev 0)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.cwed/weight.csv 2014-03-24 11:43:14 UTC (rev 59305)
@@ -0,0 +1,4 @@
+12,16,0.65
+44,123,0.32
+56,12,0.54
+23,66,0.99
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/Makefile
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/Makefile 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/Makefile 2014-03-24 11:43:14 UTC (rev 59305)
@@ -4,7 +4,7 @@
LIB_NAME = grass_rli.$(GRASS_VERSION_NUMBER)
-LIB_OBJS = daemon.o list.o ipc.o worker.o GenericCell.o avl.o avlID.o
+LIB_OBJS = daemon.o list.o worker.o GenericCell.o avl.o avlID.o
DEPENDENCIES = $(GISDEP)
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avl.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avl.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avl.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -57,7 +57,32 @@
return root;
}
+void avl_destroy(avl_tree root)
+{
+ struct avl_node *it;
+ struct avl_node *save = root;
+ /*
+ Rotate away the left links so that
+ we can treat this like the destruction
+ of a linked list
+ */
+ while((it = save) != NULL) {
+ if (it->left_child == NULL) {
+ /* No left links, just kill the node and move on */
+ save = it->right_child;
+ G_free(it);
+ it = NULL;
+ }
+ else {
+ /* Rotate away the left link and check again */
+ save = it->left_child;
+ it->left_child = save->right_child;
+ save->right_child = it;
+ }
+ }
+}
+
long howManyCell(const avl_tree root, const generic_cell k)
{
avl_node *nodo = NULL;
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avl.h
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avl.h 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avl.h 2014-03-24 11:43:14 UTC (rev 59305)
@@ -34,6 +34,7 @@
/* prototype of functions */
avl_tree avl_make(const generic_cell k, const long n);
+void avl_destroy(avl_tree root);
avl_node *avl_find(const avl_tree root, const generic_cell k);
int avl_add(avl_tree * root, const generic_cell k, const long n);
long avl_to_array(avl_node * root, long i, AVL_table * a);
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avlID.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avlID.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avlID.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -49,7 +49,32 @@
return root;
}
+void avlID_destroy(avlID_tree root)
+{
+ struct avlID_node *it;
+ struct avlID_node *save = root;
+ /*
+ Rotate away the left links so that
+ we can treat this like the destruction
+ of a linked list
+ */
+ while((it = save) != NULL) {
+ if (it->left_child == NULL) {
+ /* No left links, just kill the node and move on */
+ save = it->right_child;
+ G_free(it);
+ it = NULL;
+ }
+ else {
+ /* Rotate away the left link and check again */
+ save = it->left_child;
+ it->left_child = save->right_child;
+ save->right_child = it;
+ }
+ }
+}
+
long howManyID(const avlID_tree root, const long k)
{
avlID_node *nodo = NULL;
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avlID.h
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avlID.h 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/avlID.h 2014-03-24 11:43:14 UTC (rev 59305)
@@ -29,6 +29,7 @@
/* prototype of functions */
avlID_tree avlID_make(const long k, const long n);
+void avlID_destroy(avlID_tree root);
avlID_node *avlID_find(const avlID_tree root, const long k);
int avlID_add(avlID_tree * root, const long k, const long n);
long avlID_to_array(avlID_node * root, long i, avlID_table * a);
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/daemon.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/daemon.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/daemon.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -40,27 +40,17 @@
#define random rand
#endif
-int calculateIndex(char *file, int f(int, char **, struct area_entry *, double *),
+int calculateIndex(char *file, rli_func *f,
char **parameters, char *raster, char *output)
{
char pathSetup[GPATH_MAX], out[GPATH_MAX], parsed;
- char *reportChannelName, *random_access_name;
+ char *random_access_name;
struct History history;
struct g_area *g;
- int receiveChannel;
int res;
- int i, mypid, doneDir, withoutJob, mv_fd, random_access;
+ int i, doneDir, mv_fd, random_access;
- int num_workers;
- /* check if environment variable override was set */
- const char *p = getenv("WORKERS");
- num_workers = p ? atoi(p) : DEFAULT_WORKERS;
- if ((num_workers <= 0) || (num_workers > 1e6))
- G_fatal_error(_("Invalid number of workers: [%s]"), p);
-
- wd child[num_workers];
-
/* int mv_rows, mv_cols; */
struct list *l;
msg m, doneJob;
@@ -71,48 +61,10 @@
l->head = NULL;
l->tail = NULL;
l->size = 0;
- mypid = getpid();
- /* create report pipe */
- reportChannelName = G_tempfile();
- if (mkfifo(reportChannelName, 0644) == -1)
- G_fatal_error("Error in pipe creation");
+ worker_init(raster, f, parameters);
- /*###############################################
- --------------create childs-------------------
- ############################################### */
-
- i = 0;
- while (i < num_workers) {
- int childpid;
-
- /*creating pipe */
- child[i].pipe = G_tempfile();
- if (mkfifo(child[i].pipe, 0755) == -1)
- G_fatal_error(_("Error in pipe creation"));
- childpid = fork();
- if (childpid) {
- /*father process */
- child[i].pid = childpid;
- child[i].channel = open(child[i].pipe, O_WRONLY | O_CREAT, 0755);
-
- if (child[i].channel == -1) {
- G_fatal_error(_("Error opening channel %i"), i);
- }
- i++;
- }
- else {
- /*child process */
- worker(raster, f, reportChannelName, child[i].pipe, parameters);
- exit(0);
- }
- }
-
- /*open reportChannel */
- receiveChannel = open(reportChannelName, O_RDONLY, 0755);
-
-
- /*########################################################
+ /*#########################################################
-----------------create area queue----------------------
######################################################### */
@@ -124,6 +76,7 @@
file += strlen(testpath);
/* TODO: check if this path is portable */
+ /* TODO: use G_rc_path() */
sprintf(pathSetup, "%s/.r.li/history/%s", G_home(), file);
G_debug(1, "r.li.daemon pathSetup: [%s]", pathSetup);
parsed = parseSetup(pathSetup, l, g, raster);
@@ -150,10 +103,17 @@
/* text file output */
/* check if ~/.r.li/output exists */
sprintf(out, "%s/.r.li/", G_home());
+ doneDir = G_mkdir(out);
+ if (doneDir == -1 && errno != EEXIST)
+ G_fatal_error(_("Cannot create %s/.r.li/ directory"), G_home());
+ /* check if ~/.r.li/ exists */
+ sprintf(out, "%s/.r.li/", G_home());
doneDir = G_mkdir(out);
if (doneDir == -1 && errno != EEXIST)
G_fatal_error(_("Cannot create %s/.r.li/ directory"), G_home());
+
+ /* check if ~/.r.li/output exists */
sprintf(out, "%s/.r.li/output", G_home());
doneDir = G_mkdir(out);
if (doneDir == -1 && errno != EEXIST)
@@ -167,22 +127,16 @@
/*#######################################################
------------------analysis loop----------------------
####################################################### */
- /* first job scheduling */
- while ((i < num_workers) && next_Area(parsed, l, g, &m) != 0) {
- send(child[i].channel, &m);
- i++;
- }
/*body */
while (next_Area(parsed, l, g, &m) != 0) {
- int j = 0, donePid;
+ worker_process(&doneJob, &m);
- receive(receiveChannel, &doneJob);
-
+ /*perc++; */
+ /*G_percent (perc, WORKERS, 1); */
if (doneJob.type == DONE) {
double result;
- donePid = doneJob.f.f_d.pid;
result = doneJob.f.f_d.res;
/* output */
if (parsed != MVWIN) {
@@ -196,7 +150,6 @@
}
}
else {
- donePid = doneJob.f.f_e.pid;
if (parsed != MVWIN) {
/* text file output */
error_Output(res, doneJob);
@@ -206,97 +159,10 @@
/* TODO write to raster NULL ??? */
}
}
- j = 0;
-
-
- while (j < num_workers && donePid != child[j].pid)
- j++;
-
- send(child[j].channel, &m);
-
}
- /* kill childs */
- withoutJob = i;
- while (i > 0) {
- int j = 0, donePid, status;
+ worker_end();
- receive(receiveChannel, &doneJob);
- if (doneJob.type == DONE) {
- double result;
-
- donePid = doneJob.f.f_d.pid;
- result = doneJob.f.f_d.res;
- if (parsed != MVWIN) {
- /* text file output */
- print_Output(res, doneJob);
- }
- else {
- /* raster output */
- raster_Output(random_access, doneJob.f.f_d.aid, g,
- doneJob.f.f_d.res);
- }
- }
- else {
- donePid = doneJob.f.f_e.pid;
- if (parsed != MVWIN) {
- /* text file output */
- error_Output(res, doneJob);
- }
- else {
- /* printf("todo2 "); fflush(stdout); */
- /* TODO write to raster */
- }
- }
-
- i--;
-
- while (j < num_workers && donePid != child[j].pid)
- j++;
-
- m.type = TERM;
- m.f.f_t.pid = mypid;
- send(child[j].channel, &m);
- wait(&status);
-
- if (!(WIFEXITED(status)))
- G_warning(_("r.li.worker (pid %i) exited with abnormal status: %i"),
- donePid, status);
- else
- G_verbose_message(_("r.li.worker (pid %i) terminated successfully"),
- donePid);
-
- /* remove pipe */
- if (close(child[j].channel) != 0)
- G_message(_("Cannot close %s file (PIPE)"), child[j].pipe);
- if (unlink(child[j].pipe) != 0)
- G_message(_("Cannot delete %s file (PIPE)"), child[j].pipe);
- }
-
- /* kill children without Job */
- for (i = withoutJob; i < num_workers; i++) {
- int status;
-
- m.type = TERM;
- m.f.f_t.pid = mypid;
- send(child[i].channel, &m);
- wait(&status);
-
- if (!(WIFEXITED(status)))
- G_warning(_("r.li.worker (pid %i) exited with abnormal status: %i"),
- child[i].pid, status);
- else
- G_verbose_message(_("r.li.worker (pid %i) terminated successfully"),
- child[i].pid);
-
- /* remove pipe */
- if (close(child[i].channel) != 0)
- G_message(_("Cannot close %s file (PIPE2)"), child[i].pipe);
- if (unlink(child[i].pipe) != 0)
- G_message(_("Cannot delete %s file (PIPE2)"), child[i].pipe);
- }
-
-
/*################################################
--------------delete tmp files------------------
################################################ */
@@ -309,17 +175,12 @@
G_short_history(output, "raster", &history);
G_command_history(&history);
G_write_history(output, &history);
+ G_message(_("Raster map <%s> created."), output);
} else {
/* text file output */
G_message("Result written to ASCII file <%s>", out);
}
- if (close(receiveChannel) != 0)
- G_message(_("Cannot close receive channel file"));
-
- if (unlink(reportChannelName) != 0)
- G_message(_("Cannot delete %s file"), child[i].pipe);
-
return 1;
}
@@ -328,12 +189,14 @@
{
struct stat s;
struct Cell_head cellhd;
- char *buf, *token, *mapset; /* *raster_fqn, */
+ char *buf, *mapset; /* *raster_fqn, */
+ const char *token;
int setup;
int letti;
double rel_x, rel_y, rel_rl, rel_cl;
double sf_n, sf_s, sf_e, sf_w;
int sf_x, sf_y, sf_rl, sf_cl;
+ int sa_x, sa_y, sa_rl, sa_cl;
int size;
if (stat(path, &s) != 0)
@@ -366,11 +229,28 @@
if (G_get_cellhd(raster, mapset, &cellhd) == -1)
G_fatal_error(_("Cannot read raster header file"));
+ /* use current region ! */
+ G_get_window(&cellhd);
+
/* calculate absolute sampling frame definition */
sf_x = (int)rint(cellhd.cols * rel_x);
sf_y = (int)rint(cellhd.rows * rel_y);
sf_rl = (int)rint(cellhd.rows * rel_rl);
sf_cl = (int)rint(cellhd.cols * rel_cl);
+
+ /* sanity check */
+ if (sf_x < 0)
+ sf_x = 0;
+ if (sf_y < 0)
+ sf_y = 0;
+ if (sf_x > cellhd.cols)
+ sf_x = cellhd.cols;
+ if (sf_y > cellhd.rows)
+ sf_y = cellhd.rows;
+ if (sf_rl > cellhd.rows - sf_y)
+ sf_rl = cellhd.rows - sf_y;
+ if (sf_cl > cellhd.cols - sf_x)
+ sf_cl = cellhd.cols - sf_x;
/* calculate sample frame boundaries */
sf_n = cellhd.north - (cellhd.ns_res * sf_y);
@@ -393,19 +273,28 @@
if (rel_sa_x == -1.0 && rel_sa_y == -1.0) {
/* runtime disposition */
- int sa_rl, sa_cl;
sa_rl = (int)rint(cellhd.rows * rel_sa_rl);
sa_cl = (int)rint(cellhd.cols * rel_sa_cl);
+
+ /* sanity check */
+ if (sa_rl > cellhd.rows - sf_y)
+ sa_rl = cellhd.rows - sf_y;
+ if (sa_cl > cellhd.cols - sf_x)
+ sa_cl = cellhd.cols - sf_x;
+
+ /* total sample area */
g->rows = sf_rl;
g->cols = sf_cl;
+ g->x = sf_x;
+ g->y = sf_y;
+ /* current sample area (subset of total sample area) */
g->rl = sa_rl;
g->cl = sa_cl;
- g->count = 1;
g->sf_x = sf_x;
g->sf_y = sf_y;
- g->x = sf_x;
- g->y = sf_y;
+
+ g->count = 1;
g->maskname = NULL;
return disposeAreas(l, g, strtok(NULL, "\n"));
@@ -416,10 +305,30 @@
toReturn = NORMAL;
/*read file and create list */
m.type = AREA;
- m.f.f_a.x = (int)rint(cellhd.cols * rel_sa_x);
- m.f.f_a.y = (int)rint(cellhd.rows * rel_sa_y);
- m.f.f_a.rl = (int)rint(cellhd.rows * rel_sa_rl);
- m.f.f_a.cl = (int)rint(cellhd.cols * rel_sa_cl);
+ /* current sample area (subset of total sample area) */
+ sa_x = (int)rint(cellhd.cols * rel_sa_x);
+ sa_y = (int)rint(cellhd.rows * rel_sa_y);
+ sa_rl = (int)rint(cellhd.rows * rel_sa_rl);
+ sa_cl = (int)rint(cellhd.cols * rel_sa_cl);
+
+ /* sanity check */
+ if (sa_x < 0)
+ sa_x = 0;
+ if (sa_y < 0)
+ sa_y = 0;
+ if (sa_x > cellhd.cols)
+ sa_x = cellhd.cols;
+ if (sa_y > cellhd.rows)
+ sa_y = cellhd.rows;
+ if (sa_rl > cellhd.rows - sa_y)
+ sa_rl = cellhd.rows - sa_y;
+ if (sa_cl > cellhd.cols - sa_x)
+ sa_cl = cellhd.cols - sa_x;
+
+ m.f.f_a.x = sa_x;
+ m.f.f_a.y = sa_y;
+ m.f.f_a.rl = sa_rl;
+ m.f.f_a.cl = sa_cl;
m.f.f_a.aid = aid;
aid++;
insertNode(l, m);
@@ -445,17 +354,25 @@
if (rel_sa_x == -1 && rel_sa_y == -1) {
/* runtime disposition */
- int sa_rl, sa_cl;
sa_rl = (int)rint(cellhd.rows * rel_sa_rl);
sa_cl = (int)rint(cellhd.cols * rel_sa_cl);
+
+ /* sanity check */
+ if (sa_rl > cellhd.rows - sf_y)
+ sa_rl = cellhd.rows - sf_y;
+ if (sa_cl > cellhd.cols - sf_x)
+ sa_cl = cellhd.cols - sf_x;
+
+ /* total sample area */
g->rows = sf_rl;
g->cols = sf_cl;
+ g->x = sf_x;
+ g->y = sf_y;
+ /* current sample area (subset of total sample area) */
g->rl = sa_rl;
g->cl = sa_cl;
g->count = 1;
- g->x = sf_x;
- g->y = sf_y;
g->maskname = maskname;
return disposeAreas(l, g, strtok(NULL, "\n"));
}
@@ -464,10 +381,30 @@
msg m;
m.type = MASKEDAREA;
- m.f.f_ma.x = (int)rint(cellhd.cols * rel_sa_x);
- m.f.f_ma.y = (int)rint(cellhd.rows * rel_sa_y);
- m.f.f_ma.rl = (int)rint(cellhd.rows * rel_sa_rl);
- m.f.f_ma.cl = (int)rint(cellhd.cols * rel_sa_cl);
+ /* current sample area (subset of total sample area) */
+ sa_x = (int)rint(cellhd.cols * rel_sa_x);
+ sa_y = (int)rint(cellhd.rows * rel_sa_y);
+ sa_rl = (int)rint(cellhd.rows * rel_sa_rl);
+ sa_cl = (int)rint(cellhd.cols * rel_sa_cl);
+
+ /* sanity check */
+ if (sa_x < 0)
+ sa_x = 0;
+ if (sa_y < 0)
+ sa_y = 0;
+ if (sa_x > cellhd.cols)
+ sa_x = cellhd.cols;
+ if (sa_y > cellhd.rows)
+ sa_y = cellhd.rows;
+ if (sa_rl > cellhd.rows - sa_y)
+ sa_rl = cellhd.rows - sa_y;
+ if (sa_cl > cellhd.cols - sa_x)
+ sa_cl = cellhd.cols - sa_x;
+
+ m.f.f_ma.x = sa_x;
+ m.f.f_ma.y = sa_y;
+ m.f.f_ma.rl = sa_rl;
+ m.f.f_ma.cl = sa_cl;
m.f.f_ma.aid = aid;
strcpy(m.f.f_ma.mask, maskname);
aid++;
@@ -485,12 +422,11 @@
double sa_n, sa_s, sa_w, sa_e;
int aid = 1;
char maskname[GNAME_MAX] = {'\0'};
- struct Cell_head window;
msg m;
/* Get the window setting. g.region rast=<input raster> */
/* ? same as cellhd above ? */
- G_get_window(&window);
+ /* no. the current window might be different */
do {
strcpy(maskname, strtok(NULL, "|"));
@@ -501,21 +437,40 @@
m.type = MASKEDAREA;
- /* Each input overlay area from input vector are converted to raster
- via v.to.rast. See r.li.setup/sample_area_vector.sh. This is to used
- only for reading the region (NS, EW). */
+ /* Each input overlay area from input vector are converted to
+ raster via v.to.rast. See r.li.setup/sample_area_vector.sh.
+ This is used only for reading the region (NS, EW). */
- /* Get start x and y position of masked overlay raster with respect
- to input raster region from window.
- sa_n, sa_e are read from configuration file. */
+ /* current sample area (subset of total sample area) */
- m.f.f_ma.x = (int)G_easting_to_col(sa_e, &window);
- m.f.f_ma.y = (int)G_northing_to_row(sa_n, &window);
+ /* Get start x and y position of masked overlay raster with
+ respect to current region.
+ sa_n, sa_w are read from configuration file. */
+ sa_x = (int)rint((sa_w - cellhd.west) / cellhd.ew_res);
+ sa_y = (int)rint((cellhd.north - sa_n) / cellhd.ns_res);
/* Get row count and column count of overlay raster */
- m.f.f_ma.rl = (int)rint((sa_n - sa_s) / cellhd.ns_res);
- m.f.f_ma.cl = (int)rint((sa_e - sa_w) / cellhd.ew_res);
+ sa_rl = (int)rint((sa_n - sa_s) / cellhd.ns_res);
+ sa_cl = (int)rint((sa_e - sa_w) / cellhd.ew_res);
+ /* sanity check */
+ if (sa_x < 0)
+ sa_x = 0;
+ if (sa_y < 0)
+ sa_y = 0;
+ if (sa_x > cellhd.cols)
+ sa_x = cellhd.cols;
+ if (sa_y > cellhd.rows)
+ sa_y = cellhd.rows;
+ if (sa_rl > cellhd.rows - sa_y)
+ sa_rl = cellhd.rows - sa_y;
+ if (sa_cl > cellhd.cols - sa_x)
+ sa_cl = cellhd.cols - sa_x;
+
+ m.f.f_ma.x = sa_x;
+ m.f.f_ma.y = sa_y;
+ m.f.f_ma.rl = sa_rl;
+ m.f.f_ma.cl = sa_cl;
m.f.f_ma.aid = aid;
strcpy(m.f.f_ma.mask, maskname);
aid++;
@@ -710,7 +665,10 @@
char s[100];
int len;
- sprintf(s, "RESULT %i|%f\n", m.f.f_d.aid, m.f.f_d.res);
+ if (G_is_null_value(&m.f.f_d.res, DCELL_TYPE))
+ sprintf(s, "RESULT %i|NULL\n", m.f.f_d.aid);
+ else
+ sprintf(s, "RESULT %i|%.15g\n", m.f.f_d.aid, m.f.f_d.res);
len = strlen(s);
if (write(out, s, len) == len)
@@ -787,6 +745,7 @@
}
G_put_raster_row(mv_fd, cell_buf, DCELL_TYPE);
+
}
G_set_d_null_value(cell_buf, G_window_cols() + 1);
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/daemon.h
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/daemon.h 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/daemon.h 2014-03-24 11:43:14 UTC (rev 59305)
@@ -22,10 +22,6 @@
#include "defs.h"
-/**
- * \brief number of r.li.workers to use
- */
-#define DEFAULT_WORKERS 10
#define NORMAL 1
#define MVWIN 2
#define GEN 3
@@ -99,10 +95,11 @@
/**
* \brief fields of an area descriptor
- * \member x the x coordinate of upper left corner
- * \member y the y coordinate of upper left corner
- * \member rl area length in rows
- * \member cl area length in columns
+ * \member x column offset = start of sample area
+ * \member y row offset = start of sample area
+ * \member rl sample area length in rows
+ * \member cl sample area length in columns
+ * \member rc number of rows in the cache
* \member mask file descriptor of mask raster file (-1 if there is no mask)
*/
struct area_entry
@@ -111,6 +108,7 @@
int y;
int rl;
int cl;
+ int rc;
int mask;
int data_type;
cell_manager cm;
@@ -120,9 +118,18 @@
char *mask_name;
};
+/**
+ * \brief function prototype for index calculation
+ * \param fd file descripter of opened raster map
+ * \param par optional parameters
+ * \param ad definition of the sample area
+ * \param result pointer to store the result
+ * \return RLI_ERRORE error occurs in calculating index
+ * \return RLI_OK otherwise
+ */
+typedef int rli_func(int fd, char **par, struct area_entry *ad, double *result);
-
/**
* \brief applies the f index once for every
* area defined in setup file
@@ -132,7 +139,8 @@
* \return 0 error occurs in calculating index
* \return 1 otherwise
*/
-int calculateIndex(char *file, int f(int, char **, struct area_entry *, double *),
+
+int calculateIndex(char *file, rli_func *f,
char **parameters, char *raster, char *output);
/**
@@ -197,12 +205,13 @@
* \brief client implementation
* \param raster the raster map to analyze
* \param f the function used for index computing
- * \param server_channel the channel where to send the result
- * \param mychannel the channel where to receive the area messages
* \param result where to put the result of index computing
*/
-void worker(char *raster, int f(int, char **, struct area_entry *, double *),
- char *server_channel, char *mychannel, char **parameters);
+void worker_init(char *raster, rli_func *f,
+ char **parameters);
+void worker_process(msg * ret, msg * m);
+void worker_end(void);
+
/**
* \brief adapts the mask at current raster file
* \param mask name of mask raster file
@@ -211,7 +220,7 @@
* \param cl the lenght in cols of sample area
* \return the name of mask raster file to use
*/
-char *mask_preprocessing(char *mask, char *raster, int rl, int cl);
+char *mask_preprocessing(char *mask, char *raster, struct area_entry *ad);
/**
* \brief writes the output for a raster file
@@ -266,4 +275,3 @@
*/
FCELL *RLI_get_fcell_raster_row(int fd, int row, struct area_entry * ad);
-#include "index.h"
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/description.html
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/description.html 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/description.html 2014-03-24 11:43:14 UTC (rev 59305)
@@ -68,9 +68,6 @@
</pre></div><br>
to use an ad hoc build memory management developed to speed up the system.
The documentation is in doxygen files.
-<p>
-The <tt>WORKERS</tt> environment variable can be set to the number of
-concurrent processes desired. If not set, the default is 10 concurrent jobs.
<h2>SEE ALSO</h2>
Deleted: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/index.h
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/index.h 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/index.h 2014-03-24 11:43:14 UTC (rev 59305)
@@ -1,50 +0,0 @@
-/*
- * \file index.h
- *
- * \brief declaration of functions for r.li raster analysis
- *
- * \author Claudio Porta, Lucio Davide Spano, Serena Pallecchi students of Computer Science University of Pisa (Italy)
- * Commission from Faunalia Pontedera (PI) www.faunalia.it
- * Luca Delucchi and Duccio Rocchini, Fondazione Edmund Mach, Italy: r.li.pielou, r.li.renyi
- *
- *
- * This program is free software under the GPL (>=v2)
- * Read the COPYING file that comes with GRASS for details.
- *
- * \version 1.1
- *
- */
-
-
- /* #################################################
- ADD HERE INDEX DECLARATIONS
- ################################################# */
-
-
-
- /**
- * \brief calculate patch density index on selected area
- * the abstract function is patch_density= patch_number / area
- */
-int patch_density(int fd, char **par, struct area_entry *ad, double *result);
-
-int patch_number(int fd, char **par, struct area_entry *ad, double *result);
-int shape_index(int fd, char **par, struct area_entry *ad, double *result);
-int shannon(int fd, char **par, struct area_entry *ad, double *result);
-
-int pielou(int fd, char **par, struct area_entry *ad, double *result);
-int renyi(int fd, char **par, struct area_entry *ad, double *result);
-
-int simpson(int fd, char **par, struct area_entry *ad, double *result);
-int meanPatchSize(int fd, char **par, struct area_entry *ad, double *result);
-int meanPixelAttribute(int fd, char **par, struct area_entry *ad, double *result);
-int contrastWeightedEdgeDensity(int fd, char **par, struct area_entry *ad,
- double *result);
-int edgedensity(int fd, char **valore, struct area_entry *ad, double *result);
-int patchAreaDistributionCV(int fd, char **par, struct area_entry *ad, double *result);
-int patchAreaDistributionMN(int fd, char **par, struct area_entry *ad, double *result);
-int patchAreaDistributionSD(int fd, char **par, struct area_entry *ad, double *result);
-int patchAreaDistributionRANGE(int fd, char **par, struct area_entry *ad,
- double *result);
-int dominance(int fd, char **par, struct area_entry *ad, double *result);
-int richness(int fd, char **par, struct area_entry *ad, double *result);
Deleted: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/ipc.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/ipc.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/ipc.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -1,87 +0,0 @@
-
-/**
- * \file IPC.c
- *
- * \brief implementation of interprocess communication
- * primitives between r.li.daemon and r.li.worker
- *
- *
- * This program is free software under the GPL (>=v2)
- * Read the COPYING file that comes with GRASS for details.
- *
- *
- * \author Lucio Davide Spano
- *
- * \version 1.0
- *
- */
-
-
-#include <unistd.h>
-#include <grass/gis.h>
-#include <grass/glocale.h>
-#include "ipc.h"
-
-
-int send(int pipe, msg *m)
-{
- int check;
-
- /* write on pipe */
- check = write(pipe, m, sizeof(msg));
-
- if (check > 0)
- return 1;
- else
- return 0;
-}
-
-int receive(int pipe, msg *m)
-{
- return read(pipe, m, sizeof(msg));
-}
-
-void printMsg(msg m)
-{
-
- switch (m.type) {
- case AREA:{
- G_message(_(" AREA MESSAGE: \n \
- aid = %i \n \
- x = %i \n \
- y = %i \n \
- rl = %i \n \
- cl = %i \n "), m.f.f_a.aid, m.f.f_a.x, m.f.f_a.y, m.f.f_a.rl, m.f.f_a.cl);
- }
- break;
- case MASKEDAREA:{
- G_message(_(" MASKEDAREA MESSAGE: \n \
- aid = %i \n \
- x = %i \n \
- y = %i \n \
- rl = %i \n \
- cl = %i \n \
- mask = %s \n "),
- m.f.f_ma.aid, m.f.f_ma.x, m.f.f_ma.y, m.f.f_ma.rl, m.f.f_ma.cl, m.f.f_ma.mask);
- }
- break;
- case DONE:{
- G_message(_(" DONE MESSAGE: \n \
- aid = %i \n \
- pid = %i \n \
- result = %f \n "), m.f.f_d.aid, m.f.f_d.pid, m.f.f_d.res);
- }
- break;
- case ERROR:{
- G_message(_(" ERROR MESSAGE: \n \
- aid = %i \n \
- pid = %i \n "), m.f.f_e.aid, m.f.f_e.pid);
- }
- break;
- case TERM:{
- G_message(_(" TERM MESSAGE: \n \
- pid = %i \n "), m.f.f_t.pid);
- }
- break;
- }
-}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/ipc.h
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/ipc.h 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/ipc.h 2014-03-24 11:43:14 UTC (rev 59305)
@@ -120,23 +120,3 @@
fields f;
} msg;
-/**
- * \brief send the specified message through the pipe channel.
- * \param pipe the pipe used to send message
- * \param m the message to send
- * \return 1 message sent, 0 otherwise
- */
-int send(int pipe, msg * m);
-
-/**
- * \brief receive a message through the pipe channel
- * \param pipe the pipe used to receive message
- * \param m the message to receive
- * \return 1 message sent, 0 otherwise
- */
-int receive(int pipe, msg * m);
-
-/**
- * \brief debug function, print a message to STDOUT
- */
-void printMsg(msg m);
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/list.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/list.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/list.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -65,7 +65,8 @@
struct node *tmp = l->head;
l->head = NULL;
- free(tmp);
+ G_free(tmp->m);
+ G_free(tmp);
l->size--;
}
else {
@@ -73,7 +74,8 @@
l->head = l->head->next;
l->head->prev = NULL;
- free(tmp);
+ G_free(tmp->m);
+ G_free(tmp);
l->size--;
}
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/list.h
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/list.h 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/list.h 2014-03-24 11:43:14 UTC (rev 59305)
@@ -68,13 +68,15 @@
* \param dist inter-area distance
* \param add_row cell to add in rows
* \param add_col cell to add in columns
- * \param x x coordinate of next area
- * \param y y coordinate of next area
- * \param rl area length in rows
- * \param cl areal length in columns
+ * \param rows area length in rows
+ * \param cols area length in columns
+ * \param x column offset of next area
+ * \param y row offset of next area
+ * \param rl sample area length in rows
+ * \param cl sample area length in columns
* \param count identifier of next area
- * \param sf_x x coordinate of sample frame
- * \param sf_y y coordinate of sample frame
+ * \param sf_x column offset of sample frame
+ * \param sf_y row offset of sample frame
* \param maskname name of mask for the area
*/
struct g_area
Deleted: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/main.c.unused
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/main.c.unused 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/main.c.unused 2014-03-24 11:43:14 UTC (rev 59305)
@@ -1,227 +0,0 @@
-/****************************************************************************
- *
- * MODULE: r.li.daemon
- * AUTHOR(S): Claudio Porta, Lucio D. Spano, Serena Pallecchi (original contributors)
- * students of Computer Science University of Pisa (Italy)
- * Commission from Faunalia Pontedera (PI) www.faunalia.it
- * Fixes: Markus Neteler <neteler itc.it>
- *
- * PURPOSE: r.li.daemon with a simple index for library debug
- * COPYRIGHT: (C) 2006-2007 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 <stdlib.h>
-#include <fcntl.h>
-#include <grass/gis.h>
-#include <grass/glocale.h>
-#include "daemon.h"
-
-/**
- * main with a simple index for library debug
- *
- * This program is free software under the GPL (>=v2)
- * Read the COPYING file that comes with GRASS for details.
- *
- */
-int main(int argc, char *argv[]){
- struct Option *raster, *conf, *output;
- struct GModule *module;
-
- G_gisinit(argv[0]);
- module = G_define_module();
- module->description =_("Calculates <simple> index on a raster map");
- module->keywords = _("raster, landscape structure analysis, job launcher");
-
- /* define options */
-
- raster = G_define_standard_option(G_OPT_R_MAP);
-
- conf = G_define_option();
- conf->key = "conf";
- conf->description = "Areas configuration file";
- conf->gisprompt = "old_file,file,input";
- conf->type = TYPE_STRING;
- conf->required = YES;
-
- output = G_define_standard_option(G_OPT_R_OUTPUT);
-
- /** add other options for index parameters here */
-
- if (G_parser(argc, argv))
- exit(EXIT_FAILURE);
-
- return calculateIndex(conf->answer, simple_index, NULL, raster->answer, output->answer);
-
-}
-
-int simple_index(int fd, char ** par, area_des ad, double *result){
- CELL *buf, *sup;
- int count, i,j, connected=0, complete_line=1;
- double area;
- char *mapset, c[150];
- struct Cell_head hd;
- CELL complete_value;
-
- G_set_c_null_value(&complete_value, 1);
- mapset = G_find_cell(ad->raster, "");
- if (G_get_cellhd(ad->raster, mapset, &hd) == - 1)
- return 0;
- sup = G_allocate_cell_buf();
- if(ad->mask == -1){
- double meters_row, meters_col;
- /* no mask */
-
- /*calculate area size */
- meters_row = G_distance(hd.north,hd.west, hd.south, hd.west)\
- /hd.rows;
- meters_col = G_distance(hd.north, hd.west, hd.north, hd.east)\
- /hd.cols;
- area = meters_row * ad->rl * meters_col * ad->cl;
-
- /*calculate number of patch*/
- count =0;
- for(i = 0; i<ad->rl; i++){
- connected = 0;
- buf = RLI_get_cell_raster_row(fd, i+ad->y, ad);
- if(i > 0){
- sup = RLI_get_cell_raster_row(fd, i-1+ad->y, ad);
- }
-
- if (complete_line){
- if (! G_is_null_value( &(buf[ad->x]), CELL_TYPE) &&\
- buf[ad->x] != complete_value)
- count++;
- for(j=0; j<ad->cl; j++){
- if (buf[j+ad->x] != buf[j+1+ad->x]){
- complete_line=0;
- if(!G_is_null_value( &(buf[j+ad->x]), CELL_TYPE) &&\
- buf[j+ad->x] != complete_value)
- count++;
- }
- }
- if (complete_line){
- complete_value = buf[ad->x];
- }
- }
- else{
- complete_line = 1;
- for(j=0; j<ad->cl; j++){
- if (sup[j+ad->x] == buf[j+ad->x]){
- connected = 1;
- }
- if (buf[j+ad->x] != buf[j+1+ad->x]){
- complete_line =0;
- if (!connected && \
- !G_is_null_value( &(buf[j+ad->x]), CELL_TYPE)){
- count++;
- connected =0;
- }
- else{
- connected=0;
- }
- }
- }
- if (complete_line)
- complete_value = buf[ad->x];
- }
- }
-
- #ifdef DEBUG
- printf("number of patch = %i\n", count);
- #endif
- #ifdef DEBUG
- printf("area = %f\n", area);
- #endif
- *result= (count/area) * 10000;
- return 1;
- }
- else{
- double meters_row, meters_col;
- int cell_dim = 0, mask_fd, *mask_buf;
- CELL null_value;
-
- G_set_c_null_value(&null_value, 1);
- /* mask */
- if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
- return 0;
- mask_buf = malloc(ad->cl * sizeof(int));
- /*calculate area size */
- meters_row = G_distance(hd.north,hd.west, hd.south, hd.west)\
- /hd.rows;
- meters_col = G_distance(hd.north, hd.west, hd.north, hd.east)\
- /hd.cols;
-
- /*calculate number of patch*/
- count =0;
- for(i = 0; i<ad->rl; i++){
- G_get_raster_row(fd, buf, i+ad->y, CELL_TYPE);
- if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
- return 0;
- if(i>0){
- G_get_raster_row(fd, sup, i-1, CELL_TYPE);
- }
- /* mask values */
- for (j=0; j<ad->cl; j++){
- if(mask_buf[j] == 0)
- buf[ad->x +j] = null_value;
- }
- if (complete_line){
- if (! G_is_null_value( &(buf[ad->x]), CELL_TYPE) &&\
- buf[ad->x] != complete_value)
- count++;
- for(j=0; j<ad->cl; j++){
- if (buf[j+ad->x] != buf[j+1+ad->x]){
- complete_line=0;
- if(!G_is_null_value( &(buf[j+ad->x]), CELL_TYPE)&&\
- buf[j+ad->x] != complete_value)
- count++;
- }
- }
- if (complete_line){
- complete_value = buf[ad->x];
- }
- }
- else{
- complete_line = 1;
- for(j=0; j<ad->cl; j++){
- if (sup[j+ad->x] == buf[j+ad->x]){
- connected = 1;
- }
- if (buf[j+ad->x] != buf[j+1+ad->x]){
- complete_line =0;
- if (!connected && \
- !G_is_null_value( &(buf[j+ad->x]), CELL_TYPE)){
- count++;
- connected =0;
- }
- else{
- connected=0;
- }
- }
- }
- if (complete_line)
- complete_value = buf[ad->x];
- }
- }
- #ifdef DEBUG
- printf("number of patch = %i\n", count);
- #endif
- #ifdef DEBUG
- printf("area = %f\n", area);
- #endif
- area = cell_dim * meters_row * meters_col;
- *result= (count/area)*10000;
- free(buf);
- free(sup);
- free(mask_buf);
- return 1;
- }
-}
-
-
-
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/worker.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/worker.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.daemon/worker.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -37,36 +37,41 @@
#define CACHESIZE 4194304
-void worker(char *raster, int f(int, char **, struct area_entry *, double *),
- char *server_channel, char *mychannel, char **parameters)
+static int fd, aid;
+static int erease_mask = 0, data_type = 0;
+static int cache_rows, used = 0;
+static struct area_entry * ad;
+static double result;
+static struct Cell_head hd;
+static cell_manager cm;
+static dcell_manager dm;
+static fcell_manager fm;
+static char *raster;
+static char **parameters;
+static rli_func *func;
+
+void worker_init(char *r, rli_func *f, char **p)
{
char *mapset;
- int fd, aid;
- int rec_ch, send_ch, erease_mask = 0, data_type = 0;
- int cache_rows, used = 0;
- msg toReceive, toSend;
- static struct area_entry *ad;
- double result;
- int pid;
- struct Cell_head hd;
- cell_manager cm;
- dcell_manager dm;
- fcell_manager fm;
cm = G_malloc(sizeof(struct cell_memory_entry));
fm = G_malloc(sizeof(struct fcell_memory_entry));
dm = G_malloc(sizeof(struct dcell_memory_entry));
- pid = getpid();
ad = G_malloc(sizeof(struct area_entry));
+ raster = r;
+ parameters = p;
+ func = f;
+
/* open raster map */
mapset = G_find_cell(raster, "");
fd = G_open_cell_old(raster, mapset);
- if (G_get_cellhd(raster, mapset, &hd) == -1) {
- G_message(_("CHILD[pid = %i] cannot open raster map"), pid);
- exit(EXIT_FAILURE);
- }
+ if (G_get_cellhd(raster, mapset, &hd) == -1)
+ G_fatal_error(_("Cannot open raster map <%s>"), raster);
+ /* get current window */
+ G_get_window(&hd);
+
/* read data type to allocate cache */
data_type = G_raster_map_type(raster, mapset);
@@ -74,6 +79,8 @@
switch (data_type) {
case CELL_TYPE:{
cache_rows = CACHESIZE / (hd.cols * sizeof(CELL));
+ if (cache_rows < 4)
+ cache_rows = 4;
cm->cache = G_malloc(cache_rows * sizeof(CELL *));
cm->contents = G_malloc(cache_rows * sizeof(int));
cm->used = 0;
@@ -81,6 +88,8 @@
} break;
case DCELL_TYPE:{
cache_rows = CACHESIZE / (hd.cols * sizeof(DCELL));
+ if (cache_rows < 4)
+ cache_rows = 4;
dm->cache = G_malloc(cache_rows * sizeof(DCELL *));
dm->contents = G_malloc(cache_rows * sizeof(int));
dm->used = 0;
@@ -88,6 +97,8 @@
} break;
case FCELL_TYPE:{
cache_rows = CACHESIZE / (hd.cols * sizeof(FCELL));
+ if (cache_rows < 4)
+ cache_rows = 4;
fm->cache = G_malloc(cache_rows * sizeof(FCELL *));
fm->contents = G_malloc(cache_rows * sizeof(int));
fm->used = 0;
@@ -95,146 +106,132 @@
} break;
}
ad->data_type = data_type;
+ ad->rc = cache_rows;
ad->cm = cm;
ad->fm = fm;
ad->dm = dm;
+}
- /* open receive channel */
- rec_ch = open(mychannel, O_RDONLY, 0755);
- if (rec_ch == -1) {
- G_message(_("CHILD[pid = %i] cannot open receive channel"), pid);
- exit(0);
- }
+void worker_process(msg * ret, msg * m)
+{
+ switch (m->type) {
+ case AREA:
+ aid = m->f.f_a.aid;
+ ad->x = m->f.f_a.x;
+ ad->y = m->f.f_a.y;
+ ad->rl = m->f.f_a.rl;
+ ad->cl = m->f.f_a.cl;
+ ad->raster = raster;
+ ad->mask = -1;
+ break;
+ case MASKEDAREA:
+ aid = m->f.f_ma.aid;
+ ad->x = m->f.f_ma.x;
+ ad->y = m->f.f_ma.y;
+ ad->rl = m->f.f_ma.rl;
+ ad->cl = m->f.f_ma.cl;
+ ad->raster = raster;
- /* open send channel */
- send_ch = open(server_channel, O_WRONLY, 0755);
- if (send_ch == -1) {
- G_message(_("CHILD[pid = %i] cannot open receive channel"), pid);
- exit(0);
- }
+ /* mask preprocessing */
+ ad->mask_name = mask_preprocessing(m->f.f_ma.mask, raster, ad);
- /* receive loop */
- receive(rec_ch, &toReceive);
-
- while (toReceive.type != TERM) {
- if (toReceive.type == AREA) {
- aid = toReceive.f.f_ma.aid;
- ad->x = toReceive.f.f_a.x;
- ad->y = toReceive.f.f_a.y;
- ad->rl = toReceive.f.f_a.rl;
- ad->cl = toReceive.f.f_a.cl;
- ad->raster = raster;
+ if (ad->mask_name == NULL) {
+ G_message(_("unable to open <%s> mask ... continuing without!"),
+ m->f.f_ma.mask);
ad->mask = -1;
}
- else if (toReceive.type == MASKEDAREA) {
- aid = toReceive.f.f_ma.aid;
- ad->x = toReceive.f.f_ma.x;
- ad->y = toReceive.f.f_ma.y;
- ad->rl = toReceive.f.f_ma.rl;
- ad->cl = toReceive.f.f_ma.cl;
- ad->raster = raster;
-
- /* mask preprocessing */
- ad->mask_name = mask_preprocessing(toReceive.f.f_ma.mask,
- raster, ad->rl, ad->cl);
- if (ad->mask_name == NULL) {
- G_message(_("CHILD[pid = %i]: unable to open <%s> mask ... continuing without!"),
- pid, toReceive.f.f_ma.mask);
- ad->mask = -1;
- }
- else {
- if (strcmp(toReceive.f.f_ma.mask, ad->mask_name) != 0)
- /* temporary mask created */
- erease_mask = 1;
- ad->mask = open(ad->mask_name, O_WRONLY, 0755);
- if (ad->mask == -1) {
- G_message(_("CHILD[pid = %i]: unable to open <%s> mask ... continuing without!"),
- pid, toReceive.f.f_ma.mask);
- }
- }
+ else {
+ if (strcmp(m->f.f_ma.mask, ad->mask_name) != 0)
+ /* temporary mask created */
+ erease_mask = 1;
+ ad->mask = 1;
}
- else
- G_fatal_error("Program error, worker() toReceive.type=%d",
- toReceive.type);
+ break;
+ default:
+ G_fatal_error("Program error, worker() type=%d", m->type);
+ break;
+ }
+
+ /* sanity check on the sample area ? */
+ /* 0 <= ad->x < hd.cols */
+ /* 0 <= ad->y < hd.rows */
+ /* ad->rl + ad->y <= hd.rows */
+ /* ad->cl + ad->x <= hd.cols */
- /* memory menagement */
- if (ad->rl > used) {
- /* allocate cache */
- int i;
+ /* memory menagement */
+ if (ad->rc > used) {
+ /* allocate cache */
+ int i;
- switch (data_type) {
- case CELL_TYPE:{
- for (i = 0; i < (ad->rl - used); i++) {
- cm->cache[used + i] = G_allocate_cell_buf();
- }
+ switch (data_type) {
+ case CELL_TYPE:{
+ for (i = 0; i < (ad->rc - used); i++) {
+ cm->cache[used + i] = G_allocate_cell_buf();
+ cm->contents[used + i] = -1;
}
- break;
- case DCELL_TYPE:{
- for (i = 0; i < ad->rl - used; i++) {
- dm->cache[used + i] = G_allocate_d_raster_buf();
- }
+ }
+ break;
+ case DCELL_TYPE:{
+ for (i = 0; i < ad->rc - used; i++) {
+ dm->cache[used + i] = G_allocate_d_raster_buf();
+ dm->contents[used + i] = -1;
}
- break;
- case FCELL_TYPE:{
- for (i = 0; i < ad->rl - used; i++) {
- fm->cache[used + i] = G_allocate_f_raster_buf();
- }
+ }
+ break;
+ case FCELL_TYPE:{
+ for (i = 0; i < ad->rc - used; i++) {
+ fm->cache[used + i] = G_allocate_f_raster_buf();
+ fm->contents[used + i] = -1;
}
- break;
}
- cm->used = ad->rl;
- dm->used = ad->rl;
- fm->used = ad->rl;
- used = ad->rl;
+ break;
}
+ cm->used = ad->rc;
+ dm->used = ad->rc;
+ fm->used = ad->rc;
+ used = ad->rc;
+ }
- /* calculate function */
+ /* calculate function */
- if (f(fd, parameters, ad, &result) == RLI_OK) {
- /* success */
- toSend.type = DONE;
- toSend.f.f_d.aid = aid;
- toSend.f.f_d.pid = getpid();
- toSend.f.f_d.res = result;
- }
- else {
- /* fail */
- toSend.type = ERROR;
- toSend.f.f_e.aid = aid;
- toSend.f.f_e.pid = getpid();
- }
+ if (func(fd, parameters, ad, &result) == RLI_OK) {
+ /* success */
+ ret->type = DONE;
+ ret->f.f_d.aid = aid;
+ ret->f.f_d.pid = 0;
+ ret->f.f_d.res = result;
+ }
+ else {
+ /* fail */
+ ret->type = ERROR;
+ ret->f.f_e.aid = aid;
+ ret->f.f_e.pid = 0;
+ }
- send(send_ch, &toSend);
-
- if (erease_mask == 1) {
- erease_mask = 0;
- unlink(ad->mask_name);
- }
-
- receive(rec_ch, &toReceive);
+ if (erease_mask == 1) {
+ erease_mask = 0;
+ unlink(ad->mask_name);
}
+}
+
+void worker_end(void)
+{
/* close raster map */
G_close_cell(fd);
-
- /* close channels */
- close(rec_ch);
- close(send_ch);
-
- return;
}
-char *mask_preprocessing(char *mask, char *raster, int rl, int cl)
+char *mask_preprocessing(char *mask, char *raster, struct area_entry *ad)
{
- char *mapset, *mask_mapset, *tmp_file;
+ const char *tmp_file;
+ char *mapset, *mask_mapset;
struct Cell_head cell, oldcell;
int mask_fd, old_fd, *buf, i, j;
CELL *old;
- double add_row, add_col;
- buf = G_malloc(cl * sizeof(int));
+ buf = G_malloc(ad->cl * sizeof(int));
G_debug(3, "daemon mask preproc: raster=[%s] mask=[%s] rl=%d cl=%d",
- raster, mask, rl, cl);
+ raster, mask, ad->rl, ad->cl);
/* mapset is used hold the mapset of input raster */
mapset = G_find_cell(raster, "");
@@ -243,40 +240,37 @@
if (G_get_cellhd(raster, mapset, &cell) == -1)
return NULL;
-
mask_mapset = G_find_cell(mask, "");
/* open raster */
if (G_get_cellhd(mask, mask_mapset, &oldcell) == -1)
return NULL;
- add_row = 1.0 * oldcell.rows / rl;
- add_col = 1.0 * oldcell.cols / cl;
-
tmp_file = G_tempfile();
mask_fd = open(tmp_file, O_RDWR | O_CREAT, 0755);
-
old_fd = G_open_cell_old(mask, mask_mapset);
-
- G_debug(1, "worker.c: mask <%s@%s>", mask, mask_mapset);
old = G_allocate_cell_buf();
- for (i = 0; i < rl; i++) {
- int riga;
+ /* write out sample area size: ad->rl rows and ad->cl columns */
- riga = (int)rint(i * add_row);
- G_get_map_row_nomask(old_fd, old, riga);
- for (j = 0; j < cl; j++) {
- int colonna;
+ for (i = 0; i < ad->rl; i++) {
- colonna = (int)rint(j * add_col);
- buf[j] = old[colonna];
+ G_get_map_row_nomask(old_fd, old, i + ad->y);
+ for (j = 0; j < ad->cl; j++) {
+
+ /* NULL -> 0, else 1 */
+ buf[j] = !G_is_null_value(&old[j + ad->x], CELL_TYPE);
}
- if (write(mask_fd, buf, cl * sizeof(int)) < 0)
+ if (write(mask_fd, buf, ad->cl * sizeof(int)) < 0)
return NULL;
}
close(mask_fd);
+ G_close_cell(old_fd);
+
+ G_free(buf);
+ G_free(old);
+
return G_store(tmp_file);
}
@@ -284,7 +278,7 @@
{
int hash;
- hash = row % ad->rl;
+ hash = row % ad->rc;
if (ad->cm->contents[hash] == row)
return ad->cm->cache[hash];
else {
@@ -299,7 +293,7 @@
{
int hash;
- hash = row % ad->rl;
+ hash = row % ad->rc;
if (ad->dm->contents[hash] == row)
return ad->dm->cache[hash];
else {
@@ -314,7 +308,7 @@
{
int hash;
- hash = row % ad->rl;
+ hash = row % ad->rc;
if (ad->fm->contents[hash] == row)
return ad->fm->cache[hash];
else {
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.dominance/dominance.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.dominance/dominance.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.dominance/dominance.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -15,20 +15,20 @@
*
*****************************************************************************/
-#include <grass/gis.h>
-#include <grass/glocale.h>
-
#include <stdlib.h>
#include <fcntl.h>
#include <math.h>
-#include "../r.li.daemon/defs.h"
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#include "../r.li.daemon/daemon.h"
#include "../r.li.daemon/avlDefs.h"
#include "../r.li.daemon/avl.h"
-#include "../r.li.daemon/daemon.h"
/* template is shannon */
+rli_func dominance;
int calculate(int fd, struct area_entry *ad, double *result);
int calculateD(int fd, struct area_entry *ad, double *result);
int calculateF(int fd, struct area_entry *ad, double *result);
@@ -66,15 +66,9 @@
int dominance(int fd, char **par, struct area_entry *ad, double *result)
{
- char *mapset;
int ris = RLI_OK;
double indice = 0;
- struct Cell_head hd;
- mapset = G_find_cell(ad->raster, "");
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
- return RLI_ERRORE;
-
switch (ad->data_type) {
case CELL_TYPE:
{
@@ -98,8 +92,9 @@
}
}
- if (ris != RLI_OK)
+ if (ris != RLI_OK) {
return RLI_ERRORE;
+ }
*result = indice;
@@ -114,30 +109,23 @@
CELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
+ long totCorr = 1;
- double indice = 0;
- double somma = 0;
- double percentuale = 0;
- double area = 0;
- double t;
- double logaritmo;
+ long area = 0;
avl_tree albero = NULL;
AVL_table *array;
+ generic_cell uc;
- generic_cell cc;
+ uc.t = CELL_TYPE;
- cc.t = CELL_TYPE;
-
/* open mask if needed */
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
@@ -151,7 +139,6 @@
}
G_set_c_null_value(&precCell, 1);
-
for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
@@ -161,74 +148,73 @@
}
buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
+
for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
- area++;
corrCell = buf[i + ad->x];
- if ((masked) && (mask_buf[i + ad->x] == 0)) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_c_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, CELL_TYPE))) {
- a = 1;
- if (G_is_null_value(&precCell, cc.t)) {
- precCell = corrCell;
- }
- if (corrCell != precCell) {
- if (albero == NULL) {
- cc.val.c = precCell;
- albero = avl_make(cc, totCorr);
+ if (!(G_is_null_value(&corrCell, uc.t))) {
+ /* total patch area */
+ area++;
+ }
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
+
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.c = precCell;
+ albero = avl_make(uc, totCorr);
+ if (albero == NULL) {
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.c = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- /* TODO missing?: else - see r.li.simpson/simpson.c */
- m++;
- }
- else {
- cc.val.c = precCell;
- ris = avl_add(&albero, cc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_add unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
}
- else {
- totCorr++;
- }
- precCell = corrCell;
- }
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
+ }
+ }
- } /* end for */
- } /* end for */
-
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
- cc.val.c = precCell;
- albero = avl_make(cc, totCorr);
-
+ uc.val.c = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
G_fatal_error("avl_make error");
return RLI_ERRORE;
@@ -236,8 +222,8 @@
m++;
}
else {
- cc.val.c = precCell;
- ris = avl_add(&albero, cc, totCorr);
+ uc.val.c = precCell;
+ ris = avl_add(&albero, uc, totCorr);
switch (ris) {
case AVL_ERR:
{
@@ -260,7 +246,12 @@
}
}
}
+ }
+ if (area > 0) {
+ double t;
+ double shannon;
+ double perc, logarithm;
array = G_malloc(m * sizeof(AVL_tableRow));
if (array == NULL) {
@@ -274,28 +265,26 @@
}
/* calculate shannon */
+ shannon = 0;
for (i = 0; i < m; i++) {
- t = (double)array[i]->tot;
- percentuale = (double)(t / area);
- logaritmo = (double)log(percentuale);
- somma = somma + (percentuale * logaritmo);
+ t = array[i]->tot;
+ perc = t / area;
+ logarithm = log(perc);
+ shannon += perc * logarithm;
}
-
- if (m != 0)
- indice = log((double)m) + somma;
- else
- indice = 0;
G_free(array);
+
+ *result = log(m) + shannon;
}
- else /*if a is 0, that is all cell are null, i put index=-1 */
- indice = (double)(-1);
+ else
+ G_set_d_null_value(result, 1);
-
- if (masked)
+ avl_destroy(albero);
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
+ }
- *result = indice;
-
return RLI_OK;
}
@@ -307,28 +296,22 @@
DCELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
+ long totCorr = 1;
- double indice = 0;
- double somma = 0;
- double percentuale = 0;
- double area = 0;
- double t;
- double logaritmo;
+ long area = 0;
avl_tree albero = NULL;
AVL_table *array;
- generic_cell cc;
+ generic_cell uc;
- cc.t = DCELL_TYPE;
+ uc.t = DCELL_TYPE;
/* open mask if needed */
if (ad->mask == 1) {
@@ -343,7 +326,6 @@
}
G_set_d_null_value(&precCell, 1);
-
for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
@@ -354,75 +336,72 @@
buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
- for (i = 0; i < ad->cl; i++) { /* for each dcell in the row */
- area++;
+ for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_d_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, DCELL_TYPE))) {
- a = 1;
- if (G_is_null_value(&precCell, DCELL_TYPE)) {
- precCell = corrCell;
- }
- if (corrCell != precCell) {
+ if (!(G_is_null_value(&corrCell, uc.t))) {
+ /* total patch area */
+ area++;
+ }
+
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
+
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.dc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
- cc.val.dc = precCell;
- albero = avl_make(cc, totCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.dc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- m++;
- }
- else {
- cc.val.dc = precCell;
- ris = avl_add(&albero, cc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_add unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
}
- else {
- totCorr++;
- }
- precCell = corrCell;
- }
-
- } /*close for */
- } /*close for */
-
- if (masked) {
- G_free(mask_buf);
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
+ }
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
- cc.val.dc = precCell;
- albero = avl_make(cc, totCorr);
+ uc.val.dc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
G_fatal_error("avl_make error");
return RLI_ERRORE;
@@ -430,8 +409,8 @@
m++;
}
else {
- cc.val.fc = precCell;
- ris = avl_add(&albero, cc, totCorr);
+ uc.val.dc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
switch (ris) {
case AVL_ERR:
{
@@ -454,7 +433,12 @@
}
}
}
+ }
+ if (area > 0) {
+ double t;
+ double shannon;
+ double perc, logarithm;
array = G_malloc(m * sizeof(AVL_tableRow));
if (array == NULL) {
@@ -463,33 +447,31 @@
}
tot = avl_to_array(albero, zero, array);
if (tot != m) {
- G_warning
- ("avl_to_array unaspected value. the result could be wrong");
+ G_warning("avl_to_array unexpected value. the result could be wrong");
return RLI_ERRORE;
}
- /* calculate summary */
+ /* calculate shannon */
+ shannon = 0;
for (i = 0; i < m; i++) {
- t = (double)array[i]->tot;
- percentuale = (double)(t / area);
- logaritmo = (double)log(percentuale);
- somma = somma + (percentuale * logaritmo);
+ t = array[i]->tot;
+ perc = t / area;
+ logarithm = log(perc);
+ shannon += perc * logarithm;
}
G_free(array);
- if (m != 0)
- indice = log((double)m) + somma;
- else
- indice = 0;
+ *result = log(m) + shannon;
}
else
- /*if a is 0, that is all cell are null, i put index=-1 */
- indice = (double)(-1);
+ G_set_d_null_value(result, 1);
+ avl_destroy(albero);
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
+ }
- *result = indice;
-
-
return RLI_OK;
}
@@ -501,28 +483,22 @@
FCELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
+ long totCorr = 1;
- double indice = 0;
- double somma = 0;
- double percentuale = 0;
- double area = 0;
- double t;
- double logaritmo;
+ long area = 0;
avl_tree albero = NULL;
AVL_table *array;
- generic_cell cc;
+ generic_cell uc;
- cc.t = FCELL_TYPE;
+ uc.t = FCELL_TYPE;
/* open mask if needed */
if (ad->mask == 1) {
@@ -547,73 +523,72 @@
buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
- for (i = 0; i < ad->cl; i++) { /* for each fcell in the row */
-
- area++;
+ for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_f_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, FCELL_TYPE))) {
- a = 1;
- if (G_is_null_value(&precCell, FCELL_TYPE)) {
- precCell = corrCell;
- }
- if (corrCell != precCell) {
+ if (!(G_is_null_value(&corrCell, uc.t))) {
+ /* total patch area */
+ area++;
+ }
+
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
+
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.fc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
- cc.val.fc = precCell;
- albero = avl_make(cc, totCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.fc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- m++;
- }
- else {
- cc.val.fc = precCell;
- ris = avl_add(&albero, cc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_add unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
}
- else {
- totCorr++;
- }
-
- precCell = corrCell;
- }
-
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
}
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
- cc.val.fc = precCell;
- albero = avl_make(cc, totCorr);
+ uc.val.fc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
G_fatal_error("avl_make error");
return RLI_ERRORE;
@@ -621,8 +596,8 @@
m++;
}
else {
- cc.val.fc = precCell;
- ris = avl_add(&albero, cc, totCorr);
+ uc.val.fc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
switch (ris) {
case AVL_ERR:
{
@@ -645,7 +620,12 @@
}
}
}
+ }
+ if (area > 0) {
+ double t;
+ double shannon;
+ double perc, logarithm;
array = G_malloc(m * sizeof(AVL_tableRow));
if (array == NULL) {
@@ -659,29 +639,25 @@
}
/* calculate shannon */
+ shannon = 0;
for (i = 0; i < m; i++) {
- t = (double)array[i]->tot;
- percentuale = (double)(t / area);
- logaritmo = (double)log(percentuale);
- somma = somma + (percentuale * logaritmo);
+ t = array[i]->tot;
+ perc = t / area;
+ logarithm = log(perc);
+ shannon += perc * logarithm;
}
-
- if (m != 0)
- indice = log((double)m) + somma;
- else
- indice = 0;
-
G_free(array);
+
+ *result = log(m) + shannon;
}
- else /*if a is 0, that is all cell are null, i put index=-1 */
- indice = (double)(-1);
+ else
+ G_set_d_null_value(result, 1);
-
+ avl_destroy(albero);
if (masked) {
+ close(mask_fd);
G_free(mask_buf);
}
- *result = indice;
-
return RLI_OK;
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.edgedensity/edgedensity.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.edgedensity/edgedensity.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.edgedensity/edgedensity.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -1,28 +1,35 @@
-/*
- * \brief calculates edge density index
+
+/****************************************************************************
*
- * AUTHOR: Serena Pallecchi student of Computer Science University of Pisa (Italy)
- * Commission from Faunalia Pontedera (PI) www.faunalia.it
+ * MODULE: r.li.edgedensity
+ * AUTHOR(S): Serena Pallecchi student of Computer Science University of Pisa (Italy)
+ * Commission from Faunalia Pontedera (PI) www.faunalia.it
+ * Rewrite: Markus Metz
*
- * This program is free software under the GPL (>=v2)
- * Read the COPYING file that comes with GRASS for details.
+ * PURPOSE: calculates edge density index
+ * COPYRIGHT: (C) 2006-2014 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/glocale.h>
-
#include <stdlib.h>
#include <fcntl.h> /* for O_RDONLY usage */
#include <math.h>
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
#include "../r.li.daemon/avlDefs.h"
#include "../r.li.daemon/avl.h"
#include "../r.li.daemon/daemon.h"
-int calculate(int fd, struct area_entry *ad, char **valore, double *result);
-int calculateD(int fd, struct area_entry *ad, char **valore, double *result);
-int calculateF(int fd, struct area_entry *ad, char **valore, double *result);
+rli_func edgedensity;
+int calculate(int fd, struct area_entry *ad, char **par, double *result);
+int calculateD(int fd, struct area_entry *ad, char **par, double *result);
+int calculateF(int fd, struct area_entry *ad, char **par, double *result);
int main(int argc, char *argv[])
{
@@ -56,6 +63,7 @@
class->description = _("It can be integer, double or float; "
"it will be changed in function of map type");
+
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
@@ -67,35 +75,27 @@
return calculateIndex(conf->answer, edgedensity, par, raster->answer,
output->answer);
-
}
-int edgedensity(int fd, char **valore, struct area_entry *ad, double *result)
+int edgedensity(int fd, char **par, struct area_entry *ad, double *result)
{
- struct Cell_head hd;
int ris = -1;
- char *mapset;
double indice = 0;
- mapset = G_find_cell(ad->raster, "");
-
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
- return RLI_ERRORE;
-
switch (ad->data_type) {
case CELL_TYPE:
{
- ris = calculate(fd, ad, valore, &indice);
+ ris = calculate(fd, ad, par, &indice);
break;
}
case DCELL_TYPE:
{
- ris = calculateD(fd, ad, valore, &indice);
+ ris = calculateD(fd, ad, par, &indice);
break;
}
case FCELL_TYPE:
{
- ris = calculateF(fd, ad, valore, &indice);
+ ris = calculateF(fd, ad, par, &indice);
break;
}
default:
@@ -114,726 +114,536 @@
}
-int calculate(int fd, struct area_entry *ad, char **valore, double *result)
+int calculate(int fd, struct area_entry *ad, char **par, double *result)
{
- double indice = 0;
- double e = 0;
- double somma = 0;
- double area = 0;
- CELL *buf_corr, *buf_sup, *buf_inf;
- CELL prevCell, corrCell, supCell, infCell, nextCell;
- AVL_table *array;
- long tot = 0;
- long zero = 0;
- long m = 0;
- long bordoCorr = 0;
- avl_tree albero = NULL;
+ CELL *buf, *buf_sup, *buf_null;
+ CELL corrCell, precCell, supCell;
+ CELL ptype;
+ long nedges, area;
int i, j;
- int mask_fd = -1, *mask_corr, *mask_sup, *mask_inf;
- int masked = FALSE;
- int ris;
- generic_cell c1;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- buf_sup = NULL;
- c1.t = CELL_TYPE;
+ G_get_window(&hd);
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
-
- if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) {
- G_fatal_error("Cannot open mask file <%s>", ad->mask_name);
- return RLI_ERRORE; /* FIXME: can not return from a fatal error */
- }
-
- mask_corr = G_malloc(ad->cl * sizeof(int));
- if (mask_corr == NULL) {
- G_fatal_error("malloc mask_corr failed");
+ if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
+ mask_buf = G_malloc(ad->cl * sizeof(int));
+ if (mask_buf == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
}
-
- mask_inf = G_malloc(ad->cl * sizeof(int));
- if (mask_inf == NULL) {
- G_fatal_error("malloc mask_inf failed");
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
masked = TRUE;
}
- buf_sup = G_allocate_cell_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
+ buf_null = G_allocate_cell_buf();
+ if (buf_null == NULL) {
+ G_fatal_error("malloc buf_null failed");
return RLI_ERRORE;
}
/* the first time buf_sup is all null */
- G_set_c_null_value(buf_sup + ad->x, ad->cl);
+ G_set_c_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+ if (par != NULL) { /* only 1 class */
+ char *sval;
+
+ sval = par[0];
+ ptype = atoi(sval);
+ }
+ else
+ G_set_c_null_value(&ptype, 1);
+
+ nedges = 0;
+ area = 0;
+
/* for each raster row */
- for (j = 0; j < ad->rl; j++) {
+ for (i = 0; i < ad->rl; i++) {
/* read row of raster */
- buf_corr = RLI_get_cell_raster_row(fd, j + ad->y, ad);
+ buf = RLI_get_cell_raster_row(fd, i + ad->y, ad);
- if (j > 0) /* not first row */
- buf_sup = RLI_get_cell_raster_row(fd, j - 1 + ad->y, ad);
+ if (i > 0) /* not first row */
+ buf_sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad);
- if ((j + 1) < ad->rl) { /*not last row */
- buf_inf = RLI_get_cell_raster_row(fd, 1 + j + ad->y, ad);
- }
- else {
- buf_inf = G_allocate_cell_buf();
- if (buf_inf == NULL) {
- G_fatal_error("malloc buf_inf failed");
+ /* read mask if needed */
+ if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
return RLI_ERRORE;
- }
- G_set_c_null_value(buf_inf + ad->x, ad->cl);
}
- /*read mask if needed */
- if (masked) {
- if (read(mask_fd, mask_corr, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("reading mask_corr");
- return RLI_ERRORE;
- }
+ G_set_c_null_value(&precCell, 1);
- if ((j + 1) < ad->rl) { /* not last row */
- if (read(mask_fd, mask_inf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("reading mask_inf at row j");
- return RLI_ERRORE;
- }
+ for (j = 0; j < ad->cl; j++) {
+ corrCell = buf[j + ad->x];
+
+ if (masked && mask_buf[j] == 0) {
+ G_set_c_null_value(&corrCell, 1);
}
else {
- int z = 0;
-
- for (z = 0; z < ad->cl; z++)
- mask_inf[z + ad->x] = 0;
+ /* total sample area */
+ area++;
}
- }
- G_set_c_null_value(&nextCell, 1);
- G_set_c_null_value(&prevCell, 1);
- G_set_c_null_value(&corrCell, 1);
-
- for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
- area++;
- corrCell = buf_corr[i + ad->x];
-
-
- if (masked && mask_corr[i + ad->x] == 0) {
- G_set_c_null_value(&corrCell, 1);
- area--;
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_c_null_value(&supCell, 1);
}
- if (!(G_is_null_value(&corrCell, CELL_TYPE))) {
- if ((i + 1) == ad->cl) /*last cell of the row */
- G_set_c_null_value(&nextCell, 1);
- else if (masked && mask_corr[i + 1 + ad->x] == 0)
- G_set_c_null_value(&nextCell, 1);
- else
- nextCell = buf_corr[i + 1 + ad->x];
-
- supCell = buf_sup[i + ad->x];
-
- if (masked && mask_inf[i + ad->x] == 0)
- G_set_c_null_value(&infCell, 1);
- else
- infCell = buf_inf[i + ad->x];
-
- /* calculate how many edges the cell has */
- if ((G_is_null_value(&prevCell, CELL_TYPE)) ||
- (corrCell != prevCell)) {
- bordoCorr++;
+ if (!G_is_c_null_value(&ptype)) {
+ /* only one patch type */
+ if (!G_is_c_null_value(&corrCell) && corrCell == ptype) {
+ if (corrCell != precCell)
+ nedges++;
+ if (corrCell != supCell)
+ nedges++;
+ /* right and bottom */
+ if (i == ad->rl - 1)
+ nedges++;
+ if (j == ad->cl - 1)
+ nedges++;
}
-
- if ((G_is_null_value(&supCell, CELL_TYPE)) ||
- (corrCell != supCell)) {
- bordoCorr++;
+ if (!G_is_c_null_value(&precCell) && precCell == ptype) {
+ if (corrCell != precCell)
+ nedges++;
}
-
- if ((G_is_null_value(&infCell, CELL_TYPE)) ||
- (corrCell != infCell)) {
- bordoCorr++;
+ if (!G_is_c_null_value(&supCell) && supCell == ptype) {
+ if (corrCell != supCell)
+ nedges++;
}
-
- if ((G_is_null_value(&nextCell, CELL_TYPE)) ||
- (corrCell != nextCell)) {
- bordoCorr++;
- }
-
- /* store the result in the tree */
- if (albero == NULL) {
- c1.val.c = corrCell;
- albero = avl_make(c1, bordoCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
- return RLI_ERRORE;
+ }
+ else {
+ /* all patch types */
+ if (!G_is_c_null_value(&corrCell)) {
+ if (corrCell != precCell) {
+ nedges++;
}
- m++;
- }
- else {
- c1.val.c = corrCell;
- ris = avl_add(&albero, c1, bordoCorr);
-
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_add unknown error");
- return RLI_ERRORE;
- }
+ if (corrCell != supCell) {
+ nedges++;
}
+ /* right and bottom */
+ if (i == ad->rl - 1)
+ nedges++;
+ if (j == ad->cl - 1)
+ nedges++;
}
- bordoCorr = 0;
+ if (!G_is_c_null_value(&precCell) && corrCell != precCell) {
+ nedges++;
+ }
+ if (!G_is_c_null_value(&supCell) && corrCell != supCell) {
+ nedges++;
+ }
}
- prevCell = buf_corr[i + ad->x];
+ precCell = corrCell;
}
- if (masked)
- mask_sup = mask_corr;
}
/* calculate index */
- if (area == 0)
- indice = -1;
- else {
+ if (area > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double elength, cell_size;
- if (valore != NULL) { /* only 1 class */
- char *sval;
- int val;
- CELL cella;
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
- sval = valore[0];
- val = atoi(sval);
- cella = val;
- c1.t = CELL_TYPE;
- c1.val.c = cella;
- e = (double)howManyCell(albero, c1);
- somma = e;
- }
- else { /* all classes */
- array = G_malloc(m * sizeof(AVL_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avl_to_array(albero, zero, array);
- if (tot != m) {
- G_warning
- ("avl_to_array unexpected value. the result could be wrong");
- }
- for (i = 0; i < m; i++) {
- e = (double)array[i]->tot;
- somma = somma + e;
- }
- G_free(array);
- }
+ elength = ((EW_DIST1 + EW_DIST2) / (2 * hd.cols) +
+ (NS_DIST1 + NS_DIST2) / (2 * hd.rows)) / 2;
- indice = somma * 10000 / area;
+ cell_size = ((EW_DIST1 + EW_DIST2) / (2 * hd.cols)) *
+ ((NS_DIST1 + NS_DIST2) / (2 * hd.rows));
+
+ *result = (double) nedges * elength * 10000 / (area * cell_size);
}
+ else
+ G_set_d_null_value(result, 1);
- *result = indice;
if (masked) {
- G_free(mask_inf);
- G_free(mask_corr);
+ close(mask_fd);
+ G_free(mask_buf);
+ G_free(mask_sup);
}
+ G_free(buf_null);
- /* G_free(buf_sup); */ /* <-- why not free it? */
return RLI_OK;
}
-int calculateD(int fd, struct area_entry *ad, char **valore, double *result)
+int calculateD(int fd, struct area_entry *ad, char **par, double *result)
{
- double indice = 0;
- double e = 0;
- double somma = 0;
- double area = 0;
-
- DCELL *buf_corr, *buf_sup, *buf_inf;
- DCELL prevCell, corrCell, supCell, infCell, nextCell;
-
- AVL_table *array;
-
- long tot = 0;
- long zero = 0;
- long m = 0;
- long bordoCorr = 0;
-
- avl_tree albero = NULL;
-
+ DCELL *buf, *buf_sup, *buf_null;
+ DCELL corrCell, precCell, supCell;
+ DCELL ptype;
+ long nedges, area;
int i, j;
- int mask_fd = -1, *mask_corr, *mask_sup, *mask_inf;
- int masked = FALSE;
- int ris;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- generic_cell c1;
+ G_get_window(&hd);
- c1.t = DCELL_TYPE;
-
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
- if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) {
- G_fatal_error("Cannot open mask file");
- return RLI_ERRORE; /* FIXME: can not return from a fatal error */
- }
-
- mask_corr = G_malloc(ad->cl * sizeof(int));
- if (mask_corr == NULL) {
- G_fatal_error("malloc mask_corr failed");
+ if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
+ mask_buf = G_malloc(ad->cl * sizeof(int));
+ if (mask_buf == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
}
-
- mask_inf = G_malloc(ad->cl * sizeof(int));
- if (mask_inf == NULL) {
- G_fatal_error("malloc mask_inf failed");
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
masked = TRUE;
}
- buf_sup = G_allocate_d_raster_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
+ buf_null = G_allocate_d_raster_buf();
+ if (buf_null == NULL) {
+ G_fatal_error("malloc buf_null failed");
return RLI_ERRORE;
}
- G_set_d_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
+ /* the first time buf_sup is all null */
+ G_set_d_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+ if (par != NULL) { /* only 1 class */
+ char *sval;
- for (j = 0; j < ad->rl; j++) { /* for each raster row */
+ sval = par[0];
+ ptype = atof(sval);
+ }
+ else
+ G_set_d_null_value(&ptype, 1);
- buf_corr = RLI_get_dcell_raster_row(fd, j + ad->y, ad); /* read row of raster */
+ nedges = 0;
+ area = 0;
- if (j > 0) /* not first row */
- buf_sup = RLI_get_dcell_raster_row(fd, j - 1 + ad->y, ad);
+ /* for each raster row */
+ for (i = 0; i < ad->rl; i++) {
+ /* read row of raster */
+ buf = RLI_get_dcell_raster_row(fd, i + ad->y, ad);
- if ((j + 1) < ad->rl) { /*not last row */
+ if (i > 0) /* not first row */
+ buf_sup = RLI_get_dcell_raster_row(fd, i - 1 + ad->y, ad);
- buf_inf = RLI_get_dcell_raster_row(fd, 1 + j + ad->y, ad);
- }
- else {
- buf_inf = G_allocate_d_raster_buf();
- if (buf_inf == NULL) {
- G_fatal_error("malloc buf_inf failed");
+ /* read mask if needed */
+ if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
return RLI_ERRORE;
- }
-
- G_set_d_null_value(buf_inf + ad->x, ad->cl);
}
- /*read mask if needed */
- if (masked) {
+ G_set_d_null_value(&precCell, 1);
- if (read(mask_fd, mask_corr, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("reading mask_corr");
- return RLI_ERRORE;
- }
+ for (j = 0; j < ad->cl; j++) {
+ corrCell = buf[j + ad->x];
- if ((j + 1) < ad->rl) { /*not last row */
- if (read(mask_fd, mask_inf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("reading mask_inf");
- return RLI_ERRORE;
- }
+ if (masked && mask_buf[j] == 0) {
+ G_set_d_null_value(&corrCell, 1);
}
else {
- int z = 0;
-
- for (z = 0; z < ad->cl; z++)
- mask_inf[z + ad->x] = 0;
+ /* total sample area */
+ area++;
}
- }
- G_set_d_null_value(&nextCell, 1);
- G_set_d_null_value(&prevCell, 1);
- G_set_d_null_value(&corrCell, 1);
-
- for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
- area++;
- corrCell = buf_corr[i + ad->x];
-
- if (masked && mask_corr[i + ad->x] == 0) {
- G_set_d_null_value(&corrCell, 1);
- area--;
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_d_null_value(&supCell, 1);
}
- if (!(G_is_null_value(&corrCell, DCELL_TYPE))) {
- if ((i + 1) == ad->cl) /*last cell of the row */
- G_set_d_null_value(&nextCell, 1);
- else if (masked && mask_corr[i + 1 + ad->x] == 0)
- G_set_d_null_value(&nextCell, 1);
- else
- nextCell = buf_corr[i + 1 + ad->x];
-
- supCell = buf_sup[i + ad->x];
-
- if (masked && mask_inf[i + ad->x] == 0)
- G_set_d_null_value(&infCell, 1);
- else
- infCell = buf_inf[i + ad->x];
-
- /* calculate how many edge the cell has */
-
- if ((G_is_null_value(&prevCell, DCELL_TYPE)) ||
- (corrCell != prevCell)) {
- bordoCorr++;
+ if (!G_is_d_null_value(&ptype)) {
+ /* only one patch type */
+ if (!G_is_d_null_value(&corrCell) && corrCell == ptype) {
+ if (corrCell != precCell)
+ nedges++;
+ if (corrCell != supCell)
+ nedges++;
+ /* right and bottom */
+ if (i == ad->rl - 1)
+ nedges++;
+ if (j == ad->cl - 1)
+ nedges++;
}
-
- if ((G_is_null_value(&supCell, DCELL_TYPE)) ||
- (corrCell != supCell)) {
- bordoCorr++;
+ if (!G_is_d_null_value(&precCell) && precCell == ptype) {
+ if (corrCell != precCell)
+ nedges++;
}
-
- if ((G_is_null_value(&infCell, DCELL_TYPE)) ||
- (corrCell != infCell)) {
- bordoCorr++;
+ if (!G_is_d_null_value(&supCell) && supCell == ptype) {
+ if (corrCell != supCell)
+ nedges++;
}
-
- if ((G_is_null_value(&nextCell, DCELL_TYPE)) ||
- (corrCell != nextCell)) {
- bordoCorr++;
- }
-
- /* store the result in the tree */
- if (albero == NULL) {
- c1.val.dc = corrCell;
- albero = avl_make(c1, bordoCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
- return RLI_ERRORE;
+ }
+ else {
+ /* all patch types */
+ if (!G_is_d_null_value(&corrCell)) {
+ if (corrCell != precCell) {
+ nedges++;
}
- m++;
- }
- else {
- c1.val.dc = corrCell;
- ris = avl_add(&albero, c1, bordoCorr);
-
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_add unknown error");
- return RLI_ERRORE;
- }
+ if (corrCell != supCell) {
+ nedges++;
}
+ /* right and bottom */
+ if (i == ad->rl - 1)
+ nedges++;
+ if (j == ad->cl - 1)
+ nedges++;
}
- bordoCorr = 0;
+ if (!G_is_d_null_value(&precCell) && corrCell != precCell) {
+ nedges++;
+ }
+ if (!G_is_d_null_value(&supCell) && corrCell != supCell) {
+ nedges++;
+ }
}
- prevCell = buf_corr[i + ad->x];
+ precCell = corrCell;
}
- if (masked)
- mask_sup = mask_corr;
}
/* calculate index */
- if (area == 0)
- indice = -1;
- else {
- if (valore != NULL) { /* only 1 class */
- char *sval;
- double val;
- DCELL cella;
+ if (area > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double elength, cell_size;
- sval = valore[0];
- val = (double)atof(sval);
- cella = val;
- c1.val.dc = cella;
- c1.t = DCELL_TYPE;
- e = (double)howManyCell(albero, c1);
- somma = e;
- }
- else { /* all classes */
- array = G_malloc(m * sizeof(AVL_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avl_to_array(albero, zero, array);
- if (tot != m) {
- G_warning
- ("avl_to_array unexpected value. the result could be wrong");
- }
- for (i = 0; i < m; i++) {
- e = (double)array[i]->tot;
- somma = somma + e;
- }
- G_free(array);
- }
- indice = somma * 10000 / area;
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
+
+ elength = ((EW_DIST1 + EW_DIST2) / (2 * hd.cols) +
+ (NS_DIST1 + NS_DIST2) / (2 * hd.rows)) / 2;
+
+ cell_size = ((EW_DIST1 + EW_DIST2) / (2 * hd.cols)) *
+ ((NS_DIST1 + NS_DIST2) / (2 * hd.rows));
+
+ *result = (double) nedges * elength * 10000 / (area * cell_size);
}
+ else
+ G_set_d_null_value(result, 1);
- *result = indice;
if (masked) {
- G_free(mask_inf);
- G_free(mask_corr);
+ close(mask_fd);
+ G_free(mask_buf);
+ G_free(mask_sup);
}
+ G_free(buf_null);
+
return RLI_OK;
}
-int calculateF(int fd, struct area_entry *ad, char **valore, double *result)
+int calculateF(int fd, struct area_entry *ad, char **par, double *result)
{
- double indice = 0;
- double e = 0;
- double somma = 0;
- double area = 0;
-
- FCELL *buf_corr, *buf_sup, *buf_inf;
- FCELL prevCell, corrCell, supCell, infCell, nextCell;
-
- AVL_table *array;
-
- long tot = 0;
- long zero = 0;
- long m = 0;
- long bordoCorr = 0;
-
- avl_tree albero = NULL;
-
+ FCELL *buf, *buf_sup, *buf_null;
+ FCELL corrCell, precCell, supCell;
+ FCELL ptype;
+ long nedges, area;
int i, j;
- int mask_fd = -1, *mask_corr, *mask_sup, *mask_inf;
- int masked = FALSE;
- int ris;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- generic_cell c1;
+ G_get_window(&hd);
- c1.t = FCELL_TYPE;
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
- if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0) {
- G_fatal_error("Cannot open mask file");
- return RLI_ERRORE; /* FIXME: can not return from a fatal error */
- }
-
- mask_corr = G_malloc(ad->cl * sizeof(int));
- if (mask_corr == NULL) {
- G_fatal_error("malloc mask_corr failed");
+ if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
+ mask_buf = G_malloc(ad->cl * sizeof(int));
+ if (mask_buf == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
}
-
- mask_inf = G_malloc(ad->cl * sizeof(int));
- if (mask_inf == NULL) {
- G_fatal_error("malloc mask_inf failed");
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
masked = TRUE;
}
- buf_sup = G_allocate_f_raster_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
+ buf_null = G_allocate_f_raster_buf();
+ if (buf_null == NULL) {
+ G_fatal_error("malloc buf_null failed");
return RLI_ERRORE;
}
/* the first time buf_sup is all null */
- G_set_f_null_value(buf_sup + ad->x, ad->cl);
+ G_set_f_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+ if (par != NULL) { /* only 1 class */
+ char *sval;
+
+ sval = par[0];
+ ptype = atof(sval);
+ }
+ else
+ G_set_f_null_value(&ptype, 1);
+
+ nedges = 0;
+ area = 0;
+
/* for each raster row */
- for (j = 0; j < ad->rl; j++) {
+ for (i = 0; i < ad->rl; i++) {
+
/* read row of raster */
- buf_corr = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
+ buf = RLI_get_fcell_raster_row(fd, i + ad->y, ad);
- if (j > 0) /* not first row */
- buf_sup = RLI_get_fcell_raster_row(fd, j - 1 + ad->y, ad);
+ if (i > 0) /* not first row */
+ buf_sup = RLI_get_fcell_raster_row(fd, i - 1 + ad->y, ad);
- if ((j + 1) < ad->rl) { /* not last row */
- buf_inf = RLI_get_fcell_raster_row(fd, 1 + j + ad->y, ad);
- }
- else {
- buf_inf = G_allocate_f_raster_buf();
- if (mask_inf == NULL) {
- G_fatal_error("malloc mask_inf failed");
+ /* read mask if needed */
+ if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
return RLI_ERRORE;
- }
- G_set_f_null_value(buf_inf + ad->x, ad->cl);
}
- /* read mask if needed */
- if (masked) {
+ G_set_f_null_value(&precCell, 1);
- if (read(mask_fd, mask_corr, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("reading mask_corr");
- return RLI_ERRORE;
- }
+ for (j = 0; j < ad->cl; j++) {
+ corrCell = buf[j + ad->x];
- if ((j + 1) < ad->rl) { /*not last row */
- if (read(mask_fd, mask_inf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("reading mask_inf");
- return RLI_ERRORE;
- }
+ if (masked && mask_buf[j] == 0) {
+ G_set_f_null_value(&corrCell, 1);
}
else {
- int z = 0;
-
- for (z = 0; z < ad->cl; z++)
- mask_inf[z + ad->x] = 0;
+ /* total sample area */
+ area++;
}
- }
- G_set_f_null_value(&nextCell, 1);
- G_set_f_null_value(&prevCell, 1);
- G_set_f_null_value(&corrCell, 1);
-
- for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
- area++;
- corrCell = buf_corr[i + ad->x];
-
-
- if (masked && mask_corr[i + ad->x] == 0) {
- G_set_f_null_value(&corrCell, 1);
- area--;
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_f_null_value(&supCell, 1);
}
- if (!(G_is_null_value(&corrCell, FCELL_TYPE))) {
-
- if ((i + 1) == ad->cl) /*last cell of the row */
- G_set_f_null_value(&nextCell, 1);
- else if (masked && mask_corr[i + 1 + ad->x] == 0)
- G_set_f_null_value(&nextCell, 1);
- else
- nextCell = buf_corr[i + 1 + ad->x];
-
- supCell = buf_sup[i + ad->x];
-
- if (masked && mask_inf[i + ad->x] == 0)
- G_set_f_null_value(&infCell, 1);
- else
- infCell = buf_inf[i + ad->x];
-
- /* calculate how many edge the cell has */
- if ((G_is_null_value(&prevCell, FCELL_TYPE)) ||
- (corrCell != prevCell)) {
- bordoCorr++;
+ if (!G_is_f_null_value(&ptype)) {
+ /* only one patch type */
+ if (!G_is_f_null_value(&corrCell) && corrCell == ptype) {
+ if (corrCell != precCell)
+ nedges++;
+ if (corrCell != supCell)
+ nedges++;
+ /* right and bottom */
+ if (i == ad->rl - 1)
+ nedges++;
+ if (j == ad->cl - 1)
+ nedges++;
}
-
- if ((G_is_null_value(&supCell, FCELL_TYPE)) ||
- (corrCell != supCell)) {
- bordoCorr++;
+ if (!G_is_f_null_value(&precCell) && precCell == ptype) {
+ if (corrCell != precCell)
+ nedges++;
}
-
- if ((G_is_null_value(&infCell, FCELL_TYPE)) ||
- (corrCell != infCell)) {
- bordoCorr++;
+ if (!G_is_f_null_value(&supCell) && supCell == ptype) {
+ if (corrCell != supCell)
+ nedges++;
}
-
- if ((G_is_null_value(&nextCell, FCELL_TYPE)) ||
- (corrCell != nextCell)) {
- bordoCorr++;
- }
-
- /* store the result in the tree */
- if (albero == NULL) {
- c1.val.c = corrCell;
- albero = avl_make(c1, bordoCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
- return RLI_ERRORE;
+ }
+ else {
+ /* all patch types */
+ if (!G_is_f_null_value(&corrCell)) {
+ if (corrCell != precCell) {
+ nedges++;
}
- m++;
- }
- else {
- c1.val.c = corrCell;
- ris = avl_add(&albero, c1, bordoCorr);
-
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_add unknown error");
- return RLI_ERRORE;
- }
+ if (corrCell != supCell) {
+ nedges++;
}
+ /* right and bottom */
+ if (i == ad->rl - 1)
+ nedges++;
+ if (j == ad->cl - 1)
+ nedges++;
}
- bordoCorr = 0;
+ if (!G_is_f_null_value(&precCell) && corrCell != precCell) {
+ nedges++;
+ }
+ if (!G_is_f_null_value(&supCell) && corrCell != supCell) {
+ nedges++;
+ }
}
- prevCell = buf_corr[i + ad->x];
+ precCell = corrCell;
}
- if (masked)
- mask_sup = mask_corr;
}
/* calculate index */
- if (area == 0)
- indice = -1;
- else {
- if (valore != NULL) { /* only 1 class */
- char *sval;
- float val;
- FCELL cella;
+ if (area > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double elength, cell_size;
- sval = valore[0];
- val = (float)atof(sval);
- cella = val;
- c1.t = FCELL_TYPE;
- c1.val.fc = cella;
- e = (double)howManyCell(albero, c1);
- somma = e;
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
- }
- else { /* all classes */
- array = G_malloc(m * sizeof(AVL_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failederror");
- return RLI_ERRORE;
- }
- tot = avl_to_array(albero, zero, array);
- if (tot != m) {
- G_warning
- ("avl_to_array unaspected value. the result could be wrong");
- }
- for (i = 0; i < m; i++) {
- e = (double)array[i]->tot;
- somma = somma + e;
- }
- G_free(array);
- }
- indice = somma * 10000 / area;
+ elength = ((EW_DIST1 + EW_DIST2) / (2 * hd.cols) +
+ (NS_DIST1 + NS_DIST2) / (2 * hd.rows)) / 2;
+
+ cell_size = ((EW_DIST1 + EW_DIST2) / (2 * hd.cols)) *
+ ((NS_DIST1 + NS_DIST2) / (2 * hd.rows));
+
+ *result = (double) nedges * elength * 10000 / (area * cell_size);
}
+ else
+ G_set_d_null_value(result, 1);
- *result = indice;
if (masked) {
close(mask_fd);
- G_free(mask_inf);
- G_free(mask_corr);
+ G_free(mask_buf);
+ G_free(mask_sup);
}
+ G_free(buf_null);
+
return RLI_OK;
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.mpa/mpa.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.mpa/mpa.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.mpa/mpa.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -1,14 +1,19 @@
-
-/*
- * \brief calculates mean pixel attribute index
+/****************************************************************************
*
- * \AUTHOR: Serena Pallecchi student of Computer Science University of Pisa (Italy)
- * Commission from Faunalia Pontedera (PI) www.faunalia.it
+ * MODULE: r.li.mpa
+ * AUTHOR(S): Serena Pallecchi (original contributor)
+ * student of Computer Science University of Pisa (Italy)
+ * Commission from Faunalia Pontedera (PI) www.faunalia.it
+ * Rewrite: Markus Metz
*
- * This program is free software under the GPL (>=v2)
- * Read the COPYING file that comes with GRASS for details.
+ * PURPOSE: calculates mean pixel attribute index
+ * COPYRIGHT: (C) 2007-2014 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/glocale.h>
@@ -21,7 +26,7 @@
#include "../r.li.daemon/defs.h"
#include "../r.li.daemon/daemon.h"
-
+rli_func meanPixelAttribute;
int calculate(int fd, struct area_entry *ad, double *result);
int calculateD(int fd, struct area_entry *ad, double *result);
int calculateF(int fd, struct area_entry *ad, double *result);
@@ -58,15 +63,9 @@
int meanPixelAttribute(int fd, char **par, struct area_entry *ad, double *result)
{
- char *mapset;
int ris = 0;
double indice = 0;
- struct Cell_head hd;
- mapset = G_find_cell(ad->raster, "");
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
- return RLI_ERRORE;
-
switch (ad->data_type) {
case CELL_TYPE:
{
@@ -105,11 +104,10 @@
CELL *buf;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int masked = FALSE;
double area = 0;
- double indice = 0;
double somma = 0;
/* open mask if needed */
@@ -126,35 +124,32 @@
masked = TRUE;
}
+ for (j = 0; j < ad->rl; j++) {
+ buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
- for (j = 0; j < ad->rl; j++) { /*for each raster row */
- buf = RLI_get_cell_raster_row(fd, j + ad->y, ad); /*read raster row */
-
- if (masked) { /*read mask row if needed */
+ if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
G_fatal_error("mask read failed");
return RLI_ERRORE;
}
}
- for (i = 0; i < ad->cl; i++) { /*for each cell in the row */
- area++;
- if (masked && mask_buf[i + ad->x] == 0) {
+ for (i = 0; i < ad->cl; i++) {
+ if (masked && mask_buf[i] == 0) {
G_set_c_null_value(&buf[i + ad->x], 1);
- area--;
}
- if (!(G_is_null_value(&buf[i + ad->x], CELL_TYPE))) { /*if it's a cell to consider */
+ if (!(G_is_c_null_value(&buf[i + ad->x]))) {
+ area++;
somma = somma + buf[i + ad->x];
}
}
}
- if (area == 0)
- indice = (double)-1;
+ if (area > 0)
+ *result = somma / area;
else
- indice = somma / area;
+ G_set_d_null_value(result, 1);
- *result = indice;
if (masked) {
close(mask_fd);
G_free(mask_buf);
@@ -169,11 +164,10 @@
DCELL *buf;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int masked = FALSE;
double area = 0;
- double indice = 0;
double somma = 0;
/* open mask if needed */
@@ -190,36 +184,32 @@
masked = TRUE;
}
+ for (j = 0; j < ad->rl; j++) {
+ buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
-
- for (j = 0; j < ad->rl; j++) { /*for each raster row */
- buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad); /*read raster row */
-
- if (masked) { /*read mask row if needed */
+ if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
G_fatal_error("mask read failed");
return RLI_ERRORE;
}
}
- for (i = 0; i < ad->cl; i++) { /*for each cell in the row */
- area++;
- if ((masked) && (mask_buf[i + ad->x] == 0)) {
- area--;
+ for (i = 0; i < ad->cl; i++) {
+ if (masked && mask_buf[i] == 0) {
G_set_d_null_value(&buf[i + ad->x], 1);
}
- if (!(G_is_null_value(&buf[i + ad->x], DCELL_TYPE))) {
+ if (!(G_is_d_null_value(&buf[i + ad->x]))) {
+ area++;
somma = somma + buf[i + ad->x];
}
}
}
- if (area == 0)
- indice = (double)-1;
+ if (area > 0)
+ *result = somma / area;
else
- indice = somma / area;
+ G_set_d_null_value(result, 1);
- *result = indice;
if (masked) {
close(mask_fd);
G_free(mask_buf);
@@ -233,11 +223,10 @@
FCELL *buf;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int masked = FALSE;
double area = 0;
- double indice = 0;
double somma = 0;
/* open mask if needed */
@@ -254,36 +243,32 @@
masked = TRUE;
}
+ for (j = 0; j < ad->rl; j++) {
+ buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
- for (j = 0; j < ad->rl; j++) { /*for each raster row */
- buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad); /*read raster row */
-
- if (masked) { /*read mask row if needed */
+ if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
G_fatal_error("mask read failed");
return RLI_ERRORE;
}
}
- for (i = 0; i < ad->cl; i++) { /*for each cell in the row */
- area++;
-
- if ((masked) && (mask_buf[i + ad->x] == 0)) {
- area--;
+ for (i = 0; i < ad->cl; i++) {
+ if (masked && mask_buf[i] == 0) {
G_set_f_null_value(&buf[i + ad->x], 1);
}
- if (!(G_is_null_value(&buf[i + ad->x], FCELL_TYPE))) {
+ if (!(G_is_f_null_value(&buf[i + ad->x]))) {
+ area++;
somma = somma + buf[i + ad->x];
}
}
}
- if (area == 0)
- indice = (double)-1;
+ if (area > 0)
+ *result = somma / area;
else
- indice = somma / area;
+ G_set_d_null_value(result, 1);
- *result = indice;
if (masked) {
close(mask_fd);
G_free(mask_buf);
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.mps/mps.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.mps/mps.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.mps/mps.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -4,6 +4,8 @@
* AUTHOR(S): Serena Pallecchi (original contributor)
* student of Computer Science University of Pisa (Italy)
* Commission from Faunalia Pontedera (PI) www.faunalia.it
+ * Rewrite: Markus Metz
+ * Patch identification: Michael Shapiro - CERL
*
* PURPOSE: calculates mean patch size index
* COPYRIGHT: (C) 2007-2014 by the GRASS Development Team
@@ -21,16 +23,22 @@
#include <grass/gis.h>
#include <grass/glocale.h>
-#include "../r.li.daemon/defs.h"
-#include "../r.li.daemon/avlDefs.h"
-#include "../r.li.daemon/avlID.h"
#include "../r.li.daemon/daemon.h"
+#include "../r.li.daemon/GenericCell.h"
+/* template is patchnum */
-int calculate(int fd, struct area_entry *ad, struct Cell_head hd, double *result);
-int calculateD(int fd, struct area_entry *ad, struct Cell_head hd, double *result);
-int calculateF(int fd, struct area_entry *ad, struct Cell_head hd, double *result);
+/* cell count and type of each patch */
+struct pst {
+ long count;
+ generic_cell type;
+};
+rli_func meanPatchSize;
+int calculate(int fd, struct area_entry *ad, double *result);
+int calculateD(int fd, struct area_entry *ad, double *result);
+int calculateF(int fd, struct area_entry *ad, double *result);
+
int main(int argc, char *argv[])
{
struct Option *raster, *conf, *output;
@@ -62,29 +70,23 @@
int meanPatchSize(int fd, char **par, struct area_entry *ad, double *result)
{
- char *mapset;
- int ris = 0;
+ int ris = RLI_OK;
double indice = 0;
- struct Cell_head hd;
- mapset = G_find_cell(ad->raster, "");
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
- return RLI_ERRORE;
-
switch (ad->data_type) {
case CELL_TYPE:
{
- ris = calculate(fd, ad, hd, &indice);
+ ris = calculate(fd, ad, &indice);
break;
}
case DCELL_TYPE:
{
- ris = calculateD(fd, ad, hd, &indice);
+ ris = calculateD(fd, ad, &indice);
break;
}
case FCELL_TYPE:
{
- ris = calculateF(fd, ad, hd, &indice);
+ ris = calculateF(fd, ad, &indice);
break;
}
default:
@@ -92,10 +94,11 @@
G_fatal_error("data type unknown");
return RLI_ERRORE;
}
-
}
- if (ris != RLI_OK)
+
+ if (ris != RLI_OK) {
return RLI_ERRORE;
+ }
*result = indice;
@@ -103,40 +106,38 @@
}
-int calculate(int fd, struct area_entry *ad, struct Cell_head hd, double *result)
+int calculate(int fd, struct area_entry *ad, double *result)
{
- CELL *buf;
- CELL *buf_sup;
+ CELL *buf, *buf_sup, *buf_null;
+ CELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- CELL corrCell;
- CELL precCell;
- CELL supCell;
+ G_get_window(&hd);
- int i, j;
- int mask_fd = -1, *mask_buf;
- int ris = 0;
- int masked = FALSE;
+ buf_null = G_allocate_cell_buf();
+ G_set_c_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+ /* initialize patch ids */
+ pid_corr = G_malloc(ad->cl * sizeof(long));
+ pid_sup = G_malloc(ad->cl * sizeof(long));
- long npatch = 0;
- long tot = 0;
- long zero = 0;
- long uno = 1;
- long idCorr = 0;
- long lastId = 0;
- long doppi = 0;
- long *mask_patch_sup;
- long *mask_patch_corr;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
- double indice = 0;
- double area = 0; /*if all cells are null area=0 */
- double areaCorrect = 0;
- double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
-
- avlID_tree albero = NULL;
- avlID_table *array;
-
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
@@ -145,301 +146,156 @@
G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
masked = TRUE;
}
- mask_patch_sup = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_sup == NULL) {
- G_fatal_error("malloc mask_patch_sup failed");
- return RLI_ERRORE;
- }
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
- mask_patch_corr = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_corr == NULL) {
- G_fatal_error("malloc mask_patch_corr failed");
- return RLI_ERRORE;
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
}
- buf_sup = G_allocate_cell_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
- return RLI_ERRORE;
- }
-
- buf = G_allocate_cell_buf();
- if (buf == NULL) {
- G_fatal_error("malloc buf failed");
- return RLI_ERRORE;
- }
-
- G_set_c_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
-
- for (i = 0; i < ad->cl; i++) {
- mask_patch_sup[i] = 0;
- mask_patch_corr[i] = 0;
- }
-
- /*for each raster row */
-
- for (j = 0; j < ad->rl; j++) {
- if (j > 0) {
- buf_sup = RLI_get_cell_raster_row(fd, j - 1 + ad->y, ad);
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_cell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad);
}
- buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
+
if (masked) {
- if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("mask read failed");
- return RLI_ERRORE;
- }
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
}
- G_set_c_null_value(&precCell, 1);
- for (i = 0; i < ad->cl; i++) { /*for each cell in the row */
- corrCell = buf[i + ad->x];
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
- if ((masked) && (mask_buf[i + ad->x] == 0)) {
+ G_set_c_null_value(&precCell, 1);
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
G_set_c_null_value(&corrCell, 1);
}
- /*valid cell */
- if (!(G_is_null_value(&corrCell, CELL_TYPE))) {
- area++;
- if (i > 0)
- precCell = buf[i - 1 + ad->x];
+ if (G_is_c_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_c_null_value(&supCell, 1);
+ }
- if (j == 0)
- G_set_c_null_value(&supCell, 1);
- else
- supCell = buf_sup[i + ad->x];
+ if (!G_is_c_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j] = pid_corr[j - 1];
+ connected = 1;
+ pst[pid_corr[j]].count++;
+ }
+ else {
+ connected = 0;
+ }
+ if (!G_is_c_null_value(&supCell) && corrCell == supCell) {
- if (corrCell != precCell) {
- if (corrCell != supCell) {
- /*new patch */
- if (idCorr == 0) { /*first patch */
- lastId = 1;
- idCorr = 1;
- mask_patch_corr[i] = idCorr;
- }
- else { /*not first patch */
- /* put in the tree previous values */
- if (albero == NULL) {
- albero = avlID_make(idCorr, uno);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ if (pid_corr[j] != pid_sup[j]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
- }
- else { /* tree not null */
-
- ris = avlID_add(&albero, idCorr, uno);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error
- ("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
-
- lastId++;
- idCorr = lastId;
- mask_patch_corr[i] = idCorr;
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
}
}
- else { /*current cell and upper cell are equal */
- if ((corrCell == precCell) &&
- (mask_patch_sup[i] != mask_patch_corr[i - 1])) {
- long r = 0;
- long del = mask_patch_sup[i];
-
- r = avlID_sub(&albero, del);
- if (r == 0) {
- G_fatal_error("avlID_sub error");
- return RLI_ERRORE;
- }
- /*Remove one patch because it makes part of a patch already found */
- ris = avlID_add(&albero, idCorr, uno);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- r = i;
- while (i < ad->cl) {
- if (mask_patch_sup[r] == del) {
- mask_patch_sup[r] = idCorr;
- }
- else {
- r = ad->cl + 1;
- }
- }
+ old_pid = pid_corr[j];
+ new_pid = pid_sup[j];
+ pid_corr[j] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k] == old_pid)
+ pid_corr[k] = new_pid;
}
-
- if (albero == NULL) {
- albero = avlID_make(idCorr, uno);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k] == old_pid)
+ pid_sup[k] = new_pid;
}
- else { /* tree not null */
-
- ris = avlID_add(&albero, idCorr, uno);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
-
- idCorr = mask_patch_sup[i];
- mask_patch_corr[i] = idCorr;
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
- }
- else { /*current cell and previous cell are equal */
-
-
- if ((corrCell == supCell) &&
- (mask_patch_sup[i] != mask_patch_corr[i - 1])) {
- int l;
-
- mask_patch_corr[i] = mask_patch_sup[i];
- l = i - 1;
- while (l >= 0) {
- if (mask_patch_corr[l] == idCorr) {
- mask_patch_corr[l] = mask_patch_sup[i];
- l--;
- }
- else {
- l = (-1);
- }
- }
- lastId--;
- idCorr = mask_patch_sup[i];
- }
else {
- mask_patch_corr[i] = idCorr;
+ pst[new_pid].count++;
}
-
}
+ connected = 1;
}
- else { /*cell not to consider or cell is null */
- mask_patch_corr[i] = 0;
- }
- }
- mask_patch_sup = mask_patch_corr;
- }
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j] = pid;
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
- if (area != 0) {
- if (albero == NULL) {
- albero = avlID_make(idCorr, uno);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
- npatch++;
+ precCell = corrCell;
}
- else {
- ris = avlID_add(&albero, idCorr, uno);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
+ }
+ if (npatch > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_units;
- array = G_malloc(npatch * sizeof(avlID_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avlID_to_array(albero, zero, array);
-
- if (tot != npatch) {
- G_warning
- ("avlID_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
-
- for (i = 0; i < npatch; i++) {
- if (array[i]->tot == 0)
- doppi++;
- }
- npatch = npatch - doppi;
-
- /*calculate distance */
+ /* calculate distance */
G_begin_distance_calculations();
/* EW Dist at North edge */
EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
@@ -450,60 +306,61 @@
/* NS Dist at West edge */
NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
- areaCorrect = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
- (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * (area);
- indice = areaCorrect / npatch;
- G_free(array);
+ area_units = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
+ (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * area;
+
+ *result = area_units / (npatch * 10000);
}
- else
- indice = (double)(0);
+ else {
+ *result = 0;
+ }
-
- *result = indice;
-
-
- if (masked)
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
- G_free(mask_patch_corr);
-
- /* G_free(buf_sup); */ /* <-- why not free it? */
return RLI_OK;
}
-int calculateD(int fd, struct area_entry *ad, struct Cell_head hd, double *result)
+int calculateD(int fd, struct area_entry *ad, double *result)
{
- DCELL *buf;
- DCELL *buf_sup;
- DCELL corrCell;
- DCELL precCell;
- DCELL supCell;
- int i, j;
- int mask_fd = -1, *mask_buf;
- int ris = 0;
- int masked = FALSE;
- long npatch = 0;
- long tot = 0;
- long zero = 0;
- long uno = 1;
- long idCorr = 0;
- long lastId = 0;
- long doppi = 0;
- long *mask_patch_sup;
- long *mask_patch_corr;
- double indice = 0;
- double area = 0; /*if all cells are null area=0 */
- double areaCorrect = 0;
- double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ DCELL *buf, *buf_sup, *buf_null;
+ DCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- avlID_tree albero = NULL;
+ G_get_window(&hd);
- avlID_table *array;
+ buf_null = G_allocate_d_raster_buf();
+ G_set_d_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+ /* initialize patch ids */
+ pid_corr = G_malloc(ad->cl * sizeof(long));
+ pid_sup = G_malloc(ad->cl * sizeof(long));
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
@@ -512,300 +369,156 @@
G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
masked = TRUE;
}
- mask_patch_sup = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_sup == NULL) {
- G_fatal_error("malloc mask_patch_sup failed");
- return RLI_ERRORE;
- }
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
- mask_patch_corr = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_corr == NULL) {
- G_fatal_error("malloc mask_patch_corr failed");
- return RLI_ERRORE;
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
}
- buf_sup = G_allocate_d_raster_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
- return RLI_ERRORE;
- }
-
- buf = G_allocate_d_raster_buf();
- if (buf == NULL) {
- G_fatal_error("malloc buf failed");
- return RLI_ERRORE;
- }
-
- G_set_d_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
-
- for (i = 0; i < ad->cl; i++) {
- mask_patch_sup[i] = 0;
- mask_patch_corr[i] = 0;
- }
-
- /*read each row and put in an avlId tree cell value with the number of cells which have that value */
- for (j = 0; j < ad->rl; j++) {
- if (j > 0) {
- buf_sup = RLI_get_dcell_raster_row(fd, j - 1 + ad->y, ad);
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_dcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_dcell_raster_row(fd, i - 1 + ad->y, ad);
}
- buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
+
if (masked) {
- if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("mask read failed");
- return RLI_ERRORE;
- }
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
}
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
G_set_d_null_value(&precCell, 1);
- for (i = 0; i < ad->cl; i++) { /*for each cell in the row */
- corrCell = buf[i + ad->x];
-
- if ((masked) && (mask_buf[i + ad->x] == 0)) {
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
G_set_d_null_value(&corrCell, 1);
}
- if (!(G_is_null_value(&corrCell, DCELL_TYPE))) {
- area++;
- if (i > 0)
- precCell = buf[i - 1 + ad->x];
+ if (G_is_d_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_d_null_value(&supCell, 1);
+ }
- if (j == 0)
- G_set_d_null_value(&supCell, 1);
- else
- supCell = buf_sup[i + ad->x];
+ if (!G_is_d_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j] = pid_corr[j - 1];
+ connected = 1;
+ pst[pid_corr[j]].count++;
+ }
+ else {
+ connected = 0;
+ }
- if (corrCell != precCell) {
- if (corrCell != supCell) {
- /*new patch */
- if (idCorr == 0) { /*first patch */
- lastId = 1;
- idCorr = 1;
- mask_patch_corr[i] = idCorr;
- }
- else { /*not first patch */
- /* put in the tree previous value */
- if (albero == NULL) {
- albero = avlID_make(idCorr, uno);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ if (!G_is_d_null_value(&supCell) && corrCell == supCell) {
- }
- else { /* tree not null */
+ if (pid_corr[j] != pid_sup[j]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
- ris = avlID_add(&albero, idCorr, uno);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error
- ("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
-
- lastId++;
- idCorr = lastId;
- mask_patch_corr[i] = idCorr;
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
}
}
- else { /*current cell and upper cell are equal */
- if ((corrCell == precCell) &&
- (mask_patch_sup[i] != mask_patch_corr[i - 1])) {
- long r = 0;
- long del = mask_patch_sup[i];
-
- /*Remove one patch because it makes part of a patch already found */
- r = avlID_sub(&albero, del);
- if (r == 0) {
- G_fatal_error("avlID_sub error");
- return RLI_ERRORE;
- }
-
- ris = avlID_add(&albero, idCorr, uno);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- r = i;
- while (i < ad->cl) {
- if (mask_patch_sup[r] == del) {
- mask_patch_sup[r] = idCorr;
- }
- else {
- r = ad->cl + 1;
- }
- }
+ old_pid = pid_corr[j];
+ new_pid = pid_sup[j];
+ pid_corr[j] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k] == old_pid)
+ pid_corr[k] = new_pid;
}
-
- if (albero == NULL) {
- albero = avlID_make(idCorr, uno);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k] == old_pid)
+ pid_sup[k] = new_pid;
}
- else { /*tree not null */
-
- ris = avlID_add(&albero, idCorr, uno);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
-
- idCorr = mask_patch_sup[i];
- mask_patch_corr[i] = idCorr;
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
- }
- else { /*current cell and previous cell are equals */
-
-
- if ((corrCell == supCell) &&
- (mask_patch_sup[i] != mask_patch_corr[i - 1])) {
- int l;
-
- mask_patch_corr[i] = mask_patch_sup[i];
- l = i - 1;
- while (l >= 0) {
- if (mask_patch_corr[l] == idCorr) {
- mask_patch_corr[l] = mask_patch_sup[i];
- l--;
- }
- else {
- l = (-1);
- }
- }
- lastId--;
- idCorr = mask_patch_sup[i];
- }
else {
- mask_patch_corr[i] = idCorr;
+ pst[new_pid].count++;
}
-
}
+ connected = 1;
}
- else { /*cell null or not to consider */
- mask_patch_corr[i] = 0;
- }
- }
- mask_patch_sup = mask_patch_corr;
- }
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j] = pid;
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
- if (area != 0) {
- if (albero == NULL) {
- albero = avlID_make(idCorr, uno);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
- npatch++;
+ precCell = corrCell;
}
- else {
- ris = avlID_add(&albero, idCorr, uno);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
+ }
+ if (npatch > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_units;
- array = G_malloc(npatch * sizeof(avlID_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avlID_to_array(albero, zero, array);
-
- if (tot != npatch) {
- G_warning
- ("avlID_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
-
- for (i = 0; i < npatch; i++) {
- if (array[i]->tot == 0)
- doppi++;
-
- }
- npatch = npatch - doppi;
-
- /*calculate distance */
+ /* calculate distance */
G_begin_distance_calculations();
/* EW Dist at North edge */
EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
@@ -816,64 +529,61 @@
/* NS Dist at West edge */
NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
- areaCorrect = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
- (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * (area);
- indice = areaCorrect / npatch;
- G_free(array);
+ area_units = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
+ (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * area;
+
+ *result = area_units / (npatch * 10000);
}
- else
- indice = (double)(0);
+ else {
+ *result = 0;
+ }
-
- *result = indice;
-
-
- if (masked)
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
- G_free(mask_patch_corr);
-
return RLI_OK;
}
-int calculateF(int fd, struct area_entry *ad, struct Cell_head hd, double *result)
+int calculateF(int fd, struct area_entry *ad, double *result)
{
- FCELL *buf;
- FCELL *buf_sup;
+ FCELL *buf, *buf_sup, *buf_null;
+ FCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- FCELL corrCell;
- FCELL precCell;
- FCELL supCell;
+ G_get_window(&hd);
- int i, j;
- int mask_fd = -1, *mask_buf;
- int ris = 0;
- int masked = FALSE;
+ buf_null = G_allocate_f_raster_buf();
+ G_set_f_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+ /* initialize patch ids */
+ pid_corr = G_malloc(ad->cl * sizeof(long));
+ pid_sup = G_malloc(ad->cl * sizeof(long));
- long npatch = 0;
- long tot = 0;
- long zero = 0;
- long uno = 1;
- long idCorr = 0;
- long lastId = 0;
- long doppi = 0;
- long *mask_patch_sup;
- long *mask_patch_corr;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
- double indice = 0;
- double area = 0; /*if all cells are null area=0 */
- double areaCorrect = 0;
- double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
-
- avlID_tree albero = NULL;
-
- avlID_table *array;
-
-
-
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
@@ -882,297 +592,156 @@
G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
masked = TRUE;
}
- mask_patch_sup = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_sup == NULL) {
- G_fatal_error("malloc mask_patch_sup failed");
- return RLI_ERRORE;
- }
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
- mask_patch_corr = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_corr == NULL) {
- G_fatal_error("malloc mask_patch_corr failed");
- return RLI_ERRORE;
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
}
- buf_sup = G_allocate_f_raster_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
- return RLI_ERRORE;
- }
-
-
- buf = G_allocate_f_raster_buf();
- if (buf == NULL) {
- G_fatal_error("malloc buf failed");
- return RLI_ERRORE;
- }
-
- G_set_f_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
-
- for (i = 0; i < ad->cl; i++) {
- mask_patch_sup[i] = 0;
- mask_patch_corr[i] = 0;
- }
- /*for each raster row */
-
- for (j = 0; j < ad->rl; j++) {
- if (j > 0) {
- buf_sup = RLI_get_fcell_raster_row(fd, j - 1 + ad->y, ad);
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_fcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_fcell_raster_row(fd, i - 1 + ad->y, ad);
}
- buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
+
if (masked) {
- if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("mask read failed");
- return RLI_ERRORE;
- }
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
}
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
G_set_f_null_value(&precCell, 1);
- for (i = 0; i < ad->cl; i++) { /*for each cell in the row */
-
- corrCell = buf[i + ad->x];
- if (((masked) && (mask_buf[i + ad->x] == 0))) {
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
G_set_f_null_value(&corrCell, 1);
}
- if (!(G_is_null_value(&corrCell, FCELL_TYPE))) {
- area++;
- if (i > 0)
- precCell = buf[i - 1 + ad->x];
- if (j == 0)
- G_set_f_null_value(&supCell, 1);
- else
- supCell = buf_sup[i + ad->x];
+ if (G_is_f_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_f_null_value(&supCell, 1);
+ }
- if (corrCell != precCell) {
- if (corrCell != supCell) {
- /*new patch */
- if (idCorr == 0) { /*first patch */
- lastId = 1;
- idCorr = 1;
- mask_patch_corr[i] = idCorr;
- }
- else { /*not first patch */
- /* put in the tree previous value */
- if (albero == NULL) {
- albero = avlID_make(idCorr, uno);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ if (!G_is_f_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j] = pid_corr[j - 1];
+ connected = 1;
+ pst[pid_corr[j]].count++;
+ }
+ else {
+ connected = 0;
+ }
- }
- else { /*tree not empty */
+ if (!G_is_f_null_value(&supCell) && corrCell == supCell) {
- ris = avlID_add(&albero, idCorr, uno);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error
- ("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
+ if (pid_corr[j] != pid_sup[j]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
- lastId++;
- idCorr = lastId;
- mask_patch_corr[i] = idCorr;
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
}
}
- else { /*current cell and upper cell are equal */
- if ((corrCell == precCell) &&
- (mask_patch_sup[i] != mask_patch_corr[i - 1])) {
- long r = 0;
- long del = mask_patch_sup[i];
-
- r = avlID_sub(&albero, del);
- if (r == 0) {
- G_fatal_error("avlID_sub error");
- return RLI_ERRORE;
- }
- /*Remove one patch because it makes part of a patch already found */
- ris = avlID_add(&albero, idCorr, uno);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- r = i;
- while (i < ad->cl) {
- if (mask_patch_sup[r] == del) {
- mask_patch_sup[r] = idCorr;
- }
- else {
- r = ad->cl + 1;
- }
- }
+ old_pid = pid_corr[j];
+ new_pid = pid_sup[j];
+ pid_corr[j] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k] == old_pid)
+ pid_corr[k] = new_pid;
}
-
- if (albero == NULL) {
- albero = avlID_make(idCorr, uno);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k] == old_pid)
+ pid_sup[k] = new_pid;
}
- else { /*the tree (albero) isn't null */
-
- ris = avlID_add(&albero, idCorr, uno);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
-
- idCorr = mask_patch_sup[i];
- mask_patch_corr[i] = idCorr;
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
- }
- else { /*current cell and previous cell are equal */
-
- if ((corrCell == supCell) &&
- (mask_patch_sup[i] != mask_patch_corr[i - 1])) {
- int l;
-
- mask_patch_corr[i] = mask_patch_sup[i];
- l = i - 1;
- while (l >= 0) {
- if (mask_patch_corr[l] == idCorr) {
- mask_patch_corr[l] = mask_patch_sup[i];
- l--;
- }
- else {
- l = (-1);
- }
- }
- lastId--;
- idCorr = mask_patch_sup[i];
- }
else {
- mask_patch_corr[i] = idCorr;
+ pst[new_pid].count++;
}
-
}
+ connected = 1;
}
- else { /*null cell or cell not to consider */
- mask_patch_corr[i] = 0;
- }
- }
- mask_patch_sup = mask_patch_corr;
- }
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j] = pid;
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
- if (area != 0) {
- if (albero == NULL) {
- albero = avlID_make(idCorr, uno);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
- npatch++;
+ precCell = corrCell;
}
- else {
- ris = avlID_add(&albero, idCorr, uno);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
+ }
- array = G_malloc(npatch * sizeof(avlID_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avlID_to_array(albero, zero, array);
+ if (npatch > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_units;
- if (tot != npatch) {
- G_warning
- ("avlID_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
-
- for (i = 0; i < npatch; i++) {
- if (array[i]->tot == 0)
- doppi++;
-
- }
- npatch = npatch - doppi;
-
- /*calculate distance */
+ /* calculate distance */
G_begin_distance_calculations();
/* EW Dist at North edge */
EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
@@ -1183,22 +752,24 @@
/* NS Dist at West edge */
NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
- areaCorrect = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
- (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * (area);
- indice = areaCorrect / npatch;
- G_free(array);
+ area_units = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
+ (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * area;
+
+ *result = area_units / (npatch * 10000);
}
- else
- indice = (double)(0);
+ else {
+ *result = 0;
+ }
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
- *result = indice;
-
-
- if (masked)
- G_free(mask_buf);
-/* TODO: fix if? */
- G_free(mask_patch_corr);
-
return RLI_OK;
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.padcv/padcv.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.padcv/padcv.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.padcv/padcv.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -5,6 +5,8 @@
* student of Computer Science University of Pisa (Italy)
* Commission from Faunalia Pontedera (PI) www.faunalia.it
* Fixes: Markus Neteler <neteler itc.it>
+ * Rewrite: Markus Metz
+ * Patch identification: Michael Shapiro - CERL
*
* PURPOSE: calculates coefficient of variation of patch areas
* COPYRIGHT: (C) 2007-2014 by the GRASS Development Team
@@ -22,12 +24,18 @@
#include <grass/gis.h>
#include <grass/glocale.h>
-#include "../r.li.daemon/defs.h"
-#include "../r.li.daemon/avlDefs.h"
-#include "../r.li.daemon/avlID.h"
-#include "../r.li.daemon/GenericCell.h"
#include "../r.li.daemon/daemon.h"
+#include "../r.li.daemon/GenericCell.h"
+/* template is patchnum */
+
+/* cell count and type of each patch */
+struct pst {
+ long count;
+ generic_cell type;
+};
+
+rli_func patchAreaDistributionCV;
int calculate(int fd, struct area_entry *ad, double *result);
int calculateD(int fd, struct area_entry *ad, double *result);
int calculateF(int fd, struct area_entry *ad, double *result);
@@ -61,14 +69,9 @@
int patchAreaDistributionCV(int fd, char **par, struct area_entry *ad, double *result)
{
- char *mapset;
double indice = 0;
- struct Cell_head hd;
int ris = RLI_OK;
- mapset = G_find_cell(ad->raster, "");
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
- return RLI_ERRORE;
switch (ad->data_type) {
case CELL_TYPE:
{
@@ -105,39 +108,36 @@
int calculate(int fd, struct area_entry *ad, double *result)
{
- CELL *buf;
- CELL *buf_sup;
- CELL corrCell;
- CELL precCell;
- CELL supCell;
- int i, j;
- int mask_fd = -1, *mask_buf;
- int ris = 0;
- int masked = FALSE;
- int areaPatch = 0; /*if all cells are null areaPatch=0 */
- long npatch = 0;
- long tot = 0;
- long zero = 0;
- long totCorr = 0;
- long idCorr = 0;
- long lastId = 0;
- long doppi = 0;
- long np = 0;
- long *mask_patch_sup;
- long *mask_patch_corr;
- double indice = 0;
- double somma = 0;
- double area = 0;
- double mn = 0;
- double sd = 0;
- double cv = 0;
- avlID_tree albero = NULL;
- avlID_table *array = NULL;
- generic_cell gc;
+ CELL *buf, *buf_sup, *buf_null;
+ CELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- gc.t = CELL_TYPE;
+ G_get_window(&hd);
+ buf_null = G_allocate_cell_buf();
+ G_set_c_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(G_window_cols() * sizeof(long));
+ pid_sup = G_malloc(G_window_cols() * sizeof(long));
+
+ for (j = 0; j < G_window_cols(); j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
@@ -146,388 +146,241 @@
G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
masked = TRUE;
}
- mask_patch_sup = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_sup == NULL) {
- G_fatal_error("malloc mask_patch_sup failed");
- return RLI_ERRORE;
+
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
+
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
}
- mask_patch_corr = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_corr == NULL) {
- G_fatal_error("malloc mask_patch_corr failed");
- return RLI_ERRORE;
- }
- buf_sup = G_allocate_cell_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
- return RLI_ERRORE;
- }
- buf = G_allocate_cell_buf();
- if (buf == NULL) {
- G_fatal_error("malloc buf failed");
- return RLI_ERRORE;
- }
- G_set_c_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
- for (i = 0; i < ad->cl; i++) {
- mask_patch_sup[i] = 0;
- mask_patch_corr[i] = 0;
- }
- for (j = 0; j < ad->rl; j++)
- /*for each raster row */
- {
- if (j > 0) {
- buf_sup = RLI_get_cell_raster_row(fd, j - 1 + ad->y, ad);
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_cell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad);
}
- buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
+
if (masked) {
- if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("mask read failed");
- return RLI_ERRORE;
- }
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
}
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
G_set_c_null_value(&precCell, 1);
- for (i = 0; i < ad->cl; i++)
- /* for each cell in the row */
- {
- area++;
- corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j + ad->x] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
G_set_c_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, gc.t))) {
- areaPatch++;
- if (i > 0)
- precCell = buf[i - 1 + ad->x];
- if (j == 0)
- G_set_c_null_value(&supCell, 1);
- else
- supCell = buf_sup[i + ad->x];
+ if (G_is_c_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_c_null_value(&supCell, 1);
+ }
- if (corrCell != precCell)
- /* ?
- * 1 2
- * */
- {
- if (corrCell != supCell) {
- /* 3
- * 1 2
- * */
- /*new patch */
- if (idCorr == 0) { /*first found patch */
- lastId = 1;
- idCorr = 1;
- totCorr = 1;
- mask_patch_corr[i] = idCorr;
- }
+ if (!G_is_c_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j + ad->x] = pid_corr[j - 1 + ad->x];
+ connected = 1;
+ pst[pid_corr[j + ad->x]].count++;
+ }
+ else {
+ connected = 0;
+ }
- else
- /*not first patch */
- /* put in the tree the previous value */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
+ if (!G_is_c_null_value(&supCell) && corrCell == supCell) {
- else
- /*tree not empty */
- {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error
- ("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
- totCorr = 1;
- lastId++;
- idCorr = lastId;
- mask_patch_corr[i] = idCorr;
- }
- }
+ if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
- else
- /* current cell and upper cell are equal */
- /* 2
- * 1 2
- * */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
}
- else { /*tree not null */
-
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
-
- idCorr = mask_patch_sup[i];
- mask_patch_corr[i] = idCorr;
- totCorr = 1;
}
- }
- else { /*current cell and previuos cell are equal */
- /* ?
- * 1 1
- */
- if (corrCell == supCell) { /*current cell and upper cell are equal */
- /* 1
- * 1 1
- */
- if (mask_patch_sup[i] != mask_patch_corr[i - 1]) {
- long r = 0;
- long del = mask_patch_sup[i];
-
-
- r = avlID_sub(&albero, del); /*r=number of cell of patch removed */
-
- if (r == 0) {
- G_fatal_error("avlID_sub error");
- return RLI_ERRORE;
- }
-
- /*Remove one patch because it makes part of a patch already found */
- ris = avlID_add(&albero, idCorr, r);
-
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- r = i;
- while (r < ad->cl) {
- if (mask_patch_sup[r] == del) {
- mask_patch_sup[r] = idCorr;
- }
-
- r++;
- }
-
- mask_patch_corr[i] = idCorr;
+ old_pid = pid_corr[j + ad->x];
+ new_pid = pid_sup[j + ad->x];
+ pid_corr[j + ad->x] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k + ad->x] == old_pid)
+ pid_corr[k + ad->x] = new_pid;
}
- else {
- mask_patch_corr[i] = idCorr;
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k + ad->x] == old_pid)
+ pid_sup[k + ad->x] = new_pid;
}
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
- else { /*current cell and upper cell are not equal */
- /* 2
- * 1 1
- */
- mask_patch_corr[i] = idCorr;
+ else {
+ pst[new_pid].count++;
}
-
- totCorr++;
}
+ connected = 1;
}
- else { /*cell is null or is not to consider */
- mask_patch_corr[i] = 0;
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j + ad->x] = pid;
- }
- }
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
- {
- int ii;
- long c;
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
- for (ii = 0; ii < ad->cl; ii++) {
- c = mask_patch_corr[ii];
- mask_patch_sup[ii] = c;
- mask_patch_corr[ii] = 0;
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
+ precCell = corrCell;
}
-
-
}
+ if (npatch > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_units;
+ double area_p;
+ double cell_size_m;
+ double mps;
+ double psd;
+ double pcv;
+ double diff;
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
+ cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
+ (((NS_DIST1 + NS_DIST2) / 2) / hd.rows);
+ area_units = cell_size_m * area;
- if (areaPatch != 0) {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
+ /* mean patch size in hectares */
+ mps = area_units / (npatch * 10000);
- else {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
+ /* calculate patch size standard deviation */
+ psd = 0;
+ for (old_pid = 1; old_pid <= pid; old_pid++) {
+ if (pst[old_pid].count > 0) {
+ area_p = cell_size_m * pst[old_pid].count / 10000;
+ diff = area_p - mps;
+ psd += diff * diff;
}
}
- array = G_malloc(npatch * sizeof(avlID_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avlID_to_array(albero, zero, array);
- if (tot != npatch) {
- G_warning
- ("avlID_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
- for (i = 0; i < npatch; i++) {
- if (array[i]->tot == 0) {
- doppi++;
- }
- }
- np = npatch;
- npatch = npatch - doppi;
- mn = areaPatch / npatch;
-
- /* calculate summary */
- for (i = 0; i < np; i++) {
- long areaPi = 0;
- double diff;
-
- if (array[i]->tot != 0) {
- ris = ris + array[i]->tot;
- areaPi = (double)array[i]->tot;
- diff = areaPi - mn;
- somma = somma + (diff * diff);
- }
- }
- sd = sqrt(somma / npatch);
- cv = sd * 100 / mn;
- indice = cv;
- G_free(array);
+ psd = sqrt(psd / npatch);
+ pcv = psd * 100 / mps;
+ *result = pcv;
}
-
else
- indice = (double)(-1);
- if (masked)
+ G_set_d_null_value(result, 1);
+
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
- G_free(mask_patch_sup);
- *result = indice;
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
- /* G_free(buf_sup); */ /* <-- why not free it? */
return RLI_OK;
}
+
int calculateD(int fd, struct area_entry *ad, double *result)
{
- DCELL *buf;
- DCELL *buf_sup;
- DCELL corrCell;
- DCELL precCell;
- DCELL supCell;
- int i, j;
- int mask_fd = -1, *mask_buf;
- int ris = 0;
- int masked = FALSE;
- int areaPatch = 0; /*if all cells are null areaPatch=0 */
- long npatch = 0;
- long tot = 0;
- long zero = 0;
- long totCorr = 0;
- long idCorr = 0;
- long lastId = 0;
- long doppi = 0;
- long np = 0;
- long *mask_patch_sup;
- long *mask_patch_corr;
- double indice = 0;
- double somma = 0;
- double area = 0;
- double mn = 0;
- double sd = 0;
- double cv = 0;
- avlID_tree albero = NULL;
- avlID_table *array = NULL;
- generic_cell gc;
+ DCELL *buf, *buf_sup, *buf_null;
+ DCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- gc.t = DCELL_TYPE;
+ G_get_window(&hd);
+ buf_null = G_allocate_d_raster_buf();
+ G_set_d_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(G_window_cols() * sizeof(long));
+ pid_sup = G_malloc(G_window_cols() * sizeof(long));
+
+ for (j = 0; j < G_window_cols(); j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
@@ -536,384 +389,241 @@
G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
masked = TRUE;
}
- mask_patch_sup = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_sup == NULL) {
- G_fatal_error("malloc mask_patch_sup failed");
- return RLI_ERRORE;
+
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
+
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
}
- mask_patch_corr = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_corr == NULL) {
- G_fatal_error("malloc mask_patch_corr failed");
- return RLI_ERRORE;
- }
- buf_sup = G_allocate_d_raster_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
- return RLI_ERRORE;
- }
- buf = G_allocate_d_raster_buf();
- if (buf == NULL) {
- G_fatal_error("malloc buf failed");
- return RLI_ERRORE;
- }
- G_set_d_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
- for (i = 0; i < ad->cl; i++) {
- mask_patch_sup[i] = 0;
- mask_patch_corr[i] = 0;
- }
- for (j = 0; j < ad->rl; j++)
- /*for each raster row */
- {
- if (j > 0) {
- buf_sup = RLI_get_dcell_raster_row(fd, j - 1 + ad->y, ad);
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_dcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_dcell_raster_row(fd, i - 1 + ad->y, ad);
}
- buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
+
if (masked) {
- if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("mask read failed");
- return RLI_ERRORE;
- }
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
}
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
G_set_d_null_value(&precCell, 1);
- for (i = 0; i < ad->cl; i++) {
- /* for each dcell in the row */
- area++;
- corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j + ad->x] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
G_set_d_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, gc.t))) {
- areaPatch++;
- if (i > 0)
- precCell = buf[i - 1 + ad->x];
- if (j == 0)
- G_set_d_null_value(&supCell, 1);
- else
- supCell = buf_sup[i + ad->x];
- if (corrCell != precCell)
- /* ?
- * 1 2
- * */
- {
- if (corrCell != supCell) {
+ if (G_is_d_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_d_null_value(&supCell, 1);
+ }
- /* 3
- * 1 2
- * */
- /*new patch */
- if (idCorr == 0) { /*first patch */
- lastId = 1;
- idCorr = 1;
- totCorr = 1;
- mask_patch_corr[i] = idCorr;
- }
+ if (!G_is_d_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j + ad->x] = pid_corr[j - 1 + ad->x];
+ connected = 1;
+ pst[pid_corr[j + ad->x]].count++;
+ }
+ else {
+ connected = 0;
+ }
- else
- /*not first patch */
- /* put in the tree the previous value */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
+ if (!G_is_d_null_value(&supCell) && corrCell == supCell) {
- else
- /*tree not empty */
- {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error
- ("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
- totCorr = 1;
- lastId++;
- idCorr = lastId;
- mask_patch_corr[i] = idCorr;
- }
- }
+ if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
- else
- /*current cell and upper cell are equal */
- /* 2
- * 1 2
- * */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
}
- else { /*tree not null */
-
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
-
- idCorr = mask_patch_sup[i];
- mask_patch_corr[i] = idCorr;
- totCorr = 1;
}
- }
- else { /*current cell and previuos cell are equal */
- /* ?
- * 1 1
- */
- if (corrCell == supCell) { /*current cell and upper cell are equal */
- /* 1
- * 1 1
- */
- if (mask_patch_sup[i] != mask_patch_corr[i - 1]) {
- long r = 0;
- long del = mask_patch_sup[i];
-
-
- r = avlID_sub(&albero, del); /*r=number of cell of patch removed */
-
- if (r == 0) {
- G_fatal_error("avlID_sub error");
- return RLI_ERRORE;
- }
-
- /*Remove one patch because it makes part of a patch already found */
- ris = avlID_add(&albero, idCorr, r);
-
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- r = i;
- while (r < ad->cl) {
- if (mask_patch_sup[r] == del) {
- mask_patch_sup[r] = idCorr;
- }
-
- r++;
- }
-
- mask_patch_corr[i] = idCorr;
+ old_pid = pid_corr[j + ad->x];
+ new_pid = pid_sup[j + ad->x];
+ pid_corr[j + ad->x] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k + ad->x] == old_pid)
+ pid_corr[k + ad->x] = new_pid;
}
- else {
- mask_patch_corr[i] = idCorr;
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k + ad->x] == old_pid)
+ pid_sup[k + ad->x] = new_pid;
}
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
- else { /*current cell and upper cell are not equal */
- /* 2
- * 1 1
- */
- mask_patch_corr[i] = idCorr;
+ else {
+ pst[new_pid].count++;
}
-
- totCorr++;
}
+ connected = 1;
}
- else { /*cell is null or is not to consider */
- mask_patch_corr[i] = 0;
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j + ad->x] = pid;
- }
- }
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
- {
- int ii;
- long c;
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
- for (ii = 0; ii < ad->cl; ii++) {
- c = mask_patch_corr[ii];
- mask_patch_sup[ii] = c;
- mask_patch_corr[ii] = 0;
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
+ precCell = corrCell;
}
-
-
}
+ if (npatch > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_units;
+ double area_p;
+ double cell_size_m;
+ double mps;
+ double psd;
+ double pcv;
+ double diff;
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
- if (areaPatch != 0) {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
+ cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
+ (((NS_DIST1 + NS_DIST2) / 2) / hd.rows);
+ area_units = cell_size_m * area;
- else {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
- array = G_malloc(npatch * sizeof(avlID_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avlID_to_array(albero, zero, array);
- if (tot != npatch) {
- G_warning
- ("avlID_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
- for (i = 0; i < npatch; i++) {
- if (array[i]->tot == 0) {
- doppi++;
- }
- }
- np = npatch;
- npatch = npatch - doppi;
- mn = areaPatch / npatch;
+ /* mean patch size in hectares */
+ mps = area_units / (npatch * 10000);
- /* calculate summary */
- for (i = 0; i < np; i++) {
- long areaPi = 0;
- double diff;
-
- if (array[i]->tot != 0) {
- ris = ris + array[i]->tot;
- areaPi = (double)array[i]->tot;
- diff = areaPi - mn;
- somma = somma + (diff * diff);
+ /* calculate patch size standard deviation */
+ psd = 0;
+ for (old_pid = 1; old_pid <= pid; old_pid++) {
+ if (pst[old_pid].count > 0) {
+ area_p = cell_size_m * pst[old_pid].count / 10000;
+ diff = area_p - mps;
+ psd += diff * diff;
}
}
- sd = sqrt(somma / npatch);
- cv = sd * 100 / mn;
- indice = cv;
- G_free(array);
+ psd = sqrt(psd / npatch);
+ pcv = psd * 100 / mps;
+ *result = pcv;
}
-
else
- indice = (double)(-1);
- if (masked)
+ G_set_d_null_value(result, 1);
+
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
- G_free(mask_patch_sup);
- *result = indice;
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
+
return RLI_OK;
}
+
int calculateF(int fd, struct area_entry *ad, double *result)
{
- FCELL *buf;
- FCELL *buf_sup;
- FCELL corrCell;
- FCELL precCell;
- FCELL supCell;
- int i, j;
- int mask_fd = -1, *mask_buf;
- int ris = 0;
- int masked = FALSE;
- int areaPatch = 0; /*if all cells are null areaPatch=0 */
- long npatch = 0;
- long np = 0;
- long tot = 0;
- long zero = 0;
- long totCorr = 0;
- long idCorr = 0;
- long lastId = 0;
- long doppi = 0;
- long *mask_patch_sup;
- long *mask_patch_corr;
- double indice = 0;
- double somma = 0;
- double area = 0;
- double mn = 0;
- double sd = 0;
- double cv = 0;
- avlID_tree albero = NULL;
- avlID_table *array = NULL;
- generic_cell gc;
+ FCELL *buf, *buf_sup, *buf_null;
+ FCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- gc.t = FCELL_TYPE;
+ G_get_window(&hd);
+ buf_null = G_allocate_f_raster_buf();
+ G_set_f_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(G_window_cols() * sizeof(long));
+ pid_sup = G_malloc(G_window_cols() * sizeof(long));
+
+ for (j = 0; j < G_window_cols(); j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
@@ -922,350 +632,204 @@
G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
masked = TRUE;
}
- mask_patch_sup = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_sup == NULL) {
- G_fatal_error("malloc mask_patch_sup failed");
- return RLI_ERRORE;
+
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
+
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
}
- mask_patch_corr = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_corr == NULL) {
- G_fatal_error("malloc mask_patch_corr failed");
- return RLI_ERRORE;
- }
- buf_sup = G_allocate_f_raster_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
- return RLI_ERRORE;
- }
- buf = G_allocate_f_raster_buf();
- if (buf == NULL) {
- G_fatal_error("malloc buf failed");
- return RLI_ERRORE;
- }
- G_set_f_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
- for (i = 0; i < ad->cl; i++) {
- mask_patch_sup[i] = 0;
- mask_patch_corr[i] = 0;
- }
- for (j = 0; j < ad->rl; j++)
- /*for each raster row */
- {
- if (j > 0) {
- buf_sup = RLI_get_fcell_raster_row(fd, j - 1 + ad->y, ad);
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_fcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_fcell_raster_row(fd, i - 1 + ad->y, ad);
}
- buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
+
if (masked) {
- if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("mask read failed");
- return RLI_ERRORE;
- }
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
}
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
G_set_f_null_value(&precCell, 1);
- for (i = 0; i < ad->cl; i++) {
- /* for each fcell in the row */
- area++;
- corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j + ad->x] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
G_set_f_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, gc.t))) {
- areaPatch++;
- if (i > 0)
- precCell = buf[i - 1 + ad->x];
- if (j == 0)
- G_set_f_null_value(&supCell, 1);
- else
- supCell = buf_sup[i + ad->x];
+ if (G_is_f_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_f_null_value(&supCell, 1);
+ }
- if (corrCell != precCell)
- /* ?
- * 1 2
- * */
- {
- if (corrCell != supCell)
- /* 3
- * 1 2
- * */
- {
+ if (!G_is_f_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j + ad->x] = pid_corr[j - 1 + ad->x];
+ connected = 1;
+ pst[pid_corr[j + ad->x]].count++;
+ }
+ else {
+ connected = 0;
+ }
- /*new patch */
- if (idCorr == 0) { /*first patch */
- lastId = 1;
- idCorr = 1;
- totCorr = 1;
- mask_patch_corr[i] = idCorr;
- }
+ if (!G_is_f_null_value(&supCell) && corrCell == supCell) {
- else
- /*not first patch */
- /* put in the tree the previous value */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
+ if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
- else
- /*tree not empty */
- {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error
- ("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
- totCorr = 1;
- lastId++;
- idCorr = lastId;
- mask_patch_corr[i] = idCorr;
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
}
}
- else
- /*current cell and upper cell are equal */
- /* 2
- * 1 2
- * */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ old_pid = pid_corr[j + ad->x];
+ new_pid = pid_sup[j + ad->x];
+ pid_corr[j + ad->x] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k + ad->x] == old_pid)
+ pid_corr[k + ad->x] = new_pid;
}
- else { /*tree not null */
-
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k + ad->x] == old_pid)
+ pid_sup[k + ad->x] = new_pid;
}
-
- idCorr = mask_patch_sup[i];
- mask_patch_corr[i] = idCorr;
- totCorr = 1;
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
- }
- else { /*current cell and previuos cell are equal */
- /* ?
- * 1 1
- */
-
- if (corrCell == supCell) { /*current cell and upper cell are equal */
- /* 1
- * 1 1
- */
- if (mask_patch_sup[i] != mask_patch_corr[i - 1]) {
- long r = 0;
- long del = mask_patch_sup[i];
-
-
- r = avlID_sub(&albero, del); /*r=number of cell of patch removed */
-
- if (r == 0) {
- G_fatal_error("avlID_sub error");
- return RLI_ERRORE;
- }
-
- /*Remove one patch because it makes part of a patch already found */
- ris = avlID_add(&albero, idCorr, r);
-
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- r = i;
- while (r < ad->cl) {
- if (mask_patch_sup[r] == del) {
- mask_patch_sup[r] = idCorr;
- }
-
- r++;
- }
-
- mask_patch_corr[i] = idCorr;
- }
- else {
- mask_patch_corr[i] = idCorr;
- }
+ else {
+ pst[new_pid].count++;
}
- else { /*current cell and upper cell are not equal */
- /* 2
- * 1 1
- */
- mask_patch_corr[i] = idCorr;
- }
-
- totCorr++;
}
+ connected = 1;
}
- else { /*cell is null or is not to consider */
- mask_patch_corr[i] = 0;
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j + ad->x] = pid;
- }
- }
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
- {
- int ii;
- long c;
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
- for (ii = 0; ii < ad->cl; ii++) {
- c = mask_patch_corr[ii];
- mask_patch_sup[ii] = c;
- mask_patch_corr[ii] = 0;
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
+ precCell = corrCell;
}
-
-
}
+ if (npatch > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_units;
+ double area_p;
+ double cell_size_m;
+ double mps;
+ double psd;
+ double pcv;
+ double diff;
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
+ cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
+ (((NS_DIST1 + NS_DIST2) / 2) / hd.rows);
+ area_units = cell_size_m * area;
- if (areaPatch != 0) {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
+ /* mean patch size in hectares */
+ mps = area_units / (npatch * 10000);
- else {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
+ /* calculate patch size standard deviation */
+ psd = 0;
+ for (old_pid = 1; old_pid <= pid; old_pid++) {
+ if (pst[old_pid].count > 0) {
+ area_p = cell_size_m * pst[old_pid].count / 10000;
+ diff = area_p - mps;
+ psd += diff * diff;
}
}
- array = G_malloc(npatch * sizeof(avlID_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avlID_to_array(albero, zero, array);
- if (tot != npatch) {
- G_warning
- ("avlID_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
- for (i = 0; i < npatch; i++) {
- if (array[i]->tot == 0) {
- doppi++;
- }
- }
- np = npatch;
- npatch = npatch - doppi;
- mn = areaPatch / npatch;
-
- /* calculate summary */
- for (i = 0; i < np; i++) {
- long areaPi = 0;
- double diff;
-
- if (array[i]->tot != 0) {
- ris = ris + array[i]->tot;
- areaPi = (double)array[i]->tot;
- diff = areaPi - mn;
- somma = somma + (diff * diff);
- }
- }
- sd = sqrt(somma / npatch);
- cv = sd * 100 / mn;
- indice = cv;
- G_free(array);
+ psd = sqrt(psd / npatch);
+ pcv = psd * 100 / mps;
+ *result = pcv;
}
-
else
- indice = (double)(-1);
- if (masked)
- G_free(mask_buf);
-/* TODO: fix if? */
- G_free(mask_patch_sup);
+ G_set_d_null_value(result, 1);
- *result = indice;
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
+
return RLI_OK;
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.padrange/padrange.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.padrange/padrange.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.padrange/padrange.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -5,6 +5,8 @@
* student of Computer Science University of Pisa (Italy)
* Commission from Faunalia Pontedera (PI) www.faunalia.it
* Fixes: Markus Neteler <neteler itc.it>
+ * Rewrite: Markus Metz
+ * Patch identification: Michael Shapiro - CERL
*
* PURPOSE: calculates calculates standard deviation of patch areas
* COPYRIGHT: (C) 2007-2014 by the GRASS Development Team
@@ -22,12 +24,18 @@
#include <grass/gis.h>
#include <grass/glocale.h>
-#include "../r.li.daemon/defs.h"
-#include "../r.li.daemon/avlDefs.h"
-#include "../r.li.daemon/avlID.h"
-#include "../r.li.daemon/GenericCell.h"
#include "../r.li.daemon/daemon.h"
+#include "../r.li.daemon/GenericCell.h"
+/* template is patchnum */
+
+/* cell count and type of each patch */
+struct pst {
+ long count;
+ generic_cell type;
+};
+
+rli_func patchAreaDistributionRANGE;
int calculate(int fd, struct area_entry *ad, double *result);
int calculateD(int fd, struct area_entry *ad, double *result);
int calculateF(int fd, struct area_entry *ad, double *result);
@@ -62,14 +70,9 @@
int patchAreaDistributionRANGE(int fd, char **par, struct area_entry *ad,
double *result)
{
- char *mapset;
double indice = 0;
- struct Cell_head hd;
int ris = RLI_OK;
- mapset = G_find_cell(ad->raster, "");
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
- return RLI_ERRORE;
switch (ad->data_type) {
case CELL_TYPE:
{
@@ -105,38 +108,36 @@
int calculate(int fd, struct area_entry *ad, double *result)
{
+ CELL *buf, *buf_sup, *buf_null;
+ CELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- CELL *buf;
- CELL *buf_sup;
+ G_get_window(&hd);
- CELL corrCell;
- CELL precCell;
- CELL supCell;
+ buf_null = G_allocate_cell_buf();
+ G_set_c_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
- int i, j;
- int mask_fd = -1, *mask_buf;
- int ris = 0;
- int masked = FALSE;
- int areaPatch = 0; /*if all cells are null areaPatch=0 */
- int area_max = 0, area_min = 0;
+ /* initialize patch ids */
+ pid_corr = G_malloc(G_window_cols() * sizeof(long));
+ pid_sup = G_malloc(G_window_cols() * sizeof(long));
- long npatch = 0;
- long tot = 0;
- long zero = 0;
- long totCorr = 0;
- long idCorr = 0;
- long lastId = 0;
- long *mask_patch_sup;
- long *mask_patch_corr;
+ for (j = 0; j < G_window_cols(); j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
- double indice = 0;
- double rk = 0;
- avlID_tree albero = NULL;
- avlID_table *array = NULL;
- generic_cell gc;
- gc.t = CELL_TYPE;
-
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
@@ -145,397 +146,234 @@
G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
masked = TRUE;
}
- mask_patch_sup = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_sup == NULL) {
- G_fatal_error("malloc mask_patch_sup failed");
- return RLI_ERRORE;
- }
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
- mask_patch_corr = G_malloc(ad->cl * sizeof(long));
-
- if (mask_patch_corr == NULL) {
- G_fatal_error("malloc mask_patch_corr failed");
- return RLI_ERRORE;
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
}
- buf_sup = G_allocate_cell_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
- return RLI_ERRORE;
- }
-
- buf = G_allocate_cell_buf();
- if (buf == NULL) {
- G_fatal_error("malloc buf failed");
- return RLI_ERRORE;
- }
-
- G_set_c_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
-
- for (i = 0; i < ad->cl; i++) {
- mask_patch_sup[i] = 0;
- mask_patch_corr[i] = 0;
- }
-
- for (j = 0; j < ad->rl; j++)
- /*for each raster row */
- {
- if (j > 0) {
- buf_sup = RLI_get_cell_raster_row(fd, j - 1 + ad->y, ad);
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_cell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad);
}
- buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
-
if (masked) {
- if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("mask read failed");
- return RLI_ERRORE;
- }
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
}
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
G_set_c_null_value(&precCell, 1);
- for (i = 0; i < ad->cl; i++)
- /* for each cell in the row */
- {
- corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j + ad->x] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
G_set_c_null_value(&corrCell, 1);
}
- if (!(G_is_null_value(&corrCell, gc.t))) {
- areaPatch++;
- if (i > 0)
- precCell = buf[i - 1 + ad->x];
+ if (G_is_c_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_c_null_value(&supCell, 1);
+ }
- if (j == 0)
- G_set_c_null_value(&supCell, 1);
- else
- supCell = buf_sup[i + ad->x];
+ if (!G_is_c_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j + ad->x] = pid_corr[j - 1 + ad->x];
+ connected = 1;
+ pst[pid_corr[j + ad->x]].count++;
+ }
+ else {
+ connected = 0;
+ }
- if (corrCell != precCell)
- /* ?
- * 1 2
- * */
- {
- if (corrCell != supCell) {
+ if (!G_is_c_null_value(&supCell) && corrCell == supCell) {
- /* 3
- * 1 2
- * */
- /*new patch */
- if (idCorr == 0)
- /*first found patch */
- {
- lastId = 1;
- idCorr = 1;
- totCorr = 1;
- mask_patch_corr[i] = idCorr;
- }
+ if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
- else
- /*not first patch */
- /* put in the tree the previous value */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
-
- else
- /*tree not empty */
- {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error
- ("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
- totCorr = 1;
- lastId++;
- idCorr = lastId;
- mask_patch_corr[i] = idCorr;
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
}
}
- else
- /* current cell and upper cell are equal */
- /* 2
- * 1 2
- * */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ old_pid = pid_corr[j + ad->x];
+ new_pid = pid_sup[j + ad->x];
+ pid_corr[j + ad->x] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k + ad->x] == old_pid)
+ pid_corr[k + ad->x] = new_pid;
}
- else { /*tree not null */
-
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k + ad->x] == old_pid)
+ pid_sup[k + ad->x] = new_pid;
}
-
- idCorr = mask_patch_sup[i];
- mask_patch_corr[i] = idCorr;
- totCorr = 1;
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
- }
- else { /*current cell and previuos cell are equal */
- /* ?
- * 1 1
- */
-
- if (corrCell == supCell) { /*current cell and upper cell are equal */
- /* 1
- * 1 1
- */
- if (mask_patch_sup[i] != mask_patch_corr[i - 1]) {
- long r = 0;
- long del = mask_patch_sup[i];
-
-
- r = avlID_sub(&albero, del); /*r=number of cell of patch removed */
-
- if (r == 0) {
- G_fatal_error("avlID_sub error");
- return RLI_ERRORE;
- }
-
- /*Remove one patch because it makes part of a patch already found */
- ris = avlID_add(&albero, idCorr, r);
-
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- r = i;
- while (r < ad->cl) {
- if (mask_patch_sup[r] == del) {
- mask_patch_sup[r] = idCorr;
- }
-
- r++;
- }
-
- mask_patch_corr[i] = idCorr;
- }
- else {
- mask_patch_corr[i] = idCorr;
- }
+ else {
+ pst[new_pid].count++;
}
- else { /*current cell and upper cell are not equal */
- /* 2
- * 1 1
- */
- mask_patch_corr[i] = idCorr;
- }
-
- totCorr++;
}
+ connected = 1;
}
- else { /*cell is null or is not to consider */
- mask_patch_corr[i] = 0;
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j + ad->x] = pid;
- }
- }
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
- {
- int ii;
- long c;
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
- for (ii = 0; ii < ad->cl; ii++) {
- c = mask_patch_corr[ii];
- mask_patch_sup[ii] = c;
- mask_patch_corr[ii] = 0;
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
+ precCell = corrCell;
}
-
-
}
+ if (npatch > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_p;
+ double cell_size_m;
+ double min, max;
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
- if (areaPatch != 0) {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
- else {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
+ cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
+ (((NS_DIST1 + NS_DIST2) / 2) / hd.rows);
-
- array = G_malloc(npatch * sizeof(avlID_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avlID_to_array(albero, zero, array);
-
- if (tot != npatch) {
- G_warning
- ("avlID_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
-
-
- for (i = 0; i < npatch; i++) {
-
- if (array[i]->tot != 0) {
-
- if (array[i]->tot > area_max) {
- area_max = array[i]->tot;
- }
- if (array[i]->tot < area_min || area_min == 0) {
- area_min = array[i]->tot;
- }
+ /* get min and max patch size */
+ min = 1.0 / 0.0; /* inf */
+ max = -1.0 / 0.0; /* -inf */
+ for (old_pid = 1; old_pid <= pid; old_pid++) {
+ if (pst[old_pid].count > 0) {
+ area_p = cell_size_m * pst[old_pid].count / 10000;
+ if (min > area_p)
+ min = area_p;
+ if (max < area_p)
+ max = area_p;
}
}
-
- rk = area_max - area_min;
-
- indice = rk;
-
- G_free(array);
+ *result = max - min;
}
else
- indice = (double)(-1);
+ G_set_d_null_value(result, 1);
-
- if (masked)
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
- G_free(mask_patch_sup);
-
- *result = indice;
-
- G_free(buf_sup);
return RLI_OK;
}
-
int calculateD(int fd, struct area_entry *ad, double *result)
{
- DCELL *buf;
- DCELL *buf_sup;
- DCELL corrCell;
- DCELL precCell;
- DCELL supCell;
- int i, j;
- int mask_fd = -1, *mask_buf;
- int ris = 0;
- int masked = FALSE;
- int areaPatch = 0; /*if all cells are null areaPatch=0 */
- int area_max = 0, area_min = 0;
- long npatch = 0;
- long tot = 0;
- long zero = 0;
- long totCorr = 0;
- long idCorr = 0;
- long lastId = 0;
- long *mask_patch_sup;
- long *mask_patch_corr;
- double indice = 0;
- double rk = 0;
- avlID_tree albero = NULL;
- avlID_table *array = NULL;
- generic_cell gc;
+ DCELL *buf, *buf_sup, *buf_null;
+ DCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- gc.t = DCELL_TYPE;
+ G_get_window(&hd);
+ buf_null = G_allocate_d_raster_buf();
+ G_set_d_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(G_window_cols() * sizeof(long));
+ pid_sup = G_malloc(G_window_cols() * sizeof(long));
+
+ for (j = 0; j < G_window_cols(); j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
@@ -544,381 +382,234 @@
G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
masked = TRUE;
}
- mask_patch_sup = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_sup == NULL) {
- G_fatal_error("malloc mask_patch_sup failed");
- return RLI_ERRORE;
+
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
+
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
}
- mask_patch_corr = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_corr == NULL) {
- G_fatal_error("malloc mask_patch_corr failed");
- return RLI_ERRORE;
- }
- buf_sup = G_allocate_d_raster_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
- return RLI_ERRORE;
- }
- buf = G_allocate_d_raster_buf();
- if (buf == NULL) {
- G_fatal_error("malloc buf failed");
- return RLI_ERRORE;
- }
- G_set_d_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
- for (i = 0; i < ad->cl; i++) {
- mask_patch_sup[i] = 0;
- mask_patch_corr[i] = 0;
- }
- for (j = 0; j < ad->rl; j++)
- /*for each raster row */
- {
- if (j > 0) {
- buf_sup = RLI_get_dcell_raster_row(fd, j - 1 + ad->y, ad);
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_dcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_dcell_raster_row(fd, i - 1 + ad->y, ad);
}
- buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
+
if (masked) {
- if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("mask read failed");
- return RLI_ERRORE;
- }
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
}
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
G_set_d_null_value(&precCell, 1);
- for (i = 0; i < ad->cl; i++) {
- /* for each dcell in the row */
- corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j + ad->x] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
G_set_d_null_value(&corrCell, 1);
}
- if (!(G_is_null_value(&corrCell, gc.t))) {
- areaPatch++;
- if (i > 0)
- precCell = buf[i - 1 + ad->x];
+ if (G_is_d_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_d_null_value(&supCell, 1);
+ }
- if (j == 0)
- G_set_d_null_value(&supCell, 1);
- else
- supCell = buf_sup[i + ad->x];
+ if (!G_is_d_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j + ad->x] = pid_corr[j - 1 + ad->x];
+ connected = 1;
+ pst[pid_corr[j + ad->x]].count++;
+ }
+ else {
+ connected = 0;
+ }
- if (corrCell != precCell)
- /* ?
- * 1 2
- * */
- {
- if (corrCell != supCell) {
+ if (!G_is_d_null_value(&supCell) && corrCell == supCell) {
- /* 3
- * 1 2
- * */
- /*new patch */
- if (idCorr == 0) { /*first found patch */
- lastId = 1;
- idCorr = 1;
- totCorr = 1;
- mask_patch_corr[i] = idCorr;
- }
+ if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
- else
- /*not first patch */
- /* put in the tree the previous value */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
-
- else
- /*tree not empty */
- {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error
- ("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
- totCorr = 1;
- lastId++;
- idCorr = lastId;
- mask_patch_corr[i] = idCorr;
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
}
}
- else
- /* current cell and upper cell are equal */
- /* 2
- * 1 2
- * */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ old_pid = pid_corr[j + ad->x];
+ new_pid = pid_sup[j + ad->x];
+ pid_corr[j + ad->x] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k + ad->x] == old_pid)
+ pid_corr[k + ad->x] = new_pid;
}
- else { /*tree not null */
-
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k + ad->x] == old_pid)
+ pid_sup[k + ad->x] = new_pid;
}
-
- idCorr = mask_patch_sup[i];
- mask_patch_corr[i] = idCorr;
- totCorr = 1;
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
- }
- else { /*current cell and previuos cell are equal */
- /* ?
- * 1 1
- */
-
- if (corrCell == supCell) { /*current cell and upper cell are equal */
- /* 1
- * 1 1
- */
- if (mask_patch_sup[i] != mask_patch_corr[i - 1]) {
- long r = 0;
- long del = mask_patch_sup[i];
-
-
- r = avlID_sub(&albero, del); /*r=number of cell of patch removed */
-
- if (r == 0) {
- G_fatal_error("avlID_sub error");
- return RLI_ERRORE;
- }
-
- /*Remove one patch because it makes part of a patch already found */
- ris = avlID_add(&albero, idCorr, r);
-
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- r = i;
- while (r < ad->cl) {
- if (mask_patch_sup[r] == del) {
- mask_patch_sup[r] = idCorr;
- }
-
- r++;
- }
-
- mask_patch_corr[i] = idCorr;
- }
- else {
- mask_patch_corr[i] = idCorr;
- }
+ else {
+ pst[new_pid].count++;
}
- else { /*current cell and upper cell are not equal */
- /* 2
- * 1 1
- */
- mask_patch_corr[i] = idCorr;
- }
-
- totCorr++;
}
+ connected = 1;
}
- else { /*cell is null or is not to consider */
- mask_patch_corr[i] = 0;
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j + ad->x] = pid;
- }
- }
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
- {
- int ii;
- long c;
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
- for (ii = 0; ii < ad->cl; ii++) {
- c = mask_patch_corr[ii];
- mask_patch_sup[ii] = c;
- mask_patch_corr[ii] = 0;
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
+ precCell = corrCell;
}
-
-
}
+ if (npatch > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_p;
+ double cell_size_m;
+ double min, max;
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
- if (areaPatch != 0) {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
- else {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
+ cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
+ (((NS_DIST1 + NS_DIST2) / 2) / hd.rows);
-
- array = G_malloc(npatch * sizeof(avlID_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avlID_to_array(albero, zero, array);
-
- if (tot != npatch) {
- G_warning
- ("avlID_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
-
-
- for (i = 0; i < npatch; i++) {
-
- if (array[i]->tot != 0) {
-
- if (array[i]->tot > area_max) {
- area_max = array[i]->tot;
- }
- if (array[i]->tot < area_min || area_min == 0) {
- area_min = array[i]->tot;
- }
+ /* get min and max patch size */
+ min = 1.0 / 0.0; /* inf */
+ max = -1.0 / 0.0; /* -inf */
+ for (old_pid = 1; old_pid <= pid; old_pid++) {
+ if (pst[old_pid].count > 0) {
+ area_p = cell_size_m * pst[old_pid].count / 10000;
+ if (min > area_p)
+ min = area_p;
+ if (max < area_p)
+ max = area_p;
}
}
-
-
-
- rk = area_max - area_min;
-
- indice = rk;
-
- G_free(array);
+ *result = max - min;
}
else
- indice = (double)(-1);
+ G_set_d_null_value(result, 1);
-
- if (masked)
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
- G_free(mask_patch_sup);
- *result = indice;
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
+
return RLI_OK;
}
-
int calculateF(int fd, struct area_entry *ad, double *result)
{
- FCELL *buf;
- FCELL *buf_sup;
- FCELL corrCell;
- FCELL precCell;
- FCELL supCell;
- int i, j;
- int mask_fd = -1, *mask_buf;
- int ris = 0;
- int masked = FALSE;
- int areaPatch = 0; /*if all cells are null areaPatch=0 */
- int area_max = 0, area_min = 0;
- long npatch = 0;
- long tot = 0;
- long zero = 0;
- long totCorr = 0;
- long idCorr = 0;
- long lastId = 0;
- long *mask_patch_sup;
- long *mask_patch_corr;
- double indice = 0;
- double rk = 0;
- avlID_tree albero = NULL;
- avlID_table *array = NULL;
- generic_cell gc;
+ FCELL *buf, *buf_sup, *buf_null;
+ FCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- gc.t = FCELL_TYPE;
+ G_get_window(&hd);
+ buf_null = G_allocate_f_raster_buf();
+ G_set_f_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(G_window_cols() * sizeof(long));
+ pid_sup = G_malloc(G_window_cols() * sizeof(long));
+
+ for (j = 0; j < G_window_cols(); j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
@@ -927,349 +618,197 @@
G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
masked = TRUE;
}
- mask_patch_sup = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_sup == NULL) {
- G_fatal_error("malloc mask_patch_sup failed");
- return RLI_ERRORE;
- }
- mask_patch_corr = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_corr == NULL) {
- G_fatal_error("malloc mask_patch_corr failed");
- return RLI_ERRORE;
- }
- buf_sup = G_allocate_f_raster_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
- return RLI_ERRORE;
- }
- buf = G_allocate_f_raster_buf();
- if (buf == NULL) {
- G_fatal_error("malloc buf failed");
- return RLI_ERRORE;
- }
- G_set_f_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
- for (i = 0; i < ad->cl; i++) {
- mask_patch_sup[i] = 0;
- mask_patch_corr[i] = 0;
- }
- for (j = 0; j < ad->rl; j++)
- /*for each raster row */
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
- {
- if (j > 0) {
- buf_sup = RLI_get_fcell_raster_row(fd, j - 1 + ad->y, ad);
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
+ }
+
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_fcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_fcell_raster_row(fd, i - 1 + ad->y, ad);
}
- buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
+
if (masked) {
- if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("mask read failed");
- return RLI_ERRORE;
- }
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
}
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
G_set_f_null_value(&precCell, 1);
- for (i = 0; i < ad->cl; i++) {
- /* for each fcell in the row */
- corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j + ad->x] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
G_set_f_null_value(&corrCell, 1);
}
- if (!(G_is_null_value(&corrCell, gc.t))) {
- areaPatch++;
- if (i > 0)
- precCell = buf[i - 1 + ad->x];
+ if (G_is_f_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_f_null_value(&supCell, 1);
+ }
- if (j == 0)
- G_set_f_null_value(&supCell, 1);
- else
- supCell = buf_sup[i + ad->x];
+ if (!G_is_f_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j + ad->x] = pid_corr[j - 1 + ad->x];
+ connected = 1;
+ pst[pid_corr[j + ad->x]].count++;
+ }
+ else {
+ connected = 0;
+ }
- if (corrCell != precCell)
- /* ?
- * 1 2
- * */
- {
- if (corrCell != supCell) {
+ if (!G_is_f_null_value(&supCell) && corrCell == supCell) {
- /* 3
- * 1 2
- * */
- /*new patch */
- if (idCorr == 0) { /*first found patch */
- lastId = 1;
- idCorr = 1;
- totCorr = 1;
- mask_patch_corr[i] = idCorr;
- }
+ if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
- else
- /*not first patch */
- /* put in the tree the previous value */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
-
- else
- /*tree not empty */
- {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error
- ("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
- totCorr = 1;
- lastId++;
- idCorr = lastId;
- mask_patch_corr[i] = idCorr;
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
}
}
- else
- /* current cell and upper cell are equal */
- /* 2
- * 1 2
- * */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ old_pid = pid_corr[j + ad->x];
+ new_pid = pid_sup[j + ad->x];
+ pid_corr[j + ad->x] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k + ad->x] == old_pid)
+ pid_corr[k + ad->x] = new_pid;
}
- else { /*tree not null */
-
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k + ad->x] == old_pid)
+ pid_sup[k + ad->x] = new_pid;
}
-
- idCorr = mask_patch_sup[i];
- mask_patch_corr[i] = idCorr;
- totCorr = 1;
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
- }
- else { /*current cell and previuos cell are equal */
- /* ?
- * 1 1
- */
-
- if (corrCell == supCell) { /*current cell and upper cell are equal */
- /* 1
- * 1 1
- */
- if (mask_patch_sup[i] != mask_patch_corr[i - 1]) {
- long r = 0;
- long del = mask_patch_sup[i];
-
-
- r = avlID_sub(&albero, del); /*r=number of cell of patch removed */
-
- if (r == 0) {
- G_fatal_error("avlID_sub error");
- return RLI_ERRORE;
- }
-
- /*Remove one patch because it makes part of a patch already found */
- ris = avlID_add(&albero, idCorr, r);
-
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- r = i;
- while (r < ad->cl) {
- if (mask_patch_sup[r] == del) {
- mask_patch_sup[r] = idCorr;
- }
-
- r++;
- }
-
- mask_patch_corr[i] = idCorr;
- }
- else {
- mask_patch_corr[i] = idCorr;
- }
+ else {
+ pst[new_pid].count++;
}
- else { /*current cell and upper cell are not equal */
- /* 2
- * 1 1
- */
- mask_patch_corr[i] = idCorr;
- }
-
- totCorr++;
}
+ connected = 1;
}
- else { /*cell is null or is not to consider */
- mask_patch_corr[i] = 0;
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j + ad->x] = pid;
- }
- }
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
- {
- int ii;
- long c;
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
- for (ii = 0; ii < ad->cl; ii++) {
- c = mask_patch_corr[ii];
- mask_patch_sup[ii] = c;
- mask_patch_corr[ii] = 0;
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
+ precCell = corrCell;
}
-
-
}
+ if (npatch > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_p;
+ double cell_size_m;
+ double min, max;
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
- if (areaPatch != 0) {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
- else {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
+ cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
+ (((NS_DIST1 + NS_DIST2) / 2) / hd.rows);
-
- array = G_malloc(npatch * sizeof(avlID_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avlID_to_array(albero, zero, array);
-
- if (tot != npatch) {
- G_warning
- ("avlID_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
-
-
- for (i = 0; i < npatch; i++) {
-
- if (array[i]->tot != 0) {
-
- if (array[i]->tot > area_max) {
- area_max = array[i]->tot;
- }
- if (array[i]->tot < area_min || area_min == 0) {
- area_min = array[i]->tot;
- }
+ /* get min and max patch size */
+ min = 1.0 / 0.0; /* inf */
+ max = -1.0 / 0.0; /* -inf */
+ for (old_pid = 1; old_pid <= pid; old_pid++) {
+ if (pst[old_pid].count > 0) {
+ area_p = cell_size_m * pst[old_pid].count / 10000;
+ if (min > area_p)
+ min = area_p;
+ if (max < area_p)
+ max = area_p;
}
}
-
-
-
- rk = area_max - area_min;
-
- indice = rk;
-
- G_free(array);
+ *result = max - min;
}
else
- indice = (double)(-1);
+ G_set_d_null_value(result, 1);
-
- if (masked)
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
- G_free(mask_patch_sup);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
- *result = indice;
-
return RLI_OK;
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.padsd/padsd.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.padsd/padsd.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.padsd/padsd.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -5,6 +5,8 @@
* student of Computer Science University of Pisa (Italy)
* Commission from Faunalia Pontedera (PI) www.faunalia.it
* Fixes: Markus Neteler <neteler itc.it>
+ * Rewrite: Markus Metz
+ * Patch identification: Michael Shapiro - CERL
*
* PURPOSE: calculates calculates standard deviation of patch areas
* COPYRIGHT: (C) 2007-2014 by the GRASS Development Team
@@ -22,11 +24,18 @@
#include <grass/gis.h>
#include <grass/glocale.h>
-#include "../r.li.daemon/defs.h"
-#include "../r.li.daemon/avlDefs.h"
-#include "../r.li.daemon/avlID.h"
-#include "../r.li.daemon/GenericCell.h"
#include "../r.li.daemon/daemon.h"
+#include "../r.li.daemon/GenericCell.h"
+
+/* template is patchnum */
+
+/* cell count and type of each patch */
+struct pst {
+ long count;
+ generic_cell type;
+};
+
+rli_func patchAreaDistributionSD;
int calculate(int fd, struct area_entry *ad, double *result);
int calculateD(int fd, struct area_entry *ad, double *result);
int calculateF(int fd, struct area_entry *ad, double *result);
@@ -60,14 +69,9 @@
int patchAreaDistributionSD(int fd, char **par, struct area_entry *ad, double *result)
{
- char *mapset;
double indice = 0;
- struct Cell_head hd;
int ris = RLI_OK;
- mapset = G_find_cell(ad->raster, "");
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
- return RLI_ERRORE;
switch (ad->data_type) {
case CELL_TYPE:
{
@@ -103,38 +107,36 @@
int calculate(int fd, struct area_entry *ad, double *result)
{
- CELL *buf;
- CELL *buf_sup;
- CELL corrCell;
- CELL precCell;
- CELL supCell;
- int i, j;
- int mask_fd = -1, *mask_buf;
- int ris = 0;
- int masked = FALSE;
- int areaPatch = 0; /*if all cells are null areaPatch=0 */
- long npatch = 0;
- long np = 0;
- long tot = 0;
- long zero = 0;
- long totCorr = 0;
- long idCorr = 0;
- long lastId = 0;
- long doppi = 0;
- long *mask_patch_sup;
- long *mask_patch_corr;
- double indice = 0;
- double somma = 0;
- double area = 0;
- double mn = 0;
- double sd = 0;
- avlID_tree albero = NULL;
- avlID_table *array = NULL;
- generic_cell gc;
+ CELL *buf, *buf_sup, *buf_null;
+ CELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- gc.t = CELL_TYPE;
+ G_get_window(&hd);
+ buf_null = G_allocate_cell_buf();
+ G_set_c_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(G_window_cols() * sizeof(long));
+ pid_sup = G_malloc(G_window_cols() * sizeof(long));
+
+ for (j = 0; j < G_window_cols(); j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
@@ -143,397 +145,239 @@
G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
masked = TRUE;
}
- mask_patch_sup = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_sup == NULL) {
- G_fatal_error("malloc mask_patch_sup failed");
- return RLI_ERRORE;
+
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
+
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
}
- mask_patch_corr = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_corr == NULL) {
- G_fatal_error("malloc mask_patch_corr failed");
- return RLI_ERRORE;
- }
- buf_sup = G_allocate_cell_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
- return RLI_ERRORE;
- }
- buf = G_allocate_cell_buf();
- if (buf == NULL) {
- G_fatal_error("malloc buf failed");
- return RLI_ERRORE;
- }
- G_set_c_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
- for (i = 0; i < ad->cl; i++) {
- mask_patch_sup[i] = 0;
- mask_patch_corr[i] = 0;
- }
- for (j = 0; j < ad->rl; j++)
- /*for each raster row */
- {
- if (j > 0) {
- buf_sup = RLI_get_cell_raster_row(fd, j - 1 + ad->y, ad);
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_cell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad);
}
- buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
+
if (masked) {
- if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("mask read failed");
- return RLI_ERRORE;
- }
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
}
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
G_set_c_null_value(&precCell, 1);
- for (i = 0; i < ad->cl; i++)
- /* for each cell in the row */
- {
- area++;
- corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j + ad->x] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
G_set_c_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, gc.t))) {
- areaPatch++;
- if (i > 0)
- precCell = buf[i - 1 + ad->x];
- if (j == 0)
- G_set_c_null_value(&supCell, 1);
- else
- supCell = buf_sup[i + ad->x];
+ if (G_is_c_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_c_null_value(&supCell, 1);
+ }
- if (corrCell != precCell)
- /* ?
- * 1 2
- * */
- {
- if (corrCell != supCell) {
- /* 3
- * 1 2
- * */
- /*new patch */
- if (idCorr == 0)
- /*first found patch */
+ if (!G_is_c_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j + ad->x] = pid_corr[j - 1 + ad->x];
+ connected = 1;
+ pst[pid_corr[j + ad->x]].count++;
+ }
+ else {
+ connected = 0;
+ }
- {
- lastId = 1;
- idCorr = 1;
- totCorr = 1;
- mask_patch_corr[i] = idCorr;
- }
+ if (!G_is_c_null_value(&supCell) && corrCell == supCell) {
- else
- /*not first patch */
- /* put in the tree the previous value */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
+ if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
- else
- /*tree not empty */
- {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
-
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
-
- {
- npatch++;
- break;
- }
- case AVL_PRES:
-
- {
- break;
- }
- default:
-
- {
- G_fatal_error
- ("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
- totCorr = 1;
- lastId++;
- idCorr = lastId;
- mask_patch_corr[i] = idCorr;
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
}
}
- else
- /* 2
- * 1 2
- * */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ old_pid = pid_corr[j + ad->x];
+ new_pid = pid_sup[j + ad->x];
+ pid_corr[j + ad->x] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k + ad->x] == old_pid)
+ pid_corr[k + ad->x] = new_pid;
}
- else { /*tree not null */
-
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k + ad->x] == old_pid)
+ pid_sup[k + ad->x] = new_pid;
}
-
- idCorr = mask_patch_sup[i];
- mask_patch_corr[i] = idCorr;
- totCorr = 1;
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
- }
- else { /*current cell and previuos cell are equal */
- /* ?
- * 1 1
- */
-
- if (corrCell == supCell) { /*current cell and upper cell are equal */
- /* 1
- * 1 1
- */
- if (mask_patch_sup[i] != mask_patch_corr[i - 1]) {
- long r = 0;
- long del = mask_patch_sup[i];
-
-
- r = avlID_sub(&albero, del); /*r=number of cell of patch removed */
-
- if (r == 0) {
- G_fatal_error("avlID_sub error");
- return RLI_ERRORE;
- }
-
- /*Remove one patch because it makes part of a patch already found */
- ris = avlID_add(&albero, idCorr, r);
-
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- r = i;
- while (r < ad->cl) {
- if (mask_patch_sup[r] == del) {
- mask_patch_sup[r] = idCorr;
- }
-
- r++;
- }
-
- mask_patch_corr[i] = idCorr;
- }
- else {
- mask_patch_corr[i] = idCorr;
- }
+ else {
+ pst[new_pid].count++;
}
- else { /*current cell and upper cell are not equal */
- /* 2
- * 1 1
- */
- mask_patch_corr[i] = idCorr;
- }
-
- totCorr++;
}
+ connected = 1;
}
- else { /*cell is null or is not to consider */
- mask_patch_corr[i] = 0;
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j + ad->x] = pid;
- }
- }
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
- {
- int ii;
- long c;
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
- for (ii = 0; ii < ad->cl; ii++) {
- c = mask_patch_corr[ii];
- mask_patch_sup[ii] = c;
- mask_patch_corr[ii] = 0;
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
+ precCell = corrCell;
}
-
-
}
+ if (npatch > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_units;
+ double area_p;
+ double cell_size_m;
+ double mps;
+ double psd;
+ double diff;
- if (areaPatch != 0) {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
- else {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
+ cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
+ (((NS_DIST1 + NS_DIST2) / 2) / hd.rows);
+ area_units = cell_size_m * area;
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
+ /* mean patch size in hectares */
+ mps = area_units / (npatch * 10000);
- {
- npatch++;
- break;
- }
- case AVL_PRES:
-
- {
- break;
- }
- default:
-
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
+ /* calculate patch size standard deviation */
+ psd = 0;
+ for (old_pid = 1; old_pid <= pid; old_pid++) {
+ if (pst[old_pid].count > 0) {
+ area_p = cell_size_m * pst[old_pid].count / 10000;
+ diff = area_p - mps;
+ psd += diff * diff;
}
}
- array = G_malloc(npatch * sizeof(avlID_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avlID_to_array(albero, zero, array);
- if (tot != npatch) {
- G_warning
- ("avlID_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
- for (i = 0; i < npatch; i++) {
- if (array[i]->tot == 0) {
- doppi++;
- }
- }
- np = npatch;
- npatch = npatch - doppi;
- mn = areaPatch / npatch;
-
- /* calculate summary */
- for (i = 0; i < np; i++) {
- long areaPi = 0;
- double diff;
-
- if (array[i]->tot != 0) {
- ris = ris + array[i]->tot;
- areaPi = (double)array[i]->tot;
- diff = areaPi - mn;
- somma = somma + (diff * diff);
- }
- }
- sd = sqrt(somma / npatch);
- indice = sd;
- G_free(array);
+ psd = sqrt(psd / npatch);
+ *result = psd;
}
-
else
- indice = (double)(-1);
- if (masked)
+ G_set_d_null_value(result, 1);
+
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
- G_free(mask_patch_sup);
- *result = indice;
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
- G_free(buf_sup);
- G_free(buf);
return RLI_OK;
}
-
int calculateD(int fd, struct area_entry *ad, double *result)
{
- DCELL *buf;
- DCELL *buf_sup;
- DCELL corrCell;
- DCELL precCell;
- DCELL supCell;
- int i, j;
- int mask_fd = -1, *mask_buf;
- int ris = 0;
- int masked = FALSE;
- int areaPatch = 0; /*if all cells are null areaPatch=0 */
- long npatch = 0;
- long np = 0;
- long tot = 0;
- long zero = 0;
- long totCorr = 0;
- long idCorr = 0;
- long lastId = 0;
- long doppi = 0;
- long *mask_patch_sup;
- long *mask_patch_corr;
- double indice = 0;
- double somma = 0;
- double area = 0;
- double mn = 0;
- double sd = 0;
- avlID_tree albero = NULL;
- avlID_table *array = NULL;
- generic_cell gc;
+ DCELL *buf, *buf_sup, *buf_null;
+ DCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- gc.t = DCELL_TYPE;
+ G_get_window(&hd);
+ buf_null = G_allocate_d_raster_buf();
+ G_set_d_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(G_window_cols() * sizeof(long));
+ pid_sup = G_malloc(G_window_cols() * sizeof(long));
+
+ for (j = 0; j < G_window_cols(); j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
@@ -542,390 +386,239 @@
G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
masked = TRUE;
}
- mask_patch_sup = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_sup == NULL) {
- G_fatal_error("malloc mask_patch_sup failed");
- return RLI_ERRORE;
+
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
+
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
}
- mask_patch_corr = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_corr == NULL) {
- G_fatal_error("malloc mask_patch_corr failed");
- return RLI_ERRORE;
- }
- buf_sup = G_allocate_d_raster_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
- return RLI_ERRORE;
- }
- buf = G_allocate_d_raster_buf();
- if (buf == NULL) {
- G_fatal_error("malloc buf failed");
- return RLI_ERRORE;
- }
- G_set_d_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
- for (i = 0; i < ad->cl; i++) {
- mask_patch_sup[i] = 0;
- mask_patch_corr[i] = 0;
- }
- for (j = 0; j < ad->rl; j++)
- /*for each raster row */
- {
- if (j > 0) {
- buf_sup = RLI_get_dcell_raster_row(fd, j - 1 + ad->y, ad);
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_dcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_dcell_raster_row(fd, i - 1 + ad->y, ad);
}
- buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
+
if (masked) {
- if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("mask read failed");
- return RLI_ERRORE;
- }
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
}
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
G_set_d_null_value(&precCell, 1);
- for (i = 0; i < ad->cl; i++)
- /* for each dcell in the row */
- {
- area++;
- corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j + ad->x] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
G_set_d_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, gc.t))) {
- areaPatch++;
- if (i > 0)
- precCell = buf[i - 1 + ad->x];
- if (j == 0)
- G_set_d_null_value(&supCell, 1);
- else
- supCell = buf_sup[i + ad->x];
- if (corrCell != precCell)
- /* ?
- * 1 2
- * */
- {
- if (corrCell != supCell) {
- /* 3
- * 1 2
- * */
- /*new patch */
- if (idCorr == 0) { /*first patch */
- lastId = 1;
- idCorr = 1;
- totCorr = 1;
- mask_patch_corr[i] = idCorr;
- }
+ if (G_is_d_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_d_null_value(&supCell, 1);
+ }
- else
- /*not first patch */
- /* put in the tree the previous value */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
+ if (!G_is_d_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j + ad->x] = pid_corr[j - 1 + ad->x];
+ connected = 1;
+ pst[pid_corr[j + ad->x]].count++;
+ }
+ else {
+ connected = 0;
+ }
- else
- /*tree not empty */
- {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
+ if (!G_is_d_null_value(&supCell) && corrCell == supCell) {
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
+ if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
- {
- npatch++;
- break;
- }
- case AVL_PRES:
-
- {
- break;
- }
- default:
-
- {
- G_fatal_error
- ("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
- totCorr = 1;
- lastId++;
- idCorr = lastId;
- mask_patch_corr[i] = idCorr;
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
}
}
- else
- /*current cell and upper cell are equal */
- /* 2
- * 1 2
- * */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ old_pid = pid_corr[j + ad->x];
+ new_pid = pid_sup[j + ad->x];
+ pid_corr[j + ad->x] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k + ad->x] == old_pid)
+ pid_corr[k + ad->x] = new_pid;
}
- else { /*tree not null */
-
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k + ad->x] == old_pid)
+ pid_sup[k + ad->x] = new_pid;
}
-
- idCorr = mask_patch_sup[i];
- mask_patch_corr[i] = idCorr;
- totCorr = 1;
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
- }
- else { /*current cell and previuos cell are equal */
- /* ?
- * 1 1
- */
-
- if (corrCell == supCell) { /*current cell and upper cell are equal */
- /* 1
- * 1 1
- */
- if (mask_patch_sup[i] != mask_patch_corr[i - 1]) {
- long r = 0;
- long del = mask_patch_sup[i];
-
-
- r = avlID_sub(&albero, del); /*r=number of cell of patch removed */
-
- if (r == 0) {
- G_fatal_error("avlID_sub error");
- return RLI_ERRORE;
- }
-
- /*Remove one patch because it makes part of a patch already found */
- ris = avlID_add(&albero, idCorr, r);
-
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- r = i;
- while (r < ad->cl) {
- if (mask_patch_sup[r] == del) {
- mask_patch_sup[r] = idCorr;
- }
-
- r++;
- }
-
- mask_patch_corr[i] = idCorr;
- }
- else {
- mask_patch_corr[i] = idCorr;
- }
+ else {
+ pst[new_pid].count++;
}
- else { /*current cell and upper cell are not equal */
- /* 2
- * 1 1
- */
- mask_patch_corr[i] = idCorr;
- }
-
- totCorr++;
}
+ connected = 1;
}
- else { /*cell is null or is not to consider */
- mask_patch_corr[i] = 0;
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j + ad->x] = pid;
- }
- }
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
- {
- int ii;
- long c;
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
- for (ii = 0; ii < ad->cl; ii++) {
- c = mask_patch_corr[ii];
- mask_patch_sup[ii] = c;
- mask_patch_corr[ii] = 0;
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
+ precCell = corrCell;
}
-
-
}
+ if (npatch > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_units;
+ double area_p;
+ double cell_size_m;
+ double mps;
+ double psd;
+ double diff;
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
- if (areaPatch != 0) {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
+ cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
+ (((NS_DIST1 + NS_DIST2) / 2) / hd.rows);
+ area_units = cell_size_m * area;
- else {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
+ /* mean patch size in hectares */
+ mps = area_units / (npatch * 10000);
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
-
- {
- npatch++;
- break;
- }
- case AVL_PRES:
-
- {
- break;
- }
- default:
-
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
+ /* calculate patch size standard deviation */
+ psd = 0;
+ for (old_pid = 1; old_pid <= pid; old_pid++) {
+ if (pst[old_pid].count > 0) {
+ area_p = cell_size_m * pst[old_pid].count / 10000;
+ diff = area_p - mps;
+ psd += diff * diff;
}
}
- array = G_malloc(npatch * sizeof(avlID_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avlID_to_array(albero, zero, array);
- if (tot != npatch) {
- G_warning
- ("avlID_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
- for (i = 0; i < npatch; i++) {
- if (array[i]->tot == 0) {
- doppi++;
- }
- }
- np = npatch;
- npatch = npatch - doppi;
- mn = areaPatch / npatch;
-
- /* calculate summary */
- for (i = 0; i < np; i++) {
- long areaPi = 0;
- double diff;
-
- if (array[i]->tot != 0) {
- ris = ris + array[i]->tot;
- areaPi = (double)array[i]->tot;
- diff = areaPi - mn;
- somma = somma + (diff * diff);
- }
- }
- sd = sqrt(somma / npatch);
- indice = sd;
- G_free(array);
+ psd = sqrt(psd / npatch);
+ *result = psd;
}
-
else
- indice = (double)(-1);
- if (masked)
+ G_set_d_null_value(result, 1);
+
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
- G_free(mask_patch_sup);
- *result = indice;
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
+
return RLI_OK;
}
+
int calculateF(int fd, struct area_entry *ad, double *result)
{
- FCELL *buf;
- FCELL *buf_sup;
- FCELL corrCell;
- FCELL precCell;
- FCELL supCell;
- int i, j;
- int mask_fd = -1, *mask_buf;
- int ris = 0;
- int masked = FALSE;
- int areaPatch = 0; /*if all cells are null areaPatch=0 */
- long npatch = 0;
- long tot = 0;
- long zero = 0;
- long totCorr = 0;
- long idCorr = 0;
- long lastId = 0;
- long doppi = 0;
- long *mask_patch_sup;
- long *mask_patch_corr;
- long np = 0;
- double indice = 0;
- double somma = 0;
- double area = 0;
- double mn = 0;
- double sd = 0;
- avlID_tree albero = NULL;
- avlID_table *array = NULL;
- generic_cell gc;
+ FCELL *buf, *buf_sup, *buf_null;
+ FCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
- gc.t = FCELL_TYPE;
+ G_get_window(&hd);
+ buf_null = G_allocate_f_raster_buf();
+ G_set_f_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(G_window_cols() * sizeof(long));
+ pid_sup = G_malloc(G_window_cols() * sizeof(long));
+
+ for (j = 0; j < G_window_cols(); j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
return RLI_ERRORE;
@@ -934,351 +627,202 @@
G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
masked = TRUE;
}
- mask_patch_sup = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_sup == NULL) {
- G_fatal_error("malloc mask_patch_sup failed");
- return RLI_ERRORE;
+
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
+
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
}
- mask_patch_corr = G_malloc(ad->cl * sizeof(long));
- if (mask_patch_corr == NULL) {
- G_fatal_error("malloc mask_patch_corr failed");
- return RLI_ERRORE;
- }
- buf_sup = G_allocate_f_raster_buf();
- if (buf_sup == NULL) {
- G_fatal_error("malloc buf_sup failed");
- return RLI_ERRORE;
- }
- buf = G_allocate_f_raster_buf();
- if (buf == NULL) {
- G_fatal_error("malloc buf failed");
- return RLI_ERRORE;
- }
- G_set_f_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
- for (i = 0; i < ad->cl; i++) {
- mask_patch_sup[i] = 0;
- mask_patch_corr[i] = 0;
- }
- for (j = 0; j < ad->rl; j++)
- /*for each raster row */
- {
- if (j > 0) {
- buf_sup = RLI_get_fcell_raster_row(fd, j - 1 + ad->y, ad);
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_fcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_fcell_raster_row(fd, i - 1 + ad->y, ad);
}
- buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
+
if (masked) {
- if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
- G_fatal_error("mask read failed");
- return RLI_ERRORE;
- }
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
}
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
G_set_f_null_value(&precCell, 1);
- for (i = 0; i < ad->cl; i++) {
- /* for each fcell in the row */
- area++;
- corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j + ad->x] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
G_set_f_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, gc.t))) {
- areaPatch++;
- if (i > 0)
- precCell = buf[i - 1 + ad->x];
- if (j == 0)
- G_set_f_null_value(&supCell, 1);
- else
- supCell = buf_sup[i + ad->x];
- if (corrCell != precCell)
- /* ?
- * 1 2
- * */
- {
- if (corrCell != supCell) {
- /* 3
- * 1 2
- * */
- /*new patch */
- if (idCorr == 0) { /*first patch */
- lastId = 1;
- idCorr = 1;
- totCorr = 1;
- mask_patch_corr[i] = idCorr;
- }
+ if (G_is_f_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_f_null_value(&supCell, 1);
+ }
- else
- /*not first patch */
- /* put in the tree the previous value */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
+ if (!G_is_f_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j + ad->x] = pid_corr[j - 1 + ad->x];
+ connected = 1;
+ pst[pid_corr[j + ad->x]].count++;
+ }
+ else {
+ connected = 0;
+ }
- else
- /*tree not empty */
- {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
+ if (!G_is_f_null_value(&supCell) && corrCell == supCell) {
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
+ if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
- {
- npatch++;
- break;
- }
- case AVL_PRES:
-
- {
- break;
- }
- default:
-
- {
- G_fatal_error
- ("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- }
- totCorr = 1;
- lastId++;
- idCorr = lastId;
- mask_patch_corr[i] = idCorr;
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
}
}
- else
- /*current cell and upper cell are equal */
- /* 2
- * 1 2
- * */
- {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
+ old_pid = pid_corr[j + ad->x];
+ new_pid = pid_sup[j + ad->x];
+ pid_corr[j + ad->x] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k + ad->x] == old_pid)
+ pid_corr[k + ad->x] = new_pid;
}
- else { /*tree not null */
-
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k + ad->x] == old_pid)
+ pid_sup[k + ad->x] = new_pid;
}
-
- idCorr = mask_patch_sup[i];
- mask_patch_corr[i] = idCorr;
- totCorr = 1;
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
- }
- else { /*current cell and previuos cell are equal */
- /* ?
- * 1 1
- */
-
- if (corrCell == supCell) { /*current cell and upper cell are equal */
- /* 1
- * 1 1
- */
- if (mask_patch_sup[i] != mask_patch_corr[i - 1]) {
- long r = 0;
- long del = mask_patch_sup[i];
-
-
- r = avlID_sub(&albero, del); /*r=number of cell of patch removed */
-
- if (r == 0) {
- G_fatal_error("avlID_sub error");
- return RLI_ERRORE;
- }
-
- /*Remove one patch because it makes part of a patch already found */
- ris = avlID_add(&albero, idCorr, r);
-
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- npatch++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
- }
- r = i;
- while (r < ad->cl) {
- if (mask_patch_sup[r] == del) {
- mask_patch_sup[r] = idCorr;
- }
-
- r++;
- }
-
- mask_patch_corr[i] = idCorr;
- }
- else {
- mask_patch_corr[i] = idCorr;
- }
+ else {
+ pst[new_pid].count++;
}
- else { /*current cell and upper cell are not equal */
- /* 2
- * 1 1
- */
- mask_patch_corr[i] = idCorr;
- }
-
- totCorr++;
}
+ connected = 1;
}
- else { /*cell is null or is not to consider */
- mask_patch_corr[i] = 0;
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j + ad->x] = pid;
- }
- }
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
- {
- int ii;
- long c;
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
- for (ii = 0; ii < ad->cl; ii++) {
- c = mask_patch_corr[ii];
- mask_patch_sup[ii] = c;
- mask_patch_corr[ii] = 0;
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
+ precCell = corrCell;
}
-
-
}
+ if (npatch > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_units;
+ double area_p;
+ double cell_size_m;
+ double mps;
+ double psd;
+ double diff;
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
- if (areaPatch != 0) {
- if (albero == NULL) {
- albero = avlID_make(idCorr, totCorr);
- if (albero == NULL) {
- G_fatal_error("avlID_make error");
- return RLI_ERRORE;
- }
- npatch++;
- }
+ cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
+ (((NS_DIST1 + NS_DIST2) / 2) / hd.rows);
+ area_units = cell_size_m * area;
- else {
- ris = avlID_add(&albero, idCorr, totCorr);
- switch (ris) {
- case AVL_ERR:
+ /* mean patch size in hectares */
+ mps = area_units / (npatch * 10000);
- {
- G_fatal_error("avlID_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
-
- {
- npatch++;
- break;
- }
- case AVL_PRES:
-
- {
- break;
- }
- default:
-
- {
- G_fatal_error("avlID_add unknown error");
- return RLI_ERRORE;
- }
+ /* calculate patch size standard deviation */
+ psd = 0;
+ for (old_pid = 1; old_pid <= pid; old_pid++) {
+ if (pst[old_pid].count > 0) {
+ area_p = cell_size_m * pst[old_pid].count / 10000;
+ diff = area_p - mps;
+ psd += diff * diff;
}
}
- array = G_malloc(npatch * sizeof(avlID_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avlID_to_array(albero, zero, array);
- if (tot != npatch) {
- G_warning
- ("avlID_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
- for (i = 0; i < npatch; i++) {
- if (array[i]->tot == 0) {
- doppi++;
- }
- }
- np = npatch;
- npatch = npatch - doppi;
- mn = areaPatch / npatch;
-
- /* calculate summary */
- for (i = 0; i < np; i++) {
- long areaPi = 0;
- double diff;
-
- if (array[i]->tot != 0) {
- ris = ris + array[i]->tot;
- areaPi = (double)array[i]->tot;
- diff = areaPi - mn;
- somma = somma + (diff * diff);
- }
- }
- sd = sqrt(somma / npatch);
- indice = sd;
- G_free(array);
+ psd = sqrt(psd / npatch);
+ *result = psd;
}
-
else
- indice = (double)(-1);
- if (masked)
+ G_set_d_null_value(result, 1);
+
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
- G_free(mask_patch_sup);
- *result = indice;
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
+
return RLI_OK;
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.patchdensity/main.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.patchdensity/main.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.patchdensity/main.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -6,6 +6,9 @@
* students of Computer Science University of Pisa (Italy)
* Commission from Faunalia Pontedera (PI) www.faunalia.it
* Fixes: Serena Pallecchi, Markus Neteler <neteler itc.it>
+ * Rewrite: Markus Metz
+ * Patch identification: Michael Shapiro - CERL
+ *
* PURPOSE: calculates patch density index
* COPYRIGHT: (C) 2006-2014 by the GRASS Development Team
*
@@ -20,7 +23,21 @@
#include <grass/gis.h>
#include <grass/glocale.h>
#include "../r.li.daemon/daemon.h"
+#include "../r.li.daemon/GenericCell.h"
+/* template is patchnum */
+
+/* cell count and type of each patch */
+struct pst {
+ long count;
+ generic_cell type;
+};
+
+rli_func patch_density;
+int calculate(int fd, struct area_entry *ad, double *result);
+int calculateD(int fd, struct area_entry *ad, double *result);
+int calculateF(int fd, struct area_entry *ad, double *result);
+
int main(int argc, char *argv[])
{
struct Option *raster, *conf, *output;
@@ -53,152 +70,712 @@
int patch_density(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;
- double area;
- char *mapset;
+ int ris = RLI_OK;
+ double indice = 0;
+
+ switch (ad->data_type) {
+ case CELL_TYPE:
+ {
+ ris = calculate(fd, ad, &indice);
+ break;
+ }
+ case DCELL_TYPE:
+ {
+ ris = calculateD(fd, ad, &indice);
+ break;
+ }
+ case FCELL_TYPE:
+ {
+ ris = calculateF(fd, ad, &indice);
+ break;
+ }
+ default:
+ {
+ G_fatal_error("data type unknown");
+ return RLI_ERRORE;
+ }
+ }
+
+ if (ris != RLI_OK) {
+ return RLI_ERRORE;
+ }
+
+ *result = indice;
+
+ return RLI_OK;
+}
+
+
+int calculate(int fd, struct area_entry *ad, double *result)
+{
+ CELL *buf, *buf_sup, *buf_null;
+ CELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
struct Cell_head hd;
- CELL complete_value;
- double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
- int mask_fd = -1, *mask_buf, *mask_sup, null_count = 0;
- G_debug(1, "begin patch_density() index");
+ G_get_window(&hd);
- G_set_c_null_value(&complete_value, 1);
- mapset = G_find_cell(ad->raster, "");
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
- return 0;
+ buf_null = G_allocate_cell_buf();
+ G_set_c_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+ /* initialize patch ids */
+ pid_corr = G_malloc(ad->cl * sizeof(long));
+ pid_sup = G_malloc(ad->cl * sizeof(long));
+
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
- return 0;
+ return RLI_ERRORE;
+ mask_buf = G_malloc(ad->cl * sizeof(int));
+ if (mask_buf == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
- mask_buf = malloc(ad->cl * sizeof(int));
- mask_sup = malloc(ad->cl * sizeof(int));
+ masked = TRUE;
}
- sup = G_allocate_cell_buf();
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
- /* calculate distance */
- G_begin_distance_calculations();
- /* EW Dist at North edge */
- EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
- /* EW Dist at South Edge */
- EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
- /* NS Dist at East edge */
- NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
- /* NS Dist at West edge */
- NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
+ }
-
- /* calculate number of patch */
-
for (i = 0; i < ad->rl; i++) {
buf = RLI_get_cell_raster_row(fd, i + ad->y, ad);
-
if (i > 0) {
- sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad);
+ buf_sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad);
}
- /* mask values */
- if (ad->mask == 1) {
- int k;
+ if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
+ }
- if (i > 0) {
- int *tmp;
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
- tmp = mask_sup;
- mask_buf = mask_sup;
+ G_set_c_null_value(&precCell, 1);
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
+ G_set_c_null_value(&corrCell, 1);
}
- 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) {
- G_set_c_null_value(mask_buf + k, 1);
- null_count++;
+ else {
+ /* total landscape area */
+ area++;
+ }
+
+ if (G_is_c_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_c_null_value(&supCell, 1);
+ }
+
+ if (!G_is_c_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j] = pid_corr[j - 1];
+ connected = 1;
+ pst[pid_corr[j]].count++;
+ }
+ else {
+ connected = 0;
+ }
+
+ if (!G_is_c_null_value(&supCell) && corrCell == supCell) {
+
+ if (pid_corr[j] != pid_sup[j]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
+
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
+ }
+ }
+
+ old_pid = pid_corr[j];
+ new_pid = pid_sup[j];
+ pid_corr[j] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k] == old_pid)
+ pid_corr[k] = new_pid;
+ }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k] == old_pid)
+ pid_sup[k] = new_pid;
+ }
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
+ }
+ else {
+ pst[new_pid].count++;
+ }
}
+ connected = 1;
}
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j] = pid;
+
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
+
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
+
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
+ }
+ precCell = corrCell;
}
+ }
+ if (area > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_units;
- if (complete_line) {
- if (!G_is_null_value(&(buf[ad->x]), CELL_TYPE) &&
- buf[ad->x] != complete_value)
- count++;
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
- for (j = 0; j < ad->cl - 1; j++) {
+ area_units = ((EW_DIST1 + EW_DIST2) / (2 * hd.cols)) *
+ ((NS_DIST1 + NS_DIST2) / (2 * hd.rows)) * area;
- if (buf[j + ad->x] != buf[j + 1 + ad->x]) {
- complete_line = 0;
- if (!G_is_null_value(&(buf[j + 1 + ad->x]), CELL_TYPE) &&
- buf[j + 1 + ad->x] != complete_value)
- count++;
- }
+ *result = (npatch / area_units) * 1000000;
+ }
+ else {
+ G_set_d_null_value(result, 1);
+ }
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
+
+ return RLI_OK;
+}
+
+
+int calculateD(int fd, struct area_entry *ad, double *result)
+{
+ DCELL *buf, *buf_sup, *buf_null;
+ DCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
+
+ G_get_window(&hd);
+
+ buf_null = G_allocate_d_raster_buf();
+ G_set_d_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(ad->cl * sizeof(long));
+ pid_sup = G_malloc(ad->cl * sizeof(long));
+
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
+ /* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
+ if (ad->mask == 1) {
+ if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
+ return RLI_ERRORE;
+ mask_buf = G_malloc(ad->cl * sizeof(int));
+ if (mask_buf == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
+ masked = TRUE;
+ }
+
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
+
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
+ }
+
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_dcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_dcell_raster_row(fd, i - 1 + ad->y, ad);
+ }
+
+ if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
+ }
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
+ G_set_d_null_value(&precCell, 1);
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
+ G_set_d_null_value(&corrCell, 1);
}
- if (complete_line) {
- complete_value = buf[ad->x];
+ else {
+ /* total landscape area */
+ area++;
}
- }
- 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;
- count--;
+
+ if (G_is_d_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_d_null_value(&supCell, 1);
+ }
+
+ if (!G_is_d_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j] = pid_corr[j - 1];
+ connected = 1;
+ pst[pid_corr[j]].count++;
+ }
+ else {
+ connected = 0;
+ }
+
+ if (!G_is_d_null_value(&supCell) && corrCell == supCell) {
+
+ if (pid_corr[j] != pid_sup[j]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
+
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
+ }
}
- }
- else {
- if (connected &&
- !G_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 &&
- !G_is_null_value(&(buf[j + ad->x]), CELL_TYPE)) {
- count++;
- connected = 0;
- other_above = 0;
+ old_pid = pid_corr[j];
+ new_pid = pid_sup[j];
+ pid_corr[j] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k] == old_pid)
+ pid_corr[k] = new_pid;
+ }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k] == old_pid)
+ pid_sup[k] = new_pid;
+ }
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
else {
- connected = 0;
- other_above = 0;
+ pst[new_pid].count++;
}
}
+ connected = 1;
}
- if (!connected &&
- sup[ad->cl - 1 + ad->x] != buf[ad->cl - 1 + ad->x]) {
- if (!G_is_null_value(&(buf[ad->cl - 1 + ad->x]), CELL_TYPE)) {
- count++;
- complete_line = 0;
+
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j] = pid;
+
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
+
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
}
+
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
+ precCell = corrCell;
+ }
+ }
- if (complete_line)
- complete_value = buf[ad->x];
+ if (area > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_units;
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
+
+ area_units = ((EW_DIST1 + EW_DIST2) / (2 * hd.cols)) *
+ ((NS_DIST1 + NS_DIST2) / (2 * hd.rows)) * area;
+
+ *result = (npatch / area_units) * 1000000;
+ }
+ else {
+ G_set_d_null_value(result, 1);
+ }
+
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
+
+ return RLI_OK;
+}
+
+
+int calculateF(int fd, struct area_entry *ad, double *result)
+{
+ FCELL *buf, *buf_sup, *buf_null;
+ FCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
+
+ G_get_window(&hd);
+
+ buf_null = G_allocate_f_raster_buf();
+ G_set_f_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(ad->cl * sizeof(long));
+ pid_sup = G_malloc(ad->cl * sizeof(long));
+
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
+ /* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
+ if (ad->mask == 1) {
+ if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
+ return RLI_ERRORE;
+ mask_buf = G_malloc(ad->cl * sizeof(int));
+ if (mask_buf == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+ masked = TRUE;
}
- area = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
- (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) *
- (ad->rl *ad->cl - null_count);
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
- if (area != 0)
- *result = (count / area) * 1000000;
- else
- *result = -1;
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
+ }
- G_free(sup);
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_fcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_fcell_raster_row(fd, i - 1 + ad->y, ad);
+ }
+ if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
+ }
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
+ G_set_f_null_value(&precCell, 1);
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
+ G_set_f_null_value(&corrCell, 1);
+ }
+ else {
+ /* total landscape area */
+ area++;
+ }
+
+ if (G_is_f_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_f_null_value(&supCell, 1);
+ }
+
+ if (!G_is_f_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j] = pid_corr[j - 1];
+ connected = 1;
+ pst[pid_corr[j]].count++;
+ }
+ else {
+ connected = 0;
+ }
+
+ if (!G_is_f_null_value(&supCell) && corrCell == supCell) {
+
+ if (pid_corr[j] != pid_sup[j]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
+
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
+ }
+ }
+
+ old_pid = pid_corr[j];
+ new_pid = pid_sup[j];
+ pid_corr[j] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k] == old_pid)
+ pid_corr[k] = new_pid;
+ }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k] == old_pid)
+ pid_sup[k] = new_pid;
+ }
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
+ }
+ else {
+ pst[new_pid].count++;
+ }
+ }
+ connected = 1;
+ }
+
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j] = pid;
+
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
+
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
+
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
+ }
+ precCell = corrCell;
+ }
+ }
+
+ if (area > 0) {
+ double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
+ double area_units;
+
+ /* calculate distance */
+ G_begin_distance_calculations();
+ /* EW Dist at North edge */
+ EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
+ /* EW Dist at South Edge */
+ EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
+ /* NS Dist at East edge */
+ NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
+ /* NS Dist at West edge */
+ NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
+
+ area_units = ((EW_DIST1 + EW_DIST2) / (2 * hd.cols)) *
+ ((NS_DIST1 + NS_DIST2) / (2 * hd.rows)) * area;
+
+ *result = (npatch / area_units) * 1000000;
+ }
+ else {
+ G_set_d_null_value(result, 1);
+ }
+
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
+
return RLI_OK;
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.patchnum/main.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.patchnum/main.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.patchnum/main.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -1,4 +1,3 @@
-
/****************************************************************************
*
* MODULE: r.li.patchnum
@@ -6,6 +5,8 @@
* students of Computer Science University of Pisa (Italy)
* Commission from Faunalia Pontedera (PI) www.faunalia.it
* Fixes: Markus Neteler <neteler itc.it>
+ * Rewrite: Markus Metz
+ * Patch identification: Michael Shapiro - CERL
*
* PURPOSE: calculates patch number index
* COPYRIGHT: (C) 2007-2014 by the GRASS Development Team
@@ -21,8 +22,21 @@
#include <grass/gis.h>
#include <grass/glocale.h>
#include "../r.li.daemon/daemon.h"
-#include "../r.li.daemon/defs.h"
+#include "../r.li.daemon/GenericCell.h"
+/* template for patch density, mps, padcv, padrange, padsd */
+
+/* cell count and type of each patch */
+struct pst {
+ long count;
+ generic_cell type;
+};
+
+rli_func patch_number;
+int calculate(int fd, struct area_entry *ad, double *result);
+int calculateD(int fd, struct area_entry *ad, double *result);
+int calculateF(int fd, struct area_entry *ad, double *result);
+
int main(int argc, char *argv[])
{
struct Option *raster, *conf, *output;
@@ -52,126 +66,643 @@
output->answer);
}
+
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;
- char *mapset;
+ int ris = RLI_OK;
+ double indice = 0;
+
+ switch (ad->data_type) {
+ case CELL_TYPE:
+ {
+ ris = calculate(fd, ad, &indice);
+ break;
+ }
+ case DCELL_TYPE:
+ {
+ ris = calculateD(fd, ad, &indice);
+ break;
+ }
+ case FCELL_TYPE:
+ {
+ ris = calculateF(fd, ad, &indice);
+ break;
+ }
+ default:
+ {
+ G_fatal_error("data type unknown");
+ return RLI_ERRORE;
+ }
+ }
+
+ if (ris != RLI_OK) {
+ return RLI_ERRORE;
+ }
+
+ *result = indice;
+
+ return RLI_OK;
+}
+
+
+int calculate(int fd, struct area_entry *ad, double *result)
+{
+ CELL *buf, *buf_sup, *buf_null;
+ CELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
struct Cell_head hd;
- CELL complete_value;
- int mask_fd = -1, *mask_buf, *mask_sup, null_count = 0;
- G_set_c_null_value(&complete_value, 1);
- mapset = G_find_cell(ad->raster, "");
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
- return 0;
- sup = G_allocate_cell_buf();
+ G_get_window(&hd);
+ buf_null = G_allocate_cell_buf();
+ G_set_c_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(ad->cl * sizeof(long));
+ pid_sup = G_malloc(ad->cl * sizeof(long));
+
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
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));
+ return RLI_ERRORE;
+ mask_buf = G_malloc(ad->cl * sizeof(int));
+ if (mask_buf == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
+ masked = TRUE;
}
- /*calculate number of patch */
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
+ }
+
for (i = 0; i < ad->rl; i++) {
buf = RLI_get_cell_raster_row(fd, i + ad->y, ad);
if (i > 0) {
- sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad);
+ buf_sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad);
}
- /* mask values */
- if (ad->mask == 1) {
- int k;
- if (i > 0) {
- int *tmp;
+ if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
+ }
- tmp = mask_sup;
- mask_buf = mask_sup;
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
+ G_set_c_null_value(&precCell, 1);
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
+ G_set_c_null_value(&corrCell, 1);
}
- 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) {
- G_set_c_null_value(mask_buf + k, 1);
- null_count++;
+
+ if (G_is_c_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_c_null_value(&supCell, 1);
+ }
+
+ if (!G_is_c_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j] = pid_corr[j - 1];
+ connected = 1;
+ pst[pid_corr[j]].count++;
+ }
+ else {
+ connected = 0;
+ }
+
+ if (!G_is_c_null_value(&supCell) && corrCell == supCell) {
+
+ if (pid_corr[j] != pid_sup[j]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
+
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
+ }
+ }
+
+ old_pid = pid_corr[j];
+ new_pid = pid_sup[j];
+ pid_corr[j] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k] == old_pid)
+ pid_corr[k] = new_pid;
+ }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k] == old_pid)
+ pid_sup[k] = new_pid;
+ }
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
+ }
+ else {
+ pst[new_pid].count++;
+ }
}
+ connected = 1;
}
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j] = pid;
+
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
+
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
+
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
+ }
+ precCell = corrCell;
}
+ }
+ *result = npatch;
- if (complete_line) {
- if (!G_is_null_value(&(buf[ad->x]), CELL_TYPE) &&
- buf[ad->x] != complete_value)
- count++;
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
- for (j = 0; j < ad->cl - 1; j++) {
+ return RLI_OK;
+}
- if (buf[j + ad->x] != buf[j + 1 + ad->x]) {
- complete_line = 0;
- if (!G_is_null_value(&(buf[j + 1 + ad->x]), CELL_TYPE) &&
- buf[j + 1 + ad->x] != complete_value)
- count++;
- }
+int calculateD(int fd, struct area_entry *ad, double *result)
+{
+ DCELL *buf, *buf_sup, *buf_null;
+ DCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
+
+ G_get_window(&hd);
+
+ buf_null = G_allocate_d_raster_buf();
+ G_set_d_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(ad->cl * sizeof(long));
+ pid_sup = G_malloc(ad->cl * sizeof(long));
+
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
+ /* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
+ if (ad->mask == 1) {
+ if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
+ return RLI_ERRORE;
+ mask_buf = G_malloc(ad->cl * sizeof(int));
+ if (mask_buf == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
+ masked = TRUE;
+ }
+
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
+
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
+ }
+
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_dcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_dcell_raster_row(fd, i - 1 + ad->y, ad);
+ }
+
+ if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
+ }
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
+ G_set_d_null_value(&precCell, 1);
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
+ G_set_d_null_value(&corrCell, 1);
}
- if (complete_line) {
- complete_value = buf[ad->x];
+
+ if (G_is_d_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
}
- }
- 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;
- count--;
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_d_null_value(&supCell, 1);
+ }
+
+ if (!G_is_d_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j] = pid_corr[j - 1];
+ connected = 1;
+ pst[pid_corr[j]].count++;
+ }
+ else {
+ connected = 0;
+ }
+
+ if (!G_is_d_null_value(&supCell) && corrCell == supCell) {
+
+ if (pid_corr[j] != pid_sup[j]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
+
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
+ }
}
- }
- else {
- if (connected &&
- !G_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 &&
- !G_is_null_value(&(buf[j + ad->x]), CELL_TYPE)) {
- count++;
- connected = 0;
- other_above = 0;
+ old_pid = pid_corr[j];
+ new_pid = pid_sup[j];
+ pid_corr[j] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k] == old_pid)
+ pid_corr[k] = new_pid;
+ }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k] == old_pid)
+ pid_sup[k] = new_pid;
+ }
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
}
else {
- connected = 0;
- other_above = 0;
+ pst[new_pid].count++;
}
}
+ connected = 1;
}
- if (!connected &&
- sup[ad->cl - 1 + ad->x] != buf[ad->cl - 1 + ad->x]) {
- if (!G_is_null_value(&(buf[ad->cl - 1 + ad->x]), CELL_TYPE)) {
- count++;
- complete_line = 0;
+
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j] = pid;
+
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
+
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
}
+
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
}
+ precCell = corrCell;
+ }
+ }
- if (complete_line)
- complete_value = buf[ad->x];
+ *result = npatch;
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
+
+ return RLI_OK;
+}
+
+
+int calculateF(int fd, struct area_entry *ad, double *result)
+{
+ FCELL *buf, *buf_sup, *buf_null;
+ FCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+ struct Cell_head hd;
+
+ G_get_window(&hd);
+
+ buf_null = G_allocate_f_raster_buf();
+ G_set_f_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(ad->cl * sizeof(long));
+ pid_sup = G_malloc(ad->cl * sizeof(long));
+
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
+ /* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
+ if (ad->mask == 1) {
+ if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
+ return RLI_ERRORE;
+ mask_buf = G_malloc(ad->cl * sizeof(int));
+ if (mask_buf == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
}
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+ masked = TRUE;
}
- *result = count;
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
- G_free(sup);
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].count = 0;
+ }
+
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_fcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_fcell_raster_row(fd, i - 1 + ad->y, ad);
+ }
+
+ if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
+ }
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
+ G_set_f_null_value(&precCell, 1);
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
+ G_set_f_null_value(&corrCell, 1);
+ }
+
+ if (G_is_f_null_value(&corrCell)) {
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ area++;
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_f_null_value(&supCell, 1);
+ }
+
+ if (!G_is_f_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j] = pid_corr[j - 1];
+ connected = 1;
+ pst[pid_corr[j]].count++;
+ }
+ else {
+ connected = 0;
+ }
+
+ if (!G_is_f_null_value(&supCell) && corrCell == supCell) {
+
+ if (pid_corr[j] != pid_sup[j]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
+
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
+ }
+ }
+
+ old_pid = pid_corr[j];
+ new_pid = pid_sup[j];
+ pid_corr[j] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k] == old_pid)
+ pid_corr[k] = new_pid;
+ }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k] == old_pid)
+ pid_sup[k] = new_pid;
+ }
+ pst[new_pid].count += pst[old_pid].count;
+ pst[old_pid].count = 0;
+
+ if (old_pid == pid)
+ pid--;
+ }
+ else {
+ pst[new_pid].count++;
+ }
+ }
+ connected = 1;
+ }
+
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j] = pid;
+
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
+
+ for (k = nalloc; k < pid + incr; k++)
+ pst[k].count = 0;
+
+ nalloc = pid + incr;
+ }
+
+ pst[pid].count = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
+ }
+ precCell = corrCell;
+ }
+ }
+
+ *result = npatch;
+
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
+
return RLI_OK;
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.pielou/pielou.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.pielou/pielou.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.pielou/pielou.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -7,6 +7,7 @@
*
* AUTHOR(S): Luca Delucchi, Fondazione Edmund Mach
* Serena Pallecchi student of Computer Science University of Pisa (Italy)
+ * Rewrite: Markus Metz
*
* COPYRIGHT:
* This program is free software under the GPL (>=v2)
@@ -21,36 +22,20 @@
#include <grass/gis.h>
#include <grass/glocale.h>
-#include "../r.li.daemon/defs.h"
+#include "../r.li.daemon/daemon.h"
#include "../r.li.daemon/avlDefs.h"
#include "../r.li.daemon/avl.h"
-#include "../r.li.daemon/daemon.h"
/* template is shannon */
+rli_func pielou;
int calculate(int fd, struct area_entry *ad, double *result);
-
int calculateD(int fd, struct area_entry *ad, double *result);
-
int calculateF(int fd, struct area_entry *ad, double *result);
-/*This function is used to sort the values in the moving window */
-static int cmp(const void *pa, const void *pb)
-{
- int *p1 = (int *)pa;
- int *p2 = (int *)pb;
-
- if (*p1 < *p2)
- return -1;
- if (*p1 > *p2)
- return 1;
- return 0;
-}
-
int main(int argc, char *argv[])
{
struct Option *raster, *conf, *output;
-
struct GModule *module;
G_gisinit(argv[0]);
@@ -78,32 +63,26 @@
output->answer);
}
+
int pielou(int fd, char **par, struct area_entry *ad, double *result)
{
- char *mapset;
int ris = RLI_OK;
double indice = 0;
- struct Cell_head hd;
- mapset = G_find_cell(ad->raster, "");
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
- return RLI_ERRORE;
-
-
switch (ad->data_type) {
case CELL_TYPE:
{
- calculate(fd, ad, &indice);
+ ris = calculate(fd, ad, &indice);
break;
}
case DCELL_TYPE:
{
- calculateD(fd, ad, &indice);
+ ris = calculateD(fd, ad, &indice);
break;
}
case FCELL_TYPE:
{
- calculateF(fd, ad, &indice);
+ ris = calculateF(fd, ad, &indice);
break;
}
default:
@@ -130,34 +109,22 @@
CELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
+
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
- double indice = 0;
- double somma = 0;
- double percentuale = 0;
- double area = 0;
- double t;
- double logaritmo;
+ long totCorr = 1;
- /* add to compute the number of class */
- long *array_copy;
- int totNumClass = 1;
- double logTotNumClass;
+ long area = 0;
- generic_cell cc;
-
- generic_cell cc_passage; /*add to compute the number of class */
-
avl_tree albero = NULL;
AVL_table *array;
+ generic_cell uc;
- cc.t = CELL_TYPE;
+ uc.t = CELL_TYPE;
/* open mask if needed */
if (ad->mask == 1) {
@@ -172,11 +139,7 @@
}
G_set_c_null_value(&precCell, 1);
-
- /*for each row */
- for (j = 0; j < ad->rl; j++) {
- buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
-
+ for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
G_fatal_error("mask read failed");
@@ -184,77 +147,74 @@
}
}
+ buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
- area++;
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_c_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, cc.t))) {
- a = 1;
- if (G_is_null_value(&precCell, cc.t)) {
- precCell = corrCell;
- }
+ if (!(G_is_null_value(&corrCell, uc.t))) {
+ /* total patch area */
+ area++;
+ }
- if (corrCell != precCell) {
- if (albero == NULL) {
- cc.val.c = precCell;
- albero = avl_make(cc, totCorr);
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.c = precCell;
+ albero = avl_make(uc, totCorr);
+ if (albero == NULL) {
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.c = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- else
+ case AVL_ADD:
+ {
m++;
- }
- else {
- cc.val.c = precCell;
- ris = avl_add(&albero, cc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_add unknown error");
- return RLI_ERRORE;
- }
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
}
- else {
- totCorr++;
- }
- precCell = corrCell;
- }
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
+ }
+ }
- } /* end for */
- } /* end for */
-
-
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
- cc.val.c = precCell;
- albero = avl_make(cc, totCorr);
-
+ uc.val.c = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
G_fatal_error("avl_make error");
return RLI_ERRORE;
@@ -262,8 +222,8 @@
m++;
}
else {
- cc.val.c = precCell;
- ris = avl_add(&albero, cc, totCorr);
+ uc.val.c = precCell;
+ ris = avl_add(&albero, uc, totCorr);
switch (ris) {
case AVL_ERR:
{
@@ -288,59 +248,40 @@
}
}
- array = G_malloc(m * sizeof(AVL_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avl_to_array(albero, zero, array);
+ if (area > 0 && m > 1) {
+ double t;
+ double shannon;
+ double perc, logarithm;
- if (tot != m) {
- G_warning("avl_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
+ array = G_malloc(m * sizeof(AVL_tableRow));
+ if (array == NULL) {
+ G_fatal_error("malloc array failed");
+ return RLI_ERRORE;
+ }
+ tot = avl_to_array(albero, zero, array);
+ if (tot != m) {
+ G_warning("avl_to_array unexpected value. the result could be wrong");
+ return RLI_ERRORE;
+ }
- array_copy = G_malloc(m * sizeof(AVL_tableRow));
- for (i = 0; i < m; i++) {
- cc_passage = array[i]->k;
- array_copy[i] = cc_passage.val.c;
- }
-
- qsort(array_copy, m, sizeof(int), cmp);
-
- for (i = 1; i < m; i++) {
- if (array_copy[i - 1] != array_copy[i]) {
- totNumClass++;
+ /* calculate shannon */
+ shannon = 0;
+ for (i = 0; i < m; i++) {
+ t = array[i]->tot;
+ perc = t / area;
+ logarithm = log(perc);
+ shannon += perc * logarithm;
}
- }
+ G_free(array);
- /* calculate summary */
- for (i = 0; i < m; i++) {
- t = (double)array[i]->tot;
- percentuale = (double)(t / area);
- logaritmo = (double)log(percentuale);
- somma = somma + (percentuale * logaritmo);
+ *result = -shannon / log(m);
}
+ else
+ G_set_d_null_value(result, 1);
- logTotNumClass = (double)log(totNumClass);
- /*if a is 0, that is all cell are null, i put index=-1 */
- if (a != 0) {
- indice = ((-1) * somma) / logTotNumClass;
- }
- else {
- indice = (double)(-1);
- }
-
- if (isnan(indice) || isinf(indice)) {
- indice = -1;
- }
- G_debug(1, "somma: %g, number of logTotNumClass: %g, valore finale: %g",
- somma, logTotNumClass, indice);
-
- *result = indice;
-
- G_free(array);
+ avl_destroy(albero);
if (masked) {
+ close(mask_fd);
G_free(mask_buf);
}
@@ -348,42 +289,29 @@
}
-
int calculateD(int fd, struct area_entry *ad, double *result)
{
-
DCELL *buf;
DCELL corrCell;
DCELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
- double indice = 0;
- double somma = 0;
- double percentuale = 0;
- double area = 0;
- double t;
- double logaritmo;
+ long totCorr = 1;
- /*add to compute the number of class */
- long *array_copy;
- int totNumClass = 1;
- double logTotNumClass;
+ long area = 0;
avl_tree albero = NULL;
AVL_table *array;
- generic_cell cc;
- generic_cell cc_passage; /*add to compute the number of class */
+ generic_cell uc;
- cc.t = DCELL_TYPE;
+ uc.t = DCELL_TYPE;
/* open mask if needed */
if (ad->mask == 1) {
@@ -397,14 +325,8 @@
masked = TRUE;
}
-
G_set_d_null_value(&precCell, 1);
-
- /*for each row */
- for (j = 0; j < ad->rl; j++) {
- buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
-
-
+ for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
G_fatal_error("mask read failed");
@@ -412,76 +334,74 @@
}
}
+ buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
- for (i = 0; i < ad->cl; i++) { /* for each dcell in the row */
- area++;
+ for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_d_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, DCELL_TYPE))) {
- a = 1;
- if (G_is_null_value(&precCell, DCELL_TYPE)) {
- precCell = corrCell;
- }
- if (corrCell != precCell) {
+ if (!(G_is_null_value(&corrCell, uc.t))) {
+ /* total patch area */
+ area++;
+ }
+
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
+
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.dc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
- cc.val.dc = precCell;
- albero = avl_make(cc, totCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.dc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- m++;
- }
- else {
- cc.val.dc = precCell;
- ris = avl_add(&albero, cc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_add unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
}
- else {
- totCorr++;
- }
- precCell = corrCell;
- }
-
- } /*close for */
- } /*close for */
-
- if (masked) {
- G_free(mask_buf);
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
+ }
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
- cc.val.dc = precCell;
- albero = avl_make(cc, totCorr);
+ uc.val.dc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
G_fatal_error("avl_make error");
return RLI_ERRORE;
@@ -489,8 +409,8 @@
m++;
}
else {
- cc.val.fc = precCell;
- ris = avl_add(&albero, cc, totCorr);
+ uc.val.dc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
switch (ris) {
case AVL_ERR:
{
@@ -513,7 +433,12 @@
}
}
}
+ }
+ if (area > 0 && m > 1) {
+ double t;
+ double shannon;
+ double perc, logarithm;
array = G_malloc(m * sizeof(AVL_tableRow));
if (array == NULL) {
@@ -521,92 +446,59 @@
return RLI_ERRORE;
}
tot = avl_to_array(albero, zero, array);
-
if (tot != m) {
- G_warning
- ("avl_to_array unaspected value. the result could be wrong");
+ G_warning("avl_to_array unexpected value. the result could be wrong");
return RLI_ERRORE;
}
- array_copy = G_malloc(m * sizeof(AVL_tableRow));
-
+ /* calculate shannon */
+ shannon = 0;
for (i = 0; i < m; i++) {
- cc_passage = array[i]->k;
- array_copy[i] = cc_passage.val.c;
+ t = array[i]->tot;
+ perc = t / area;
+ logarithm = log(perc);
+ shannon += perc * logarithm;
}
-
- qsort(array_copy, m, sizeof(int), cmp);
-
- for (i = 1; i < m; i++) {
- if (array_copy[i - 1] != array_copy[i]) {
- totNumClass++;
- }
- }
-
-
- /* calculate summary */
- for (i = 0; i < m; i++) {
- t = (double)array[i]->tot;
- percentuale = (double)(t / area);
- logaritmo = (double)log(percentuale);
- somma = somma + (percentuale * logaritmo);
- }
-
G_free(array);
- logTotNumClass = (double)log(totNumClass);
-
- indice = (-1) * somma / logTotNumClass;
+ *result = -shannon / log(m);
}
- else {
- /*if a is 0, that is all cell are null, i put index=-1 */
- indice = ((double)(-1));
- }
+ else
+ G_set_d_null_value(result, 1);
- if (isnan(indice) || isinf(indice)) {
- indice = -1;
+ avl_destroy(albero);
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
}
- G_debug(1, "somma: %g, number of logTotNumClass: %g, valore finale: %g",
- somma, logTotNumClass, indice);
- *result = indice;
-
return RLI_OK;
}
int calculateF(int fd, struct area_entry *ad, double *result)
{
-
FCELL *buf;
FCELL corrCell;
FCELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
+
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
- double indice = 0;
- double somma = 0;
- double percentuale = 0;
- double area = 0;
- double t;
- double logaritmo;
- long *array_copy;
- int totNumClass = 1;
- double logTotNumClass;
+ long totCorr = 1;
+ long area = 0;
+
avl_tree albero = NULL;
AVL_table *array;
- generic_cell cc;
- generic_cell cc_passage;
+ generic_cell uc;
- cc.t = FCELL_TYPE;
+ uc.t = FCELL_TYPE;
/* open mask if needed */
if (ad->mask == 1) {
@@ -620,15 +512,8 @@
masked = TRUE;
}
-
G_set_f_null_value(&precCell, 1);
-
-
- /*for each row */
- for (j = 0; j < ad->rl; j++) {
- buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
-
-
+ for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
G_fatal_error("mask read failed");
@@ -636,71 +521,74 @@
}
}
- for (i = 0; i < ad->cl; i++) { /* for each fcell in the row */
- area++;
+ buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
+
+ for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_f_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, cc.t))) {
- a = 1;
- if (G_is_null_value(&precCell, cc.t)) {
- precCell = corrCell;
- }
- if (corrCell != precCell) {
+ if (!(G_is_null_value(&corrCell, uc.t))) {
+ /* total patch area */
+ area++;
+ }
+
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
+
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.fc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
- cc.val.fc = precCell;
- albero = avl_make(cc, totCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.fc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- m++;
- }
- else {
- cc.val.fc = precCell;
- ris = avl_add(&albero, cc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_add unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
}
- else {
- totCorr++;
- }
-
- precCell = corrCell;
- }
-
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
}
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
- cc.val.fc = precCell;
- albero = avl_make(cc, totCorr);
+ uc.val.fc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
G_fatal_error("avl_make error");
return RLI_ERRORE;
@@ -708,8 +596,8 @@
m++;
}
else {
- cc.val.fc = precCell;
- ris = avl_add(&albero, cc, totCorr);
+ uc.val.fc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
switch (ris) {
case AVL_ERR:
{
@@ -734,63 +622,42 @@
}
}
- array = G_malloc(m * sizeof(AVL_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avl_to_array(albero, zero, array);
+ if (area > 0 && m > 1) {
+ double t;
+ double shannon;
+ double perc, logarithm;
- if (tot != m) {
- G_warning("avl_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
+ array = G_malloc(m * sizeof(AVL_tableRow));
+ if (array == NULL) {
+ G_fatal_error("malloc array failed");
+ return RLI_ERRORE;
+ }
+ tot = avl_to_array(albero, zero, array);
+ if (tot != m) {
+ G_warning("avl_to_array unexpected value. the result could be wrong");
+ return RLI_ERRORE;
+ }
- array_copy = G_malloc(m * sizeof(AVL_tableRow));
-
- for (i = 0; i < m; i++) {
- cc_passage = array[i]->k;
- array_copy[i] = cc_passage.val.c;
- }
-
- qsort(array_copy, m, sizeof(int), cmp);
-
- for (i = 1; i < m; i++) {
- if (array_copy[i - 1] != array_copy[i]) {
- totNumClass++;
+ /* calculate shannon */
+ shannon = 0;
+ for (i = 0; i < m; i++) {
+ t = array[i]->tot;
+ perc = t / area;
+ logarithm = log(perc);
+ shannon += perc * logarithm;
}
- }
+ G_free(array);
- /* calculate summary */
- for (i = 0; i < m; i++) {
- t = (double)array[i]->tot;
- percentuale = (double)(t / area);
- logaritmo = (double)log(percentuale);
- somma = somma + (percentuale * logaritmo);
+ *result = -shannon / log(m);
}
+ else
+ G_set_d_null_value(result, 1);
- logTotNumClass = (double)log(totNumClass);
-
-
- /*if a is 0, that is all cell are null, i put index=-1 */
- if (a != 0) {
- indice = ((-1) * somma) / logTotNumClass;
- }
- else {
- indice = (double)(-1);
- }
-
- if (isnan(indice) || isinf(indice)) {
- indice = -1;
- }
- G_debug(1, "somma: %g, number of logTotNumClass: %g, valore finale: %g",
- somma, logTotNumClass, indice);
-
- *result = indice;
-
- G_free(array);
+ avl_destroy(albero);
if (masked) {
+ close(mask_fd);
G_free(mask_buf);
}
+
return RLI_OK;
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.renyi/renyi.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.renyi/renyi.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.renyi/renyi.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -3,10 +3,11 @@
*
* MODULE: r.li.renyi
*
- * PURPOSE: brief calculates renyi's diversity index
+ * PURPOSE: calculates renyi's diversity index
*
* AUTHOR(S): Luca Delucchi, Fondazione Edmund Mach
* Serena Pallecchi student of Computer Science University of Pisa (Italy)
+ * Rewrite: Markus Metz
*
* COPYRIGHT:
* This program is free software under the GPL (>=v2)
@@ -21,17 +22,17 @@
#include <grass/gis.h>
#include <grass/glocale.h>
-#include "../r.li.daemon/defs.h"
+#include "../r.li.daemon/daemon.h"
#include "../r.li.daemon/avlDefs.h"
#include "../r.li.daemon/avl.h"
-#include "../r.li.daemon/daemon.h"
-double calculate(struct area_entry *ad, int fd, char **par, double *result);
+/* template is shannon */
-double calculateD(struct area_entry *ad, int fd, char **par, double *result);
+rli_func renyi;
+int calculate(int fd, struct area_entry *ad, char **par, double *result);
+int calculateD(int fd, struct area_entry *ad, char **par, double *result);
+int calculateF(int fd, struct area_entry *ad, char **par, double *result);
-double calculateF(struct area_entry *ad, int fd, char **par, double *result);
-
int main(int argc, char *argv[])
{
struct Option *raster, *conf, *output, *alpha;
@@ -49,11 +50,9 @@
raster = G_define_standard_option(G_OPT_R_MAP);
- conf = G_define_option();
+ conf = G_define_standard_option(G_OPT_F_INPUT);
conf->key = "conf";
conf->description = _("Configuration file");
- conf->type = TYPE_STRING;
- conf->gisprompt = "old_file,file,input";
conf->required = YES;
alpha = G_define_option();
@@ -68,7 +67,7 @@
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
- if (atoi(alpha->answer) == 1) {
+ if (atof(alpha->answer) == 1) {
G_fatal_error
("If alpha = 1 Renyi index is not defined. (Ricotta et al., 2003, Environ. Model. Softw.)");
exit(RLI_ERRORE);
@@ -83,34 +82,31 @@
}
return calculateIndex(conf->answer, renyi, par, raster->answer,
output->answer);
-
}
+
int renyi(int fd, char **par, struct area_entry *ad, double *result)
{
- char *mapset;
int ris = RLI_OK;
double indice = 0;
- struct Cell_head hd;
- mapset = G_find_cell(ad->raster, "");
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
- return RLI_ERRORE;
+ if (!par)
+ G_fatal_error("par is NULL");
switch (ad->data_type) {
case CELL_TYPE:
{
- ris = calculate(ad, fd, par, &indice);
+ ris = calculate(fd, ad, par, &indice);
break;
}
case DCELL_TYPE:
{
- ris = calculateD(ad, fd, par, &indice);
+ ris = calculateD(fd, ad, par, &indice);
break;
}
case FCELL_TYPE:
{
- ris = calculateF(ad, fd, par, &indice);
+ ris = calculateF(fd, ad, par, &indice);
break;
}
default:
@@ -118,41 +114,36 @@
G_fatal_error("data type unknown");
return RLI_ERRORE;
}
-
}
- if (ris != RLI_OK)
+ if (ris != RLI_OK) {
return RLI_ERRORE;
+ }
*result = indice;
return RLI_OK;
-
}
-
-double calculate(struct area_entry *ad, int fd, char **par, double *result)
+int calculate(int fd, struct area_entry *ad, char **par, double *result)
{
CELL *buf;
CELL corrCell;
CELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
+
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
- double indice = 0;
- double somma = 0;
- double p = 0;
- double area = 0;
- double t;
+ long totCorr = 1;
+ long area = 0;
+
avl_tree albero = NULL;
AVL_table *array;
generic_cell uc;
@@ -172,8 +163,6 @@
}
G_set_c_null_value(&precCell, 1);
-
-
for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
@@ -183,70 +172,70 @@
}
buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
+
for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
- area++;
corrCell = buf[i + ad->x];
- if ((masked) && (mask_buf[i + ad->x] == 0)) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_c_null_value(&corrCell, 1);
- area--;
}
if (!(G_is_null_value(&corrCell, uc.t))) {
- a = 1;
- if (G_is_null_value(&precCell, uc.t)) {
- precCell = corrCell;
+ /* total patch area */
+ area++;
+ }
+
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
+
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.c = precCell;
+ albero = avl_make(uc, totCorr);
+ if (albero == NULL) {
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
}
- if (corrCell != precCell) {
- if (albero == NULL) {
- uc.val.c = precCell;
- albero = avl_make(uc, totCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ else {
+ uc.val.c = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- else
+ case AVL_ADD:
+ {
m++;
- }
- else {
- uc.val.c = precCell;
- ris = avl_add(&albero, uc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_make unknown error");
- return RLI_ERRORE;
- }
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
- } /* endif not equal cells */
- else { /*equal cells */
-
- totCorr++;
}
- precCell = corrCell;
- }
-
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
}
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
uc.val.c = precCell;
albero = avl_make(uc, totCorr);
@@ -282,69 +271,80 @@
}
}
}
- array = G_malloc(m * sizeof(AVL_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avl_to_array(albero, zero, array);
- if (tot != m) {
- G_warning("avl_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
- char *sval;
+ if (area > 0) {
+ double alpha;
+ double pi;
+ double t;
+ double sum, sum2;
- sval = par[0];
- double alpha_double;
+ alpha = atof(par[0]);
- alpha_double = (double)atof(sval);
- /* claculate index summary */
- for (i = 0; i < m; i++) {
- t = (double)(array[i]->tot);
- p = t / area;
- G_debug(1, "Valore p: %g, valore pow: %g", p, pow(p, alpha_double));
- somma = somma + pow(p, alpha_double);
- }
+ array = G_malloc(m * sizeof(AVL_tableRow));
+ if (array == NULL) {
+ G_fatal_error("malloc array failed");
+ return RLI_ERRORE;
+ }
+ tot = avl_to_array(albero, zero, array);
+ if (tot != m) {
+ G_warning("avl_to_array unexpected value. the result could be wrong");
+ return RLI_ERRORE;
+ }
- indice = (1 / (1 - alpha_double)) * log(somma);
- if (isnan(indice) || isinf(indice)) {
- indice = -1;
- }
- G_debug(1, "Valore somma: %g Valore indice: %g", somma, indice);
+ /* calculate renyi index */
+ sum = 0;
+ sum2 = 0;
+ for (i = 0; i < m; i++) {
+ t = array[i]->tot;
+ pi = t / area;
+ sum += pow(pi, alpha);
+ sum2 += pi;
+ }
+ G_free(array);
- *result = indice;
+ /* correction for numerical instability */
+ if (sum2 != 1)
+ sum += 1 - sum2;
+ if ((alpha < 1 && sum < 1) || (alpha > 1 && sum > 1)) {
+ G_warning("Renyi index calculation reached numerical instability. "
+ "This can happen with alpha close to 1. The result will be set to zero.");
+ sum = 1;
+ }
- G_free(array);
- if (masked)
+ *result = (1 / (1 - alpha)) * log(sum);
+ }
+ else
+ G_set_d_null_value(result, 1);
+
+ avl_destroy(albero);
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
+ }
return RLI_OK;
}
-double calculateD(struct area_entry *ad, int fd, char **par, double *result)
+int calculateD(int fd, struct area_entry *ad, char **par, double *result)
{
DCELL *buf;
DCELL corrCell;
DCELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
+
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
- double indice = 0;
- double somma = 0;
- double p = 0;
- double area = 0;
- double t;
+ long totCorr = 1;
+ long area = 0;
+
avl_tree albero = NULL;
AVL_table *array;
generic_cell uc;
@@ -357,14 +357,13 @@
return RLI_ERRORE;
mask_buf = G_malloc(ad->cl * sizeof(int));
if (mask_buf == NULL) {
- G_fatal_error("malloc mask_buffailed");
+ G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
masked = TRUE;
}
G_set_d_null_value(&precCell, 1);
-
for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
@@ -375,71 +374,69 @@
buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
- for (i = 0; i < ad->cl; i++) { /* for each dcell in the row */
- area++;
+ for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_d_null_value(&corrCell, 1);
- area--;
}
if (!(G_is_null_value(&corrCell, uc.t))) {
- a = 1;
+ /* total patch area */
+ area++;
+ }
- if (G_is_null_value(&precCell, uc.t)) {
- precCell = corrCell;
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
+
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.dc = precCell;
+ albero = avl_make(uc, totCorr);
+ if (albero == NULL) {
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
}
- if (corrCell != precCell) {
- if (albero == NULL) {
- uc.val.dc = precCell;
- albero = avl_make(uc, totCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ else {
+ uc.val.dc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- m++;
- }
- else {
- uc.val.dc = precCell;
- ris = avl_add(&albero, uc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_make unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
- } /* endif not equal dcells */
- else { /*equal dcells */
-
- totCorr++;
}
- precCell = corrCell;
- }
-
-
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
}
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
uc.val.dc = precCell;
albero = avl_make(uc, totCorr);
@@ -475,71 +472,80 @@
}
}
}
- array = G_malloc(m * sizeof(AVL_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avl_to_array(albero, zero, array);
- if (tot != m) {
- G_warning("avl_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
- char *sval;
+ if (area > 0) {
+ double alpha;
+ double pi;
+ double t;
+ double sum, sum2;
- sval = par[0];
- double alpha_double;
+ alpha = atof(par[0]);
- alpha_double = (double)atof(sval);
- /* claculate index summary */
- for (i = 0; i < m; i++) {
- t = (double)(array[i]->tot);
- p = t / area;
- G_debug(1, "Valore p: %g, valore pow: %g", p, pow(p, alpha_double));
- somma = somma + pow(p, alpha_double);
- }
+ array = G_malloc(m * sizeof(AVL_tableRow));
+ if (array == NULL) {
+ G_fatal_error("malloc array failed");
+ return RLI_ERRORE;
+ }
+ tot = avl_to_array(albero, zero, array);
+ if (tot != m) {
+ G_warning("avl_to_array unexpected value. the result could be wrong");
+ return RLI_ERRORE;
+ }
- indice = (1 / (1 - alpha_double)) * log(somma);
+ /* calculate renyi index */
+ sum = 0;
+ sum2 = 0;
+ for (i = 0; i < m; i++) {
+ t = array[i]->tot;
+ pi = t / area;
+ sum += pow(pi, alpha);
+ sum += pi;
+ }
+ G_free(array);
- if (isnan(indice) || isinf(indice)) {
- indice = -1;
- }
+ /* correction for numerical instability */
+ if (sum2 != 1)
+ sum += 1 - sum2;
- G_debug(1, "Valore somma: %g Valore indice: %g", somma, indice);
+ if ((alpha < 1 && sum < 1) || (alpha > 1 && sum > 1)) {
+ G_warning("Renyi index calculation reached numerical instability. "
+ "This can happen with alpha close to 1. The result will be set to zero.");
+ sum = 1;
+ }
- *result = indice;
+ *result = (1 / (1 - alpha)) * log(sum);
+ }
+ else
+ G_set_d_null_value(result, 1);
- G_free(array);
- if (masked)
+ avl_destroy(albero);
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
+ }
return RLI_OK;
}
-
-double calculateF(struct area_entry *ad, int fd, char **par, double *result)
+int calculateF(int fd, struct area_entry *ad, char **par, double *result)
{
FCELL *buf;
FCELL corrCell;
FCELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
+
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
- double indice = 0;
- double somma = 0;
- double p = 0;
- double area = 0;
- double t;
+ long totCorr = 1;
+ long area = 0;
+
avl_tree albero = NULL;
AVL_table *array;
generic_cell uc;
@@ -559,8 +565,6 @@
}
G_set_f_null_value(&precCell, 1);
-
-
for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
@@ -571,72 +575,69 @@
buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
-
- for (i = 0; i < ad->cl; i++) { /* for each fcell in the row */
-
- area++;
+ for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_f_null_value(&corrCell, 1);
- area--;
}
if (!(G_is_null_value(&corrCell, uc.t))) {
- a = 1;
- if (G_is_null_value(&precCell, uc.t)) {
- precCell = corrCell;
+ /* total patch area */
+ area++;
+ }
+
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
+
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.fc = precCell;
+ albero = avl_make(uc, totCorr);
+ if (albero == NULL) {
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
}
- if (corrCell != precCell) {
- if (albero == NULL) {
- uc.val.fc = precCell;
- albero = avl_make(uc, totCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ else {
+ uc.val.fc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- m++;
- }
- else {
- uc.val.fc = precCell;
- ris = avl_add(&albero, uc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_make unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
- } /* endif not equal fcells */
- else { /*equal fcells */
-
- totCorr++;
}
- precCell = corrCell;
- }
-
-
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
}
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
uc.val.fc = precCell;
albero = avl_make(uc, totCorr);
@@ -673,45 +674,56 @@
}
}
- array = G_malloc(m * sizeof(AVL_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avl_to_array(albero, zero, array);
- if (tot != m) {
- G_warning("avl_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
+ if (area > 0) {
+ double alpha;
+ double pi;
+ double t;
+ double sum, sum2;
- char *sval;
+ alpha = atof(par[0]);
- sval = par[0];
- double alpha_double;
+ array = G_malloc(m * sizeof(AVL_tableRow));
+ if (array == NULL) {
+ G_fatal_error("malloc array failed");
+ return RLI_ERRORE;
+ }
+ tot = avl_to_array(albero, zero, array);
+ if (tot != m) {
+ G_warning("avl_to_array unexpected value. the result could be wrong");
+ return RLI_ERRORE;
+ }
- alpha_double = (double)atof(sval);
- /* calculate index summary */
- for (i = 0; i < m; i++) {
- t = (double)(array[i]->tot);
- p = t / area;
- G_debug(1, "Valore p: %g, valore pow: %g", p, pow(p, alpha_double));
- somma = somma + pow(p, alpha_double);
- }
+ /* calculate renyi index */
+ sum = 0;
+ sum2 = 0;
+ for (i = 0; i < m; i++) {
+ t = array[i]->tot;
+ pi = t / area;
+ sum += pow(pi, alpha);
+ sum2 += pi;
+ }
+ G_free(array);
- indice = (1 / (1 - alpha_double)) * log(somma);
+ /* correction for numerical instability */
+ if (sum2 != 1)
+ sum += 1 - sum2;
- if (isnan(indice) || isinf(indice)) {
- indice = -1;
+ if ((alpha < 1 && sum < 1) || (alpha > 1 && sum > 1)) {
+ G_warning("Renyi index calculation reached numerical instability. "
+ "This can happen with alpha close to 1. The result will be set to zero.");
+ sum = 1;
+ }
+
+ *result = (1 / (1 - alpha)) * log(sum);
}
+ else
+ G_set_d_null_value(result, 1);
- G_debug(1, "Valore somma: %g Valore indice: %g", somma, indice);
-
- *result = indice;
-
- G_free(array);
- if (masked)
+ avl_destroy(albero);
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
+ }
return RLI_OK;
-
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.richness/richness.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.richness/richness.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.richness/richness.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -1,30 +1,34 @@
-
-/*
- * \brief calculates richness diversity index
+/****************************************************************************
*
- * \AUTHOR: Serena Pallecchi student of Computer Science University of Pisa (Italy)
- * Commission from Faunalia Pontedera (PI) www.faunalia.it
+ * MODULE: r.li.ritchness
*
- * This program is free software under the GPL (>=v2)
- * Read the COPYING file that comes with GRASS for details.
+ * PURPOSE: calculates richness diversity index
*
- */
+ * AUTHOR(S): Serena Pallecchi student of Computer Science University of Pisa (Italy)
+ * Commission from Faunalia Pontedera (PI) www.faunalia.it
+ * Rewrite: Markus Metz
+ *
+ * COPYRIGHT:
+ * This program is free software under the GPL (>=v2)
+ * Read the COPYING file that comes with GRASS for details.
+ *
+ ***************************************************************************/
-#include <grass/gis.h>
-#include <grass/glocale.h>
-
#include <stdlib.h>
#include <fcntl.h>
#include <math.h>
-#include "../r.li.daemon/defs.h"
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#include "../r.li.daemon/daemon.h"
#include "../r.li.daemon/avlDefs.h"
#include "../r.li.daemon/avl.h"
-#include "../r.li.daemon/daemon.h"
-double calculate(struct area_entry *ad, int fd, double *result);
-double calculateD(struct area_entry *ad, int fd, double *result);
-double calculateF(struct area_entry *ad, int fd, double *result);
+rli_func richness;
+int calculate(int fd, struct area_entry *ad, double *result);
+int calculateD(int fd, struct area_entry *ad, double *result);
+int calculateF(int fd, struct area_entry *ad, double *result);
int main(int argc, char *argv[])
{
@@ -34,9 +38,9 @@
G_gisinit(argv[0]);
module = G_define_module();
module->description =
- _("Calculates dominance's diversity index on a raster map");
+ _("Calculates richness index on a raster map");
module->keywords =
- _("raster, landscape structure analysis, dominance index");
+ _("raster, landscape structure analysis, diversity index");
/* define options */
@@ -52,36 +56,29 @@
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
- return calculateIndex(conf->answer, dominance, NULL, raster->answer,
+ return calculateIndex(conf->answer, richness, NULL, raster->answer,
output->answer);
-
}
-int dominance(int fd, char **par, struct area_entry *ad, double *result)
+int richness(int fd, char **par, struct area_entry *ad, double *result)
{
- char *mapset;
int ris = RLI_OK;
double indice = 0;
- struct Cell_head hd;
- mapset = G_find_cell(ad->raster, "");
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
- return RLI_ERRORE;
-
switch (ad->data_type) {
case CELL_TYPE:
{
- ris = calculate(ad, fd, &indice);
+ ris = calculate(fd, ad, &indice);
break;
}
case DCELL_TYPE:
{
- ris = calculateD(ad, fd, &indice);
+ ris = calculateD(fd, ad, &indice);
break;
}
case FCELL_TYPE:
{
- ris = calculateF(ad, fd, &indice);
+ ris = calculateF(fd, ad, &indice);
break;
}
default:
@@ -89,33 +86,30 @@
G_fatal_error("data type unknown");
return RLI_ERRORE;
}
-
}
- if (ris != RLI_OK)
+ if (ris != RLI_OK) {
return RLI_ERRORE;
+ }
*result = indice;
return RLI_OK;
-
}
-
-double calculate(struct area_entry *ad, int fd, double *result)
+int calculate(int fd, struct area_entry *ad, double *result)
{
CELL *buf;
CELL corrCell;
CELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
long m = 0;
- double indice = 0;
+ long area = 0;
avl_tree albero = NULL;
generic_cell uc;
@@ -134,8 +128,6 @@
}
G_set_c_null_value(&precCell, 1);
-
-
for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
@@ -145,67 +137,62 @@
}
buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
+
for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
corrCell = buf[i + ad->x];
- if ((masked) && (mask_buf[i + ad->x] == 0)) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_c_null_value(&corrCell, 1);
}
+ else {
+ /* total sample area */
+ area++;
+ }
- if (!(G_is_null_value(&corrCell, uc.t))) {
- a = 1;
- if (G_is_null_value(&precCell, uc.t)) {
- precCell = corrCell;
- }
- if (corrCell != precCell) {
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ if (albero == NULL) {
+ uc.val.c = precCell;
+ albero = avl_make(uc, (long)1);
if (albero == NULL) {
- uc.val.c = precCell;
- albero = avl_make(uc, (long)1);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.c = precCell;
+ ris = avl_add(&albero, uc, (long)1);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- else
+ case AVL_ADD:
+ {
m++;
- }
- else {
- uc.val.c = precCell;
- ris = avl_add(&albero, uc, (long)1);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_make unknown error");
- return RLI_ERRORE;
- }
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- } /* endif not equal cells */
- else { /*equal cells */
-
- ;
}
- precCell = corrCell;
- }
-
+ } /* endif not equal cells */
+ precCell = corrCell;
}
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (!(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
uc.val.c = precCell;
albero = avl_make(uc, (long)1);
@@ -242,36 +229,34 @@
}
}
- if (a != 0) {
- indice = m;
- }
- else /*if a is 0, that is all cell are null, i put index=-1 */
- indice = (double)(-1);
+ if (area)
+ *result = m;
+ else
+ G_set_d_null_value(result, 1);
- if (masked)
+ avl_destroy(albero);
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
+ }
- *result = indice;
-
return RLI_OK;
}
-double calculateD(struct area_entry *ad, int fd, double *result)
+int calculateD(int fd, struct area_entry *ad, double *result)
{
DCELL *buf;
DCELL corrCell;
DCELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
long m = 0;
- double indice = 0;
+ long area = 0;
avl_tree albero = NULL;
-
generic_cell uc;
uc.t = DCELL_TYPE;
@@ -282,14 +267,13 @@
return RLI_ERRORE;
mask_buf = G_malloc(ad->cl * sizeof(int));
if (mask_buf == NULL) {
- G_fatal_error("malloc mask_buffailed");
+ G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
masked = TRUE;
}
G_set_d_null_value(&precCell, 1);
-
for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
@@ -303,66 +287,58 @@
for (i = 0; i < ad->cl; i++) { /* for each dcell in the row */
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_d_null_value(&corrCell, 1);
}
+ else {
+ /* total sample area */
+ area++;
+ }
- if (!(G_is_null_value(&corrCell, uc.t))) {
- a = 1;
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
- if (G_is_null_value(&precCell, uc.t)) {
- precCell = corrCell;
- }
- if (corrCell != precCell) {
+ if (albero == NULL) {
+ uc.val.dc = precCell;
+ albero = avl_make(uc, (long)1);
if (albero == NULL) {
- uc.val.dc = precCell;
- albero = avl_make(uc, (long)1);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.dc = precCell;
+ ris = avl_add(&albero, uc, (long)1);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- m++;
- }
- else {
- uc.val.dc = precCell;
- ris = avl_add(&albero, uc, (long)1);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_make unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
-
- } /* endif not equal dcells */
- else { /*equal dcells */
-
- ;
}
- precCell = corrCell;
- }
-
-
+ } /* endif not equal dcells */
+ precCell = corrCell;
}
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (!(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
uc.val.dc = precCell;
albero = avl_make(uc, (long)1);
@@ -399,41 +375,34 @@
}
}
-
- if (a != 0) { /*if a is 0, that is all cell are null, i put index=-1 */
- indice = m;
- }
+ if (area)
+ *result = m;
else
- indice = (double)(-1);
+ G_set_d_null_value(result, 1);
-
- if (masked)
+ avl_destroy(albero);
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
+ }
- *result = indice;
return RLI_OK;
}
-
-double calculateF(struct area_entry *ad, int fd, double *result)
+int calculateF(int fd, struct area_entry *ad, double *result)
{
FCELL *buf;
FCELL corrCell;
FCELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
-
long m = 0;
-
- double indice = 0;
-
+ long area = 0;
avl_tree albero = NULL;
-
generic_cell uc;
uc.t = FCELL_TYPE;
@@ -451,8 +420,6 @@
}
G_set_f_null_value(&precCell, 1);
-
-
for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
@@ -463,70 +430,63 @@
buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
-
for (i = 0; i < ad->cl; i++) { /* for each fcell in the row */
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_f_null_value(&corrCell, 1);
}
+ else {
+ /* total sample area */
+ area++;
+ }
- if (!(G_is_null_value(&corrCell, uc.t))) {
- a = 1;
- if (G_is_null_value(&precCell, uc.t)) {
- precCell = corrCell;
- }
- if (corrCell != precCell) {
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ if (albero == NULL) {
+ uc.val.fc = precCell;
+ albero = avl_make(uc, (long)1);
if (albero == NULL) {
- uc.val.fc = precCell;
- albero = avl_make(uc, (long)1);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.fc = precCell;
+ ris = avl_add(&albero, uc, (long)1);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- m++;
- }
- else {
- uc.val.fc = precCell;
- ris = avl_add(&albero, uc, (long)1);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_make unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
-
- } /* endif not equal fcells */
- else { /*equal fcells */
-
- ;
}
- precCell = corrCell;
- }
-
+ } /* endif not equal fcells */
+ precCell = corrCell;
}
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (!(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
uc.val.fc = precCell;
albero = avl_make(uc, (long)1);
@@ -563,19 +523,16 @@
}
}
-
-
- if (a != 0) { /*if a is 0, that is all cell are null, i put index=-1 */
- indice = m;
- }
+ if (area)
+ *result = m;
else
- indice = (double)(-1);
+ G_set_d_null_value(result, 1);
-
- if (masked)
+ avl_destroy(albero);
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
+ }
-
- *result = indice;
return RLI_OK;
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.shannon/shannon.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.shannon/shannon.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.shannon/shannon.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -4,6 +4,7 @@
* AUTHOR(S): Serena Pallecchi (original contributor)
* student of Computer Science University of Pisa (Italy)
* Commission from Faunalia Pontedera (PI) www.faunalia.it
+ * Rewrite: Markus Metz
*
* PURPOSE: calculates Shannon's diversity index
* COPYRIGHT: (C) 2007-2014 by the GRASS Development Team
@@ -14,20 +15,20 @@
*
*****************************************************************************/
-#include <grass/gis.h>
-#include <grass/glocale.h>
-
#include <stdlib.h>
#include <fcntl.h>
#include <math.h>
-#include "../r.li.daemon/defs.h"
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#include "../r.li.daemon/daemon.h"
#include "../r.li.daemon/avlDefs.h"
#include "../r.li.daemon/avl.h"
-#include "../r.li.daemon/daemon.h"
/* template for dominance, renyi, pielou, simpson */
+rli_func shannon;
int calculate(int fd, struct area_entry *ad, double *result);
int calculateD(int fd, struct area_entry *ad, double *result);
int calculateF(int fd, struct area_entry *ad, double *result);
@@ -63,7 +64,7 @@
}
-int shannon(int fd, char **par, struct area_entry * ad, double *result)
+int shannon(int fd, char **par, struct area_entry *ad, double *result)
{
char *mapset;
int ris = RLI_OK;
@@ -78,17 +79,17 @@
switch (ad->data_type) {
case CELL_TYPE:
{
- calculate(fd, ad, &indice);
+ ris = calculate(fd, ad, &indice);
break;
}
case DCELL_TYPE:
{
- calculateD(fd, ad, &indice);
+ ris = calculateD(fd, ad, &indice);
break;
}
case FCELL_TYPE:
{
- calculateF(fd, ad, &indice);
+ ris = calculateF(fd, ad, &indice);
break;
}
default:
@@ -115,29 +116,22 @@
CELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
+ long totCorr = 1;
- double indice = 0;
- double somma = 0;
- double percentuale = 0;
- double area = 0;
- double t;
- double logaritmo;
+ long area = 0;
- generic_cell cc;
-
avl_tree albero = NULL;
AVL_table *array;
+ generic_cell uc;
- cc.t = CELL_TYPE;
+ uc.t = CELL_TYPE;
/* open mask if needed */
if (ad->mask == 1) {
@@ -151,15 +145,8 @@
masked = TRUE;
}
-
G_set_c_null_value(&precCell, 1);
-
-
- /*for each row */
- for (j = 0; j < ad->rl; j++) {
- buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
-
-
+ for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
G_fatal_error("mask read failed");
@@ -167,76 +154,74 @@
}
}
+ buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
- area++;
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_c_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, CELL_TYPE))) {
- a = 1;
- if (G_is_null_value(&precCell, cc.t)) {
- precCell = corrCell;
- }
+ if (!(G_is_null_value(&corrCell, uc.t))) {
+ /* total patch area */
+ area++;
+ }
- if (corrCell != precCell) {
- if (albero == NULL) {
- cc.val.c = precCell;
- albero = avl_make(cc, totCorr);
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.c = precCell;
+ albero = avl_make(uc, totCorr);
+ if (albero == NULL) {
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.c = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- m++;
- }
- else {
- cc.val.c = precCell;
- ris = avl_add(&albero, cc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_add unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
}
- else {
- totCorr++;
- }
- precCell = corrCell;
- }
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
+ }
+ }
- } /* end for */
- } /* end for */
-
-
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
- cc.val.c = precCell;
- albero = avl_make(cc, totCorr);
-
+ uc.val.c = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
G_fatal_error("avl_make error");
return RLI_ERRORE;
@@ -244,8 +229,8 @@
m++;
}
else {
- cc.val.c = precCell;
- ris = avl_add(&albero, cc, totCorr);
+ uc.val.c = precCell;
+ ris = avl_add(&albero, uc, totCorr);
switch (ris) {
case AVL_ERR:
{
@@ -270,37 +255,40 @@
}
}
- array = G_malloc(m * sizeof(AVL_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avl_to_array(albero, zero, array);
+ if (area > 0) {
+ double t;
+ double shannon;
+ double perc, logarithm;
- if (tot != m) {
- G_warning("avl_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
+ array = G_malloc(m * sizeof(AVL_tableRow));
+ if (array == NULL) {
+ G_fatal_error("malloc array failed");
+ return RLI_ERRORE;
+ }
+ tot = avl_to_array(albero, zero, array);
+ if (tot != m) {
+ G_warning("avl_to_array unexpected value. the result could be wrong");
+ return RLI_ERRORE;
+ }
- /* calculate summary */
- for (i = 0; i < m; i++) {
- t = (double)array[i]->tot;
- percentuale = (double)(t / area);
- logaritmo = (double)log(percentuale);
- somma = somma + (percentuale * logaritmo);
- }
+ /* calculate shannon */
+ shannon = 0;
+ for (i = 0; i < m; i++) {
+ t = array[i]->tot;
+ perc = t / area;
+ logarithm = log(perc);
+ shannon += perc * logarithm;
+ }
+ G_free(array);
-
- /*if a is 0, that is all cell are null, i put index=-1 */
- if (a != 0)
- indice = (-1) * somma;
+ *result = -shannon;
+ }
else
- indice = (double)(-1);
+ G_set_d_null_value(result, 1);
- *result = indice;
-
- G_free(array);
+ avl_destroy(albero);
if (masked) {
+ close(mask_fd);
G_free(mask_buf);
}
@@ -308,40 +296,30 @@
}
-
int calculateD(int fd, struct area_entry *ad, double *result)
{
-
DCELL *buf;
DCELL corrCell;
DCELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
+ long totCorr = 1;
- double indice = 0;
- double somma = 0;
- double percentuale = 0;
- double area = 0;
- double t;
- double logaritmo;
+ long area = 0;
avl_tree albero = NULL;
-
AVL_table *array;
+ generic_cell uc;
- generic_cell cc;
+ uc.t = DCELL_TYPE;
- cc.t = DCELL_TYPE;
-
/* open mask if needed */
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
@@ -354,14 +332,8 @@
masked = TRUE;
}
-
G_set_d_null_value(&precCell, 1);
-
- /*for each row */
- for (j = 0; j < ad->rl; j++) {
- buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
-
-
+ for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
G_fatal_error("mask read failed");
@@ -369,76 +341,74 @@
}
}
+ buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
- for (i = 0; i < ad->cl; i++) { /* for each dcell in the row */
- area++;
+ for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_d_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, DCELL_TYPE))) {
- a = 1;
- if (G_is_null_value(&precCell, DCELL_TYPE)) {
- precCell = corrCell;
- }
- if (corrCell != precCell) {
+ if (!(G_is_null_value(&corrCell, uc.t))) {
+ /* total patch area */
+ area++;
+ }
+
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
+
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.dc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
- cc.val.dc = precCell;
- albero = avl_make(cc, totCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.dc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- m++;
- }
- else {
- cc.val.dc = precCell;
- ris = avl_add(&albero, cc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_add unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
}
- else {
- totCorr++;
- }
- precCell = corrCell;
- }
-
- } /*close for */
- } /*close for */
-
- if (masked) {
- G_free(mask_buf);
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
+ }
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
- cc.val.dc = precCell;
- albero = avl_make(cc, totCorr);
+ uc.val.dc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
G_fatal_error("avl_make error");
return RLI_ERRORE;
@@ -446,8 +416,8 @@
m++;
}
else {
- cc.val.fc = precCell;
- ris = avl_add(&albero, cc, totCorr);
+ uc.val.dc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
switch (ris) {
case AVL_ERR:
{
@@ -470,7 +440,12 @@
}
}
}
+ }
+ if (area > 0) {
+ double t;
+ double shannon;
+ double perc, logarithm;
array = G_malloc(m * sizeof(AVL_tableRow));
if (array == NULL) {
@@ -478,73 +453,60 @@
return RLI_ERRORE;
}
tot = avl_to_array(albero, zero, array);
-
if (tot != m) {
- G_warning
- ("avl_to_array unaspected value. the result could be wrong");
+ G_warning("avl_to_array unexpected value. the result could be wrong");
return RLI_ERRORE;
}
- /* calculate summary */
+ /* calculate shannon */
+ shannon = 0;
for (i = 0; i < m; i++) {
- t = (double)array[i]->tot;
- percentuale = (double)(t / area);
- logaritmo = (double)log(percentuale);
- somma = somma + (percentuale * logaritmo);
+ t = array[i]->tot;
+ perc = t / area;
+ logarithm = log(perc);
+ shannon += perc * logarithm;
}
-
G_free(array);
-
- indice = (-1) * somma;
+ *result = -shannon;
}
else
- /*if a is 0, that is all cell are null, i put index=-1 */
- indice = (double)(-1);
+ G_set_d_null_value(result, 1);
+ avl_destroy(albero);
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
+ }
- *result = indice;
-
-
-
-
return RLI_OK;
}
int calculateF(int fd, struct area_entry *ad, double *result)
{
-
FCELL *buf;
FCELL corrCell;
FCELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
+ long totCorr = 1;
- double indice = 0;
- double somma = 0;
- double percentuale = 0;
- double area = 0;
- double t;
- double logaritmo;
+ long area = 0;
avl_tree albero = NULL;
-
AVL_table *array;
+ generic_cell uc;
- generic_cell cc;
+ uc.t = FCELL_TYPE;
- cc.t = FCELL_TYPE;
-
/* open mask if needed */
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
@@ -557,15 +519,8 @@
masked = TRUE;
}
-
G_set_f_null_value(&precCell, 1);
-
-
- /*for each row */
- for (j = 0; j < ad->rl; j++) {
- buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
-
-
+ for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
G_fatal_error("mask read failed");
@@ -573,73 +528,74 @@
}
}
+ buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
- for (i = 0; i < ad->cl; i++) { /* for each fcell in the row */
- area++;
+ for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_f_null_value(&corrCell, 1);
- area--;
}
- if (!(G_is_null_value(&corrCell, FCELL_TYPE))) {
- a = 1;
- if (G_is_null_value(&precCell, FCELL_TYPE)) {
- precCell = corrCell;
- }
- if (corrCell != precCell) {
+ if (!(G_is_null_value(&corrCell, uc.t))) {
+ /* total patch area */
+ area++;
+ }
+
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
+
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.fc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
- cc.val.fc = precCell;
- albero = avl_make(cc, totCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.fc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- m++;
- }
- else {
- cc.val.fc = precCell;
- ris = avl_add(&albero, cc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_add unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
}
- else {
- totCorr++;
- }
-
- precCell = corrCell;
- }
-
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
}
}
-
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
- cc.val.fc = precCell;
- albero = avl_make(cc, totCorr);
+ uc.val.fc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
G_fatal_error("avl_make error");
return RLI_ERRORE;
@@ -647,8 +603,8 @@
m++;
}
else {
- cc.val.fc = precCell;
- ris = avl_add(&albero, cc, totCorr);
+ uc.val.fc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
switch (ris) {
case AVL_ERR:
{
@@ -673,39 +629,42 @@
}
}
- array = G_malloc(m * sizeof(AVL_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avl_to_array(albero, zero, array);
+ if (area > 0) {
+ double t;
+ double shannon;
+ double perc, logarithm;
- if (tot != m) {
- G_warning("avl_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
+ array = G_malloc(m * sizeof(AVL_tableRow));
+ if (array == NULL) {
+ G_fatal_error("malloc array failed");
+ return RLI_ERRORE;
+ }
+ tot = avl_to_array(albero, zero, array);
+ if (tot != m) {
+ G_warning("avl_to_array unexpected value. the result could be wrong");
+ return RLI_ERRORE;
+ }
- /* calculate summary */
- for (i = 0; i < m; i++) {
- t = (double)array[i]->tot;
- percentuale = (double)(t / area);
- logaritmo = (double)log(percentuale);
- somma = somma + (percentuale * logaritmo);
- }
+ /* calculate shannon */
+ shannon = 0;
+ for (i = 0; i < m; i++) {
+ t = array[i]->tot;
+ perc = t / area;
+ logarithm = log(perc);
+ shannon += perc * logarithm;
+ }
+ G_free(array);
- /*if a is 0, that is all cell are null, i put index=-1 */
- if (a != 0)
- indice = (-1) * somma;
+ *result = -shannon;
+ }
else
- indice = (double)(-1);
+ G_set_d_null_value(result, 1);
-
- *result = indice;
-
-
- G_free(array);
+ avl_destroy(albero);
if (masked) {
+ close(mask_fd);
G_free(mask_buf);
}
+
return RLI_OK;
}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.shape/main.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.shape/main.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.shape/main.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -6,10 +6,11 @@
* students of Computer Science University of Pisa (Italy)
* Commission from Faunalia Pontedera (PI) www.faunalia.it
* Fixes: Markus Neteler <neteler itc.it>
- *
- * PURPOSE: calculates shape index
- * COPYRIGHT: (C) 2006-2007 by the GRASS Development Team
+ * Rewrite: Markus Metz
*
+ * PURPOSE: calculates patch number index
+ * COPYRIGHT: (C) 2007-2014 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.
@@ -18,10 +19,26 @@
#include <stdlib.h>
#include <fcntl.h>
+#include <math.h>
#include <grass/gis.h>
+#include <grass/raster.h>
#include <grass/glocale.h>
#include "../r.li.daemon/daemon.h"
+#include "../r.li.daemon/GenericCell.h"
+
+/* type, cell count and edge count of each patch */
+struct pst {
+ generic_cell type;
+ long cells;
+ long edges;
+};
+
+rli_func shape_index;
+int calculate(int fd, struct area_entry *ad, double *result);
+int calculateD(int fd, struct area_entry *ad, double *result);
+int calculateF(int fd, struct area_entry *ad, double *result);
+
int main(int argc, char *argv[])
{
struct Option *raster, *conf, *output;
@@ -54,55 +71,754 @@
int shape_index(int fd, char **par, struct area_entry *ad, double *result)
{
- double area;
- char *mapset;
- struct Cell_head hd;
- CELL complete_value;
- double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
- int mask_fd = -1, null_count = 0;
- int i = 0, k = 0;
- int *mask_buf;
+ int ris = RLI_OK;
+ double indice = 0;
- G_set_c_null_value(&complete_value, 1);
+ switch (ad->data_type) {
+ case CELL_TYPE:
+ {
+ ris = calculate(fd, ad, &indice);
+ break;
+ }
+ case DCELL_TYPE:
+ {
+ ris = calculateD(fd, ad, &indice);
+ break;
+ }
+ case FCELL_TYPE:
+ {
+ ris = calculateF(fd, ad, &indice);
+ break;
+ }
+ default:
+ {
+ G_fatal_error("data type unknown");
+ return RLI_ERRORE;
+ }
+ }
- mapset = G_find_cell(ad->raster, "");
- if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
- return 0;
+ if (ris != RLI_OK) {
+ return RLI_ERRORE;
+ }
+ *result = indice;
+ return RLI_OK;
+}
+
+
+int calculate(int fd, struct area_entry *ad, double *result)
+{
+ CELL *buf, *buf_sup, *buf_null;
+ CELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+
+ buf_null = G_allocate_cell_buf();
+ G_set_c_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(ad->cl * sizeof(long));
+ pid_sup = G_malloc(ad->cl * sizeof(long));
+
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
/* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
if (ad->mask == 1) {
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
- return 0;
- mask_buf = malloc(ad->cl * sizeof(int));
- for (i = 0; i < ad->rl; i++) {
+ return RLI_ERRORE;
+ mask_buf = G_malloc(ad->cl * sizeof(int));
+ if (mask_buf == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
+ masked = TRUE;
+ }
+
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
+
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].cells = 0;
+ pst[k].edges = 0;
+ }
+
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_cell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad);
+ }
+
+ if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
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) {
- null_count++;
+ }
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
+ G_set_c_null_value(&precCell, 1);
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
+ G_set_c_null_value(&corrCell, 1);
+ }
+ else {
+ /* total sample area */
+ area++;
+ }
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_c_null_value(&supCell, 1);
+ }
+
+ if (G_is_c_null_value(&corrCell)) {
+ if (!G_is_c_null_value(&precCell))
+ pst[pid_corr[j - 1]].edges++;
+ if (!G_is_c_null_value(&supCell))
+ pst[pid_sup[j]].edges++;
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ if (!G_is_c_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j] = pid_corr[j - 1];
+ connected = 1;
+ pst[pid_corr[j]].cells++;
+ }
+ else {
+ connected = 0;
+ }
+
+ if (!G_is_c_null_value(&supCell) && corrCell == supCell) {
+
+ if (pid_corr[j] != pid_sup[j]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
+
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
+ }
+ }
+
+ old_pid = pid_corr[j];
+ new_pid = pid_sup[j];
+ pid_corr[j] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k] == old_pid)
+ pid_corr[k] = new_pid;
+ }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k] == old_pid)
+ pid_sup[k] = new_pid;
+ }
+ pst[new_pid].cells += pst[old_pid].cells;
+ pst[old_pid].cells = 0;
+ pst[new_pid].edges += pst[old_pid].edges;
+ pst[old_pid].edges = 0;
+
+ if (old_pid == pid)
+ pid--;
+ }
+ else {
+ pst[new_pid].cells++;
+ }
}
+ connected = 1;
}
+
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j] = pid;
+
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
+
+ for (k = nalloc; k < pid + incr; k++) {
+ pst[k].cells = 0;
+ pst[k].edges = 0;
+ }
+
+ nalloc = pid + incr;
+ }
+
+ pst[pid].cells = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
+ }
+ /* update edge count for corr */
+ if (G_is_c_null_value(&precCell) || precCell != corrCell)
+ pst[pid_corr[j]].edges++;
+ if (G_is_c_null_value(&supCell) || supCell != corrCell)
+ pst[pid_corr[j]].edges++;
+ if (i == ad->rl - 1)
+ pst[pid_corr[j]].edges++;
+ if (j == ad->cl - 1)
+ pst[pid_corr[j]].edges++;
+ /* update edge count for prec */
+ if (!G_is_c_null_value(&precCell) && precCell != corrCell)
+ pst[pid_corr[j - 1]].edges++;
+ /* update edge count for sup */
+ if (!G_is_c_null_value(&supCell) && supCell != corrCell)
+ pst[pid_sup[j]].edges++;
+
+ precCell = corrCell;
}
- /* todo? free(mask_buf); */
}
- /* calculate distance */
- G_begin_distance_calculations();
- /* EW Dist at North edge */
- EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
- /* EW Dist at South Edge */
- EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
- /* NS Dist at East edge */
- NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
- /* NS Dist at West edge */
- NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
+ if (npatch > 0) {
+ double edges, cells;
- area = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
- (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) *
- (ad->rl * ad->cl - null_count);
+ edges = cells = 0;
+
+ for (i = 1; i <= pid; i++) {
+ cells += pst[i].cells;
+ edges += pst[i].edges;
+ }
- *result = area;
+ *result = 0.25 * edges / sqrt(cells);
+ }
+ else {
+ G_set_d_null_value(result, 1);
+ }
- return 1;
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
+
+ return RLI_OK;
}
+
+
+int calculateD(int fd, struct area_entry *ad, double *result)
+{
+ DCELL *buf, *buf_sup, *buf_null;
+ DCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+
+ buf_null = G_allocate_d_raster_buf();
+ G_set_d_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(ad->cl * sizeof(long));
+ pid_sup = G_malloc(ad->cl * sizeof(long));
+
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
+ /* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
+ if (ad->mask == 1) {
+ if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
+ return RLI_ERRORE;
+ mask_buf = G_malloc(ad->cl * sizeof(int));
+ if (mask_buf == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
+ masked = TRUE;
+ }
+
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
+
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].cells = 0;
+ pst[k].edges = 0;
+ }
+
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_dcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_dcell_raster_row(fd, i - 1 + ad->y, ad);
+ }
+
+ if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
+ }
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
+ G_set_d_null_value(&precCell, 1);
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
+ G_set_d_null_value(&corrCell, 1);
+ }
+ else {
+ /* total sample area */
+ area++;
+ }
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_d_null_value(&supCell, 1);
+ }
+
+ if (G_is_d_null_value(&corrCell)) {
+ if (!G_is_d_null_value(&precCell))
+ pst[pid_corr[j - 1]].edges++;
+ if (!G_is_d_null_value(&supCell))
+ pst[pid_sup[j]].edges++;
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ if (!G_is_d_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j] = pid_corr[j - 1];
+ connected = 1;
+ pst[pid_corr[j]].cells++;
+ }
+ else {
+ connected = 0;
+ }
+
+ if (!G_is_d_null_value(&supCell) && corrCell == supCell) {
+
+ if (pid_corr[j] != pid_sup[j]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
+
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
+ }
+ }
+
+ old_pid = pid_corr[j];
+ new_pid = pid_sup[j];
+ pid_corr[j] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k] == old_pid)
+ pid_corr[k] = new_pid;
+ }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k] == old_pid)
+ pid_sup[k] = new_pid;
+ }
+ pst[new_pid].cells += pst[old_pid].cells;
+ pst[old_pid].cells = 0;
+ pst[new_pid].edges += pst[old_pid].edges;
+ pst[old_pid].edges = 0;
+
+ if (old_pid == pid)
+ pid--;
+ }
+ else {
+ pst[new_pid].cells++;
+ }
+ }
+ connected = 1;
+ }
+
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j] = pid;
+
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
+
+ for (k = nalloc; k < pid + incr; k++) {
+ pst[k].cells = 0;
+ pst[k].edges = 0;
+ }
+
+ nalloc = pid + incr;
+ }
+
+ pst[pid].cells = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
+ }
+ /* update edge count for corr */
+ if (G_is_d_null_value(&precCell) || precCell != corrCell)
+ pst[pid_corr[j]].edges++;
+ if (G_is_d_null_value(&supCell) || supCell != corrCell)
+ pst[pid_corr[j]].edges++;
+ if (i == ad->rl - 1)
+ pst[pid_corr[j]].edges++;
+ if (j == ad->cl - 1)
+ pst[pid_corr[j]].edges++;
+ /* update edge count for prec */
+ if (!G_is_d_null_value(&precCell) && precCell != corrCell)
+ pst[pid_corr[j - 1]].edges++;
+ /* update edge count for sup */
+ if (!G_is_d_null_value(&supCell) && supCell != corrCell)
+ pst[pid_sup[j]].edges++;
+
+ precCell = corrCell;
+ }
+ }
+
+ if (npatch > 0) {
+ double edges, cells;
+
+ edges = cells = 0;
+
+ for (i = 1; i <= pid; i++) {
+ cells += pst[i].cells;
+ edges += pst[i].edges;
+ }
+
+ *result = 0.25 * edges / sqrt(cells);
+ }
+ else {
+ G_set_d_null_value(result, 1);
+ }
+
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
+
+ return RLI_OK;
+}
+
+
+int calculateF(int fd, struct area_entry *ad, double *result)
+{
+ FCELL *buf, *buf_sup, *buf_null;
+ FCELL corrCell, precCell, supCell;
+ long npatch, area;
+ long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
+ struct pst *pst;
+ long nalloc, incr;
+ int i, j, k;
+ int connected;
+ int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
+
+ buf_null = G_allocate_f_raster_buf();
+ G_set_f_null_value(buf_null, G_window_cols());
+ buf_sup = buf_null;
+
+ /* initialize patch ids */
+ pid_corr = G_malloc(ad->cl * sizeof(long));
+ pid_sup = G_malloc(ad->cl * sizeof(long));
+
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+ pid_sup[j] = 0;
+ }
+
+ /* open mask if needed */
+ mask_fd = -1;
+ mask_buf = mask_sup = NULL;
+ masked = FALSE;
+ if (ad->mask == 1) {
+ if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
+ return RLI_ERRORE;
+ mask_buf = G_malloc(ad->cl * sizeof(int));
+ if (mask_buf == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ mask_sup = G_malloc(ad->cl * sizeof(int));
+ if (mask_sup == NULL) {
+ G_fatal_error("malloc mask_buf failed");
+ return RLI_ERRORE;
+ }
+ for (j = 0; j < ad->cl; j++)
+ mask_buf[j] = 0;
+
+ masked = TRUE;
+ }
+
+ /* calculate number of patches */
+ npatch = 0;
+ area = 0;
+ pid = 0;
+
+ /* patch size and type */
+ incr = 1024;
+ if (incr > ad->rl)
+ incr = ad->rl;
+ if (incr > ad->cl)
+ incr = ad->cl;
+ if (incr < 2)
+ incr = 2;
+ nalloc = incr;
+ pst = G_malloc(nalloc * sizeof(struct pst));
+ for (k = 0; k < nalloc; k++) {
+ pst[k].cells = 0;
+ pst[k].edges = 0;
+ }
+
+ for (i = 0; i < ad->rl; i++) {
+ buf = RLI_get_fcell_raster_row(fd, i + ad->y, ad);
+ if (i > 0) {
+ buf_sup = RLI_get_fcell_raster_row(fd, i - 1 + ad->y, ad);
+ }
+
+ if (masked) {
+ mask_tmp = mask_sup;
+ mask_sup = mask_buf;
+ mask_buf = mask_tmp;
+ if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
+ return 0;
+ }
+
+ ltmp = pid_sup;
+ pid_sup = pid_corr;
+ pid_corr = ltmp;
+
+ G_set_f_null_value(&precCell, 1);
+
+ connected = 0;
+ for (j = 0; j < ad->cl; j++) {
+ pid_corr[j] = 0;
+
+ corrCell = buf[j + ad->x];
+ if (masked && (mask_buf[j] == 0)) {
+ G_set_f_null_value(&corrCell, 1);
+ }
+ else {
+ /* total sample area */
+ area++;
+ }
+
+ supCell = buf_sup[j + ad->x];
+ if (masked && (mask_sup[j] == 0)) {
+ G_set_f_null_value(&supCell, 1);
+ }
+
+ if (G_is_f_null_value(&corrCell)) {
+ if (!G_is_f_null_value(&precCell))
+ pst[pid_corr[j - 1]].edges++;
+ if (!G_is_f_null_value(&supCell))
+ pst[pid_sup[j]].edges++;
+ connected = 0;
+ precCell = corrCell;
+ continue;
+ }
+
+ if (!G_is_f_null_value(&precCell) && corrCell == precCell) {
+ pid_corr[j] = pid_corr[j - 1];
+ connected = 1;
+ pst[pid_corr[j]].cells++;
+ }
+ else {
+ connected = 0;
+ }
+
+ if (!G_is_f_null_value(&supCell) && corrCell == supCell) {
+
+ if (pid_corr[j] != pid_sup[j]) {
+ /* connect or merge */
+ /* after r.clump */
+ if (connected) {
+ npatch--;
+
+ if (npatch == 0) {
+ G_fatal_error("npatch == 0 at row %d, col %d", i, j);
+ }
+ }
+
+ old_pid = pid_corr[j];
+ new_pid = pid_sup[j];
+ pid_corr[j] = new_pid;
+ if (old_pid > 0) {
+ /* merge */
+ /* update left side of the current row */
+ for (k = 0; k < j; k++) {
+ if (pid_corr[k] == old_pid)
+ pid_corr[k] = new_pid;
+ }
+ /* update right side of the previous row */
+ for (k = j + 1; k < ad->cl; k++) {
+ if (pid_sup[k] == old_pid)
+ pid_sup[k] = new_pid;
+ }
+ pst[new_pid].cells += pst[old_pid].cells;
+ pst[old_pid].cells = 0;
+ pst[new_pid].edges += pst[old_pid].edges;
+ pst[old_pid].edges = 0;
+
+ if (old_pid == pid)
+ pid--;
+ }
+ else {
+ pst[new_pid].cells++;
+ }
+ }
+ connected = 1;
+ }
+
+ if (!connected) {
+ /* start new patch */
+ npatch++;
+ pid++;
+ pid_corr[j] = pid;
+
+ if (pid >= nalloc) {
+ pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
+
+ for (k = nalloc; k < pid + incr; k++) {
+ pst[k].cells = 0;
+ pst[k].edges = 0;
+ }
+
+ nalloc = pid + incr;
+ }
+
+ pst[pid].cells = 1;
+ pst[pid].type.t = CELL_TYPE;
+ pst[pid].type.val.c = corrCell;
+ }
+ /* update edge count for corr */
+ if (G_is_f_null_value(&precCell) || precCell != corrCell)
+ pst[pid_corr[j]].edges++;
+ if (G_is_f_null_value(&supCell) || supCell != corrCell)
+ pst[pid_corr[j]].edges++;
+ if (i == ad->rl - 1)
+ pst[pid_corr[j]].edges++;
+ if (j == ad->cl - 1)
+ pst[pid_corr[j]].edges++;
+ /* update edge count for prec */
+ if (!G_is_f_null_value(&precCell) && precCell != corrCell)
+ pst[pid_corr[j - 1]].edges++;
+ /* update edge count for sup */
+ if (!G_is_f_null_value(&supCell) && supCell != corrCell)
+ pst[pid_sup[j]].edges++;
+
+ precCell = corrCell;
+ }
+ }
+
+ if (npatch > 0) {
+ double edges, cells;
+
+ edges = cells = 0;
+
+ for (i = 1; i <= pid; i++) {
+ cells += pst[i].cells;
+ edges += pst[i].edges;
+ }
+
+ *result = 0.25 * edges / sqrt(cells);
+ }
+ else {
+ G_set_d_null_value(result, 1);
+ }
+
+ if (masked) {
+ close(mask_fd);
+ G_free(mask_buf);
+ G_free(mask_sup);
+ }
+ G_free(buf_null);
+ G_free(pid_corr);
+ G_free(pid_sup);
+ G_free(pst);
+
+ return RLI_OK;
+}
Modified: grass/branches/releasebranch_6_4/raster/r.li/r.li.simpson/simpson.c
===================================================================
--- grass/branches/releasebranch_6_4/raster/r.li/r.li.simpson/simpson.c 2014-03-24 11:40:14 UTC (rev 59304)
+++ grass/branches/releasebranch_6_4/raster/r.li/r.li.simpson/simpson.c 2014-03-24 11:43:14 UTC (rev 59305)
@@ -22,16 +22,16 @@
#include <grass/gis.h>
#include <grass/glocale.h>
-#include "../r.li.daemon/defs.h"
+#include "../r.li.daemon/daemon.h"
#include "../r.li.daemon/avlDefs.h"
#include "../r.li.daemon/avl.h"
-#include "../r.li.daemon/daemon.h"
/* template is shannon */
-double calculate(struct area_entry *ad, int fd, double *result);
-double calculateD(struct area_entry *ad, int fd, double *result);
-double calculateF(struct area_entry *ad, int fd, double *result);
+rli_func simpson;
+int calculate(int fd, struct area_entry *ad, double *result);
+int calculateD(int fd, struct area_entry *ad, double *result);
+int calculateF(int fd, struct area_entry *ad, double *result);
int main(int argc, char *argv[])
{
@@ -49,7 +49,7 @@
raster = G_define_standard_option(G_OPT_R_MAP);
- conf = G_define_option();
+ conf = G_define_standard_option(G_OPT_F_INPUT);
conf->key = "conf";
conf->description = _("Configuration file");
conf->required = YES;
@@ -63,6 +63,7 @@
output->answer);
}
+
int simpson(int fd, char **par, struct area_entry *ad, double *result)
{
char *mapset;
@@ -74,20 +75,21 @@
if (G_get_cellhd(ad->raster, mapset, &hd) == -1)
return RLI_ERRORE;
+
switch (ad->data_type) {
case CELL_TYPE:
{
- ris = calculate(ad, fd, &indice);
+ ris = calculate(fd, ad, &indice);
break;
}
case DCELL_TYPE:
{
- ris = calculateD(ad, fd, &indice);
+ ris = calculateD(fd, ad, &indice);
break;
}
case FCELL_TYPE:
{
- ris = calculateF(ad, fd, &indice);
+ ris = calculateF(fd, ad, &indice);
break;
}
default:
@@ -97,8 +99,9 @@
}
}
- if (ris != RLI_OK)
+ if (ris != RLI_OK) {
return RLI_ERRORE;
+ }
*result = indice;
@@ -106,28 +109,23 @@
}
-double calculate(struct area_entry *ad, int fd, double *result)
+int calculate(int fd, struct area_entry *ad, double *result)
{
CELL *buf;
CELL corrCell;
CELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
+ long totCorr = 1;
- double indice = 0;
- double somma = 0;
- double p = 0;
- double area = 0;
- double t;
+ long area = 0;
avl_tree albero = NULL;
AVL_table *array;
@@ -148,8 +146,6 @@
}
G_set_c_null_value(&precCell, 1);
-
-
for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
@@ -159,70 +155,70 @@
}
buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
+
for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
- area++;
corrCell = buf[i + ad->x];
- if ((masked) && (mask_buf[i + ad->x] == 0)) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_c_null_value(&corrCell, 1);
- area--;
}
if (!(G_is_null_value(&corrCell, uc.t))) {
- a = 1;
- if (G_is_null_value(&precCell, uc.t)) {
- precCell = corrCell;
- }
- if (corrCell != precCell) {
+ /* total patch area */
+ area++;
+ }
+
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
+
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.c = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
- uc.val.c = precCell;
- albero = avl_make(uc, totCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.c = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- else
+ case AVL_ADD:
+ {
m++;
- }
- else {
- uc.val.c = precCell;
- ris = avl_add(&albero, uc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_make unknown error");
- return RLI_ERRORE;
- }
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
- } /* endif not equal cells */
- else { /*equal cells */
-
- totCorr++;
}
- precCell = corrCell;
- }
-
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
}
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
uc.val.c = precCell;
albero = avl_make(uc, totCorr);
@@ -258,63 +254,64 @@
}
}
}
- array = G_malloc(m * sizeof(AVL_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avl_to_array(albero, zero, array);
- if (tot != m) {
- G_warning("avl_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
- /* calculate index summary */
- for (i = 0; i < m; i++) {
- t = (double)(array[i]->tot);
- p = t / area;
- somma = somma + (p * p);
- }
+ if (area > 0) {
+ double t;
+ double p;
+ double simpson;
- if (a != 0) {
- indice = 1 - somma;
- }
- else /*if a is 0, that is all cell are null, i put index=-1 */
- indice = (double)(-1);
+ array = G_malloc(m * sizeof(AVL_tableRow));
+ if (array == NULL) {
+ G_fatal_error("malloc array failed");
+ return RLI_ERRORE;
+ }
+ tot = avl_to_array(albero, zero, array);
+ if (tot != m) {
+ G_warning("avl_to_array unexpected value. the result could be wrong");
+ return RLI_ERRORE;
+ }
+ /* calculate simpson */
+ simpson = 0;
+ for (i = 0; i < m; i++) {
+ t = (double)(array[i]->tot);
+ p = t / area;
+ simpson += (p * p);
+ }
+ G_free(array);
- G_free(array);
- if (masked)
+ *result = 1 - simpson;
+ }
+ else
+ G_set_d_null_value(result, 1);
+
+ avl_destroy(albero);
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
+ }
- *result = indice;
-
return RLI_OK;
}
-double calculateD(struct area_entry *ad, int fd, double *result)
+int calculateD(int fd, struct area_entry *ad, double *result)
{
DCELL *buf;
DCELL corrCell;
DCELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
+ long totCorr = 1;
- double indice = 0;
- double somma = 0;
- double p = 0;
- double area = 0;
- double t;
+ long area = 0;
avl_tree albero = NULL;
AVL_table *array;
@@ -328,14 +325,13 @@
return RLI_ERRORE;
mask_buf = G_malloc(ad->cl * sizeof(int));
if (mask_buf == NULL) {
- G_fatal_error("malloc mask_buffailed");
+ G_fatal_error("malloc mask_buf failed");
return RLI_ERRORE;
}
masked = TRUE;
}
G_set_d_null_value(&precCell, 1);
-
for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
@@ -346,71 +342,69 @@
buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
- for (i = 0; i < ad->cl; i++) { /* for each dcell in the row */
- area++;
+ for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_d_null_value(&corrCell, 1);
- area--;
}
if (!(G_is_null_value(&corrCell, uc.t))) {
- a = 1;
+ /* total patch area */
+ area++;
+ }
- if (G_is_null_value(&precCell, uc.t)) {
- precCell = corrCell;
- }
- if (corrCell != precCell) {
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
+
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.dc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
- uc.val.dc = precCell;
- albero = avl_make(uc, totCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.dc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- m++;
- }
- else {
- uc.val.dc = precCell;
- ris = avl_add(&albero, uc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_make unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
- } /* endif not equal dcells */
- else { /*equal dcells */
-
- totCorr++;
}
- precCell = corrCell;
- }
-
-
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
}
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
uc.val.dc = precCell;
albero = avl_make(uc, totCorr);
@@ -446,66 +440,67 @@
}
}
}
- array = G_malloc(m * sizeof(AVL_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avl_to_array(albero, zero, array);
- if (tot != m) {
- G_warning("avl_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
- /* claculate index summary */
- for (i = 0; i < m; i++) {
- t = (double)(array[i]->tot);
- p = t / area;
- somma = somma + (p * p);
- }
+ if (area > 0) {
+ double t;
+ double p;
+ double simpson;
- if (a != 0) { /*if a is 0, that is all cell are null, i put index=-1 */
- indice = 1 - somma;
+ array = G_malloc(m * sizeof(AVL_tableRow));
+ if (array == NULL) {
+ G_fatal_error("malloc array failed");
+ return RLI_ERRORE;
+ }
+ tot = avl_to_array(albero, zero, array);
+ if (tot != m) {
+ G_warning("avl_to_array unexpected value. the result could be wrong");
+ return RLI_ERRORE;
+ }
+
+ /* calculate simpson */
+ simpson = 0;
+ for (i = 0; i < m; i++) {
+ t = (double)(array[i]->tot);
+ p = t / area;
+ simpson += (p * p);
+ }
+ G_free(array);
+
+ *result = 1 - simpson;
}
else
- indice = (double)(-1);
+ G_set_d_null_value(result, 1);
- G_free(array);
- if (masked)
+ avl_destroy(albero);
+ if (masked) {
+ close(mask_fd);
G_free(mask_buf);
+ }
- *result = indice;
return RLI_OK;
}
-double calculateF(struct area_entry *ad, int fd, double *result)
+int calculateF(int fd, struct area_entry *ad, double *result)
{
FCELL *buf;
FCELL corrCell;
FCELL precCell;
int i, j;
- int mask_fd = -1, *mask_buf;
+ int mask_fd = -1, *mask_buf = NULL;
int ris = 0;
int masked = FALSE;
- int a = 0; /* a=0 if all cells are null */
long m = 0;
long tot = 0;
long zero = 0;
- long totCorr = 0;
+ long totCorr = 1;
- double indice = 0;
- double somma = 0;
- double p = 0;
- double area = 0;
- double t;
+ long area = 0;
avl_tree albero = NULL;
-
AVL_table *array;
-
generic_cell uc;
uc.t = FCELL_TYPE;
@@ -523,7 +518,6 @@
}
G_set_f_null_value(&precCell, 1);
-
for (j = 0; j < ad->rl; j++) { /* for each row */
if (masked) {
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
@@ -534,69 +528,69 @@
buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
- for (i = 0; i < ad->cl; i++) { /* for each fcell in the row */
- area++;
+ for (i = 0; i < ad->cl; i++) { /* for each cell in the row */
corrCell = buf[i + ad->x];
- if (masked && mask_buf[i + ad->x] == 0) {
+ if ((masked) && (mask_buf[i] == 0)) {
G_set_f_null_value(&corrCell, 1);
- area--;
}
if (!(G_is_null_value(&corrCell, uc.t))) {
- a = 1;
- if (G_is_null_value(&precCell, uc.t)) {
- precCell = corrCell;
- }
- if (corrCell != precCell) {
+ /* total patch area */
+ area++;
+ }
+
+ if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell == precCell) {
+
+ totCorr++;
+ }
+ else if (!(G_is_null_value(&precCell, uc.t)) &&
+ corrCell != precCell) {
+
+ /* add precCell to search tree */
+ if (albero == NULL) {
+ uc.val.fc = precCell;
+ albero = avl_make(uc, totCorr);
if (albero == NULL) {
- uc.val.fc = precCell;
- albero = avl_make(uc, totCorr);
- if (albero == NULL) {
- G_fatal_error("avl_make error");
+ G_fatal_error("avl_make error");
+ return RLI_ERRORE;
+ }
+ m++;
+ }
+ else {
+ uc.val.fc = precCell;
+ ris = avl_add(&albero, uc, totCorr);
+ switch (ris) {
+ case AVL_ERR:
+ {
+ G_fatal_error("avl_add error");
return RLI_ERRORE;
}
- m++;
- }
- else {
- uc.val.fc = precCell;
- ris = avl_add(&albero, uc, totCorr);
- switch (ris) {
- case AVL_ERR:
- {
- G_fatal_error("avl_add error");
- return RLI_ERRORE;
- }
- case AVL_ADD:
- {
- m++;
- break;
- }
- case AVL_PRES:
- {
- break;
- }
- default:
- {
- G_fatal_error("avl_make unknown error");
- return RLI_ERRORE;
- }
+ case AVL_ADD:
+ {
+ m++;
+ break;
}
+ case AVL_PRES:
+ {
+ break;
+ }
+ default:
+ {
+ G_fatal_error("avl_make unknown error");
+ return RLI_ERRORE;
+ }
}
- totCorr = 1;
- } /* endif not equal fcells */
- else { /*equal fcells */
-
- totCorr++;
}
- precCell = corrCell;
- }
-
+ totCorr = 1;
+ } /* endif not equal cells */
+ precCell = corrCell;
}
}
- /*last closing */
- if (a != 0) {
+ /* last closing */
+ if (area > 0 && !(G_is_null_value(&precCell, uc.t))) {
if (albero == NULL) {
uc.val.fc = precCell;
albero = avl_make(uc, totCorr);
@@ -633,37 +627,41 @@
}
}
- array = G_malloc(m * sizeof(AVL_tableRow));
- if (array == NULL) {
- G_fatal_error("malloc array failed");
- return RLI_ERRORE;
- }
- tot = avl_to_array(albero, zero, array);
- if (tot != m) {
- G_warning("avl_to_array unaspected value. the result could be wrong");
- return RLI_ERRORE;
- }
+ if (area > 0) {
+ double t;
+ double p;
+ double simpson;
- /* calculate index summary */
- for (i = 0; i < m; i++) {
- t = (double)(array[i]->tot);
- p = t / area;
- somma = somma + (p * p);
- }
+ array = G_malloc(m * sizeof(AVL_tableRow));
+ if (array == NULL) {
+ G_fatal_error("malloc array failed");
+ return RLI_ERRORE;
+ }
+ tot = avl_to_array(albero, zero, array);
+ if (tot != m) {
+ G_warning("avl_to_array unexpected value. the result could be wrong");
+ return RLI_ERRORE;
+ }
- if (a != 0) { /*if a is 0, that is all cell are null, i put index=-1 */
- indice = 1 - somma;
+ /* calculate simpson */
+ simpson = 0;
+ for (i = 0; i < m; i++) {
+ t = (double)(array[i]->tot);
+ p = t / area;
+ simpson += (p * p);
+ }
+ G_free(array);
+
+ *result = 1 - simpson;
}
else
- indice = (double)(-1);
+ G_set_d_null_value(result, 1);
-
- G_free(array);
+ avl_destroy(albero);
if (masked) {
close(mask_fd);
G_free(mask_buf);
}
- *result = indice;
return RLI_OK;
}
More information about the grass-commit
mailing list