Exemple #1
0
double calculateF(area_des ad, int fd, char **par, double *result)
{
    FCELL *buf;
    FCELL corrCell;
    FCELL precCell;

    int i, j;
    int mask_fd = -1, *mask_buf;
    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;

    avl_tree albero = NULL;

    AVL_table *array;
    generic_cell uc;

    uc.t = FCELL_TYPE;

    /* open mask if needed */
    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;
	}
	masked = TRUE;
    }

    Rast_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) {
		G_fatal_error("mask read failed");
		return RLI_ERRORE;
	    }
	}

	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++;
	    corrCell = buf[i + ad->x];

	    if (masked && mask_buf[i + ad->x] == 0) {
		Rast_set_f_null_value(&corrCell, 1);
		area--;
	    }

	    if (!(Rast_is_null_value(&corrCell, uc.t))) {
		a = 1;
		if (Rast_is_null_value(&precCell, uc.t)) {
		    precCell = corrCell;
		}
		if (corrCell != precCell) {
		    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++;
		    }
		    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;
			    }
			}
		    }
		    totCorr = 1;
		}		/* endif not equal fcells */
		else {		/*equal fcells */

		    totCorr++;
		}
		precCell = corrCell;
	    }


	}
    }

    /*last closing */
    if (a != 0) {
	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++;
	}
	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_add unknown error");
		    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 unaspected value. the result could be wrong");
	return RLI_ERRORE;
    }

    char *sval;

    sval = par[0];
    double alpha_double;

    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);
    }

    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);

    *result = indice;


    G_free(array);
    if (masked)
	G_free(mask_buf);

    return RLI_OK;

}
Exemple #2
0
int calculateF(int fd, area_des 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;

    gc.t = FCELL_TYPE;

    /* open mask if needed */
    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;
	}
	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 */

    {
	if (j > 0) {
	    buf_sup = RLI_get_fcell_raster_row(fd, j - 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;
	    }
	}
	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) {
		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;
			}

			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;
			}
		    }

		    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++;
			}
			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;
			}
			else {
			    mask_patch_corr[i] = idCorr;
			}
		    }
		    else {	/*current cell and upper cell are not equal */
			/*        2
			 *      1 1
			 */
			mask_patch_corr[i] = idCorr;
		    }

		    totCorr++;
		}
	    }
	    else {		/*cell is null or is not to consider */

		mask_patch_corr[i] = 0;

	    }
	}

	{
	    int ii;
	    long c;

	    for (ii = 0; ii < ad->cl; ii++) {
		c = mask_patch_corr[ii];
		mask_patch_sup[ii] = c;
		mask_patch_corr[ii] = 0;
	    }
	}


    }




    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;
		}
	    }
	}
	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);
    }

    else
	indice = (double)(-1);
    if (masked)
	G_free(mask_buf);
    G_free(mask_patch_sup);
    *result = indice;
    return RLI_OK;
}
Exemple #3
0
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;

    Rast_get_window(&hd);

    buf_null = Rast_allocate_f_buf();
    Rast_set_f_null_value(buf_null, Rast_window_cols());
    buf_sup = buf_null;

    /* initialize patch ids */
    pid_corr = G_malloc(Rast_window_cols() * sizeof(long));
    pid_sup = G_malloc(Rast_window_cols() * sizeof(long));

    for (j = 0; j < Rast_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;
	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_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;

	Rast_set_f_null_value(&precCell, 1);

	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)) {
		Rast_set_f_null_value(&corrCell, 1);
	    }

	    if (Rast_is_f_null_value(&corrCell)) {
		connected = 0;
		precCell = corrCell;
		continue;
	    }
	    
	    area++;
	    
	    supCell = buf_sup[j + ad->x];
	    if (masked && (mask_sup[j] == 0)) {
		Rast_set_f_null_value(&supCell, 1);
	    }

	    if (!Rast_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 (!Rast_is_f_null_value(&supCell) && corrCell == supCell) {

		if (pid_corr[j + ad->x] != pid_sup[j + ad->x]) {
		    /* 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 + 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;
			}
			/* 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 {
			pst[new_pid].count++;
		    }
		}
		connected = 1;
	    }

	    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));

		    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 (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);

	cell_size_m = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
	              (((NS_DIST1 + NS_DIST2) / 2) / hd.rows);

	/* 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;
	    }
	}
	*result = max - min;
    }
    else
	Rast_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;
}
Exemple #4
0
int calculateF(int fd, area_des ad, struct Cell_head hd, 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;


    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;

    avlID_tree albero = NULL;

    avlID_table *array;



    /* open mask if needed */
    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;
        }
        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 = Rast_allocate_f_buf();
    if (buf_sup == NULL) {
        G_fatal_error("malloc buf_sup failed");
        return RLI_ERRORE;
    }


    buf = Rast_allocate_f_buf();
    if (buf == NULL) {
        G_fatal_error("malloc buf failed");
        return RLI_ERRORE;
    }

    Rast_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);
        }
        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;
            }
        }
        Rast_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))) {
                Rast_set_f_null_value(&corrCell, 1);
            }
            if (!(Rast_is_null_value(&corrCell, FCELL_TYPE))) {
                area++;
                if (i > 0)
                    precCell = buf[i - 1 + ad->x];
                if (j == 0)
                    Rast_set_f_null_value(&supCell, 1);
                else
                    supCell = buf_sup[i + ad->x];


                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++;

                            }
                            else {	/*tree not empty */

                                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;
                        }
                    }
                    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;
                                }
                            }
                        }

                        if (albero == NULL) {
                            albero = avlID_make(idCorr, uno);
                            if (albero == NULL) {
                                G_fatal_error("avlID_make error");
                                return RLI_ERRORE;
                            }
                            npatch++;
                        }
                        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;
                    }
                }
                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;
                    }

                }
            }
            else {		/*null cell or cell not to consider */

                mask_patch_corr[i] = 0;
            }
        }
        mask_patch_sup = mask_patch_corr;
    }



    if (area != 0) {
        if (albero == NULL) {
            albero = avlID_make(idCorr, uno);
            if (albero == NULL) {
                G_fatal_error("avlID_make error");
                return RLI_ERRORE;
            }
            npatch++;
        }
        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 (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 */
        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);

        areaCorrect = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
                      (((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * (area);
        indice = areaCorrect / npatch;
        G_free(array);
    }
    else
        indice = (double)(0);


    *result = indice;


    if (masked)
        G_free(mask_buf);

    G_free(mask_patch_corr);

    return RLI_OK;
}