int main( int argc, char **argv ) { struct GModule *module; struct Option *info_opt, *rast_opt, *vect_opt, *coor_opt, *north_opt, *south_opt, *east_opt, *west_opt, *rows_opt, *cols_opt; struct Cell_head window; /* Initialize the GIS calls */ G_gisinit( argv[0] ); module = G_define_module(); module->description = ( "Get info about locations,mapsets,maps" ); info_opt = G_define_option(); info_opt->key = "info"; info_opt->type = TYPE_STRING; info_opt->description = "info key"; info_opt->options = "proj,window,size,query,info,colors,stats"; rast_opt = G_define_standard_option( G_OPT_R_INPUT ); rast_opt->key = "rast"; rast_opt->required = NO; vect_opt = G_define_standard_option( G_OPT_V_INPUT ); vect_opt->key = "vect"; vect_opt->required = NO; coor_opt = G_define_option(); coor_opt->key = "coor"; coor_opt->type = TYPE_DOUBLE; coor_opt->multiple = YES; north_opt = G_define_option(); north_opt->key = "north"; north_opt->type = TYPE_STRING; south_opt = G_define_option(); south_opt->key = "south"; south_opt->type = TYPE_STRING; east_opt = G_define_option(); east_opt->key = "east"; east_opt->type = TYPE_STRING; west_opt = G_define_option(); west_opt->key = "west"; west_opt->type = TYPE_STRING; rows_opt = G_define_option(); rows_opt->key = "rows"; rows_opt->type = TYPE_INTEGER; cols_opt = G_define_option(); cols_opt->key = "cols"; cols_opt->type = TYPE_INTEGER; if ( G_parser( argc, argv ) ) exit( EXIT_FAILURE ); if ( strcmp( "proj", info_opt->answer ) == 0 ) { G_get_window( &window ); /* code from g.proj */ if ( window.proj != PROJECTION_XY ) { struct Key_Value *projinfo, *projunits; char *wkt; projinfo = G_get_projinfo(); projunits = G_get_projunits(); wkt = GPJ_grass_to_wkt( projinfo, projunits, 0, 0 ); fprintf( stdout, "%s", wkt ); } } else if ( strcmp( "window", info_opt->answer ) == 0 ) { if ( rast_opt->answer ) { G_get_cellhd( rast_opt->answer, "", &window ); fprintf( stdout, "%f,%f,%f,%f", window.west, window.south, window.east, window.north ); } else if ( vect_opt->answer ) { G_fatal_error( "Not yet supported" ); } } // raster width and height else if ( strcmp( "size", info_opt->answer ) == 0 ) { if ( rast_opt->answer ) { G_get_cellhd( rast_opt->answer, "", &window ); fprintf( stdout, "%d,%d", window.cols, window.rows ); } else if ( vect_opt->answer ) { G_fatal_error( "Not yet supported" ); } } // raster informations else if ( strcmp( "info", info_opt->answer ) == 0 ) { struct FPRange range; double zmin, zmax; // Data type RASTER_MAP_TYPE raster_type = G_raster_map_type( rast_opt->answer, "" ); fprintf( stdout, "TYPE:%d\n", raster_type ); // Statistics if ( G_read_fp_range( rast_opt->answer, "", &range ) < 0 ) { G_fatal_error(( "Unable to read range file" ) ); } G_get_fp_range_min_max( &range, &zmin, &zmax ); fprintf( stdout, "MIN_VALUE:%.17e\n", zmin ); fprintf( stdout, "MAX_VALUE:%.17e\n", zmax ); } else if ( strcmp( "colors", info_opt->answer ) == 0 ) { // Color table struct Colors colors; int i, ccount; if ( G_read_colors( rast_opt->answer, "", &colors ) == 1 ) { //int maxcolor; //CELL min, max; //G_get_color_range ( &min, &max, &colors); ccount = G_colors_count( &colors ); for ( i = ccount - 1; i >= 0; i-- ) { DCELL val1, val2; unsigned char r1, g1, b1, r2, g2, b2; G_get_f_color_rule( &val1, &r1, &g1, &b1, &val2, &r2, &g2, &b2, &colors, i ); fprintf( stdout, "%.17e %.17e %d %d %d %d %d %d\n", val1, val2, r1, g1, b1, r2, g2, b2 ); } } } else if ( strcmp( "query", info_opt->answer ) == 0 ) { double x, y; int row, col; //x = atof( coor_opt->answers[0] ); //y = atof( coor_opt->answers[1] ); if ( rast_opt->answer ) { int fd; RASTER_MAP_TYPE rast_type; DCELL *dcell; CELL *cell; char buff[101]; G_get_cellhd( rast_opt->answer, "", &window ); G_set_window( &window ); fd = G_open_cell_old( rast_opt->answer, "" ); // wait for coors from stdin while ( fgets( buff, 100, stdin ) != 0 ) { if ( sscanf( buff, "%lf%lf", &x, &y ) != 2 ) { fprintf( stdout, "value:error\n" ); } else { col = ( int ) G_easting_to_col( x, &window ); row = ( int ) G_northing_to_row( y, &window ); if ( col == window.cols ) col--; if ( row == window.rows ) row--; if ( col < 0 || col > window.cols || row < 0 || row > window.rows ) { fprintf( stdout, "value:out\n" ); } else { void *ptr; double val; #if defined(GRASS_VERSION_MAJOR) && defined(GRASS_VERSION_MINOR) && \ ( ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR > 2 ) || GRASS_VERSION_MAJOR > 6 ) rast_type = G_get_raster_map_type( fd ); #else rast_type = G_raster_map_type( rast_opt->answer, "" ); #endif cell = G_allocate_c_raster_buf(); dcell = G_allocate_d_raster_buf(); if ( rast_type == CELL_TYPE ) { if ( G_get_c_raster_row( fd, cell, row ) < 0 ) { G_fatal_error(( "Unable to read raster map <%s> row %d" ), rast_opt->answer, row ); } val = cell[col]; ptr = &( cell[col] ); } else { if ( G_get_d_raster_row( fd, dcell, row ) < 0 ) { G_fatal_error(( "Unable to read raster map <%s> row %d" ), rast_opt->answer, row ); } val = dcell[col]; ptr = &( dcell[col] ); } if ( G_is_null_value( ptr, rast_type ) ) { fprintf( stdout, "value:null\n" ); } else { fprintf( stdout, "value:%f\n", val ); } } } fflush( stdout ); } G_close_cell( fd ); } else if ( vect_opt->answer ) { G_fatal_error( "Not yet supported" ); } } else if ( strcmp( "stats", info_opt->answer ) == 0 ) { if ( rast_opt->answer ) { int fd; RASTER_MAP_TYPE rast_type; DCELL *dcell; CELL *cell; int ncols, nrows; int row, col; void *ptr; double val; double min = DBL_MAX; double max = -DBL_MAX; double sum = 0; // sum of values int count = 0; // count of non null values double mean = 0; double squares_sum = 0; // sum of squares double stdev = 0; // standard deviation G_get_cellhd( rast_opt->answer, "", &window ); window.north = atof( north_opt->answer ); window.south = atof( south_opt->answer ); window.east = atof( east_opt->answer ); window.west = atof( west_opt->answer ); window.rows = ( int ) atoi( rows_opt->answer ); window.cols = ( int ) atoi( cols_opt->answer ); G_set_window( &window ); fd = G_open_cell_old( rast_opt->answer, "" ); ncols = G_window_cols(); nrows = G_window_rows(); #if defined(GRASS_VERSION_MAJOR) && defined(GRASS_VERSION_MINOR) && \ ( ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR > 2 ) || GRASS_VERSION_MAJOR > 6 ) rast_type = G_get_raster_map_type( fd ); #else rast_type = G_raster_map_type( rast_opt->answer, "" ); #endif cell = G_allocate_c_raster_buf(); dcell = G_allocate_d_raster_buf(); // Calc stats is very slow for large rasters -> prefer optimization for speed over // code length and readability (which is not currently true) for ( row = 0; row < nrows; row++ ) { if ( rast_type == CELL_TYPE ) { if ( G_get_c_raster_row( fd, cell, row ) < 0 ) { G_fatal_error(( "Unable to read raster map <%s> row %d" ), rast_opt->answer, row ); } } else { if ( G_get_d_raster_row( fd, dcell, row ) < 0 ) { G_fatal_error(( "Unable to read raster map <%s> row %d" ), rast_opt->answer, row ); } } for ( col = 0; col < ncols; col++ ) { if ( rast_type == CELL_TYPE ) { val = cell[col]; ptr = &( cell[col] ); } else { val = dcell[col]; ptr = &( dcell[col] ); } if ( ! G_is_null_value( ptr, rast_type ) ) { if ( val < min ) min = val; if ( val > max ) max = val; sum += val; count++; squares_sum += pow( val, 2 ); } } } mean = sum / count; squares_sum -= count * pow( mean, 2 ); stdev = sqrt( squares_sum / ( count - 1 ) ); fprintf( stdout, "MIN:%.17e\n", min ); fprintf( stdout, "MAX:%.17e\n", max ); fprintf( stdout, "SUM:%.17e\n", sum ); fprintf( stdout, "MEAN:%.17e\n", mean ); fprintf( stdout, "COUNT:%d\n", count ); fprintf( stdout, "STDEV:%.17e\n", stdev ); fprintf( stdout, "SQSUM:%.17e\n", squares_sum ); G_close_cell( fd ); } else if ( vect_opt->answer ) { G_fatal_error( "Not yet supported" ); } } exit( EXIT_SUCCESS ); }
static int cell_draw( char *name, char *mapset, struct Colors *colors, RASTER_MAP_TYPE data_type, char *format ) { int cellfile; void *xarray; int row; int ncols, nrows; static unsigned char *red, *grn, *blu, *set; int i; void *ptr; int big_endian; long one = 1; FILE *fo; int raster_size; big_endian = !( *(( char * )( &one ) ) ); ncols = G_window_cols(); nrows = G_window_rows(); /* Make sure map is available */ if (( cellfile = G_open_cell_old( name, mapset ) ) == -1 ) G_fatal_error(( "Unable to open raster map <%s>" ), name ); /* Allocate space for cell buffer */ xarray = G_allocate_raster_buf( data_type ); red = G_malloc( ncols ); grn = G_malloc( ncols ); blu = G_malloc( ncols ); set = G_malloc( ncols ); /* some buggy C libraries require BOTH setmode() and fdopen(bin) */ #ifdef WIN32 if ( _setmode( _fileno( stdout ), _O_BINARY ) == -1 ) G_fatal_error( "Cannot set stdout mode" ); #endif // Unfortunately this is not sufficient on Windows to switch stdout to binary mode fo = fdopen( fileno( stdout ), "wb" ); raster_size = G_raster_size( data_type ); //fprintf( fo, "%d %d", data_type, raster_size ); //exit(0); /* loop for array rows */ for ( row = 0; row < nrows; row++ ) { G_get_raster_row( cellfile, xarray, row, data_type ); ptr = xarray; G_lookup_raster_colors( xarray, red, grn, blu, set, ncols, colors, data_type ); for ( i = 0; i < ncols; i++ ) { unsigned char alpha = 255; //G_debug ( 0, "row = %d col = %d", row, i ); if ( G_is_null_value( ptr, data_type ) ) { alpha = 0; } if ( strcmp( format, "color" ) == 0 ) { // We need data suitable for QImage 32-bpp // the data are stored in QImage as QRgb which is unsigned int. // Because it depends on byte order of the platform we have to // consider byte order (well, middle endian ignored) if ( big_endian ) { // I have never tested this fprintf( fo, "%c%c%c%c", alpha, red[i], grn[i], blu[i] ); } else { fprintf( fo, "%c%c%c%c", blu[i], grn[i], red[i], alpha ); } } else { if ( data_type == CELL_TYPE ) { //G_debug ( 0, "valx = %d", *((CELL *) ptr)); } if ( G_is_null_value( ptr, data_type ) ) { if ( data_type == CELL_TYPE ) { int nul = -2147483647; fwrite( &nul , 4, 1, fo ); } else if ( data_type == DCELL_TYPE ) { double nul = 2.2250738585072014e-308; fwrite( &nul , 8, 1, fo ); } else if ( data_type == FCELL_TYPE ) { double nul = 1.17549435e-38F; fwrite( &nul , 4, 1, fo ); } } else { fwrite( ptr, raster_size, 1, fo ); } } ptr = G_incr_void_ptr( ptr, raster_size ); } } G_close_cell( cellfile ); return ( 0 ); }
int main(int argc, char *argv[]) { FILE *in_fp; int out_fd; char *infile, *outmap; int xcol, ycol, zcol, max_col, percent; int do_zfilter; int method = -1; int bin_n, bin_min, bin_max, bin_sum, bin_sumsq, bin_index; double zrange_min, zrange_max, d_tmp; char *fs; /* field delim */ off_t filesize; int linesize; long estimated_lines; int from_stdin; int can_seek; RASTER_MAP_TYPE rtype; struct History history; char title[64]; void *n_array, *min_array, *max_array, *sum_array, *sumsq_array, *index_array; void *raster_row, *ptr; struct Cell_head region; int rows, cols; /* scan box size */ int row, col; /* counters */ int pass, npasses; unsigned long line; char buff[BUFFSIZE]; double x, y, z; char **tokens; int ntokens; /* number of tokens */ double pass_north, pass_south; int arr_row, arr_col; unsigned long count, count_total; double min = 0.0 / 0.0; /* init as nan */ double max = 0.0 / 0.0; /* init as nan */ double zscale = 1.0; size_t offset, n_offset; int n = 0; double sum = 0.; double sumsq = 0.; double variance, mean, skew, sumdev; int pth = 0; double trim = 0.0; int j, k; int head_id, node_id; int r_low, r_up; struct GModule *module; struct Option *input_opt, *output_opt, *delim_opt, *percent_opt, *type_opt; struct Option *method_opt, *xcol_opt, *ycol_opt, *zcol_opt, *zrange_opt, *zscale_opt; struct Option *trim_opt, *pth_opt; struct Flag *scan_flag, *shell_style, *skipline; G_gisinit(argv[0]); module = G_define_module(); module->keywords = _("raster, import, LIDAR"); module->description = _("Create a raster map from an assemblage of many coordinates using univariate statistics."); input_opt = G_define_standard_option(G_OPT_F_INPUT); input_opt->description = _("ASCII file containing input data (or \"-\" to read from stdin)"); output_opt = G_define_standard_option(G_OPT_R_OUTPUT); method_opt = G_define_option(); method_opt->key = "method"; method_opt->type = TYPE_STRING; method_opt->required = NO; method_opt->description = _("Statistic to use for raster values"); method_opt->options = "n,min,max,range,sum,mean,stddev,variance,coeff_var,median,percentile,skewness,trimmean"; method_opt->answer = "mean"; method_opt->guisection = _("Statistic"); type_opt = G_define_option(); type_opt->key = "type"; type_opt->type = TYPE_STRING; type_opt->required = NO; type_opt->options = "CELL,FCELL,DCELL"; type_opt->answer = "FCELL"; type_opt->description = _("Storage type for resultant raster map"); delim_opt = G_define_standard_option(G_OPT_F_SEP); delim_opt->guisection = _("Input"); xcol_opt = G_define_option(); xcol_opt->key = "x"; xcol_opt->type = TYPE_INTEGER; xcol_opt->required = NO; xcol_opt->answer = "1"; xcol_opt->description = _("Column number of x coordinates in input file (first column is 1)"); xcol_opt->guisection = _("Input"); ycol_opt = G_define_option(); ycol_opt->key = "y"; ycol_opt->type = TYPE_INTEGER; ycol_opt->required = NO; ycol_opt->answer = "2"; ycol_opt->description = _("Column number of y coordinates in input file"); ycol_opt->guisection = _("Input"); zcol_opt = G_define_option(); zcol_opt->key = "z"; zcol_opt->type = TYPE_INTEGER; zcol_opt->required = NO; zcol_opt->answer = "3"; zcol_opt->description = _("Column number of data values in input file"); zcol_opt->guisection = _("Input"); zrange_opt = G_define_option(); zrange_opt->key = "zrange"; zrange_opt->type = TYPE_DOUBLE; zrange_opt->required = NO; zrange_opt->key_desc = "min,max"; zrange_opt->description = _("Filter range for z data (min,max)"); zscale_opt = G_define_option(); zscale_opt->key = "zscale"; zscale_opt->type = TYPE_DOUBLE; zscale_opt->required = NO; zscale_opt->answer = "1.0"; zscale_opt->description = _("Scale to apply to z data"); percent_opt = G_define_option(); percent_opt->key = "percent"; percent_opt->type = TYPE_INTEGER; percent_opt->required = NO; percent_opt->answer = "100"; percent_opt->options = "1-100"; percent_opt->description = _("Percent of map to keep in memory"); pth_opt = G_define_option(); pth_opt->key = "pth"; pth_opt->type = TYPE_INTEGER; pth_opt->required = NO; pth_opt->options = "1-100"; pth_opt->description = _("pth percentile of the values"); pth_opt->guisection = _("Statistic"); trim_opt = G_define_option(); trim_opt->key = "trim"; trim_opt->type = TYPE_DOUBLE; trim_opt->required = NO; trim_opt->options = "0-50"; trim_opt->description = _("Discard <trim> percent of the smallest and <trim> percent of the largest observations"); trim_opt->guisection = _("Statistic"); scan_flag = G_define_flag(); scan_flag->key = 's'; scan_flag->description = _("Scan data file for extent then exit"); shell_style = G_define_flag(); shell_style->key = 'g'; shell_style->description = _("In scan mode, print using shell script style"); skipline = G_define_flag(); skipline->key = 'i'; skipline->description = _("Ignore broken lines"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* parse input values */ infile = input_opt->answer; outmap = output_opt->answer; if (shell_style->answer && !scan_flag->answer) { scan_flag->answer = 1; } fs = delim_opt->answer; if (strcmp(fs, "\\t") == 0) fs = "\t"; if (strcmp(fs, "tab") == 0) fs = "\t"; if (strcmp(fs, "space") == 0) fs = " "; xcol = atoi(xcol_opt->answer); ycol = atoi(ycol_opt->answer); zcol = atoi(zcol_opt->answer); if ((xcol < 0) || (ycol < 0) || (zcol < 0)) G_fatal_error(_("Please specify a reasonable column number.")); max_col = (xcol > ycol) ? xcol : ycol; max_col = (zcol > max_col) ? zcol : max_col; percent = atoi(percent_opt->answer); zscale = atof(zscale_opt->answer); /* parse zrange */ do_zfilter = FALSE; if (zrange_opt->answer != NULL) { if (zrange_opt->answers[0] == NULL) G_fatal_error(_("Invalid zrange")); sscanf(zrange_opt->answers[0], "%lf", &zrange_min); sscanf(zrange_opt->answers[1], "%lf", &zrange_max); do_zfilter = TRUE; if (zrange_min > zrange_max) { d_tmp = zrange_max; zrange_max = zrange_min; zrange_min = d_tmp; } } /* figure out what maps we need in memory */ /* n n min min max max range min max max - min sum sum mean sum n sum/n stddev sum sumsq n sqrt((sumsq - sum*sum/n)/n) variance sum sumsq n (sumsq - sum*sum/n)/n coeff_var sum sumsq n sqrt((sumsq - sum*sum/n)/n) / (sum/n) median n array index to linked list percentile n array index to linked list skewness n array index to linked list trimmean n array index to linked list */ bin_n = FALSE; bin_min = FALSE; bin_max = FALSE; bin_sum = FALSE; bin_sumsq = FALSE; bin_index = FALSE; if (strcmp(method_opt->answer, "n") == 0) { method = METHOD_N; bin_n = TRUE; } if (strcmp(method_opt->answer, "min") == 0) { method = METHOD_MIN; bin_min = TRUE; } if (strcmp(method_opt->answer, "max") == 0) { method = METHOD_MAX; bin_max = TRUE; } if (strcmp(method_opt->answer, "range") == 0) { method = METHOD_RANGE; bin_min = TRUE; bin_max = TRUE; } if (strcmp(method_opt->answer, "sum") == 0) { method = METHOD_SUM; bin_sum = TRUE; } if (strcmp(method_opt->answer, "mean") == 0) { method = METHOD_MEAN; bin_sum = TRUE; bin_n = TRUE; } if (strcmp(method_opt->answer, "stddev") == 0) { method = METHOD_STDDEV; bin_sum = TRUE; bin_sumsq = TRUE; bin_n = TRUE; } if (strcmp(method_opt->answer, "variance") == 0) { method = METHOD_VARIANCE; bin_sum = TRUE; bin_sumsq = TRUE; bin_n = TRUE; } if (strcmp(method_opt->answer, "coeff_var") == 0) { method = METHOD_COEFF_VAR; bin_sum = TRUE; bin_sumsq = TRUE; bin_n = TRUE; } if (strcmp(method_opt->answer, "median") == 0) { method = METHOD_MEDIAN; bin_index = TRUE; } if (strcmp(method_opt->answer, "percentile") == 0) { if (pth_opt->answer != NULL) pth = atoi(pth_opt->answer); else G_fatal_error(_("Unable to calculate percentile without the pth option specified!")); method = METHOD_PERCENTILE; bin_index = TRUE; } if (strcmp(method_opt->answer, "skewness") == 0) { method = METHOD_SKEWNESS; bin_index = TRUE; } if (strcmp(method_opt->answer, "trimmean") == 0) { if (trim_opt->answer != NULL) trim = atof(trim_opt->answer) / 100.0; else G_fatal_error(_("Unable to calculate trimmed mean without the trim option specified!")); method = METHOD_TRIMMEAN; bin_index = TRUE; } if (strcmp("CELL", type_opt->answer) == 0) rtype = CELL_TYPE; else if (strcmp("DCELL", type_opt->answer) == 0) rtype = DCELL_TYPE; else rtype = FCELL_TYPE; if (method == METHOD_N) rtype = CELL_TYPE; G_get_window(®ion); rows = (int)(region.rows * (percent / 100.0)); cols = region.cols; G_debug(2, "region.n=%f region.s=%f region.ns_res=%f", region.north, region.south, region.ns_res); G_debug(2, "region.rows=%d [box_rows=%d] region.cols=%d", region.rows, rows, region.cols); npasses = (int)ceil(1.0 * region.rows / rows); if (!scan_flag->answer) { /* allocate memory (test for enough before we start) */ if (bin_n) n_array = G_calloc(rows * (cols + 1), G_raster_size(CELL_TYPE)); if (bin_min) min_array = G_calloc(rows * (cols + 1), G_raster_size(rtype)); if (bin_max) max_array = G_calloc(rows * (cols + 1), G_raster_size(rtype)); if (bin_sum) sum_array = G_calloc(rows * (cols + 1), G_raster_size(rtype)); if (bin_sumsq) sumsq_array = G_calloc(rows * (cols + 1), G_raster_size(rtype)); if (bin_index) index_array = G_calloc(rows * (cols + 1), G_raster_size(CELL_TYPE)); /* and then free it again */ if (bin_n) G_free(n_array); if (bin_min) G_free(min_array); if (bin_max) G_free(max_array); if (bin_sum) G_free(sum_array); if (bin_sumsq) G_free(sumsq_array); if (bin_index) G_free(index_array); /** end memory test **/ } /* open input file */ if (strcmp("-", infile) == 0) { from_stdin = TRUE; in_fp = stdin; infile = G_store("stdin"); /* filename for history metadata */ } else { if ((in_fp = fopen(infile, "r")) == NULL) G_fatal_error(_("Unable to open input file <%s>"), infile); } can_seek = fseek(in_fp, 0, SEEK_SET) == 0; /* can't rewind() non-files */ if (!can_seek && npasses != 1) { G_warning(_("If input is not from a file it is only possible to perform a single pass.")); npasses = 1; } if (scan_flag->answer) { if (zrange_opt->answer) G_warning(_("zrange will not be taken into account during scan")); scan_bounds(in_fp, xcol, ycol, zcol, fs, shell_style->answer, skipline->answer, zscale); if (!from_stdin) fclose(in_fp); exit(EXIT_SUCCESS); } /* open output map */ out_fd = G_open_raster_new(outmap, rtype); if (out_fd < 0) G_fatal_error(_("Unable to create raster map <%s>"), outmap); if (can_seek) { /* guess at number of lines in the file without actually reading it all in */ for (line = 0; line < 10; line++) { /* arbitrarily use 10th line for guess */ if (0 == G_getl2(buff, BUFFSIZE - 1, in_fp)) break; linesize = strlen(buff) + 1; } fseek(in_fp, 0L, SEEK_END); filesize = ftell(in_fp); rewind(in_fp); if (linesize < 6) /* min possible: "0,0,0\n" */ linesize = 6; estimated_lines = filesize / linesize; G_debug(2, "estimated number of lines in file: %ld", estimated_lines); } else estimated_lines = -1; /* allocate memory for a single row of output data */ raster_row = G_allocate_raster_buf(rtype); G_message(_("Reading data ...")); count_total = 0; /* main binning loop(s) */ for (pass = 1; pass <= npasses; pass++) { if (npasses > 1) G_message(_("Pass #%d (of %d) ..."), pass, npasses); if (can_seek) rewind(in_fp); /* figure out segmentation */ pass_north = region.north - (pass - 1) * rows * region.ns_res; if (pass == npasses) rows = region.rows - (pass - 1) * rows; pass_south = pass_north - rows * region.ns_res; G_debug(2, "pass=%d/%d pass_n=%f pass_s=%f rows=%d", pass, npasses, pass_north, pass_south, rows); if (bin_n) { G_debug(2, "allocating n_array"); n_array = G_calloc(rows * (cols + 1), G_raster_size(CELL_TYPE)); blank_array(n_array, rows, cols, CELL_TYPE, 0); } if (bin_min) { G_debug(2, "allocating min_array"); min_array = G_calloc(rows * (cols + 1), G_raster_size(rtype)); blank_array(min_array, rows, cols, rtype, -1); /* fill with NULLs */ } if (bin_max) { G_debug(2, "allocating max_array"); max_array = G_calloc(rows * (cols + 1), G_raster_size(rtype)); blank_array(max_array, rows, cols, rtype, -1); /* fill with NULLs */ } if (bin_sum) { G_debug(2, "allocating sum_array"); sum_array = G_calloc(rows * (cols + 1), G_raster_size(rtype)); blank_array(sum_array, rows, cols, rtype, 0); } if (bin_sumsq) { G_debug(2, "allocating sumsq_array"); sumsq_array = G_calloc(rows * (cols + 1), G_raster_size(rtype)); blank_array(sumsq_array, rows, cols, rtype, 0); } if (bin_index) { G_debug(2, "allocating index_array"); index_array = G_calloc(rows * (cols + 1), G_raster_size(CELL_TYPE)); blank_array(index_array, rows, cols, CELL_TYPE, -1); /* fill with NULLs */ } line = 0; count = 0; G_percent_reset(); while (0 != G_getl2(buff, BUFFSIZE - 1, in_fp)) { line++; if (line % 10000 == 0) { /* mod for speed */ if (!can_seek) G_clicker(); else if (line < estimated_lines) G_percent(line, estimated_lines, 3); } if ((buff[0] == '#') || (buff[0] == '\0')) { continue; /* line is a comment or blank */ } G_chop(buff); /* remove leading and trailing whitespace from the string. unneded?? */ tokens = G_tokenize(buff, fs); ntokens = G_number_of_tokens(tokens); if ((ntokens < 3) || (max_col > ntokens)) { if (skipline->answer) { G_warning(_("Not enough data columns. " "Incorrect delimiter or column number? " "Found the following character(s) in row %lu:\n[%s]"), line, buff); G_warning(_("Line ignored as requested")); continue; /* line is garbage */ } else { G_fatal_error(_("Not enough data columns. " "Incorrect delimiter or column number? " "Found the following character(s) in row %lu:\n[%s]"), line, buff); } } /* too slow? if ( G_projection() == PROJECTION_LL ) { G_scan_easting( tokens[xcol-1], &x, region.proj); G_scan_northing( tokens[ycol-1], &y, region.proj); } else { */ if (1 != sscanf(tokens[ycol - 1], "%lf", &y)) G_fatal_error(_("Bad y-coordinate line %lu column %d. <%s>"), line, ycol, tokens[ycol - 1]); if (y <= pass_south || y > pass_north) { G_free_tokens(tokens); continue; } if (1 != sscanf(tokens[xcol - 1], "%lf", &x)) G_fatal_error(_("Bad x-coordinate line %lu column %d. <%s>"), line, xcol, tokens[xcol - 1]); if (x < region.west || x > region.east) { G_free_tokens(tokens); continue; } if (1 != sscanf(tokens[zcol - 1], "%lf", &z)) G_fatal_error(_("Bad z-coordinate line %lu column %d. <%s>"), line, zcol, tokens[zcol - 1]); z = z * zscale; if (zrange_opt->answer) { if (z < zrange_min || z > zrange_max) { G_free_tokens(tokens); continue; } } count++; /* G_debug(5, "x: %f, y: %f, z: %f", x, y, z); */ G_free_tokens(tokens); /* find the bin in the current array box */ arr_row = (int)((pass_north - y) / region.ns_res); arr_col = (int)((x - region.west) / region.ew_res); /* G_debug(5, "arr_row: %d arr_col: %d", arr_row, arr_col); */ /* The range should be [0,cols-1]. We use (int) to round down, but if the point exactly on eastern edge arr_col will be /just/ on the max edge .0000000 and end up on the next row. We could make above bounds check "if(x>=region.east) continue;" But instead we go to all sorts of trouble so that not one single data point is lost. GE is too small to catch them all. We don't try to make y happy as percent segmenting will make some points happen twice that way; so instead we use the y<= test above. */ if (arr_col >= cols) { if (((x - region.west) / region.ew_res) - cols < 10 * GRASS_EPSILON) arr_col--; else { /* oh well, we tried. */ G_debug(3, "skipping extraneous data point [%.3f], column %d of %d", x, arr_col, cols); continue; } } if (bin_n) update_n(n_array, cols, arr_row, arr_col); if (bin_min) update_min(min_array, cols, arr_row, arr_col, rtype, z); if (bin_max) update_max(max_array, cols, arr_row, arr_col, rtype, z); if (bin_sum) update_sum(sum_array, cols, arr_row, arr_col, rtype, z); if (bin_sumsq) update_sumsq(sumsq_array, cols, arr_row, arr_col, rtype, z); if (bin_index) { ptr = index_array; ptr = G_incr_void_ptr(ptr, ((arr_row * cols) + arr_col) * G_raster_size(CELL_TYPE)); if (G_is_null_value(ptr, CELL_TYPE)) { /* first node */ head_id = new_node(); nodes[head_id].next = -1; nodes[head_id].z = z; G_set_raster_value_c(ptr, head_id, CELL_TYPE); /* store index to head */ } else { /* head is already there */ head_id = G_get_raster_value_c(ptr, CELL_TYPE); /* get index to head */ head_id = add_node(head_id, z); if (head_id != -1) G_set_raster_value_c(ptr, head_id, CELL_TYPE); /* store index to head */ } } } /* while !EOF */ G_percent(1, 1, 1); /* flush */ G_debug(2, "pass %d finished, %lu coordinates in box", pass, count); count_total += count; /* calc stats and output */ G_message(_("Writing to map ...")); for (row = 0; row < rows; row++) { switch (method) { case METHOD_N: /* n is a straight copy */ G_raster_cpy(raster_row, n_array + (row * cols * G_raster_size(CELL_TYPE)), cols, CELL_TYPE); break; case METHOD_MIN: G_raster_cpy(raster_row, min_array + (row * cols * G_raster_size(rtype)), cols, rtype); break; case METHOD_MAX: G_raster_cpy(raster_row, max_array + (row * cols * G_raster_size(rtype)), cols, rtype); break; case METHOD_SUM: G_raster_cpy(raster_row, sum_array + (row * cols * G_raster_size(rtype)), cols, rtype); break; case METHOD_RANGE: /* (max-min) */ ptr = raster_row; for (col = 0; col < cols; col++) { offset = (row * cols + col) * G_raster_size(rtype); min = G_get_raster_value_d(min_array + offset, rtype); max = G_get_raster_value_d(max_array + offset, rtype); G_set_raster_value_d(ptr, max - min, rtype); ptr = G_incr_void_ptr(ptr, G_raster_size(rtype)); } break; case METHOD_MEAN: /* (sum / n) */ ptr = raster_row; for (col = 0; col < cols; col++) { offset = (row * cols + col) * G_raster_size(rtype); n_offset = (row * cols + col) * G_raster_size(CELL_TYPE); n = G_get_raster_value_c(n_array + n_offset, CELL_TYPE); sum = G_get_raster_value_d(sum_array + offset, rtype); if (n == 0) G_set_null_value(ptr, 1, rtype); else G_set_raster_value_d(ptr, (sum / n), rtype); ptr = G_incr_void_ptr(ptr, G_raster_size(rtype)); } break; case METHOD_STDDEV: /* sqrt(variance) */ case METHOD_VARIANCE: /* (sumsq - sum*sum/n)/n */ case METHOD_COEFF_VAR: /* 100 * stdev / mean */ ptr = raster_row; for (col = 0; col < cols; col++) { offset = (row * cols + col) * G_raster_size(rtype); n_offset = (row * cols + col) * G_raster_size(CELL_TYPE); n = G_get_raster_value_c(n_array + n_offset, CELL_TYPE); sum = G_get_raster_value_d(sum_array + offset, rtype); sumsq = G_get_raster_value_d(sumsq_array + offset, rtype); if (n == 0) G_set_null_value(ptr, 1, rtype); else { variance = (sumsq - sum * sum / n) / n; if (variance < GRASS_EPSILON) variance = 0.0; if (method == METHOD_STDDEV) G_set_raster_value_d(ptr, sqrt(variance), rtype); else if (method == METHOD_VARIANCE) G_set_raster_value_d(ptr, variance, rtype); else if (method == METHOD_COEFF_VAR) G_set_raster_value_d(ptr, 100 * sqrt(variance) / (sum / n), rtype); } ptr = G_incr_void_ptr(ptr, G_raster_size(rtype)); } break; case METHOD_MEDIAN: /* median, if only one point in cell we will use that */ ptr = raster_row; for (col = 0; col < cols; col++) { n_offset = (row * cols + col) * G_raster_size(CELL_TYPE); if (G_is_null_value(index_array + n_offset, CELL_TYPE)) /* no points in cell */ G_set_null_value(ptr, 1, rtype); else { /* one or more points in cell */ head_id = G_get_raster_value_c(index_array + n_offset, CELL_TYPE); node_id = head_id; n = 0; while (node_id != -1) { /* count number of points in cell */ n++; node_id = nodes[node_id].next; } if (n == 1) /* only one point, use that */ G_set_raster_value_d(ptr, nodes[head_id].z, rtype); else if (n % 2 != 0) { /* odd number of points: median_i = (n + 1) / 2 */ n = (n + 1) / 2; node_id = head_id; for (j = 1; j < n; j++) /* get "median element" */ node_id = nodes[node_id].next; G_set_raster_value_d(ptr, nodes[node_id].z, rtype); } else { /* even number of points: median = (val_below + val_above) / 2 */ z = (n + 1) / 2.0; n = floor(z); node_id = head_id; for (j = 1; j < n; j++) /* get element "below" */ node_id = nodes[node_id].next; z = (nodes[node_id].z + nodes[nodes[node_id].next].z) / 2; G_set_raster_value_d(ptr, z, rtype); } } ptr = G_incr_void_ptr(ptr, G_raster_size(rtype)); } break; case METHOD_PERCENTILE: /* rank = (pth*(n+1))/100; interpolate linearly */ ptr = raster_row; for (col = 0; col < cols; col++) { n_offset = (row * cols + col) * G_raster_size(CELL_TYPE); if (G_is_null_value(index_array + n_offset, CELL_TYPE)) /* no points in cell */ G_set_null_value(ptr, 1, rtype); else { head_id = G_get_raster_value_c(index_array + n_offset, CELL_TYPE); node_id = head_id; n = 0; while (node_id != -1) { /* count number of points in cell */ n++; node_id = nodes[node_id].next; } z = (pth * (n + 1)) / 100.0; r_low = floor(z); /* lower rank */ if (r_low < 1) r_low = 1; else if (r_low > n) r_low = n; r_up = ceil(z); /* upper rank */ if (r_up > n) r_up = n; node_id = head_id; for (j = 1; j < r_low; j++) /* search lower value */ node_id = nodes[node_id].next; z = nodes[node_id].z; /* save lower value */ node_id = head_id; for (j = 1; j < r_up; j++) /* search upper value */ node_id = nodes[node_id].next; z = (z + nodes[node_id].z) / 2; G_set_raster_value_d(ptr, z, rtype); } ptr = G_incr_void_ptr(ptr, G_raster_size(rtype)); } break; case METHOD_SKEWNESS: /* skewness = sum(xi-mean)^3/(N-1)*s^3 */ ptr = raster_row; for (col = 0; col < cols; col++) { n_offset = (row * cols + col) * G_raster_size(CELL_TYPE); if (G_is_null_value(index_array + n_offset, CELL_TYPE)) /* no points in cell */ G_set_null_value(ptr, 1, rtype); else { head_id = G_get_raster_value_c(index_array + n_offset, CELL_TYPE); node_id = head_id; n = 0; /* count */ sum = 0.0; /* sum */ sumsq = 0.0; /* sum of squares */ sumdev = 0.0; /* sum of (xi - mean)^3 */ skew = 0.0; /* skewness */ while (node_id != -1) { z = nodes[node_id].z; n++; sum += z; sumsq += (z * z); node_id = nodes[node_id].next; } if (n > 1) { /* if n == 1, skew is "0.0" */ mean = sum / n; node_id = head_id; while (node_id != -1) { z = nodes[node_id].z; sumdev += pow((z - mean), 3); node_id = nodes[node_id].next; } variance = (sumsq - sum * sum / n) / n; if (variance < GRASS_EPSILON) skew = 0.0; else skew = sumdev / ((n - 1) * pow(sqrt(variance), 3)); } G_set_raster_value_d(ptr, skew, rtype); } ptr = G_incr_void_ptr(ptr, G_raster_size(rtype)); } break; case METHOD_TRIMMEAN: ptr = raster_row; for (col = 0; col < cols; col++) { n_offset = (row * cols + col) * G_raster_size(CELL_TYPE); if (G_is_null_value(index_array + n_offset, CELL_TYPE)) /* no points in cell */ G_set_null_value(ptr, 1, rtype); else { head_id = G_get_raster_value_c(index_array + n_offset, CELL_TYPE); node_id = head_id; n = 0; while (node_id != -1) { /* count number of points in cell */ n++; node_id = nodes[node_id].next; } if (1 == n) mean = nodes[head_id].z; else { k = floor(trim * n + 0.5); /* number of ranks to discard on each tail */ if (k > 0 && (n - 2 * k) > 0) { /* enough elements to discard */ node_id = head_id; for (j = 0; j < k; j++) /* move to first rank to consider */ node_id = nodes[node_id].next; j = k + 1; k = n - k; n = 0; sum = 0.0; while (j <= k) { /* get values in interval */ n++; sum += nodes[node_id].z; node_id = nodes[node_id].next; j++; } } else { node_id = head_id; n = 0; sum = 0.0; while (node_id != -1) { n++; sum += nodes[node_id].z; node_id = nodes[node_id].next; } } mean = sum / n; } G_set_raster_value_d(ptr, mean, rtype); } ptr = G_incr_void_ptr(ptr, G_raster_size(rtype)); } break; default: G_fatal_error("?"); } /* write out line of raster data */ if (1 != G_put_raster_row(out_fd, raster_row, rtype)) { G_close_cell(out_fd); G_fatal_error(_("Writing map, row %d"), ((pass - 1) * rows) + row); } } /* free memory */ if (bin_n) G_free(n_array); if (bin_min) G_free(min_array); if (bin_max) G_free(max_array); if (bin_sum) G_free(sum_array); if (bin_sumsq) G_free(sumsq_array); if (bin_index) { G_free(index_array); G_free(nodes); num_nodes = 0; max_nodes = 0; nodes = NULL; } } /* passes loop */ G_percent(1, 1, 1); /* flush */ G_free(raster_row); /* close input file */ if (!from_stdin) fclose(in_fp); /* close raster file & write history */ G_close_cell(out_fd); sprintf(title, "Raw x,y,z data binned into a raster grid by cell %s", method_opt->answer); G_put_cell_title(outmap, title); G_short_history(outmap, "raster", &history); G_command_history(&history); strncpy(history.datsrc_1, infile, RECORD_LEN); history.datsrc_1[RECORD_LEN - 1] = '\0'; /* strncpy() doesn't null terminate if maxfill */ G_write_history(outmap, &history); sprintf(buff, _("%lu points found in region."), count_total); G_done_msg(buff); G_debug(1, "Processed %lu lines.", line); exit(EXIT_SUCCESS); }
static int cell_draw( char *name, char *mapset, struct Colors *colors, RASTER_MAP_TYPE data_type, char *format ) { int cellfile; void *xarray = 0; int row; int ncols, nrows; static unsigned char *red, *grn, *blu, *set; int i; void *ptr = 0; int big_endian; long one = 1; FILE *fo = 0; size_t raster_size; #ifdef NAN double dnul = NAN; float fnul = ( float )( NAN ); #else double dnul = strtod( "NAN", 0 ); float fnul = strtof( "NAN", 0 ); // another possibility would be nan()/nanf() - C99 // and 0./0. if all fails #endif assert( dnul != dnul ); assert( fnul != fnul ); big_endian = !( *( ( char * )( &one ) ) ); ncols = G_window_cols(); nrows = G_window_rows(); /* Make sure map is available */ if ( ( cellfile = G_open_cell_old( name, mapset ) ) == -1 ) G_fatal_error( ( "Unable to open raster map <%s>" ), name ); /* Allocate space for cell buffer */ xarray = G_allocate_raster_buf( data_type ); red = G_malloc( ncols ); grn = G_malloc( ncols ); blu = G_malloc( ncols ); set = G_malloc( ncols ); /* some buggy C libraries require BOTH setmode() and fdopen(bin) */ // Do not use Q_OS_WIN, we are in C file, no Qt headers #ifdef WIN32 if ( _setmode( _fileno( stdout ), _O_BINARY ) == -1 ) G_fatal_error( "Cannot set stdout mode" ); #endif // Unfortunately this is not sufficient on Windows to switch stdout to binary mode fo = fdopen( fileno( stdout ), "wb" ); raster_size = G_raster_size( data_type ); //fprintf( fo, "%d %d", data_type, raster_size ); //exit(0); /* loop for array rows */ for ( row = 0; row < nrows; row++ ) { G_get_raster_row( cellfile, xarray, row, data_type ); ptr = xarray; G_lookup_raster_colors( xarray, red, grn, blu, set, ncols, colors, data_type ); for ( i = 0; i < ncols; i++ ) { unsigned char alpha = 255; //G_debug ( 0, "row = %d col = %d", row, i ); if ( G_is_null_value( ptr, data_type ) ) { alpha = 0; } if ( strcmp( format, "color" ) == 0 ) { // We need data suitable for QImage 32-bpp // the data are stored in QImage as QRgb which is unsigned int. // Because it depends on byte order of the platform we have to // consider byte order (well, middle endian ignored) if ( big_endian ) { // I have never tested this fprintf( fo, "%c%c%c%c", alpha, red[i], grn[i], blu[i] ); } else { fprintf( fo, "%c%c%c%c", blu[i], grn[i], red[i], alpha ); } } else { if ( data_type == CELL_TYPE ) { //G_debug ( 0, "valx = %d", *((CELL *) ptr)); } if ( G_is_null_value( ptr, data_type ) ) { // see comments in QgsGrassRasterProvider::noDataValue() if ( data_type == CELL_TYPE ) { //int nul = -2000000000; int nul = INT_MIN; fwrite( &nul, 4, 1, fo ); } else if ( data_type == DCELL_TYPE ) { //double nul = -1e+300; fwrite( &dnul, 8, 1, fo ); } else if ( data_type == FCELL_TYPE ) { //double nul = -1e+30; fwrite( &fnul, 4, 1, fo ); } } else { fwrite( ptr, raster_size, 1, fo ); } } ptr = G_incr_void_ptr( ptr, raster_size ); } } G_close_cell( cellfile ); fclose( fo ); return ( 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; }