int G_read_colors(const char *name, const char *mapset, struct Colors *colors) { int fp; char buf[GNAME_MAX]; char *err; char xname[GNAME_MAX]; struct Range range; struct FPRange drange; CELL min, max; DCELL dmin, dmax; fp = G_raster_map_is_fp(name, mapset); G_init_colors(colors); strcpy(xname, name); mapset = G_find_cell(xname, mapset); name = xname; if (fp) G_mark_colors_as_fp(colors); /* first look for secondary color table in current mapset */ sprintf(buf, "colr2/%s", mapset); if (read_colors(buf, name, G_mapset(), colors) >= 0) return 1; /* now look for the regular color table */ switch (read_colors("colr", name, mapset, colors)) { case -2: if (!fp) { if (G_read_range(name, mapset, &range) >= 0) { G_get_range_min_max(&range, &min, &max); if (!G_is_c_null_value(&min) && !G_is_c_null_value(&max)) G_make_rainbow_colors(colors, min, max); return 0; } } else { if (G_read_fp_range(name, mapset, &drange) >= 0) { G_get_fp_range_min_max(&drange, &dmin, &dmax); if (!G_is_d_null_value(&dmin) && !G_is_d_null_value(&dmax)) G_make_rainbow_fp_colors(colors, dmin, dmax); return 0; } } err = "missing"; break; case -1: err = "invalid"; break; default: return 1; } G_warning(_("color support for [%s] in mapset [%s] %s"), name, mapset, err); return -1; }
int G_quantize_fp_map(const char *name, const char *mapset, CELL min, CELL max) { char buf[300]; DCELL d_min, d_max; struct FPRange fp_range; if (G_read_fp_range(name, mapset, &fp_range) < 0) { sprintf(buf, "G_quantize_fp_map: can't read fp range for map %s", name); G_warning(buf); return -1; } G_get_fp_range_min_max(&fp_range, &d_min, &d_max); if (G_is_d_null_value(&d_min) || G_is_d_null_value(&d_max)) { sprintf(buf, "G_quantize_fp_map: raster map %s is empty", name); G_warning(buf); return -1; } return G_quantize_fp_map_range(name, mapset, d_min, d_max, min, max); }
GRASSRasterBand::GRASSRasterBand( GRASSDataset *poDS, int nBand, const char * pszMapset, const char * pszCellName ) { struct Cell_head sCellInfo; // Note: GISDBASE, LOCATION_NAME ans MAPSET was set in GRASSDataset::Open this->poDS = poDS; this->nBand = nBand; this->valid = false; this->pszCellName = G_store ( (char *) pszCellName ); this->pszMapset = G_store ( (char *) pszMapset ); G_get_cellhd( (char *) pszCellName, (char *) pszMapset, &sCellInfo ); nGRSType = G_raster_map_type( (char *) pszCellName, (char *) pszMapset ); /* -------------------------------------------------------------------- */ /* Get min/max values. */ /* -------------------------------------------------------------------- */ struct FPRange sRange; if( G_read_fp_range( (char *) pszCellName, (char *) pszMapset, &sRange ) == -1 ) { bHaveMinMax = FALSE; } else { bHaveMinMax = TRUE; G_get_fp_range_min_max( &sRange, &dfCellMin, &dfCellMax ); } /* -------------------------------------------------------------------- */ /* Setup band type, and preferred nodata value. */ /* -------------------------------------------------------------------- */ // Negative values are also (?) stored as 4 bytes (format = 3) // => raster with format < 3 has only positive values // GRASS modules usually do not waste space and only the format necessary to keep // full raster values range is used -> no checks if shorter type could be used if( nGRSType == CELL_TYPE ) { if ( sCellInfo.format == 0 ) { // 1 byte / cell -> possible range 0,255 if ( bHaveMinMax && dfCellMin > 0 ) { this->eDataType = GDT_Byte; dfNoData = 0.0; } else if ( bHaveMinMax && dfCellMax < 255 ) { this->eDataType = GDT_Byte; dfNoData = 255.0; } else { // maximum is not known or full range is used this->eDataType = GDT_UInt16; dfNoData = 256.0; } nativeNulls = false; } else if ( sCellInfo.format == 1 ) { // 2 bytes / cell -> possible range 0,65535 if ( bHaveMinMax && dfCellMin > 0 ) { this->eDataType = GDT_UInt16; dfNoData = 0.0; } else if ( bHaveMinMax && dfCellMax < 65535 ) { this->eDataType = GDT_UInt16; dfNoData = 65535; } else { // maximum is not known or full range is used CELL cval; this->eDataType = GDT_Int32; G_set_c_null_value ( &cval, 1); dfNoData = (double) cval; nativeNulls = true; } nativeNulls = false; } else { // 3-4 bytes CELL cval; this->eDataType = GDT_Int32; G_set_c_null_value ( &cval, 1); dfNoData = (double) cval; nativeNulls = true; } } else if( nGRSType == FCELL_TYPE ) { FCELL fval; this->eDataType = GDT_Float32; G_set_f_null_value ( &fval, 1); dfNoData = (double) fval; nativeNulls = true; } else if( nGRSType == DCELL_TYPE ) { DCELL dval; this->eDataType = GDT_Float64; G_set_d_null_value ( &dval, 1); dfNoData = (double) dval; nativeNulls = true; } nBlockXSize = poDS->nRasterXSize;; nBlockYSize = 1; G_set_window( &(((GRASSDataset *)poDS)->sCellInfo) ); if ( (hCell = G_open_cell_old((char *) pszCellName, (char *) pszMapset)) < 0 ) { CPLError( CE_Warning, CPLE_AppDefined, "GRASS: Cannot open raster '%s'", pszCellName ); return; } G_copy((void *) &sOpenWindow, (void *) &(((GRASSDataset *)poDS)->sCellInfo), sizeof(struct Cell_head)); /* -------------------------------------------------------------------- */ /* Do we have a color table? */ /* -------------------------------------------------------------------- */ poCT = NULL; if( G_read_colors( (char *) pszCellName, (char *) pszMapset, &sGrassColors ) == 1 ) { int maxcolor; CELL min, max; G_get_color_range ( &min, &max, &sGrassColors); if ( bHaveMinMax ) { if ( max < dfCellMax ) { maxcolor = max; } else { maxcolor = (int) ceil ( dfCellMax ); } if ( maxcolor > GRASS_MAX_COLORS ) { maxcolor = GRASS_MAX_COLORS; CPLDebug( "GRASS", "Too many values, color table cut to %d entries.", maxcolor ); } } else { if ( max < GRASS_MAX_COLORS ) { maxcolor = max; } else { maxcolor = GRASS_MAX_COLORS; CPLDebug( "GRASS", "Too many values, color table set to %d entries.", maxcolor ); } } poCT = new GDALColorTable(); for( int iColor = 0; iColor <= maxcolor; iColor++ ) { int nRed, nGreen, nBlue; GDALColorEntry sColor; #if GRASS_VERSION_MAJOR >= 7 if( Rast_get_c_color( &iColor, &nRed, &nGreen, &nBlue, &sGrassColors ) ) #else if( G_get_color( iColor, &nRed, &nGreen, &nBlue, &sGrassColors ) ) #endif { sColor.c1 = nRed; sColor.c2 = nGreen; sColor.c3 = nBlue; sColor.c4 = 255; poCT->SetColorEntry( iColor, &sColor ); } else { sColor.c1 = 0; sColor.c2 = 0; sColor.c3 = 0; sColor.c4 = 0; poCT->SetColorEntry( iColor, &sColor ); } } /* Create metadata enries for color table rules */ char key[200], value[200]; int rcount = G_colors_count ( &sGrassColors ); sprintf ( value, "%d", rcount ); this->SetMetadataItem( "COLOR_TABLE_RULES_COUNT", value ); /* Add the rules in reverse order */ for ( int i = rcount-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, &sGrassColors, i ); sprintf ( key, "COLOR_TABLE_RULE_RGB_%d", rcount-i-1 ); sprintf ( value, "%e %e %d %d %d %d %d %d", val1, val2, r1, g1, b1, r2, g2, b2 ); this->SetMetadataItem( key, value ); } } else { this->SetMetadataItem( "COLOR_TABLE_RULES_COUNT", "0" ); } this->valid = true; }
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 ); }
int E_edit_fp_cats(const char *name, struct Categories *cats) { long incr; long atnum; long startcat; long endcat; char buff[NLINES][60]; char next[20]; char next_line[80]; char title[80]; char msg1[80]; char msg2[80]; int line, ncats; size_t lab_len; DCELL max_val[NLINES], min_val[NLINES]; DCELL dmin, dmax; CELL tmp_cell; struct Categories old_cats; struct FPRange fp_range; if (G_read_fp_range(name, G_mapset(), &fp_range) < 0) G_fatal_error("can't read the floating point range for %s", name); G_get_fp_range_min_max(&fp_range, &dmin, &dmax); /* first save old cats */ G_copy_raster_cats(&old_cats, cats); G_init_raster_cats(old_cats.title, cats); G_free_raster_cats(cats); ncats = old_cats.ncats; V_clear(); if (!ncats) sprintf(msg1, "There are no predefined fp ranges to label"); else sprintf(msg1, "There are %d predefined fp ranges to label", ncats); sprintf(msg2, "Enter the number of fp ranges you want to label"); V_line(1, msg1); V_line(2, msg2); V_ques(&ncats, 'l', 2, 48, 5); V_line(16, next_line); *next_line = 0; V_intrpt_ok(); if (!V_call()) return -1; *title = 0; if (old_cats.title != NULL) strcpy(title, old_cats.title); startcat = 0; sprintf(msg1, "The fp data in map %s ranges from %f to %f", name, dmin, dmax); sprintf(msg2, "[%s] ENTER NEW CATEGORY NAMES FOR THESE CATEGORIES", name); while (1) { V_clear(); V_line(0, msg1); V_line(1, msg2); V_line(3, "TITLE: "); V_line(4, "FP RANGE NEW CATEGORY NAME"); V_ques(title, 's', 2, 8, 60); endcat = startcat + NLINES <= ncats ? startcat + NLINES : ncats; line = 6; for (incr = startcat; incr < endcat; incr++) { atnum = incr - startcat; if (incr < old_cats.ncats) { /* if editing existing range label */ lab_len = strlen(old_cats.labels[incr]); if (lab_len > 58) lab_len = 58; strncpy(buff[atnum], old_cats.labels[incr], lab_len); buff[atnum][lab_len] = 0; G_quant_get_ith_rule(&old_cats.q, incr, &min_val[atnum], &max_val[atnum], &tmp_cell, &tmp_cell); } else { /* adding new range label */ strcpy(buff[atnum], ""); max_val[atnum] = min_val[atnum] = 0; } V_ques(&min_val[atnum], 'd', line, 1, 8); V_const("-", 's', line, 9, 1); V_ques(&max_val[atnum], 'd', line, 10, 8); V_ques(buff[atnum], 's', line, 19, 58); line++; } line += 2; *next = 0; if (endcat >= ncats) strcpy(next, "end"); else sprintf(next, "%ld", endcat); sprintf(next_line, "%*s%*s (of %d)", 41, "Next range number ('end' to end): ", 5, "", ncats); V_line(line, next_line); V_ques(next, 's', line, 41, 5); V_intrpt_ok(); if (!V_call()) return -1; /* store new category name in structure */ for (incr = startcat; incr < endcat; incr++) { atnum = incr - startcat; G_strip(buff[atnum]); /* adding new range label */ if (!(strcmp(buff[atnum], "") == 0 && min_val[atnum] == 0. && max_val[atnum] == 0.)) G_set_d_raster_cat(&min_val[atnum], &max_val[atnum], buff[atnum], cats); } if (*next == 0) break; if (strcmp(next, "end") == 0) break; if (sscanf(next, "%ld", &endcat) != 1) continue; if (endcat < 0) endcat = 0; if (endcat > ncats) { endcat = ncats - NLINES + 1; if (endcat < 0) endcat = 0; } startcat = endcat; } G_strip(title); cats->title = G_store(title); /* since label pointers in old_cats point to the old allocated strings, and cats now has all the newly allocated strings, it never reuses old ones, we need to free them */ return (1); }
int describe(char *name, char *mapset, int compact, char *no_data_str, int range, int windowed, int nsteps, int as_int, int skip_nulls) { int fd; struct Cell_stats statf; CELL *buf, *b; int nrows, ncols; int row, col; struct Cell_head window; CELL negmin = 0, negmax = 0, zero = 0, posmin = 0, posmax = 0; CELL null = 0; RASTER_MAP_TYPE map_type; struct Quant q; struct FPRange r; DCELL dmin, dmax; int (*get_row) (); if (windowed) { get_row = G_get_c_raster_row; } else { char msg[100]; if (G_get_cellhd(name, mapset, &window) < 0) { sprintf(msg, "can't get cell header for [%s] in [%s]", name, mapset); G_fatal_error(msg); } G_set_window(&window); get_row = G_get_c_raster_row_nomask; } fd = G_open_cell_old(name, mapset); if (fd < 0) return 0; map_type = G_get_raster_map_type(fd); if (as_int) map_type = CELL_TYPE; /* read as int */ /* allocate the cell buffer */ buf = G_allocate_cell_buf(); if (map_type != CELL_TYPE && range) /* this will make it report fp range */ { range = 0; nsteps = 1; } /* start the cell stats */ if (!range) { G_init_cell_stats(&statf); } else { zero = 0; negmin = 0; negmax = 0; posmin = 0; posmax = 0; null = 0; dmin = 0.0; dmax = 0.0; } /* set up quantization rules */ if (map_type != CELL_TYPE) { G_quant_init(&q); G_read_fp_range(name, mapset, &r); G_get_fp_range_min_max(&r, &dmin, &dmax); G_quant_add_rule(&q, dmin, dmax, 1, nsteps); G_set_quant_rules(fd, &q); } nrows = G_window_rows(); ncols = G_window_cols(); G_verbose_message("Reading [%s in %s] ...", name, mapset); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); if ((*get_row) (fd, b = buf, row) < 0) break; if (range) { for (col = ncols; col-- > 0; b++) { if (G_is_c_null_value(b)) null = 1; else if (*b == 0) zero = 1; else if (*b < 0) { if (!negmin) negmin = negmax = *b; else if (*b > negmax) negmax = *b; else if (*b < negmin) negmin = *b; } else { if (!posmin) posmin = posmax = *b; else if (*b > posmax) posmax = *b; else if (*b < posmin) posmin = *b; } } } else G_update_cell_stats(buf, ncols, &statf); } G_percent(nrows, nrows, 2); G_close_cell(fd); G_free(buf); if (range) { if (compact) compact_range_list(negmin, negmax, zero, posmin, posmax, null, no_data_str, skip_nulls); else range_list(negmin, negmax, zero, posmin, posmax, null, no_data_str, skip_nulls); } else { G_rewind_cell_stats(&statf); if (compact) compact_list(&statf, dmin, dmax, no_data_str, skip_nulls, map_type, nsteps); else long_list(&statf, dmin, dmax, no_data_str, skip_nulls, map_type, nsteps); G_free_cell_stats(&statf); } return 1; }
int main(int argc, char **argv) { int overwrite; int interactive; int remove; int have_colors; struct Colors colors, colors_tmp; struct Cell_stats statf; int have_stats = 0; struct FPRange range; DCELL min, max; char *name, *mapset; char *style, *cmap, *cmapset; char *rules; int fp; struct GModule *module; struct { struct Flag *r, *w, *l, *g, *a, *e, *i, *q, *n; } flag; struct { struct Option *map, *colr, *rast, *rules; } opt; G_gisinit(argv[0]); module = G_define_module(); module->keywords = _("raster, color table"); module->description = _("Creates/modifies the color table associated with a raster map layer."); opt.map = G_define_standard_option(G_OPT_R_MAP); opt.map->required = NO; opt.map->guisection = _("Required"); scan_rules(); opt.colr = G_define_option(); opt.colr->key = "color"; opt.colr->key_desc = "style"; opt.colr->type = TYPE_STRING; opt.colr->required = NO; opt.colr->options = rules_list(); opt.colr->description = _("Type of color table"); opt.colr->descriptions = rules_descriptions(); opt.colr->guisection = _("Colors"); opt.rast = G_define_option(); opt.rast->key = "raster"; opt.rast->type = TYPE_STRING; opt.rast->required = NO; opt.rast->gisprompt = "old,cell,raster"; opt.rast->description = _("Raster map name from which to copy color table"); opt.rules = G_define_standard_option(G_OPT_F_INPUT); opt.rules->key = "rules"; opt.rules->required = NO; opt.rules->description = _("Path to rules file (\"-\" to read rules from stdin)"); opt.rules->guisection = _("Colors"); flag.r = G_define_flag(); flag.r->key = 'r'; flag.r->description = _("Remove existing color table"); flag.w = G_define_flag(); flag.w->key = 'w'; flag.w->description = _("Only write new color table if one doesn't already exist"); flag.l = G_define_flag(); flag.l->key = 'l'; flag.l->description = _("List available rules then exit"); flag.n = G_define_flag(); flag.n->key = 'n'; flag.n->description = _("Invert colors"); flag.n->guisection = _("Colors"); flag.g = G_define_flag(); flag.g->key = 'g'; flag.g->description = _("Logarithmic scaling"); flag.g->guisection = _("Colors"); flag.a = G_define_flag(); flag.a->key = 'a'; flag.a->description = _("Logarithmic-absolute scaling"); flag.a->guisection = _("Colors"); flag.e = G_define_flag(); flag.e->key = 'e'; flag.e->description = _("Histogram equalization"); flag.e->guisection = _("Colors"); flag.i = G_define_flag(); flag.i->key = 'i'; flag.i->description = _("Enter rules interactively"); /* please, remove before GRASS 7 released */ flag.q = G_define_flag(); flag.q->key = 'q'; flag.q->description = _("Run quietly"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* please, remove before GRASS 7 released */ if (flag.q->answer) { G_putenv("GRASS_VERBOSE", "0"); G_warning(_("The '-q' flag is superseded and will be removed " "in future. Please use '--quiet' instead.")); } if (flag.l->answer) { list_rules(); return EXIT_SUCCESS; } overwrite = !flag.w->answer; interactive = flag.i->answer; remove = flag.r->answer; name = opt.map->answer; style = opt.colr->answer; cmap = opt.rast->answer; rules = opt.rules->answer; if (!name) G_fatal_error(_("No raster map specified")); if (!cmap && !style && !rules && !interactive && !remove) G_fatal_error(_("One of \"-i\" or \"-r\" or options \"color\", \"rast\" or \"rules\" must be specified!")); if (interactive && (style || rules || cmap)) G_fatal_error(_("Interactive mode is incompatible with \"color\", \"rules\", and \"raster\" options")); if ((style && (cmap || rules)) || (cmap && rules)) { if ((style && rules && !cmap) && strcmp(style, "rules") == 0) style = NULL; else G_fatal_error( _("\"color\", \"rules\", and \"raster\" options are mutually exclusive")); } /* handle rules="-" (from stdin) by translating that to colors=rules */ /* this method should not be ported to GRASS 7 verbatim, as color=rules DNE */ if (rules && strcmp(rules, "-") == 0) { style = G_store("rules"); rules = NULL; } if (flag.g->answer && flag.a->answer) G_fatal_error(_("-g and -a flags are mutually exclusive")); mapset = G_find_cell2(name, ""); if (mapset == NULL) G_fatal_error(_("Raster map <%s> not found"), name); if (remove) { int stat = G_remove_colors(name, mapset); if (stat < 0) G_fatal_error(_("Unable to remove color table of raster map <%s>"), name); if (stat == 0) G_warning(_("Color table of raster map <%s> not found"), name); return EXIT_SUCCESS; } G_suppress_warnings(1); have_colors = G_read_colors(name, mapset, &colors); /*if (have_colors >= 0) G_free_colors(&colors); */ if (have_colors > 0 && !overwrite) { G_warning(_("Color table exists. Exiting.")); exit(EXIT_FAILURE); } G_suppress_warnings(0); fp = G_raster_map_is_fp(name, mapset); G_read_fp_range(name, mapset, &range); G_get_fp_range_min_max(&range, &min, &max); if (interactive) { if (!read_color_rules(stdin, &colors, min, max, fp)) exit(EXIT_FAILURE); } else if (style) { /* * here the predefined color-table color-styles are created by GRASS library calls. */ if (strcmp(style, "random") == 0) { if (fp) G_fatal_error(_("Color table 'random' is not supported for floating point raster map")); G_make_random_colors(&colors, (CELL) min, (CELL) max); } else if (strcmp(style, "grey.eq") == 0) { if (fp) G_fatal_error(_("Color table 'grey.eq' is not supported for floating point raster map")); if (!have_stats) have_stats = get_stats(name, mapset, &statf); G_make_histogram_eq_colors(&colors, &statf); } else if (strcmp(style, "grey.log") == 0) { if (fp) G_fatal_error(_("Color table 'grey.log' is not supported for floating point raster map")); if (!have_stats) have_stats = get_stats(name, mapset, &statf); G_make_histogram_log_colors(&colors, &statf, (CELL) min, (CELL) max); } else if (strcmp(style, "rules") == 0) { if (!read_color_rules(stdin, &colors, min, max, fp)) exit(EXIT_FAILURE); } else if (find_rule(style)) G_make_fp_colors(&colors, style, min, max); else G_fatal_error(_("Unknown color request '%s'"), style); } else if (rules) { if (!G_load_fp_colors(&colors, rules, min, max)) { /* for backwards compatibility try as std name; remove for GRASS 7 */ char path[GPATH_MAX]; /* don't bother with native dirsep as not needed for backwards compatibility */ sprintf(path, "%s/etc/colors/%s", G_gisbase(), rules); if (!G_load_fp_colors(&colors, path, min, max)) G_fatal_error(_("Unable to load rules file <%s>"), rules); } } else { /* use color from another map (cmap) */ cmapset = G_find_cell2(cmap, ""); if (cmapset == NULL) G_fatal_error(_("Raster map <%s> not found"), cmap); if (G_read_colors(cmap, cmapset, &colors) < 0) G_fatal_error(_("Unable to read color table for raster map <%s>"), cmap); } if (fp) G_mark_colors_as_fp(&colors); if (flag.n->answer) G_invert_colors(&colors); if (flag.e->answer) { if (fp) { struct FP_stats fpstats; get_fp_stats(name, mapset, &fpstats, min, max, flag.g->answer, flag.a->answer); G_histogram_eq_colors_fp(&colors_tmp, &colors, &fpstats); } else { if (!have_stats) have_stats = get_stats(name, mapset, &statf); G_histogram_eq_colors(&colors_tmp, &colors, &statf); } colors = colors_tmp; } if (flag.g->answer) { G_log_colors(&colors_tmp, &colors, 100); colors = colors_tmp; } if (flag.a->answer) { G_abs_log_colors(&colors_tmp, &colors, 100); colors = colors_tmp; } if (fp) G_mark_colors_as_fp(&colors); if (G_write_colors(name, mapset, &colors) >= 0) G_message(_("Color table for raster map <%s> set to '%s'"), name, interactive ? "rules" : style ? style : rules ? rules : cmap); exit(EXIT_SUCCESS); }
int G_ask_colors(const char *name, const char *mapset, struct Colors *pcolr) { char buff[128]; int answ; struct FPRange range; DCELL min, max; G_init_colors(pcolr); /* determine range cell values */ if (G_read_fp_range(name, mapset, &range) < 0) return -1; G_get_fp_range_min_max(&range, &min, &max); if (G_is_d_null_value(&min) || G_is_d_null_value(&max)) { sprintf(buff, _(" The raster map %s@%s is empty"), name, mapset); G_warning(buff); return -1; } /* Prompting */ ASK: G_clear_screen(); fprintf(stderr, _("\n\nColor table needed for file [%s] in mapset [%s].\n"), name, mapset); fprintf(stderr, _("\nPlease identify the type desired:\n")); fprintf(stderr, _(" 1: Random colors\n")); fprintf(stderr, _(" 2: Red, green, and blue color ramps\n")); fprintf(stderr, _(" 3: Color wave\n")); fprintf(stderr, _(" 4: Gray scale\n")); fprintf(stderr, _(" 5: Aspect\n")); fprintf(stderr, _(" 6: Rainbow colors\n")); fprintf(stderr, _(" 7: Red through yellow to green\n")); fprintf(stderr, _(" 8: Green through yellow to red\n")); fprintf(stderr, _("RETURN quit\n")); fprintf(stderr, "\n> "); for (;;) { if (!G_gets(buff)) goto ASK; G_strip(buff); if (*buff == 0) return -1; if (sscanf(buff, "%d", &answ) != 1) answ = -1; switch (answ) { case 1: return G_make_random_colors(pcolr, (CELL) min, (CELL) max); case 2: return G_make_ramp_fp_colors(pcolr, min, max); case 3: return G_make_wave_fp_colors(pcolr, min, max); case 4: return G_make_grey_scale_fp_colors(pcolr, min, max); case 5: return G_make_aspect_fp_colors(pcolr, min, max); case 6: return G_make_rainbow_fp_colors(pcolr, min, max); case 7: return G_make_ryg_fp_colors(pcolr, min, max); case 8: return G_make_gyr_fp_colors(pcolr, min, max); default: fprintf(stderr, _("\n%s invalid; Try again > "), buff); break; } } }
GRASSRasterBand::GRASSRasterBand( GRASSDataset *poDS, int nBand, const char * pszMapset, const char * pszCellName ) { struct Cell_head sCellInfo; this->poDS = poDS; this->nBand = nBand; G_get_cellhd( (char *) pszCellName, (char *) pszMapset, &sCellInfo ); nGRSType = G_raster_map_type( (char *) pszCellName, (char *) pszMapset ); /* -------------------------------------------------------------------- */ /* Get min/max values. */ /* -------------------------------------------------------------------- */ struct FPRange sRange; if( G_read_fp_range( (char *) pszCellName, (char *) pszMapset, &sRange ) == -1 ) { bHaveMinMax = FALSE; } else { bHaveMinMax = TRUE; G_get_fp_range_min_max( &sRange, &dfCellMin, &dfCellMax ); } /* -------------------------------------------------------------------- */ /* Setup band type, and preferred nodata value. */ /* -------------------------------------------------------------------- */ dfNoData = 0.0; if( nGRSType == CELL_TYPE && sCellInfo.format == 0 ) { if( bHaveMinMax && dfCellMin < 1.0 && dfCellMax > 254.0 ) { this->eDataType = GDT_UInt16; dfNoData = 256.0; } else { this->eDataType = GDT_Byte; if( dfCellMax < 255.0 ) dfNoData = 255.0; else dfNoData = 0.0; } } else if( nGRSType == CELL_TYPE && sCellInfo.format == 1 ) { this->eDataType = GDT_UInt16; dfNoData = 65535.0; } else if( nGRSType == CELL_TYPE ) { this->eDataType = GDT_UInt32; dfNoData = 65535.0; } else if( nGRSType == FCELL_TYPE ) { this->eDataType = GDT_Float32; dfNoData = -12345.0; } else if( nGRSType == DCELL_TYPE ) { this->eDataType = GDT_Float64; dfNoData = -12345.0; } nBlockXSize = poDS->nRasterXSize;; nBlockYSize = 1; hCell = G_open_cell_old((char *) pszCellName, (char *) pszMapset); /* -------------------------------------------------------------------- */ /* Do we have a color table? */ /* -------------------------------------------------------------------- */ struct Colors sGrassColors; poCT = NULL; if( G_read_colors( (char *) pszCellName, (char *) pszMapset, &sGrassColors ) == 1 ) { poCT = new GDALColorTable(); for( int iColor = 0; iColor < 256; iColor++ ) { int nRed, nGreen, nBlue; GDALColorEntry sColor; if( G_get_color( iColor, &nRed, &nGreen, &nBlue, &sGrassColors ) ) { sColor.c1 = nRed; sColor.c2 = nGreen; sColor.c3 = nBlue; sColor.c4 = 255; poCT->SetColorEntry( iColor, &sColor ); } else { sColor.c1 = 0; sColor.c2 = 0; sColor.c3 = 0; sColor.c4 = 0; poCT->SetColorEntry( iColor, &sColor ); } } G_free_colors( &sGrassColors ); } }