long avl_to_array(avl_node * root, long i, AVL_table a) { if (root != NULL) { i = avl_to_array(root->left_child, i, a); if (a == NULL) G_fatal_error("avl, avl_to_array: null value"); else { a[i].k = root->key; a[i].tot = root->counter; i++; i = avl_to_array(root->right_child, i, a); } } return i; }
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; }