Example #1
0
double calculate(area_des ad, int fd, char **par, double *result)
{

    CELL *buf;
    CELL corrCell;
    CELL 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 = CELL_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_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) {
		G_fatal_error("mask read failed");
		return RLI_ERRORE;
	    }
	}

	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)) {
		Rast_set_c_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.c = precCell;
			albero = avl_make(uc, totCorr);
			if (albero == NULL) {
			    G_fatal_error("avl_make error");
			    return RLI_ERRORE;
			}
			else
			    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;
			    }
			}
		    }
		    totCorr = 1;
		}		/* endif not equal cells */
		else {		/*equal cells */

		    totCorr++;
		}
		precCell = corrCell;
	    }

	}
    }

    /*last closing */
    if (a != 0) {
	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;
		}
	    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);
    /* 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);
    }

    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;
}
Example #2
0
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;

    Rast_get_window(&hd);

    buf_null = Rast_allocate_c_buf();
    Rast_set_c_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_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;
	}
	
	ltmp = pid_sup;
	pid_sup = pid_corr;
	pid_corr = ltmp;

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

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

	    if (!Rast_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 (!Rast_is_c_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;
}
Example #3
0
int calculate(int fd, area_des 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;

    gc.t = CELL_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_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);
	}
	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;
	    }
	}
	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) {
		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 (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;
			}

			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;

    G_free(buf_sup);
    return RLI_OK;
}
Example #4
0
int calculate(int fd, area_des ad, struct Cell_head hd, 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;


    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_c_buf();
    if (buf_sup == NULL) {
        G_fatal_error("malloc buf_sup failed");
        return RLI_ERRORE;
    }

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

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

            /*valid cell */
            if (!(Rast_is_null_value(&corrCell, CELL_TYPE))) {
                area++;
                if (i > 0)
                    precCell = buf[i - 1 + ad->x];

                if (j == 0)
                    Rast_set_c_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 values */
                            if (albero == NULL) {
                                albero = avlID_make(idCorr, uno);
                                if (albero == NULL) {
                                    G_fatal_error("avlID_make error");
                                    return RLI_ERRORE;
                                }
                                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;
                        }
                    }
                    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 {	/* 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;
                    }
                }
                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 {		/*cell not to consider or cell is null */

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

    G_free(buf_sup);
    return RLI_OK;
}
Example #5
0
int patch_number(int fd, char **par, area_des ad, double *result)
{
    CELL *buf, *sup;
    int count = 0, i, j, connected = 0, complete_line = 1, other_above = 0;
    struct Cell_head hd;
    CELL complete_value;
    int mask_fd = -1, *mask_buf, *mask_sup, null_count = 0;

    Rast_set_c_null_value(&complete_value, 1);
    Rast_get_cellhd(ad->raster, "", &hd);

    sup = Rast_allocate_c_buf();

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

    /*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);
	}
	/* mask values */
	if (ad->mask == 1) {
	    int k;

	    if (i > 0) {
		int *tmp;

		tmp = mask_sup;
		mask_buf = mask_sup;
	    }
	    if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
		return 0;
	    for (k = 0; k < ad->cl; k++) {
		if (mask_buf[k] == 0) {
		    Rast_set_c_null_value(mask_buf + k, 1);
		    null_count++;
		}
	    }

	}


	if (complete_line) {
	    if (!Rast_is_null_value(&(buf[ad->x]), CELL_TYPE) &&
		buf[ad->x] != complete_value)
		count++;

	    for (j = 0; j < ad->cl - 1; j++) {

		if (buf[j + ad->x] != buf[j + 1 + ad->x]) {
		    complete_line = 0;
		    if (!Rast_is_null_value(&(buf[j + 1 + ad->x]), CELL_TYPE)
			&& buf[j + 1 + ad->x] != complete_value)
			count++;
		}

	    }
	    if (complete_line) {
		complete_value = buf[ad->x];
	    }
	}
	else {
	    complete_line = 1;
	    connected = 0;
	    other_above = 0;
	    for (j = 0; j < ad->cl; j++) {
		if (sup[j + ad->x] == buf[j + ad->x]) {
		    connected = 1;
		    if (other_above) {
			other_above = 0;
			count--;
		    }
		}
		else {
		    if (connected &&
			!Rast_is_null_value(&(buf[j + ad->x]), CELL_TYPE))
			other_above = 1;
		}
		if (j < ad->cl - 1 && buf[j + ad->x] != buf[j + 1 + ad->x]) {
		    complete_line = 0;
		    if (!connected &&
			!Rast_is_null_value(&(buf[j + ad->x]), CELL_TYPE)) {

			count++;
			connected = 0;
			other_above = 0;
		    }
		    else {
			connected = 0;
			other_above = 0;
		    }
		}
	    }
	    if (!connected &&
		sup[ad->cl - 1 + ad->x] != buf[ad->cl - 1 + ad->x]) {
		if (!Rast_is_null_value
		    (&(buf[ad->cl - 1 + ad->x]), CELL_TYPE)) {
		    count++;
		    complete_line = 0;
		}
	    }

	    if (complete_line)
		complete_value = buf[ad->x];

	}

    }

    *result = count;

    G_free(sup);
    return RLI_OK;
}
Example #6
0
int patch_density(int fd, char **par, area_des ad, double *result)
{
    CELL *buf, *sup;
    int count = 0, i, j, connected = 0, complete_line = 1, other_above = 0;
    double area;
    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;

    Rast_set_c_null_value(&complete_value, 1);
    Rast_get_cellhd(ad->raster, "", &hd);

    sup = Rast_allocate_c_buf();

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

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




    /*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);
	}
	/* mask values */
	if (ad->mask == 1) {
	    int k;

	    if (i > 0) {
		int *tmp;

		tmp = mask_sup;
		mask_buf = mask_sup;
	    }
	    if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
		return 0;
	    for (k = 0; k < ad->cl; k++) {
		if (mask_buf[k] == 0) {
		    Rast_set_c_null_value(mask_buf + k, 1);
		    null_count++;
		}
	    }

	}


	if (complete_line) {
	    if (!Rast_is_null_value(&(buf[ad->x]), CELL_TYPE) &&
		buf[ad->x] != complete_value)
		count++;

	    for (j = 0; j < ad->cl - 1; j++) {

		if (buf[j + ad->x] != buf[j + 1 + ad->x]) {
		    complete_line = 0;
		    if (!Rast_is_null_value(&(buf[j + 1 + ad->x]), CELL_TYPE)
			&& buf[j + 1 + ad->x] != complete_value)
			count++;
		}

	    }
	    if (complete_line) {
		complete_value = buf[ad->x];
	    }
	}
	else {
	    complete_line = 1;
	    connected = 0;
	    other_above = 0;
	    for (j = 0; j < ad->cl; j++) {
		if (sup[j + ad->x] == buf[j + ad->x]) {
		    connected = 1;
		    if (other_above) {
			other_above = 0;
			count--;
		    }
		}
		else {
		    if (connected &&
			!Rast_is_null_value(&(buf[j + ad->x]), CELL_TYPE))
			other_above = 1;
		}
		if (j < ad->cl - 1 && buf[j + ad->x] != buf[j + 1 + ad->x]) {
		    complete_line = 0;
		    if (!connected &&
			!Rast_is_null_value(&(buf[j + ad->x]), CELL_TYPE)) {

			count++;
			connected = 0;
			other_above = 0;
		    }
		    else {
			connected = 0;
			other_above = 0;
		    }
		}
	    }
	    if (!connected &&
		sup[ad->cl - 1 + ad->x] != buf[ad->cl - 1 + ad->x]) {
		if (!Rast_is_null_value
		    (&(buf[ad->cl - 1 + ad->x]), CELL_TYPE)) {
		    count++;
		    complete_line = 0;
		}
	    }

	    if (complete_line)
		complete_value = buf[ad->x];

	}

    }

    area = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
	(((NS_DIST1 + NS_DIST2) / 2) / hd.rows) *
	(ad->rl * ad->cl - null_count);

    if (area != 0)
	*result = (count / area) * 1000000;
    else
	*result = -1;

    G_free(sup);
    return RLI_OK;
}